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 #ifndef __STDC_LIMIT_MACROS
12 #define __STDC_LIMIT_MACROS
14 #ifndef __STDC_CONSTANT_MACROS
15 #define __STDC_CONSTANT_MACROS
18 #include "llvm-c/Core.h"
19 #include "llvm-c/ExecutionEngine.h"
20 #include "llvm-c/BitWriter.h"
21 #include "llvm-c/Analysis.h"
23 #include "mini-llvm-cpp.h"
26 * Information associated by mono with LLVM modules.
30 LLVMValueRef throw, throw_corlib_exception;
31 GHashTable *llvm_types;
33 const char *got_symbol;
34 GHashTable *plt_entries;
38 * Information associated by the backend with mono basic blocks.
41 LLVMBasicBlockRef bblock, end_bblock;
42 LLVMValueRef finally_ind;
43 gboolean added, invoke_target;
45 * If this bblock is the start of a finally clause, this is a list of bblocks it
46 * needs to branch to in ENDFINALLY.
48 GSList *call_handler_return_bbs;
49 LLVMValueRef endfinally_switch;
54 * Structure containing emit state
59 /* Maps method names to the corresponding LLVMValueRef */
60 GHashTable *emitted_method_decls;
64 MonoLLVMModule *lmodule;
67 int sindex, default_index, ex_index;
68 LLVMBuilderRef builder;
69 LLVMValueRef *values, *addresses;
70 MonoType **vreg_cli_types;
72 MonoMethodSignature *sig;
74 GHashTable *region_to_handler;
75 LLVMBuilderRef alloca_builder;
76 LLVMValueRef last_alloca;
84 MonoBasicBlock *in_bb;
89 * Instruction metadata
90 * This is the same as ins_info, but LREG != IREG.
98 #define MINI_OP(a,b,dest,src1,src2) dest, src1, src2, ' ',
99 #define MINI_OP3(a,b,dest,src1,src2,src3) dest, src1, src2, src3,
106 /* keep in sync with the enum in mini.h */
109 #include "mini-ops.h"
114 #if SIZEOF_VOID_P == 4
115 #define GET_LONG_IMM(ins) (((guint64)(ins)->inst_ms_word << 32) | (guint64)(guint32)(ins)->inst_ls_word)
117 #define GET_LONG_IMM(ins) ((ins)->inst_imm)
120 #define LLVM_INS_INFO(opcode) (&llvm_ins_info [((opcode) - OP_START - 1) * 4])
123 #define TRACE_FAILURE(msg) do { printf ("%s\n", msg); } while (0)
125 #define TRACE_FAILURE(msg)
128 #define LLVM_FAILURE(ctx, reason) do { \
129 TRACE_FAILURE (reason); \
130 (ctx)->cfg->exception_message = g_strdup (reason); \
131 (ctx)->cfg->disable_llvm = TRUE; \
135 #define CHECK_FAILURE(ctx) do { \
136 if ((ctx)->cfg->disable_llvm) \
140 static LLVMIntPredicate cond_to_llvm_cond [] = {
153 static LLVMRealPredicate fpcond_to_llvm_cond [] = {
166 static LLVMExecutionEngineRef ee;
167 static guint32 current_cfg_tls_id;
169 static MonoLLVMModule jit_module, aot_module;
170 static gboolean jit_module_inited;
172 static void init_jit_module (void);
177 * The LLVM type with width == sizeof (gpointer)
182 return sizeof (gpointer) == 8 ? LLVMInt64Type () : LLVMInt32Type ();
188 * Return the size of the LLVM representation of the vtype T.
191 get_vtype_size (MonoType *t)
195 size = mono_class_value_size (mono_class_from_mono_type (t), NULL);
197 while (size < sizeof (gpointer) && mono_is_power_of_two (size) == -1)
204 * simd_class_to_llvm_type:
206 * Return the LLVM type corresponding to the Mono.SIMD class KLASS
209 simd_class_to_llvm_type (EmitContext *ctx, MonoClass *klass)
211 if (!strcmp (klass->name, "Vector2d")) {
212 return LLVMVectorType (LLVMDoubleType (), 2);
213 } else if (!strcmp (klass->name, "Vector2l")) {
214 return LLVMVectorType (LLVMInt64Type (), 2);
215 } else if (!strcmp (klass->name, "Vector2ul")) {
216 return LLVMVectorType (LLVMInt64Type (), 2);
217 } else if (!strcmp (klass->name, "Vector4i")) {
218 return LLVMVectorType (LLVMInt32Type (), 4);
219 } else if (!strcmp (klass->name, "Vector4ui")) {
220 return LLVMVectorType (LLVMInt32Type (), 4);
221 } else if (!strcmp (klass->name, "Vector4f")) {
222 return LLVMVectorType (LLVMFloatType (), 4);
223 } else if (!strcmp (klass->name, "Vector8s")) {
224 return LLVMVectorType (LLVMInt16Type (), 8);
225 } else if (!strcmp (klass->name, "Vector8us")) {
226 return LLVMVectorType (LLVMInt16Type (), 8);
227 } else if (!strcmp (klass->name, "Vector16sb")) {
228 return LLVMVectorType (LLVMInt8Type (), 16);
229 } else if (!strcmp (klass->name, "Vector16b")) {
230 return LLVMVectorType (LLVMInt8Type (), 16);
232 printf ("%s\n", klass->name);
241 * Return the LLVM type corresponding to T.
244 type_to_llvm_type (EmitContext *ctx, MonoType *t)
247 return LLVMPointerType (LLVMInt8Type (), 0);
250 return LLVMVoidType ();
252 return LLVMInt8Type ();
254 return LLVMInt16Type ();
256 return LLVMInt32Type ();
258 return LLVMInt8Type ();
260 return LLVMInt16Type ();
262 return LLVMInt32Type ();
263 case MONO_TYPE_BOOLEAN:
264 return LLVMInt8Type ();
267 return LLVMInt64Type ();
269 return LLVMInt16Type ();
271 return LLVMFloatType ();
273 return LLVMDoubleType ();
276 return IntPtrType ();
277 case MONO_TYPE_OBJECT:
278 case MONO_TYPE_CLASS:
279 case MONO_TYPE_ARRAY:
280 case MONO_TYPE_SZARRAY:
281 case MONO_TYPE_STRING:
283 return LLVMPointerType (IntPtrType (), 0);
286 /* Because of generic sharing */
287 return IntPtrType ();
288 case MONO_TYPE_GENERICINST:
289 if (!mono_type_generic_inst_is_valuetype (t))
290 return IntPtrType ();
292 case MONO_TYPE_VALUETYPE:
293 case MONO_TYPE_TYPEDBYREF: {
297 klass = mono_class_from_mono_type (t);
299 if (MONO_CLASS_IS_SIMD (ctx->cfg, klass))
300 return simd_class_to_llvm_type (ctx, klass);
303 return type_to_llvm_type (ctx, mono_class_enum_basetype (klass));
304 ltype = g_hash_table_lookup (ctx->lmodule->llvm_types, klass);
307 LLVMTypeRef *eltypes;
309 size = get_vtype_size (t);
311 eltypes = g_new (LLVMTypeRef, size);
312 for (i = 0; i < size; ++i)
313 eltypes [i] = LLVMInt8Type ();
315 ltype = LLVMStructType (eltypes, size, FALSE);
316 g_hash_table_insert (ctx->lmodule->llvm_types, klass, ltype);
323 printf ("X: %d\n", t->type);
324 ctx->cfg->exception_message = g_strdup_printf ("type %s", mono_type_full_name (t));
325 ctx->cfg->disable_llvm = TRUE;
333 * Return whenever T is an unsigned int type.
336 type_is_unsigned (EmitContext *ctx, MonoType *t)
352 * type_to_llvm_arg_type:
354 * Same as type_to_llvm_type, but treat i8/i16 as i32.
357 type_to_llvm_arg_type (EmitContext *ctx, MonoType *t)
359 LLVMTypeRef ptype = type_to_llvm_type (ctx, t);
361 if (ptype == LLVMInt8Type () || ptype == LLVMInt16Type ()) {
363 * LLVM generates code which only sets the lower bits, while JITted
364 * code expects all the bits to be set.
366 ptype = LLVMInt32Type ();
373 * llvm_type_to_stack_type:
375 * Return the LLVM type which needs to be used when a value of type TYPE is pushed
378 static G_GNUC_UNUSED LLVMTypeRef
379 llvm_type_to_stack_type (LLVMTypeRef type)
383 if (type == LLVMInt8Type ())
384 return LLVMInt32Type ();
385 else if (type == LLVMInt16Type ())
386 return LLVMInt32Type ();
387 else if (type == LLVMFloatType ())
388 return LLVMDoubleType ();
394 * regtype_to_llvm_type:
396 * Return the LLVM type corresponding to the regtype C used in instruction
400 regtype_to_llvm_type (char c)
404 return LLVMInt32Type ();
406 return LLVMInt64Type ();
408 return LLVMDoubleType ();
417 * Return the LLVM type corresponding to the unary/binary opcode OPCODE.
420 op_to_llvm_type (int opcode)
425 return LLVMInt8Type ();
428 return LLVMInt8Type ();
431 return LLVMInt16Type ();
434 return LLVMInt16Type ();
437 return LLVMInt32Type ();
440 return LLVMInt32Type ();
442 return LLVMInt64Type ();
444 return LLVMFloatType ();
446 return LLVMDoubleType ();
448 return LLVMInt64Type ();
450 return LLVMInt32Type ();
452 return LLVMInt64Type ();
455 return LLVMInt8Type ();
458 return LLVMInt16Type ();
461 return sizeof (gpointer) == 8 ? LLVMInt64Type () : LLVMInt32Type ();
468 return LLVMInt32Type ();
475 return LLVMInt64Type ();
477 printf ("%s\n", mono_inst_name (opcode));
478 g_assert_not_reached ();
484 * load_store_to_llvm_type:
486 * Return the size/sign/zero extension corresponding to the load/store opcode
490 load_store_to_llvm_type (int opcode, int *size, gboolean *sext, gboolean *zext)
496 case OP_LOADI1_MEMBASE:
497 case OP_STOREI1_MEMBASE_REG:
498 case OP_STOREI1_MEMBASE_IMM:
501 return LLVMInt8Type ();
502 case OP_LOADU1_MEMBASE:
506 return LLVMInt8Type ();
507 case OP_LOADI2_MEMBASE:
508 case OP_STOREI2_MEMBASE_REG:
509 case OP_STOREI2_MEMBASE_IMM:
512 return LLVMInt16Type ();
513 case OP_LOADU2_MEMBASE:
517 return LLVMInt16Type ();
518 case OP_LOADI4_MEMBASE:
519 case OP_LOADU4_MEMBASE:
522 case OP_STOREI4_MEMBASE_REG:
523 case OP_STOREI4_MEMBASE_IMM:
525 return LLVMInt32Type ();
526 case OP_LOADI8_MEMBASE:
528 case OP_STOREI8_MEMBASE_REG:
529 case OP_STOREI8_MEMBASE_IMM:
531 return LLVMInt64Type ();
532 case OP_LOADR4_MEMBASE:
533 case OP_STORER4_MEMBASE_REG:
535 return LLVMFloatType ();
536 case OP_LOADR8_MEMBASE:
537 case OP_STORER8_MEMBASE_REG:
539 return LLVMDoubleType ();
540 case OP_LOAD_MEMBASE:
542 case OP_STORE_MEMBASE_REG:
543 case OP_STORE_MEMBASE_IMM:
544 *size = sizeof (gpointer);
545 return IntPtrType ();
547 g_assert_not_reached ();
555 * Return the LLVM intrinsics corresponding to the overflow opcode OPCODE.
558 ovf_op_to_intrins (int opcode)
562 return "llvm.sadd.with.overflow.i32";
564 return "llvm.uadd.with.overflow.i32";
566 return "llvm.ssub.with.overflow.i32";
568 return "llvm.usub.with.overflow.i32";
570 return "llvm.smul.with.overflow.i32";
572 return "llvm.umul.with.overflow.i32";
574 return "llvm.sadd.with.overflow.i64";
576 return "llvm.uadd.with.overflow.i64";
578 return "llvm.ssub.with.overflow.i64";
580 return "llvm.usub.with.overflow.i64";
582 return "llvm.smul.with.overflow.i64";
584 return "llvm.umul.with.overflow.i64";
586 g_assert_not_reached ();
592 simd_op_to_intrins (int opcode)
595 #if defined(TARGET_X86) || defined(TARGET_AMD64)
597 return "llvm.x86.sse2.min.pd";
599 return "llvm.x86.sse2.min.ps";
601 return "llvm.x86.sse41.pminud";
603 return "llvm.x86.sse41.pminuw";
605 return "llvm.x86.sse41.pminub";
607 return "llvm.x86.sse2.max.pd";
609 return "llvm.x86.sse2.max.ps";
611 return "llvm.x86.sse41.pmaxud";
613 return "llvm.x86.sse41.pmaxuw";
615 return "llvm.x86.sse41.pmaxub";
618 g_assert_not_reached ();
626 * Return the LLVM basic block corresponding to BB.
628 static LLVMBasicBlockRef
629 get_bb (EmitContext *ctx, MonoBasicBlock *bb)
633 if (ctx->bblocks [bb->block_num].bblock == NULL) {
634 sprintf (bb_name, "BB%d", bb->block_num);
636 ctx->bblocks [bb->block_num].bblock = LLVMAppendBasicBlock (ctx->lmethod, bb_name);
637 ctx->bblocks [bb->block_num].end_bblock = ctx->bblocks [bb->block_num].bblock;
640 return ctx->bblocks [bb->block_num].bblock;
646 * Return the last LLVM bblock corresponding to BB.
647 * This might not be equal to the bb returned by get_bb () since we need to generate
648 * multiple LLVM bblocks for a mono bblock to handle throwing exceptions.
650 static LLVMBasicBlockRef
651 get_end_bb (EmitContext *ctx, MonoBasicBlock *bb)
654 return ctx->bblocks [bb->block_num].end_bblock;
657 static LLVMBasicBlockRef
658 gen_bb (EmitContext *ctx, const char *prefix)
662 sprintf (bb_name, "%s%d", prefix, ++ ctx->ex_index);
663 return LLVMAppendBasicBlock (ctx->lmethod, bb_name);
669 * Return the target of the patch identified by TYPE and TARGET.
672 resolve_patch (MonoCompile *cfg, MonoJumpInfoType type, gconstpointer target)
676 memset (&ji, 0, sizeof (ji));
678 ji.data.target = target;
680 return mono_resolve_patch_target (cfg->method, cfg->domain, NULL, &ji, FALSE);
686 * Emit code to convert the LLVM value V to DTYPE.
689 convert_full (EmitContext *ctx, LLVMValueRef v, LLVMTypeRef dtype, gboolean is_unsigned)
691 LLVMTypeRef stype = LLVMTypeOf (v);
693 if (stype != dtype) {
694 gboolean ext = FALSE;
697 if (dtype == LLVMInt64Type () && (stype == LLVMInt32Type () || stype == LLVMInt16Type () || stype == LLVMInt8Type ()))
699 else if (dtype == LLVMInt32Type () && (stype == LLVMInt16Type () || stype == LLVMInt8Type ()))
701 else if (dtype == LLVMInt16Type () && (stype == LLVMInt8Type ()))
705 return is_unsigned ? LLVMBuildZExt (ctx->builder, v, dtype, "") : LLVMBuildSExt (ctx->builder, v, dtype, "");
707 if (dtype == LLVMDoubleType () && stype == LLVMFloatType ())
708 return LLVMBuildFPExt (ctx->builder, v, dtype, "");
711 if (stype == LLVMInt64Type () && (dtype == LLVMInt32Type () || dtype == LLVMInt16Type () || dtype == LLVMInt8Type ()))
712 return LLVMBuildTrunc (ctx->builder, v, dtype, "");
713 if (stype == LLVMInt32Type () && (dtype == LLVMInt16Type () || dtype == LLVMInt8Type ()))
714 return LLVMBuildTrunc (ctx->builder, v, dtype, "");
715 if (stype == LLVMDoubleType () && dtype == LLVMFloatType ())
716 return LLVMBuildFPTrunc (ctx->builder, v, dtype, "");
718 if (LLVMGetTypeKind (stype) == LLVMPointerTypeKind && LLVMGetTypeKind (dtype) == LLVMPointerTypeKind)
719 return LLVMBuildBitCast (ctx->builder, v, dtype, "");
720 if (LLVMGetTypeKind (dtype) == LLVMPointerTypeKind)
721 return LLVMBuildIntToPtr (ctx->builder, v, dtype, "");
722 if (LLVMGetTypeKind (stype) == LLVMPointerTypeKind)
723 return LLVMBuildPtrToInt (ctx->builder, v, dtype, "");
725 #ifdef MONO_ARCH_SOFT_FLOAT
726 if (stype == LLVMInt32Type () && dtype == LLVMFloatType ())
727 return LLVMBuildBitCast (ctx->builder, v, dtype, "");
728 if (stype == LLVMInt32Type () && dtype == LLVMDoubleType ())
729 return LLVMBuildBitCast (ctx->builder, LLVMBuildZExt (ctx->builder, v, LLVMInt64Type (), ""), dtype, "");
733 LLVMDumpValue (LLVMConstNull (dtype));
734 g_assert_not_reached ();
742 convert (EmitContext *ctx, LLVMValueRef v, LLVMTypeRef dtype)
744 return convert_full (ctx, v, dtype, FALSE);
748 * emit_volatile_load:
750 * If vreg is volatile, emit a load from its address.
753 emit_volatile_load (EmitContext *ctx, int vreg)
757 LLVMValueRef v = LLVMBuildLoad (ctx->builder, ctx->addresses [vreg], "");
758 t = ctx->vreg_cli_types [vreg];
759 if (t && !t->byref) {
761 * Might have to zero extend since llvm doesn't have
764 if (t->type == MONO_TYPE_U1 || t->type == MONO_TYPE_U2)
765 v = LLVMBuildZExt (ctx->builder, v, LLVMInt32Type (), "");
766 else if (t->type == MONO_TYPE_U8)
767 v = LLVMBuildZExt (ctx->builder, v, LLVMInt64Type (), "");
774 * emit_volatile_store:
776 * If VREG is volatile, emit a store from its value to its address.
779 emit_volatile_store (EmitContext *ctx, int vreg)
781 MonoInst *var = get_vreg_to_inst (ctx->cfg, vreg);
783 if (var && var->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT)) {
784 g_assert (ctx->addresses [vreg]);
785 LLVMBuildStore (ctx->builder, convert (ctx, ctx->values [vreg], type_to_llvm_type (ctx, var->inst_vtype)), ctx->addresses [vreg]);
792 * Return the LLVM signature corresponding to the mono signature SIG using the
793 * calling convention information in CINFO.
796 sig_to_llvm_sig (EmitContext *ctx, MonoMethodSignature *sig, LLVMCallInfo *cinfo)
798 LLVMTypeRef ret_type;
799 LLVMTypeRef *param_types = NULL;
802 gboolean vretaddr = FALSE;
804 ret_type = type_to_llvm_type (ctx, sig->ret);
807 if (cinfo && cinfo->ret.storage == LLVMArgVtypeInReg) {
808 /* LLVM models this by returning an aggregate value */
809 if (cinfo->ret.pair_storage [0] == LLVMArgInIReg && cinfo->ret.pair_storage [1] == LLVMArgNone) {
810 LLVMTypeRef members [2];
812 members [0] = IntPtrType ();
813 ret_type = LLVMStructType (members, 1, FALSE);
815 g_assert_not_reached ();
817 } else if (cinfo && MONO_TYPE_ISSTRUCT (sig->ret)) {
818 g_assert (cinfo->ret.storage == LLVMArgVtypeRetAddr);
822 param_types = g_new0 (LLVMTypeRef, (sig->param_count * 2) + 2);
825 ret_type = LLVMVoidType ();
826 param_types [pindex ++] = IntPtrType ();
829 param_types [pindex ++] = IntPtrType ();
830 for (i = 0; i < sig->param_count; ++i) {
831 if (cinfo && cinfo->args [i + sig->hasthis].storage == LLVMArgVtypeInReg) {
832 for (j = 0; j < 2; ++j) {
833 switch (cinfo->args [i + sig->hasthis].pair_storage [j]) {
835 param_types [pindex ++] = LLVMIntType (sizeof (gpointer) * 8);
840 g_assert_not_reached ();
843 } else if (cinfo && cinfo->args [i + sig->hasthis].storage == LLVMArgVtypeByVal) {
844 param_types [pindex] = type_to_llvm_arg_type (ctx, sig->params [i]);
846 param_types [pindex] = LLVMPointerType (param_types [pindex], 0);
849 param_types [pindex ++] = type_to_llvm_arg_type (ctx, sig->params [i]);
854 res = LLVMFunctionType (ret_type, param_types, pindex, FALSE);
855 g_free (param_types);
860 g_free (param_types);
868 * Create an LLVM function type from the arguments.
870 static G_GNUC_UNUSED LLVMTypeRef
871 LLVMFunctionType1(LLVMTypeRef ReturnType,
872 LLVMTypeRef ParamType1,
875 LLVMTypeRef param_types [1];
877 param_types [0] = ParamType1;
879 return LLVMFunctionType (ReturnType, param_types, 1, IsVarArg);
885 * Create an LLVM function type from the arguments.
888 LLVMFunctionType2(LLVMTypeRef ReturnType,
889 LLVMTypeRef ParamType1,
890 LLVMTypeRef ParamType2,
893 LLVMTypeRef param_types [2];
895 param_types [0] = ParamType1;
896 param_types [1] = ParamType2;
898 return LLVMFunctionType (ReturnType, param_types, 2, IsVarArg);
904 * Create an LLVM function type from the arguments.
907 LLVMFunctionType3(LLVMTypeRef ReturnType,
908 LLVMTypeRef ParamType1,
909 LLVMTypeRef ParamType2,
910 LLVMTypeRef ParamType3,
913 LLVMTypeRef param_types [3];
915 param_types [0] = ParamType1;
916 param_types [1] = ParamType2;
917 param_types [2] = ParamType3;
919 return LLVMFunctionType (ReturnType, param_types, 3, IsVarArg);
925 * Create an LLVM builder and remember it so it can be freed later.
927 static LLVMBuilderRef
928 create_builder (EmitContext *ctx)
930 LLVMBuilderRef builder = LLVMCreateBuilder ();
932 ctx->builders = g_slist_prepend_mempool (ctx->cfg->mempool, ctx->builders, builder);
938 get_plt_entry (EmitContext *ctx, LLVMTypeRef llvm_sig, MonoJumpInfoType type, gconstpointer data)
940 char *callee_name = mono_aot_get_plt_symbol (type, data);
947 callee = g_hash_table_lookup (ctx->lmodule->plt_entries, callee_name);
949 callee = LLVMAddFunction (ctx->module, callee_name, llvm_sig);
951 LLVMSetVisibility (callee, LLVMHiddenVisibility);
953 g_hash_table_insert (ctx->lmodule->plt_entries, (char*)callee_name, callee);
960 emit_cond_throw_pos (EmitContext *ctx)
967 * Emit an LLVM call or invoke instruction depending on whenever the call is inside
971 emit_call (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, LLVMValueRef callee, LLVMValueRef *args, int pindex)
973 MonoCompile *cfg = ctx->cfg;
975 LLVMBuilderRef builder = *builder_ref;
977 // FIXME: Nested clauses
978 if (bb->region != -1 && MONO_BBLOCK_IS_IN_REGION (bb, MONO_REGION_TRY)) {
979 MonoMethodHeader *header = mono_method_get_header (cfg->method);
980 // FIXME: Add a macro for this
981 int clause_index = (bb->region >> 8) - 1;
982 MonoExceptionClause *ec = &header->clauses [clause_index];
983 MonoBasicBlock *tblock;
984 LLVMBasicBlockRef ex_bb, noex_bb;
987 * Have to use an invoke instead of a call, branching to the
988 * handler bblock of the clause containing this bblock.
991 g_assert (ec->flags == MONO_EXCEPTION_CLAUSE_NONE || ec->flags == MONO_EXCEPTION_CLAUSE_FINALLY);
993 tblock = cfg->cil_offset_to_bb [ec->handler_offset];
996 ctx->bblocks [tblock->block_num].invoke_target = TRUE;
998 ex_bb = get_bb (ctx, tblock);
1000 noex_bb = gen_bb (ctx, "NOEX_BB");
1003 lcall = LLVMBuildInvoke (builder, callee, args, pindex, noex_bb, ex_bb, "");
1005 builder = ctx->builder = create_builder (ctx);
1006 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
1008 ctx->bblocks [bb->block_num].end_bblock = noex_bb;
1010 lcall = LLVMBuildCall (builder, callee, args, pindex, "");
1011 ctx->builder = builder;
1014 *builder_ref = ctx->builder;
1020 * emit_cond_system_exception:
1022 * Emit code to throw the exception EXC_TYPE if the condition CMP is false.
1025 emit_cond_system_exception (EmitContext *ctx, MonoBasicBlock *bb, const char *exc_type, LLVMValueRef cmp)
1027 LLVMBasicBlockRef ex_bb, noex_bb;
1028 LLVMBuilderRef builder;
1029 MonoClass *exc_class;
1030 LLVMValueRef args [2];
1032 ex_bb = gen_bb (ctx, "EX_BB");
1033 noex_bb = gen_bb (ctx, "NOEX_BB");
1035 LLVMBuildCondBr (ctx->builder, cmp, ex_bb, noex_bb);
1037 exc_class = mono_class_from_name (mono_defaults.corlib, "System", exc_type);
1038 g_assert (exc_class);
1040 /* Emit exception throwing code */
1041 builder = create_builder (ctx);
1042 LLVMPositionBuilderAtEnd (builder, ex_bb);
1044 if (!ctx->lmodule->throw_corlib_exception) {
1045 LLVMValueRef callee;
1048 MonoMethodSignature *throw_sig = mono_metadata_signature_alloc (mono_defaults.corlib, 2);
1049 throw_sig->ret = &mono_defaults.void_class->byval_arg;
1050 throw_sig->params [0] = &mono_defaults.int32_class->byval_arg;
1051 throw_sig->params [1] = &mono_defaults.int32_class->byval_arg;
1052 sig = sig_to_llvm_sig (ctx, throw_sig, NULL);
1054 if (ctx->cfg->compile_aot) {
1055 callee = get_plt_entry (ctx, sig, MONO_PATCH_INFO_INTERNAL_METHOD, "mono_arch_throw_corlib_exception");
1057 callee = LLVMAddFunction (ctx->module, "throw_corlib_exception", sig_to_llvm_sig (ctx, throw_sig, NULL));
1061 * LLVM generated code doesn't push the arguments, so we need another
1064 LLVMAddGlobalMapping (ee, callee, resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, "mono_arch_llvm_throw_corlib_exception"));
1066 LLVMAddGlobalMapping (ee, callee, resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, "mono_arch_throw_corlib_exception"));
1070 mono_memory_barrier ();
1071 ctx->lmodule->throw_corlib_exception = callee;
1075 args [0] = LLVMConstInt (LLVMInt32Type (), exc_class->type_token - MONO_TOKEN_TYPE_DEF, FALSE);
1077 args [0] = LLVMConstInt (LLVMInt32Type (), exc_class->type_token, FALSE);
1080 * FIXME: The offset is 0, this is not a problem for exception handling
1081 * in general, because we don't llvm compile methods with handlers, its only
1082 * a problem for line numbers in stack traces.
1084 args [1] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
1085 emit_call (ctx, bb, &builder, ctx->lmodule->throw_corlib_exception, args, 2);
1087 LLVMBuildUnreachable (builder);
1089 ctx->builder = create_builder (ctx);
1090 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
1092 ctx->bblocks [bb->block_num].end_bblock = noex_bb;
1098 * emit_reg_to_vtype:
1100 * Emit code to store the vtype in the registers REGS to the address ADDRESS.
1103 emit_reg_to_vtype (EmitContext *ctx, LLVMBuilderRef builder, MonoType *t, LLVMValueRef address, LLVMArgInfo *ainfo, LLVMValueRef *regs)
1107 size = get_vtype_size (t);
1109 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (t))) {
1110 address = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (LLVMInt8Type (), 0), "");
1113 for (j = 0; j < 2; ++j) {
1114 LLVMValueRef index [2], addr;
1115 int part_size = size > sizeof (gpointer) ? sizeof (gpointer) : size;
1116 LLVMTypeRef part_type;
1118 if (ainfo->pair_storage [j] == LLVMArgNone)
1121 part_type = LLVMIntType (part_size * 8);
1122 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (t))) {
1123 index [0] = LLVMConstInt (LLVMInt32Type (), j * sizeof (gpointer), FALSE);
1124 addr = LLVMBuildGEP (builder, address, index, 1, "");
1126 index [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
1127 index [1] = LLVMConstInt (LLVMInt32Type (), j * sizeof (gpointer), FALSE);
1128 addr = LLVMBuildGEP (builder, address, index, 2, "");
1130 switch (ainfo->pair_storage [j]) {
1132 LLVMBuildStore (builder, convert (ctx, regs [j], part_type), LLVMBuildBitCast (ctx->builder, addr, LLVMPointerType (part_type, 0), ""));
1137 g_assert_not_reached ();
1140 size -= sizeof (gpointer);
1145 * emit_vtype_to_reg:
1147 * Emit code to load a vtype at address ADDRESS into registers. Store the registers
1148 * into REGS, and the number of registers into NREGS.
1151 emit_vtype_to_reg (EmitContext *ctx, LLVMBuilderRef builder, MonoType *t, LLVMValueRef address, LLVMArgInfo *ainfo, LLVMValueRef *regs, guint32 *nregs)
1156 size = get_vtype_size (t);
1158 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (t))) {
1159 address = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (LLVMInt8Type (), 0), "");
1162 for (j = 0; j < 2; ++j) {
1163 LLVMValueRef index [2], addr;
1164 int partsize = size > sizeof (gpointer) ? sizeof (gpointer) : size;
1166 if (ainfo->pair_storage [j] == LLVMArgNone)
1169 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (t))) {
1170 index [0] = LLVMConstInt (LLVMInt32Type (), j * sizeof (gpointer), FALSE);
1171 addr = LLVMBuildGEP (builder, address, index, 1, "");
1173 index [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
1174 index [1] = LLVMConstInt (LLVMInt32Type (), j * sizeof (gpointer), FALSE);
1175 addr = LLVMBuildGEP (builder, address, index, 2, "");
1177 switch (ainfo->pair_storage [j]) {
1179 regs [pindex ++] = convert (ctx, LLVMBuildLoad (builder, LLVMBuildBitCast (ctx->builder, addr, LLVMPointerType (LLVMIntType (partsize * 8), 0), ""), ""), IntPtrType ());
1184 g_assert_not_reached ();
1186 size -= sizeof (gpointer);
1193 build_alloca (EmitContext *ctx, MonoType *t)
1195 MonoClass *k = mono_class_from_mono_type (t);
1198 if (MONO_CLASS_IS_SIMD (ctx->cfg, k))
1201 align = mono_class_min_align (k);
1203 /* Sometimes align is not a power of 2 */
1204 while (mono_is_power_of_two (align) == -1)
1208 * Have to place all alloca's at the end of the entry bb, since otherwise they would
1209 * get executed every time control reaches them.
1211 LLVMPositionBuilder (ctx->alloca_builder, get_bb (ctx, ctx->cfg->bb_entry), ctx->last_alloca);
1213 ctx->last_alloca = mono_llvm_build_alloca (ctx->alloca_builder, type_to_llvm_type (ctx, t), NULL, align, "");
1214 return ctx->last_alloca;
1218 * Put the global into the 'llvm.used' array to prevent it from being optimized away.
1221 mark_as_used (LLVMModuleRef module, LLVMValueRef global)
1223 LLVMTypeRef used_type;
1224 LLVMValueRef used, used_elem;
1226 used_type = LLVMArrayType (LLVMPointerType (LLVMInt8Type (), 0), 1);
1227 used = LLVMAddGlobal (module, used_type, "llvm.used");
1228 used_elem = LLVMConstBitCast (global, LLVMPointerType (LLVMInt8Type (), 0));
1229 LLVMSetInitializer (used, LLVMConstArray (LLVMPointerType (LLVMInt8Type (), 0), &used_elem, 1));
1230 LLVMSetLinkage (used, LLVMAppendingLinkage);
1231 LLVMSetSection (used, "llvm.metadata");
1237 * Emit code to load/convert arguments.
1240 emit_entry_bb (EmitContext *ctx, LLVMBuilderRef builder, int *pindexes)
1243 MonoCompile *cfg = ctx->cfg;
1244 MonoMethodSignature *sig = ctx->sig;
1245 LLVMCallInfo *linfo = ctx->linfo;
1248 ctx->alloca_builder = create_builder (ctx);
1251 * Handle indirect/volatile variables by allocating memory for them
1252 * using 'alloca', and storing their address in a temporary.
1254 for (i = 0; i < cfg->num_varinfo; ++i) {
1255 MonoInst *var = cfg->varinfo [i];
1258 if (var->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT) || MONO_TYPE_ISSTRUCT (var->inst_vtype)) {
1259 vtype = type_to_llvm_type (ctx, var->inst_vtype);
1260 CHECK_FAILURE (ctx);
1261 /* Could be already created by an OP_VPHI */
1262 if (!ctx->addresses [var->dreg])
1263 ctx->addresses [var->dreg] = build_alloca (ctx, var->inst_vtype);
1264 ctx->vreg_cli_types [var->dreg] = var->inst_vtype;
1268 for (i = 0; i < sig->param_count; ++i) {
1269 LLVMArgInfo *ainfo = &linfo->args [i + sig->hasthis];
1270 int reg = cfg->args [i + sig->hasthis]->dreg;
1272 if (ainfo->storage == LLVMArgVtypeInReg) {
1273 LLVMValueRef regs [2];
1276 * Emit code to save the argument from the registers to
1277 * the real argument.
1279 pindex = pindexes [i];
1280 regs [0] = LLVMGetParam (ctx->lmethod, pindex);
1281 if (ainfo->pair_storage [1] != LLVMArgNone)
1282 regs [1] = LLVMGetParam (ctx->lmethod, pindex + 1);
1286 ctx->addresses [reg] = build_alloca (ctx, sig->params [i]);
1288 emit_reg_to_vtype (ctx, builder, sig->params [i], ctx->addresses [reg], ainfo, regs);
1290 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (sig->params [i]))) {
1291 /* Treat these as normal values */
1292 ctx->values [reg] = LLVMBuildLoad (builder, ctx->addresses [reg], "");
1294 } else if (ainfo->storage == LLVMArgVtypeByVal) {
1295 ctx->addresses [reg] = LLVMGetParam (ctx->lmethod, pindexes [i]);
1297 ctx->values [reg] = convert (ctx, ctx->values [reg], llvm_type_to_stack_type (type_to_llvm_type (ctx, sig->params [i])));
1302 emit_volatile_store (ctx, cfg->vret_addr->dreg);
1304 emit_volatile_store (ctx, cfg->args [0]->dreg);
1305 for (i = 0; i < sig->param_count; ++i)
1306 if (!MONO_TYPE_ISSTRUCT (sig->params [i]))
1307 emit_volatile_store (ctx, cfg->args [i + sig->hasthis]->dreg);
1310 * For finally clauses, create an indicator variable telling OP_ENDFINALLY whenever
1311 * it needs to continue normally, or return back to the exception handling system.
1313 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
1314 if (bb->region != -1 && (bb->flags & BB_EXCEPTION_HANDLER))
1315 g_hash_table_insert (ctx->region_to_handler, GUINT_TO_POINTER (mono_get_block_region_notry (cfg, bb->region)), bb);
1316 if (bb->region != -1 && (bb->flags & BB_EXCEPTION_HANDLER) && bb->in_scount == 0) {
1317 LLVMValueRef val = LLVMBuildAlloca (builder, LLVMInt32Type (), "");
1318 LLVMBuildStore (builder, LLVMConstInt (LLVMInt32Type (), 0, FALSE), val);
1320 ctx->bblocks [bb->block_num].finally_ind = val;
1328 /* Have to export this for AOT */
1330 mono_personality (void);
1333 mono_personality (void)
1336 g_assert_not_reached ();
1340 * mono_llvm_emit_method:
1342 * Emit LLVM IL from the mono IL, and compile it to native code using LLVM.
1345 mono_llvm_emit_method (MonoCompile *cfg)
1348 MonoMethodSignature *sig;
1350 LLVMTypeRef method_type;
1351 LLVMValueRef method = NULL, debug_alias = NULL;
1352 char *method_name, *debug_name = NULL;
1353 LLVMValueRef *values, *addresses;
1354 LLVMTypeRef *vreg_types;
1355 MonoType **vreg_cli_types;
1356 int i, max_block_num, pindex, bb_index;
1357 int *pindexes = NULL;
1358 gboolean last = FALSE;
1359 GPtrArray *phi_values;
1360 LLVMCallInfo *linfo;
1362 LLVMModuleRef module;
1364 gboolean *unreachable;
1366 GPtrArray *bblock_list;
1367 MonoMethodHeader *header;
1368 MonoExceptionClause *clause;
1370 /* The code below might acquire the loader lock, so use it for global locking */
1371 mono_loader_lock ();
1373 /* Used to communicate with the callbacks */
1374 TlsSetValue (current_cfg_tls_id, cfg);
1376 ctx = g_new0 (EmitContext, 1);
1378 ctx->mempool = cfg->mempool;
1381 * This maps vregs to the LLVM instruction defining them
1383 values = g_new0 (LLVMValueRef, cfg->next_vreg);
1385 * This maps vregs for volatile variables to the LLVM instruction defining their
1388 addresses = g_new0 (LLVMValueRef, cfg->next_vreg);
1389 vreg_types = g_new0 (LLVMTypeRef, cfg->next_vreg);
1390 vreg_cli_types = g_new0 (MonoType*, cfg->next_vreg);
1391 phi_values = g_ptr_array_new ();
1393 * This signals whenever the vreg was defined by a phi node with no input vars
1394 * (i.e. all its input bblocks end with NOT_REACHABLE).
1396 is_dead = g_new0 (gboolean, cfg->next_vreg);
1397 /* Whenever the bblock is unreachable */
1398 unreachable = g_new0 (gboolean, cfg->max_block_num);
1400 bblock_list = g_ptr_array_new ();
1402 ctx->values = values;
1403 ctx->addresses = addresses;
1404 ctx->vreg_cli_types = vreg_cli_types;
1405 ctx->region_to_handler = g_hash_table_new (NULL, NULL);
1407 if (cfg->compile_aot) {
1408 ctx->lmodule = &aot_module;
1409 method_name = mono_aot_get_method_name (cfg);
1410 debug_name = mono_aot_get_method_debug_name (cfg);
1413 ctx->lmodule = &jit_module;
1414 method_name = mono_method_full_name (cfg->method, TRUE);
1418 module = ctx->module = ctx->lmodule->module;
1422 static int count = 0;
1425 if (getenv ("LLVM_COUNT")) {
1426 if (count == atoi (getenv ("LLVM_COUNT"))) {
1427 printf ("LAST: %s\n", mono_method_full_name (cfg->method, TRUE));
1430 if (count > atoi (getenv ("LLVM_COUNT")))
1431 LLVM_FAILURE (ctx, "");
1436 sig = mono_method_signature (cfg->method);
1439 linfo = mono_arch_get_llvm_call_info (cfg, sig);
1441 CHECK_FAILURE (ctx);
1443 method_type = sig_to_llvm_sig (ctx, sig, linfo);
1444 CHECK_FAILURE (ctx);
1446 method = LLVMAddFunction (module, method_name, method_type);
1447 ctx->lmethod = method;
1449 LLVMSetLinkage (method, LLVMPrivateLinkage);
1451 if (cfg->method->save_lmf)
1452 LLVM_FAILURE (ctx, "lmf");
1455 LLVM_FAILURE (ctx, "pinvoke signature");
1457 header = mono_method_get_header (cfg->method);
1458 for (i = 0; i < header->num_clauses; ++i) {
1459 clause = &header->clauses [i];
1460 if (clause->flags != MONO_EXCEPTION_CLAUSE_FINALLY && clause->flags != MONO_EXCEPTION_CLAUSE_NONE)
1461 LLVM_FAILURE (ctx, "non-finally/catch clause.");
1465 * This maps parameter indexes in the original signature to the indexes in
1466 * the LLVM signature.
1468 pindexes = g_new0 (int, sig->param_count);
1470 if (cfg->vret_addr) {
1471 values [cfg->vret_addr->dreg] = LLVMGetParam (method, pindex);
1475 values [cfg->args [0]->dreg] = LLVMGetParam (method, pindex);
1478 for (i = 0; i < sig->param_count; ++i) {
1479 values [cfg->args [i + sig->hasthis]->dreg] = LLVMGetParam (method, pindex);
1480 pindexes [i] = pindex;
1481 if (linfo->args [i + sig->hasthis].storage == LLVMArgVtypeInReg) {
1482 if (linfo->args [i + sig->hasthis].pair_storage [0] != LLVMArgNone)
1484 if (linfo->args [i + sig->hasthis].pair_storage [1] != LLVMArgNone)
1486 } else if (linfo->args [i + sig->hasthis].storage == LLVMArgVtypeByVal) {
1487 LLVMAddAttribute (LLVMGetParam (method, pindex), LLVMByValAttribute);
1495 for (bb = cfg->bb_entry; bb; bb = bb->next_bb)
1496 max_block_num = MAX (max_block_num, bb->block_num);
1497 ctx->bblocks = bblocks = g_new0 (BBInfo, max_block_num + 1);
1499 /* Add branches between non-consecutive bblocks */
1500 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
1501 if (bb->last_ins && MONO_IS_COND_BRANCH_OP (bb->last_ins) &&
1502 bb->next_bb != bb->last_ins->inst_false_bb) {
1504 MonoInst *inst = mono_mempool_alloc0 (cfg->mempool, sizeof (MonoInst));
1505 inst->opcode = OP_BR;
1506 inst->inst_target_bb = bb->last_ins->inst_false_bb;
1507 mono_bblock_add_inst (bb, inst);
1512 * Make a first pass over the code to precreate PHI nodes.
1514 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
1516 LLVMBuilderRef builder;
1518 char dname_buf[128];
1520 builder = create_builder (ctx);
1522 for (ins = bb->code; ins; ins = ins->next) {
1523 switch (ins->opcode) {
1528 LLVMTypeRef phi_type = llvm_type_to_stack_type (type_to_llvm_type (ctx, &ins->klass->byval_arg));
1530 CHECK_FAILURE (ctx);
1532 if (ins->opcode == OP_VPHI) {
1533 /* Treat valuetype PHI nodes as operating on the address itself */
1534 g_assert (ins->klass);
1535 phi_type = LLVMPointerType (type_to_llvm_type (ctx, &ins->klass->byval_arg), 0);
1539 * Have to precreate these, as they can be referenced by
1540 * earlier instructions.
1542 sprintf (dname_buf, "t%d", ins->dreg);
1544 values [ins->dreg] = LLVMBuildPhi (builder, phi_type, dname);
1546 if (ins->opcode == OP_VPHI)
1547 addresses [ins->dreg] = values [ins->dreg];
1549 g_ptr_array_add (phi_values, values [ins->dreg]);
1552 * Set the expected type of the incoming arguments since these have
1553 * to have the same type.
1555 for (i = 0; i < ins->inst_phi_args [0]; i++) {
1556 int sreg1 = ins->inst_phi_args [i + 1];
1559 vreg_types [sreg1] = phi_type;
1570 * Create an ordering for bblocks, use the depth first order first, then
1571 * put the exception handling bblocks last.
1573 for (bb_index = 0; bb_index < cfg->num_bblocks; ++bb_index) {
1574 bb = cfg->bblocks [bb_index];
1575 if (!(bb->region != -1 && !MONO_BBLOCK_IS_IN_REGION (bb, MONO_REGION_TRY))) {
1576 g_ptr_array_add (bblock_list, bb);
1577 bblocks [bb->block_num].added = TRUE;
1581 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
1582 if (!bblocks [bb->block_num].added)
1583 g_ptr_array_add (bblock_list, bb);
1587 * Second pass: generate code.
1589 for (bb_index = 0; bb_index < bblock_list->len; ++bb_index) {
1591 LLVMBasicBlockRef cbb;
1592 LLVMBuilderRef builder;
1593 gboolean has_terminator;
1595 LLVMValueRef lhs, rhs;
1597 bb = g_ptr_array_index (bblock_list, bb_index);
1599 if (!(bb == cfg->bb_entry || bb->in_count > 0))
1602 cbb = get_bb (ctx, bb);
1603 builder = create_builder (ctx);
1604 ctx->builder = builder;
1605 LLVMPositionBuilderAtEnd (builder, cbb);
1607 if (bb == cfg->bb_entry)
1608 emit_entry_bb (ctx, builder, pindexes);
1609 CHECK_FAILURE (ctx);
1611 if (bb->flags & BB_EXCEPTION_HANDLER) {
1613 LLVMValueRef eh_selector, eh_exception, personality, args [4];
1615 static gint32 mapping_inited;
1616 static int ti_generator;
1619 LLVMValueRef type_info;
1622 if (!bblocks [bb->block_num].invoke_target) {
1624 * LLVM asserts if llvm.eh.selector is called from a bblock which
1625 * doesn't have an invoke pointing at it.
1627 LLVM_FAILURE (ctx, "handler without invokes");
1630 eh_selector = LLVMGetNamedFunction (module, "llvm.eh.selector");
1632 if (cfg->compile_aot) {
1633 /* Use a dummy personality function */
1634 personality = LLVMGetNamedFunction (module, "mono_aot_personality");
1635 g_assert (personality);
1637 personality = LLVMGetNamedFunction (module, "mono_personality");
1638 if (InterlockedCompareExchange (&mapping_inited, 1, 0) == 0)
1639 LLVMAddGlobalMapping (ee, personality, mono_personality);
1642 i8ptr = LLVMPointerType (LLVMInt8Type (), 0);
1644 clause_index = (mono_get_block_region_notry (cfg, bb->region) >> 8) - 1;
1647 * Create the type info
1649 sprintf (ti_name, "type_info_%d", ti_generator);
1652 if (cfg->compile_aot) {
1653 /* decode_eh_frame () in aot-runtime.c will decode this */
1654 type_info = LLVMAddGlobal (module, LLVMInt32Type (), ti_name);
1655 LLVMSetInitializer (type_info, LLVMConstInt (LLVMInt32Type (), clause_index, FALSE));
1657 LLVMSetLinkage (type_info, LLVMPrivateLinkage);
1658 LLVMSetVisibility (type_info, LLVMHiddenVisibility);
1661 * FIXME: llc currently generates incorrect data in the LSDA:
1662 * .byte 0x9B # @TType format (indirect pcrel sdata4)
1664 * .quad type_info_1 # TypeInfo
1666 LLVM_FAILURE (ctx, "aot+clauses");
1668 /* exception_cb will decode this */
1669 ti = g_malloc (sizeof (gint32));
1670 *(gint32*)ti = clause_index;
1672 type_info = LLVMAddGlobal (module, i8ptr, ti_name);
1674 LLVMAddGlobalMapping (ee, type_info, ti);
1677 args [0] = LLVMConstNull (i8ptr);
1678 args [1] = LLVMConstBitCast (personality, i8ptr);
1679 args [2] = type_info;
1680 LLVMBuildCall (builder, eh_selector, args, 3, "");
1682 /* Store the exception into the exvar */
1683 if (bb->in_scount == 1) {
1684 g_assert (bb->in_scount == 1);
1685 exvar = bb->in_stack [0];
1687 eh_exception = LLVMGetNamedFunction (module, "llvm.eh.exception");
1689 // FIXME: This is shared with filter clauses ?
1690 g_assert (!values [exvar->dreg]);
1691 values [exvar->dreg] = LLVMBuildCall (builder, eh_exception, NULL, 0, "");
1692 emit_volatile_store (ctx, exvar->dreg);
1696 has_terminator = FALSE;
1697 for (ins = bb->code; ins; ins = ins->next) {
1698 const char *spec = LLVM_INS_INFO (ins->opcode);
1700 char dname_buf [128];
1703 /* There could be instructions after a terminator, skip them */
1706 if (spec [MONO_INST_DEST] != ' ' && !MONO_IS_STORE_MEMBASE (ins)) {
1707 sprintf (dname_buf, "t%d", ins->dreg);
1711 if (spec [MONO_INST_SRC1] != ' ' && spec [MONO_INST_SRC1] != 'v') {
1712 MonoInst *var = get_vreg_to_inst (cfg, ins->sreg1);
1714 if (var && var->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT)) {
1715 lhs = emit_volatile_load (ctx, ins->sreg1);
1717 /* It is ok for SETRET to have an uninitialized argument */
1718 if (!values [ins->sreg1] && ins->opcode != OP_SETRET)
1719 LLVM_FAILURE (ctx, "sreg1");
1720 lhs = values [ins->sreg1];
1726 if (spec [MONO_INST_SRC2] != ' ' && spec [MONO_INST_SRC2] != ' ') {
1727 MonoInst *var = get_vreg_to_inst (cfg, ins->sreg2);
1728 if (var && var->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT)) {
1729 rhs = emit_volatile_load (ctx, ins->sreg2);
1731 if (!values [ins->sreg2])
1732 LLVM_FAILURE (ctx, "sreg2");
1733 rhs = values [ins->sreg2];
1739 //mono_print_ins (ins);
1740 switch (ins->opcode) {
1743 case OP_LIVERANGE_START:
1744 case OP_LIVERANGE_END:
1747 values [ins->dreg] = LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE);
1750 #if SIZEOF_VOID_P == 4
1751 values [ins->dreg] = LLVMConstInt (LLVMInt64Type (), GET_LONG_IMM (ins), FALSE);
1753 values [ins->dreg] = LLVMConstInt (LLVMInt64Type (), (gint64)ins->inst_c0, FALSE);
1757 values [ins->dreg] = LLVMConstReal (LLVMDoubleType (), *(double*)ins->inst_p0);
1760 values [ins->dreg] = LLVMConstFPExt (LLVMConstReal (LLVMFloatType (), *(float*)ins->inst_p0), LLVMDoubleType ());
1763 LLVMBuildBr (builder, get_bb (ctx, ins->inst_target_bb));
1764 has_terminator = TRUE;
1770 LLVMBasicBlockRef new_bb;
1771 LLVMBuilderRef new_builder;
1773 // The default branch is already handled
1774 // FIXME: Handle it here
1776 /* Start new bblock */
1777 sprintf (bb_name, "SWITCH_DEFAULT_BB%d", ctx->default_index ++);
1778 new_bb = LLVMAppendBasicBlock (ctx->lmethod, bb_name);
1780 lhs = convert (ctx, lhs, LLVMInt32Type ());
1781 v = LLVMBuildSwitch (builder, lhs, new_bb, GPOINTER_TO_UINT (ins->klass));
1782 for (i = 0; i < GPOINTER_TO_UINT (ins->klass); ++i) {
1783 MonoBasicBlock *target_bb = ins->inst_many_bb [i];
1785 LLVMAddCase (v, LLVMConstInt (LLVMInt32Type (), i, FALSE), get_bb (ctx, target_bb));
1788 new_builder = create_builder (ctx);
1789 LLVMPositionBuilderAtEnd (new_builder, new_bb);
1790 LLVMBuildUnreachable (new_builder);
1792 has_terminator = TRUE;
1793 g_assert (!ins->next);
1799 if (linfo->ret.storage == LLVMArgVtypeInReg) {
1800 LLVMTypeRef ret_type = LLVMGetReturnType (LLVMGetElementType (LLVMTypeOf (method)));
1801 LLVMValueRef part1, retval;
1804 size = get_vtype_size (sig->ret);
1806 g_assert (addresses [ins->sreg1]);
1808 g_assert (linfo->ret.pair_storage [0] == LLVMArgInIReg);
1809 g_assert (linfo->ret.pair_storage [1] == LLVMArgNone);
1811 part1 = convert (ctx, LLVMBuildLoad (builder, LLVMBuildBitCast (builder, addresses [ins->sreg1], LLVMPointerType (LLVMIntType (size * 8), 0), ""), ""), IntPtrType ());
1813 retval = LLVMBuildInsertValue (builder, LLVMGetUndef (ret_type), part1, 0, "");
1815 LLVMBuildRet (builder, retval);
1819 if (linfo->ret.storage == LLVMArgVtypeRetAddr) {
1820 LLVMBuildRetVoid (builder);
1824 if (!lhs || is_dead [ins->sreg1]) {
1826 * The method did not set its return value, probably because it
1827 * ends with a throw.
1830 LLVMBuildRetVoid (builder);
1832 LLVMBuildRet (builder, LLVMConstNull (type_to_llvm_type (ctx, sig->ret)));
1834 LLVMBuildRet (builder, convert (ctx, lhs, type_to_llvm_type (ctx, sig->ret)));
1836 has_terminator = TRUE;
1842 case OP_ICOMPARE_IMM:
1843 case OP_LCOMPARE_IMM:
1844 case OP_COMPARE_IMM:
1846 case OP_AMD64_ICOMPARE_MEMBASE_REG:
1847 case OP_AMD64_ICOMPARE_MEMBASE_IMM:
1850 case OP_X86_COMPARE_MEMBASE_REG:
1851 case OP_X86_COMPARE_MEMBASE_IMM:
1857 if (ins->next->opcode == OP_NOP)
1860 if (ins->next->opcode == OP_BR)
1861 /* The comparison result is not needed */
1864 rel = mono_opcode_to_cond (ins->next->opcode);
1866 /* Used for implementing bound checks */
1868 if ((ins->opcode == OP_AMD64_ICOMPARE_MEMBASE_REG) || (ins->opcode == OP_AMD64_ICOMPARE_MEMBASE_IMM)) {
1873 t = LLVMInt32Type ();
1875 g_assert (ins->inst_offset % size == 0);
1876 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
1878 lhs = LLVMBuildLoad (builder, LLVMBuildGEP (builder, convert (ctx, values [ins->inst_basereg], LLVMPointerType (t, 0)), &index, 1, ""), "");
1880 if (ins->opcode == OP_AMD64_ICOMPARE_MEMBASE_IMM) {
1881 lhs = convert (ctx, lhs, LLVMInt32Type ());
1882 rhs = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
1884 if (ins->opcode == OP_AMD64_ICOMPARE_MEMBASE_REG)
1885 rhs = convert (ctx, rhs, LLVMInt32Type ());
1889 if ((ins->opcode == OP_X86_COMPARE_MEMBASE_REG) || (ins->opcode == OP_X86_COMPARE_MEMBASE_IMM)) {
1894 t = LLVMInt32Type ();
1896 g_assert (ins->inst_offset % size == 0);
1897 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
1899 lhs = LLVMBuildLoad (builder, LLVMBuildGEP (builder, convert (ctx, values [ins->inst_basereg], LLVMPointerType (t, 0)), &index, 1, ""), "");
1901 if (ins->opcode == OP_X86_COMPARE_MEMBASE_IMM) {
1902 lhs = convert (ctx, lhs, LLVMInt32Type ());
1903 rhs = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
1905 if (ins->opcode == OP_X86_COMPARE_MEMBASE_REG)
1906 rhs = convert (ctx, rhs, LLVMInt32Type ());
1909 if (ins->opcode == OP_ICOMPARE_IMM) {
1910 lhs = convert (ctx, lhs, LLVMInt32Type ());
1911 rhs = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
1913 if (ins->opcode == OP_LCOMPARE_IMM) {
1914 lhs = convert (ctx, lhs, LLVMInt64Type ());
1915 rhs = LLVMConstInt (LLVMInt64Type (), GET_LONG_IMM (ins), FALSE);
1917 if (ins->opcode == OP_LCOMPARE) {
1918 lhs = convert (ctx, lhs, LLVMInt64Type ());
1919 rhs = convert (ctx, rhs, LLVMInt64Type ());
1921 if (ins->opcode == OP_ICOMPARE) {
1922 lhs = convert (ctx, lhs, LLVMInt32Type ());
1923 rhs = convert (ctx, rhs, LLVMInt32Type ());
1927 if (LLVMGetTypeKind (LLVMTypeOf (lhs)) == LLVMPointerTypeKind)
1928 rhs = convert (ctx, rhs, LLVMTypeOf (lhs));
1929 else if (LLVMGetTypeKind (LLVMTypeOf (rhs)) == LLVMPointerTypeKind)
1930 lhs = convert (ctx, lhs, LLVMTypeOf (rhs));
1933 /* We use COMPARE+SETcc/Bcc, llvm uses SETcc+br cond */
1934 if (ins->opcode == OP_FCOMPARE)
1935 cmp = LLVMBuildFCmp (builder, fpcond_to_llvm_cond [rel], convert (ctx, lhs, LLVMDoubleType ()), convert (ctx, rhs, LLVMDoubleType ()), "");
1936 else if (ins->opcode == OP_COMPARE_IMM)
1937 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE), "");
1938 else if (ins->opcode == OP_COMPARE)
1939 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, IntPtrType ()), convert (ctx, rhs, IntPtrType ()), "");
1941 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], lhs, rhs, "");
1943 if (MONO_IS_COND_BRANCH_OP (ins->next)) {
1944 LLVMBuildCondBr (builder, cmp, get_bb (ctx, ins->next->inst_true_bb), get_bb (ctx, ins->next->inst_false_bb));
1945 has_terminator = TRUE;
1946 } else if (MONO_IS_SETCC (ins->next)) {
1947 sprintf (dname_buf, "t%d", ins->next->dreg);
1949 values [ins->next->dreg] = LLVMBuildZExt (builder, cmp, LLVMInt32Type (), dname);
1951 /* Add stores for volatile variables */
1952 emit_volatile_store (ctx, ins->next->dreg);
1953 } else if (MONO_IS_COND_EXC (ins->next)) {
1954 //emit_cond_throw_pos (ctx);
1955 emit_cond_system_exception (ctx, bb, ins->next->inst_p1, cmp);
1956 builder = ctx->builder;
1958 LLVM_FAILURE (ctx, "next");
1972 rel = mono_opcode_to_cond (ins->opcode);
1974 cmp = LLVMBuildFCmp (builder, fpcond_to_llvm_cond [rel], convert (ctx, lhs, LLVMDoubleType ()), convert (ctx, rhs, LLVMDoubleType ()), "");
1975 values [ins->dreg] = LLVMBuildZExt (builder, cmp, LLVMInt32Type (), dname);
1983 gboolean empty = TRUE;
1985 /* Check that all input bblocks really branch to us */
1986 for (i = 0; i < bb->in_count; ++i) {
1987 if (bb->in_bb [i]->last_ins && bb->in_bb [i]->last_ins->opcode == OP_NOT_REACHED)
1988 ins->inst_phi_args [i + 1] = -1;
1994 /* LLVM doesn't like phi instructions with zero operands */
1995 is_dead [ins->dreg] = TRUE;
1999 /* Created earlier, insert it now */
2000 LLVMInsertIntoBuilder (builder, values [ins->dreg]);
2002 for (i = 0; i < ins->inst_phi_args [0]; i++) {
2003 int sreg1 = ins->inst_phi_args [i + 1];
2007 * Count the number of times the incoming bblock branches to us,
2008 * since llvm requires a separate entry for each.
2010 if (bb->in_bb [i]->last_ins && bb->in_bb [i]->last_ins->opcode == OP_SWITCH) {
2011 MonoInst *switch_ins = bb->in_bb [i]->last_ins;
2014 for (j = 0; j < GPOINTER_TO_UINT (switch_ins->klass); ++j) {
2015 if (switch_ins->inst_many_bb [j] == bb)
2022 /* Remember for later */
2023 for (j = 0; j < count; ++j) {
2024 PhiNode *node = mono_mempool_alloc0 (ctx->mempool, sizeof (PhiNode));
2027 node->in_bb = bb->in_bb [i];
2029 bblocks [bb->in_bb [i]->block_num].phi_nodes = g_slist_prepend_mempool (ctx->mempool, bblocks [bb->in_bb [i]->block_num].phi_nodes, node);
2038 values [ins->dreg] = lhs;
2041 MonoInst *var = get_vreg_to_inst (cfg, ins->dreg);
2044 values [ins->dreg] = lhs;
2046 if (var && var->klass->byval_arg.type == MONO_TYPE_R4) {
2048 * This is added by the spilling pass in case of the JIT,
2049 * but we have to do it ourselves.
2051 values [ins->dreg] = convert (ctx, values [ins->dreg], LLVMFloatType ());
2085 lhs = convert (ctx, lhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
2086 rhs = convert (ctx, rhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
2088 switch (ins->opcode) {
2092 values [ins->dreg] = LLVMBuildAdd (builder, lhs, rhs, dname);
2097 values [ins->dreg] = LLVMBuildSub (builder, lhs, rhs, dname);
2102 values [ins->dreg] = LLVMBuildMul (builder, lhs, rhs, dname);
2106 values [ins->dreg] = LLVMBuildSRem (builder, lhs, rhs, dname);
2110 values [ins->dreg] = LLVMBuildURem (builder, lhs, rhs, dname);
2114 values [ins->dreg] = LLVMBuildSDiv (builder, lhs, rhs, dname);
2118 values [ins->dreg] = LLVMBuildUDiv (builder, lhs, rhs, dname);
2121 values [ins->dreg] = LLVMBuildFDiv (builder, lhs, rhs, dname);
2125 values [ins->dreg] = LLVMBuildAnd (builder, lhs, rhs, dname);
2129 values [ins->dreg] = LLVMBuildOr (builder, lhs, rhs, dname);
2133 values [ins->dreg] = LLVMBuildXor (builder, lhs, rhs, dname);
2137 values [ins->dreg] = LLVMBuildShl (builder, lhs, rhs, dname);
2141 values [ins->dreg] = LLVMBuildAShr (builder, lhs, rhs, dname);
2145 values [ins->dreg] = LLVMBuildLShr (builder, lhs, rhs, dname);
2148 g_assert_not_reached ();
2155 case OP_IREM_UN_IMM:
2157 case OP_IDIV_UN_IMM:
2163 case OP_ISHR_UN_IMM:
2172 case OP_LSHR_UN_IMM:
2180 if (spec [MONO_INST_SRC1] == 'l') {
2181 imm = LLVMConstInt (LLVMInt64Type (), GET_LONG_IMM (ins), FALSE);
2183 imm = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
2186 #if SIZEOF_VOID_P == 4
2187 if (ins->opcode == OP_LSHL_IMM || ins->opcode == OP_LSHR_IMM || ins->opcode == OP_LSHR_UN_IMM)
2188 imm = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
2191 if (LLVMGetTypeKind (LLVMTypeOf (lhs)) == LLVMPointerTypeKind)
2192 lhs = convert (ctx, lhs, IntPtrType ());
2193 imm = convert (ctx, imm, LLVMTypeOf (lhs));
2194 switch (ins->opcode) {
2198 values [ins->dreg] = LLVMBuildAdd (builder, lhs, imm, dname);
2202 values [ins->dreg] = LLVMBuildSub (builder, lhs, imm, dname);
2206 values [ins->dreg] = LLVMBuildMul (builder, lhs, imm, dname);
2210 values [ins->dreg] = LLVMBuildSDiv (builder, lhs, imm, dname);
2212 case OP_IDIV_UN_IMM:
2213 case OP_LDIV_UN_IMM:
2214 values [ins->dreg] = LLVMBuildUDiv (builder, lhs, imm, dname);
2218 values [ins->dreg] = LLVMBuildSRem (builder, lhs, imm, dname);
2220 case OP_IREM_UN_IMM:
2221 values [ins->dreg] = LLVMBuildURem (builder, lhs, imm, dname);
2226 values [ins->dreg] = LLVMBuildAnd (builder, lhs, imm, dname);
2230 values [ins->dreg] = LLVMBuildOr (builder, lhs, imm, dname);
2234 values [ins->dreg] = LLVMBuildXor (builder, lhs, imm, dname);
2239 values [ins->dreg] = LLVMBuildShl (builder, lhs, imm, dname);
2244 values [ins->dreg] = LLVMBuildAShr (builder, lhs, imm, dname);
2246 case OP_ISHR_UN_IMM:
2247 /* This is used to implement conv.u4, so the lhs could be an i8 */
2248 lhs = convert (ctx, lhs, LLVMInt32Type ());
2249 imm = convert (ctx, imm, LLVMInt32Type ());
2250 values [ins->dreg] = LLVMBuildLShr (builder, lhs, imm, dname);
2252 case OP_LSHR_UN_IMM:
2253 values [ins->dreg] = LLVMBuildLShr (builder, lhs, imm, dname);
2256 g_assert_not_reached ();
2261 values [ins->dreg] = LLVMBuildSub (builder, LLVMConstInt (LLVMInt32Type (), 0, FALSE), convert (ctx, lhs, LLVMInt32Type ()), dname);
2264 values [ins->dreg] = LLVMBuildSub (builder, LLVMConstInt (LLVMInt64Type (), 0, FALSE), lhs, dname);
2267 lhs = convert (ctx, lhs, LLVMDoubleType ());
2268 values [ins->dreg] = LLVMBuildSub (builder, LLVMConstReal (LLVMDoubleType (), 0.0), lhs, dname);
2271 guint32 v = 0xffffffff;
2272 values [ins->dreg] = LLVMBuildXor (builder, LLVMConstInt (LLVMInt32Type (), v, FALSE), lhs, dname);
2276 guint64 v = 0xffffffffffffffffLL;
2277 values [ins->dreg] = LLVMBuildXor (builder, LLVMConstInt (LLVMInt64Type (), v, FALSE), lhs, dname);
2280 #if defined(TARGET_X86) || defined(TARGET_AMD64)
2282 LLVMValueRef v1, v2;
2284 v1 = LLVMBuildMul (builder, convert (ctx, rhs, IntPtrType ()), LLVMConstInt (IntPtrType (), (1 << ins->backend.shift_amount), FALSE), "");
2285 v2 = LLVMBuildAdd (builder, convert (ctx, lhs, IntPtrType ()), v1, "");
2286 values [ins->dreg] = LLVMBuildAdd (builder, v2, LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE), dname);
2291 case OP_ICONV_TO_I1:
2292 case OP_ICONV_TO_I2:
2293 case OP_ICONV_TO_I4:
2294 case OP_ICONV_TO_U1:
2295 case OP_ICONV_TO_U2:
2296 case OP_ICONV_TO_U4:
2297 case OP_LCONV_TO_I1:
2298 case OP_LCONV_TO_I2:
2299 case OP_LCONV_TO_U1:
2300 case OP_LCONV_TO_U2:
2301 case OP_LCONV_TO_U4: {
2304 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);
2306 /* Have to do two casts since our vregs have type int */
2307 v = LLVMBuildTrunc (builder, lhs, op_to_llvm_type (ins->opcode), "");
2309 values [ins->dreg] = LLVMBuildSExt (builder, v, LLVMInt32Type (), dname);
2311 values [ins->dreg] = LLVMBuildZExt (builder, v, LLVMInt32Type (), dname);
2314 case OP_ICONV_TO_I8:
2315 values [ins->dreg] = LLVMBuildSExt (builder, lhs, LLVMInt64Type (), dname);
2317 case OP_ICONV_TO_U8:
2318 values [ins->dreg] = LLVMBuildZExt (builder, lhs, LLVMInt64Type (), dname);
2320 case OP_FCONV_TO_I4:
2321 values [ins->dreg] = LLVMBuildFPToSI (builder, lhs, LLVMInt32Type (), dname);
2323 case OP_FCONV_TO_I1:
2324 values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildFPToSI (builder, lhs, LLVMInt8Type (), dname), LLVMInt32Type (), "");
2326 case OP_FCONV_TO_U1:
2327 values [ins->dreg] = LLVMBuildZExt (builder, LLVMBuildFPToUI (builder, lhs, LLVMInt8Type (), dname), LLVMInt32Type (), "");
2329 case OP_FCONV_TO_I2:
2330 values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildFPToSI (builder, lhs, LLVMInt16Type (), dname), LLVMInt32Type (), "");
2332 case OP_FCONV_TO_U2:
2333 values [ins->dreg] = LLVMBuildZExt (builder, LLVMBuildFPToUI (builder, lhs, LLVMInt16Type (), dname), LLVMInt32Type (), "");
2335 case OP_FCONV_TO_I8:
2336 values [ins->dreg] = LLVMBuildFPToSI (builder, lhs, LLVMInt64Type (), dname);
2339 values [ins->dreg] = LLVMBuildFPToSI (builder, lhs, IntPtrType (), dname);
2341 case OP_ICONV_TO_R8:
2342 case OP_LCONV_TO_R8:
2343 values [ins->dreg] = LLVMBuildSIToFP (builder, lhs, LLVMDoubleType (), dname);
2345 case OP_LCONV_TO_R_UN:
2346 values [ins->dreg] = LLVMBuildUIToFP (builder, lhs, LLVMDoubleType (), dname);
2348 #if SIZEOF_VOID_P == 4
2351 case OP_LCONV_TO_I4:
2352 values [ins->dreg] = LLVMBuildTrunc (builder, lhs, LLVMInt32Type (), dname);
2354 case OP_ICONV_TO_R4:
2355 case OP_LCONV_TO_R4:
2356 v = LLVMBuildSIToFP (builder, lhs, LLVMFloatType (), "");
2357 values [ins->dreg] = LLVMBuildFPExt (builder, v, LLVMDoubleType (), dname);
2359 case OP_FCONV_TO_R4:
2360 v = LLVMBuildFPTrunc (builder, lhs, LLVMFloatType (), "");
2361 values [ins->dreg] = LLVMBuildFPExt (builder, v, LLVMDoubleType (), dname);
2364 values [ins->dreg] = LLVMBuildSExt (builder, lhs, LLVMInt64Type (), dname);
2367 values [ins->dreg] = LLVMBuildZExt (builder, lhs, LLVMInt64Type (), dname);
2370 values [ins->dreg] = LLVMBuildTrunc (builder, lhs, LLVMInt32Type (), dname);
2372 case OP_LOCALLOC_IMM: {
2375 guint32 size = ins->inst_imm;
2376 size = (size + (MONO_ARCH_FRAME_ALIGNMENT - 1)) & ~ (MONO_ARCH_FRAME_ALIGNMENT - 1);
2378 v = mono_llvm_build_alloca (builder, LLVMInt8Type (), LLVMConstInt (LLVMInt32Type (), size, FALSE), MONO_ARCH_FRAME_ALIGNMENT, "");
2380 if (ins->flags & MONO_INST_INIT) {
2381 LLVMValueRef args [4];
2384 args [1] = LLVMConstInt (LLVMInt8Type (), 0, FALSE);
2385 args [2] = LLVMConstInt (LLVMInt32Type (), size, FALSE);
2386 args [3] = LLVMConstInt (LLVMInt32Type (), MONO_ARCH_FRAME_ALIGNMENT, FALSE);
2387 LLVMBuildCall (builder, LLVMGetNamedFunction (module, "llvm.memset.i32"), args, 4, "");
2390 values [ins->dreg] = v;
2394 LLVMValueRef v, size;
2396 size = LLVMBuildAnd (builder, LLVMBuildAdd (builder, lhs, LLVMConstInt (LLVMInt32Type (), MONO_ARCH_FRAME_ALIGNMENT - 1, FALSE), ""), LLVMConstInt (LLVMInt32Type (), ~ (MONO_ARCH_FRAME_ALIGNMENT - 1), FALSE), "");
2398 v = mono_llvm_build_alloca (builder, LLVMInt8Type (), size, MONO_ARCH_FRAME_ALIGNMENT, "");
2400 if (ins->flags & MONO_INST_INIT) {
2401 LLVMValueRef args [4];
2404 args [1] = LLVMConstInt (LLVMInt8Type (), 0, FALSE);
2406 args [3] = LLVMConstInt (LLVMInt32Type (), MONO_ARCH_FRAME_ALIGNMENT, FALSE);
2407 LLVMBuildCall (builder, LLVMGetNamedFunction (module, "llvm.memset.i32"), args, 4, "");
2409 values [ins->dreg] = v;
2413 case OP_LOADI1_MEMBASE:
2414 case OP_LOADU1_MEMBASE:
2415 case OP_LOADI2_MEMBASE:
2416 case OP_LOADU2_MEMBASE:
2417 case OP_LOADI4_MEMBASE:
2418 case OP_LOADU4_MEMBASE:
2419 case OP_LOADI8_MEMBASE:
2420 case OP_LOADR4_MEMBASE:
2421 case OP_LOADR8_MEMBASE:
2422 case OP_LOAD_MEMBASE:
2430 LLVMValueRef index, addr;
2432 gboolean sext = FALSE, zext = FALSE;
2433 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
2435 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
2441 * We emit volatile loads for loads which can fault, because otherwise
2442 * LLVM will generate invalid code when encountering a load from a
2445 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)) {
2446 addr = LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE);
2447 } else if (ins->inst_offset == 0) {
2448 addr = values [ins->inst_basereg];
2449 } else if (ins->inst_offset % size != 0) {
2450 /* Unaligned load */
2451 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset, FALSE);
2452 addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_basereg], LLVMPointerType (LLVMInt8Type (), 0)), &index, 1, "");
2454 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
2455 addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_basereg], LLVMPointerType (t, 0)), &index, 1, "");
2458 addr = convert (ctx, addr, LLVMPointerType (t, 0));
2460 values [ins->dreg] = mono_llvm_build_load (builder, addr, dname, is_volatile);
2463 values [ins->dreg] = LLVMBuildSExt (builder, values [ins->dreg], LLVMInt32Type (), dname);
2465 values [ins->dreg] = LLVMBuildZExt (builder, values [ins->dreg], LLVMInt32Type (), dname);
2466 else if (ins->opcode == OP_LOADR4_MEMBASE)
2467 values [ins->dreg] = LLVMBuildFPExt (builder, values [ins->dreg], LLVMDoubleType (), dname);
2471 case OP_STOREI1_MEMBASE_REG:
2472 case OP_STOREI2_MEMBASE_REG:
2473 case OP_STOREI4_MEMBASE_REG:
2474 case OP_STOREI8_MEMBASE_REG:
2475 case OP_STORER4_MEMBASE_REG:
2476 case OP_STORER8_MEMBASE_REG:
2477 case OP_STORE_MEMBASE_REG: {
2479 LLVMValueRef index, addr;
2481 gboolean sext = FALSE, zext = FALSE;
2483 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
2485 if (ins->inst_offset % size != 0) {
2486 /* Unaligned store */
2487 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset, FALSE);
2488 addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (LLVMInt8Type (), 0)), &index, 1, "");
2490 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
2491 addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (t, 0)), &index, 1, "");
2493 LLVMBuildStore (builder, convert (ctx, values [ins->sreg1], t), convert (ctx, addr, LLVMPointerType (t, 0)));
2497 case OP_STOREI1_MEMBASE_IMM:
2498 case OP_STOREI2_MEMBASE_IMM:
2499 case OP_STOREI4_MEMBASE_IMM:
2500 case OP_STOREI8_MEMBASE_IMM:
2501 case OP_STORE_MEMBASE_IMM: {
2503 LLVMValueRef index, addr;
2505 gboolean sext = FALSE, zext = FALSE;
2507 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
2509 if (ins->inst_offset % size != 0) {
2510 /* Unaligned store */
2511 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset, FALSE);
2512 addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (LLVMInt8Type (), 0)), &index, 1, "");
2514 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
2515 addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (t, 0)), &index, 1, "");
2517 LLVMBuildStore (builder, convert (ctx, LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE), t), addr);
2522 mono_llvm_build_load (builder, convert (ctx, values [ins->sreg1], LLVMPointerType (IntPtrType (), 0)), "", TRUE);
2524 case OP_OUTARG_VTRETADDR:
2531 case OP_VOIDCALL_MEMBASE:
2532 case OP_CALL_MEMBASE:
2533 case OP_LCALL_MEMBASE:
2534 case OP_FCALL_MEMBASE:
2535 case OP_VCALL_MEMBASE:
2536 case OP_VOIDCALL_REG:
2540 case OP_VCALL_REG: {
2541 MonoCallInst *call = (MonoCallInst*)ins;
2542 MonoMethodSignature *sig = call->signature;
2543 LLVMValueRef callee, lcall;
2545 LLVMCallInfo *cinfo;
2549 LLVMTypeRef llvm_sig;
2552 gboolean virtual, calli;
2554 cinfo = call->cinfo;
2556 vretaddr = cinfo && cinfo->ret.storage == LLVMArgVtypeRetAddr;
2558 llvm_sig = sig_to_llvm_sig (ctx, sig, cinfo);
2559 CHECK_FAILURE (ctx);
2561 virtual = (ins->opcode == OP_VOIDCALL_MEMBASE || ins->opcode == OP_CALL_MEMBASE || ins->opcode == OP_VCALL_MEMBASE || ins->opcode == OP_LCALL_MEMBASE || ins->opcode == OP_FCALL_MEMBASE);
2562 calli = (ins->opcode == OP_VOIDCALL_REG || ins->opcode == OP_CALL_REG || ins->opcode == OP_VCALL_REG || ins->opcode == OP_LCALL_REG || ins->opcode == OP_FCALL_REG);
2564 pindexes = mono_mempool_alloc0 (cfg->mempool, (sig->param_count + 2) * sizeof (guint32));
2566 /* FIXME: Avoid creating duplicate methods */
2568 if (ins->flags & MONO_INST_HAS_METHOD) {
2572 if (cfg->compile_aot) {
2573 callee = get_plt_entry (ctx, llvm_sig, MONO_PATCH_INFO_METHOD, call->method);
2575 LLVM_FAILURE (ctx, "can't encode patch");
2577 callee = LLVMAddFunction (module, "", llvm_sig);
2580 mono_create_jit_trampoline_in_domain (mono_domain_get (),
2582 LLVMAddGlobalMapping (ee, callee, target);
2587 MonoJitICallInfo *info = mono_find_jit_icall_by_addr (call->fptr);
2593 memset (&ji, 0, sizeof (ji));
2594 ji.type = MONO_PATCH_INFO_JIT_ICALL_ADDR;
2595 ji.data.target = info->name;
2597 target = mono_resolve_patch_target (cfg->method, cfg->domain, NULL, &ji, FALSE);
2599 if (cfg->compile_aot) {
2600 callee = get_plt_entry (ctx, llvm_sig, MONO_PATCH_INFO_INTERNAL_METHOD, (char*)info->name);
2602 LLVM_FAILURE (ctx, "can't encode patch");
2604 callee = LLVMAddFunction (module, "", llvm_sig);
2605 target = (gpointer)mono_icall_get_wrapper (info);
2606 LLVMAddGlobalMapping (ee, callee, target);
2609 if (cfg->compile_aot) {
2611 if (cfg->abs_patches) {
2612 MonoJumpInfo *abs_ji = g_hash_table_lookup (cfg->abs_patches, call->fptr);
2614 callee = get_plt_entry (ctx, llvm_sig, abs_ji->type, abs_ji->data.target);
2616 LLVM_FAILURE (ctx, "can't encode patch");
2620 LLVM_FAILURE (ctx, "aot");
2622 callee = LLVMAddFunction (module, "", llvm_sig);
2624 if (cfg->abs_patches) {
2625 MonoJumpInfo *abs_ji = g_hash_table_lookup (cfg->abs_patches, call->fptr);
2628 * The monitor entry/exit trampolines might have
2629 * their own calling convention on some platforms.
2631 #ifndef TARGET_AMD64
2632 if (abs_ji->type == MONO_PATCH_INFO_MONITOR_ENTER || abs_ji->type == MONO_PATCH_INFO_MONITOR_EXIT)
2633 LLVM_FAILURE (ctx, "monitor enter/exit");
2635 target = mono_resolve_patch_target (cfg->method, cfg->domain, NULL, abs_ji, FALSE);
2636 LLVMAddGlobalMapping (ee, callee, target);
2640 LLVMAddGlobalMapping (ee, callee, (gpointer)call->fptr);
2646 int size = sizeof (gpointer);
2649 g_assert (ins->inst_offset % size == 0);
2650 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
2652 // FIXME: mono_arch_get_vcall_slot () can't decode the code
2653 // generated by LLVM
2654 //LLVM_FAILURE (ctx, "virtual call");
2656 if (call->method && call->method->klass->flags & TYPE_ATTRIBUTE_INTERFACE) {
2657 #ifdef MONO_ARCH_HAVE_LLVM_IMT_TRAMPOLINE
2658 if (cfg->compile_aot) {
2659 MonoJumpInfoImtTramp *imt_tramp = g_new0 (MonoJumpInfoImtTramp, 1);
2660 imt_tramp->method = call->method;
2661 imt_tramp->vt_offset = call->inst.inst_offset;
2663 callee = get_plt_entry (ctx, llvm_sig, MONO_PATCH_INFO_LLVM_IMT_TRAMPOLINE, imt_tramp);
2665 callee = LLVMAddFunction (module, "", llvm_sig);
2666 target = mono_create_llvm_imt_trampoline (cfg->domain, call->method, call->inst.inst_offset);
2667 LLVMAddGlobalMapping (ee, callee, target);
2670 /* No support for passing the IMT argument */
2671 LLVM_FAILURE (ctx, "imt");
2674 callee = convert (ctx, LLVMBuildLoad (builder, LLVMBuildGEP (builder, convert (ctx, values [ins->inst_basereg], LLVMPointerType (LLVMPointerType (IntPtrType (), 0), 0)), &index, 1, ""), ""), LLVMPointerType (llvm_sig, 0));
2677 callee = convert (ctx, values [ins->sreg1], LLVMPointerType (llvm_sig, 0));
2679 if (ins->flags & MONO_INST_HAS_METHOD) {
2684 * Collect and convert arguments
2687 args = alloca (sizeof (LLVMValueRef) * ((sig->param_count * 2) + sig->hasthis + vretaddr));
2688 l = call->out_ireg_args;
2691 if (!addresses [call->inst.dreg])
2692 addresses [call->inst.dreg] = build_alloca (ctx, sig->ret);
2693 args [pindex ++] = LLVMBuildPtrToInt (builder, addresses [call->inst.dreg], IntPtrType (), "");
2696 for (i = 0; i < sig->param_count + sig->hasthis; ++i) {
2699 LLVMArgInfo *ainfo = call->cinfo ? &call->cinfo->args [i] : NULL;
2701 regpair = (guint32)(gssize)(l->data);
2702 reg = regpair & 0xffffff;
2703 args [pindex] = values [reg];
2704 if (ainfo->storage == LLVMArgVtypeInReg) {
2706 LLVMValueRef regs [2];
2711 g_assert (addresses [reg]);
2713 emit_vtype_to_reg (ctx, builder, sig->params [i - sig->hasthis], addresses [reg], ainfo, regs, &nregs);
2714 for (j = 0; j < nregs; ++j)
2715 args [pindex ++] = regs [j];
2718 // FIXME: Get rid of the VMOVE
2719 } else if (ainfo->storage == LLVMArgVtypeByVal) {
2720 g_assert (addresses [reg]);
2721 args [pindex] = addresses [reg];
2722 pindexes [i] = pindex;
2725 g_assert (args [pindex]);
2726 if (i == 0 && sig->hasthis)
2727 args [pindex] = convert (ctx, args [pindex], IntPtrType ());
2729 args [pindex] = convert (ctx, args [pindex], type_to_llvm_arg_type (ctx, sig->params [i - sig->hasthis]));
2736 // FIXME: Align call sites
2742 lcall = emit_call (ctx, bb, &builder, callee, args, pindex);
2744 /* Add byval attributes if needed */
2745 for (i = 0; i < sig->param_count + sig->hasthis; ++i) {
2746 LLVMArgInfo *ainfo = call->cinfo ? &call->cinfo->args [i] : NULL;
2748 if (ainfo && ainfo->storage == LLVMArgVtypeByVal) {
2749 LLVMAddInstrAttribute (lcall, pindexes [i] + 1, LLVMByValAttribute);
2754 * Convert the result
2756 if (cinfo && cinfo->ret.storage == LLVMArgVtypeInReg) {
2757 LLVMValueRef regs [2];
2759 if (!addresses [ins->dreg])
2760 addresses [ins->dreg] = build_alloca (ctx, sig->ret);
2762 regs [0] = LLVMBuildExtractValue (builder, lcall, 0, "");
2763 if (cinfo->ret.pair_storage [1] != LLVMArgNone)
2764 regs [1] = LLVMBuildExtractValue (builder, lcall, 1, "");
2766 emit_reg_to_vtype (ctx, builder, sig->ret, addresses [ins->dreg], &cinfo->ret, regs);
2767 } else if (sig->ret->type != MONO_TYPE_VOID && !vretaddr) {
2768 /* If the method returns an unsigned value, need to zext it */
2770 values [ins->dreg] = convert_full (ctx, lcall, llvm_type_to_stack_type (type_to_llvm_type (ctx, sig->ret)), type_is_unsigned (ctx, sig->ret));
2776 LLVMValueRef indexes [2];
2778 LLVMValueRef got_entry_addr;
2781 * FIXME: Can't allocate from the cfg mempool since that is freed if
2782 * the LLVM compile fails.
2784 ji = g_new0 (MonoJumpInfo, 1);
2785 ji->type = (MonoJumpInfoType)ins->inst_i1;
2786 ji->data.target = ins->inst_p0;
2788 ji = mono_aot_patch_info_dup (ji);
2790 ji->next = cfg->patch_info;
2791 cfg->patch_info = ji;
2793 //mono_add_patch_info (cfg, 0, (MonoJumpInfoType)ins->inst_i1, ins->inst_p0);
2794 got_offset = mono_aot_get_got_offset (cfg->patch_info);
2796 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
2797 indexes [1] = LLVMConstInt (LLVMInt32Type (), (gssize)got_offset, FALSE);
2798 got_entry_addr = LLVMBuildGEP (builder, ctx->lmodule->got_var, indexes, 2, "");
2800 // FIXME: This doesn't work right now, because it must be
2801 // paired with an invariant.end, and even then, its only in effect
2802 // inside its basic block
2805 LLVMValueRef args [3];
2806 LLVMValueRef ptr, val;
2808 ptr = LLVMBuildBitCast (builder, got_entry_addr, LLVMPointerType (LLVMInt8Type (), 0), "ptr");
2810 args [0] = LLVMConstInt (LLVMInt64Type (), sizeof (gpointer), FALSE);
2812 val = LLVMBuildCall (builder, LLVMGetNamedFunction (module, "llvm.invariant.start"), args, 2, "");
2816 values [ins->dreg] = LLVMBuildLoad (builder, got_entry_addr, dname);
2819 case OP_NOT_REACHED:
2820 LLVMBuildUnreachable (builder);
2821 has_terminator = TRUE;
2822 g_assert (bb->block_num < cfg->max_block_num);
2823 unreachable [bb->block_num] = TRUE;
2824 /* Might have instructions after this */
2826 MonoInst *next = ins->next;
2827 MONO_DELETE_INS (bb, next);
2831 MonoInst *var = ins->inst_p0;
2833 values [ins->dreg] = addresses [var->dreg];
2837 LLVMValueRef args [1];
2839 args [0] = convert (ctx, lhs, LLVMDoubleType ());
2840 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, "llvm.sin.f64"), args, 1, dname);
2844 LLVMValueRef args [1];
2846 args [0] = convert (ctx, lhs, LLVMDoubleType ());
2847 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, "llvm.cos.f64"), args, 1, dname);
2850 /* test_0_sqrt_nan fails with LLVM */
2853 LLVMValueRef args [1];
2856 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, "llvm.sqrt.f64"), args, 1, dname);
2862 LLVMValueRef args [1];
2865 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, "fabs"), args, 1, dname);
2871 LLVMValueRef v = LLVMBuildICmp (builder, LLVMIntSLE, lhs, rhs, "");
2872 values [ins->dreg] = LLVMBuildSelect (builder, v, lhs, rhs, dname);
2877 LLVMValueRef v = LLVMBuildICmp (builder, LLVMIntSGE, lhs, rhs, "");
2878 values [ins->dreg] = LLVMBuildSelect (builder, v, lhs, rhs, dname);
2883 LLVMValueRef v = LLVMBuildICmp (builder, LLVMIntULE, lhs, rhs, "");
2884 values [ins->dreg] = LLVMBuildSelect (builder, v, lhs, rhs, dname);
2889 LLVMValueRef v = LLVMBuildICmp (builder, LLVMIntUGE, lhs, rhs, "");
2890 values [ins->dreg] = LLVMBuildSelect (builder, v, lhs, rhs, dname);
2893 case OP_ATOMIC_EXCHANGE_I4: {
2894 LLVMValueRef args [2];
2896 g_assert (ins->inst_offset == 0);
2898 args [0] = convert (ctx, lhs, LLVMPointerType (LLVMInt32Type (), 0));
2900 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, "llvm.atomic.swap.i32.p0i32"), args, 2, dname);
2903 case OP_ATOMIC_EXCHANGE_I8: {
2904 LLVMValueRef args [2];
2906 g_assert (ins->inst_offset == 0);
2908 args [0] = convert (ctx, lhs, LLVMPointerType (LLVMInt64Type (), 0));
2910 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, "llvm.atomic.swap.i64.p0i64"), args, 2, dname);
2913 case OP_ATOMIC_ADD_NEW_I4: {
2914 LLVMValueRef args [2];
2916 g_assert (ins->inst_offset == 0);
2918 args [0] = convert (ctx, lhs, LLVMPointerType (LLVMInt32Type (), 0));
2920 values [ins->dreg] = LLVMBuildAdd (builder, LLVMBuildCall (builder, LLVMGetNamedFunction (module, "llvm.atomic.load.add.i32.p0i32"), args, 2, ""), args [1], dname);
2923 case OP_ATOMIC_ADD_NEW_I8: {
2924 LLVMValueRef args [2];
2926 g_assert (ins->inst_offset == 0);
2928 args [0] = convert (ctx, lhs, LLVMPointerType (LLVMInt64Type (), 0));
2929 args [1] = convert (ctx, rhs, LLVMInt64Type ());
2930 values [ins->dreg] = LLVMBuildAdd (builder, LLVMBuildCall (builder, LLVMGetNamedFunction (module, "llvm.atomic.load.add.i64.p0i64"), args, 2, ""), args [1], dname);
2933 case OP_ATOMIC_CAS_I4:
2934 case OP_ATOMIC_CAS_I8: {
2935 LLVMValueRef args [3];
2937 const char *intrins;
2939 if (ins->opcode == OP_ATOMIC_CAS_I4) {
2940 t = LLVMInt32Type ();
2941 intrins = "llvm.atomic.cmp.swap.i32.p0i32";
2943 t = LLVMInt64Type ();
2944 intrins = "llvm.atomic.cmp.swap.i64.p0i64";
2947 args [0] = convert (ctx, lhs, LLVMPointerType (t, 0));
2949 args [1] = convert (ctx, values [ins->sreg3], t);
2951 args [2] = convert (ctx, values [ins->sreg2], t);
2952 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, intrins), args, 3, dname);
2955 case OP_MEMORY_BARRIER: {
2956 LLVMValueRef args [5];
2958 for (i = 0; i < 5; ++i)
2959 args [i] = LLVMConstInt (LLVMInt1Type (), TRUE, TRUE);
2961 LLVMBuildCall (builder, LLVMGetNamedFunction (module, "llvm.memory.barrier"), args, 5, "");
2964 case OP_RELAXED_NOP: {
2965 #if defined(TARGET_AMD64) || defined(TARGET_X86)
2966 /* No way to get LLVM to emit this */
2967 LLVM_FAILURE (ctx, "relaxed_nop");
2973 #if defined(TARGET_AMD64) || defined(TARGET_X86)
2975 // 257 == FS segment register
2976 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 257);
2978 // 256 == GS segment register
2979 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 256);
2983 values [ins->dreg] = LLVMBuildLoad (builder, LLVMBuildIntToPtr (builder, LLVMConstInt (IntPtrType (), ins->inst_offset, TRUE), ptrtype, ""), "");
2985 LLVM_FAILURE (ctx, "opcode tls-get");
2995 case OP_IADD_OVF_UN:
2997 case OP_ISUB_OVF_UN:
2999 case OP_IMUL_OVF_UN:
3000 #if SIZEOF_VOID_P == 8
3002 case OP_LADD_OVF_UN:
3004 case OP_LSUB_OVF_UN:
3006 case OP_LMUL_OVF_UN:
3009 LLVMValueRef args [2], val, ovf, func;
3011 emit_cond_throw_pos (ctx);
3013 args [0] = convert (ctx, lhs, op_to_llvm_type (ins->opcode));
3014 args [1] = convert (ctx, rhs, op_to_llvm_type (ins->opcode));
3015 func = LLVMGetNamedFunction (module, ovf_op_to_intrins (ins->opcode));
3017 val = LLVMBuildCall (builder, func, args, 2, "");
3018 values [ins->dreg] = LLVMBuildExtractValue (builder, val, 0, dname);
3019 ovf = LLVMBuildExtractValue (builder, val, 1, "");
3020 emit_cond_system_exception (ctx, bb, "OverflowException", ovf);
3021 builder = ctx->builder;
3027 * We currently model them using arrays. Promotion to local vregs is
3028 * disabled for them in mono_handle_global_vregs () in the LLVM case,
3029 * so we always have an entry in cfg->varinfo for them.
3030 * FIXME: Is this needed ?
3033 MonoClass *klass = ins->klass;
3034 LLVMValueRef args [4];
3038 LLVM_FAILURE (ctx, "!klass");
3042 if (!addresses [ins->dreg])
3043 addresses [ins->dreg] = build_alloca (ctx, &klass->byval_arg);
3044 args [0] = LLVMBuildBitCast (builder, addresses [ins->dreg], LLVMPointerType (LLVMInt8Type (), 0), "");
3045 args [1] = LLVMConstInt (LLVMInt8Type (), 0, FALSE);
3046 args [2] = LLVMConstInt (LLVMInt32Type (), mono_class_value_size (klass, NULL), FALSE);
3048 args [3] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
3049 LLVMBuildCall (builder, LLVMGetNamedFunction (module, "llvm.memset.i32"), args, 4, "");
3053 case OP_STOREV_MEMBASE:
3054 case OP_LOADV_MEMBASE:
3056 MonoClass *klass = ins->klass;
3057 LLVMValueRef src, dst, args [4];
3058 gboolean done = FALSE;
3062 LLVM_FAILURE (ctx, "!klass");
3066 switch (ins->opcode) {
3067 case OP_STOREV_MEMBASE:
3068 if (!addresses [ins->sreg1]) {
3070 g_assert (values [ins->sreg1]);
3071 dst = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_destbasereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (type_to_llvm_type (ctx, &klass->byval_arg), 0));
3072 LLVMBuildStore (builder, values [ins->sreg1], dst);
3075 src = LLVMBuildBitCast (builder, addresses [ins->sreg1], LLVMPointerType (LLVMInt8Type (), 0), "");
3076 dst = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_destbasereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (LLVMInt8Type (), 0));
3079 case OP_LOADV_MEMBASE:
3080 if (!addresses [ins->dreg])
3081 addresses [ins->dreg] = build_alloca (ctx, &klass->byval_arg);
3082 src = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_basereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (LLVMInt8Type (), 0));
3083 dst = LLVMBuildBitCast (builder, addresses [ins->dreg], LLVMPointerType (LLVMInt8Type (), 0), "");
3086 if (!addresses [ins->sreg1])
3087 addresses [ins->sreg1] = build_alloca (ctx, &klass->byval_arg);
3088 if (!addresses [ins->dreg])
3089 addresses [ins->dreg] = build_alloca (ctx, &klass->byval_arg);
3090 src = LLVMBuildBitCast (builder, addresses [ins->sreg1], LLVMPointerType (LLVMInt8Type (), 0), "");
3091 dst = LLVMBuildBitCast (builder, addresses [ins->dreg], LLVMPointerType (LLVMInt8Type (), 0), "");
3094 g_assert_not_reached ();
3102 args [2] = LLVMConstInt (LLVMInt32Type (), mono_class_value_size (klass, NULL), FALSE);
3103 args [3] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
3105 args [3] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
3106 LLVMBuildCall (builder, LLVMGetNamedFunction (module, "llvm.memcpy.i32"), args, 4, "");
3109 case OP_LLVM_OUTARG_VT:
3110 if (!addresses [ins->sreg1]) {
3111 addresses [ins->sreg1] = build_alloca (ctx, &ins->klass->byval_arg);
3112 g_assert (values [ins->sreg1]);
3113 LLVMBuildStore (builder, values [ins->sreg1], addresses [ins->sreg1]);
3115 addresses [ins->dreg] = addresses [ins->sreg1];
3121 #if defined(TARGET_X86) || defined(TARGET_AMD64)
3123 values [ins->dreg] = LLVMConstNull (type_to_llvm_type (ctx, &ins->klass->byval_arg));
3126 case OP_LOADX_MEMBASE: {
3127 LLVMTypeRef t = type_to_llvm_type (ctx, &ins->klass->byval_arg);
3130 src = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_basereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (t, 0));
3131 values [ins->dreg] = LLVMBuildLoad (builder, src, "");
3140 values [ins->dreg] = LLVMBuildAdd (builder, lhs, rhs, "");
3148 values [ins->dreg] = LLVMBuildSub (builder, lhs, rhs, "");
3152 values [ins->dreg] = LLVMBuildMul (builder, lhs, rhs, "");
3156 values [ins->dreg] = LLVMBuildFDiv (builder, lhs, rhs, "");
3159 values [ins->dreg] = LLVMBuildAnd (builder, lhs, rhs, "");
3162 values [ins->dreg] = LLVMBuildOr (builder, lhs, rhs, "");
3165 values [ins->dreg] = LLVMBuildXor (builder, lhs, rhs, "");
3178 switch (ins->opcode) {
3183 t = LLVMVectorType (LLVMInt32Type (), 4);
3184 rt = LLVMVectorType (LLVMFloatType (), 4);
3190 t = LLVMVectorType (LLVMInt64Type (), 2);
3191 rt = LLVMVectorType (LLVMDoubleType (), 2);
3194 t = LLVMInt32Type ();
3195 rt = LLVMInt32Type ();
3196 g_assert_not_reached ();
3199 lhs = LLVMBuildBitCast (builder, lhs, t, "");
3200 rhs = LLVMBuildBitCast (builder, rhs, t, "");
3201 switch (ins->opcode) {
3204 v = LLVMBuildAnd (builder, lhs, rhs, "");
3208 v = LLVMBuildOr (builder, lhs, rhs, "");
3212 v = LLVMBuildXor (builder, lhs, rhs, "");
3216 v = LLVMBuildAnd (builder, lhs, LLVMBuildNot (builder, rhs, ""), "");
3219 values [ins->dreg] = LLVMBuildBitCast (builder, v, rt, "");
3232 LLVMValueRef args [2];
3237 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, simd_op_to_intrins (ins->opcode)), args, 2, dname);
3246 case OP_EXTRACT_U1: {
3249 switch (ins->opcode) {
3251 t = LLVMVectorType (LLVMDoubleType (), 2);
3254 t = LLVMVectorType (LLVMInt64Type (), 2);
3257 t = LLVMVectorType (LLVMInt32Type (), 4);
3261 t = LLVMVectorType (LLVMInt16Type (), 8);
3265 t = LLVMVectorType (LLVMInt8Type (), 16);
3268 t = LLVMInt32Type ();
3269 g_assert_not_reached ();
3272 lhs = LLVMBuildBitCast (builder, lhs, t, "");
3273 values [ins->dreg] = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), "");
3282 * EXCEPTION HANDLING
3284 case OP_IMPLICIT_EXCEPTION:
3285 /* This marks a place where an implicit exception can happen */
3286 if (bb->region != -1)
3287 LLVM_FAILURE (ctx, "implicit-exception");
3290 MonoMethodSignature *throw_sig;
3291 LLVMValueRef callee, arg;
3293 if (!ctx->lmodule->throw) {
3294 throw_sig = mono_metadata_signature_alloc (mono_defaults.corlib, 1);
3295 throw_sig->ret = &mono_defaults.void_class->byval_arg;
3296 throw_sig->params [0] = &mono_defaults.object_class->byval_arg;
3297 if (cfg->compile_aot) {
3298 callee = get_plt_entry (ctx, sig_to_llvm_sig (ctx, throw_sig, NULL), MONO_PATCH_INFO_INTERNAL_METHOD, "mono_arch_throw_exception");
3300 callee = LLVMAddFunction (module, "mono_arch_throw_exception", sig_to_llvm_sig (ctx, throw_sig, NULL));
3304 * LLVM doesn't push the exception argument, so we need a different
3307 LLVMAddGlobalMapping (ee, callee, resolve_patch (cfg, MONO_PATCH_INFO_INTERNAL_METHOD, "mono_arch_llvm_throw_exception"));
3309 LLVMAddGlobalMapping (ee, callee, resolve_patch (cfg, MONO_PATCH_INFO_INTERNAL_METHOD, "mono_arch_throw_exception"));
3313 mono_memory_barrier ();
3314 ctx->lmodule->throw = callee;
3316 arg = convert (ctx, values [ins->sreg1], type_to_llvm_type (ctx, &mono_defaults.object_class->byval_arg));
3317 emit_call (ctx, bb, &builder, ctx->lmodule->throw, &arg, 1);
3320 case OP_CALL_HANDLER: {
3322 * We don't 'call' handlers, but instead simply branch to them.
3323 * The code generated by ENDFINALLY will branch back to us.
3325 LLVMBasicBlockRef finally_bb, noex_bb;
3328 finally_bb = get_bb (ctx, ins->inst_target_bb);
3330 bb_list = bblocks [ins->inst_target_bb->block_num].call_handler_return_bbs;
3333 * Set the indicator variable for the finally clause.
3335 lhs = bblocks [ins->inst_target_bb->block_num].finally_ind;
3337 LLVMBuildStore (builder, LLVMConstInt (LLVMInt32Type (), g_slist_length (bb_list) + 1, FALSE), lhs);
3339 /* Branch to the finally clause */
3340 LLVMBuildBr (builder, finally_bb);
3342 noex_bb = gen_bb (ctx, "CALL_HANDLER_CONT_BB");
3343 // FIXME: Use a mempool
3344 bblocks [ins->inst_target_bb->block_num].call_handler_return_bbs = g_slist_append (bblocks [ins->inst_target_bb->block_num].call_handler_return_bbs, noex_bb);
3346 builder = ctx->builder = create_builder (ctx);
3347 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
3349 bblocks [bb->block_num].end_bblock = noex_bb;
3352 case OP_START_HANDLER: {
3355 case OP_ENDFINALLY: {
3356 LLVMBasicBlockRef resume_bb;
3357 MonoBasicBlock *handler_bb;
3358 LLVMValueRef val, switch_ins;
3361 handler_bb = g_hash_table_lookup (ctx->region_to_handler, GUINT_TO_POINTER (mono_get_block_region_notry (cfg, bb->region)));
3362 g_assert (handler_bb);
3363 lhs = bblocks [handler_bb->block_num].finally_ind;
3366 bb_list = bblocks [handler_bb->block_num].call_handler_return_bbs;
3368 resume_bb = gen_bb (ctx, "ENDFINALLY_RESUME_BB");
3370 /* Load the finally variable */
3371 val = LLVMBuildLoad (builder, lhs, "");
3373 /* Reset the variable */
3374 LLVMBuildStore (builder, LLVMConstInt (LLVMInt32Type (), 0, FALSE), lhs);
3376 /* Branch to either resume_bb, or to the bblocks in bb_list */
3377 switch_ins = LLVMBuildSwitch (builder, val, resume_bb, g_slist_length (bb_list));
3379 * The other targets are added at the end to handle OP_CALL_HANDLER
3380 * opcodes processed later.
3382 bblocks [handler_bb->block_num].endfinally_switch = switch_ins;
3384 for (i = 0; i < g_slist_length (bb_list); ++i)
3385 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), i + 1, FALSE), g_slist_nth (bb_list, i)->data);
3388 builder = ctx->builder = create_builder (ctx);
3389 LLVMPositionBuilderAtEnd (ctx->builder, resume_bb);
3391 LLVMBuildCall (builder, LLVMGetNamedFunction (module, "mono_resume_unwind"), NULL, 0, "");
3392 LLVMBuildUnreachable (builder);
3393 has_terminator = TRUE;
3399 sprintf (reason, "opcode %s", mono_inst_name (ins->opcode));
3400 LLVM_FAILURE (ctx, reason);
3405 /* Convert the value to the type required by phi nodes */
3406 if (spec [MONO_INST_DEST] != ' ' && !MONO_IS_STORE_MEMBASE (ins) && vreg_types [ins->dreg]) {
3407 if (!values [ins->dreg])
3409 values [ins->dreg] = addresses [ins->dreg];
3411 values [ins->dreg] = convert (ctx, values [ins->dreg], vreg_types [ins->dreg]);
3414 /* Add stores for volatile variables */
3415 if (spec [MONO_INST_DEST] != ' ' && spec [MONO_INST_DEST] != 'v' && !MONO_IS_STORE_MEMBASE (ins))
3416 emit_volatile_store (ctx, ins->dreg);
3419 if (!has_terminator && bb->next_bb && (bb == cfg->bb_entry || bb->in_count > 0))
3420 LLVMBuildBr (builder, get_bb (ctx, bb->next_bb));
3422 if (bb == cfg->bb_exit && sig->ret->type == MONO_TYPE_VOID)
3423 LLVMBuildRetVoid (builder);
3425 if (bb == cfg->bb_entry)
3426 ctx->last_alloca = LLVMGetLastInstruction (get_bb (ctx, cfg->bb_entry));
3429 /* Add incoming phi values */
3430 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
3431 GSList *l, *ins_list;
3433 ins_list = bblocks [bb->block_num].phi_nodes;
3435 for (l = ins_list; l; l = l->next) {
3436 PhiNode *node = l->data;
3437 MonoInst *phi = node->phi;
3438 int sreg1 = node->sreg;
3439 LLVMBasicBlockRef in_bb;
3444 in_bb = get_end_bb (ctx, node->in_bb);
3446 if (unreachable [node->in_bb->block_num])
3449 g_assert (values [sreg1]);
3451 g_assert (LLVMTypeOf (values [sreg1]) == LLVMTypeOf (values [phi->dreg]));
3452 LLVMAddIncoming (values [phi->dreg], &values [sreg1], &in_bb, 1);
3456 /* Create the SWITCH statements for ENDFINALLY instructions */
3457 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
3458 if (bblocks [bb->block_num].endfinally_switch) {
3459 LLVMValueRef switch_ins = bblocks [bb->block_num].endfinally_switch;
3460 GSList *bb_list = bblocks [bb->block_num].call_handler_return_bbs;
3462 for (i = 0; i < g_slist_length (bb_list); ++i)
3463 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), i + 1, FALSE), g_slist_nth (bb_list, i)->data);
3467 if (cfg->verbose_level > 1)
3468 mono_llvm_dump_value (method);
3470 mark_as_used (module, method);
3472 if (cfg->compile_aot) {
3473 /* Don't generate native code, keep the LLVM IR */
3475 /* Can't delete the method if it has an alias, so only add it if successful */
3477 debug_alias = LLVMAddAlias (module, LLVMTypeOf (method), method, debug_name);
3478 LLVMSetLinkage (debug_alias, LLVMInternalLinkage);
3479 LLVMSetVisibility (debug_alias, LLVMHiddenVisibility);
3482 if (cfg->compile_aot && cfg->verbose_level)
3483 printf ("%s emitted as %s\n", mono_method_full_name (cfg->method, TRUE), method_name);
3485 //LLVMVerifyFunction(method, 0);
3487 mono_llvm_optimize_method (method);
3489 if (cfg->verbose_level > 1)
3490 mono_llvm_dump_value (method);
3492 cfg->native_code = LLVMGetPointerToGlobal (ee, method);
3494 /* Set by emit_cb */
3495 g_assert (cfg->code_len);
3497 /* FIXME: Free the LLVM IL for the function */
3505 /* Need to add unused phi nodes as they can be referenced by other values */
3506 LLVMBasicBlockRef phi_bb = LLVMAppendBasicBlock (method, "PHI_BB");
3507 LLVMBuilderRef builder;
3509 builder = create_builder (ctx);
3510 LLVMPositionBuilderAtEnd (builder, phi_bb);
3512 for (i = 0; i < phi_values->len; ++i) {
3513 LLVMValueRef v = g_ptr_array_index (phi_values, i);
3514 if (LLVMGetInstructionParent (v) == NULL)
3515 LLVMInsertIntoBuilder (builder, v);
3518 LLVMDeleteFunction (method);
3524 g_free (vreg_types);
3525 g_free (vreg_cli_types);
3527 g_free (debug_name);
3528 g_ptr_array_free (phi_values, TRUE);
3529 g_free (ctx->bblocks);
3530 g_hash_table_destroy (ctx->region_to_handler);
3531 g_free (method_name);
3532 g_ptr_array_free (bblock_list, TRUE);
3534 for (l = ctx->builders; l; l = l->next) {
3535 LLVMBuilderRef builder = l->data;
3536 LLVMDisposeBuilder (builder);
3541 TlsSetValue (current_cfg_tls_id, NULL);
3543 mono_loader_unlock ();
3547 * mono_llvm_emit_call:
3549 * Same as mono_arch_emit_call () for LLVM.
3552 mono_llvm_emit_call (MonoCompile *cfg, MonoCallInst *call)
3555 MonoMethodSignature *sig;
3556 int i, n, stack_size;
3561 sig = call->signature;
3562 n = sig->param_count + sig->hasthis;
3564 call->cinfo = mono_arch_get_llvm_call_info (cfg, sig);
3566 if (cfg->disable_llvm)
3569 if (sig->call_convention == MONO_CALL_VARARG) {
3570 cfg->exception_message = g_strdup ("varargs");
3571 cfg->disable_llvm = TRUE;
3574 for (i = 0; i < n; ++i) {
3577 ainfo = call->cinfo->args + i;
3579 in = call->args [i];
3581 /* Simply remember the arguments */
3582 switch (ainfo->storage) {
3584 MONO_INST_NEW (cfg, ins, OP_MOVE);
3585 ins->dreg = mono_alloc_ireg (cfg);
3586 ins->sreg1 = in->dreg;
3588 case LLVMArgInFPReg:
3589 MONO_INST_NEW (cfg, ins, OP_FMOVE);
3590 ins->dreg = mono_alloc_freg (cfg);
3591 ins->sreg1 = in->dreg;
3593 case LLVMArgVtypeByVal:
3594 case LLVMArgVtypeInReg:
3595 MONO_INST_NEW (cfg, ins, OP_LLVM_OUTARG_VT);
3596 ins->dreg = mono_alloc_ireg (cfg);
3597 ins->sreg1 = in->dreg;
3598 ins->klass = mono_class_from_mono_type (sig->params [i - sig->hasthis]);
3601 call->cinfo = mono_arch_get_llvm_call_info (cfg, sig);
3602 cfg->exception_message = g_strdup ("ainfo->storage");
3603 cfg->disable_llvm = TRUE;
3607 if (!cfg->disable_llvm) {
3608 MONO_ADD_INS (cfg->cbb, ins);
3609 mono_call_inst_add_outarg_reg (cfg, call, ins->dreg, 0, FALSE);
3614 static unsigned char*
3615 alloc_cb (LLVMValueRef function, int size)
3619 cfg = TlsGetValue (current_cfg_tls_id);
3623 return mono_domain_code_reserve (cfg->domain, size);
3625 return mono_domain_code_reserve (mono_domain_get (), size);
3630 emitted_cb (LLVMValueRef function, void *start, void *end)
3634 cfg = TlsGetValue (current_cfg_tls_id);
3636 cfg->code_len = (guint8*)end - (guint8*)start;
3640 exception_cb (void *data)
3643 MonoJitExceptionInfo *ei;
3645 gpointer *type_info;
3647 cfg = TlsGetValue (current_cfg_tls_id);
3651 * data points to a DWARF FDE structure, convert it to our unwind format and
3653 * An alternative would be to save it directly, and modify our unwinder to work
3656 cfg->encoded_unwind_ops = mono_unwind_decode_fde ((guint8*)data, &cfg->encoded_unwind_ops_len, NULL, &ei, &ei_len, &type_info);
3658 cfg->llvm_ex_info = mono_mempool_alloc0 (cfg->mempool, ei_len * sizeof (MonoJitExceptionInfo));
3659 cfg->llvm_ex_info_len = ei_len;
3660 memcpy (cfg->llvm_ex_info, ei, ei_len * sizeof (MonoJitExceptionInfo));
3661 /* Fill the rest of the information from the type info */
3662 for (i = 0; i < ei_len; ++i) {
3663 gint32 clause_index = *(gint32*)type_info [i];
3664 MonoExceptionClause *clause = &mono_method_get_header (cfg->method)->clauses [clause_index];
3666 cfg->llvm_ex_info [i].flags = clause->flags;
3667 cfg->llvm_ex_info [i].data.catch_class = clause->data.catch_class;
3674 add_intrinsics (LLVMModuleRef module)
3676 /* Emit declarations of instrinsics */
3678 LLVMTypeRef memset_params [] = { LLVMPointerType (LLVMInt8Type (), 0), LLVMInt8Type (), LLVMInt32Type (), LLVMInt32Type () };
3680 LLVMAddFunction (module, "llvm.memset.i32", LLVMFunctionType (LLVMVoidType (), memset_params, 4, FALSE));
3684 LLVMTypeRef memcpy_params [] = { LLVMPointerType (LLVMInt8Type (), 0), LLVMPointerType (LLVMInt8Type (), 0), LLVMInt32Type (), LLVMInt32Type () };
3686 LLVMAddFunction (module, "llvm.memcpy.i32", LLVMFunctionType (LLVMVoidType (), memcpy_params, 4, FALSE));
3690 LLVMTypeRef params [] = { LLVMDoubleType () };
3692 LLVMAddFunction (module, "llvm.sin.f64", LLVMFunctionType (LLVMDoubleType (), params, 1, FALSE));
3693 LLVMAddFunction (module, "llvm.cos.f64", LLVMFunctionType (LLVMDoubleType (), params, 1, FALSE));
3694 LLVMAddFunction (module, "llvm.sqrt.f64", LLVMFunctionType (LLVMDoubleType (), params, 1, FALSE));
3696 /* This isn't an intrinsic, instead llvm seems to special case it by name */
3697 LLVMAddFunction (module, "fabs", LLVMFunctionType (LLVMDoubleType (), params, 1, FALSE));
3701 LLVMTypeRef membar_params [] = { LLVMInt1Type (), LLVMInt1Type (), LLVMInt1Type (), LLVMInt1Type (), LLVMInt1Type () };
3703 LLVMAddFunction (module, "llvm.atomic.swap.i32.p0i32", LLVMFunctionType2 (LLVMInt32Type (), LLVMPointerType (LLVMInt32Type (), 0), LLVMInt32Type (), FALSE));
3704 LLVMAddFunction (module, "llvm.atomic.swap.i64.p0i64", LLVMFunctionType2 (LLVMInt64Type (), LLVMPointerType (LLVMInt64Type (), 0), LLVMInt64Type (), FALSE));
3705 LLVMAddFunction (module, "llvm.atomic.load.add.i32.p0i32", LLVMFunctionType2 (LLVMInt32Type (), LLVMPointerType (LLVMInt32Type (), 0), LLVMInt32Type (), FALSE));
3706 LLVMAddFunction (module, "llvm.atomic.load.add.i64.p0i64", LLVMFunctionType2 (LLVMInt64Type (), LLVMPointerType (LLVMInt64Type (), 0), LLVMInt64Type (), FALSE));
3707 LLVMAddFunction (module, "llvm.atomic.cmp.swap.i32.p0i32", LLVMFunctionType3 (LLVMInt32Type (), LLVMPointerType (LLVMInt32Type (), 0), LLVMInt32Type (), LLVMInt32Type (), FALSE));
3708 LLVMAddFunction (module, "llvm.atomic.cmp.swap.i64.p0i64", LLVMFunctionType3 (LLVMInt64Type (), LLVMPointerType (LLVMInt64Type (), 0), LLVMInt64Type (), LLVMInt64Type (), FALSE));
3709 LLVMAddFunction (module, "llvm.memory.barrier", LLVMFunctionType (LLVMVoidType (), membar_params, 5, FALSE));
3713 LLVMTypeRef ovf_res_i32 [] = { LLVMInt32Type (), LLVMInt1Type () };
3714 LLVMTypeRef ovf_params_i32 [] = { LLVMInt32Type (), LLVMInt32Type () };
3716 LLVMAddFunction (module, "llvm.sadd.with.overflow.i32", LLVMFunctionType (LLVMStructType (ovf_res_i32, 2, FALSE), ovf_params_i32, 2, FALSE));
3717 LLVMAddFunction (module, "llvm.uadd.with.overflow.i32", LLVMFunctionType (LLVMStructType (ovf_res_i32, 2, FALSE), ovf_params_i32, 2, FALSE));
3718 LLVMAddFunction (module, "llvm.ssub.with.overflow.i32", LLVMFunctionType (LLVMStructType (ovf_res_i32, 2, FALSE), ovf_params_i32, 2, FALSE));
3719 LLVMAddFunction (module, "llvm.usub.with.overflow.i32", LLVMFunctionType (LLVMStructType (ovf_res_i32, 2, FALSE), ovf_params_i32, 2, FALSE));
3720 LLVMAddFunction (module, "llvm.smul.with.overflow.i32", LLVMFunctionType (LLVMStructType (ovf_res_i32, 2, FALSE), ovf_params_i32, 2, FALSE));
3721 LLVMAddFunction (module, "llvm.umul.with.overflow.i32", LLVMFunctionType (LLVMStructType (ovf_res_i32, 2, FALSE), ovf_params_i32, 2, FALSE));
3725 LLVMTypeRef ovf_res_i64 [] = { LLVMInt64Type (), LLVMInt1Type () };
3726 LLVMTypeRef ovf_params_i64 [] = { LLVMInt64Type (), LLVMInt64Type () };
3728 LLVMAddFunction (module, "llvm.sadd.with.overflow.i64", LLVMFunctionType (LLVMStructType (ovf_res_i64, 2, FALSE), ovf_params_i64, 2, FALSE));
3729 LLVMAddFunction (module, "llvm.uadd.with.overflow.i64", LLVMFunctionType (LLVMStructType (ovf_res_i64, 2, FALSE), ovf_params_i64, 2, FALSE));
3730 LLVMAddFunction (module, "llvm.ssub.with.overflow.i64", LLVMFunctionType (LLVMStructType (ovf_res_i64, 2, FALSE), ovf_params_i64, 2, FALSE));
3731 LLVMAddFunction (module, "llvm.usub.with.overflow.i64", LLVMFunctionType (LLVMStructType (ovf_res_i64, 2, FALSE), ovf_params_i64, 2, FALSE));
3732 LLVMAddFunction (module, "llvm.smul.with.overflow.i64", LLVMFunctionType (LLVMStructType (ovf_res_i64, 2, FALSE), ovf_params_i64, 2, FALSE));
3733 LLVMAddFunction (module, "llvm.umul.with.overflow.i64", LLVMFunctionType (LLVMStructType (ovf_res_i64, 2, FALSE), ovf_params_i64, 2, FALSE));
3737 LLVMTypeRef struct_ptr = LLVMPointerType (LLVMStructType (NULL, 0, FALSE), 0);
3738 LLVMTypeRef invariant_start_params [] = { LLVMInt64Type (), LLVMPointerType (LLVMInt8Type (), 0) };
3739 LLVMTypeRef invariant_end_params [] = { struct_ptr, LLVMInt64Type (), LLVMPointerType (LLVMInt8Type (), 0) };
3741 LLVMAddFunction (module, "llvm.invariant.start", LLVMFunctionType (struct_ptr, invariant_start_params, 2, FALSE));
3743 LLVMAddFunction (module, "llvm.invariant.end", LLVMFunctionType (LLVMVoidType (), invariant_end_params, 3, FALSE));
3748 LLVMTypeRef arg_types [2];
3750 arg_types [0] = LLVMPointerType (LLVMInt8Type (), 0);
3751 arg_types [1] = LLVMPointerType (LLVMInt8Type (), 0);
3752 LLVMAddFunction (module, "llvm.eh.selector", LLVMFunctionType (LLVMInt32Type (), arg_types, 2, TRUE));
3754 LLVMAddFunction (module, "llvm.eh.exception", LLVMFunctionType (LLVMPointerType (LLVMInt8Type (), 0), NULL, 0, FALSE));
3756 LLVMAddFunction (module, "mono_personality", LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE));
3758 LLVMAddFunction (module, "mono_resume_unwind", LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE));
3761 /* SSE intrinsics */
3763 LLVMTypeRef vector_type, arg_types [2];
3765 vector_type = LLVMVectorType (LLVMInt32Type (), 4);
3766 arg_types [0] = vector_type;
3767 arg_types [1] = vector_type;
3768 LLVMAddFunction (module, "llvm.x86.sse41.pminud", LLVMFunctionType (vector_type, arg_types, 2, FALSE));
3769 LLVMAddFunction (module, "llvm.x86.sse41.pmaxud", LLVMFunctionType (vector_type, arg_types, 2, FALSE));
3771 vector_type = LLVMVectorType (LLVMInt16Type (), 8);
3772 arg_types [0] = vector_type;
3773 arg_types [1] = vector_type;
3774 LLVMAddFunction (module, "llvm.x86.sse41.pminuw", LLVMFunctionType (vector_type, arg_types, 2, FALSE));
3775 LLVMAddFunction (module, "llvm.x86.sse41.pmaxuw", LLVMFunctionType (vector_type, arg_types, 2, FALSE));
3777 vector_type = LLVMVectorType (LLVMInt8Type (), 16);
3778 arg_types [0] = vector_type;
3779 arg_types [1] = vector_type;
3780 LLVMAddFunction (module, "llvm.x86.sse41.pminub", LLVMFunctionType (vector_type, arg_types, 2, FALSE));
3781 LLVMAddFunction (module, "llvm.x86.sse41.pmaxub", LLVMFunctionType (vector_type, arg_types, 2, FALSE));
3783 vector_type = LLVMVectorType (LLVMDoubleType (), 2);
3784 arg_types [0] = vector_type;
3785 arg_types [1] = vector_type;
3786 LLVMAddFunction (module, "llvm.x86.sse2.min.pd", LLVMFunctionType (vector_type, arg_types, 2, FALSE));
3787 LLVMAddFunction (module, "llvm.x86.sse2.max.pd", LLVMFunctionType (vector_type, arg_types, 2, FALSE));
3789 vector_type = LLVMVectorType (LLVMFloatType (), 4);
3790 arg_types [0] = vector_type;
3791 arg_types [1] = vector_type;
3792 LLVMAddFunction (module, "llvm.x86.sse2.min.ps", LLVMFunctionType (vector_type, arg_types, 2, FALSE));
3793 LLVMAddFunction (module, "llvm.x86.sse2.max.ps", LLVMFunctionType (vector_type, arg_types, 2, FALSE));
3798 mono_llvm_init (void)
3800 current_cfg_tls_id = TlsAlloc ();
3804 init_jit_module (void)
3806 if (jit_module_inited)
3809 mono_loader_lock ();
3811 if (jit_module_inited) {
3812 mono_loader_unlock ();
3816 jit_module.module = LLVMModuleCreateWithName ("mono");
3818 ee = mono_llvm_create_ee (LLVMCreateModuleProviderForExistingModule (jit_module.module), alloc_cb, emitted_cb, exception_cb);
3820 add_intrinsics (jit_module.module);
3822 jit_module.llvm_types = g_hash_table_new (NULL, NULL);
3824 LLVMAddGlobalMapping (ee, LLVMGetNamedFunction (jit_module.module, "mono_resume_unwind"), mono_resume_unwind);
3826 jit_module_inited = TRUE;
3828 mono_loader_unlock ();
3832 mono_llvm_cleanup (void)
3835 mono_llvm_dispose_ee (ee);
3837 if (jit_module.llvm_types)
3838 g_hash_table_destroy (jit_module.llvm_types);
3842 mono_llvm_create_aot_module (const char *got_symbol)
3844 /* Delete previous module */
3845 if (aot_module.plt_entries)
3846 g_hash_table_destroy (aot_module.plt_entries);
3848 memset (&aot_module, 0, sizeof (aot_module));
3850 aot_module.module = LLVMModuleCreateWithName ("aot");
3851 aot_module.got_symbol = got_symbol;
3853 add_intrinsics (aot_module.module);
3857 * We couldn't compute the type of the LLVM global representing the got because
3858 * its size is only known after all the methods have been emitted. So create
3859 * a dummy variable, and replace all uses it with the real got variable when
3860 * its size is known in mono_llvm_emit_aot_module ().
3863 LLVMTypeRef got_type = LLVMArrayType (IntPtrType (), 0);
3865 aot_module.got_var = LLVMAddGlobal (aot_module.module, got_type, "mono_dummy_got");
3866 LLVMSetInitializer (aot_module.got_var, LLVMConstNull (got_type));
3869 /* Add a dummy personality function */
3871 LLVMBasicBlockRef lbb;
3872 LLVMBuilderRef lbuilder;
3873 LLVMValueRef personality;
3875 personality = LLVMAddFunction (aot_module.module, "mono_aot_personality", LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE));
3876 LLVMSetLinkage (personality, LLVMPrivateLinkage);
3877 lbb = LLVMAppendBasicBlock (personality, "BB0");
3878 lbuilder = LLVMCreateBuilder ();
3879 LLVMPositionBuilderAtEnd (lbuilder, lbb);
3880 LLVMBuildRetVoid (lbuilder);
3883 aot_module.llvm_types = g_hash_table_new (NULL, NULL);
3884 aot_module.plt_entries = g_hash_table_new (g_str_hash, g_str_equal);
3888 * Emit the aot module into the LLVM bitcode file FILENAME.
3891 mono_llvm_emit_aot_module (const char *filename, int got_size)
3893 LLVMTypeRef got_type;
3894 LLVMValueRef real_got;
3897 * Create the real got variable and replace all uses of the dummy variable with
3900 got_type = LLVMArrayType (IntPtrType (), got_size);
3901 real_got = LLVMAddGlobal (aot_module.module, got_type, aot_module.got_symbol);
3902 LLVMSetInitializer (real_got, LLVMConstNull (got_type));
3903 LLVMSetLinkage (real_got, LLVMInternalLinkage);
3905 mono_llvm_replace_uses_of (aot_module.got_var, real_got);
3907 mark_as_used (aot_module.module, real_got);
3909 /* Delete the dummy got so it doesn't become a global */
3910 LLVMDeleteGlobal (aot_module.got_var);
3916 if (LLVMVerifyModule (aot_module.module, LLVMReturnStatusAction, &verifier_err)) {
3917 g_assert_not_reached ();
3922 LLVMWriteBitcodeToFile (aot_module.module, filename);
3927 - Emit LLVM IR from the mono IR using the LLVM C API.
3928 - The original arch specific code remains, so we can fall back to it if we run
3929 into something we can't handle.
3931 - llvm's PrettyStackTrace class seems to register a signal handler which screws
3932 up our GC. Also, it calls sigaction () a _lot_ of times instead of just once.
3936 A partial list of issues:
3937 - Handling of opcodes which can throw exceptions.
3939 In the mono JIT, these are implemented using code like this:
3946 push throw_pos - method
3947 call <exception trampoline>
3949 The problematic part is push throw_pos - method, which cannot be represented
3950 in the LLVM IR, since it does not support label values.
3951 -> this can be implemented in AOT mode using inline asm + labels, but cannot
3952 be implemented in JIT mode ?
3953 -> a possible but slower implementation would use the normal exception
3954 throwing code but it would need to control the placement of the throw code
3955 (it needs to be exactly after the compare+branch).
3956 -> perhaps add a PC offset intrinsics ?
3958 - efficient implementation of .ovf opcodes.
3960 These are currently implemented as:
3961 <ins which sets the condition codes>
3964 Some overflow opcodes are now supported by LLVM SVN.
3966 - exception handling, unwinding.
3967 - SSA is disabled for methods with exception handlers
3968 - How to obtain unwind info for LLVM compiled methods ?
3969 -> this is now solved by converting the unwind info generated by LLVM
3971 - LLVM uses the c++ exception handling framework, while we use our home grown
3972 code, and couldn't use the c++ one:
3973 - its not supported under VC++, other exotic platforms.
3974 - it might be impossible to support filter clauses with it.
3978 The trampolines need a predictable call sequence, since they need to disasm
3979 the calling code to obtain register numbers / offsets.
3981 LLVM currently generates this code in non-JIT mode:
3982 mov -0x98(%rax),%eax
3984 Here, the vtable pointer is lost.
3985 -> solution: use one vtable trampoline per class.
3987 - passing/receiving the IMT pointer/RGCTX.
3988 -> solution: pass them as normal arguments ?
3992 LLVM does not allow the specification of argument registers etc. This means
3993 that all calls are made according to the platform ABI.
3995 - passing/receiving vtypes.
3997 Vtypes passed/received in registers are handled by the front end by using
3998 a signature with scalar arguments, and loading the parts of the vtype into those
4001 Vtypes passed on the stack are handled using the 'byval' attribute.
4005 Supported though alloca, we need to emit the load/store code.
4009 The mono JIT uses pointer sized iregs/double fregs, while LLVM uses precisely
4010 typed registers, so we have to keep track of the precise LLVM type of each vreg.
4011 This is made easier because the IR is already in SSA form.
4012 An additional problem is that our IR is not consistent with types, i.e. i32/ia64
4013 types are frequently used incorrectly.
4018 Emit LLVM bytecode into a .bc file, compile it using llc into a .s file, then
4019 append the AOT data structures to that file. For methods which cannot be
4020 handled by LLVM, the normal JIT compiled versions are used.
4023 /* FIXME: Normalize some aspects of the mono IR to allow easier translation, like:
4024 * - each bblock should end with a branch
4025 * - setting the return value, making cfg->ret non-volatile
4026 * - merge some changes back to HEAD, to reduce the differences.
4027 * - avoid some transformations in the JIT which make it harder for us to generate
4029 * - fix memory leaks.
4030 * - use pointer types to help optimizations.