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, rethrow, 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;
50 * If this bblock is the start of a finally clause, this is the bblock that
51 * CALL_HANDLER needs to branch to.
53 LLVMBasicBlockRef call_handler_target_bb;
54 /* The list of switch statements generated by ENDFINALLY instructions */
55 GSList *endfinally_switch_ins_list;
60 * Structure containing emit state
65 /* Maps method names to the corresponding LLVMValueRef */
66 GHashTable *emitted_method_decls;
70 MonoLLVMModule *lmodule;
73 int sindex, default_index, ex_index;
74 LLVMBuilderRef builder;
75 LLVMValueRef *values, *addresses;
76 MonoType **vreg_cli_types;
78 MonoMethodSignature *sig;
80 GHashTable *region_to_handler;
81 LLVMBuilderRef alloca_builder;
82 LLVMValueRef last_alloca;
83 LLVMValueRef rgctx_arg;
84 LLVMTypeRef *vreg_types;
86 gboolean *unreachable;
95 MonoBasicBlock *in_bb;
100 * Instruction metadata
101 * This is the same as ins_info, but LREG != IREG.
109 #define MINI_OP(a,b,dest,src1,src2) dest, src1, src2, ' ',
110 #define MINI_OP3(a,b,dest,src1,src2,src3) dest, src1, src2, src3,
117 /* keep in sync with the enum in mini.h */
120 #include "mini-ops.h"
125 #if SIZEOF_VOID_P == 4
126 #define GET_LONG_IMM(ins) (((guint64)(ins)->inst_ms_word << 32) | (guint64)(guint32)(ins)->inst_ls_word)
128 #define GET_LONG_IMM(ins) ((ins)->inst_imm)
131 #define LLVM_INS_INFO(opcode) (&llvm_ins_info [((opcode) - OP_START - 1) * 4])
134 #define TRACE_FAILURE(msg) do { printf ("%s\n", msg); } while (0)
136 #define TRACE_FAILURE(msg)
140 #define IS_TARGET_X86 1
142 #define IS_TARGET_X86 0
145 #define LLVM_FAILURE(ctx, reason) do { \
146 TRACE_FAILURE (reason); \
147 (ctx)->cfg->exception_message = g_strdup (reason); \
148 (ctx)->cfg->disable_llvm = TRUE; \
152 #define CHECK_FAILURE(ctx) do { \
153 if ((ctx)->cfg->disable_llvm) \
157 static LLVMIntPredicate cond_to_llvm_cond [] = {
170 static LLVMRealPredicate fpcond_to_llvm_cond [] = {
183 static LLVMExecutionEngineRef ee;
184 static guint32 current_cfg_tls_id;
186 static MonoLLVMModule jit_module, aot_module;
187 static gboolean jit_module_inited;
188 static int memset_param_count, memcpy_param_count;
189 static const char *memset_func_name;
190 static const char *memcpy_func_name;
191 static const char *eh_selector_name;
193 static void init_jit_module (void);
198 * The LLVM type with width == sizeof (gpointer)
203 return sizeof (gpointer) == 8 ? LLVMInt64Type () : LLVMInt32Type ();
209 * Return the size of the LLVM representation of the vtype T.
212 get_vtype_size (MonoType *t)
216 size = mono_class_value_size (mono_class_from_mono_type (t), NULL);
218 while (size < sizeof (gpointer) && mono_is_power_of_two (size) == -1)
225 * simd_class_to_llvm_type:
227 * Return the LLVM type corresponding to the Mono.SIMD class KLASS
230 simd_class_to_llvm_type (EmitContext *ctx, MonoClass *klass)
232 if (!strcmp (klass->name, "Vector2d")) {
233 return LLVMVectorType (LLVMDoubleType (), 2);
234 } else if (!strcmp (klass->name, "Vector2l")) {
235 return LLVMVectorType (LLVMInt64Type (), 2);
236 } else if (!strcmp (klass->name, "Vector2ul")) {
237 return LLVMVectorType (LLVMInt64Type (), 2);
238 } else if (!strcmp (klass->name, "Vector4i")) {
239 return LLVMVectorType (LLVMInt32Type (), 4);
240 } else if (!strcmp (klass->name, "Vector4ui")) {
241 return LLVMVectorType (LLVMInt32Type (), 4);
242 } else if (!strcmp (klass->name, "Vector4f")) {
243 return LLVMVectorType (LLVMFloatType (), 4);
244 } else if (!strcmp (klass->name, "Vector8s")) {
245 return LLVMVectorType (LLVMInt16Type (), 8);
246 } else if (!strcmp (klass->name, "Vector8us")) {
247 return LLVMVectorType (LLVMInt16Type (), 8);
248 } else if (!strcmp (klass->name, "Vector16sb")) {
249 return LLVMVectorType (LLVMInt8Type (), 16);
250 } else if (!strcmp (klass->name, "Vector16b")) {
251 return LLVMVectorType (LLVMInt8Type (), 16);
253 printf ("%s\n", klass->name);
259 /* Return the 128 bit SIMD type corresponding to the mono type TYPE */
260 static inline G_GNUC_UNUSED LLVMTypeRef
261 type_to_simd_type (int type)
265 return LLVMVectorType (LLVMInt8Type (), 16);
267 return LLVMVectorType (LLVMInt16Type (), 8);
269 return LLVMVectorType (LLVMInt32Type (), 4);
271 return LLVMVectorType (LLVMInt64Type (), 2);
273 return LLVMVectorType (LLVMDoubleType (), 2);
275 return LLVMVectorType (LLVMFloatType (), 4);
277 g_assert_not_reached ();
285 * Return the LLVM type corresponding to T.
288 type_to_llvm_type (EmitContext *ctx, MonoType *t)
291 return LLVMPointerType (LLVMInt8Type (), 0);
294 return LLVMVoidType ();
296 return LLVMInt8Type ();
298 return LLVMInt16Type ();
300 return LLVMInt32Type ();
302 return LLVMInt8Type ();
304 return LLVMInt16Type ();
306 return LLVMInt32Type ();
307 case MONO_TYPE_BOOLEAN:
308 return LLVMInt8Type ();
311 return LLVMInt64Type ();
313 return LLVMInt16Type ();
315 return LLVMFloatType ();
317 return LLVMDoubleType ();
320 return IntPtrType ();
321 case MONO_TYPE_OBJECT:
322 case MONO_TYPE_CLASS:
323 case MONO_TYPE_ARRAY:
324 case MONO_TYPE_SZARRAY:
325 case MONO_TYPE_STRING:
327 return LLVMPointerType (IntPtrType (), 0);
330 /* Because of generic sharing */
331 return IntPtrType ();
332 case MONO_TYPE_GENERICINST:
333 if (!mono_type_generic_inst_is_valuetype (t))
334 return IntPtrType ();
336 case MONO_TYPE_VALUETYPE:
337 case MONO_TYPE_TYPEDBYREF: {
341 klass = mono_class_from_mono_type (t);
343 if (MONO_CLASS_IS_SIMD (ctx->cfg, klass))
344 return simd_class_to_llvm_type (ctx, klass);
347 return type_to_llvm_type (ctx, mono_class_enum_basetype (klass));
348 ltype = g_hash_table_lookup (ctx->lmodule->llvm_types, klass);
351 LLVMTypeRef *eltypes;
353 size = get_vtype_size (t);
355 eltypes = g_new (LLVMTypeRef, size);
356 for (i = 0; i < size; ++i)
357 eltypes [i] = LLVMInt8Type ();
359 ltype = LLVMStructType (eltypes, size, FALSE);
360 g_hash_table_insert (ctx->lmodule->llvm_types, klass, ltype);
367 printf ("X: %d\n", t->type);
368 ctx->cfg->exception_message = g_strdup_printf ("type %s", mono_type_full_name (t));
369 ctx->cfg->disable_llvm = TRUE;
377 * Return whenever T is an unsigned int type.
380 type_is_unsigned (EmitContext *ctx, MonoType *t)
396 * type_to_llvm_arg_type:
398 * Same as type_to_llvm_type, but treat i8/i16 as i32.
401 type_to_llvm_arg_type (EmitContext *ctx, MonoType *t)
403 LLVMTypeRef ptype = type_to_llvm_type (ctx, t);
405 if (ptype == LLVMInt8Type () || ptype == LLVMInt16Type ()) {
407 * LLVM generates code which only sets the lower bits, while JITted
408 * code expects all the bits to be set.
410 ptype = LLVMInt32Type ();
417 * llvm_type_to_stack_type:
419 * Return the LLVM type which needs to be used when a value of type TYPE is pushed
422 static G_GNUC_UNUSED LLVMTypeRef
423 llvm_type_to_stack_type (LLVMTypeRef type)
427 if (type == LLVMInt8Type ())
428 return LLVMInt32Type ();
429 else if (type == LLVMInt16Type ())
430 return LLVMInt32Type ();
431 else if (type == LLVMFloatType ())
432 return LLVMDoubleType ();
438 * regtype_to_llvm_type:
440 * Return the LLVM type corresponding to the regtype C used in instruction
444 regtype_to_llvm_type (char c)
448 return LLVMInt32Type ();
450 return LLVMInt64Type ();
452 return LLVMDoubleType ();
461 * Return the LLVM type corresponding to the unary/binary opcode OPCODE.
464 op_to_llvm_type (int opcode)
469 return LLVMInt8Type ();
472 return LLVMInt8Type ();
475 return LLVMInt16Type ();
478 return LLVMInt16Type ();
481 return LLVMInt32Type ();
484 return LLVMInt32Type ();
486 return LLVMInt64Type ();
488 return LLVMFloatType ();
490 return LLVMDoubleType ();
492 return LLVMInt64Type ();
494 return LLVMInt32Type ();
496 return LLVMInt64Type ();
499 return LLVMInt8Type ();
502 return LLVMInt16Type ();
505 return sizeof (gpointer) == 8 ? LLVMInt64Type () : LLVMInt32Type ();
512 return LLVMInt32Type ();
519 return LLVMInt64Type ();
521 printf ("%s\n", mono_inst_name (opcode));
522 g_assert_not_reached ();
528 * load_store_to_llvm_type:
530 * Return the size/sign/zero extension corresponding to the load/store opcode
534 load_store_to_llvm_type (int opcode, int *size, gboolean *sext, gboolean *zext)
540 case OP_LOADI1_MEMBASE:
541 case OP_STOREI1_MEMBASE_REG:
542 case OP_STOREI1_MEMBASE_IMM:
545 return LLVMInt8Type ();
546 case OP_LOADU1_MEMBASE:
550 return LLVMInt8Type ();
551 case OP_LOADI2_MEMBASE:
552 case OP_STOREI2_MEMBASE_REG:
553 case OP_STOREI2_MEMBASE_IMM:
556 return LLVMInt16Type ();
557 case OP_LOADU2_MEMBASE:
561 return LLVMInt16Type ();
562 case OP_LOADI4_MEMBASE:
563 case OP_LOADU4_MEMBASE:
566 case OP_STOREI4_MEMBASE_REG:
567 case OP_STOREI4_MEMBASE_IMM:
569 return LLVMInt32Type ();
570 case OP_LOADI8_MEMBASE:
572 case OP_STOREI8_MEMBASE_REG:
573 case OP_STOREI8_MEMBASE_IMM:
575 return LLVMInt64Type ();
576 case OP_LOADR4_MEMBASE:
577 case OP_STORER4_MEMBASE_REG:
579 return LLVMFloatType ();
580 case OP_LOADR8_MEMBASE:
581 case OP_STORER8_MEMBASE_REG:
583 return LLVMDoubleType ();
584 case OP_LOAD_MEMBASE:
586 case OP_STORE_MEMBASE_REG:
587 case OP_STORE_MEMBASE_IMM:
588 *size = sizeof (gpointer);
589 return IntPtrType ();
591 g_assert_not_reached ();
599 * Return the LLVM intrinsics corresponding to the overflow opcode OPCODE.
602 ovf_op_to_intrins (int opcode)
606 return "llvm.sadd.with.overflow.i32";
608 return "llvm.uadd.with.overflow.i32";
610 return "llvm.ssub.with.overflow.i32";
612 return "llvm.usub.with.overflow.i32";
614 return "llvm.smul.with.overflow.i32";
616 return "llvm.umul.with.overflow.i32";
618 return "llvm.sadd.with.overflow.i64";
620 return "llvm.uadd.with.overflow.i64";
622 return "llvm.ssub.with.overflow.i64";
624 return "llvm.usub.with.overflow.i64";
626 return "llvm.smul.with.overflow.i64";
628 return "llvm.umul.with.overflow.i64";
630 g_assert_not_reached ();
636 simd_op_to_intrins (int opcode)
639 #if defined(TARGET_X86) || defined(TARGET_AMD64)
641 return "llvm.x86.sse2.min.pd";
643 return "llvm.x86.sse.min.ps";
645 return "llvm.x86.sse41.pminud";
647 return "llvm.x86.sse41.pminuw";
649 return "llvm.x86.sse2.pminu.b";
651 return "llvm.x86.sse2.pmins.w";
653 return "llvm.x86.sse2.max.pd";
655 return "llvm.x86.sse.max.ps";
657 return "llvm.x86.sse3.hadd.pd";
659 return "llvm.x86.sse3.hadd.ps";
661 return "llvm.x86.sse3.hsub.pd";
663 return "llvm.x86.sse3.hsub.ps";
665 return "llvm.x86.sse41.pmaxud";
667 return "llvm.x86.sse41.pmaxuw";
669 return "llvm.x86.sse2.pmaxu.b";
671 return "llvm.x86.sse3.addsub.pd";
672 case OP_EXTRACT_MASK:
673 return "llvm.x86.sse2.pmovmskb.128";
675 return "llvm.x86.sse2.psrli.w";
677 return "llvm.x86.sse2.psrli.d";
679 return "llvm.x86.sse2.psrli.q";
681 return "llvm.x86.sse2.pslli.w";
683 return "llvm.x86.sse2.pslli.d";
685 return "llvm.x86.sse2.pslli.q";
687 return "llvm.x86.sse2.padds.b";
689 return "llvm.x86.sse2.padds.w";
691 return "llvm.x86.sse2.psubs.b";
693 return "llvm.x86.sse2.psubs.w";
694 case OP_PADDB_SAT_UN:
695 return "llvm.x86.sse2.paddus.b";
696 case OP_PADDW_SAT_UN:
697 return "llvm.x86.sse2.paddus.w";
698 case OP_PSUBB_SAT_UN:
699 return "llvm.x86.sse2.psubus.b";
700 case OP_PSUBW_SAT_UN:
701 return "llvm.x86.sse2.psubus.w";
703 return "llvm.x86.sse2.pcmpeq.b";
705 return "llvm.x86.sse2.pcmpeq.w";
707 return "llvm.x86.sse2.pcmpeq.d";
709 return "llvm.x86.sse41.pcmpeqq";
711 return "llvm.x86.sse2.pcmpgt.b";
713 return "llvm.x86.sse2.cvtdq2pd";
715 return "llvm.x86.sse2.cvtdq2ps";
717 return "llvm.x86.sse2.cvtpd2dq";
719 return "llvm.x86.sse2.cvtps2dq";
721 return "llvm.x86.sse2.cvtpd2ps";
723 return "llvm.x86.sse2.cvtps2pd";
725 return "llvm.x86.sse2.cvttpd2dq";
727 return "llvm.x86.sse2.cvttps2dq";
729 return "llvm.x86.sse.cmp.ps";
731 return "llvm.x86.sse2.cmp.pd";
734 g_assert_not_reached ();
740 simd_op_to_llvm_type (int opcode)
742 #if defined(TARGET_X86) || defined(TARGET_AMD64)
746 return type_to_simd_type (MONO_TYPE_R8);
749 return type_to_simd_type (MONO_TYPE_I8);
752 return type_to_simd_type (MONO_TYPE_I4);
757 return type_to_simd_type (MONO_TYPE_I2);
761 return type_to_simd_type (MONO_TYPE_I1);
763 return type_to_simd_type (MONO_TYPE_R4);
766 return type_to_simd_type (MONO_TYPE_I4);
770 return type_to_simd_type (MONO_TYPE_R8);
774 return type_to_simd_type (MONO_TYPE_R4);
775 case OP_EXTRACT_MASK:
776 return type_to_simd_type (MONO_TYPE_I1);
778 g_assert_not_reached ();
789 * Return the LLVM basic block corresponding to BB.
791 static LLVMBasicBlockRef
792 get_bb (EmitContext *ctx, MonoBasicBlock *bb)
796 if (ctx->bblocks [bb->block_num].bblock == NULL) {
797 sprintf (bb_name, "BB%d", bb->block_num);
799 ctx->bblocks [bb->block_num].bblock = LLVMAppendBasicBlock (ctx->lmethod, bb_name);
800 ctx->bblocks [bb->block_num].end_bblock = ctx->bblocks [bb->block_num].bblock;
803 return ctx->bblocks [bb->block_num].bblock;
809 * Return the last LLVM bblock corresponding to BB.
810 * This might not be equal to the bb returned by get_bb () since we need to generate
811 * multiple LLVM bblocks for a mono bblock to handle throwing exceptions.
813 static LLVMBasicBlockRef
814 get_end_bb (EmitContext *ctx, MonoBasicBlock *bb)
817 return ctx->bblocks [bb->block_num].end_bblock;
820 static LLVMBasicBlockRef
821 gen_bb (EmitContext *ctx, const char *prefix)
825 sprintf (bb_name, "%s%d", prefix, ++ ctx->ex_index);
826 return LLVMAppendBasicBlock (ctx->lmethod, bb_name);
832 * Return the target of the patch identified by TYPE and TARGET.
835 resolve_patch (MonoCompile *cfg, MonoJumpInfoType type, gconstpointer target)
839 memset (&ji, 0, sizeof (ji));
841 ji.data.target = target;
843 return mono_resolve_patch_target (cfg->method, cfg->domain, NULL, &ji, FALSE);
849 * Emit code to convert the LLVM value V to DTYPE.
852 convert_full (EmitContext *ctx, LLVMValueRef v, LLVMTypeRef dtype, gboolean is_unsigned)
854 LLVMTypeRef stype = LLVMTypeOf (v);
856 if (stype != dtype) {
857 gboolean ext = FALSE;
860 if (dtype == LLVMInt64Type () && (stype == LLVMInt32Type () || stype == LLVMInt16Type () || stype == LLVMInt8Type ()))
862 else if (dtype == LLVMInt32Type () && (stype == LLVMInt16Type () || stype == LLVMInt8Type ()))
864 else if (dtype == LLVMInt16Type () && (stype == LLVMInt8Type ()))
868 return is_unsigned ? LLVMBuildZExt (ctx->builder, v, dtype, "") : LLVMBuildSExt (ctx->builder, v, dtype, "");
870 if (dtype == LLVMDoubleType () && stype == LLVMFloatType ())
871 return LLVMBuildFPExt (ctx->builder, v, dtype, "");
874 if (stype == LLVMInt64Type () && (dtype == LLVMInt32Type () || dtype == LLVMInt16Type () || dtype == LLVMInt8Type ()))
875 return LLVMBuildTrunc (ctx->builder, v, dtype, "");
876 if (stype == LLVMInt32Type () && (dtype == LLVMInt16Type () || dtype == LLVMInt8Type ()))
877 return LLVMBuildTrunc (ctx->builder, v, dtype, "");
878 if (stype == LLVMInt16Type () && dtype == LLVMInt8Type ())
879 return LLVMBuildTrunc (ctx->builder, v, dtype, "");
880 if (stype == LLVMDoubleType () && dtype == LLVMFloatType ())
881 return LLVMBuildFPTrunc (ctx->builder, v, dtype, "");
883 if (LLVMGetTypeKind (stype) == LLVMPointerTypeKind && LLVMGetTypeKind (dtype) == LLVMPointerTypeKind)
884 return LLVMBuildBitCast (ctx->builder, v, dtype, "");
885 if (LLVMGetTypeKind (dtype) == LLVMPointerTypeKind)
886 return LLVMBuildIntToPtr (ctx->builder, v, dtype, "");
887 if (LLVMGetTypeKind (stype) == LLVMPointerTypeKind)
888 return LLVMBuildPtrToInt (ctx->builder, v, dtype, "");
890 #ifdef MONO_ARCH_SOFT_FLOAT
891 if (stype == LLVMInt32Type () && dtype == LLVMFloatType ())
892 return LLVMBuildBitCast (ctx->builder, v, dtype, "");
893 if (stype == LLVMInt32Type () && dtype == LLVMDoubleType ())
894 return LLVMBuildBitCast (ctx->builder, LLVMBuildZExt (ctx->builder, v, LLVMInt64Type (), ""), dtype, "");
897 if (LLVMGetTypeKind (stype) == LLVMVectorTypeKind && LLVMGetTypeKind (dtype) == LLVMVectorTypeKind)
898 return LLVMBuildBitCast (ctx->builder, v, dtype, "");
901 LLVMDumpValue (LLVMConstNull (dtype));
902 g_assert_not_reached ();
910 convert (EmitContext *ctx, LLVMValueRef v, LLVMTypeRef dtype)
912 return convert_full (ctx, v, dtype, FALSE);
916 * emit_volatile_load:
918 * If vreg is volatile, emit a load from its address.
921 emit_volatile_load (EmitContext *ctx, int vreg)
925 LLVMValueRef v = LLVMBuildLoad (ctx->builder, ctx->addresses [vreg], "");
926 t = ctx->vreg_cli_types [vreg];
927 if (t && !t->byref) {
929 * Might have to zero extend since llvm doesn't have
932 if (t->type == MONO_TYPE_U1 || t->type == MONO_TYPE_U2 || t->type == MONO_TYPE_CHAR || t->type == MONO_TYPE_BOOLEAN)
933 v = LLVMBuildZExt (ctx->builder, v, LLVMInt32Type (), "");
934 else if (t->type == MONO_TYPE_U8)
935 v = LLVMBuildZExt (ctx->builder, v, LLVMInt64Type (), "");
942 * emit_volatile_store:
944 * If VREG is volatile, emit a store from its value to its address.
947 emit_volatile_store (EmitContext *ctx, int vreg)
949 MonoInst *var = get_vreg_to_inst (ctx->cfg, vreg);
951 if (var && var->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT)) {
952 g_assert (ctx->addresses [vreg]);
953 LLVMBuildStore (ctx->builder, convert (ctx, ctx->values [vreg], type_to_llvm_type (ctx, var->inst_vtype)), ctx->addresses [vreg]);
959 * Maps parameter indexes in the original signature to parameter indexes
960 * in the LLVM signature.
963 /* The indexes of various special arguments in the LLVM signature */
964 int vret_arg_pindex, this_arg_pindex, rgctx_arg_pindex, imt_arg_pindex;
968 * sig_to_llvm_sig_full:
970 * Return the LLVM signature corresponding to the mono signature SIG using the
971 * calling convention information in CINFO. Return parameter mapping information in SINFO.
974 sig_to_llvm_sig_full (EmitContext *ctx, MonoMethodSignature *sig, LLVMCallInfo *cinfo,
977 LLVMTypeRef ret_type;
978 LLVMTypeRef *param_types = NULL;
980 int i, j, pindex, vret_arg_pindex = 0;
982 gboolean vretaddr = FALSE;
985 memset (sinfo, 0, sizeof (LLVMSigInfo));
987 ret_type = type_to_llvm_type (ctx, sig->ret);
990 if (cinfo && cinfo->ret.storage == LLVMArgVtypeInReg) {
991 /* LLVM models this by returning an aggregate value */
992 if (cinfo->ret.pair_storage [0] == LLVMArgInIReg && cinfo->ret.pair_storage [1] == LLVMArgNone) {
993 LLVMTypeRef members [2];
995 members [0] = IntPtrType ();
996 ret_type = LLVMStructType (members, 1, FALSE);
998 g_assert_not_reached ();
1000 } else if (cinfo && MONO_TYPE_ISSTRUCT (sig->ret)) {
1001 g_assert (cinfo->ret.storage == LLVMArgVtypeRetAddr);
1003 ret_type = LLVMVoidType ();
1006 pindexes = g_new0 (int, sig->param_count);
1007 param_types = g_new0 (LLVMTypeRef, (sig->param_count * 2) + 3);
1009 if (cinfo && cinfo->rgctx_arg) {
1011 sinfo->rgctx_arg_pindex = pindex;
1012 param_types [pindex] = IntPtrType ();
1015 if (cinfo && cinfo->imt_arg && IS_LLVM_MONO_BRANCH) {
1017 sinfo->imt_arg_pindex = pindex;
1018 param_types [pindex] = IntPtrType ();
1022 /* Compute the index in the LLVM signature where the vret arg needs to be passed */
1023 vret_arg_pindex = pindex;
1024 if (cinfo->vret_arg_index == 1) {
1025 /* Add the slots consumed by the first argument */
1026 LLVMArgInfo *ainfo = &cinfo->args [0];
1027 switch (ainfo->storage) {
1028 case LLVMArgVtypeInReg:
1029 for (j = 0; j < 2; ++j) {
1030 if (ainfo->pair_storage [j] == LLVMArgInIReg)
1040 sinfo->vret_arg_pindex = vret_arg_pindex;
1043 if (vretaddr && vret_arg_pindex == pindex)
1044 param_types [pindex ++] = IntPtrType ();
1047 sinfo->this_arg_pindex = pindex;
1048 param_types [pindex ++] = IntPtrType ();
1050 if (vretaddr && vret_arg_pindex == pindex)
1051 param_types [pindex ++] = IntPtrType ();
1052 for (i = 0; i < sig->param_count; ++i) {
1053 if (vretaddr && vret_arg_pindex == pindex)
1054 param_types [pindex ++] = IntPtrType ();
1055 pindexes [i] = pindex;
1056 if (cinfo && cinfo->args [i + sig->hasthis].storage == LLVMArgVtypeInReg) {
1057 for (j = 0; j < 2; ++j) {
1058 switch (cinfo->args [i + sig->hasthis].pair_storage [j]) {
1060 param_types [pindex ++] = LLVMIntType (sizeof (gpointer) * 8);
1065 g_assert_not_reached ();
1068 } else if (cinfo && cinfo->args [i + sig->hasthis].storage == LLVMArgVtypeByVal) {
1069 param_types [pindex] = type_to_llvm_arg_type (ctx, sig->params [i]);
1070 CHECK_FAILURE (ctx);
1071 param_types [pindex] = LLVMPointerType (param_types [pindex], 0);
1074 param_types [pindex ++] = type_to_llvm_arg_type (ctx, sig->params [i]);
1077 if (vretaddr && vret_arg_pindex == pindex)
1078 param_types [pindex ++] = IntPtrType ();
1080 CHECK_FAILURE (ctx);
1082 res = LLVMFunctionType (ret_type, param_types, pindex, FALSE);
1083 g_free (param_types);
1086 sinfo->pindexes = pindexes;
1094 g_free (param_types);
1100 sig_to_llvm_sig (EmitContext *ctx, MonoMethodSignature *sig)
1102 return sig_to_llvm_sig_full (ctx, sig, NULL, NULL);
1106 * LLVMFunctionType1:
1108 * Create an LLVM function type from the arguments.
1110 static G_GNUC_UNUSED LLVMTypeRef
1111 LLVMFunctionType1(LLVMTypeRef ReturnType,
1112 LLVMTypeRef ParamType1,
1115 LLVMTypeRef param_types [1];
1117 param_types [0] = ParamType1;
1119 return LLVMFunctionType (ReturnType, param_types, 1, IsVarArg);
1123 * LLVMFunctionType2:
1125 * Create an LLVM function type from the arguments.
1128 LLVMFunctionType2(LLVMTypeRef ReturnType,
1129 LLVMTypeRef ParamType1,
1130 LLVMTypeRef ParamType2,
1133 LLVMTypeRef param_types [2];
1135 param_types [0] = ParamType1;
1136 param_types [1] = ParamType2;
1138 return LLVMFunctionType (ReturnType, param_types, 2, IsVarArg);
1142 * LLVMFunctionType3:
1144 * Create an LLVM function type from the arguments.
1147 LLVMFunctionType3(LLVMTypeRef ReturnType,
1148 LLVMTypeRef ParamType1,
1149 LLVMTypeRef ParamType2,
1150 LLVMTypeRef ParamType3,
1153 LLVMTypeRef param_types [3];
1155 param_types [0] = ParamType1;
1156 param_types [1] = ParamType2;
1157 param_types [2] = ParamType3;
1159 return LLVMFunctionType (ReturnType, param_types, 3, IsVarArg);
1165 * Create an LLVM builder and remember it so it can be freed later.
1167 static LLVMBuilderRef
1168 create_builder (EmitContext *ctx)
1170 LLVMBuilderRef builder = LLVMCreateBuilder ();
1172 ctx->builders = g_slist_prepend_mempool (ctx->cfg->mempool, ctx->builders, builder);
1178 get_plt_entry (EmitContext *ctx, LLVMTypeRef llvm_sig, MonoJumpInfoType type, gconstpointer data)
1180 char *callee_name = mono_aot_get_plt_symbol (type, data);
1181 LLVMValueRef callee;
1186 if (ctx->cfg->compile_aot)
1187 /* Add a patch so referenced wrappers can be compiled in full aot mode */
1188 mono_add_patch_info (ctx->cfg, 0, type, data);
1191 callee = g_hash_table_lookup (ctx->lmodule->plt_entries, callee_name);
1193 callee = LLVMAddFunction (ctx->module, callee_name, llvm_sig);
1195 LLVMSetVisibility (callee, LLVMHiddenVisibility);
1197 g_hash_table_insert (ctx->lmodule->plt_entries, (char*)callee_name, callee);
1204 get_handler_clause (MonoCompile *cfg, MonoBasicBlock *bb)
1206 MonoMethodHeader *header = cfg->header;
1207 MonoExceptionClause *clause;
1211 if (bb->region != -1 && MONO_BBLOCK_IS_IN_REGION (bb, MONO_REGION_TRY))
1212 return (bb->region >> 8) - 1;
1215 for (i = 0; i < header->num_clauses; ++i) {
1216 clause = &header->clauses [i];
1218 if (MONO_OFFSET_IN_CLAUSE (clause, bb->real_offset) && clause->flags == MONO_EXCEPTION_CLAUSE_NONE)
1226 set_metadata_flag (LLVMValueRef v, const char *flag_name)
1228 #if LLVM_CHECK_VERSION (2, 8)
1229 LLVMValueRef md_arg;
1232 if (!IS_LLVM_MONO_BRANCH)
1235 md_kind = LLVMGetMDKindID (flag_name, strlen (flag_name));
1236 md_arg = LLVMMDString ("mono", 4);
1237 LLVMSetMetadata (v, md_kind, LLVMMDNode (&md_arg, 1));
1244 * Emit an LLVM call or invoke instruction depending on whenever the call is inside
1248 emit_call (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, LLVMValueRef callee, LLVMValueRef *args, int pindex)
1250 MonoCompile *cfg = ctx->cfg;
1252 LLVMBuilderRef builder = *builder_ref;
1255 clause_index = get_handler_clause (cfg, bb);
1257 if (clause_index != -1) {
1258 MonoMethodHeader *header = cfg->header;
1259 MonoExceptionClause *ec = &header->clauses [clause_index];
1260 MonoBasicBlock *tblock;
1261 LLVMBasicBlockRef ex_bb, noex_bb;
1264 * Have to use an invoke instead of a call, branching to the
1265 * handler bblock of the clause containing this bblock.
1268 g_assert (ec->flags == MONO_EXCEPTION_CLAUSE_NONE || ec->flags == MONO_EXCEPTION_CLAUSE_FINALLY);
1270 tblock = cfg->cil_offset_to_bb [ec->handler_offset];
1273 ctx->bblocks [tblock->block_num].invoke_target = TRUE;
1275 ex_bb = get_bb (ctx, tblock);
1277 noex_bb = gen_bb (ctx, "NOEX_BB");
1280 lcall = LLVMBuildInvoke (builder, callee, args, pindex, noex_bb, ex_bb, "");
1282 builder = ctx->builder = create_builder (ctx);
1283 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
1285 ctx->bblocks [bb->block_num].end_bblock = noex_bb;
1287 lcall = LLVMBuildCall (builder, callee, args, pindex, "");
1288 ctx->builder = builder;
1291 *builder_ref = ctx->builder;
1297 emit_load (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, int size, LLVMValueRef addr, const char *name, gboolean is_faulting)
1299 const char *intrins_name;
1300 LLVMValueRef args [16], res;
1301 LLVMTypeRef addr_type;
1303 if (is_faulting && bb->region != -1 && IS_LLVM_MONO_BRANCH) {
1305 * We handle loads which can fault by calling a mono specific intrinsic
1306 * using an invoke, so they are handled properly inside try blocks.
1307 * We can't use this outside clauses, since LLVM optimizes intrinsics which
1308 * are marked with IntrReadArgMem.
1312 intrins_name = "llvm.mono.load.i8.p0i8";
1315 intrins_name = "llvm.mono.load.i16.p0i16";
1318 intrins_name = "llvm.mono.load.i32.p0i32";
1321 intrins_name = "llvm.mono.load.i64.p0i64";
1324 g_assert_not_reached ();
1327 addr_type = LLVMTypeOf (addr);
1328 if (addr_type == LLVMPointerType (LLVMDoubleType (), 0) || addr_type == LLVMPointerType (LLVMFloatType (), 0))
1329 addr = LLVMBuildBitCast (*builder_ref, addr, LLVMPointerType (LLVMIntType (size * 8), 0), "");
1332 args [1] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
1333 args [2] = LLVMConstInt (LLVMInt1Type (), TRUE, FALSE);
1334 res = emit_call (ctx, bb, builder_ref, LLVMGetNamedFunction (ctx->module, intrins_name), args, 3);
1336 if (addr_type == LLVMPointerType (LLVMDoubleType (), 0))
1337 res = LLVMBuildBitCast (*builder_ref, res, LLVMDoubleType (), "");
1338 else if (addr_type == LLVMPointerType (LLVMFloatType (), 0))
1339 res = LLVMBuildBitCast (*builder_ref, res, LLVMFloatType (), "");
1346 * We emit volatile loads for loads which can fault, because otherwise
1347 * LLVM will generate invalid code when encountering a load from a
1350 res = mono_llvm_build_load (*builder_ref, addr, name, is_faulting);
1352 /* Mark it with a custom metadata */
1355 set_metadata_flag (res, "mono.faulting.load");
1363 emit_store (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, int size, LLVMValueRef value, LLVMValueRef addr, gboolean is_faulting)
1365 const char *intrins_name;
1366 LLVMValueRef args [16];
1368 if (is_faulting && bb->region != -1 && IS_LLVM_MONO_BRANCH) {
1371 intrins_name = "llvm.mono.store.i8.p0i8";
1374 intrins_name = "llvm.mono.store.i16.p0i16";
1377 intrins_name = "llvm.mono.store.i32.p0i32";
1380 intrins_name = "llvm.mono.store.i64.p0i64";
1383 g_assert_not_reached ();
1386 if (LLVMTypeOf (value) == LLVMDoubleType () || LLVMTypeOf (value) == LLVMFloatType ()) {
1387 value = LLVMBuildBitCast (*builder_ref, value, LLVMIntType (size * 8), "");
1388 addr = LLVMBuildBitCast (*builder_ref, addr, LLVMPointerType (LLVMIntType (size * 8), 0), "");
1393 args [2] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
1394 args [3] = LLVMConstInt (LLVMInt1Type (), TRUE, FALSE);
1395 emit_call (ctx, bb, builder_ref, LLVMGetNamedFunction (ctx->module, intrins_name), args, 4);
1397 LLVMBuildStore (*builder_ref, value, addr);
1402 * emit_cond_system_exception:
1404 * Emit code to throw the exception EXC_TYPE if the condition CMP is false.
1405 * Might set the ctx exception.
1408 emit_cond_system_exception (EmitContext *ctx, MonoBasicBlock *bb, const char *exc_type, LLVMValueRef cmp)
1410 LLVMBasicBlockRef ex_bb, noex_bb;
1411 LLVMBuilderRef builder;
1412 MonoClass *exc_class;
1413 LLVMValueRef args [2];
1415 ex_bb = gen_bb (ctx, "EX_BB");
1416 noex_bb = gen_bb (ctx, "NOEX_BB");
1418 LLVMBuildCondBr (ctx->builder, cmp, ex_bb, noex_bb);
1420 exc_class = mono_class_from_name (mono_get_corlib (), "System", exc_type);
1421 g_assert (exc_class);
1423 /* Emit exception throwing code */
1424 builder = create_builder (ctx);
1425 LLVMPositionBuilderAtEnd (builder, ex_bb);
1427 if (!ctx->lmodule->throw_corlib_exception) {
1428 LLVMValueRef callee;
1430 const char *icall_name;
1432 MonoMethodSignature *throw_sig = mono_metadata_signature_alloc (mono_get_corlib (), 2);
1433 throw_sig->ret = &mono_get_void_class ()->byval_arg;
1434 throw_sig->params [0] = &mono_get_int32_class ()->byval_arg;
1435 if (IS_LLVM_MONO_BRANCH) {
1436 icall_name = "llvm_throw_corlib_exception_abs_trampoline";
1437 throw_sig->params [1] = &mono_get_intptr_class ()->byval_arg;
1439 icall_name = "llvm_throw_corlib_exception_trampoline";
1440 throw_sig->params [1] = &mono_get_int32_class ()->byval_arg;
1442 sig = sig_to_llvm_sig (ctx, throw_sig);
1444 if (ctx->cfg->compile_aot) {
1445 callee = get_plt_entry (ctx, sig, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
1447 callee = LLVMAddFunction (ctx->module, "llvm_throw_corlib_exception_trampoline", sig_to_llvm_sig (ctx, throw_sig));
1450 * Differences between the LLVM/non-LLVM throw corlib exception trampoline:
1451 * - On x86, LLVM generated code doesn't push the arguments
1452 * - When using the LLVM mono branch, the trampoline takes the throw address as an
1453 * arguments, not a pc offset.
1455 LLVMAddGlobalMapping (ee, callee, resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name));
1458 mono_memory_barrier ();
1459 ctx->lmodule->throw_corlib_exception = callee;
1463 args [0] = LLVMConstInt (LLVMInt32Type (), exc_class->type_token - MONO_TOKEN_TYPE_DEF, FALSE);
1465 args [0] = LLVMConstInt (LLVMInt32Type (), exc_class->type_token, FALSE);
1467 if (IS_LLVM_MONO_BRANCH) {
1469 * The LLVM mono branch contains changes so a block address can be passed as an
1470 * argument to a call.
1472 args [1] = LLVMBuildPtrToInt (builder, LLVMBlockAddress (ctx->lmethod, ex_bb), IntPtrType (), "");
1473 emit_call (ctx, bb, &builder, ctx->lmodule->throw_corlib_exception, args, 2);
1476 * FIXME: The offset is 0, this is only a problem if the code is inside a clause,
1477 * otherwise only the line numbers in stack traces are incorrect.
1479 if (bb->region != -1 && !IS_LLVM_MONO_BRANCH)
1480 LLVM_FAILURE (ctx, "system-ex-in-region");
1482 args [1] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
1483 emit_call (ctx, bb, &builder, ctx->lmodule->throw_corlib_exception, args, 2);
1486 LLVMBuildUnreachable (builder);
1488 ctx->builder = create_builder (ctx);
1489 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
1491 ctx->bblocks [bb->block_num].end_bblock = noex_bb;
1501 * emit_reg_to_vtype:
1503 * Emit code to store the vtype in the registers REGS to the address ADDRESS.
1506 emit_reg_to_vtype (EmitContext *ctx, LLVMBuilderRef builder, MonoType *t, LLVMValueRef address, LLVMArgInfo *ainfo, LLVMValueRef *regs)
1510 size = get_vtype_size (t);
1512 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (t))) {
1513 address = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (LLVMInt8Type (), 0), "");
1516 for (j = 0; j < 2; ++j) {
1517 LLVMValueRef index [2], addr;
1518 int part_size = size > sizeof (gpointer) ? sizeof (gpointer) : size;
1519 LLVMTypeRef part_type;
1521 if (ainfo->pair_storage [j] == LLVMArgNone)
1524 part_type = LLVMIntType (part_size * 8);
1525 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (t))) {
1526 index [0] = LLVMConstInt (LLVMInt32Type (), j * sizeof (gpointer), FALSE);
1527 addr = LLVMBuildGEP (builder, address, index, 1, "");
1529 index [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
1530 index [1] = LLVMConstInt (LLVMInt32Type (), j * sizeof (gpointer), FALSE);
1531 addr = LLVMBuildGEP (builder, address, index, 2, "");
1533 switch (ainfo->pair_storage [j]) {
1535 LLVMBuildStore (builder, convert (ctx, regs [j], part_type), LLVMBuildBitCast (ctx->builder, addr, LLVMPointerType (part_type, 0), ""));
1540 g_assert_not_reached ();
1543 size -= sizeof (gpointer);
1548 * emit_vtype_to_reg:
1550 * Emit code to load a vtype at address ADDRESS into registers. Store the registers
1551 * into REGS, and the number of registers into NREGS.
1554 emit_vtype_to_reg (EmitContext *ctx, LLVMBuilderRef builder, MonoType *t, LLVMValueRef address, LLVMArgInfo *ainfo, LLVMValueRef *regs, guint32 *nregs)
1559 size = get_vtype_size (t);
1561 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (t))) {
1562 address = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (LLVMInt8Type (), 0), "");
1565 for (j = 0; j < 2; ++j) {
1566 LLVMValueRef index [2], addr;
1567 int partsize = size > sizeof (gpointer) ? sizeof (gpointer) : size;
1569 if (ainfo->pair_storage [j] == LLVMArgNone)
1572 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (t))) {
1573 index [0] = LLVMConstInt (LLVMInt32Type (), j * sizeof (gpointer), FALSE);
1574 addr = LLVMBuildGEP (builder, address, index, 1, "");
1576 index [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
1577 index [1] = LLVMConstInt (LLVMInt32Type (), j * sizeof (gpointer), FALSE);
1578 addr = LLVMBuildGEP (builder, address, index, 2, "");
1580 switch (ainfo->pair_storage [j]) {
1582 regs [pindex ++] = convert (ctx, LLVMBuildLoad (builder, LLVMBuildBitCast (ctx->builder, addr, LLVMPointerType (LLVMIntType (partsize * 8), 0), ""), ""), IntPtrType ());
1587 g_assert_not_reached ();
1589 size -= sizeof (gpointer);
1596 build_alloca (EmitContext *ctx, MonoType *t)
1598 MonoClass *k = mono_class_from_mono_type (t);
1601 if (MONO_CLASS_IS_SIMD (ctx->cfg, k))
1604 align = mono_class_min_align (k);
1606 /* Sometimes align is not a power of 2 */
1607 while (mono_is_power_of_two (align) == -1)
1611 * Have to place all alloca's at the end of the entry bb, since otherwise they would
1612 * get executed every time control reaches them.
1614 LLVMPositionBuilder (ctx->alloca_builder, get_bb (ctx, ctx->cfg->bb_entry), ctx->last_alloca);
1616 ctx->last_alloca = mono_llvm_build_alloca (ctx->alloca_builder, type_to_llvm_type (ctx, t), NULL, align, "");
1617 return ctx->last_alloca;
1621 * Put the global into the 'llvm.used' array to prevent it from being optimized away.
1624 mark_as_used (LLVMModuleRef module, LLVMValueRef global)
1626 LLVMTypeRef used_type;
1627 LLVMValueRef used, used_elem;
1629 used_type = LLVMArrayType (LLVMPointerType (LLVMInt8Type (), 0), 1);
1630 used = LLVMAddGlobal (module, used_type, "llvm.used");
1631 used_elem = LLVMConstBitCast (global, LLVMPointerType (LLVMInt8Type (), 0));
1632 LLVMSetInitializer (used, LLVMConstArray (LLVMPointerType (LLVMInt8Type (), 0), &used_elem, 1));
1633 LLVMSetLinkage (used, LLVMAppendingLinkage);
1634 LLVMSetSection (used, "llvm.metadata");
1640 * Emit code to load/convert arguments.
1643 emit_entry_bb (EmitContext *ctx, LLVMBuilderRef builder)
1646 MonoCompile *cfg = ctx->cfg;
1647 MonoMethodSignature *sig = ctx->sig;
1648 LLVMCallInfo *linfo = ctx->linfo;
1651 ctx->alloca_builder = create_builder (ctx);
1654 * Handle indirect/volatile variables by allocating memory for them
1655 * using 'alloca', and storing their address in a temporary.
1657 for (i = 0; i < cfg->num_varinfo; ++i) {
1658 MonoInst *var = cfg->varinfo [i];
1661 if (var->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT) || MONO_TYPE_ISSTRUCT (var->inst_vtype)) {
1662 vtype = type_to_llvm_type (ctx, var->inst_vtype);
1663 CHECK_FAILURE (ctx);
1664 /* Could be already created by an OP_VPHI */
1665 if (!ctx->addresses [var->dreg])
1666 ctx->addresses [var->dreg] = build_alloca (ctx, var->inst_vtype);
1667 ctx->vreg_cli_types [var->dreg] = var->inst_vtype;
1671 for (i = 0; i < sig->param_count; ++i) {
1672 LLVMArgInfo *ainfo = &linfo->args [i + sig->hasthis];
1673 int reg = cfg->args [i + sig->hasthis]->dreg;
1675 if (ainfo->storage == LLVMArgVtypeInReg) {
1676 LLVMValueRef regs [2];
1679 * Emit code to save the argument from the registers to
1680 * the real argument.
1682 pindex = ctx->pindexes [i];
1683 regs [0] = LLVMGetParam (ctx->lmethod, pindex);
1684 if (ainfo->pair_storage [1] != LLVMArgNone)
1685 regs [1] = LLVMGetParam (ctx->lmethod, pindex + 1);
1689 ctx->addresses [reg] = build_alloca (ctx, sig->params [i]);
1691 emit_reg_to_vtype (ctx, builder, sig->params [i], ctx->addresses [reg], ainfo, regs);
1693 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (sig->params [i]))) {
1694 /* Treat these as normal values */
1695 ctx->values [reg] = LLVMBuildLoad (builder, ctx->addresses [reg], "");
1697 } else if (ainfo->storage == LLVMArgVtypeByVal) {
1698 ctx->addresses [reg] = LLVMGetParam (ctx->lmethod, ctx->pindexes [i]);
1700 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (sig->params [i]))) {
1701 /* Treat these as normal values */
1702 ctx->values [reg] = LLVMBuildLoad (builder, ctx->addresses [reg], "");
1705 ctx->values [reg] = convert (ctx, ctx->values [reg], llvm_type_to_stack_type (type_to_llvm_type (ctx, sig->params [i])));
1710 emit_volatile_store (ctx, cfg->vret_addr->dreg);
1712 emit_volatile_store (ctx, cfg->args [0]->dreg);
1713 for (i = 0; i < sig->param_count; ++i)
1714 if (!MONO_TYPE_ISSTRUCT (sig->params [i]))
1715 emit_volatile_store (ctx, cfg->args [i + sig->hasthis]->dreg);
1717 if (sig->hasthis && !cfg->rgctx_var && cfg->generic_sharing_context) {
1718 LLVMValueRef this_alloc;
1721 * The exception handling code needs the location where the this argument was
1722 * stored for gshared methods. We create a separate alloca to hold it, and mark it
1723 * with the "mono.this" custom metadata to tell llvm that it needs to save its
1724 * location into the LSDA.
1726 this_alloc = mono_llvm_build_alloca (builder, IntPtrType (), LLVMConstInt (LLVMInt32Type (), 1, FALSE), 0, "");
1727 /* This volatile store will keep the alloca alive */
1728 mono_llvm_build_store (builder, ctx->values [cfg->args [0]->dreg], this_alloc, TRUE);
1730 set_metadata_flag (this_alloc, "mono.this");
1733 if (cfg->rgctx_var) {
1734 LLVMValueRef rgctx_alloc, store;
1737 * We handle the rgctx arg similarly to the this pointer.
1739 g_assert (ctx->addresses [cfg->rgctx_var->dreg]);
1740 rgctx_alloc = ctx->addresses [cfg->rgctx_var->dreg];
1741 /* This volatile store will keep the alloca alive */
1742 store = mono_llvm_build_store (builder, ctx->rgctx_arg, rgctx_alloc, TRUE);
1744 set_metadata_flag (rgctx_alloc, "mono.this");
1748 * For finally clauses, create an indicator variable telling OP_ENDFINALLY whenever
1749 * it needs to continue normally, or return back to the exception handling system.
1751 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
1752 if (bb->region != -1 && (bb->flags & BB_EXCEPTION_HANDLER))
1753 g_hash_table_insert (ctx->region_to_handler, GUINT_TO_POINTER (mono_get_block_region_notry (cfg, bb->region)), bb);
1754 if (bb->region != -1 && (bb->flags & BB_EXCEPTION_HANDLER) && bb->in_scount == 0) {
1758 sprintf (name, "finally_ind_bb%d", bb->block_num);
1759 val = LLVMBuildAlloca (builder, LLVMInt32Type (), name);
1760 LLVMBuildStore (builder, LLVMConstInt (LLVMInt32Type (), 0, FALSE), val);
1762 ctx->bblocks [bb->block_num].finally_ind = val;
1765 * Create a new bblock which CALL_HANDLER can branch to, because branching to the
1766 * LLVM bblock containing the call to llvm.eh.selector causes problems for the
1767 * LLVM optimizer passes.
1769 sprintf (name, "BB_%d_CALL_HANDLER_TARGET", bb->block_num);
1770 ctx->bblocks [bb->block_num].call_handler_target_bb = LLVMAppendBasicBlock (ctx->lmethod, name);
1778 /* Have to export this for AOT */
1780 mono_personality (void);
1783 mono_personality (void)
1786 g_assert_not_reached ();
1790 process_call (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, MonoInst *ins)
1792 MonoCompile *cfg = ctx->cfg;
1793 LLVMModuleRef module = ctx->module;
1794 LLVMValueRef *values = ctx->values;
1795 LLVMValueRef *addresses = ctx->addresses;
1796 MonoCallInst *call = (MonoCallInst*)ins;
1797 MonoMethodSignature *sig = call->signature;
1798 LLVMValueRef callee, lcall;
1800 LLVMCallInfo *cinfo;
1804 LLVMTypeRef llvm_sig;
1806 gboolean virtual, calli;
1807 LLVMBuilderRef builder = *builder_ref;
1810 if (call->signature->call_convention != MONO_CALL_DEFAULT)
1811 LLVM_FAILURE (ctx, "non-default callconv");
1813 if (call->rgctx_arg_reg && !IS_LLVM_MONO_BRANCH)
1814 LLVM_FAILURE (ctx, "rgctx reg in call");
1816 if (call->rgctx_reg && !IS_LLVM_MONO_BRANCH) {
1818 * It might be possible to support this by creating a static rgctx trampoline, but
1819 * common_call_trampoline () would patch callsites to call the trampoline, which
1820 * would be incorrect if the rgctx arg is computed dynamically.
1822 LLVM_FAILURE (ctx, "rgctx reg");
1825 cinfo = call->cinfo;
1826 if (call->rgctx_arg_reg)
1827 cinfo->rgctx_arg = TRUE;
1828 if (call->imt_arg_reg)
1829 cinfo->imt_arg = TRUE;
1831 vretaddr = cinfo && cinfo->ret.storage == LLVMArgVtypeRetAddr;
1833 llvm_sig = sig_to_llvm_sig_full (ctx, sig, cinfo, &sinfo);
1834 CHECK_FAILURE (ctx);
1836 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);
1837 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);
1839 /* FIXME: Avoid creating duplicate methods */
1841 if (ins->flags & MONO_INST_HAS_METHOD) {
1845 if (cfg->compile_aot) {
1846 callee = get_plt_entry (ctx, llvm_sig, MONO_PATCH_INFO_METHOD, call->method);
1848 LLVM_FAILURE (ctx, "can't encode patch");
1850 callee = LLVMAddFunction (module, "", llvm_sig);
1853 mono_create_jit_trampoline_in_domain (mono_domain_get (),
1855 LLVMAddGlobalMapping (ee, callee, target);
1860 MonoJitICallInfo *info = mono_find_jit_icall_by_addr (call->fptr);
1866 memset (&ji, 0, sizeof (ji));
1867 ji.type = MONO_PATCH_INFO_JIT_ICALL_ADDR;
1868 ji.data.target = info->name;
1870 target = mono_resolve_patch_target (cfg->method, cfg->domain, NULL, &ji, FALSE);
1872 if (cfg->compile_aot) {
1873 callee = get_plt_entry (ctx, llvm_sig, MONO_PATCH_INFO_INTERNAL_METHOD, (char*)info->name);
1875 LLVM_FAILURE (ctx, "can't encode patch");
1877 callee = LLVMAddFunction (module, "", llvm_sig);
1878 target = (gpointer)mono_icall_get_wrapper (info);
1879 LLVMAddGlobalMapping (ee, callee, target);
1882 if (cfg->compile_aot) {
1884 if (cfg->abs_patches) {
1885 MonoJumpInfo *abs_ji = g_hash_table_lookup (cfg->abs_patches, call->fptr);
1887 callee = get_plt_entry (ctx, llvm_sig, abs_ji->type, abs_ji->data.target);
1889 LLVM_FAILURE (ctx, "can't encode patch");
1893 LLVM_FAILURE (ctx, "aot");
1895 callee = LLVMAddFunction (module, "", llvm_sig);
1897 if (cfg->abs_patches) {
1898 MonoJumpInfo *abs_ji = g_hash_table_lookup (cfg->abs_patches, call->fptr);
1901 * FIXME: Some trampolines might have
1902 * their own calling convention on some platforms.
1904 #ifndef TARGET_AMD64
1905 if (abs_ji->type == MONO_PATCH_INFO_MONITOR_ENTER || abs_ji->type == MONO_PATCH_INFO_MONITOR_EXIT || abs_ji->type == MONO_PATCH_INFO_GENERIC_CLASS_INIT)
1906 LLVM_FAILURE (ctx, "trampoline with own cconv");
1908 target = mono_resolve_patch_target (cfg->method, cfg->domain, NULL, abs_ji, FALSE);
1909 LLVMAddGlobalMapping (ee, callee, target);
1913 LLVMAddGlobalMapping (ee, callee, (gpointer)call->fptr);
1919 int size = sizeof (gpointer);
1922 g_assert (ins->inst_offset % size == 0);
1923 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
1926 * When using the llvm mono branch, we can support IMT directly, otherwise
1927 * we need to call a trampoline.
1929 if (call->method && call->method->klass->flags & TYPE_ATTRIBUTE_INTERFACE && !IS_LLVM_MONO_BRANCH) {
1930 #ifdef MONO_ARCH_HAVE_LLVM_IMT_TRAMPOLINE
1931 if (cfg->compile_aot) {
1932 MonoJumpInfoImtTramp *imt_tramp = g_new0 (MonoJumpInfoImtTramp, 1);
1933 imt_tramp->method = call->method;
1934 imt_tramp->vt_offset = call->inst.inst_offset;
1936 callee = get_plt_entry (ctx, llvm_sig, MONO_PATCH_INFO_LLVM_IMT_TRAMPOLINE, imt_tramp);
1938 callee = LLVMAddFunction (module, "", llvm_sig);
1939 target = mono_create_llvm_imt_trampoline (cfg->domain, call->method, call->inst.inst_offset);
1940 LLVMAddGlobalMapping (ee, callee, target);
1943 /* No support for passing the IMT argument */
1944 LLVM_FAILURE (ctx, "imt");
1947 callee = convert (ctx, LLVMBuildLoad (builder, LLVMBuildGEP (builder, convert (ctx, values [ins->inst_basereg], LLVMPointerType (LLVMPointerType (IntPtrType (), 0), 0)), &index, 1, ""), ""), LLVMPointerType (llvm_sig, 0));
1950 callee = convert (ctx, values [ins->sreg1], LLVMPointerType (llvm_sig, 0));
1952 if (ins->flags & MONO_INST_HAS_METHOD) {
1957 * Collect and convert arguments
1959 len = sizeof (LLVMValueRef) * ((sig->param_count * 2) + sig->hasthis + vretaddr + call->rgctx_reg);
1960 args = alloca (len);
1961 memset (args, 0, len);
1962 l = call->out_ireg_args;
1964 if (IS_LLVM_MONO_BRANCH) {
1965 if (call->rgctx_arg_reg) {
1966 g_assert (values [call->rgctx_arg_reg]);
1967 args [sinfo.rgctx_arg_pindex] = values [call->rgctx_arg_reg];
1969 if (call->imt_arg_reg) {
1970 g_assert (values [call->imt_arg_reg]);
1971 args [sinfo.imt_arg_pindex] = values [call->imt_arg_reg];
1976 if (!addresses [call->inst.dreg])
1977 addresses [call->inst.dreg] = build_alloca (ctx, sig->ret);
1978 args [sinfo.vret_arg_pindex] = LLVMBuildPtrToInt (builder, addresses [call->inst.dreg], IntPtrType (), "");
1981 for (i = 0; i < sig->param_count + sig->hasthis; ++i) {
1984 LLVMArgInfo *ainfo = call->cinfo ? &call->cinfo->args [i] : NULL;
1988 pindex = sinfo.this_arg_pindex;
1990 pindex = sinfo.pindexes [i - 1];
1992 pindex = sinfo.pindexes [i];
1995 regpair = (guint32)(gssize)(l->data);
1996 reg = regpair & 0xffffff;
1997 args [pindex] = values [reg];
1998 if (ainfo->storage == LLVMArgVtypeInReg) {
2000 LLVMValueRef regs [2];
2005 g_assert (addresses [reg]);
2007 emit_vtype_to_reg (ctx, builder, sig->params [i - sig->hasthis], addresses [reg], ainfo, regs, &nregs);
2008 for (j = 0; j < nregs; ++j)
2009 args [pindex ++] = regs [j];
2012 // FIXME: Get rid of the VMOVE
2013 } else if (ainfo->storage == LLVMArgVtypeByVal) {
2014 g_assert (addresses [reg]);
2015 args [pindex] = addresses [reg];
2017 g_assert (args [pindex]);
2018 if (i == 0 && sig->hasthis)
2019 args [pindex] = convert (ctx, args [pindex], IntPtrType ());
2021 args [pindex] = convert (ctx, args [pindex], type_to_llvm_arg_type (ctx, sig->params [i - sig->hasthis]));
2027 // FIXME: Align call sites
2033 lcall = emit_call (ctx, bb, &builder, callee, args, LLVMCountParamTypes (llvm_sig));
2035 #ifdef LLVM_MONO_BRANCH
2037 * Modify cconv and parameter attributes to pass rgctx/imt correctly.
2039 #if defined(MONO_ARCH_IMT_REG) && defined(MONO_ARCH_RGCTX_REG)
2040 g_assert (MONO_ARCH_IMT_REG == MONO_ARCH_RGCTX_REG);
2042 /* The two can't be used together, so use only one LLVM calling conv to pass them */
2043 g_assert (!(call->rgctx_arg_reg && call->imt_arg_reg));
2045 LLVMSetInstructionCallConv (lcall, LLVMMono1CallConv);
2047 if (call->rgctx_arg_reg)
2048 LLVMAddInstrAttribute (lcall, 1 + sinfo.rgctx_arg_pindex, LLVMInRegAttribute);
2049 if (call->imt_arg_reg)
2050 LLVMAddInstrAttribute (lcall, 1 + sinfo.imt_arg_pindex, LLVMInRegAttribute);
2053 /* Add byval attributes if needed */
2054 for (i = 0; i < sig->param_count; ++i) {
2055 LLVMArgInfo *ainfo = call->cinfo ? &call->cinfo->args [i + sig->hasthis] : NULL;
2057 if (ainfo && ainfo->storage == LLVMArgVtypeByVal) {
2058 LLVMAddInstrAttribute (lcall, 1 + sinfo.pindexes [i], LLVMByValAttribute);
2063 * Convert the result
2065 if (cinfo && cinfo->ret.storage == LLVMArgVtypeInReg) {
2066 LLVMValueRef regs [2];
2068 if (!addresses [ins->dreg])
2069 addresses [ins->dreg] = build_alloca (ctx, sig->ret);
2071 regs [0] = LLVMBuildExtractValue (builder, lcall, 0, "");
2072 if (cinfo->ret.pair_storage [1] != LLVMArgNone)
2073 regs [1] = LLVMBuildExtractValue (builder, lcall, 1, "");
2075 emit_reg_to_vtype (ctx, builder, sig->ret, addresses [ins->dreg], &cinfo->ret, regs);
2076 } else if (sig->ret->type != MONO_TYPE_VOID && !vretaddr) {
2077 /* If the method returns an unsigned value, need to zext it */
2079 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));
2082 *builder_ref = ctx->builder;
2084 g_free (sinfo.pindexes);
2092 process_bb (EmitContext *ctx, MonoBasicBlock *bb)
2094 MonoCompile *cfg = ctx->cfg;
2095 MonoMethodSignature *sig = ctx->sig;
2096 LLVMValueRef method = ctx->lmethod;
2097 LLVMValueRef *values = ctx->values;
2098 LLVMValueRef *addresses = ctx->addresses;
2100 LLVMCallInfo *linfo = ctx->linfo;
2101 LLVMModuleRef module = ctx->module;
2102 BBInfo *bblocks = ctx->bblocks;
2104 LLVMBasicBlockRef cbb;
2105 LLVMBuilderRef builder;
2106 gboolean has_terminator;
2108 LLVMValueRef lhs, rhs;
2110 cbb = get_bb (ctx, bb);
2111 builder = create_builder (ctx);
2112 ctx->builder = builder;
2113 LLVMPositionBuilderAtEnd (builder, cbb);
2115 if (bb == cfg->bb_entry)
2116 emit_entry_bb (ctx, builder);
2117 CHECK_FAILURE (ctx);
2119 if (bb->flags & BB_EXCEPTION_HANDLER) {
2121 LLVMValueRef eh_selector, eh_exception, personality, args [4];
2122 LLVMBasicBlockRef target_bb;
2124 static gint32 mapping_inited;
2125 static int ti_generator;
2128 LLVMValueRef type_info;
2131 if (!bblocks [bb->block_num].invoke_target) {
2133 * LLVM asserts if llvm.eh.selector is called from a bblock which
2134 * doesn't have an invoke pointing at it.
2136 LLVM_FAILURE (ctx, "handler without invokes");
2139 eh_selector = LLVMGetNamedFunction (module, eh_selector_name);
2141 if (cfg->compile_aot) {
2142 /* Use a dummy personality function */
2143 personality = LLVMGetNamedFunction (module, "mono_aot_personality");
2144 g_assert (personality);
2146 personality = LLVMGetNamedFunction (module, "mono_personality");
2147 if (InterlockedCompareExchange (&mapping_inited, 1, 0) == 0)
2148 LLVMAddGlobalMapping (ee, personality, mono_personality);
2151 i8ptr = LLVMPointerType (LLVMInt8Type (), 0);
2153 clause_index = (mono_get_block_region_notry (cfg, bb->region) >> 8) - 1;
2156 * Create the type info
2158 sprintf (ti_name, "type_info_%d", ti_generator);
2161 if (cfg->compile_aot) {
2162 /* decode_eh_frame () in aot-runtime.c will decode this */
2163 type_info = LLVMAddGlobal (module, LLVMInt32Type (), ti_name);
2164 LLVMSetInitializer (type_info, LLVMConstInt (LLVMInt32Type (), clause_index, FALSE));
2166 LLVMSetLinkage (type_info, LLVMPrivateLinkage);
2167 LLVMSetVisibility (type_info, LLVMHiddenVisibility);
2170 * Enabling this causes llc to crash:
2171 * http://llvm.org/bugs/show_bug.cgi?id=6102
2173 //LLVM_FAILURE (ctx, "aot+clauses");
2176 * After the cfg mempool is freed, the type info will point to stale memory,
2177 * but this is not a problem, since we decode it once in exception_cb during
2180 ti = mono_mempool_alloc (cfg->mempool, sizeof (gint32));
2181 *(gint32*)ti = clause_index;
2183 type_info = LLVMAddGlobal (module, i8ptr, ti_name);
2185 LLVMAddGlobalMapping (ee, type_info, ti);
2188 args [0] = LLVMConstNull (i8ptr);
2189 args [1] = LLVMConstBitCast (personality, i8ptr);
2190 args [2] = type_info;
2191 LLVMBuildCall (builder, eh_selector, args, 3, "");
2193 /* Store the exception into the exvar */
2194 if (bb->in_scount == 1) {
2195 g_assert (bb->in_scount == 1);
2196 exvar = bb->in_stack [0];
2198 eh_exception = LLVMGetNamedFunction (module, "llvm.eh.exception");
2200 // FIXME: This is shared with filter clauses ?
2201 g_assert (!values [exvar->dreg]);
2202 values [exvar->dreg] = LLVMBuildCall (builder, eh_exception, NULL, 0, "");
2203 emit_volatile_store (ctx, exvar->dreg);
2206 /* Start a new bblock which CALL_HANDLER can branch to */
2207 target_bb = bblocks [bb->block_num].call_handler_target_bb;
2209 LLVMBuildBr (builder, target_bb);
2211 ctx->builder = builder = create_builder (ctx);
2212 LLVMPositionBuilderAtEnd (ctx->builder, target_bb);
2214 ctx->bblocks [bb->block_num].end_bblock = target_bb;
2218 has_terminator = FALSE;
2219 for (ins = bb->code; ins; ins = ins->next) {
2220 const char *spec = LLVM_INS_INFO (ins->opcode);
2222 char dname_buf [128];
2225 /* There could be instructions after a terminator, skip them */
2228 if (spec [MONO_INST_DEST] != ' ' && !MONO_IS_STORE_MEMBASE (ins)) {
2229 sprintf (dname_buf, "t%d", ins->dreg);
2233 if (spec [MONO_INST_SRC1] != ' ' && spec [MONO_INST_SRC1] != 'v') {
2234 MonoInst *var = get_vreg_to_inst (cfg, ins->sreg1);
2236 if (var && var->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT)) {
2237 lhs = emit_volatile_load (ctx, ins->sreg1);
2239 /* It is ok for SETRET to have an uninitialized argument */
2240 if (!values [ins->sreg1] && ins->opcode != OP_SETRET)
2241 LLVM_FAILURE (ctx, "sreg1");
2242 lhs = values [ins->sreg1];
2248 if (spec [MONO_INST_SRC2] != ' ' && spec [MONO_INST_SRC2] != ' ') {
2249 MonoInst *var = get_vreg_to_inst (cfg, ins->sreg2);
2250 if (var && var->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT)) {
2251 rhs = emit_volatile_load (ctx, ins->sreg2);
2253 if (!values [ins->sreg2])
2254 LLVM_FAILURE (ctx, "sreg2");
2255 rhs = values [ins->sreg2];
2261 //mono_print_ins (ins);
2262 switch (ins->opcode) {
2265 case OP_LIVERANGE_START:
2266 case OP_LIVERANGE_END:
2269 values [ins->dreg] = LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE);
2272 #if SIZEOF_VOID_P == 4
2273 values [ins->dreg] = LLVMConstInt (LLVMInt64Type (), GET_LONG_IMM (ins), FALSE);
2275 values [ins->dreg] = LLVMConstInt (LLVMInt64Type (), (gint64)ins->inst_c0, FALSE);
2279 values [ins->dreg] = LLVMConstReal (LLVMDoubleType (), *(double*)ins->inst_p0);
2282 values [ins->dreg] = LLVMConstFPExt (LLVMConstReal (LLVMFloatType (), *(float*)ins->inst_p0), LLVMDoubleType ());
2285 LLVMBuildBr (builder, get_bb (ctx, ins->inst_target_bb));
2286 has_terminator = TRUE;
2292 LLVMBasicBlockRef new_bb;
2293 LLVMBuilderRef new_builder;
2295 // The default branch is already handled
2296 // FIXME: Handle it here
2298 /* Start new bblock */
2299 sprintf (bb_name, "SWITCH_DEFAULT_BB%d", ctx->default_index ++);
2300 new_bb = LLVMAppendBasicBlock (ctx->lmethod, bb_name);
2302 lhs = convert (ctx, lhs, LLVMInt32Type ());
2303 v = LLVMBuildSwitch (builder, lhs, new_bb, GPOINTER_TO_UINT (ins->klass));
2304 for (i = 0; i < GPOINTER_TO_UINT (ins->klass); ++i) {
2305 MonoBasicBlock *target_bb = ins->inst_many_bb [i];
2307 LLVMAddCase (v, LLVMConstInt (LLVMInt32Type (), i, FALSE), get_bb (ctx, target_bb));
2310 new_builder = create_builder (ctx);
2311 LLVMPositionBuilderAtEnd (new_builder, new_bb);
2312 LLVMBuildUnreachable (new_builder);
2314 has_terminator = TRUE;
2315 g_assert (!ins->next);
2321 if (linfo->ret.storage == LLVMArgVtypeInReg) {
2322 LLVMTypeRef ret_type = LLVMGetReturnType (LLVMGetElementType (LLVMTypeOf (method)));
2323 LLVMValueRef part1, retval;
2326 size = get_vtype_size (sig->ret);
2328 g_assert (addresses [ins->sreg1]);
2330 g_assert (linfo->ret.pair_storage [0] == LLVMArgInIReg);
2331 g_assert (linfo->ret.pair_storage [1] == LLVMArgNone);
2333 part1 = convert (ctx, LLVMBuildLoad (builder, LLVMBuildBitCast (builder, addresses [ins->sreg1], LLVMPointerType (LLVMIntType (size * 8), 0), ""), ""), IntPtrType ());
2335 retval = LLVMBuildInsertValue (builder, LLVMGetUndef (ret_type), part1, 0, "");
2337 LLVMBuildRet (builder, retval);
2341 if (linfo->ret.storage == LLVMArgVtypeRetAddr) {
2342 LLVMBuildRetVoid (builder);
2346 if (!lhs || ctx->is_dead [ins->sreg1]) {
2348 * The method did not set its return value, probably because it
2349 * ends with a throw.
2352 LLVMBuildRetVoid (builder);
2354 LLVMBuildRet (builder, LLVMConstNull (type_to_llvm_type (ctx, sig->ret)));
2356 LLVMBuildRet (builder, convert (ctx, lhs, type_to_llvm_type (ctx, sig->ret)));
2358 has_terminator = TRUE;
2364 case OP_ICOMPARE_IMM:
2365 case OP_LCOMPARE_IMM:
2366 case OP_COMPARE_IMM: {
2370 if (ins->next->opcode == OP_NOP)
2373 if (ins->next->opcode == OP_BR)
2374 /* The comparison result is not needed */
2377 rel = mono_opcode_to_cond (ins->next->opcode);
2379 if (ins->opcode == OP_ICOMPARE_IMM) {
2380 lhs = convert (ctx, lhs, LLVMInt32Type ());
2381 rhs = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
2383 if (ins->opcode == OP_LCOMPARE_IMM) {
2384 lhs = convert (ctx, lhs, LLVMInt64Type ());
2385 rhs = LLVMConstInt (LLVMInt64Type (), GET_LONG_IMM (ins), FALSE);
2387 if (ins->opcode == OP_LCOMPARE) {
2388 lhs = convert (ctx, lhs, LLVMInt64Type ());
2389 rhs = convert (ctx, rhs, LLVMInt64Type ());
2391 if (ins->opcode == OP_ICOMPARE) {
2392 lhs = convert (ctx, lhs, LLVMInt32Type ());
2393 rhs = convert (ctx, rhs, LLVMInt32Type ());
2397 if (LLVMGetTypeKind (LLVMTypeOf (lhs)) == LLVMPointerTypeKind)
2398 rhs = convert (ctx, rhs, LLVMTypeOf (lhs));
2399 else if (LLVMGetTypeKind (LLVMTypeOf (rhs)) == LLVMPointerTypeKind)
2400 lhs = convert (ctx, lhs, LLVMTypeOf (rhs));
2403 /* We use COMPARE+SETcc/Bcc, llvm uses SETcc+br cond */
2404 if (ins->opcode == OP_FCOMPARE)
2405 cmp = LLVMBuildFCmp (builder, fpcond_to_llvm_cond [rel], convert (ctx, lhs, LLVMDoubleType ()), convert (ctx, rhs, LLVMDoubleType ()), "");
2406 else if (ins->opcode == OP_COMPARE_IMM)
2407 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE), "");
2408 else if (ins->opcode == OP_LCOMPARE_IMM) {
2409 if (SIZEOF_REGISTER == 4 && COMPILE_LLVM (cfg)) {
2410 /* The immediate is encoded in two fields */
2411 guint64 l = ((guint64)(guint32)ins->inst_offset << 32) | ((guint32)ins->inst_imm);
2412 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, LLVMInt64Type ()), LLVMConstInt (LLVMInt64Type (), l, FALSE), "");
2414 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, LLVMInt64Type ()), LLVMConstInt (LLVMInt64Type (), ins->inst_imm, FALSE), "");
2417 else if (ins->opcode == OP_COMPARE)
2418 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, IntPtrType ()), convert (ctx, rhs, IntPtrType ()), "");
2420 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], lhs, rhs, "");
2422 if (MONO_IS_COND_BRANCH_OP (ins->next)) {
2423 LLVMBuildCondBr (builder, cmp, get_bb (ctx, ins->next->inst_true_bb), get_bb (ctx, ins->next->inst_false_bb));
2424 has_terminator = TRUE;
2425 } else if (MONO_IS_SETCC (ins->next)) {
2426 sprintf (dname_buf, "t%d", ins->next->dreg);
2428 values [ins->next->dreg] = LLVMBuildZExt (builder, cmp, LLVMInt32Type (), dname);
2430 /* Add stores for volatile variables */
2431 emit_volatile_store (ctx, ins->next->dreg);
2432 } else if (MONO_IS_COND_EXC (ins->next)) {
2433 emit_cond_system_exception (ctx, bb, ins->next->inst_p1, cmp);
2434 CHECK_FAILURE (ctx);
2435 builder = ctx->builder;
2437 LLVM_FAILURE (ctx, "next");
2451 rel = mono_opcode_to_cond (ins->opcode);
2453 cmp = LLVMBuildFCmp (builder, fpcond_to_llvm_cond [rel], convert (ctx, lhs, LLVMDoubleType ()), convert (ctx, rhs, LLVMDoubleType ()), "");
2454 values [ins->dreg] = LLVMBuildZExt (builder, cmp, LLVMInt32Type (), dname);
2462 gboolean empty = TRUE;
2464 /* Check that all input bblocks really branch to us */
2465 for (i = 0; i < bb->in_count; ++i) {
2466 if (bb->in_bb [i]->last_ins && bb->in_bb [i]->last_ins->opcode == OP_NOT_REACHED)
2467 ins->inst_phi_args [i + 1] = -1;
2473 /* LLVM doesn't like phi instructions with zero operands */
2474 ctx->is_dead [ins->dreg] = TRUE;
2478 /* Created earlier, insert it now */
2479 LLVMInsertIntoBuilder (builder, values [ins->dreg]);
2481 for (i = 0; i < ins->inst_phi_args [0]; i++) {
2482 int sreg1 = ins->inst_phi_args [i + 1];
2486 * Count the number of times the incoming bblock branches to us,
2487 * since llvm requires a separate entry for each.
2489 if (bb->in_bb [i]->last_ins && bb->in_bb [i]->last_ins->opcode == OP_SWITCH) {
2490 MonoInst *switch_ins = bb->in_bb [i]->last_ins;
2493 for (j = 0; j < GPOINTER_TO_UINT (switch_ins->klass); ++j) {
2494 if (switch_ins->inst_many_bb [j] == bb)
2501 /* Remember for later */
2502 for (j = 0; j < count; ++j) {
2503 PhiNode *node = mono_mempool_alloc0 (ctx->mempool, sizeof (PhiNode));
2506 node->in_bb = bb->in_bb [i];
2508 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);
2518 values [ins->dreg] = lhs;
2521 MonoInst *var = get_vreg_to_inst (cfg, ins->dreg);
2524 values [ins->dreg] = lhs;
2526 if (var && var->klass->byval_arg.type == MONO_TYPE_R4) {
2528 * This is added by the spilling pass in case of the JIT,
2529 * but we have to do it ourselves.
2531 values [ins->dreg] = convert (ctx, values [ins->dreg], LLVMFloatType ());
2565 lhs = convert (ctx, lhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
2566 rhs = convert (ctx, rhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
2568 switch (ins->opcode) {
2571 values [ins->dreg] = LLVMBuildAdd (builder, lhs, rhs, dname);
2575 values [ins->dreg] = LLVMBuildSub (builder, lhs, rhs, dname);
2579 values [ins->dreg] = LLVMBuildMul (builder, lhs, rhs, dname);
2583 values [ins->dreg] = LLVMBuildSRem (builder, lhs, rhs, dname);
2587 values [ins->dreg] = LLVMBuildURem (builder, lhs, rhs, dname);
2591 values [ins->dreg] = LLVMBuildSDiv (builder, lhs, rhs, dname);
2595 values [ins->dreg] = LLVMBuildUDiv (builder, lhs, rhs, dname);
2598 values [ins->dreg] = LLVMBuildFDiv (builder, lhs, rhs, dname);
2602 values [ins->dreg] = LLVMBuildAnd (builder, lhs, rhs, dname);
2606 values [ins->dreg] = LLVMBuildOr (builder, lhs, rhs, dname);
2610 values [ins->dreg] = LLVMBuildXor (builder, lhs, rhs, dname);
2614 values [ins->dreg] = LLVMBuildShl (builder, lhs, rhs, dname);
2618 values [ins->dreg] = LLVMBuildAShr (builder, lhs, rhs, dname);
2622 values [ins->dreg] = LLVMBuildLShr (builder, lhs, rhs, dname);
2626 values [ins->dreg] = LLVMBuildFAdd (builder, lhs, rhs, dname);
2629 values [ins->dreg] = LLVMBuildFSub (builder, lhs, rhs, dname);
2632 values [ins->dreg] = LLVMBuildFMul (builder, lhs, rhs, dname);
2636 g_assert_not_reached ();
2643 case OP_IREM_UN_IMM:
2645 case OP_IDIV_UN_IMM:
2651 case OP_ISHR_UN_IMM:
2660 case OP_LSHR_UN_IMM:
2668 if (spec [MONO_INST_SRC1] == 'l') {
2669 imm = LLVMConstInt (LLVMInt64Type (), GET_LONG_IMM (ins), FALSE);
2671 imm = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
2674 #if SIZEOF_VOID_P == 4
2675 if (ins->opcode == OP_LSHL_IMM || ins->opcode == OP_LSHR_IMM || ins->opcode == OP_LSHR_UN_IMM)
2676 imm = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
2679 if (LLVMGetTypeKind (LLVMTypeOf (lhs)) == LLVMPointerTypeKind)
2680 lhs = convert (ctx, lhs, IntPtrType ());
2681 imm = convert (ctx, imm, LLVMTypeOf (lhs));
2682 switch (ins->opcode) {
2686 values [ins->dreg] = LLVMBuildAdd (builder, lhs, imm, dname);
2690 values [ins->dreg] = LLVMBuildSub (builder, lhs, imm, dname);
2694 values [ins->dreg] = LLVMBuildMul (builder, lhs, imm, dname);
2698 values [ins->dreg] = LLVMBuildSDiv (builder, lhs, imm, dname);
2700 case OP_IDIV_UN_IMM:
2701 case OP_LDIV_UN_IMM:
2702 values [ins->dreg] = LLVMBuildUDiv (builder, lhs, imm, dname);
2706 values [ins->dreg] = LLVMBuildSRem (builder, lhs, imm, dname);
2708 case OP_IREM_UN_IMM:
2709 values [ins->dreg] = LLVMBuildURem (builder, lhs, imm, dname);
2714 values [ins->dreg] = LLVMBuildAnd (builder, lhs, imm, dname);
2718 values [ins->dreg] = LLVMBuildOr (builder, lhs, imm, dname);
2722 values [ins->dreg] = LLVMBuildXor (builder, lhs, imm, dname);
2727 values [ins->dreg] = LLVMBuildShl (builder, lhs, imm, dname);
2732 values [ins->dreg] = LLVMBuildAShr (builder, lhs, imm, dname);
2734 case OP_ISHR_UN_IMM:
2735 /* This is used to implement conv.u4, so the lhs could be an i8 */
2736 lhs = convert (ctx, lhs, LLVMInt32Type ());
2737 imm = convert (ctx, imm, LLVMInt32Type ());
2738 values [ins->dreg] = LLVMBuildLShr (builder, lhs, imm, dname);
2740 case OP_LSHR_UN_IMM:
2741 values [ins->dreg] = LLVMBuildLShr (builder, lhs, imm, dname);
2744 g_assert_not_reached ();
2749 values [ins->dreg] = LLVMBuildSub (builder, LLVMConstInt (LLVMInt32Type (), 0, FALSE), convert (ctx, lhs, LLVMInt32Type ()), dname);
2752 values [ins->dreg] = LLVMBuildSub (builder, LLVMConstInt (LLVMInt64Type (), 0, FALSE), lhs, dname);
2755 lhs = convert (ctx, lhs, LLVMDoubleType ());
2756 values [ins->dreg] = LLVMBuildFSub (builder, LLVMConstReal (LLVMDoubleType (), 0.0), lhs, dname);
2759 guint32 v = 0xffffffff;
2760 values [ins->dreg] = LLVMBuildXor (builder, LLVMConstInt (LLVMInt32Type (), v, FALSE), lhs, dname);
2764 guint64 v = 0xffffffffffffffffLL;
2765 values [ins->dreg] = LLVMBuildXor (builder, LLVMConstInt (LLVMInt64Type (), v, FALSE), lhs, dname);
2768 #if defined(TARGET_X86) || defined(TARGET_AMD64)
2770 LLVMValueRef v1, v2;
2772 v1 = LLVMBuildMul (builder, convert (ctx, rhs, IntPtrType ()), LLVMConstInt (IntPtrType (), (1 << ins->backend.shift_amount), FALSE), "");
2773 v2 = LLVMBuildAdd (builder, convert (ctx, lhs, IntPtrType ()), v1, "");
2774 values [ins->dreg] = LLVMBuildAdd (builder, v2, LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE), dname);
2779 case OP_ICONV_TO_I1:
2780 case OP_ICONV_TO_I2:
2781 case OP_ICONV_TO_I4:
2782 case OP_ICONV_TO_U1:
2783 case OP_ICONV_TO_U2:
2784 case OP_ICONV_TO_U4:
2785 case OP_LCONV_TO_I1:
2786 case OP_LCONV_TO_I2:
2787 case OP_LCONV_TO_U1:
2788 case OP_LCONV_TO_U2:
2789 case OP_LCONV_TO_U4: {
2792 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);
2794 /* Have to do two casts since our vregs have type int */
2795 v = LLVMBuildTrunc (builder, lhs, op_to_llvm_type (ins->opcode), "");
2797 values [ins->dreg] = LLVMBuildSExt (builder, v, LLVMInt32Type (), dname);
2799 values [ins->dreg] = LLVMBuildZExt (builder, v, LLVMInt32Type (), dname);
2802 case OP_ICONV_TO_I8:
2803 values [ins->dreg] = LLVMBuildSExt (builder, lhs, LLVMInt64Type (), dname);
2805 case OP_ICONV_TO_U8:
2806 values [ins->dreg] = LLVMBuildZExt (builder, lhs, LLVMInt64Type (), dname);
2808 case OP_FCONV_TO_I4:
2809 values [ins->dreg] = LLVMBuildFPToSI (builder, lhs, LLVMInt32Type (), dname);
2811 case OP_FCONV_TO_I1:
2812 values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildFPToSI (builder, lhs, LLVMInt8Type (), dname), LLVMInt32Type (), "");
2814 case OP_FCONV_TO_U1:
2815 values [ins->dreg] = LLVMBuildZExt (builder, LLVMBuildFPToUI (builder, lhs, LLVMInt8Type (), dname), LLVMInt32Type (), "");
2817 case OP_FCONV_TO_I2:
2818 values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildFPToSI (builder, lhs, LLVMInt16Type (), dname), LLVMInt32Type (), "");
2820 case OP_FCONV_TO_U2:
2821 values [ins->dreg] = LLVMBuildZExt (builder, LLVMBuildFPToUI (builder, lhs, LLVMInt16Type (), dname), LLVMInt32Type (), "");
2823 case OP_FCONV_TO_I8:
2824 values [ins->dreg] = LLVMBuildFPToSI (builder, lhs, LLVMInt64Type (), dname);
2827 values [ins->dreg] = LLVMBuildFPToSI (builder, lhs, IntPtrType (), dname);
2829 case OP_ICONV_TO_R8:
2830 case OP_LCONV_TO_R8:
2831 values [ins->dreg] = LLVMBuildSIToFP (builder, lhs, LLVMDoubleType (), dname);
2833 case OP_LCONV_TO_R_UN:
2834 values [ins->dreg] = LLVMBuildUIToFP (builder, lhs, LLVMDoubleType (), dname);
2836 #if SIZEOF_VOID_P == 4
2839 case OP_LCONV_TO_I4:
2840 values [ins->dreg] = LLVMBuildTrunc (builder, lhs, LLVMInt32Type (), dname);
2842 case OP_ICONV_TO_R4:
2843 case OP_LCONV_TO_R4:
2844 v = LLVMBuildSIToFP (builder, lhs, LLVMFloatType (), "");
2845 values [ins->dreg] = LLVMBuildFPExt (builder, v, LLVMDoubleType (), dname);
2847 case OP_FCONV_TO_R4:
2848 v = LLVMBuildFPTrunc (builder, lhs, LLVMFloatType (), "");
2849 values [ins->dreg] = LLVMBuildFPExt (builder, v, LLVMDoubleType (), dname);
2852 values [ins->dreg] = LLVMBuildSExt (builder, lhs, LLVMInt64Type (), dname);
2855 values [ins->dreg] = LLVMBuildZExt (builder, lhs, LLVMInt64Type (), dname);
2858 values [ins->dreg] = LLVMBuildTrunc (builder, lhs, LLVMInt32Type (), dname);
2860 case OP_LOCALLOC_IMM: {
2863 guint32 size = ins->inst_imm;
2864 size = (size + (MONO_ARCH_FRAME_ALIGNMENT - 1)) & ~ (MONO_ARCH_FRAME_ALIGNMENT - 1);
2866 v = mono_llvm_build_alloca (builder, LLVMInt8Type (), LLVMConstInt (LLVMInt32Type (), size, FALSE), MONO_ARCH_FRAME_ALIGNMENT, "");
2868 if (ins->flags & MONO_INST_INIT) {
2869 LLVMValueRef args [5];
2872 args [1] = LLVMConstInt (LLVMInt8Type (), 0, FALSE);
2873 args [2] = LLVMConstInt (LLVMInt32Type (), size, FALSE);
2874 args [3] = LLVMConstInt (LLVMInt32Type (), MONO_ARCH_FRAME_ALIGNMENT, FALSE);
2875 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
2876 LLVMBuildCall (builder, LLVMGetNamedFunction (module, memset_func_name), args, memset_param_count, "");
2879 values [ins->dreg] = v;
2883 LLVMValueRef v, size;
2885 size = LLVMBuildAnd (builder, LLVMBuildAdd (builder, convert (ctx, lhs, LLVMInt32Type ()), LLVMConstInt (LLVMInt32Type (), MONO_ARCH_FRAME_ALIGNMENT - 1, FALSE), ""), LLVMConstInt (LLVMInt32Type (), ~ (MONO_ARCH_FRAME_ALIGNMENT - 1), FALSE), "");
2887 v = mono_llvm_build_alloca (builder, LLVMInt8Type (), size, MONO_ARCH_FRAME_ALIGNMENT, "");
2889 if (ins->flags & MONO_INST_INIT) {
2890 LLVMValueRef args [5];
2893 args [1] = LLVMConstInt (LLVMInt8Type (), 0, FALSE);
2895 args [3] = LLVMConstInt (LLVMInt32Type (), MONO_ARCH_FRAME_ALIGNMENT, FALSE);
2896 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
2897 LLVMBuildCall (builder, LLVMGetNamedFunction (module, memset_func_name), args, memset_param_count, "");
2899 values [ins->dreg] = v;
2903 case OP_LOADI1_MEMBASE:
2904 case OP_LOADU1_MEMBASE:
2905 case OP_LOADI2_MEMBASE:
2906 case OP_LOADU2_MEMBASE:
2907 case OP_LOADI4_MEMBASE:
2908 case OP_LOADU4_MEMBASE:
2909 case OP_LOADI8_MEMBASE:
2910 case OP_LOADR4_MEMBASE:
2911 case OP_LOADR8_MEMBASE:
2912 case OP_LOAD_MEMBASE:
2920 LLVMValueRef index, addr;
2922 gboolean sext = FALSE, zext = FALSE;
2923 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
2925 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
2930 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)) {
2931 addr = LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE);
2932 } else if (ins->inst_offset == 0) {
2933 addr = values [ins->inst_basereg];
2934 } else if (ins->inst_offset % size != 0) {
2935 /* Unaligned load */
2936 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset, FALSE);
2937 addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_basereg], LLVMPointerType (LLVMInt8Type (), 0)), &index, 1, "");
2939 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
2940 addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_basereg], LLVMPointerType (t, 0)), &index, 1, "");
2943 addr = convert (ctx, addr, LLVMPointerType (t, 0));
2945 values [ins->dreg] = emit_load (ctx, bb, &builder, size, addr, dname, is_volatile);
2947 if (!is_volatile && (ins->flags & MONO_INST_CONSTANT_LOAD)) {
2949 * These will signal LLVM that these loads do not alias any stores, and
2950 * they can't fail, allowing them to be hoisted out of loops.
2952 set_metadata_flag (values [ins->dreg], "mono.noalias");
2953 set_metadata_flag (values [ins->dreg], "mono.nofail.load");
2957 values [ins->dreg] = LLVMBuildSExt (builder, values [ins->dreg], LLVMInt32Type (), dname);
2959 values [ins->dreg] = LLVMBuildZExt (builder, values [ins->dreg], LLVMInt32Type (), dname);
2960 else if (ins->opcode == OP_LOADR4_MEMBASE)
2961 values [ins->dreg] = LLVMBuildFPExt (builder, values [ins->dreg], LLVMDoubleType (), dname);
2965 case OP_STOREI1_MEMBASE_REG:
2966 case OP_STOREI2_MEMBASE_REG:
2967 case OP_STOREI4_MEMBASE_REG:
2968 case OP_STOREI8_MEMBASE_REG:
2969 case OP_STORER4_MEMBASE_REG:
2970 case OP_STORER8_MEMBASE_REG:
2971 case OP_STORE_MEMBASE_REG: {
2973 LLVMValueRef index, addr;
2975 gboolean sext = FALSE, zext = FALSE;
2976 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
2978 if (!values [ins->inst_destbasereg])
2979 LLVM_FAILURE (ctx, "inst_destbasereg");
2981 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
2983 if (ins->inst_offset % size != 0) {
2984 /* Unaligned store */
2985 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset, FALSE);
2986 addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (LLVMInt8Type (), 0)), &index, 1, "");
2988 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
2989 addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (t, 0)), &index, 1, "");
2991 emit_store (ctx, bb, &builder, size, convert (ctx, values [ins->sreg1], t), convert (ctx, addr, LLVMPointerType (t, 0)), is_volatile);
2995 case OP_STOREI1_MEMBASE_IMM:
2996 case OP_STOREI2_MEMBASE_IMM:
2997 case OP_STOREI4_MEMBASE_IMM:
2998 case OP_STOREI8_MEMBASE_IMM:
2999 case OP_STORE_MEMBASE_IMM: {
3001 LLVMValueRef index, addr;
3003 gboolean sext = FALSE, zext = FALSE;
3004 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
3006 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
3008 if (ins->inst_offset % size != 0) {
3009 /* Unaligned store */
3010 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset, FALSE);
3011 addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (LLVMInt8Type (), 0)), &index, 1, "");
3013 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
3014 addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (t, 0)), &index, 1, "");
3016 emit_store (ctx, bb, &builder, size, convert (ctx, LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE), t), addr, is_volatile);
3021 emit_load (ctx, bb, &builder, sizeof (gpointer), convert (ctx, values [ins->sreg1], LLVMPointerType (IntPtrType (), 0)), "", TRUE);
3023 case OP_OUTARG_VTRETADDR:
3030 case OP_VOIDCALL_MEMBASE:
3031 case OP_CALL_MEMBASE:
3032 case OP_LCALL_MEMBASE:
3033 case OP_FCALL_MEMBASE:
3034 case OP_VCALL_MEMBASE:
3035 case OP_VOIDCALL_REG:
3039 case OP_VCALL_REG: {
3040 process_call (ctx, bb, &builder, ins);
3041 CHECK_FAILURE (ctx);
3046 LLVMValueRef indexes [2];
3048 LLVMValueRef got_entry_addr;
3051 * FIXME: Can't allocate from the cfg mempool since that is freed if
3052 * the LLVM compile fails.
3054 ji = g_new0 (MonoJumpInfo, 1);
3055 ji->type = (MonoJumpInfoType)ins->inst_i1;
3056 ji->data.target = ins->inst_p0;
3058 ji = mono_aot_patch_info_dup (ji);
3060 ji->next = cfg->patch_info;
3061 cfg->patch_info = ji;
3063 //mono_add_patch_info (cfg, 0, (MonoJumpInfoType)ins->inst_i1, ins->inst_p0);
3064 got_offset = mono_aot_get_got_offset (cfg->patch_info);
3066 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
3067 indexes [1] = LLVMConstInt (LLVMInt32Type (), (gssize)got_offset, FALSE);
3068 got_entry_addr = LLVMBuildGEP (builder, ctx->lmodule->got_var, indexes, 2, "");
3070 // FIXME: This doesn't work right now, because it must be
3071 // paired with an invariant.end, and even then, its only in effect
3072 // inside its basic block
3075 LLVMValueRef args [3];
3076 LLVMValueRef ptr, val;
3078 ptr = LLVMBuildBitCast (builder, got_entry_addr, LLVMPointerType (LLVMInt8Type (), 0), "ptr");
3080 args [0] = LLVMConstInt (LLVMInt64Type (), sizeof (gpointer), FALSE);
3082 val = LLVMBuildCall (builder, LLVMGetNamedFunction (module, "llvm.invariant.start"), args, 2, "");
3086 values [ins->dreg] = LLVMBuildLoad (builder, got_entry_addr, dname);
3089 case OP_NOT_REACHED:
3090 LLVMBuildUnreachable (builder);
3091 has_terminator = TRUE;
3092 g_assert (bb->block_num < cfg->max_block_num);
3093 ctx->unreachable [bb->block_num] = TRUE;
3094 /* Might have instructions after this */
3096 MonoInst *next = ins->next;
3098 * FIXME: If later code uses the regs defined by these instructions,
3099 * compilation will fail.
3101 MONO_DELETE_INS (bb, next);
3105 MonoInst *var = ins->inst_p0;
3107 values [ins->dreg] = addresses [var->dreg];
3111 LLVMValueRef args [1];
3113 args [0] = convert (ctx, lhs, LLVMDoubleType ());
3114 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, "llvm.sin.f64"), args, 1, dname);
3118 LLVMValueRef args [1];
3120 args [0] = convert (ctx, lhs, LLVMDoubleType ());
3121 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, "llvm.cos.f64"), args, 1, dname);
3125 LLVMValueRef args [1];
3128 * LLVM optimizes sqrt(nan) into undefined in
3129 * lib/Analysis/ConstantFolding.cpp
3130 * Also, sqrt(NegativeInfinity) is optimized into 0.
3132 LLVM_FAILURE (ctx, "sqrt");
3134 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, "llvm.sqrt.f64"), args, 1, dname);
3138 LLVMValueRef args [1];
3141 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, "fabs"), args, 1, dname);
3155 lhs = convert (ctx, lhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
3156 rhs = convert (ctx, rhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
3158 switch (ins->opcode) {
3161 v = LLVMBuildICmp (builder, LLVMIntSLE, lhs, rhs, "");
3165 v = LLVMBuildICmp (builder, LLVMIntSGE, lhs, rhs, "");
3169 v = LLVMBuildICmp (builder, LLVMIntULE, lhs, rhs, "");
3173 v = LLVMBuildICmp (builder, LLVMIntUGE, lhs, rhs, "");
3176 g_assert_not_reached ();
3179 values [ins->dreg] = LLVMBuildSelect (builder, v, lhs, rhs, dname);
3182 case OP_ATOMIC_EXCHANGE_I4: {
3183 LLVMValueRef args [2];
3185 g_assert (ins->inst_offset == 0);
3187 args [0] = convert (ctx, lhs, LLVMPointerType (LLVMInt32Type (), 0));
3189 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, "llvm.atomic.swap.i32.p0i32"), args, 2, dname);
3192 case OP_ATOMIC_EXCHANGE_I8: {
3193 LLVMValueRef args [2];
3195 g_assert (ins->inst_offset == 0);
3197 args [0] = convert (ctx, lhs, LLVMPointerType (LLVMInt64Type (), 0));
3198 args [1] = convert (ctx, rhs, LLVMInt64Type ());
3199 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, "llvm.atomic.swap.i64.p0i64"), args, 2, dname);
3202 case OP_ATOMIC_ADD_NEW_I4: {
3203 LLVMValueRef args [2];
3205 g_assert (ins->inst_offset == 0);
3207 args [0] = convert (ctx, lhs, LLVMPointerType (LLVMInt32Type (), 0));
3209 values [ins->dreg] = LLVMBuildAdd (builder, LLVMBuildCall (builder, LLVMGetNamedFunction (module, "llvm.atomic.load.add.i32.p0i32"), args, 2, ""), args [1], dname);
3212 case OP_ATOMIC_ADD_NEW_I8: {
3213 LLVMValueRef args [2];
3215 g_assert (ins->inst_offset == 0);
3217 args [0] = convert (ctx, lhs, LLVMPointerType (LLVMInt64Type (), 0));
3218 args [1] = convert (ctx, rhs, LLVMInt64Type ());
3219 values [ins->dreg] = LLVMBuildAdd (builder, LLVMBuildCall (builder, LLVMGetNamedFunction (module, "llvm.atomic.load.add.i64.p0i64"), args, 2, ""), args [1], dname);
3222 case OP_ATOMIC_CAS_I4:
3223 case OP_ATOMIC_CAS_I8: {
3224 LLVMValueRef args [3];
3226 const char *intrins;
3228 if (ins->opcode == OP_ATOMIC_CAS_I4) {
3229 t = LLVMInt32Type ();
3230 intrins = "llvm.atomic.cmp.swap.i32.p0i32";
3232 t = LLVMInt64Type ();
3233 intrins = "llvm.atomic.cmp.swap.i64.p0i64";
3236 args [0] = convert (ctx, lhs, LLVMPointerType (t, 0));
3238 args [1] = convert (ctx, values [ins->sreg3], t);
3240 args [2] = convert (ctx, values [ins->sreg2], t);
3241 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, intrins), args, 3, dname);
3244 case OP_MEMORY_BARRIER: {
3245 LLVMValueRef args [5];
3248 /* Not yet supported by llc on arm */
3249 LLVM_FAILURE (ctx, "memory-barrier+arm");
3252 for (i = 0; i < 5; ++i)
3253 args [i] = LLVMConstInt (LLVMInt1Type (), TRUE, TRUE);
3255 LLVMBuildCall (builder, LLVMGetNamedFunction (module, "llvm.memory.barrier"), args, 5, "");
3258 case OP_RELAXED_NOP: {
3259 #if defined(TARGET_AMD64) || defined(TARGET_X86)
3260 /* No way to get LLVM to emit this */
3261 LLVM_FAILURE (ctx, "relaxed_nop");
3267 #if defined(TARGET_AMD64) || defined(TARGET_X86)
3269 // 257 == FS segment register
3270 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 257);
3272 // 256 == GS segment register
3273 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 256);
3277 values [ins->dreg] = LLVMBuildLoad (builder, LLVMBuildIntToPtr (builder, LLVMConstInt (IntPtrType (), ins->inst_offset, TRUE), ptrtype, ""), "");
3279 LLVM_FAILURE (ctx, "opcode tls-get");
3289 case OP_IADD_OVF_UN:
3291 case OP_ISUB_OVF_UN:
3293 case OP_IMUL_OVF_UN:
3294 #if SIZEOF_VOID_P == 8
3296 case OP_LADD_OVF_UN:
3298 case OP_LSUB_OVF_UN:
3300 case OP_LMUL_OVF_UN:
3303 LLVMValueRef args [2], val, ovf, func;
3305 args [0] = convert (ctx, lhs, op_to_llvm_type (ins->opcode));
3306 args [1] = convert (ctx, rhs, op_to_llvm_type (ins->opcode));
3307 func = LLVMGetNamedFunction (module, ovf_op_to_intrins (ins->opcode));
3309 val = LLVMBuildCall (builder, func, args, 2, "");
3310 values [ins->dreg] = LLVMBuildExtractValue (builder, val, 0, dname);
3311 ovf = LLVMBuildExtractValue (builder, val, 1, "");
3312 emit_cond_system_exception (ctx, bb, "OverflowException", ovf);
3313 CHECK_FAILURE (ctx);
3314 builder = ctx->builder;
3320 * We currently model them using arrays. Promotion to local vregs is
3321 * disabled for them in mono_handle_global_vregs () in the LLVM case,
3322 * so we always have an entry in cfg->varinfo for them.
3323 * FIXME: Is this needed ?
3326 MonoClass *klass = ins->klass;
3327 LLVMValueRef args [5];
3331 LLVM_FAILURE (ctx, "!klass");
3335 if (!addresses [ins->dreg])
3336 addresses [ins->dreg] = build_alloca (ctx, &klass->byval_arg);
3337 args [0] = LLVMBuildBitCast (builder, addresses [ins->dreg], LLVMPointerType (LLVMInt8Type (), 0), "");
3338 args [1] = LLVMConstInt (LLVMInt8Type (), 0, FALSE);
3339 args [2] = LLVMConstInt (LLVMInt32Type (), mono_class_value_size (klass, NULL), FALSE);
3341 args [3] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
3342 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
3343 LLVMBuildCall (builder, LLVMGetNamedFunction (module, memset_func_name), args, memset_param_count, "");
3347 case OP_STOREV_MEMBASE:
3348 case OP_LOADV_MEMBASE:
3350 MonoClass *klass = ins->klass;
3351 LLVMValueRef src, dst, args [5];
3352 gboolean done = FALSE;
3356 LLVM_FAILURE (ctx, "!klass");
3360 switch (ins->opcode) {
3361 case OP_STOREV_MEMBASE:
3362 if (cfg->gen_write_barriers && klass->has_references && ins->inst_destbasereg != cfg->frame_reg) {
3363 /* FIXME: Emit write barriers like in mini_emit_stobj () */
3364 LLVM_FAILURE (ctx, "storev_membase + write barriers");
3367 if (!addresses [ins->sreg1]) {
3369 g_assert (values [ins->sreg1]);
3370 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));
3371 LLVMBuildStore (builder, values [ins->sreg1], dst);
3374 src = LLVMBuildBitCast (builder, addresses [ins->sreg1], LLVMPointerType (LLVMInt8Type (), 0), "");
3375 dst = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_destbasereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (LLVMInt8Type (), 0));
3378 case OP_LOADV_MEMBASE:
3379 if (!addresses [ins->dreg])
3380 addresses [ins->dreg] = build_alloca (ctx, &klass->byval_arg);
3381 src = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_basereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (LLVMInt8Type (), 0));
3382 dst = LLVMBuildBitCast (builder, addresses [ins->dreg], LLVMPointerType (LLVMInt8Type (), 0), "");
3385 if (!addresses [ins->sreg1])
3386 addresses [ins->sreg1] = build_alloca (ctx, &klass->byval_arg);
3387 if (!addresses [ins->dreg])
3388 addresses [ins->dreg] = build_alloca (ctx, &klass->byval_arg);
3389 src = LLVMBuildBitCast (builder, addresses [ins->sreg1], LLVMPointerType (LLVMInt8Type (), 0), "");
3390 dst = LLVMBuildBitCast (builder, addresses [ins->dreg], LLVMPointerType (LLVMInt8Type (), 0), "");
3393 g_assert_not_reached ();
3395 CHECK_FAILURE (ctx);
3402 args [2] = LLVMConstInt (LLVMInt32Type (), mono_class_value_size (klass, NULL), FALSE);
3403 args [3] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
3405 args [3] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
3406 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
3407 LLVMBuildCall (builder, LLVMGetNamedFunction (module, memcpy_func_name), args, memcpy_param_count, "");
3410 case OP_LLVM_OUTARG_VT:
3411 if (!addresses [ins->sreg1]) {
3412 addresses [ins->sreg1] = build_alloca (ctx, &ins->klass->byval_arg);
3413 g_assert (values [ins->sreg1]);
3414 LLVMBuildStore (builder, values [ins->sreg1], addresses [ins->sreg1]);
3416 addresses [ins->dreg] = addresses [ins->sreg1];
3422 #if defined(TARGET_X86) || defined(TARGET_AMD64)
3424 values [ins->dreg] = LLVMConstNull (type_to_llvm_type (ctx, &ins->klass->byval_arg));
3427 case OP_LOADX_MEMBASE: {
3428 LLVMTypeRef t = type_to_llvm_type (ctx, &ins->klass->byval_arg);
3431 src = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_basereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (t, 0));
3432 values [ins->dreg] = mono_llvm_build_aligned_load (builder, src, "", FALSE, 1);
3435 case OP_STOREX_MEMBASE: {
3436 LLVMTypeRef t = LLVMTypeOf (values [ins->sreg1]);
3439 dest = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_destbasereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (t, 0));
3440 mono_llvm_build_aligned_store (builder, values [ins->sreg1], dest, FALSE, 1);
3447 values [ins->dreg] = LLVMBuildAdd (builder, lhs, rhs, "");
3451 values [ins->dreg] = LLVMBuildFAdd (builder, lhs, rhs, "");
3457 values [ins->dreg] = LLVMBuildSub (builder, lhs, rhs, "");
3461 values [ins->dreg] = LLVMBuildFSub (builder, lhs, rhs, "");
3465 values [ins->dreg] = LLVMBuildFMul (builder, lhs, rhs, "");
3469 values [ins->dreg] = LLVMBuildFDiv (builder, lhs, rhs, "");
3472 values [ins->dreg] = LLVMBuildAnd (builder, lhs, rhs, "");
3475 values [ins->dreg] = LLVMBuildOr (builder, lhs, rhs, "");
3478 values [ins->dreg] = LLVMBuildXor (builder, lhs, rhs, "");
3491 switch (ins->opcode) {
3496 t = LLVMVectorType (LLVMInt32Type (), 4);
3497 rt = LLVMVectorType (LLVMFloatType (), 4);
3503 t = LLVMVectorType (LLVMInt64Type (), 2);
3504 rt = LLVMVectorType (LLVMDoubleType (), 2);
3507 t = LLVMInt32Type ();
3508 rt = LLVMInt32Type ();
3509 g_assert_not_reached ();
3512 lhs = LLVMBuildBitCast (builder, lhs, t, "");
3513 rhs = LLVMBuildBitCast (builder, rhs, t, "");
3514 switch (ins->opcode) {
3517 v = LLVMBuildAnd (builder, lhs, rhs, "");
3521 v = LLVMBuildOr (builder, lhs, rhs, "");
3525 v = LLVMBuildXor (builder, lhs, rhs, "");
3529 v = LLVMBuildAnd (builder, rhs, LLVMBuildNot (builder, lhs, ""), "");
3532 values [ins->dreg] = LLVMBuildBitCast (builder, v, rt, "");
3555 case OP_PADDB_SAT_UN:
3556 case OP_PADDW_SAT_UN:
3557 case OP_PSUBB_SAT_UN:
3558 case OP_PSUBW_SAT_UN:
3564 LLVMValueRef args [2];
3569 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, simd_op_to_intrins (ins->opcode)), args, 2, dname);
3577 case OP_EXTRACTX_U2:
3579 case OP_EXTRACT_U1: {
3581 gboolean zext = FALSE;
3583 t = simd_op_to_llvm_type (ins->opcode);
3585 switch (ins->opcode) {
3593 case OP_EXTRACTX_U2:
3598 t = LLVMInt32Type ();
3599 g_assert_not_reached ();
3602 lhs = LLVMBuildBitCast (builder, lhs, t, "");
3603 values [ins->dreg] = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), "");
3605 values [ins->dreg] = LLVMBuildZExt (builder, values [ins->dreg], LLVMInt32Type (), "");
3614 case OP_EXPAND_R8: {
3615 LLVMTypeRef t = simd_op_to_llvm_type (ins->opcode);
3616 LLVMValueRef mask [16], v;
3618 for (i = 0; i < 16; ++i)
3619 mask [i] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
3621 v = convert (ctx, values [ins->sreg1], LLVMGetElementType (t));
3623 values [ins->dreg] = LLVMBuildInsertElement (builder, LLVMConstNull (t), v, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
3624 values [ins->dreg] = LLVMBuildShuffleVector (builder, values [ins->dreg], LLVMGetUndef (t), LLVMConstVector (mask, LLVMGetVectorSize (t)), "");
3636 case OP_EXTRACT_MASK: {
3639 v = convert (ctx, values [ins->sreg1], simd_op_to_llvm_type (ins->opcode));
3641 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, simd_op_to_intrins (ins->opcode)), &v, 1, dname);
3645 case OP_ICONV_TO_R8_RAW:
3646 /* Same as OP_ICONV_TO_R8 */
3647 values [ins->dreg] = convert (ctx, LLVMBuildBitCast (builder, lhs, LLVMFloatType (), ""), LLVMDoubleType ());
3652 LLVMValueRef args [3];
3656 args [2] = LLVMConstInt (LLVMInt8Type (), ins->inst_c0, FALSE);
3658 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, simd_op_to_intrins (ins->opcode)), args, 3, dname);
3668 LLVMValueRef args [3];
3671 args [1] = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
3673 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, simd_op_to_intrins (ins->opcode)), args, 2, dname);
3683 * EXCEPTION HANDLING
3685 case OP_IMPLICIT_EXCEPTION:
3686 /* This marks a place where an implicit exception can happen */
3687 if (bb->region != -1)
3688 LLVM_FAILURE (ctx, "implicit-exception");
3692 MonoMethodSignature *throw_sig;
3693 LLVMValueRef callee, arg;
3694 gboolean rethrow = (ins->opcode == OP_RETHROW);
3695 const char *icall_name;
3697 callee = rethrow ? ctx->lmodule->rethrow : ctx->lmodule->throw;
3698 icall_name = rethrow ? "mono_arch_rethrow_exception" : "mono_arch_throw_exception";
3701 throw_sig = mono_metadata_signature_alloc (mono_get_corlib (), 1);
3702 throw_sig->ret = &mono_get_void_class ()->byval_arg;
3703 throw_sig->params [0] = &mono_get_object_class ()->byval_arg;
3704 if (cfg->compile_aot) {
3705 callee = get_plt_entry (ctx, sig_to_llvm_sig (ctx, throw_sig), MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
3707 callee = LLVMAddFunction (module, icall_name, sig_to_llvm_sig (ctx, throw_sig));
3711 * LLVM doesn't push the exception argument, so we need a different
3714 LLVMAddGlobalMapping (ee, callee, resolve_patch (cfg, MONO_PATCH_INFO_INTERNAL_METHOD, rethrow ? "llvm_rethrow_exception_trampoline" : "llvm_throw_exception_trampoline"));
3716 LLVMAddGlobalMapping (ee, callee, resolve_patch (cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name));
3720 mono_memory_barrier ();
3722 ctx->lmodule->rethrow = callee;
3724 ctx->lmodule->throw = callee;
3726 arg = convert (ctx, values [ins->sreg1], type_to_llvm_type (ctx, &mono_get_object_class ()->byval_arg));
3727 emit_call (ctx, bb, &builder, callee, &arg, 1);
3730 case OP_CALL_HANDLER: {
3732 * We don't 'call' handlers, but instead simply branch to them.
3733 * The code generated by ENDFINALLY will branch back to us.
3735 LLVMBasicBlockRef noex_bb;
3737 BBInfo *info = &bblocks [ins->inst_target_bb->block_num];
3739 bb_list = info->call_handler_return_bbs;
3742 * Set the indicator variable for the finally clause.
3744 lhs = info->finally_ind;
3746 LLVMBuildStore (builder, LLVMConstInt (LLVMInt32Type (), g_slist_length (bb_list) + 1, FALSE), lhs);
3748 /* Branch to the finally clause */
3749 LLVMBuildBr (builder, info->call_handler_target_bb);
3751 noex_bb = gen_bb (ctx, "CALL_HANDLER_CONT_BB");
3752 info->call_handler_return_bbs = g_slist_append_mempool (cfg->mempool, info->call_handler_return_bbs, noex_bb);
3754 builder = ctx->builder = create_builder (ctx);
3755 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
3757 bblocks [bb->block_num].end_bblock = noex_bb;
3760 case OP_START_HANDLER: {
3763 case OP_ENDFINALLY: {
3764 LLVMBasicBlockRef resume_bb;
3765 MonoBasicBlock *handler_bb;
3766 LLVMValueRef val, switch_ins, callee;
3770 handler_bb = g_hash_table_lookup (ctx->region_to_handler, GUINT_TO_POINTER (mono_get_block_region_notry (cfg, bb->region)));
3771 g_assert (handler_bb);
3772 info = &bblocks [handler_bb->block_num];
3773 lhs = info->finally_ind;
3776 bb_list = info->call_handler_return_bbs;
3778 resume_bb = gen_bb (ctx, "ENDFINALLY_RESUME_BB");
3780 /* Load the finally variable */
3781 val = LLVMBuildLoad (builder, lhs, "");
3783 /* Reset the variable */
3784 LLVMBuildStore (builder, LLVMConstInt (LLVMInt32Type (), 0, FALSE), lhs);
3786 /* Branch to either resume_bb, or to the bblocks in bb_list */
3787 switch_ins = LLVMBuildSwitch (builder, val, resume_bb, g_slist_length (bb_list));
3789 * The other targets are added at the end to handle OP_CALL_HANDLER
3790 * opcodes processed later.
3792 info->endfinally_switch_ins_list = g_slist_append_mempool (cfg->mempool, info->endfinally_switch_ins_list, switch_ins);
3794 builder = ctx->builder = create_builder (ctx);
3795 LLVMPositionBuilderAtEnd (ctx->builder, resume_bb);
3797 if (ctx->cfg->compile_aot) {
3798 callee = get_plt_entry (ctx, LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE), MONO_PATCH_INFO_INTERNAL_METHOD, "llvm_resume_unwind_trampoline");
3800 callee = LLVMGetNamedFunction (module, "llvm_resume_unwind_trampoline");
3802 LLVMBuildCall (builder, callee, NULL, 0, "");
3804 LLVMBuildUnreachable (builder);
3805 has_terminator = TRUE;
3811 sprintf (reason, "opcode %s", mono_inst_name (ins->opcode));
3812 LLVM_FAILURE (ctx, reason);
3817 /* Convert the value to the type required by phi nodes */
3818 if (spec [MONO_INST_DEST] != ' ' && !MONO_IS_STORE_MEMBASE (ins) && ctx->vreg_types [ins->dreg]) {
3819 if (!values [ins->dreg])
3821 values [ins->dreg] = addresses [ins->dreg];
3823 values [ins->dreg] = convert (ctx, values [ins->dreg], ctx->vreg_types [ins->dreg]);
3826 /* Add stores for volatile variables */
3827 if (spec [MONO_INST_DEST] != ' ' && spec [MONO_INST_DEST] != 'v' && !MONO_IS_STORE_MEMBASE (ins))
3828 emit_volatile_store (ctx, ins->dreg);
3831 if (!has_terminator && bb->next_bb && (bb == cfg->bb_entry || bb->in_count > 0))
3832 LLVMBuildBr (builder, get_bb (ctx, bb->next_bb));
3834 if (bb == cfg->bb_exit && sig->ret->type == MONO_TYPE_VOID)
3835 LLVMBuildRetVoid (builder);
3837 if (bb == cfg->bb_entry)
3838 ctx->last_alloca = LLVMGetLastInstruction (get_bb (ctx, cfg->bb_entry));
3847 * mono_llvm_check_method_supported:
3849 * Do some quick checks to decide whenever cfg->method can be compiled by LLVM, to avoid
3850 * compiling a method twice.
3853 mono_llvm_check_method_supported (MonoCompile *cfg)
3856 MonoMethodHeader *header = cfg->header;
3857 MonoExceptionClause *clause;
3861 if (cfg->generic_sharing_context && !IS_LLVM_MONO_BRANCH) {
3862 /* No way to obtain location info for this/rgctx */
3863 cfg->exception_message = g_strdup ("gshared");
3864 cfg->disable_llvm = TRUE;
3867 if (cfg->method->save_lmf) {
3868 cfg->exception_message = g_strdup ("lmf");
3869 cfg->disable_llvm = TRUE;
3872 if (!LLVM_CHECK_VERSION (2, 8)) {
3874 * FIXME: LLLVM 2.6 no longer seems to generate correct exception info
3877 cfg->exception_message = g_strdup ("clauses");
3878 cfg->disable_llvm = TRUE;
3882 for (i = 0; i < header->num_clauses; ++i) {
3883 clause = &header->clauses [i];
3885 if (i > 0 && clause->try_offset <= header->clauses [i - 1].handler_offset + header->clauses [i - 1].handler_len) {
3887 * FIXME: Some tests still fail with nested clauses.
3889 cfg->exception_message = g_strdup ("nested clauses");
3890 cfg->disable_llvm = TRUE;
3896 if (cfg->method->dynamic) {
3897 cfg->exception_message = g_strdup ("dynamic.");
3898 cfg->disable_llvm = TRUE;
3903 * mono_llvm_emit_method:
3905 * Emit LLVM IL from the mono IL, and compile it to native code using LLVM.
3908 mono_llvm_emit_method (MonoCompile *cfg)
3911 MonoMethodSignature *sig;
3913 LLVMTypeRef method_type;
3914 LLVMValueRef method = NULL;
3916 LLVMValueRef *values;
3917 int i, max_block_num, bb_index;
3918 gboolean last = FALSE;
3919 GPtrArray *phi_values;
3920 LLVMCallInfo *linfo;
3922 LLVMModuleRef module;
3924 GPtrArray *bblock_list;
3925 MonoMethodHeader *header;
3926 MonoExceptionClause *clause;
3930 /* The code below might acquire the loader lock, so use it for global locking */
3931 mono_loader_lock ();
3933 /* Used to communicate with the callbacks */
3934 TlsSetValue (current_cfg_tls_id, cfg);
3936 ctx = g_new0 (EmitContext, 1);
3938 ctx->mempool = cfg->mempool;
3941 * This maps vregs to the LLVM instruction defining them
3943 values = g_new0 (LLVMValueRef, cfg->next_vreg);
3945 * This maps vregs for volatile variables to the LLVM instruction defining their
3948 ctx->addresses = g_new0 (LLVMValueRef, cfg->next_vreg);
3949 ctx->vreg_types = g_new0 (LLVMTypeRef, cfg->next_vreg);
3950 ctx->vreg_cli_types = g_new0 (MonoType*, cfg->next_vreg);
3951 phi_values = g_ptr_array_new ();
3953 * This signals whenever the vreg was defined by a phi node with no input vars
3954 * (i.e. all its input bblocks end with NOT_REACHABLE).
3956 ctx->is_dead = g_new0 (gboolean, cfg->next_vreg);
3957 /* Whenever the bblock is unreachable */
3958 ctx->unreachable = g_new0 (gboolean, cfg->max_block_num);
3960 bblock_list = g_ptr_array_new ();
3962 ctx->values = values;
3963 ctx->region_to_handler = g_hash_table_new (NULL, NULL);
3965 if (cfg->compile_aot) {
3966 ctx->lmodule = &aot_module;
3967 method_name = mono_aot_get_method_name (cfg);
3968 cfg->llvm_method_name = g_strdup (method_name);
3971 ctx->lmodule = &jit_module;
3972 method_name = mono_method_full_name (cfg->method, TRUE);
3975 module = ctx->module = ctx->lmodule->module;
3979 static int count = 0;
3982 if (getenv ("LLVM_COUNT")) {
3983 if (count == atoi (getenv ("LLVM_COUNT"))) {
3984 printf ("LAST: %s\n", mono_method_full_name (cfg->method, TRUE));
3988 if (count > atoi (getenv ("LLVM_COUNT")))
3989 LLVM_FAILURE (ctx, "");
3994 sig = mono_method_signature (cfg->method);
3997 linfo = mono_arch_get_llvm_call_info (cfg, sig);
3999 CHECK_FAILURE (ctx);
4001 if (cfg->rgctx_var) {
4002 if (IS_LLVM_MONO_BRANCH)
4003 linfo->rgctx_arg = TRUE;
4005 LLVM_FAILURE (ctx, "rgctx arg");
4007 method_type = sig_to_llvm_sig_full (ctx, sig, linfo, &sinfo);
4008 CHECK_FAILURE (ctx);
4011 * This maps parameter indexes in the original signature to the indexes in
4012 * the LLVM signature.
4014 ctx->pindexes = sinfo.pindexes;
4016 method = LLVMAddFunction (module, method_name, method_type);
4017 ctx->lmethod = method;
4019 #ifdef LLVM_MONO_BRANCH
4020 LLVMSetFunctionCallConv (method, LLVMMono1CallConv);
4022 LLVMSetLinkage (method, LLVMPrivateLinkage);
4024 if (cfg->compile_aot) {
4025 LLVMSetLinkage (method, LLVMInternalLinkage);
4026 LLVMSetVisibility (method, LLVMHiddenVisibility);
4028 LLVMSetLinkage (method, LLVMPrivateLinkage);
4031 if (cfg->method->save_lmf)
4032 LLVM_FAILURE (ctx, "lmf");
4035 LLVM_FAILURE (ctx, "pinvoke signature");
4037 header = cfg->header;
4038 for (i = 0; i < header->num_clauses; ++i) {
4039 clause = &header->clauses [i];
4040 if (clause->flags != MONO_EXCEPTION_CLAUSE_FINALLY && clause->flags != MONO_EXCEPTION_CLAUSE_NONE)
4041 LLVM_FAILURE (ctx, "non-finally/catch clause.");
4044 if (linfo->rgctx_arg) {
4045 ctx->rgctx_arg = LLVMGetParam (method, sinfo.rgctx_arg_pindex);
4047 * We mark the rgctx parameter with the inreg attribute, which is mapped to
4048 * MONO_ARCH_RGCTX_REG in the Mono calling convention in llvm, i.e.
4049 * CC_X86_64_Mono in X86CallingConv.td.
4051 LLVMAddAttribute (ctx->rgctx_arg, LLVMInRegAttribute);
4052 LLVMSetValueName (ctx->rgctx_arg, "rgctx");
4054 if (cfg->vret_addr) {
4055 values [cfg->vret_addr->dreg] = LLVMGetParam (method, sinfo.vret_arg_pindex);
4056 LLVMSetValueName (values [cfg->vret_addr->dreg], "vret");
4059 values [cfg->args [0]->dreg] = LLVMGetParam (method, sinfo.this_arg_pindex);
4060 LLVMSetValueName (values [cfg->args [0]->dreg], "this");
4063 names = g_new (char *, sig->param_count);
4064 mono_method_get_param_names (cfg->method, (const char **) names);
4066 for (i = 0; i < sig->param_count; ++i) {
4069 values [cfg->args [i + sig->hasthis]->dreg] = LLVMGetParam (method, sinfo.pindexes [i]);
4070 if (names [i] && names [i][0] != '\0')
4071 name = g_strdup_printf ("arg_%s", names [i]);
4073 name = g_strdup_printf ("arg_%d", i);
4074 LLVMSetValueName (values [cfg->args [i + sig->hasthis]->dreg], name);
4076 if (linfo->args [i + sig->hasthis].storage == LLVMArgVtypeByVal)
4077 LLVMAddAttribute (LLVMGetParam (method, sinfo.pindexes [i]), LLVMByValAttribute);
4082 for (bb = cfg->bb_entry; bb; bb = bb->next_bb)
4083 max_block_num = MAX (max_block_num, bb->block_num);
4084 ctx->bblocks = bblocks = g_new0 (BBInfo, max_block_num + 1);
4086 /* Add branches between non-consecutive bblocks */
4087 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
4088 if (bb->last_ins && MONO_IS_COND_BRANCH_OP (bb->last_ins) &&
4089 bb->next_bb != bb->last_ins->inst_false_bb) {
4091 MonoInst *inst = mono_mempool_alloc0 (cfg->mempool, sizeof (MonoInst));
4092 inst->opcode = OP_BR;
4093 inst->inst_target_bb = bb->last_ins->inst_false_bb;
4094 mono_bblock_add_inst (bb, inst);
4099 * The INDIRECT flag added by OP_LDADDR inhibits optimizations, even if the LDADDR
4100 * was later optimized away, so clear these flags, and add them back for the still
4101 * present OP_LDADDR instructions.
4103 for (i = 0; i < cfg->next_vreg; ++i) {
4106 ins = get_vreg_to_inst (cfg, i);
4107 if (ins && ins != cfg->rgctx_var)
4108 ins->flags &= ~MONO_INST_INDIRECT;
4112 * Make a first pass over the code to precreate PHI nodes/set INDIRECT flags.
4114 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
4116 LLVMBuilderRef builder;
4118 char dname_buf[128];
4120 builder = create_builder (ctx);
4122 for (ins = bb->code; ins; ins = ins->next) {
4123 switch (ins->opcode) {
4128 LLVMTypeRef phi_type = llvm_type_to_stack_type (type_to_llvm_type (ctx, &ins->klass->byval_arg));
4130 CHECK_FAILURE (ctx);
4132 if (ins->opcode == OP_VPHI) {
4133 /* Treat valuetype PHI nodes as operating on the address itself */
4134 g_assert (ins->klass);
4135 phi_type = LLVMPointerType (type_to_llvm_type (ctx, &ins->klass->byval_arg), 0);
4139 * Have to precreate these, as they can be referenced by
4140 * earlier instructions.
4142 sprintf (dname_buf, "t%d", ins->dreg);
4144 values [ins->dreg] = LLVMBuildPhi (builder, phi_type, dname);
4146 if (ins->opcode == OP_VPHI)
4147 ctx->addresses [ins->dreg] = values [ins->dreg];
4149 g_ptr_array_add (phi_values, values [ins->dreg]);
4152 * Set the expected type of the incoming arguments since these have
4153 * to have the same type.
4155 for (i = 0; i < ins->inst_phi_args [0]; i++) {
4156 int sreg1 = ins->inst_phi_args [i + 1];
4159 ctx->vreg_types [sreg1] = phi_type;
4164 ((MonoInst*)ins->inst_p0)->flags |= MONO_INST_INDIRECT;
4173 * Create an ordering for bblocks, use the depth first order first, then
4174 * put the exception handling bblocks last.
4176 for (bb_index = 0; bb_index < cfg->num_bblocks; ++bb_index) {
4177 bb = cfg->bblocks [bb_index];
4178 if (!(bb->region != -1 && !MONO_BBLOCK_IS_IN_REGION (bb, MONO_REGION_TRY))) {
4179 g_ptr_array_add (bblock_list, bb);
4180 bblocks [bb->block_num].added = TRUE;
4184 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
4185 if (!bblocks [bb->block_num].added)
4186 g_ptr_array_add (bblock_list, bb);
4190 * Second pass: generate code.
4192 for (bb_index = 0; bb_index < bblock_list->len; ++bb_index) {
4193 bb = g_ptr_array_index (bblock_list, bb_index);
4195 if (!(bb == cfg->bb_entry || bb->in_count > 0))
4198 process_bb (ctx, bb);
4199 CHECK_FAILURE (ctx);
4202 /* Add incoming phi values */
4203 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
4204 GSList *l, *ins_list;
4206 ins_list = bblocks [bb->block_num].phi_nodes;
4208 for (l = ins_list; l; l = l->next) {
4209 PhiNode *node = l->data;
4210 MonoInst *phi = node->phi;
4211 int sreg1 = node->sreg;
4212 LLVMBasicBlockRef in_bb;
4217 in_bb = get_end_bb (ctx, node->in_bb);
4219 if (ctx->unreachable [node->in_bb->block_num])
4222 g_assert (values [sreg1]);
4224 if (phi->opcode == OP_VPHI) {
4225 g_assert (LLVMTypeOf (ctx->addresses [sreg1]) == LLVMTypeOf (values [phi->dreg]));
4226 LLVMAddIncoming (values [phi->dreg], &ctx->addresses [sreg1], &in_bb, 1);
4228 g_assert (LLVMTypeOf (values [sreg1]) == LLVMTypeOf (values [phi->dreg]));
4229 LLVMAddIncoming (values [phi->dreg], &values [sreg1], &in_bb, 1);
4234 /* Create the SWITCH statements for ENDFINALLY instructions */
4235 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
4236 BBInfo *info = &bblocks [bb->block_num];
4238 for (l = info->endfinally_switch_ins_list; l; l = l->next) {
4239 LLVMValueRef switch_ins = l->data;
4240 GSList *bb_list = info->call_handler_return_bbs;
4242 for (i = 0; i < g_slist_length (bb_list); ++i)
4243 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), i + 1, FALSE), g_slist_nth (bb_list, i)->data);
4247 if (cfg->verbose_level > 1)
4248 mono_llvm_dump_value (method);
4250 mark_as_used (module, method);
4252 if (cfg->compile_aot) {
4253 /* Don't generate native code, keep the LLVM IR */
4254 if (cfg->compile_aot && cfg->verbose_level)
4255 printf ("%s emitted as %s\n", mono_method_full_name (cfg->method, TRUE), method_name);
4257 //LLVMVerifyFunction(method, 0);
4259 mono_llvm_optimize_method (method);
4261 if (cfg->verbose_level > 1)
4262 mono_llvm_dump_value (method);
4264 cfg->native_code = LLVMGetPointerToGlobal (ee, method);
4266 /* Set by emit_cb */
4267 g_assert (cfg->code_len);
4269 /* FIXME: Free the LLVM IL for the function */
4277 /* Need to add unused phi nodes as they can be referenced by other values */
4278 LLVMBasicBlockRef phi_bb = LLVMAppendBasicBlock (method, "PHI_BB");
4279 LLVMBuilderRef builder;
4281 builder = create_builder (ctx);
4282 LLVMPositionBuilderAtEnd (builder, phi_bb);
4284 for (i = 0; i < phi_values->len; ++i) {
4285 LLVMValueRef v = g_ptr_array_index (phi_values, i);
4286 if (LLVMGetInstructionParent (v) == NULL)
4287 LLVMInsertIntoBuilder (builder, v);
4290 LLVMDeleteFunction (method);
4295 g_free (ctx->addresses);
4296 g_free (ctx->vreg_types);
4297 g_free (ctx->vreg_cli_types);
4298 g_free (ctx->pindexes);
4299 g_free (ctx->is_dead);
4300 g_free (ctx->unreachable);
4301 g_ptr_array_free (phi_values, TRUE);
4302 g_free (ctx->bblocks);
4303 g_hash_table_destroy (ctx->region_to_handler);
4304 g_free (method_name);
4305 g_ptr_array_free (bblock_list, TRUE);
4307 for (l = ctx->builders; l; l = l->next) {
4308 LLVMBuilderRef builder = l->data;
4309 LLVMDisposeBuilder (builder);
4314 TlsSetValue (current_cfg_tls_id, NULL);
4316 mono_loader_unlock ();
4320 * mono_llvm_emit_call:
4322 * Same as mono_arch_emit_call () for LLVM.
4325 mono_llvm_emit_call (MonoCompile *cfg, MonoCallInst *call)
4328 MonoMethodSignature *sig;
4329 int i, n, stack_size;
4334 sig = call->signature;
4335 n = sig->param_count + sig->hasthis;
4337 call->cinfo = mono_arch_get_llvm_call_info (cfg, sig);
4339 if (cfg->disable_llvm)
4342 if (sig->call_convention == MONO_CALL_VARARG) {
4343 cfg->exception_message = g_strdup ("varargs");
4344 cfg->disable_llvm = TRUE;
4347 for (i = 0; i < n; ++i) {
4350 ainfo = call->cinfo->args + i;
4352 in = call->args [i];
4354 /* Simply remember the arguments */
4355 switch (ainfo->storage) {
4357 MONO_INST_NEW (cfg, ins, OP_MOVE);
4358 ins->dreg = mono_alloc_ireg (cfg);
4359 ins->sreg1 = in->dreg;
4361 case LLVMArgInFPReg:
4362 MONO_INST_NEW (cfg, ins, OP_FMOVE);
4363 ins->dreg = mono_alloc_freg (cfg);
4364 ins->sreg1 = in->dreg;
4366 case LLVMArgVtypeByVal:
4367 case LLVMArgVtypeInReg:
4368 MONO_INST_NEW (cfg, ins, OP_LLVM_OUTARG_VT);
4369 ins->dreg = mono_alloc_ireg (cfg);
4370 ins->sreg1 = in->dreg;
4371 ins->klass = mono_class_from_mono_type (sig->params [i - sig->hasthis]);
4374 call->cinfo = mono_arch_get_llvm_call_info (cfg, sig);
4375 cfg->exception_message = g_strdup ("ainfo->storage");
4376 cfg->disable_llvm = TRUE;
4380 if (!cfg->disable_llvm) {
4381 MONO_ADD_INS (cfg->cbb, ins);
4382 mono_call_inst_add_outarg_reg (cfg, call, ins->dreg, 0, FALSE);
4387 static unsigned char*
4388 alloc_cb (LLVMValueRef function, int size)
4392 cfg = TlsGetValue (current_cfg_tls_id);
4396 return mono_domain_code_reserve (cfg->domain, size);
4398 return mono_domain_code_reserve (mono_domain_get (), size);
4403 emitted_cb (LLVMValueRef function, void *start, void *end)
4407 cfg = TlsGetValue (current_cfg_tls_id);
4409 cfg->code_len = (guint8*)end - (guint8*)start;
4413 exception_cb (void *data)
4416 MonoJitExceptionInfo *ei;
4417 guint32 ei_len, i, j, nested_len, nindex;
4418 gpointer *type_info;
4419 int this_reg, this_offset;
4421 cfg = TlsGetValue (current_cfg_tls_id);
4425 * data points to a DWARF FDE structure, convert it to our unwind format and
4427 * An alternative would be to save it directly, and modify our unwinder to work
4430 cfg->encoded_unwind_ops = mono_unwind_decode_fde ((guint8*)data, &cfg->encoded_unwind_ops_len, NULL, &ei, &ei_len, &type_info, &this_reg, &this_offset);
4432 /* Count nested clauses */
4434 for (i = 0; i < ei_len; ++i) {
4435 for (j = 0; j < ei_len; ++j) {
4436 gint32 cindex1 = *(gint32*)type_info [i];
4437 MonoExceptionClause *clause1 = &cfg->header->clauses [cindex1];
4438 gint32 cindex2 = *(gint32*)type_info [j];
4439 MonoExceptionClause *clause2 = &cfg->header->clauses [cindex2];
4441 if (cindex1 != cindex2 && clause1->try_offset >= clause2->try_offset && clause1->handler_offset <= clause2->handler_offset) {
4447 cfg->llvm_ex_info = mono_mempool_alloc0 (cfg->mempool, (ei_len + nested_len) * sizeof (MonoJitExceptionInfo));
4448 cfg->llvm_ex_info_len = ei_len + nested_len;
4449 memcpy (cfg->llvm_ex_info, ei, ei_len * sizeof (MonoJitExceptionInfo));
4450 /* Fill the rest of the information from the type info */
4451 for (i = 0; i < ei_len; ++i) {
4452 gint32 clause_index = *(gint32*)type_info [i];
4453 MonoExceptionClause *clause = &cfg->header->clauses [clause_index];
4455 cfg->llvm_ex_info [i].flags = clause->flags;
4456 cfg->llvm_ex_info [i].data.catch_class = clause->data.catch_class;
4460 * For nested clauses, the LLVM produced exception info associates the try interval with
4461 * the innermost handler, while mono expects it to be associated with all nesting clauses.
4463 /* FIXME: These should be order with the normal clauses */
4465 for (i = 0; i < ei_len; ++i) {
4466 for (j = 0; j < ei_len; ++j) {
4467 gint32 cindex1 = *(gint32*)type_info [i];
4468 MonoExceptionClause *clause1 = &cfg->header->clauses [cindex1];
4469 gint32 cindex2 = *(gint32*)type_info [j];
4470 MonoExceptionClause *clause2 = &cfg->header->clauses [cindex2];
4472 if (cindex1 != cindex2 && clause1->try_offset >= clause2->try_offset && clause1->handler_offset <= clause2->handler_offset) {
4474 * The try interval comes from the nested clause, everything else from the
4477 memcpy (&cfg->llvm_ex_info [nindex], &cfg->llvm_ex_info [j], sizeof (MonoJitExceptionInfo));
4478 cfg->llvm_ex_info [nindex].try_start = cfg->llvm_ex_info [i].try_start;
4479 cfg->llvm_ex_info [nindex].try_end = cfg->llvm_ex_info [i].try_end;
4484 g_assert (nindex == ei_len + nested_len);
4485 cfg->llvm_this_reg = this_reg;
4486 cfg->llvm_this_offset = this_offset;
4488 /* type_info [i] is cfg mempool allocated, no need to free it */
4495 add_intrinsics (LLVMModuleRef module)
4497 /* Emit declarations of instrinsics */
4499 LLVMTypeRef memset_params [] = { LLVMPointerType (LLVMInt8Type (), 0), LLVMInt8Type (), LLVMInt32Type (), LLVMInt32Type (), LLVMInt1Type () };
4501 if (LLVM_CHECK_VERSION(2, 8)) {
4502 memset_param_count = 5;
4503 memset_func_name = "llvm.memset.p0i8.i32";
4505 memset_param_count = 4;
4506 memset_func_name = "llvm.memset.i32";
4508 LLVMAddFunction (module, memset_func_name, LLVMFunctionType (LLVMVoidType (), memset_params, memset_param_count, FALSE));
4512 LLVMTypeRef memcpy_params [] = { LLVMPointerType (LLVMInt8Type (), 0), LLVMPointerType (LLVMInt8Type (), 0), LLVMInt32Type (), LLVMInt32Type (), LLVMInt1Type () };
4514 if (LLVM_CHECK_VERSION(2, 8)) {
4515 memcpy_param_count = 5;
4516 memcpy_func_name = "llvm.memcpy.p0i8.p0i8.i32";
4518 memcpy_param_count = 4;
4519 memcpy_func_name = "llvm.memcpy.i32";
4522 LLVMAddFunction (module, memcpy_func_name, LLVMFunctionType (LLVMVoidType (), memcpy_params, memcpy_param_count, FALSE));
4526 LLVMTypeRef params [] = { LLVMDoubleType () };
4528 LLVMAddFunction (module, "llvm.sin.f64", LLVMFunctionType (LLVMDoubleType (), params, 1, FALSE));
4529 LLVMAddFunction (module, "llvm.cos.f64", LLVMFunctionType (LLVMDoubleType (), params, 1, FALSE));
4530 LLVMAddFunction (module, "llvm.sqrt.f64", LLVMFunctionType (LLVMDoubleType (), params, 1, FALSE));
4532 /* This isn't an intrinsic, instead llvm seems to special case it by name */
4533 LLVMAddFunction (module, "fabs", LLVMFunctionType (LLVMDoubleType (), params, 1, FALSE));
4537 LLVMTypeRef membar_params [] = { LLVMInt1Type (), LLVMInt1Type (), LLVMInt1Type (), LLVMInt1Type (), LLVMInt1Type () };
4539 LLVMAddFunction (module, "llvm.atomic.swap.i32.p0i32", LLVMFunctionType2 (LLVMInt32Type (), LLVMPointerType (LLVMInt32Type (), 0), LLVMInt32Type (), FALSE));
4540 LLVMAddFunction (module, "llvm.atomic.swap.i64.p0i64", LLVMFunctionType2 (LLVMInt64Type (), LLVMPointerType (LLVMInt64Type (), 0), LLVMInt64Type (), FALSE));
4541 LLVMAddFunction (module, "llvm.atomic.load.add.i32.p0i32", LLVMFunctionType2 (LLVMInt32Type (), LLVMPointerType (LLVMInt32Type (), 0), LLVMInt32Type (), FALSE));
4542 LLVMAddFunction (module, "llvm.atomic.load.add.i64.p0i64", LLVMFunctionType2 (LLVMInt64Type (), LLVMPointerType (LLVMInt64Type (), 0), LLVMInt64Type (), FALSE));
4543 LLVMAddFunction (module, "llvm.atomic.cmp.swap.i32.p0i32", LLVMFunctionType3 (LLVMInt32Type (), LLVMPointerType (LLVMInt32Type (), 0), LLVMInt32Type (), LLVMInt32Type (), FALSE));
4544 LLVMAddFunction (module, "llvm.atomic.cmp.swap.i64.p0i64", LLVMFunctionType3 (LLVMInt64Type (), LLVMPointerType (LLVMInt64Type (), 0), LLVMInt64Type (), LLVMInt64Type (), FALSE));
4545 LLVMAddFunction (module, "llvm.memory.barrier", LLVMFunctionType (LLVMVoidType (), membar_params, 5, FALSE));
4549 LLVMTypeRef ovf_res_i32 [] = { LLVMInt32Type (), LLVMInt1Type () };
4550 LLVMTypeRef ovf_params_i32 [] = { LLVMInt32Type (), LLVMInt32Type () };
4552 LLVMAddFunction (module, "llvm.sadd.with.overflow.i32", LLVMFunctionType (LLVMStructType (ovf_res_i32, 2, FALSE), ovf_params_i32, 2, FALSE));
4553 LLVMAddFunction (module, "llvm.uadd.with.overflow.i32", LLVMFunctionType (LLVMStructType (ovf_res_i32, 2, FALSE), ovf_params_i32, 2, FALSE));
4554 LLVMAddFunction (module, "llvm.ssub.with.overflow.i32", LLVMFunctionType (LLVMStructType (ovf_res_i32, 2, FALSE), ovf_params_i32, 2, FALSE));
4555 LLVMAddFunction (module, "llvm.usub.with.overflow.i32", LLVMFunctionType (LLVMStructType (ovf_res_i32, 2, FALSE), ovf_params_i32, 2, FALSE));
4556 LLVMAddFunction (module, "llvm.smul.with.overflow.i32", LLVMFunctionType (LLVMStructType (ovf_res_i32, 2, FALSE), ovf_params_i32, 2, FALSE));
4557 LLVMAddFunction (module, "llvm.umul.with.overflow.i32", LLVMFunctionType (LLVMStructType (ovf_res_i32, 2, FALSE), ovf_params_i32, 2, FALSE));
4561 LLVMTypeRef ovf_res_i64 [] = { LLVMInt64Type (), LLVMInt1Type () };
4562 LLVMTypeRef ovf_params_i64 [] = { LLVMInt64Type (), LLVMInt64Type () };
4564 LLVMAddFunction (module, "llvm.sadd.with.overflow.i64", LLVMFunctionType (LLVMStructType (ovf_res_i64, 2, FALSE), ovf_params_i64, 2, FALSE));
4565 LLVMAddFunction (module, "llvm.uadd.with.overflow.i64", LLVMFunctionType (LLVMStructType (ovf_res_i64, 2, FALSE), ovf_params_i64, 2, FALSE));
4566 LLVMAddFunction (module, "llvm.ssub.with.overflow.i64", LLVMFunctionType (LLVMStructType (ovf_res_i64, 2, FALSE), ovf_params_i64, 2, FALSE));
4567 LLVMAddFunction (module, "llvm.usub.with.overflow.i64", LLVMFunctionType (LLVMStructType (ovf_res_i64, 2, FALSE), ovf_params_i64, 2, FALSE));
4568 LLVMAddFunction (module, "llvm.smul.with.overflow.i64", LLVMFunctionType (LLVMStructType (ovf_res_i64, 2, FALSE), ovf_params_i64, 2, FALSE));
4569 LLVMAddFunction (module, "llvm.umul.with.overflow.i64", LLVMFunctionType (LLVMStructType (ovf_res_i64, 2, FALSE), ovf_params_i64, 2, FALSE));
4573 LLVMTypeRef struct_ptr = LLVMPointerType (LLVMStructType (NULL, 0, FALSE), 0);
4574 LLVMTypeRef invariant_start_params [] = { LLVMInt64Type (), LLVMPointerType (LLVMInt8Type (), 0) };
4575 LLVMTypeRef invariant_end_params [] = { struct_ptr, LLVMInt64Type (), LLVMPointerType (LLVMInt8Type (), 0) };
4577 LLVMAddFunction (module, "llvm.invariant.start", LLVMFunctionType (struct_ptr, invariant_start_params, 2, FALSE));
4579 LLVMAddFunction (module, "llvm.invariant.end", LLVMFunctionType (LLVMVoidType (), invariant_end_params, 3, FALSE));
4584 LLVMTypeRef arg_types [2];
4585 LLVMTypeRef ret_type;
4587 arg_types [0] = LLVMPointerType (LLVMInt8Type (), 0);
4588 arg_types [1] = LLVMPointerType (LLVMInt8Type (), 0);
4589 if (LLVM_CHECK_VERSION(2, 8)) {
4590 eh_selector_name = "llvm.eh.selector";
4591 ret_type = LLVMInt32Type ();
4593 if (SIZEOF_VOID_P == 8) {
4594 eh_selector_name = "llvm.eh.selector.i64";
4595 ret_type = LLVMInt64Type ();
4597 eh_selector_name = "llvm.eh.selector.i32";
4598 ret_type = LLVMInt32Type ();
4601 LLVMAddFunction (module, eh_selector_name, LLVMFunctionType (ret_type, arg_types, 2, TRUE));
4603 LLVMAddFunction (module, "llvm.eh.exception", LLVMFunctionType (LLVMPointerType (LLVMInt8Type (), 0), NULL, 0, FALSE));
4605 LLVMAddFunction (module, "mono_personality", LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE));
4607 LLVMAddFunction (module, "llvm_resume_unwind_trampoline", LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE));
4610 /* SSE intrinsics */
4612 LLVMTypeRef ret_type, arg_types [2];
4615 ret_type = type_to_simd_type (MONO_TYPE_I4);
4616 arg_types [0] = ret_type;
4617 arg_types [1] = ret_type;
4618 LLVMAddFunction (module, "llvm.x86.sse41.pminud", LLVMFunctionType (ret_type, arg_types, 2, FALSE));
4619 LLVMAddFunction (module, "llvm.x86.sse41.pmaxud", LLVMFunctionType (ret_type, arg_types, 2, FALSE));
4620 LLVMAddFunction (module, "llvm.x86.sse2.pcmpeq.d", LLVMFunctionType (ret_type, arg_types, 2, FALSE));
4622 ret_type = type_to_simd_type (MONO_TYPE_I2);
4623 arg_types [0] = ret_type;
4624 arg_types [1] = ret_type;
4625 LLVMAddFunction (module, "llvm.x86.sse41.pminuw", LLVMFunctionType (ret_type, arg_types, 2, FALSE));
4626 LLVMAddFunction (module, "llvm.x86.sse2.pmins.w", LLVMFunctionType (ret_type, arg_types, 2, FALSE));
4627 LLVMAddFunction (module, "llvm.x86.sse41.pmaxuw", LLVMFunctionType (ret_type, arg_types, 2, FALSE));
4628 LLVMAddFunction (module, "llvm.x86.sse2.pcmpeq.w", LLVMFunctionType (ret_type, arg_types, 2, FALSE));
4629 LLVMAddFunction (module, "llvm.x86.sse2.padds.w", LLVMFunctionType (ret_type, arg_types, 2, FALSE));
4630 LLVMAddFunction (module, "llvm.x86.sse2.psubs.w", LLVMFunctionType (ret_type, arg_types, 2, FALSE));
4631 LLVMAddFunction (module, "llvm.x86.sse2.paddus.w", LLVMFunctionType (ret_type, arg_types, 2, FALSE));
4632 LLVMAddFunction (module, "llvm.x86.sse2.psubus.w", LLVMFunctionType (ret_type, arg_types, 2, FALSE));
4634 ret_type = type_to_simd_type (MONO_TYPE_I1);
4635 arg_types [0] = ret_type;
4636 arg_types [1] = ret_type;
4637 LLVMAddFunction (module, "llvm.x86.sse2.pminu.b", LLVMFunctionType (ret_type, arg_types, 2, FALSE));
4638 LLVMAddFunction (module, "llvm.x86.sse2.pmaxu.b", LLVMFunctionType (ret_type, arg_types, 2, FALSE));
4639 LLVMAddFunction (module, "llvm.x86.sse2.pcmpeq.b", LLVMFunctionType (ret_type, arg_types, 2, FALSE));
4640 LLVMAddFunction (module, "llvm.x86.sse2.pcmpgt.b", LLVMFunctionType (ret_type, arg_types, 2, FALSE));
4641 LLVMAddFunction (module, "llvm.x86.sse2.padds.b", LLVMFunctionType (ret_type, arg_types, 2, FALSE));
4642 LLVMAddFunction (module, "llvm.x86.sse2.psubs.b", LLVMFunctionType (ret_type, arg_types, 2, FALSE));
4643 LLVMAddFunction (module, "llvm.x86.sse2.paddus.b", LLVMFunctionType (ret_type, arg_types, 2, FALSE));
4644 LLVMAddFunction (module, "llvm.x86.sse2.psubus.b", LLVMFunctionType (ret_type, arg_types, 2, FALSE));
4646 ret_type = type_to_simd_type (MONO_TYPE_I8);
4647 arg_types [0] = ret_type;
4648 arg_types [1] = ret_type;
4649 LLVMAddFunction (module, "llvm.x86.sse41.pcmpeqq", LLVMFunctionType (ret_type, arg_types, 2, FALSE));
4651 ret_type = type_to_simd_type (MONO_TYPE_R8);
4652 arg_types [0] = ret_type;
4653 arg_types [1] = ret_type;
4654 LLVMAddFunction (module, "llvm.x86.sse2.min.pd", LLVMFunctionType (ret_type, arg_types, 2, FALSE));
4655 LLVMAddFunction (module, "llvm.x86.sse2.max.pd", LLVMFunctionType (ret_type, arg_types, 2, FALSE));
4656 LLVMAddFunction (module, "llvm.x86.sse3.hadd.pd", LLVMFunctionType (ret_type, arg_types, 2, FALSE));
4657 LLVMAddFunction (module, "llvm.x86.sse3.hsub.pd", LLVMFunctionType (ret_type, arg_types, 2, FALSE));
4658 LLVMAddFunction (module, "llvm.x86.sse3.addsub.pd", LLVMFunctionType (ret_type, arg_types, 2, FALSE));
4660 ret_type = type_to_simd_type (MONO_TYPE_R4);
4661 arg_types [0] = ret_type;
4662 arg_types [1] = ret_type;
4663 LLVMAddFunction (module, "llvm.x86.sse.min.ps", LLVMFunctionType (ret_type, arg_types, 2, FALSE));
4664 LLVMAddFunction (module, "llvm.x86.sse.max.ps", LLVMFunctionType (ret_type, arg_types, 2, FALSE));
4665 LLVMAddFunction (module, "llvm.x86.sse3.hadd.ps", LLVMFunctionType (ret_type, arg_types, 2, FALSE));
4666 LLVMAddFunction (module, "llvm.x86.sse3.hsub.ps", LLVMFunctionType (ret_type, arg_types, 2, FALSE));
4669 ret_type = type_to_simd_type (MONO_TYPE_R8);
4670 arg_types [0] = ret_type;
4671 arg_types [1] = ret_type;
4672 arg_types [2] = LLVMInt8Type ();
4673 LLVMAddFunction (module, "llvm.x86.sse2.cmp.pd", LLVMFunctionType (ret_type, arg_types, 3, FALSE));
4674 ret_type = type_to_simd_type (MONO_TYPE_R4);
4675 arg_types [0] = ret_type;
4676 arg_types [1] = ret_type;
4677 arg_types [2] = LLVMInt8Type ();
4678 LLVMAddFunction (module, "llvm.x86.sse.cmp.ps", LLVMFunctionType (ret_type, arg_types, 3, FALSE));
4680 /* Conversion ops */
4681 ret_type = type_to_simd_type (MONO_TYPE_R8);
4682 arg_types [0] = type_to_simd_type (MONO_TYPE_I4);
4683 LLVMAddFunction (module, "llvm.x86.sse2.cvtdq2pd", LLVMFunctionType (ret_type, arg_types, 1, FALSE));
4684 ret_type = type_to_simd_type (MONO_TYPE_R4);
4685 arg_types [0] = type_to_simd_type (MONO_TYPE_I4);
4686 LLVMAddFunction (module, "llvm.x86.sse2.cvtdq2ps", LLVMFunctionType (ret_type, arg_types, 1, FALSE));
4687 ret_type = type_to_simd_type (MONO_TYPE_I4);
4688 arg_types [0] = type_to_simd_type (MONO_TYPE_R8);
4689 LLVMAddFunction (module, "llvm.x86.sse2.cvtpd2dq", LLVMFunctionType (ret_type, arg_types, 1, FALSE));
4690 ret_type = type_to_simd_type (MONO_TYPE_I4);
4691 arg_types [0] = type_to_simd_type (MONO_TYPE_R4);
4692 LLVMAddFunction (module, "llvm.x86.sse2.cvtps2dq", LLVMFunctionType (ret_type, arg_types, 1, FALSE));
4693 ret_type = type_to_simd_type (MONO_TYPE_R4);
4694 arg_types [0] = type_to_simd_type (MONO_TYPE_R8);
4695 LLVMAddFunction (module, "llvm.x86.sse2.cvtpd2ps", LLVMFunctionType (ret_type, arg_types, 1, FALSE));
4696 ret_type = type_to_simd_type (MONO_TYPE_R8);
4697 arg_types [0] = type_to_simd_type (MONO_TYPE_R4);
4698 LLVMAddFunction (module, "llvm.x86.sse2.cvtps2pd", LLVMFunctionType (ret_type, arg_types, 1, FALSE));
4700 ret_type = type_to_simd_type (MONO_TYPE_I4);
4701 arg_types [0] = type_to_simd_type (MONO_TYPE_R8);
4702 LLVMAddFunction (module, "llvm.x86.sse2.cvttpd2dq", LLVMFunctionType (ret_type, arg_types, 1, FALSE));
4703 ret_type = type_to_simd_type (MONO_TYPE_I4);
4704 arg_types [0] = type_to_simd_type (MONO_TYPE_R4);
4705 LLVMAddFunction (module, "llvm.x86.sse2.cvttps2dq", LLVMFunctionType (ret_type, arg_types, 1, FALSE));
4708 ret_type = type_to_simd_type (MONO_TYPE_I2);
4709 arg_types [0] = ret_type;
4710 arg_types [1] = LLVMInt32Type ();
4711 LLVMAddFunction (module, "llvm.x86.sse2.psrli.w", LLVMFunctionType (ret_type, arg_types, 2, FALSE));
4712 ret_type = type_to_simd_type (MONO_TYPE_I4);
4713 arg_types [0] = ret_type;
4714 arg_types [1] = LLVMInt32Type ();
4715 LLVMAddFunction (module, "llvm.x86.sse2.psrli.d", LLVMFunctionType (ret_type, arg_types, 2, FALSE));
4716 ret_type = type_to_simd_type (MONO_TYPE_I8);
4717 arg_types [0] = ret_type;
4718 arg_types [1] = LLVMInt32Type ();
4719 LLVMAddFunction (module, "llvm.x86.sse2.psrli.q", LLVMFunctionType (ret_type, arg_types, 2, FALSE));
4720 ret_type = type_to_simd_type (MONO_TYPE_I2);
4721 arg_types [0] = ret_type;
4722 arg_types [1] = LLVMInt32Type ();
4723 LLVMAddFunction (module, "llvm.x86.sse2.pslli.w", LLVMFunctionType (ret_type, arg_types, 2, FALSE));
4724 ret_type = type_to_simd_type (MONO_TYPE_I4);
4725 arg_types [0] = ret_type;
4726 arg_types [1] = LLVMInt32Type ();
4727 LLVMAddFunction (module, "llvm.x86.sse2.pslli.d", LLVMFunctionType (ret_type, arg_types, 2, FALSE));
4728 ret_type = type_to_simd_type (MONO_TYPE_I8);
4729 arg_types [0] = ret_type;
4730 arg_types [1] = LLVMInt32Type ();
4731 LLVMAddFunction (module, "llvm.x86.sse2.pslli.q", LLVMFunctionType (ret_type, arg_types, 2, FALSE));
4734 ret_type = LLVMInt32Type ();
4735 arg_types [0] = type_to_simd_type (MONO_TYPE_I1);
4736 LLVMAddFunction (module, "llvm.x86.sse2.pmovmskb.128", LLVMFunctionType (ret_type, arg_types, 1, FALSE));
4739 /* Load/Store intrinsics */
4740 if (IS_LLVM_MONO_BRANCH) {
4741 LLVMTypeRef arg_types [5];
4745 for (i = 1; i <= 8; i *= 2) {
4746 arg_types [0] = LLVMPointerType (LLVMIntType (i * 8), 0);
4747 arg_types [1] = LLVMInt32Type ();
4748 arg_types [2] = LLVMInt1Type ();
4749 sprintf (name, "llvm.mono.load.i%d.p0i%d", i * 8, i * 8);
4750 LLVMAddFunction (module, name, LLVMFunctionType (LLVMIntType (i * 8), arg_types, 3, FALSE));
4752 arg_types [0] = LLVMIntType (i * 8);
4753 arg_types [1] = LLVMPointerType (LLVMIntType (i * 8), 0);
4754 arg_types [2] = LLVMInt32Type ();
4755 arg_types [3] = LLVMInt1Type ();
4756 sprintf (name, "llvm.mono.store.i%d.p0i%d", i * 8, i * 8);
4757 LLVMAddFunction (module, name, LLVMFunctionType (LLVMVoidType (), arg_types, 4, FALSE));
4763 mono_llvm_init (void)
4765 current_cfg_tls_id = TlsAlloc ();
4769 init_jit_module (void)
4771 MonoJitICallInfo *info;
4773 if (jit_module_inited)
4776 mono_loader_lock ();
4778 if (jit_module_inited) {
4779 mono_loader_unlock ();
4783 jit_module.module = LLVMModuleCreateWithName ("mono");
4785 ee = mono_llvm_create_ee (LLVMCreateModuleProviderForExistingModule (jit_module.module), alloc_cb, emitted_cb, exception_cb);
4787 add_intrinsics (jit_module.module);
4789 jit_module.llvm_types = g_hash_table_new (NULL, NULL);
4791 info = mono_find_jit_icall_by_name ("llvm_resume_unwind_trampoline");
4793 LLVMAddGlobalMapping (ee, LLVMGetNamedFunction (jit_module.module, "llvm_resume_unwind_trampoline"), (void*)info->func);
4795 jit_module_inited = TRUE;
4797 mono_loader_unlock ();
4801 mono_llvm_cleanup (void)
4804 mono_llvm_dispose_ee (ee);
4806 if (jit_module.llvm_types)
4807 g_hash_table_destroy (jit_module.llvm_types);
4809 if (aot_module.module)
4810 LLVMDisposeModule (aot_module.module);
4812 LLVMContextDispose (LLVMGetGlobalContext ());
4816 mono_llvm_create_aot_module (const char *got_symbol)
4818 /* Delete previous module */
4819 if (aot_module.plt_entries)
4820 g_hash_table_destroy (aot_module.plt_entries);
4821 if (aot_module.module)
4822 LLVMDisposeModule (aot_module.module);
4824 memset (&aot_module, 0, sizeof (aot_module));
4826 aot_module.module = LLVMModuleCreateWithName ("aot");
4827 aot_module.got_symbol = got_symbol;
4829 add_intrinsics (aot_module.module);
4833 * We couldn't compute the type of the LLVM global representing the got because
4834 * its size is only known after all the methods have been emitted. So create
4835 * a dummy variable, and replace all uses it with the real got variable when
4836 * its size is known in mono_llvm_emit_aot_module ().
4839 LLVMTypeRef got_type = LLVMArrayType (IntPtrType (), 0);
4841 aot_module.got_var = LLVMAddGlobal (aot_module.module, got_type, "mono_dummy_got");
4842 LLVMSetInitializer (aot_module.got_var, LLVMConstNull (got_type));
4845 /* Add a dummy personality function */
4847 LLVMBasicBlockRef lbb;
4848 LLVMBuilderRef lbuilder;
4849 LLVMValueRef personality;
4851 personality = LLVMAddFunction (aot_module.module, "mono_aot_personality", LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE));
4852 LLVMSetLinkage (personality, LLVMPrivateLinkage);
4853 lbb = LLVMAppendBasicBlock (personality, "BB0");
4854 lbuilder = LLVMCreateBuilder ();
4855 LLVMPositionBuilderAtEnd (lbuilder, lbb);
4856 LLVMBuildRetVoid (lbuilder);
4859 aot_module.llvm_types = g_hash_table_new (NULL, NULL);
4860 aot_module.plt_entries = g_hash_table_new (g_str_hash, g_str_equal);
4864 * Emit the aot module into the LLVM bitcode file FILENAME.
4867 mono_llvm_emit_aot_module (const char *filename, int got_size)
4869 LLVMTypeRef got_type;
4870 LLVMValueRef real_got;
4873 * Create the real got variable and replace all uses of the dummy variable with
4876 got_type = LLVMArrayType (IntPtrType (), got_size);
4877 real_got = LLVMAddGlobal (aot_module.module, got_type, aot_module.got_symbol);
4878 LLVMSetInitializer (real_got, LLVMConstNull (got_type));
4879 LLVMSetLinkage (real_got, LLVMInternalLinkage);
4881 mono_llvm_replace_uses_of (aot_module.got_var, real_got);
4883 mark_as_used (aot_module.module, real_got);
4885 /* Delete the dummy got so it doesn't become a global */
4886 LLVMDeleteGlobal (aot_module.got_var);
4892 if (LLVMVerifyModule (aot_module.module, LLVMReturnStatusAction, &verifier_err)) {
4893 g_assert_not_reached ();
4898 LLVMWriteBitcodeToFile (aot_module.module, filename);
4903 - Emit LLVM IR from the mono IR using the LLVM C API.
4904 - The original arch specific code remains, so we can fall back to it if we run
4905 into something we can't handle.
4909 A partial list of issues:
4910 - Handling of opcodes which can throw exceptions.
4912 In the mono JIT, these are implemented using code like this:
4919 push throw_pos - method
4920 call <exception trampoline>
4922 The problematic part is push throw_pos - method, which cannot be represented
4923 in the LLVM IR, since it does not support label values.
4924 -> this can be implemented in AOT mode using inline asm + labels, but cannot
4925 be implemented in JIT mode ?
4926 -> a possible but slower implementation would use the normal exception
4927 throwing code but it would need to control the placement of the throw code
4928 (it needs to be exactly after the compare+branch).
4929 -> perhaps add a PC offset intrinsics ?
4931 - efficient implementation of .ovf opcodes.
4933 These are currently implemented as:
4934 <ins which sets the condition codes>
4937 Some overflow opcodes are now supported by LLVM SVN.
4939 - exception handling, unwinding.
4940 - SSA is disabled for methods with exception handlers
4941 - How to obtain unwind info for LLVM compiled methods ?
4942 -> this is now solved by converting the unwind info generated by LLVM
4944 - LLVM uses the c++ exception handling framework, while we use our home grown
4945 code, and couldn't use the c++ one:
4946 - its not supported under VC++, other exotic platforms.
4947 - it might be impossible to support filter clauses with it.
4951 The trampolines need a predictable call sequence, since they need to disasm
4952 the calling code to obtain register numbers / offsets.
4954 LLVM currently generates this code in non-JIT mode:
4955 mov -0x98(%rax),%eax
4957 Here, the vtable pointer is lost.
4958 -> solution: use one vtable trampoline per class.
4960 - passing/receiving the IMT pointer/RGCTX.
4961 -> solution: pass them as normal arguments ?
4965 LLVM does not allow the specification of argument registers etc. This means
4966 that all calls are made according to the platform ABI.
4968 - passing/receiving vtypes.
4970 Vtypes passed/received in registers are handled by the front end by using
4971 a signature with scalar arguments, and loading the parts of the vtype into those
4974 Vtypes passed on the stack are handled using the 'byval' attribute.
4978 Supported though alloca, we need to emit the load/store code.
4982 The mono JIT uses pointer sized iregs/double fregs, while LLVM uses precisely
4983 typed registers, so we have to keep track of the precise LLVM type of each vreg.
4984 This is made easier because the IR is already in SSA form.
4985 An additional problem is that our IR is not consistent with types, i.e. i32/ia64
4986 types are frequently used incorrectly.
4991 Emit LLVM bytecode into a .bc file, compile it using llc into a .s file, then
4992 append the AOT data structures to that file. For methods which cannot be
4993 handled by LLVM, the normal JIT compiled versions are used.
4996 /* FIXME: Normalize some aspects of the mono IR to allow easier translation, like:
4997 * - each bblock should end with a branch
4998 * - setting the return value, making cfg->ret non-volatile
4999 * - avoid some transformations in the JIT which make it harder for us to generate
5001 * - use pointer types to help optimizations.