2 * mini-llvm.c: llvm "Backend" for the mono JIT
4 * Copyright 2009-2011 Novell Inc (http://www.novell.com)
5 * Copyright 2011 Xamarin Inc (http://www.xamarin.com)
9 #include <mono/metadata/debug-helpers.h>
10 #include <mono/metadata/mempool-internals.h>
11 #include <mono/utils/mono-tls.h>
12 #include <mono/utils/mono-dl.h>
14 #ifndef __STDC_LIMIT_MACROS
15 #define __STDC_LIMIT_MACROS
17 #ifndef __STDC_CONSTANT_MACROS
18 #define __STDC_CONSTANT_MACROS
21 #include "llvm-c/Core.h"
22 #include "llvm-c/ExecutionEngine.h"
23 #include "llvm-c/BitWriter.h"
24 #include "llvm-c/Analysis.h"
26 #include "mini-llvm-cpp.h"
29 * Information associated by mono with LLVM modules.
33 LLVMValueRef throw, rethrow, throw_corlib_exception;
34 GHashTable *llvm_types;
36 const char *got_symbol;
37 GHashTable *plt_entries;
44 * Information associated by the backend with mono basic blocks.
47 LLVMBasicBlockRef bblock, end_bblock;
48 LLVMValueRef finally_ind;
49 gboolean added, invoke_target;
51 * If this bblock is the start of a finally clause, this is a list of bblocks it
52 * needs to branch to in ENDFINALLY.
54 GSList *call_handler_return_bbs;
56 * If this bblock is the start of a finally clause, this is the bblock that
57 * CALL_HANDLER needs to branch to.
59 LLVMBasicBlockRef call_handler_target_bb;
60 /* The list of switch statements generated by ENDFINALLY instructions */
61 GSList *endfinally_switch_ins_list;
66 * Structure containing emit state
71 /* Maps method names to the corresponding LLVMValueRef */
72 GHashTable *emitted_method_decls;
76 MonoLLVMModule *lmodule;
79 int sindex, default_index, ex_index;
80 LLVMBuilderRef builder;
81 LLVMValueRef *values, *addresses;
82 MonoType **vreg_cli_types;
84 MonoMethodSignature *sig;
86 GHashTable *region_to_handler;
87 LLVMBuilderRef alloca_builder;
88 LLVMValueRef last_alloca;
89 LLVMValueRef rgctx_arg;
90 LLVMTypeRef *vreg_types;
92 gboolean *unreachable;
101 MonoBasicBlock *in_bb;
106 * Instruction metadata
107 * This is the same as ins_info, but LREG != IREG.
115 #define MINI_OP(a,b,dest,src1,src2) dest, src1, src2, ' ',
116 #define MINI_OP3(a,b,dest,src1,src2,src3) dest, src1, src2, src3,
123 /* keep in sync with the enum in mini.h */
126 #include "mini-ops.h"
131 #if SIZEOF_VOID_P == 4
132 #define GET_LONG_IMM(ins) (((guint64)(ins)->inst_ms_word << 32) | (guint64)(guint32)(ins)->inst_ls_word)
134 #define GET_LONG_IMM(ins) ((ins)->inst_imm)
137 #define LLVM_INS_INFO(opcode) (&llvm_ins_info [((opcode) - OP_START - 1) * 4])
140 #define TRACE_FAILURE(msg) do { printf ("%s\n", msg); } while (0)
142 #define TRACE_FAILURE(msg)
146 #define IS_TARGET_X86 1
148 #define IS_TARGET_X86 0
152 #define IS_TARGET_AMD64 1
154 #define IS_TARGET_AMD64 0
157 #define LLVM_FAILURE(ctx, reason) do { \
158 TRACE_FAILURE (reason); \
159 (ctx)->cfg->exception_message = g_strdup (reason); \
160 (ctx)->cfg->disable_llvm = TRUE; \
164 #define CHECK_FAILURE(ctx) do { \
165 if ((ctx)->cfg->disable_llvm) \
169 static LLVMIntPredicate cond_to_llvm_cond [] = {
182 static LLVMRealPredicate fpcond_to_llvm_cond [] = {
195 static LLVMExecutionEngineRef ee;
196 static MonoNativeTlsKey current_cfg_tls_id;
198 static MonoLLVMModule jit_module, aot_module;
199 static gboolean jit_module_inited;
200 static int memset_param_count, memcpy_param_count;
201 static const char *memset_func_name;
202 static const char *memcpy_func_name;
204 static void init_jit_module (void);
209 * The LLVM type with width == sizeof (gpointer)
214 return sizeof (gpointer) == 8 ? LLVMInt64Type () : LLVMInt32Type ();
220 return sizeof (gpointer) == 8 ? LLVMPointerType (LLVMInt64Type (), 0) : LLVMPointerType (LLVMInt32Type (), 0);
226 return sizeof (gpointer) == 8 ? LLVMPointerType (LLVMInt64Type (), 0) : LLVMPointerType (LLVMInt32Type (), 0);
232 * Return the size of the LLVM representation of the vtype T.
235 get_vtype_size (MonoType *t)
239 size = mono_class_value_size (mono_class_from_mono_type (t), NULL);
241 while (size < 2 * sizeof (gpointer) && mono_is_power_of_two (size) == -1)
248 * simd_class_to_llvm_type:
250 * Return the LLVM type corresponding to the Mono.SIMD class KLASS
253 simd_class_to_llvm_type (EmitContext *ctx, MonoClass *klass)
255 if (!strcmp (klass->name, "Vector2d")) {
256 return LLVMVectorType (LLVMDoubleType (), 2);
257 } else if (!strcmp (klass->name, "Vector2l")) {
258 return LLVMVectorType (LLVMInt64Type (), 2);
259 } else if (!strcmp (klass->name, "Vector2ul")) {
260 return LLVMVectorType (LLVMInt64Type (), 2);
261 } else if (!strcmp (klass->name, "Vector4i")) {
262 return LLVMVectorType (LLVMInt32Type (), 4);
263 } else if (!strcmp (klass->name, "Vector4ui")) {
264 return LLVMVectorType (LLVMInt32Type (), 4);
265 } else if (!strcmp (klass->name, "Vector4f")) {
266 return LLVMVectorType (LLVMFloatType (), 4);
267 } else if (!strcmp (klass->name, "Vector8s")) {
268 return LLVMVectorType (LLVMInt16Type (), 8);
269 } else if (!strcmp (klass->name, "Vector8us")) {
270 return LLVMVectorType (LLVMInt16Type (), 8);
271 } else if (!strcmp (klass->name, "Vector16sb")) {
272 return LLVMVectorType (LLVMInt8Type (), 16);
273 } else if (!strcmp (klass->name, "Vector16b")) {
274 return LLVMVectorType (LLVMInt8Type (), 16);
276 printf ("%s\n", klass->name);
282 /* Return the 128 bit SIMD type corresponding to the mono type TYPE */
283 static inline G_GNUC_UNUSED LLVMTypeRef
284 type_to_simd_type (int type)
288 return LLVMVectorType (LLVMInt8Type (), 16);
290 return LLVMVectorType (LLVMInt16Type (), 8);
292 return LLVMVectorType (LLVMInt32Type (), 4);
294 return LLVMVectorType (LLVMInt64Type (), 2);
296 return LLVMVectorType (LLVMDoubleType (), 2);
298 return LLVMVectorType (LLVMFloatType (), 4);
300 g_assert_not_reached ();
308 * Return the LLVM type corresponding to T.
311 type_to_llvm_type (EmitContext *ctx, MonoType *t)
314 return LLVMPointerType (LLVMInt8Type (), 0);
317 return LLVMVoidType ();
319 return LLVMInt8Type ();
321 return LLVMInt16Type ();
323 return LLVMInt32Type ();
325 return LLVMInt8Type ();
327 return LLVMInt16Type ();
329 return LLVMInt32Type ();
330 case MONO_TYPE_BOOLEAN:
331 return LLVMInt8Type ();
334 return LLVMInt64Type ();
336 return LLVMInt16Type ();
338 return LLVMFloatType ();
340 return LLVMDoubleType ();
343 return IntPtrType ();
344 case MONO_TYPE_OBJECT:
345 case MONO_TYPE_CLASS:
346 case MONO_TYPE_ARRAY:
347 case MONO_TYPE_SZARRAY:
348 case MONO_TYPE_STRING:
350 return ObjRefType ();
353 /* Because of generic sharing */
354 return ObjRefType ();
355 case MONO_TYPE_GENERICINST:
356 if (!mono_type_generic_inst_is_valuetype (t))
357 return ObjRefType ();
359 case MONO_TYPE_VALUETYPE:
360 case MONO_TYPE_TYPEDBYREF: {
364 klass = mono_class_from_mono_type (t);
366 if (MONO_CLASS_IS_SIMD (ctx->cfg, klass))
367 return simd_class_to_llvm_type (ctx, klass);
370 return type_to_llvm_type (ctx, mono_class_enum_basetype (klass));
371 ltype = g_hash_table_lookup (ctx->lmodule->llvm_types, klass);
374 LLVMTypeRef *eltypes;
377 size = get_vtype_size (t);
379 eltypes = g_new (LLVMTypeRef, size);
380 for (i = 0; i < size; ++i)
381 eltypes [i] = LLVMInt8Type ();
383 name = mono_type_full_name (&klass->byval_arg);
384 ltype = LLVMStructCreateNamed (LLVMGetGlobalContext (), name);
385 LLVMStructSetBody (ltype, eltypes, size, FALSE);
386 g_hash_table_insert (ctx->lmodule->llvm_types, klass, ltype);
393 printf ("X: %d\n", t->type);
394 ctx->cfg->exception_message = g_strdup_printf ("type %s", mono_type_full_name (t));
395 ctx->cfg->disable_llvm = TRUE;
403 * Return whenever T is an unsigned int type.
406 type_is_unsigned (EmitContext *ctx, MonoType *t)
422 * type_to_llvm_arg_type:
424 * Same as type_to_llvm_type, but treat i8/i16 as i32.
427 type_to_llvm_arg_type (EmitContext *ctx, MonoType *t)
429 LLVMTypeRef ptype = type_to_llvm_type (ctx, t);
431 if (ptype == LLVMInt8Type () || ptype == LLVMInt16Type ()) {
433 * LLVM generates code which only sets the lower bits, while JITted
434 * code expects all the bits to be set.
436 ptype = LLVMInt32Type ();
443 * llvm_type_to_stack_type:
445 * Return the LLVM type which needs to be used when a value of type TYPE is pushed
448 static G_GNUC_UNUSED LLVMTypeRef
449 llvm_type_to_stack_type (LLVMTypeRef type)
453 if (type == LLVMInt8Type ())
454 return LLVMInt32Type ();
455 else if (type == LLVMInt16Type ())
456 return LLVMInt32Type ();
457 else if (type == LLVMFloatType ())
458 return LLVMDoubleType ();
464 * regtype_to_llvm_type:
466 * Return the LLVM type corresponding to the regtype C used in instruction
470 regtype_to_llvm_type (char c)
474 return LLVMInt32Type ();
476 return LLVMInt64Type ();
478 return LLVMDoubleType ();
487 * Return the LLVM type corresponding to the unary/binary opcode OPCODE.
490 op_to_llvm_type (int opcode)
495 return LLVMInt8Type ();
498 return LLVMInt8Type ();
501 return LLVMInt16Type ();
504 return LLVMInt16Type ();
507 return LLVMInt32Type ();
510 return LLVMInt32Type ();
512 return LLVMInt64Type ();
514 return LLVMFloatType ();
516 return LLVMDoubleType ();
518 return LLVMInt64Type ();
520 return LLVMInt32Type ();
522 return LLVMInt64Type ();
525 return LLVMInt8Type ();
528 return LLVMInt16Type ();
531 return sizeof (gpointer) == 8 ? LLVMInt64Type () : LLVMInt32Type ();
538 return LLVMInt32Type ();
545 return LLVMInt64Type ();
547 printf ("%s\n", mono_inst_name (opcode));
548 g_assert_not_reached ();
554 * load_store_to_llvm_type:
556 * Return the size/sign/zero extension corresponding to the load/store opcode
560 load_store_to_llvm_type (int opcode, int *size, gboolean *sext, gboolean *zext)
566 case OP_LOADI1_MEMBASE:
567 case OP_STOREI1_MEMBASE_REG:
568 case OP_STOREI1_MEMBASE_IMM:
571 return LLVMInt8Type ();
572 case OP_LOADU1_MEMBASE:
576 return LLVMInt8Type ();
577 case OP_LOADI2_MEMBASE:
578 case OP_STOREI2_MEMBASE_REG:
579 case OP_STOREI2_MEMBASE_IMM:
582 return LLVMInt16Type ();
583 case OP_LOADU2_MEMBASE:
587 return LLVMInt16Type ();
588 case OP_LOADI4_MEMBASE:
589 case OP_LOADU4_MEMBASE:
592 case OP_STOREI4_MEMBASE_REG:
593 case OP_STOREI4_MEMBASE_IMM:
595 return LLVMInt32Type ();
596 case OP_LOADI8_MEMBASE:
598 case OP_STOREI8_MEMBASE_REG:
599 case OP_STOREI8_MEMBASE_IMM:
601 return LLVMInt64Type ();
602 case OP_LOADR4_MEMBASE:
603 case OP_STORER4_MEMBASE_REG:
605 return LLVMFloatType ();
606 case OP_LOADR8_MEMBASE:
607 case OP_STORER8_MEMBASE_REG:
609 return LLVMDoubleType ();
610 case OP_LOAD_MEMBASE:
612 case OP_STORE_MEMBASE_REG:
613 case OP_STORE_MEMBASE_IMM:
614 *size = sizeof (gpointer);
615 return IntPtrType ();
617 g_assert_not_reached ();
625 * Return the LLVM intrinsics corresponding to the overflow opcode OPCODE.
628 ovf_op_to_intrins (int opcode)
632 return "llvm.sadd.with.overflow.i32";
634 return "llvm.uadd.with.overflow.i32";
636 return "llvm.ssub.with.overflow.i32";
638 return "llvm.usub.with.overflow.i32";
640 return "llvm.smul.with.overflow.i32";
642 return "llvm.umul.with.overflow.i32";
644 return "llvm.sadd.with.overflow.i64";
646 return "llvm.uadd.with.overflow.i64";
648 return "llvm.ssub.with.overflow.i64";
650 return "llvm.usub.with.overflow.i64";
652 return "llvm.smul.with.overflow.i64";
654 return "llvm.umul.with.overflow.i64";
656 g_assert_not_reached ();
662 simd_op_to_intrins (int opcode)
665 #if defined(TARGET_X86) || defined(TARGET_AMD64)
667 return "llvm.x86.sse2.min.pd";
669 return "llvm.x86.sse.min.ps";
671 return "llvm.x86.sse41.pminud";
673 return "llvm.x86.sse41.pminuw";
675 return "llvm.x86.sse2.pminu.b";
677 return "llvm.x86.sse2.pmins.w";
679 return "llvm.x86.sse2.max.pd";
681 return "llvm.x86.sse.max.ps";
683 return "llvm.x86.sse3.hadd.pd";
685 return "llvm.x86.sse3.hadd.ps";
687 return "llvm.x86.sse3.hsub.pd";
689 return "llvm.x86.sse3.hsub.ps";
691 return "llvm.x86.sse41.pmaxud";
693 return "llvm.x86.sse41.pmaxuw";
695 return "llvm.x86.sse2.pmaxu.b";
697 return "llvm.x86.sse3.addsub.ps";
699 return "llvm.x86.sse3.addsub.pd";
700 case OP_EXTRACT_MASK:
701 return "llvm.x86.sse2.pmovmskb.128";
704 return "llvm.x86.sse2.psrli.w";
707 return "llvm.x86.sse2.psrli.d";
710 return "llvm.x86.sse2.psrli.q";
713 return "llvm.x86.sse2.pslli.w";
716 return "llvm.x86.sse2.pslli.d";
719 return "llvm.x86.sse2.pslli.q";
722 return "llvm.x86.sse2.psrai.w";
725 return "llvm.x86.sse2.psrai.d";
727 return "llvm.x86.sse2.padds.b";
729 return "llvm.x86.sse2.padds.w";
731 return "llvm.x86.sse2.psubs.b";
733 return "llvm.x86.sse2.psubs.w";
734 case OP_PADDB_SAT_UN:
735 return "llvm.x86.sse2.paddus.b";
736 case OP_PADDW_SAT_UN:
737 return "llvm.x86.sse2.paddus.w";
738 case OP_PSUBB_SAT_UN:
739 return "llvm.x86.sse2.psubus.b";
740 case OP_PSUBW_SAT_UN:
741 return "llvm.x86.sse2.psubus.w";
743 return "llvm.x86.sse2.pavg.b";
745 return "llvm.x86.sse2.pavg.w";
747 return "llvm.x86.sse.sqrt.ps";
749 return "llvm.x86.sse2.sqrt.pd";
751 return "llvm.x86.sse.rsqrt.ps";
753 return "llvm.x86.sse.rcp.ps";
755 return "llvm.x86.sse2.cvtdq2pd";
757 return "llvm.x86.sse2.cvtdq2ps";
759 return "llvm.x86.sse2.cvtpd2dq";
761 return "llvm.x86.sse2.cvtps2dq";
763 return "llvm.x86.sse2.cvtpd2ps";
765 return "llvm.x86.sse2.cvtps2pd";
767 return "llvm.x86.sse2.cvttpd2dq";
769 return "llvm.x86.sse2.cvttps2dq";
771 return "llvm.x86.sse.cmp.ps";
773 return "llvm.x86.sse2.cmp.pd";
775 return "llvm.x86.sse2.packsswb.128";
777 return "llvm.x86.sse2.packssdw.128";
779 return "llvm.x86.sse2.packuswb.128";
781 return "llvm.x86.sse41.packusdw";
783 return "llvm.x86.sse2.pmulh.w";
784 case OP_PMULW_HIGH_UN:
785 return "llvm.x86.sse2.pmulhu.w";
788 g_assert_not_reached ();
794 simd_op_to_llvm_type (int opcode)
796 #if defined(TARGET_X86) || defined(TARGET_AMD64)
800 return type_to_simd_type (MONO_TYPE_R8);
803 return type_to_simd_type (MONO_TYPE_I8);
806 return type_to_simd_type (MONO_TYPE_I4);
811 return type_to_simd_type (MONO_TYPE_I2);
815 return type_to_simd_type (MONO_TYPE_I1);
817 return type_to_simd_type (MONO_TYPE_R4);
820 return type_to_simd_type (MONO_TYPE_I4);
824 return type_to_simd_type (MONO_TYPE_R8);
828 return type_to_simd_type (MONO_TYPE_R4);
829 case OP_EXTRACT_MASK:
830 return type_to_simd_type (MONO_TYPE_I1);
836 return type_to_simd_type (MONO_TYPE_R4);
839 return type_to_simd_type (MONO_TYPE_R8);
841 g_assert_not_reached ();
852 * Return the LLVM basic block corresponding to BB.
854 static LLVMBasicBlockRef
855 get_bb (EmitContext *ctx, MonoBasicBlock *bb)
857 char bb_name_buf [128];
860 if (ctx->bblocks [bb->block_num].bblock == NULL) {
861 if (bb->flags & BB_EXCEPTION_HANDLER) {
862 int clause_index = (mono_get_block_region_notry (ctx->cfg, bb->region) >> 8) - 1;
863 sprintf (bb_name_buf, "EH_CLAUSE%d_BB%d", clause_index, bb->block_num);
864 bb_name = bb_name_buf;
865 } else if (bb->block_num < 256) {
866 if (!ctx->lmodule->bb_names)
867 ctx->lmodule->bb_names = g_new0 (char*, 256);
868 if (!ctx->lmodule->bb_names [bb->block_num]) {
871 n = g_strdup_printf ("BB%d", bb->block_num);
872 mono_memory_barrier ();
873 ctx->lmodule->bb_names [bb->block_num] = n;
875 bb_name = ctx->lmodule->bb_names [bb->block_num];
877 sprintf (bb_name_buf, "BB%d", bb->block_num);
878 bb_name = bb_name_buf;
881 ctx->bblocks [bb->block_num].bblock = LLVMAppendBasicBlock (ctx->lmethod, bb_name);
882 ctx->bblocks [bb->block_num].end_bblock = ctx->bblocks [bb->block_num].bblock;
885 return ctx->bblocks [bb->block_num].bblock;
891 * Return the last LLVM bblock corresponding to BB.
892 * This might not be equal to the bb returned by get_bb () since we need to generate
893 * multiple LLVM bblocks for a mono bblock to handle throwing exceptions.
895 static LLVMBasicBlockRef
896 get_end_bb (EmitContext *ctx, MonoBasicBlock *bb)
899 return ctx->bblocks [bb->block_num].end_bblock;
902 static LLVMBasicBlockRef
903 gen_bb (EmitContext *ctx, const char *prefix)
907 sprintf (bb_name, "%s%d", prefix, ++ ctx->ex_index);
908 return LLVMAppendBasicBlock (ctx->lmethod, bb_name);
914 * Return the target of the patch identified by TYPE and TARGET.
917 resolve_patch (MonoCompile *cfg, MonoJumpInfoType type, gconstpointer target)
921 memset (&ji, 0, sizeof (ji));
923 ji.data.target = target;
925 return mono_resolve_patch_target (cfg->method, cfg->domain, NULL, &ji, FALSE);
931 * Emit code to convert the LLVM value V to DTYPE.
934 convert_full (EmitContext *ctx, LLVMValueRef v, LLVMTypeRef dtype, gboolean is_unsigned)
936 LLVMTypeRef stype = LLVMTypeOf (v);
938 if (stype != dtype) {
939 gboolean ext = FALSE;
942 if (dtype == LLVMInt64Type () && (stype == LLVMInt32Type () || stype == LLVMInt16Type () || stype == LLVMInt8Type ()))
944 else if (dtype == LLVMInt32Type () && (stype == LLVMInt16Type () || stype == LLVMInt8Type ()))
946 else if (dtype == LLVMInt16Type () && (stype == LLVMInt8Type ()))
950 return is_unsigned ? LLVMBuildZExt (ctx->builder, v, dtype, "") : LLVMBuildSExt (ctx->builder, v, dtype, "");
952 if (dtype == LLVMDoubleType () && stype == LLVMFloatType ())
953 return LLVMBuildFPExt (ctx->builder, v, dtype, "");
956 if (stype == LLVMInt64Type () && (dtype == LLVMInt32Type () || dtype == LLVMInt16Type () || dtype == LLVMInt8Type ()))
957 return LLVMBuildTrunc (ctx->builder, v, dtype, "");
958 if (stype == LLVMInt32Type () && (dtype == LLVMInt16Type () || dtype == LLVMInt8Type ()))
959 return LLVMBuildTrunc (ctx->builder, v, dtype, "");
960 if (stype == LLVMInt16Type () && dtype == LLVMInt8Type ())
961 return LLVMBuildTrunc (ctx->builder, v, dtype, "");
962 if (stype == LLVMDoubleType () && dtype == LLVMFloatType ())
963 return LLVMBuildFPTrunc (ctx->builder, v, dtype, "");
965 if (LLVMGetTypeKind (stype) == LLVMPointerTypeKind && LLVMGetTypeKind (dtype) == LLVMPointerTypeKind)
966 return LLVMBuildBitCast (ctx->builder, v, dtype, "");
967 if (LLVMGetTypeKind (dtype) == LLVMPointerTypeKind)
968 return LLVMBuildIntToPtr (ctx->builder, v, dtype, "");
969 if (LLVMGetTypeKind (stype) == LLVMPointerTypeKind)
970 return LLVMBuildPtrToInt (ctx->builder, v, dtype, "");
972 if (mono_arch_is_soft_float ()) {
973 if (stype == LLVMInt32Type () && dtype == LLVMFloatType ())
974 return LLVMBuildBitCast (ctx->builder, v, dtype, "");
975 if (stype == LLVMInt32Type () && dtype == LLVMDoubleType ())
976 return LLVMBuildBitCast (ctx->builder, LLVMBuildZExt (ctx->builder, v, LLVMInt64Type (), ""), dtype, "");
979 if (LLVMGetTypeKind (stype) == LLVMVectorTypeKind && LLVMGetTypeKind (dtype) == LLVMVectorTypeKind)
980 return LLVMBuildBitCast (ctx->builder, v, dtype, "");
983 LLVMDumpValue (LLVMConstNull (dtype));
984 g_assert_not_reached ();
992 convert (EmitContext *ctx, LLVMValueRef v, LLVMTypeRef dtype)
994 return convert_full (ctx, v, dtype, FALSE);
998 * emit_volatile_load:
1000 * If vreg is volatile, emit a load from its address.
1003 emit_volatile_load (EmitContext *ctx, int vreg)
1007 LLVMValueRef v = LLVMBuildLoad (ctx->builder, ctx->addresses [vreg], "");
1008 t = ctx->vreg_cli_types [vreg];
1009 if (t && !t->byref) {
1011 * Might have to zero extend since llvm doesn't have
1014 if (t->type == MONO_TYPE_U1 || t->type == MONO_TYPE_U2 || t->type == MONO_TYPE_CHAR || t->type == MONO_TYPE_BOOLEAN)
1015 v = LLVMBuildZExt (ctx->builder, v, LLVMInt32Type (), "");
1016 else if (t->type == MONO_TYPE_U8)
1017 v = LLVMBuildZExt (ctx->builder, v, LLVMInt64Type (), "");
1024 * emit_volatile_store:
1026 * If VREG is volatile, emit a store from its value to its address.
1029 emit_volatile_store (EmitContext *ctx, int vreg)
1031 MonoInst *var = get_vreg_to_inst (ctx->cfg, vreg);
1033 if (var && var->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT)) {
1034 g_assert (ctx->addresses [vreg]);
1035 LLVMBuildStore (ctx->builder, convert (ctx, ctx->values [vreg], type_to_llvm_type (ctx, var->inst_vtype)), ctx->addresses [vreg]);
1041 * Maps parameter indexes in the original signature to parameter indexes
1042 * in the LLVM signature.
1045 /* The indexes of various special arguments in the LLVM signature */
1046 int vret_arg_pindex, this_arg_pindex, rgctx_arg_pindex, imt_arg_pindex;
1050 * sig_to_llvm_sig_full:
1052 * Return the LLVM signature corresponding to the mono signature SIG using the
1053 * calling convention information in CINFO. Return parameter mapping information in SINFO.
1056 sig_to_llvm_sig_full (EmitContext *ctx, MonoMethodSignature *sig, LLVMCallInfo *cinfo,
1059 LLVMTypeRef ret_type;
1060 LLVMTypeRef *param_types = NULL;
1062 int i, j, pindex, vret_arg_pindex = 0;
1064 gboolean vretaddr = FALSE;
1067 memset (sinfo, 0, sizeof (LLVMSigInfo));
1069 ret_type = type_to_llvm_type (ctx, sig->ret);
1070 CHECK_FAILURE (ctx);
1072 if (cinfo && cinfo->ret.storage == LLVMArgVtypeInReg) {
1073 /* LLVM models this by returning an aggregate value */
1074 if (cinfo->ret.pair_storage [0] == LLVMArgInIReg && cinfo->ret.pair_storage [1] == LLVMArgNone) {
1075 LLVMTypeRef members [2];
1077 members [0] = IntPtrType ();
1078 ret_type = LLVMStructType (members, 1, FALSE);
1080 g_assert_not_reached ();
1082 } else if (cinfo && mini_type_is_vtype (ctx->cfg, sig->ret)) {
1083 g_assert (cinfo->ret.storage == LLVMArgVtypeRetAddr);
1085 ret_type = LLVMVoidType ();
1088 pindexes = g_new0 (int, sig->param_count);
1089 param_types = g_new0 (LLVMTypeRef, (sig->param_count * 2) + 3);
1091 if (cinfo && cinfo->rgctx_arg) {
1093 sinfo->rgctx_arg_pindex = pindex;
1094 param_types [pindex] = ctx->lmodule->ptr_type;
1097 if (cinfo && cinfo->imt_arg) {
1099 sinfo->imt_arg_pindex = pindex;
1100 param_types [pindex] = ctx->lmodule->ptr_type;
1104 /* Compute the index in the LLVM signature where the vret arg needs to be passed */
1105 vret_arg_pindex = pindex;
1106 if (cinfo->vret_arg_index == 1) {
1107 /* Add the slots consumed by the first argument */
1108 LLVMArgInfo *ainfo = &cinfo->args [0];
1109 switch (ainfo->storage) {
1110 case LLVMArgVtypeInReg:
1111 for (j = 0; j < 2; ++j) {
1112 if (ainfo->pair_storage [j] == LLVMArgInIReg)
1122 sinfo->vret_arg_pindex = vret_arg_pindex;
1125 if (vretaddr && vret_arg_pindex == pindex)
1126 param_types [pindex ++] = IntPtrType ();
1129 sinfo->this_arg_pindex = pindex;
1130 param_types [pindex ++] = ThisType ();
1132 if (vretaddr && vret_arg_pindex == pindex)
1133 param_types [pindex ++] = IntPtrType ();
1134 for (i = 0; i < sig->param_count; ++i) {
1135 if (vretaddr && vret_arg_pindex == pindex)
1136 param_types [pindex ++] = IntPtrType ();
1137 pindexes [i] = pindex;
1138 if (cinfo && cinfo->args [i + sig->hasthis].storage == LLVMArgVtypeInReg) {
1139 for (j = 0; j < 2; ++j) {
1140 switch (cinfo->args [i + sig->hasthis].pair_storage [j]) {
1142 param_types [pindex ++] = LLVMIntType (sizeof (gpointer) * 8);
1147 g_assert_not_reached ();
1150 } else if (cinfo && cinfo->args [i + sig->hasthis].storage == LLVMArgVtypeByVal) {
1151 param_types [pindex] = type_to_llvm_arg_type (ctx, sig->params [i]);
1152 CHECK_FAILURE (ctx);
1153 param_types [pindex] = LLVMPointerType (param_types [pindex], 0);
1156 param_types [pindex ++] = type_to_llvm_arg_type (ctx, sig->params [i]);
1159 if (vretaddr && vret_arg_pindex == pindex)
1160 param_types [pindex ++] = IntPtrType ();
1162 CHECK_FAILURE (ctx);
1164 res = LLVMFunctionType (ret_type, param_types, pindex, FALSE);
1165 g_free (param_types);
1168 sinfo->pindexes = pindexes;
1176 g_free (param_types);
1182 sig_to_llvm_sig (EmitContext *ctx, MonoMethodSignature *sig)
1184 return sig_to_llvm_sig_full (ctx, sig, NULL, NULL);
1188 * LLVMFunctionType1:
1190 * Create an LLVM function type from the arguments.
1192 static G_GNUC_UNUSED LLVMTypeRef
1193 LLVMFunctionType1(LLVMTypeRef ReturnType,
1194 LLVMTypeRef ParamType1,
1197 LLVMTypeRef param_types [1];
1199 param_types [0] = ParamType1;
1201 return LLVMFunctionType (ReturnType, param_types, 1, IsVarArg);
1205 * LLVMFunctionType2:
1207 * Create an LLVM function type from the arguments.
1209 static G_GNUC_UNUSED LLVMTypeRef
1210 LLVMFunctionType2(LLVMTypeRef ReturnType,
1211 LLVMTypeRef ParamType1,
1212 LLVMTypeRef ParamType2,
1215 LLVMTypeRef param_types [2];
1217 param_types [0] = ParamType1;
1218 param_types [1] = ParamType2;
1220 return LLVMFunctionType (ReturnType, param_types, 2, IsVarArg);
1224 * LLVMFunctionType3:
1226 * Create an LLVM function type from the arguments.
1228 static G_GNUC_UNUSED LLVMTypeRef
1229 LLVMFunctionType3(LLVMTypeRef ReturnType,
1230 LLVMTypeRef ParamType1,
1231 LLVMTypeRef ParamType2,
1232 LLVMTypeRef ParamType3,
1235 LLVMTypeRef param_types [3];
1237 param_types [0] = ParamType1;
1238 param_types [1] = ParamType2;
1239 param_types [2] = ParamType3;
1241 return LLVMFunctionType (ReturnType, param_types, 3, IsVarArg);
1247 * Create an LLVM builder and remember it so it can be freed later.
1249 static LLVMBuilderRef
1250 create_builder (EmitContext *ctx)
1252 LLVMBuilderRef builder = LLVMCreateBuilder ();
1254 ctx->builders = g_slist_prepend_mempool (ctx->cfg->mempool, ctx->builders, builder);
1260 get_plt_entry (EmitContext *ctx, LLVMTypeRef llvm_sig, MonoJumpInfoType type, gconstpointer data)
1262 char *callee_name = mono_aot_get_plt_symbol (type, data);
1263 LLVMValueRef callee;
1268 if (ctx->cfg->compile_aot)
1269 /* Add a patch so referenced wrappers can be compiled in full aot mode */
1270 mono_add_patch_info (ctx->cfg, 0, type, data);
1273 callee = g_hash_table_lookup (ctx->lmodule->plt_entries, callee_name);
1275 callee = LLVMAddFunction (ctx->module, callee_name, llvm_sig);
1277 LLVMSetVisibility (callee, LLVMHiddenVisibility);
1279 g_hash_table_insert (ctx->lmodule->plt_entries, (char*)callee_name, callee);
1286 get_handler_clause (MonoCompile *cfg, MonoBasicBlock *bb)
1288 MonoMethodHeader *header = cfg->header;
1289 MonoExceptionClause *clause;
1293 if (bb->region != -1 && MONO_BBLOCK_IS_IN_REGION (bb, MONO_REGION_TRY))
1294 return (bb->region >> 8) - 1;
1297 for (i = 0; i < header->num_clauses; ++i) {
1298 clause = &header->clauses [i];
1300 if (MONO_OFFSET_IN_CLAUSE (clause, bb->real_offset) && clause->flags == MONO_EXCEPTION_CLAUSE_NONE)
1308 set_metadata_flag (LLVMValueRef v, const char *flag_name)
1310 LLVMValueRef md_arg;
1313 md_kind = LLVMGetMDKindID (flag_name, strlen (flag_name));
1314 md_arg = LLVMMDString ("mono", 4);
1315 LLVMSetMetadata (v, md_kind, LLVMMDNode (&md_arg, 1));
1319 set_invariant_load_flag (LLVMValueRef v)
1321 LLVMValueRef md_arg;
1323 const char *flag_name;
1325 // FIXME: Cache this
1326 flag_name = "invariant.load";
1327 md_kind = LLVMGetMDKindID (flag_name, strlen (flag_name));
1328 md_arg = LLVMMDString ("<index>", strlen ("<index>"));
1329 LLVMSetMetadata (v, md_kind, LLVMMDNode (&md_arg, 1));
1335 * Emit an LLVM call or invoke instruction depending on whenever the call is inside
1339 emit_call (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, LLVMValueRef callee, LLVMValueRef *args, int pindex)
1341 MonoCompile *cfg = ctx->cfg;
1343 LLVMBuilderRef builder = *builder_ref;
1346 clause_index = get_handler_clause (cfg, bb);
1348 if (clause_index != -1) {
1349 MonoMethodHeader *header = cfg->header;
1350 MonoExceptionClause *ec = &header->clauses [clause_index];
1351 MonoBasicBlock *tblock;
1352 LLVMBasicBlockRef ex_bb, noex_bb;
1355 * Have to use an invoke instead of a call, branching to the
1356 * handler bblock of the clause containing this bblock.
1359 g_assert (ec->flags == MONO_EXCEPTION_CLAUSE_NONE || ec->flags == MONO_EXCEPTION_CLAUSE_FINALLY);
1361 tblock = cfg->cil_offset_to_bb [ec->handler_offset];
1364 ctx->bblocks [tblock->block_num].invoke_target = TRUE;
1366 ex_bb = get_bb (ctx, tblock);
1368 noex_bb = gen_bb (ctx, "NOEX_BB");
1371 lcall = LLVMBuildInvoke (builder, callee, args, pindex, noex_bb, ex_bb, "");
1373 builder = ctx->builder = create_builder (ctx);
1374 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
1376 ctx->bblocks [bb->block_num].end_bblock = noex_bb;
1378 lcall = LLVMBuildCall (builder, callee, args, pindex, "");
1379 ctx->builder = builder;
1382 *builder_ref = ctx->builder;
1388 emit_load (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, int size, LLVMValueRef addr, const char *name, gboolean is_faulting)
1390 const char *intrins_name;
1391 LLVMValueRef args [16], res;
1392 LLVMTypeRef addr_type;
1394 if (is_faulting && bb->region != -1) {
1396 * We handle loads which can fault by calling a mono specific intrinsic
1397 * using an invoke, so they are handled properly inside try blocks.
1398 * We can't use this outside clauses, since LLVM optimizes intrinsics which
1399 * are marked with IntrReadArgMem.
1403 intrins_name = "llvm.mono.load.i8.p0i8";
1406 intrins_name = "llvm.mono.load.i16.p0i16";
1409 intrins_name = "llvm.mono.load.i32.p0i32";
1412 intrins_name = "llvm.mono.load.i64.p0i64";
1415 g_assert_not_reached ();
1418 addr_type = LLVMTypeOf (addr);
1419 if (addr_type == LLVMPointerType (LLVMDoubleType (), 0) || addr_type == LLVMPointerType (LLVMFloatType (), 0))
1420 addr = LLVMBuildBitCast (*builder_ref, addr, LLVMPointerType (LLVMIntType (size * 8), 0), "");
1423 args [1] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
1424 args [2] = LLVMConstInt (LLVMInt1Type (), TRUE, FALSE);
1425 res = emit_call (ctx, bb, builder_ref, LLVMGetNamedFunction (ctx->module, intrins_name), args, 3);
1427 if (addr_type == LLVMPointerType (LLVMDoubleType (), 0))
1428 res = LLVMBuildBitCast (*builder_ref, res, LLVMDoubleType (), "");
1429 else if (addr_type == LLVMPointerType (LLVMFloatType (), 0))
1430 res = LLVMBuildBitCast (*builder_ref, res, LLVMFloatType (), "");
1437 * We emit volatile loads for loads which can fault, because otherwise
1438 * LLVM will generate invalid code when encountering a load from a
1441 res = mono_llvm_build_load (*builder_ref, addr, name, is_faulting);
1443 /* Mark it with a custom metadata */
1446 set_metadata_flag (res, "mono.faulting.load");
1454 emit_store (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, int size, LLVMValueRef value, LLVMValueRef addr, gboolean is_faulting)
1456 const char *intrins_name;
1457 LLVMValueRef args [16];
1459 if (is_faulting && bb->region != -1) {
1462 intrins_name = "llvm.mono.store.i8.p0i8";
1465 intrins_name = "llvm.mono.store.i16.p0i16";
1468 intrins_name = "llvm.mono.store.i32.p0i32";
1471 intrins_name = "llvm.mono.store.i64.p0i64";
1474 g_assert_not_reached ();
1477 if (LLVMTypeOf (value) == LLVMDoubleType () || LLVMTypeOf (value) == LLVMFloatType ()) {
1478 value = LLVMBuildBitCast (*builder_ref, value, LLVMIntType (size * 8), "");
1479 addr = LLVMBuildBitCast (*builder_ref, addr, LLVMPointerType (LLVMIntType (size * 8), 0), "");
1484 args [2] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
1485 args [3] = LLVMConstInt (LLVMInt1Type (), TRUE, FALSE);
1486 emit_call (ctx, bb, builder_ref, LLVMGetNamedFunction (ctx->module, intrins_name), args, 4);
1488 LLVMBuildStore (*builder_ref, value, addr);
1493 * emit_cond_system_exception:
1495 * Emit code to throw the exception EXC_TYPE if the condition CMP is false.
1496 * Might set the ctx exception.
1499 emit_cond_system_exception (EmitContext *ctx, MonoBasicBlock *bb, const char *exc_type, LLVMValueRef cmp)
1501 LLVMBasicBlockRef ex_bb, noex_bb;
1502 LLVMBuilderRef builder;
1503 MonoClass *exc_class;
1504 LLVMValueRef args [2];
1506 ex_bb = gen_bb (ctx, "EX_BB");
1507 noex_bb = gen_bb (ctx, "NOEX_BB");
1509 LLVMBuildCondBr (ctx->builder, cmp, ex_bb, noex_bb);
1511 exc_class = mono_class_from_name (mono_get_corlib (), "System", exc_type);
1512 g_assert (exc_class);
1514 /* Emit exception throwing code */
1515 builder = create_builder (ctx);
1516 LLVMPositionBuilderAtEnd (builder, ex_bb);
1518 if (!ctx->lmodule->throw_corlib_exception) {
1519 LLVMValueRef callee;
1521 const char *icall_name;
1523 MonoMethodSignature *throw_sig = mono_metadata_signature_alloc (mono_get_corlib (), 2);
1524 throw_sig->ret = &mono_get_void_class ()->byval_arg;
1525 throw_sig->params [0] = &mono_get_int32_class ()->byval_arg;
1526 icall_name = "llvm_throw_corlib_exception_abs_trampoline";
1527 /* This will become i8* */
1528 throw_sig->params [1] = &mono_get_byte_class ()->this_arg;
1529 sig = sig_to_llvm_sig (ctx, throw_sig);
1531 if (ctx->cfg->compile_aot) {
1532 callee = get_plt_entry (ctx, sig, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
1534 callee = LLVMAddFunction (ctx->module, "llvm_throw_corlib_exception_trampoline", sig_to_llvm_sig (ctx, throw_sig));
1537 * Differences between the LLVM/non-LLVM throw corlib exception trampoline:
1538 * - On x86, LLVM generated code doesn't push the arguments
1539 * - The trampoline takes the throw address as an arguments, not a pc offset.
1541 LLVMAddGlobalMapping (ee, callee, resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name));
1544 mono_memory_barrier ();
1545 ctx->lmodule->throw_corlib_exception = callee;
1548 if (IS_TARGET_X86 || IS_TARGET_AMD64)
1549 args [0] = LLVMConstInt (LLVMInt32Type (), exc_class->type_token - MONO_TOKEN_TYPE_DEF, FALSE);
1551 args [0] = LLVMConstInt (LLVMInt32Type (), exc_class->type_token, FALSE);
1554 * The LLVM mono branch contains changes so a block address can be passed as an
1555 * argument to a call.
1557 args [1] = LLVMBlockAddress (ctx->lmethod, ex_bb);
1558 emit_call (ctx, bb, &builder, ctx->lmodule->throw_corlib_exception, args, 2);
1560 LLVMBuildUnreachable (builder);
1562 ctx->builder = create_builder (ctx);
1563 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
1565 ctx->bblocks [bb->block_num].end_bblock = noex_bb;
1572 * emit_reg_to_vtype:
1574 * Emit code to store the vtype in the registers REGS to the address ADDRESS.
1577 emit_reg_to_vtype (EmitContext *ctx, LLVMBuilderRef builder, MonoType *t, LLVMValueRef address, LLVMArgInfo *ainfo, LLVMValueRef *regs)
1581 size = get_vtype_size (t);
1583 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (t))) {
1584 address = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (LLVMInt8Type (), 0), "");
1587 for (j = 0; j < 2; ++j) {
1588 LLVMValueRef index [2], addr;
1589 int part_size = size > sizeof (gpointer) ? sizeof (gpointer) : size;
1590 LLVMTypeRef part_type;
1592 if (ainfo->pair_storage [j] == LLVMArgNone)
1595 part_type = LLVMIntType (part_size * 8);
1596 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (t))) {
1597 index [0] = LLVMConstInt (LLVMInt32Type (), j * sizeof (gpointer), FALSE);
1598 addr = LLVMBuildGEP (builder, address, index, 1, "");
1600 index [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
1601 index [1] = LLVMConstInt (LLVMInt32Type (), j * sizeof (gpointer), FALSE);
1602 addr = LLVMBuildGEP (builder, address, index, 2, "");
1604 switch (ainfo->pair_storage [j]) {
1606 LLVMBuildStore (builder, convert (ctx, regs [j], part_type), LLVMBuildBitCast (ctx->builder, addr, LLVMPointerType (part_type, 0), ""));
1611 g_assert_not_reached ();
1614 size -= sizeof (gpointer);
1619 * emit_vtype_to_reg:
1621 * Emit code to load a vtype at address ADDRESS into registers. Store the registers
1622 * into REGS, and the number of registers into NREGS.
1625 emit_vtype_to_reg (EmitContext *ctx, LLVMBuilderRef builder, MonoType *t, LLVMValueRef address, LLVMArgInfo *ainfo, LLVMValueRef *regs, guint32 *nregs)
1630 size = get_vtype_size (t);
1632 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (t))) {
1633 address = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (LLVMInt8Type (), 0), "");
1636 for (j = 0; j < 2; ++j) {
1637 LLVMValueRef index [2], addr;
1638 int partsize = size > sizeof (gpointer) ? sizeof (gpointer) : size;
1640 if (ainfo->pair_storage [j] == LLVMArgNone)
1643 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (t))) {
1644 index [0] = LLVMConstInt (LLVMInt32Type (), j * sizeof (gpointer), FALSE);
1645 addr = LLVMBuildGEP (builder, address, index, 1, "");
1647 index [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
1648 index [1] = LLVMConstInt (LLVMInt32Type (), j * sizeof (gpointer), FALSE);
1649 addr = LLVMBuildGEP (builder, address, index, 2, "");
1651 switch (ainfo->pair_storage [j]) {
1653 regs [pindex ++] = convert (ctx, LLVMBuildLoad (builder, LLVMBuildBitCast (ctx->builder, addr, LLVMPointerType (LLVMIntType (partsize * 8), 0), ""), ""), IntPtrType ());
1658 g_assert_not_reached ();
1660 size -= sizeof (gpointer);
1667 build_alloca (EmitContext *ctx, MonoType *t)
1669 MonoClass *k = mono_class_from_mono_type (t);
1672 if (MONO_CLASS_IS_SIMD (ctx->cfg, k))
1675 align = mono_class_min_align (k);
1677 /* Sometimes align is not a power of 2 */
1678 while (mono_is_power_of_two (align) == -1)
1682 * Have to place all alloca's at the end of the entry bb, since otherwise they would
1683 * get executed every time control reaches them.
1685 LLVMPositionBuilder (ctx->alloca_builder, get_bb (ctx, ctx->cfg->bb_entry), ctx->last_alloca);
1687 ctx->last_alloca = mono_llvm_build_alloca (ctx->alloca_builder, type_to_llvm_type (ctx, t), NULL, align, "");
1688 return ctx->last_alloca;
1692 * Put the global into the 'llvm.used' array to prevent it from being optimized away.
1695 mark_as_used (MonoLLVMModule *lmodule, LLVMValueRef global)
1698 lmodule->used = g_ptr_array_sized_new (16);
1699 g_ptr_array_add (lmodule->used, global);
1703 emit_llvm_used (MonoLLVMModule *lmodule)
1705 LLVMModuleRef module = lmodule->module;
1706 LLVMTypeRef used_type;
1707 LLVMValueRef used, *used_elem;
1713 used_type = LLVMArrayType (LLVMPointerType (LLVMInt8Type (), 0), lmodule->used->len);
1714 used = LLVMAddGlobal (module, used_type, "llvm.used");
1715 used_elem = g_new0 (LLVMValueRef, lmodule->used->len);
1716 for (i = 0; i < lmodule->used->len; ++i)
1717 used_elem [i] = LLVMConstBitCast (g_ptr_array_index (lmodule->used, i), LLVMPointerType (LLVMInt8Type (), 0));
1718 LLVMSetInitializer (used, LLVMConstArray (LLVMPointerType (LLVMInt8Type (), 0), used_elem, lmodule->used->len));
1719 LLVMSetLinkage (used, LLVMAppendingLinkage);
1720 LLVMSetSection (used, "llvm.metadata");
1726 * Emit code to load/convert arguments.
1729 emit_entry_bb (EmitContext *ctx, LLVMBuilderRef builder)
1732 MonoCompile *cfg = ctx->cfg;
1733 MonoMethodSignature *sig = ctx->sig;
1734 LLVMCallInfo *linfo = ctx->linfo;
1737 ctx->alloca_builder = create_builder (ctx);
1740 * Handle indirect/volatile variables by allocating memory for them
1741 * using 'alloca', and storing their address in a temporary.
1743 for (i = 0; i < cfg->num_varinfo; ++i) {
1744 MonoInst *var = cfg->varinfo [i];
1747 if (var->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT) || mini_type_is_vtype (cfg, var->inst_vtype)) {
1748 vtype = type_to_llvm_type (ctx, var->inst_vtype);
1749 CHECK_FAILURE (ctx);
1750 /* Could be already created by an OP_VPHI */
1751 if (!ctx->addresses [var->dreg])
1752 ctx->addresses [var->dreg] = build_alloca (ctx, var->inst_vtype);
1753 ctx->vreg_cli_types [var->dreg] = var->inst_vtype;
1757 for (i = 0; i < sig->param_count; ++i) {
1758 LLVMArgInfo *ainfo = &linfo->args [i + sig->hasthis];
1759 int reg = cfg->args [i + sig->hasthis]->dreg;
1761 if (ainfo->storage == LLVMArgVtypeInReg) {
1762 LLVMValueRef regs [2];
1765 * Emit code to save the argument from the registers to
1766 * the real argument.
1768 pindex = ctx->pindexes [i];
1769 regs [0] = LLVMGetParam (ctx->lmethod, pindex);
1770 if (ainfo->pair_storage [1] != LLVMArgNone)
1771 regs [1] = LLVMGetParam (ctx->lmethod, pindex + 1);
1775 ctx->addresses [reg] = build_alloca (ctx, sig->params [i]);
1777 emit_reg_to_vtype (ctx, builder, sig->params [i], ctx->addresses [reg], ainfo, regs);
1779 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (sig->params [i]))) {
1780 /* Treat these as normal values */
1781 ctx->values [reg] = LLVMBuildLoad (builder, ctx->addresses [reg], "");
1783 } else if (ainfo->storage == LLVMArgVtypeByVal) {
1784 ctx->addresses [reg] = LLVMGetParam (ctx->lmethod, ctx->pindexes [i]);
1786 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (sig->params [i]))) {
1787 /* Treat these as normal values */
1788 ctx->values [reg] = LLVMBuildLoad (builder, ctx->addresses [reg], "");
1791 ctx->values [reg] = convert (ctx, ctx->values [reg], llvm_type_to_stack_type (type_to_llvm_type (ctx, sig->params [i])));
1796 emit_volatile_store (ctx, cfg->vret_addr->dreg);
1798 emit_volatile_store (ctx, cfg->args [0]->dreg);
1799 for (i = 0; i < sig->param_count; ++i)
1800 if (!mini_type_is_vtype (cfg, sig->params [i]))
1801 emit_volatile_store (ctx, cfg->args [i + sig->hasthis]->dreg);
1803 if (sig->hasthis && !cfg->rgctx_var && cfg->generic_sharing_context) {
1804 LLVMValueRef this_alloc;
1807 * The exception handling code needs the location where the this argument was
1808 * stored for gshared methods. We create a separate alloca to hold it, and mark it
1809 * with the "mono.this" custom metadata to tell llvm that it needs to save its
1810 * location into the LSDA.
1812 this_alloc = mono_llvm_build_alloca (builder, ThisType (), LLVMConstInt (LLVMInt32Type (), 1, FALSE), 0, "");
1813 /* This volatile store will keep the alloca alive */
1814 mono_llvm_build_store (builder, ctx->values [cfg->args [0]->dreg], this_alloc, TRUE);
1816 set_metadata_flag (this_alloc, "mono.this");
1819 if (cfg->rgctx_var) {
1820 LLVMValueRef rgctx_alloc, store;
1823 * We handle the rgctx arg similarly to the this pointer.
1825 g_assert (ctx->addresses [cfg->rgctx_var->dreg]);
1826 rgctx_alloc = ctx->addresses [cfg->rgctx_var->dreg];
1827 /* This volatile store will keep the alloca alive */
1828 store = mono_llvm_build_store (builder, convert (ctx, ctx->rgctx_arg, IntPtrType ()), rgctx_alloc, TRUE);
1830 set_metadata_flag (rgctx_alloc, "mono.this");
1834 * For finally clauses, create an indicator variable telling OP_ENDFINALLY whenever
1835 * it needs to continue normally, or return back to the exception handling system.
1837 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
1838 if (bb->region != -1 && (bb->flags & BB_EXCEPTION_HANDLER))
1839 g_hash_table_insert (ctx->region_to_handler, GUINT_TO_POINTER (mono_get_block_region_notry (cfg, bb->region)), bb);
1840 if (bb->region != -1 && (bb->flags & BB_EXCEPTION_HANDLER) && bb->in_scount == 0) {
1844 sprintf (name, "finally_ind_bb%d", bb->block_num);
1845 val = LLVMBuildAlloca (builder, LLVMInt32Type (), name);
1846 LLVMBuildStore (builder, LLVMConstInt (LLVMInt32Type (), 0, FALSE), val);
1848 ctx->bblocks [bb->block_num].finally_ind = val;
1851 * Create a new bblock which CALL_HANDLER can branch to, because branching to the
1852 * LLVM bblock containing the call to llvm.eh.selector causes problems for the
1853 * LLVM optimizer passes.
1855 sprintf (name, "BB_%d_CALL_HANDLER_TARGET", bb->block_num);
1856 ctx->bblocks [bb->block_num].call_handler_target_bb = LLVMAppendBasicBlock (ctx->lmethod, name);
1864 /* Have to export this for AOT */
1866 mono_personality (void);
1869 mono_personality (void)
1872 g_assert_not_reached ();
1876 process_call (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, MonoInst *ins)
1878 MonoCompile *cfg = ctx->cfg;
1879 LLVMModuleRef module = ctx->module;
1880 LLVMValueRef *values = ctx->values;
1881 LLVMValueRef *addresses = ctx->addresses;
1882 MonoCallInst *call = (MonoCallInst*)ins;
1883 MonoMethodSignature *sig = call->signature;
1884 LLVMValueRef callee = NULL, lcall;
1886 LLVMCallInfo *cinfo;
1890 LLVMTypeRef llvm_sig;
1892 gboolean virtual, calli;
1893 LLVMBuilderRef builder = *builder_ref;
1896 if (call->signature->call_convention != MONO_CALL_DEFAULT)
1897 LLVM_FAILURE (ctx, "non-default callconv");
1899 cinfo = call->cinfo;
1900 if (call->rgctx_arg_reg)
1901 cinfo->rgctx_arg = TRUE;
1902 if (call->imt_arg_reg)
1903 cinfo->imt_arg = TRUE;
1905 vretaddr = cinfo && cinfo->ret.storage == LLVMArgVtypeRetAddr;
1907 llvm_sig = sig_to_llvm_sig_full (ctx, sig, cinfo, &sinfo);
1908 CHECK_FAILURE (ctx);
1910 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);
1911 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);
1913 /* FIXME: Avoid creating duplicate methods */
1915 if (ins->flags & MONO_INST_HAS_METHOD) {
1919 if (cfg->compile_aot) {
1920 callee = get_plt_entry (ctx, llvm_sig, MONO_PATCH_INFO_METHOD, call->method);
1922 LLVM_FAILURE (ctx, "can't encode patch");
1924 callee = LLVMAddFunction (module, "", llvm_sig);
1927 mono_create_jit_trampoline_in_domain (mono_domain_get (),
1929 LLVMAddGlobalMapping (ee, callee, target);
1933 if (call->method && strstr (call->method->klass->name, "AsyncVoidMethodBuilder"))
1934 /* LLVM miscompiles async methods */
1935 LLVM_FAILURE (ctx, "#13734");
1938 MonoJitICallInfo *info = mono_find_jit_icall_by_addr (call->fptr);
1944 memset (&ji, 0, sizeof (ji));
1945 ji.type = MONO_PATCH_INFO_JIT_ICALL_ADDR;
1946 ji.data.target = info->name;
1948 target = mono_resolve_patch_target (cfg->method, cfg->domain, NULL, &ji, FALSE);
1950 if (cfg->compile_aot) {
1951 callee = get_plt_entry (ctx, llvm_sig, MONO_PATCH_INFO_INTERNAL_METHOD, (char*)info->name);
1953 LLVM_FAILURE (ctx, "can't encode patch");
1955 callee = LLVMAddFunction (module, "", llvm_sig);
1956 target = (gpointer)mono_icall_get_wrapper (info);
1957 LLVMAddGlobalMapping (ee, callee, target);
1960 if (cfg->compile_aot) {
1962 if (cfg->abs_patches) {
1963 MonoJumpInfo *abs_ji = g_hash_table_lookup (cfg->abs_patches, call->fptr);
1965 callee = get_plt_entry (ctx, llvm_sig, abs_ji->type, abs_ji->data.target);
1967 LLVM_FAILURE (ctx, "can't encode patch");
1971 LLVM_FAILURE (ctx, "aot");
1973 callee = LLVMAddFunction (module, "", llvm_sig);
1975 if (cfg->abs_patches) {
1976 MonoJumpInfo *abs_ji = g_hash_table_lookup (cfg->abs_patches, call->fptr);
1979 * FIXME: Some trampolines might have
1980 * their own calling convention on some platforms.
1982 #ifndef TARGET_AMD64
1983 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)
1984 LLVM_FAILURE (ctx, "trampoline with own cconv");
1986 target = mono_resolve_patch_target (cfg->method, cfg->domain, NULL, abs_ji, FALSE);
1987 LLVMAddGlobalMapping (ee, callee, target);
1991 LLVMAddGlobalMapping (ee, callee, (gpointer)call->fptr);
1997 int size = sizeof (gpointer);
2000 g_assert (ins->inst_offset % size == 0);
2001 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
2003 callee = convert (ctx, LLVMBuildLoad (builder, LLVMBuildGEP (builder, convert (ctx, values [ins->inst_basereg], LLVMPointerType (LLVMPointerType (IntPtrType (), 0), 0)), &index, 1, ""), ""), LLVMPointerType (llvm_sig, 0));
2005 callee = convert (ctx, values [ins->sreg1], LLVMPointerType (llvm_sig, 0));
2007 if (ins->flags & MONO_INST_HAS_METHOD) {
2012 * Collect and convert arguments
2014 nargs = (sig->param_count * 2) + sig->hasthis + vretaddr + call->rgctx_reg + call->imt_arg_reg;
2015 len = sizeof (LLVMValueRef) * nargs;
2016 args = alloca (len);
2017 memset (args, 0, len);
2018 l = call->out_ireg_args;
2020 if (call->rgctx_arg_reg) {
2021 g_assert (values [call->rgctx_arg_reg]);
2022 g_assert (sinfo.rgctx_arg_pindex < nargs);
2023 args [sinfo.rgctx_arg_pindex] = convert (ctx, values [call->rgctx_arg_reg], ctx->lmodule->ptr_type);
2025 if (call->imt_arg_reg) {
2026 g_assert (values [call->imt_arg_reg]);
2027 g_assert (sinfo.imt_arg_pindex < nargs);
2028 args [sinfo.imt_arg_pindex] = convert (ctx, values [call->imt_arg_reg], ctx->lmodule->ptr_type);
2032 if (!addresses [call->inst.dreg])
2033 addresses [call->inst.dreg] = build_alloca (ctx, sig->ret);
2034 g_assert (sinfo.vret_arg_pindex < nargs);
2035 args [sinfo.vret_arg_pindex] = LLVMBuildPtrToInt (builder, addresses [call->inst.dreg], IntPtrType (), "");
2038 for (i = 0; i < sig->param_count + sig->hasthis; ++i) {
2041 LLVMArgInfo *ainfo = call->cinfo ? &call->cinfo->args [i] : NULL;
2045 pindex = sinfo.this_arg_pindex;
2047 pindex = sinfo.pindexes [i - 1];
2049 pindex = sinfo.pindexes [i];
2052 regpair = (guint32)(gssize)(l->data);
2053 reg = regpair & 0xffffff;
2054 args [pindex] = values [reg];
2055 if (ainfo->storage == LLVMArgVtypeInReg) {
2057 LLVMValueRef regs [2];
2062 g_assert (addresses [reg]);
2064 emit_vtype_to_reg (ctx, builder, sig->params [i - sig->hasthis], addresses [reg], ainfo, regs, &nregs);
2065 for (j = 0; j < nregs; ++j)
2066 args [pindex ++] = regs [j];
2069 // FIXME: Get rid of the VMOVE
2070 } else if (ainfo->storage == LLVMArgVtypeByVal) {
2071 g_assert (addresses [reg]);
2072 args [pindex] = addresses [reg];
2074 g_assert (args [pindex]);
2075 if (i == 0 && sig->hasthis)
2076 args [pindex] = convert (ctx, args [pindex], ThisType ());
2078 args [pindex] = convert (ctx, args [pindex], type_to_llvm_arg_type (ctx, sig->params [i - sig->hasthis]));
2084 // FIXME: Align call sites
2090 lcall = emit_call (ctx, bb, &builder, callee, args, LLVMCountParamTypes (llvm_sig));
2093 * Modify cconv and parameter attributes to pass rgctx/imt correctly.
2095 #if defined(MONO_ARCH_IMT_REG) && defined(MONO_ARCH_RGCTX_REG)
2096 g_assert (MONO_ARCH_IMT_REG == MONO_ARCH_RGCTX_REG);
2098 /* The two can't be used together, so use only one LLVM calling conv to pass them */
2099 g_assert (!(call->rgctx_arg_reg && call->imt_arg_reg));
2101 LLVMSetInstructionCallConv (lcall, LLVMMono1CallConv);
2103 if (call->rgctx_arg_reg)
2104 LLVMAddInstrAttribute (lcall, 1 + sinfo.rgctx_arg_pindex, LLVMInRegAttribute);
2105 if (call->imt_arg_reg)
2106 LLVMAddInstrAttribute (lcall, 1 + sinfo.imt_arg_pindex, LLVMInRegAttribute);
2108 /* Add byval attributes if needed */
2109 for (i = 0; i < sig->param_count; ++i) {
2110 LLVMArgInfo *ainfo = call->cinfo ? &call->cinfo->args [i + sig->hasthis] : NULL;
2112 if (ainfo && ainfo->storage == LLVMArgVtypeByVal) {
2113 LLVMAddInstrAttribute (lcall, 1 + sinfo.pindexes [i], LLVMByValAttribute);
2118 * Convert the result
2120 if (cinfo && cinfo->ret.storage == LLVMArgVtypeInReg) {
2121 LLVMValueRef regs [2];
2123 if (!addresses [ins->dreg])
2124 addresses [ins->dreg] = build_alloca (ctx, sig->ret);
2126 regs [0] = LLVMBuildExtractValue (builder, lcall, 0, "");
2127 if (cinfo->ret.pair_storage [1] != LLVMArgNone)
2128 regs [1] = LLVMBuildExtractValue (builder, lcall, 1, "");
2130 emit_reg_to_vtype (ctx, builder, sig->ret, addresses [ins->dreg], &cinfo->ret, regs);
2131 } else if (sig->ret->type != MONO_TYPE_VOID && !vretaddr) {
2132 /* If the method returns an unsigned value, need to zext it */
2134 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));
2137 *builder_ref = ctx->builder;
2139 g_free (sinfo.pindexes);
2147 process_bb (EmitContext *ctx, MonoBasicBlock *bb)
2149 MonoCompile *cfg = ctx->cfg;
2150 MonoMethodSignature *sig = ctx->sig;
2151 LLVMValueRef method = ctx->lmethod;
2152 LLVMValueRef *values = ctx->values;
2153 LLVMValueRef *addresses = ctx->addresses;
2155 LLVMCallInfo *linfo = ctx->linfo;
2156 LLVMModuleRef module = ctx->module;
2157 BBInfo *bblocks = ctx->bblocks;
2159 LLVMBasicBlockRef cbb;
2160 LLVMBuilderRef builder, starting_builder;
2161 gboolean has_terminator;
2163 LLVMValueRef lhs, rhs;
2166 cbb = get_bb (ctx, bb);
2167 builder = create_builder (ctx);
2168 ctx->builder = builder;
2169 LLVMPositionBuilderAtEnd (builder, cbb);
2171 if (bb == cfg->bb_entry)
2172 emit_entry_bb (ctx, builder);
2173 CHECK_FAILURE (ctx);
2175 if (bb->flags & BB_EXCEPTION_HANDLER) {
2177 LLVMValueRef personality;
2178 LLVMBasicBlockRef target_bb;
2180 static gint32 mapping_inited;
2181 static int ti_generator;
2184 LLVMValueRef type_info;
2187 if (!bblocks [bb->block_num].invoke_target) {
2189 * LLVM asserts if llvm.eh.selector is called from a bblock which
2190 * doesn't have an invoke pointing at it.
2191 * Update: LLVM no longer asserts, but some tests in exceptions.exe now fail.
2193 LLVM_FAILURE (ctx, "handler without invokes");
2196 // <resultval> = landingpad <somety> personality <type> <pers_fn> <clause>+
2198 if (cfg->compile_aot) {
2199 /* Use a dummy personality function */
2200 personality = LLVMGetNamedFunction (module, "mono_aot_personality");
2201 g_assert (personality);
2203 personality = LLVMGetNamedFunction (module, "mono_personality");
2204 if (InterlockedCompareExchange (&mapping_inited, 1, 0) == 0)
2205 LLVMAddGlobalMapping (ee, personality, mono_personality);
2208 i8ptr = LLVMPointerType (LLVMInt8Type (), 0);
2210 clause_index = (mono_get_block_region_notry (cfg, bb->region) >> 8) - 1;
2213 * Create the type info
2215 sprintf (ti_name, "type_info_%d", ti_generator);
2218 if (cfg->compile_aot) {
2219 /* decode_eh_frame () in aot-runtime.c will decode this */
2220 type_info = LLVMAddGlobal (module, LLVMInt32Type (), ti_name);
2221 LLVMSetInitializer (type_info, LLVMConstInt (LLVMInt32Type (), clause_index, FALSE));
2224 * These symbols are not really used, the clause_index is embedded into the EH tables generated by DwarfMonoException in LLVM.
2226 LLVMSetLinkage (type_info, LLVMInternalLinkage);
2229 * Enabling this causes llc to crash:
2230 * http://llvm.org/bugs/show_bug.cgi?id=6102
2232 //LLVM_FAILURE (ctx, "aot+clauses");
2234 // test_0_invalid_unbox_arrays () fails
2235 LLVM_FAILURE (ctx, "aot+clauses");
2239 * After the cfg mempool is freed, the type info will point to stale memory,
2240 * but this is not a problem, since we decode it once in exception_cb during
2243 ti = mono_mempool_alloc (cfg->mempool, sizeof (gint32));
2244 *(gint32*)ti = clause_index;
2246 type_info = LLVMAddGlobal (module, i8ptr, ti_name);
2248 LLVMAddGlobalMapping (ee, type_info, ti);
2252 LLVMTypeRef members [2], ret_type;
2253 LLVMValueRef landing_pad;
2255 members [0] = i8ptr;
2256 members [1] = LLVMInt32Type ();
2257 ret_type = LLVMStructType (members, 2, FALSE);
2259 landing_pad = LLVMBuildLandingPad (builder, ret_type, personality, 1, "");
2260 LLVMAddClause (landing_pad, type_info);
2262 /* Store the exception into the exvar */
2263 if (bb->in_scount == 1) {
2264 g_assert (bb->in_scount == 1);
2265 exvar = bb->in_stack [0];
2267 // FIXME: This is shared with filter clauses ?
2268 g_assert (!values [exvar->dreg]);
2270 values [exvar->dreg] = LLVMBuildExtractValue (builder, landing_pad, 0, "ex_obj");
2271 emit_volatile_store (ctx, exvar->dreg);
2275 /* Start a new bblock which CALL_HANDLER can branch to */
2276 target_bb = bblocks [bb->block_num].call_handler_target_bb;
2278 LLVMBuildBr (builder, target_bb);
2280 ctx->builder = builder = create_builder (ctx);
2281 LLVMPositionBuilderAtEnd (ctx->builder, target_bb);
2283 ctx->bblocks [bb->block_num].end_bblock = target_bb;
2287 has_terminator = FALSE;
2288 starting_builder = builder;
2289 for (ins = bb->code; ins; ins = ins->next) {
2290 const char *spec = LLVM_INS_INFO (ins->opcode);
2292 char dname_buf [128];
2295 if (nins > 5000 && builder == starting_builder) {
2296 /* some steps in llc are non-linear in the size of basic blocks, see #5714 */
2297 LLVM_FAILURE (ctx, "basic block too long");
2301 /* There could be instructions after a terminator, skip them */
2304 if (spec [MONO_INST_DEST] != ' ' && !MONO_IS_STORE_MEMBASE (ins)) {
2305 sprintf (dname_buf, "t%d", ins->dreg);
2309 if (spec [MONO_INST_SRC1] != ' ' && spec [MONO_INST_SRC1] != 'v') {
2310 MonoInst *var = get_vreg_to_inst (cfg, ins->sreg1);
2312 if (var && var->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT)) {
2313 lhs = emit_volatile_load (ctx, ins->sreg1);
2315 /* It is ok for SETRET to have an uninitialized argument */
2316 if (!values [ins->sreg1] && ins->opcode != OP_SETRET)
2317 LLVM_FAILURE (ctx, "sreg1");
2318 lhs = values [ins->sreg1];
2324 if (spec [MONO_INST_SRC2] != ' ' && spec [MONO_INST_SRC2] != ' ') {
2325 MonoInst *var = get_vreg_to_inst (cfg, ins->sreg2);
2326 if (var && var->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT)) {
2327 rhs = emit_volatile_load (ctx, ins->sreg2);
2329 if (!values [ins->sreg2])
2330 LLVM_FAILURE (ctx, "sreg2");
2331 rhs = values [ins->sreg2];
2337 //mono_print_ins (ins);
2338 switch (ins->opcode) {
2341 case OP_LIVERANGE_START:
2342 case OP_LIVERANGE_END:
2345 values [ins->dreg] = LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE);
2348 #if SIZEOF_VOID_P == 4
2349 values [ins->dreg] = LLVMConstInt (LLVMInt64Type (), GET_LONG_IMM (ins), FALSE);
2351 values [ins->dreg] = LLVMConstInt (LLVMInt64Type (), (gint64)ins->inst_c0, FALSE);
2355 values [ins->dreg] = LLVMConstReal (LLVMDoubleType (), *(double*)ins->inst_p0);
2358 values [ins->dreg] = LLVMConstFPExt (LLVMConstReal (LLVMFloatType (), *(float*)ins->inst_p0), LLVMDoubleType ());
2361 LLVMBuildBr (builder, get_bb (ctx, ins->inst_target_bb));
2362 has_terminator = TRUE;
2368 LLVMBasicBlockRef new_bb;
2369 LLVMBuilderRef new_builder;
2371 // The default branch is already handled
2372 // FIXME: Handle it here
2374 /* Start new bblock */
2375 sprintf (bb_name, "SWITCH_DEFAULT_BB%d", ctx->default_index ++);
2376 new_bb = LLVMAppendBasicBlock (ctx->lmethod, bb_name);
2378 lhs = convert (ctx, lhs, LLVMInt32Type ());
2379 v = LLVMBuildSwitch (builder, lhs, new_bb, GPOINTER_TO_UINT (ins->klass));
2380 for (i = 0; i < GPOINTER_TO_UINT (ins->klass); ++i) {
2381 MonoBasicBlock *target_bb = ins->inst_many_bb [i];
2383 LLVMAddCase (v, LLVMConstInt (LLVMInt32Type (), i, FALSE), get_bb (ctx, target_bb));
2386 new_builder = create_builder (ctx);
2387 LLVMPositionBuilderAtEnd (new_builder, new_bb);
2388 LLVMBuildUnreachable (new_builder);
2390 has_terminator = TRUE;
2391 g_assert (!ins->next);
2397 if (linfo->ret.storage == LLVMArgVtypeInReg) {
2398 LLVMTypeRef ret_type = LLVMGetReturnType (LLVMGetElementType (LLVMTypeOf (method)));
2399 LLVMValueRef part1, retval;
2402 size = get_vtype_size (sig->ret);
2404 g_assert (addresses [ins->sreg1]);
2406 g_assert (linfo->ret.pair_storage [0] == LLVMArgInIReg);
2407 g_assert (linfo->ret.pair_storage [1] == LLVMArgNone);
2409 part1 = convert (ctx, LLVMBuildLoad (builder, LLVMBuildBitCast (builder, addresses [ins->sreg1], LLVMPointerType (LLVMIntType (size * 8), 0), ""), ""), IntPtrType ());
2411 retval = LLVMBuildInsertValue (builder, LLVMGetUndef (ret_type), part1, 0, "");
2413 LLVMBuildRet (builder, retval);
2417 if (linfo->ret.storage == LLVMArgVtypeRetAddr) {
2418 LLVMBuildRetVoid (builder);
2422 if (!lhs || ctx->is_dead [ins->sreg1]) {
2424 * The method did not set its return value, probably because it
2425 * ends with a throw.
2428 LLVMBuildRetVoid (builder);
2430 LLVMBuildRet (builder, LLVMConstNull (type_to_llvm_type (ctx, sig->ret)));
2432 LLVMBuildRet (builder, convert (ctx, lhs, type_to_llvm_type (ctx, sig->ret)));
2434 has_terminator = TRUE;
2440 case OP_ICOMPARE_IMM:
2441 case OP_LCOMPARE_IMM:
2442 case OP_COMPARE_IMM: {
2446 if (ins->next->opcode == OP_NOP)
2449 if (ins->next->opcode == OP_BR)
2450 /* The comparison result is not needed */
2453 rel = mono_opcode_to_cond (ins->next->opcode);
2455 if (ins->opcode == OP_ICOMPARE_IMM) {
2456 lhs = convert (ctx, lhs, LLVMInt32Type ());
2457 rhs = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
2459 if (ins->opcode == OP_LCOMPARE_IMM) {
2460 lhs = convert (ctx, lhs, LLVMInt64Type ());
2461 rhs = LLVMConstInt (LLVMInt64Type (), GET_LONG_IMM (ins), FALSE);
2463 if (ins->opcode == OP_LCOMPARE) {
2464 lhs = convert (ctx, lhs, LLVMInt64Type ());
2465 rhs = convert (ctx, rhs, LLVMInt64Type ());
2467 if (ins->opcode == OP_ICOMPARE) {
2468 lhs = convert (ctx, lhs, LLVMInt32Type ());
2469 rhs = convert (ctx, rhs, LLVMInt32Type ());
2473 if (LLVMGetTypeKind (LLVMTypeOf (lhs)) == LLVMPointerTypeKind)
2474 rhs = convert (ctx, rhs, LLVMTypeOf (lhs));
2475 else if (LLVMGetTypeKind (LLVMTypeOf (rhs)) == LLVMPointerTypeKind)
2476 lhs = convert (ctx, lhs, LLVMTypeOf (rhs));
2479 /* We use COMPARE+SETcc/Bcc, llvm uses SETcc+br cond */
2480 if (ins->opcode == OP_FCOMPARE)
2481 cmp = LLVMBuildFCmp (builder, fpcond_to_llvm_cond [rel], convert (ctx, lhs, LLVMDoubleType ()), convert (ctx, rhs, LLVMDoubleType ()), "");
2482 else if (ins->opcode == OP_COMPARE_IMM) {
2483 if (LLVMGetTypeKind (LLVMTypeOf (lhs)) == LLVMPointerTypeKind && ins->inst_imm == 0)
2484 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], lhs, LLVMConstNull (LLVMTypeOf (lhs)), "");
2486 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE), "");
2487 } else if (ins->opcode == OP_LCOMPARE_IMM) {
2488 if (SIZEOF_REGISTER == 4 && COMPILE_LLVM (cfg)) {
2489 /* The immediate is encoded in two fields */
2490 guint64 l = ((guint64)(guint32)ins->inst_offset << 32) | ((guint32)ins->inst_imm);
2491 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, LLVMInt64Type ()), LLVMConstInt (LLVMInt64Type (), l, FALSE), "");
2493 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, LLVMInt64Type ()), LLVMConstInt (LLVMInt64Type (), ins->inst_imm, FALSE), "");
2496 else if (ins->opcode == OP_COMPARE) {
2497 if (LLVMGetTypeKind (LLVMTypeOf (lhs)) == LLVMPointerTypeKind && LLVMTypeOf (lhs) == LLVMTypeOf (rhs))
2498 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], lhs, rhs, "");
2500 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, IntPtrType ()), convert (ctx, rhs, IntPtrType ()), "");
2502 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], lhs, rhs, "");
2504 if (MONO_IS_COND_BRANCH_OP (ins->next)) {
2505 if (ins->next->inst_true_bb == ins->next->inst_false_bb) {
2507 * If the target bb contains PHI instructions, LLVM requires
2508 * two PHI entries for this bblock, while we only generate one.
2509 * So convert this to an unconditional bblock. (bxc #171).
2511 LLVMBuildBr (builder, get_bb (ctx, ins->next->inst_true_bb));
2513 LLVMBuildCondBr (builder, cmp, get_bb (ctx, ins->next->inst_true_bb), get_bb (ctx, ins->next->inst_false_bb));
2515 has_terminator = TRUE;
2516 } else if (MONO_IS_SETCC (ins->next)) {
2517 sprintf (dname_buf, "t%d", ins->next->dreg);
2519 values [ins->next->dreg] = LLVMBuildZExt (builder, cmp, LLVMInt32Type (), dname);
2521 /* Add stores for volatile variables */
2522 emit_volatile_store (ctx, ins->next->dreg);
2523 } else if (MONO_IS_COND_EXC (ins->next)) {
2524 emit_cond_system_exception (ctx, bb, ins->next->inst_p1, cmp);
2525 CHECK_FAILURE (ctx);
2526 builder = ctx->builder;
2528 LLVM_FAILURE (ctx, "next");
2542 rel = mono_opcode_to_cond (ins->opcode);
2544 cmp = LLVMBuildFCmp (builder, fpcond_to_llvm_cond [rel], convert (ctx, lhs, LLVMDoubleType ()), convert (ctx, rhs, LLVMDoubleType ()), "");
2545 values [ins->dreg] = LLVMBuildZExt (builder, cmp, LLVMInt32Type (), dname);
2553 gboolean empty = TRUE;
2555 /* Check that all input bblocks really branch to us */
2556 for (i = 0; i < bb->in_count; ++i) {
2557 if (bb->in_bb [i]->last_ins && bb->in_bb [i]->last_ins->opcode == OP_NOT_REACHED)
2558 ins->inst_phi_args [i + 1] = -1;
2564 /* LLVM doesn't like phi instructions with zero operands */
2565 ctx->is_dead [ins->dreg] = TRUE;
2569 /* Created earlier, insert it now */
2570 LLVMInsertIntoBuilder (builder, values [ins->dreg]);
2572 for (i = 0; i < ins->inst_phi_args [0]; i++) {
2573 int sreg1 = ins->inst_phi_args [i + 1];
2577 * Count the number of times the incoming bblock branches to us,
2578 * since llvm requires a separate entry for each.
2580 if (bb->in_bb [i]->last_ins && bb->in_bb [i]->last_ins->opcode == OP_SWITCH) {
2581 MonoInst *switch_ins = bb->in_bb [i]->last_ins;
2584 for (j = 0; j < GPOINTER_TO_UINT (switch_ins->klass); ++j) {
2585 if (switch_ins->inst_many_bb [j] == bb)
2592 /* Remember for later */
2593 for (j = 0; j < count; ++j) {
2594 PhiNode *node = mono_mempool_alloc0 (ctx->mempool, sizeof (PhiNode));
2597 node->in_bb = bb->in_bb [i];
2599 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);
2609 values [ins->dreg] = lhs;
2612 MonoInst *var = get_vreg_to_inst (cfg, ins->dreg);
2615 values [ins->dreg] = lhs;
2617 if (var && var->klass->byval_arg.type == MONO_TYPE_R4) {
2619 * This is added by the spilling pass in case of the JIT,
2620 * but we have to do it ourselves.
2622 values [ins->dreg] = convert (ctx, values [ins->dreg], LLVMFloatType ());
2656 lhs = convert (ctx, lhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
2657 rhs = convert (ctx, rhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
2659 switch (ins->opcode) {
2662 values [ins->dreg] = LLVMBuildAdd (builder, lhs, rhs, dname);
2666 values [ins->dreg] = LLVMBuildSub (builder, lhs, rhs, dname);
2670 values [ins->dreg] = LLVMBuildMul (builder, lhs, rhs, dname);
2674 values [ins->dreg] = LLVMBuildSRem (builder, lhs, rhs, dname);
2678 values [ins->dreg] = LLVMBuildURem (builder, lhs, rhs, dname);
2682 values [ins->dreg] = LLVMBuildSDiv (builder, lhs, rhs, dname);
2686 values [ins->dreg] = LLVMBuildUDiv (builder, lhs, rhs, dname);
2689 values [ins->dreg] = LLVMBuildFDiv (builder, lhs, rhs, dname);
2693 values [ins->dreg] = LLVMBuildAnd (builder, lhs, rhs, dname);
2697 values [ins->dreg] = LLVMBuildOr (builder, lhs, rhs, dname);
2701 values [ins->dreg] = LLVMBuildXor (builder, lhs, rhs, dname);
2705 values [ins->dreg] = LLVMBuildShl (builder, lhs, rhs, dname);
2709 values [ins->dreg] = LLVMBuildAShr (builder, lhs, rhs, dname);
2713 values [ins->dreg] = LLVMBuildLShr (builder, lhs, rhs, dname);
2717 values [ins->dreg] = LLVMBuildFAdd (builder, lhs, rhs, dname);
2720 values [ins->dreg] = LLVMBuildFSub (builder, lhs, rhs, dname);
2723 values [ins->dreg] = LLVMBuildFMul (builder, lhs, rhs, dname);
2727 g_assert_not_reached ();
2734 case OP_IREM_UN_IMM:
2736 case OP_IDIV_UN_IMM:
2742 case OP_ISHR_UN_IMM:
2751 case OP_LSHR_UN_IMM:
2757 case OP_SHR_UN_IMM: {
2760 if (spec [MONO_INST_SRC1] == 'l') {
2761 imm = LLVMConstInt (LLVMInt64Type (), GET_LONG_IMM (ins), FALSE);
2763 imm = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
2766 #if SIZEOF_VOID_P == 4
2767 if (ins->opcode == OP_LSHL_IMM || ins->opcode == OP_LSHR_IMM || ins->opcode == OP_LSHR_UN_IMM)
2768 imm = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
2771 if (LLVMGetTypeKind (LLVMTypeOf (lhs)) == LLVMPointerTypeKind)
2772 lhs = convert (ctx, lhs, IntPtrType ());
2773 imm = convert (ctx, imm, LLVMTypeOf (lhs));
2774 switch (ins->opcode) {
2778 values [ins->dreg] = LLVMBuildAdd (builder, lhs, imm, dname);
2782 values [ins->dreg] = LLVMBuildSub (builder, lhs, imm, dname);
2786 values [ins->dreg] = LLVMBuildMul (builder, lhs, imm, dname);
2790 values [ins->dreg] = LLVMBuildSDiv (builder, lhs, imm, dname);
2792 case OP_IDIV_UN_IMM:
2793 case OP_LDIV_UN_IMM:
2794 values [ins->dreg] = LLVMBuildUDiv (builder, lhs, imm, dname);
2798 values [ins->dreg] = LLVMBuildSRem (builder, lhs, imm, dname);
2800 case OP_IREM_UN_IMM:
2801 values [ins->dreg] = LLVMBuildURem (builder, lhs, imm, dname);
2806 values [ins->dreg] = LLVMBuildAnd (builder, lhs, imm, dname);
2810 values [ins->dreg] = LLVMBuildOr (builder, lhs, imm, dname);
2814 values [ins->dreg] = LLVMBuildXor (builder, lhs, imm, dname);
2819 values [ins->dreg] = LLVMBuildShl (builder, lhs, imm, dname);
2824 values [ins->dreg] = LLVMBuildAShr (builder, lhs, imm, dname);
2826 case OP_ISHR_UN_IMM:
2827 /* This is used to implement conv.u4, so the lhs could be an i8 */
2828 lhs = convert (ctx, lhs, LLVMInt32Type ());
2829 imm = convert (ctx, imm, LLVMInt32Type ());
2830 values [ins->dreg] = LLVMBuildLShr (builder, lhs, imm, dname);
2832 case OP_LSHR_UN_IMM:
2834 values [ins->dreg] = LLVMBuildLShr (builder, lhs, imm, dname);
2837 g_assert_not_reached ();
2842 values [ins->dreg] = LLVMBuildSub (builder, LLVMConstInt (LLVMInt32Type (), 0, FALSE), convert (ctx, lhs, LLVMInt32Type ()), dname);
2845 values [ins->dreg] = LLVMBuildSub (builder, LLVMConstInt (LLVMInt64Type (), 0, FALSE), lhs, dname);
2848 lhs = convert (ctx, lhs, LLVMDoubleType ());
2849 values [ins->dreg] = LLVMBuildFSub (builder, LLVMConstReal (LLVMDoubleType (), 0.0), lhs, dname);
2852 guint32 v = 0xffffffff;
2853 values [ins->dreg] = LLVMBuildXor (builder, LLVMConstInt (LLVMInt32Type (), v, FALSE), convert (ctx, lhs, LLVMInt32Type ()), dname);
2857 guint64 v = 0xffffffffffffffffLL;
2858 values [ins->dreg] = LLVMBuildXor (builder, LLVMConstInt (LLVMInt64Type (), v, FALSE), lhs, dname);
2861 #if defined(TARGET_X86) || defined(TARGET_AMD64)
2863 LLVMValueRef v1, v2;
2865 v1 = LLVMBuildMul (builder, convert (ctx, rhs, IntPtrType ()), LLVMConstInt (IntPtrType (), (1 << ins->backend.shift_amount), FALSE), "");
2866 v2 = LLVMBuildAdd (builder, convert (ctx, lhs, IntPtrType ()), v1, "");
2867 values [ins->dreg] = LLVMBuildAdd (builder, v2, LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE), dname);
2872 case OP_ICONV_TO_I1:
2873 case OP_ICONV_TO_I2:
2874 case OP_ICONV_TO_I4:
2875 case OP_ICONV_TO_U1:
2876 case OP_ICONV_TO_U2:
2877 case OP_ICONV_TO_U4:
2878 case OP_LCONV_TO_I1:
2879 case OP_LCONV_TO_I2:
2880 case OP_LCONV_TO_U1:
2881 case OP_LCONV_TO_U2:
2882 case OP_LCONV_TO_U4: {
2885 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);
2887 /* Have to do two casts since our vregs have type int */
2888 v = LLVMBuildTrunc (builder, lhs, op_to_llvm_type (ins->opcode), "");
2890 values [ins->dreg] = LLVMBuildSExt (builder, v, LLVMInt32Type (), dname);
2892 values [ins->dreg] = LLVMBuildZExt (builder, v, LLVMInt32Type (), dname);
2895 case OP_ICONV_TO_I8:
2896 values [ins->dreg] = LLVMBuildSExt (builder, lhs, LLVMInt64Type (), dname);
2898 case OP_ICONV_TO_U8:
2899 values [ins->dreg] = LLVMBuildZExt (builder, lhs, LLVMInt64Type (), dname);
2901 case OP_FCONV_TO_I4:
2902 values [ins->dreg] = LLVMBuildFPToSI (builder, lhs, LLVMInt32Type (), dname);
2904 case OP_FCONV_TO_I1:
2905 values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildFPToSI (builder, lhs, LLVMInt8Type (), dname), LLVMInt32Type (), "");
2907 case OP_FCONV_TO_U1:
2908 values [ins->dreg] = LLVMBuildZExt (builder, LLVMBuildFPToUI (builder, lhs, LLVMInt8Type (), dname), LLVMInt32Type (), "");
2910 case OP_FCONV_TO_I2:
2911 values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildFPToSI (builder, lhs, LLVMInt16Type (), dname), LLVMInt32Type (), "");
2913 case OP_FCONV_TO_U2:
2914 values [ins->dreg] = LLVMBuildZExt (builder, LLVMBuildFPToUI (builder, lhs, LLVMInt16Type (), dname), LLVMInt32Type (), "");
2916 case OP_FCONV_TO_I8:
2917 values [ins->dreg] = LLVMBuildFPToSI (builder, lhs, LLVMInt64Type (), dname);
2920 values [ins->dreg] = LLVMBuildFPToSI (builder, lhs, IntPtrType (), dname);
2922 case OP_ICONV_TO_R8:
2923 case OP_LCONV_TO_R8:
2924 values [ins->dreg] = LLVMBuildSIToFP (builder, lhs, LLVMDoubleType (), dname);
2926 case OP_LCONV_TO_R_UN:
2927 values [ins->dreg] = LLVMBuildUIToFP (builder, lhs, LLVMDoubleType (), dname);
2929 #if SIZEOF_VOID_P == 4
2932 case OP_LCONV_TO_I4:
2933 values [ins->dreg] = LLVMBuildTrunc (builder, lhs, LLVMInt32Type (), dname);
2935 case OP_ICONV_TO_R4:
2936 case OP_LCONV_TO_R4:
2937 v = LLVMBuildSIToFP (builder, lhs, LLVMFloatType (), "");
2938 values [ins->dreg] = LLVMBuildFPExt (builder, v, LLVMDoubleType (), dname);
2940 case OP_FCONV_TO_R4:
2941 v = LLVMBuildFPTrunc (builder, lhs, LLVMFloatType (), "");
2942 values [ins->dreg] = LLVMBuildFPExt (builder, v, LLVMDoubleType (), dname);
2945 values [ins->dreg] = LLVMBuildSExt (builder, convert (ctx, lhs, LLVMInt32Type ()), LLVMInt64Type (), dname);
2948 values [ins->dreg] = LLVMBuildZExt (builder, convert (ctx, lhs, LLVMInt32Type ()), LLVMInt64Type (), dname);
2951 values [ins->dreg] = LLVMBuildTrunc (builder, lhs, LLVMInt32Type (), dname);
2953 case OP_LOCALLOC_IMM: {
2956 guint32 size = ins->inst_imm;
2957 size = (size + (MONO_ARCH_FRAME_ALIGNMENT - 1)) & ~ (MONO_ARCH_FRAME_ALIGNMENT - 1);
2959 v = mono_llvm_build_alloca (builder, LLVMInt8Type (), LLVMConstInt (LLVMInt32Type (), size, FALSE), MONO_ARCH_FRAME_ALIGNMENT, "");
2961 if (ins->flags & MONO_INST_INIT) {
2962 LLVMValueRef args [5];
2965 args [1] = LLVMConstInt (LLVMInt8Type (), 0, FALSE);
2966 args [2] = LLVMConstInt (LLVMInt32Type (), size, FALSE);
2967 args [3] = LLVMConstInt (LLVMInt32Type (), MONO_ARCH_FRAME_ALIGNMENT, FALSE);
2968 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
2969 LLVMBuildCall (builder, LLVMGetNamedFunction (module, memset_func_name), args, memset_param_count, "");
2972 values [ins->dreg] = v;
2976 LLVMValueRef v, size;
2978 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), "");
2980 v = mono_llvm_build_alloca (builder, LLVMInt8Type (), size, MONO_ARCH_FRAME_ALIGNMENT, "");
2982 if (ins->flags & MONO_INST_INIT) {
2983 LLVMValueRef args [5];
2986 args [1] = LLVMConstInt (LLVMInt8Type (), 0, FALSE);
2988 args [3] = LLVMConstInt (LLVMInt32Type (), MONO_ARCH_FRAME_ALIGNMENT, FALSE);
2989 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
2990 LLVMBuildCall (builder, LLVMGetNamedFunction (module, memset_func_name), args, memset_param_count, "");
2992 values [ins->dreg] = v;
2996 case OP_LOADI1_MEMBASE:
2997 case OP_LOADU1_MEMBASE:
2998 case OP_LOADI2_MEMBASE:
2999 case OP_LOADU2_MEMBASE:
3000 case OP_LOADI4_MEMBASE:
3001 case OP_LOADU4_MEMBASE:
3002 case OP_LOADI8_MEMBASE:
3003 case OP_LOADR4_MEMBASE:
3004 case OP_LOADR8_MEMBASE:
3005 case OP_LOAD_MEMBASE:
3013 LLVMValueRef base, index, addr;
3015 gboolean sext = FALSE, zext = FALSE;
3016 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
3018 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
3023 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)) {
3024 addr = LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE);
3029 if (ins->inst_offset == 0) {
3031 } else if (ins->inst_offset % size != 0) {
3032 /* Unaligned load */
3033 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset, FALSE);
3034 addr = LLVMBuildGEP (builder, convert (ctx, base, LLVMPointerType (LLVMInt8Type (), 0)), &index, 1, "");
3036 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
3037 addr = LLVMBuildGEP (builder, convert (ctx, base, LLVMPointerType (t, 0)), &index, 1, "");
3041 addr = convert (ctx, addr, LLVMPointerType (t, 0));
3043 values [ins->dreg] = emit_load (ctx, bb, &builder, size, addr, dname, is_volatile);
3045 if (!is_volatile && (ins->flags & MONO_INST_INVARIANT_LOAD)) {
3047 * These will signal LLVM that these loads do not alias any stores, and
3048 * they can't fail, allowing them to be hoisted out of loops.
3050 set_invariant_load_flag (values [ins->dreg]);
3051 set_metadata_flag (values [ins->dreg], "mono.nofail.load");
3055 values [ins->dreg] = LLVMBuildSExt (builder, values [ins->dreg], LLVMInt32Type (), dname);
3057 values [ins->dreg] = LLVMBuildZExt (builder, values [ins->dreg], LLVMInt32Type (), dname);
3058 else if (ins->opcode == OP_LOADR4_MEMBASE)
3059 values [ins->dreg] = LLVMBuildFPExt (builder, values [ins->dreg], LLVMDoubleType (), dname);
3063 case OP_STOREI1_MEMBASE_REG:
3064 case OP_STOREI2_MEMBASE_REG:
3065 case OP_STOREI4_MEMBASE_REG:
3066 case OP_STOREI8_MEMBASE_REG:
3067 case OP_STORER4_MEMBASE_REG:
3068 case OP_STORER8_MEMBASE_REG:
3069 case OP_STORE_MEMBASE_REG: {
3071 LLVMValueRef index, addr;
3073 gboolean sext = FALSE, zext = FALSE;
3074 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
3076 if (!values [ins->inst_destbasereg])
3077 LLVM_FAILURE (ctx, "inst_destbasereg");
3079 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
3081 if (ins->inst_offset % size != 0) {
3082 /* Unaligned store */
3083 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset, FALSE);
3084 addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (LLVMInt8Type (), 0)), &index, 1, "");
3086 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
3087 addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (t, 0)), &index, 1, "");
3089 emit_store (ctx, bb, &builder, size, convert (ctx, values [ins->sreg1], t), convert (ctx, addr, LLVMPointerType (t, 0)), is_volatile);
3093 case OP_STOREI1_MEMBASE_IMM:
3094 case OP_STOREI2_MEMBASE_IMM:
3095 case OP_STOREI4_MEMBASE_IMM:
3096 case OP_STOREI8_MEMBASE_IMM:
3097 case OP_STORE_MEMBASE_IMM: {
3099 LLVMValueRef index, addr;
3101 gboolean sext = FALSE, zext = FALSE;
3102 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
3104 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
3106 if (ins->inst_offset % size != 0) {
3107 /* Unaligned store */
3108 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset, FALSE);
3109 addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (LLVMInt8Type (), 0)), &index, 1, "");
3111 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
3112 addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (t, 0)), &index, 1, "");
3114 emit_store (ctx, bb, &builder, size, convert (ctx, LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE), t), addr, is_volatile);
3119 emit_load (ctx, bb, &builder, sizeof (gpointer), convert (ctx, lhs, LLVMPointerType (IntPtrType (), 0)), "", TRUE);
3121 case OP_OUTARG_VTRETADDR:
3128 case OP_VOIDCALL_MEMBASE:
3129 case OP_CALL_MEMBASE:
3130 case OP_LCALL_MEMBASE:
3131 case OP_FCALL_MEMBASE:
3132 case OP_VCALL_MEMBASE:
3133 case OP_VOIDCALL_REG:
3137 case OP_VCALL_REG: {
3138 process_call (ctx, bb, &builder, ins);
3139 CHECK_FAILURE (ctx);
3144 LLVMValueRef indexes [2];
3146 LLVMValueRef got_entry_addr;
3149 * FIXME: Can't allocate from the cfg mempool since that is freed if
3150 * the LLVM compile fails.
3152 ji = g_new0 (MonoJumpInfo, 1);
3153 ji->type = (MonoJumpInfoType)ins->inst_i1;
3154 ji->data.target = ins->inst_p0;
3156 ji = mono_aot_patch_info_dup (ji);
3158 ji->next = cfg->patch_info;
3159 cfg->patch_info = ji;
3161 //mono_add_patch_info (cfg, 0, (MonoJumpInfoType)ins->inst_i1, ins->inst_p0);
3162 got_offset = mono_aot_get_got_offset (cfg->patch_info);
3164 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
3165 indexes [1] = LLVMConstInt (LLVMInt32Type (), (gssize)got_offset, FALSE);
3166 got_entry_addr = LLVMBuildGEP (builder, ctx->lmodule->got_var, indexes, 2, "");
3168 values [ins->dreg] = LLVMBuildLoad (builder, got_entry_addr, dname);
3169 set_invariant_load_flag (values [ins->dreg]);
3172 case OP_NOT_REACHED:
3173 LLVMBuildUnreachable (builder);
3174 has_terminator = TRUE;
3175 g_assert (bb->block_num < cfg->max_block_num);
3176 ctx->unreachable [bb->block_num] = TRUE;
3177 /* Might have instructions after this */
3179 MonoInst *next = ins->next;
3181 * FIXME: If later code uses the regs defined by these instructions,
3182 * compilation will fail.
3184 MONO_DELETE_INS (bb, next);
3188 MonoInst *var = ins->inst_p0;
3190 values [ins->dreg] = addresses [var->dreg];
3194 LLVMValueRef args [1];
3196 args [0] = convert (ctx, lhs, LLVMDoubleType ());
3197 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, "llvm.sin.f64"), args, 1, dname);
3201 LLVMValueRef args [1];
3203 args [0] = convert (ctx, lhs, LLVMDoubleType ());
3204 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, "llvm.cos.f64"), args, 1, dname);
3208 LLVMValueRef args [1];
3211 /* This no longer seems to happen */
3213 * LLVM optimizes sqrt(nan) into undefined in
3214 * lib/Analysis/ConstantFolding.cpp
3215 * Also, sqrt(NegativeInfinity) is optimized into 0.
3217 LLVM_FAILURE (ctx, "sqrt");
3219 args [0] = convert (ctx, lhs, LLVMDoubleType ());
3220 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, "llvm.sqrt.f64"), args, 1, dname);
3224 LLVMValueRef args [1];
3226 args [0] = convert (ctx, lhs, LLVMDoubleType ());
3227 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, "fabs"), args, 1, dname);
3241 lhs = convert (ctx, lhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
3242 rhs = convert (ctx, rhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
3244 switch (ins->opcode) {
3247 v = LLVMBuildICmp (builder, LLVMIntSLE, lhs, rhs, "");
3251 v = LLVMBuildICmp (builder, LLVMIntSGE, lhs, rhs, "");
3255 v = LLVMBuildICmp (builder, LLVMIntULE, lhs, rhs, "");
3259 v = LLVMBuildICmp (builder, LLVMIntUGE, lhs, rhs, "");
3262 g_assert_not_reached ();
3265 values [ins->dreg] = LLVMBuildSelect (builder, v, lhs, rhs, dname);
3268 case OP_ATOMIC_EXCHANGE_I4:
3269 case OP_ATOMIC_EXCHANGE_I8: {
3270 LLVMValueRef args [2];
3273 if (ins->opcode == OP_ATOMIC_EXCHANGE_I4)
3274 t = LLVMInt32Type ();
3276 t = LLVMInt64Type ();
3278 g_assert (ins->inst_offset == 0);
3280 args [0] = convert (ctx, lhs, LLVMPointerType (t, 0));
3281 args [1] = convert (ctx, rhs, t);
3283 values [ins->dreg] = mono_llvm_build_atomic_rmw (builder, LLVM_ATOMICRMW_OP_XCHG, args [0], args [1]);
3286 case OP_ATOMIC_ADD_NEW_I4:
3287 case OP_ATOMIC_ADD_NEW_I8: {
3288 LLVMValueRef args [2];
3291 if (ins->opcode == OP_ATOMIC_ADD_NEW_I4)
3292 t = LLVMInt32Type ();
3294 t = LLVMInt64Type ();
3296 g_assert (ins->inst_offset == 0);
3298 args [0] = convert (ctx, lhs, LLVMPointerType (t, 0));
3299 args [1] = convert (ctx, rhs, t);
3300 values [ins->dreg] = LLVMBuildAdd (builder, mono_llvm_build_atomic_rmw (builder, LLVM_ATOMICRMW_OP_ADD, args [0], args [1]), args [1], dname);
3303 case OP_ATOMIC_CAS_I4:
3304 case OP_ATOMIC_CAS_I8: {
3305 LLVMValueRef args [3];
3308 if (ins->opcode == OP_ATOMIC_CAS_I4)
3309 t = LLVMInt32Type ();
3311 t = LLVMInt64Type ();
3313 args [0] = convert (ctx, lhs, LLVMPointerType (t, 0));
3315 args [1] = convert (ctx, values [ins->sreg3], t);
3317 args [2] = convert (ctx, values [ins->sreg2], t);
3318 values [ins->dreg] = mono_llvm_build_cmpxchg (builder, args [0], args [1], args [2]);
3321 case OP_MEMORY_BARRIER: {
3322 mono_llvm_build_fence (builder);
3325 case OP_RELAXED_NOP: {
3326 #if defined(TARGET_AMD64) || defined(TARGET_X86)
3327 emit_call (ctx, bb, &builder, LLVMGetNamedFunction (ctx->module, "llvm.x86.sse2.pause"), NULL, 0);
3334 #if (defined(TARGET_AMD64) || defined(TARGET_X86)) && defined(__linux__)
3336 // 257 == FS segment register
3337 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 257);
3339 // 256 == GS segment register
3340 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 256);
3343 values [ins->dreg] = LLVMBuildLoad (builder, LLVMBuildIntToPtr (builder, LLVMConstInt (IntPtrType (), ins->inst_offset, TRUE), ptrtype, ""), "");
3344 #elif defined(TARGET_AMD64) && defined(TARGET_OSX)
3345 /* See mono_amd64_emit_tls_get () */
3346 int offset = mono_amd64_get_tls_gs_offset () + (ins->inst_offset * 8);
3348 // 256 == GS segment register
3349 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 256);
3350 values [ins->dreg] = LLVMBuildLoad (builder, LLVMBuildIntToPtr (builder, LLVMConstInt (IntPtrType (), offset, TRUE), ptrtype, ""), "");
3352 LLVM_FAILURE (ctx, "opcode tls-get");
3357 case OP_TLS_GET_REG: {
3358 #if defined(TARGET_AMD64) && defined(TARGET_OSX)
3359 /* See emit_tls_get_reg () */
3360 // 256 == GS segment register
3361 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 256);
3362 values [ins->dreg] = LLVMBuildLoad (builder, LLVMBuildIntToPtr (builder, convert (ctx, lhs, LLVMInt32Type ()), ptrtype, ""), "");
3364 LLVM_FAILURE (ctx, "opcode tls-get");
3373 case OP_IADD_OVF_UN:
3375 case OP_ISUB_OVF_UN:
3377 case OP_IMUL_OVF_UN:
3378 #if SIZEOF_VOID_P == 8
3380 case OP_LADD_OVF_UN:
3382 case OP_LSUB_OVF_UN:
3384 case OP_LMUL_OVF_UN:
3387 LLVMValueRef args [2], val, ovf, func;
3389 args [0] = convert (ctx, lhs, op_to_llvm_type (ins->opcode));
3390 args [1] = convert (ctx, rhs, op_to_llvm_type (ins->opcode));
3391 func = LLVMGetNamedFunction (module, ovf_op_to_intrins (ins->opcode));
3393 val = LLVMBuildCall (builder, func, args, 2, "");
3394 values [ins->dreg] = LLVMBuildExtractValue (builder, val, 0, dname);
3395 ovf = LLVMBuildExtractValue (builder, val, 1, "");
3396 emit_cond_system_exception (ctx, bb, "OverflowException", ovf);
3397 CHECK_FAILURE (ctx);
3398 builder = ctx->builder;
3404 * We currently model them using arrays. Promotion to local vregs is
3405 * disabled for them in mono_handle_global_vregs () in the LLVM case,
3406 * so we always have an entry in cfg->varinfo for them.
3407 * FIXME: Is this needed ?
3410 MonoClass *klass = ins->klass;
3411 LLVMValueRef args [5];
3415 LLVM_FAILURE (ctx, "!klass");
3419 if (!addresses [ins->dreg])
3420 addresses [ins->dreg] = build_alloca (ctx, &klass->byval_arg);
3421 args [0] = LLVMBuildBitCast (builder, addresses [ins->dreg], LLVMPointerType (LLVMInt8Type (), 0), "");
3422 args [1] = LLVMConstInt (LLVMInt8Type (), 0, FALSE);
3423 args [2] = LLVMConstInt (LLVMInt32Type (), mono_class_value_size (klass, NULL), FALSE);
3425 args [3] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
3426 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
3427 LLVMBuildCall (builder, LLVMGetNamedFunction (module, memset_func_name), args, memset_param_count, "");
3431 case OP_STOREV_MEMBASE:
3432 case OP_LOADV_MEMBASE:
3434 MonoClass *klass = ins->klass;
3435 LLVMValueRef src = NULL, dst, args [5];
3436 gboolean done = FALSE;
3440 LLVM_FAILURE (ctx, "!klass");
3444 if (mini_is_gsharedvt_klass (cfg, klass)) {
3446 LLVM_FAILURE (ctx, "gsharedvt");
3450 switch (ins->opcode) {
3451 case OP_STOREV_MEMBASE:
3452 if (cfg->gen_write_barriers && klass->has_references && ins->inst_destbasereg != cfg->frame_reg &&
3453 LLVMGetInstructionOpcode (values [ins->inst_destbasereg]) != LLVMAlloca) {
3454 /* Decomposed earlier */
3455 g_assert_not_reached ();
3458 if (!addresses [ins->sreg1]) {
3460 g_assert (values [ins->sreg1]);
3461 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));
3462 LLVMBuildStore (builder, values [ins->sreg1], dst);
3465 src = LLVMBuildBitCast (builder, addresses [ins->sreg1], LLVMPointerType (LLVMInt8Type (), 0), "");
3466 dst = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_destbasereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (LLVMInt8Type (), 0));
3469 case OP_LOADV_MEMBASE:
3470 if (!addresses [ins->dreg])
3471 addresses [ins->dreg] = build_alloca (ctx, &klass->byval_arg);
3472 src = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_basereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (LLVMInt8Type (), 0));
3473 dst = LLVMBuildBitCast (builder, addresses [ins->dreg], LLVMPointerType (LLVMInt8Type (), 0), "");
3476 if (!addresses [ins->sreg1])
3477 addresses [ins->sreg1] = build_alloca (ctx, &klass->byval_arg);
3478 if (!addresses [ins->dreg])
3479 addresses [ins->dreg] = build_alloca (ctx, &klass->byval_arg);
3480 src = LLVMBuildBitCast (builder, addresses [ins->sreg1], LLVMPointerType (LLVMInt8Type (), 0), "");
3481 dst = LLVMBuildBitCast (builder, addresses [ins->dreg], LLVMPointerType (LLVMInt8Type (), 0), "");
3484 g_assert_not_reached ();
3486 CHECK_FAILURE (ctx);
3493 args [2] = LLVMConstInt (LLVMInt32Type (), mono_class_value_size (klass, NULL), FALSE);
3494 args [3] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
3496 args [3] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
3497 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
3498 LLVMBuildCall (builder, LLVMGetNamedFunction (module, memcpy_func_name), args, memcpy_param_count, "");
3501 case OP_LLVM_OUTARG_VT:
3502 if (!addresses [ins->sreg1]) {
3503 addresses [ins->sreg1] = build_alloca (ctx, &ins->klass->byval_arg);
3504 g_assert (values [ins->sreg1]);
3505 LLVMBuildStore (builder, values [ins->sreg1], addresses [ins->sreg1]);
3507 addresses [ins->dreg] = addresses [ins->sreg1];
3513 #if defined(TARGET_X86) || defined(TARGET_AMD64)
3515 values [ins->dreg] = LLVMConstNull (type_to_llvm_type (ctx, &ins->klass->byval_arg));
3518 case OP_LOADX_MEMBASE: {
3519 LLVMTypeRef t = type_to_llvm_type (ctx, &ins->klass->byval_arg);
3522 src = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_basereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (t, 0));
3523 values [ins->dreg] = mono_llvm_build_aligned_load (builder, src, "", FALSE, 1);
3526 case OP_STOREX_MEMBASE: {
3527 LLVMTypeRef t = LLVMTypeOf (values [ins->sreg1]);
3530 dest = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_destbasereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (t, 0));
3531 mono_llvm_build_aligned_store (builder, values [ins->sreg1], dest, FALSE, 1);
3538 values [ins->dreg] = LLVMBuildAdd (builder, lhs, rhs, "");
3542 values [ins->dreg] = LLVMBuildFAdd (builder, lhs, rhs, "");
3548 values [ins->dreg] = LLVMBuildSub (builder, lhs, rhs, "");
3552 values [ins->dreg] = LLVMBuildFSub (builder, lhs, rhs, "");
3556 values [ins->dreg] = LLVMBuildFMul (builder, lhs, rhs, "");
3560 values [ins->dreg] = LLVMBuildFDiv (builder, lhs, rhs, "");
3563 values [ins->dreg] = LLVMBuildAnd (builder, lhs, rhs, "");
3566 values [ins->dreg] = LLVMBuildOr (builder, lhs, rhs, "");
3569 values [ins->dreg] = LLVMBuildXor (builder, lhs, rhs, "");
3573 values [ins->dreg] = LLVMBuildMul (builder, lhs, rhs, "");
3584 LLVMValueRef v = NULL;
3586 switch (ins->opcode) {
3591 t = LLVMVectorType (LLVMInt32Type (), 4);
3592 rt = LLVMVectorType (LLVMFloatType (), 4);
3598 t = LLVMVectorType (LLVMInt64Type (), 2);
3599 rt = LLVMVectorType (LLVMDoubleType (), 2);
3602 t = LLVMInt32Type ();
3603 rt = LLVMInt32Type ();
3604 g_assert_not_reached ();
3607 lhs = LLVMBuildBitCast (builder, lhs, t, "");
3608 rhs = LLVMBuildBitCast (builder, rhs, t, "");
3609 switch (ins->opcode) {
3612 v = LLVMBuildAnd (builder, lhs, rhs, "");
3616 v = LLVMBuildOr (builder, lhs, rhs, "");
3620 v = LLVMBuildXor (builder, lhs, rhs, "");
3624 v = LLVMBuildAnd (builder, rhs, LLVMBuildNot (builder, lhs, ""), "");
3627 values [ins->dreg] = LLVMBuildBitCast (builder, v, rt, "");
3651 case OP_PADDB_SAT_UN:
3652 case OP_PADDW_SAT_UN:
3653 case OP_PSUBB_SAT_UN:
3654 case OP_PSUBW_SAT_UN:
3662 case OP_PMULW_HIGH_UN: {
3663 LLVMValueRef args [2];
3668 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, simd_op_to_intrins (ins->opcode)), args, 2, dname);
3675 values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildICmp (builder, LLVMIntEQ, lhs, rhs, ""), LLVMTypeOf (lhs), "");
3679 values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildICmp (builder, LLVMIntSGT, lhs, rhs, ""), LLVMTypeOf (lhs), "");
3687 case OP_EXTRACTX_U2:
3689 case OP_EXTRACT_U1: {
3691 gboolean zext = FALSE;
3693 t = simd_op_to_llvm_type (ins->opcode);
3695 switch (ins->opcode) {
3703 case OP_EXTRACTX_U2:
3708 t = LLVMInt32Type ();
3709 g_assert_not_reached ();
3712 lhs = LLVMBuildBitCast (builder, lhs, t, "");
3713 values [ins->dreg] = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), "");
3715 values [ins->dreg] = LLVMBuildZExt (builder, values [ins->dreg], LLVMInt32Type (), "");
3724 case OP_EXPAND_R8: {
3725 LLVMTypeRef t = simd_op_to_llvm_type (ins->opcode);
3726 LLVMValueRef mask [16], v;
3728 for (i = 0; i < 16; ++i)
3729 mask [i] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
3731 v = convert (ctx, values [ins->sreg1], LLVMGetElementType (t));
3733 values [ins->dreg] = LLVMBuildInsertElement (builder, LLVMConstNull (t), v, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
3734 values [ins->dreg] = LLVMBuildShuffleVector (builder, values [ins->dreg], LLVMGetUndef (t), LLVMConstVector (mask, LLVMGetVectorSize (t)), "");
3739 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt8Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
3742 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt16Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
3745 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt32Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
3748 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt64Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
3751 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMFloatType ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
3754 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMDoubleType ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
3765 case OP_EXTRACT_MASK:
3772 v = convert (ctx, values [ins->sreg1], simd_op_to_llvm_type (ins->opcode));
3774 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, simd_op_to_intrins (ins->opcode)), &v, 1, dname);
3778 case OP_ICONV_TO_R8_RAW:
3779 /* Same as OP_ICONV_TO_R8 */
3780 values [ins->dreg] = convert (ctx, LLVMBuildBitCast (builder, lhs, LLVMFloatType (), ""), LLVMDoubleType ());
3785 LLVMValueRef args [3];
3789 args [2] = LLVMConstInt (LLVMInt8Type (), ins->inst_c0, FALSE);
3791 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, simd_op_to_intrins (ins->opcode)), args, 3, dname);
3796 /* This is only used for implementing shifts by non-immediate */
3797 values [ins->dreg] = lhs;
3808 LLVMValueRef args [3];
3811 args [1] = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
3813 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, simd_op_to_intrins (ins->opcode)), args, 2, dname);
3824 case OP_PSHLQ_REG: {
3825 LLVMValueRef args [3];
3828 args [1] = values [ins->sreg2];
3830 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, simd_op_to_intrins (ins->opcode)), args, 2, dname);
3837 case OP_PSHUFLEW_LOW:
3838 case OP_PSHUFLEW_HIGH: {
3840 LLVMValueRef v1 = NULL, v2 = NULL, mask_values [16];
3841 int i, mask_size = 0;
3842 int imask = ins->inst_c0;
3844 /* Convert the x86 shuffle mask to LLVM's */
3845 switch (ins->opcode) {
3848 mask [0] = ((imask >> 0) & 3);
3849 mask [1] = ((imask >> 2) & 3);
3850 mask [2] = ((imask >> 4) & 3) + 4;
3851 mask [3] = ((imask >> 6) & 3) + 4;
3852 v1 = values [ins->sreg1];
3853 v2 = values [ins->sreg2];
3857 mask [0] = ((imask >> 0) & 1);
3858 mask [1] = ((imask >> 1) & 1) + 2;
3859 v1 = values [ins->sreg1];
3860 v2 = values [ins->sreg2];
3862 case OP_PSHUFLEW_LOW:
3864 mask [0] = ((imask >> 0) & 3);
3865 mask [1] = ((imask >> 2) & 3);
3866 mask [2] = ((imask >> 4) & 3);
3867 mask [3] = ((imask >> 6) & 3);
3872 v1 = values [ins->sreg1];
3873 v2 = LLVMGetUndef (LLVMTypeOf (v1));
3875 case OP_PSHUFLEW_HIGH:
3881 mask [4] = 4 + ((imask >> 0) & 3);
3882 mask [5] = 4 + ((imask >> 2) & 3);
3883 mask [6] = 4 + ((imask >> 4) & 3);
3884 mask [7] = 4 + ((imask >> 6) & 3);
3885 v1 = values [ins->sreg1];
3886 v2 = LLVMGetUndef (LLVMTypeOf (v1));
3890 mask [0] = ((imask >> 0) & 3);
3891 mask [1] = ((imask >> 2) & 3);
3892 mask [2] = ((imask >> 4) & 3);
3893 mask [3] = ((imask >> 6) & 3);
3894 v1 = values [ins->sreg1];
3895 v2 = LLVMGetUndef (LLVMTypeOf (v1));
3898 g_assert_not_reached ();
3900 for (i = 0; i < mask_size; ++i)
3901 mask_values [i] = LLVMConstInt (LLVMInt32Type (), mask [i], FALSE);
3903 values [ins->dreg] =
3904 LLVMBuildShuffleVector (builder, v1, v2,
3905 LLVMConstVector (mask_values, mask_size), dname);
3909 case OP_UNPACK_LOWB:
3910 case OP_UNPACK_LOWW:
3911 case OP_UNPACK_LOWD:
3912 case OP_UNPACK_LOWQ:
3913 case OP_UNPACK_LOWPS:
3914 case OP_UNPACK_LOWPD:
3915 case OP_UNPACK_HIGHB:
3916 case OP_UNPACK_HIGHW:
3917 case OP_UNPACK_HIGHD:
3918 case OP_UNPACK_HIGHQ:
3919 case OP_UNPACK_HIGHPS:
3920 case OP_UNPACK_HIGHPD: {
3922 LLVMValueRef mask_values [16];
3923 int i, mask_size = 0;
3924 gboolean low = FALSE;
3926 switch (ins->opcode) {
3927 case OP_UNPACK_LOWB:
3931 case OP_UNPACK_LOWW:
3935 case OP_UNPACK_LOWD:
3936 case OP_UNPACK_LOWPS:
3940 case OP_UNPACK_LOWQ:
3941 case OP_UNPACK_LOWPD:
3945 case OP_UNPACK_HIGHB:
3948 case OP_UNPACK_HIGHW:
3951 case OP_UNPACK_HIGHD:
3952 case OP_UNPACK_HIGHPS:
3955 case OP_UNPACK_HIGHQ:
3956 case OP_UNPACK_HIGHPD:
3960 g_assert_not_reached ();
3964 for (i = 0; i < (mask_size / 2); ++i) {
3966 mask [(i * 2) + 1] = mask_size + i;
3969 for (i = 0; i < (mask_size / 2); ++i) {
3970 mask [(i * 2)] = (mask_size / 2) + i;
3971 mask [(i * 2) + 1] = mask_size + (mask_size / 2) + i;
3975 for (i = 0; i < mask_size; ++i)
3976 mask_values [i] = LLVMConstInt (LLVMInt32Type (), mask [i], FALSE);
3978 values [ins->dreg] =
3979 LLVMBuildShuffleVector (builder, values [ins->sreg1], values [ins->sreg2],
3980 LLVMConstVector (mask_values, mask_size), dname);
3985 LLVMTypeRef t = simd_op_to_llvm_type (ins->opcode);
3986 LLVMValueRef v, val;
3988 v = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
3989 val = LLVMConstNull (t);
3990 val = LLVMBuildInsertElement (builder, val, v, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
3991 val = LLVMBuildInsertElement (builder, val, v, LLVMConstInt (LLVMInt32Type (), 1, FALSE), dname);
3993 values [ins->dreg] = val;
3997 case OP_DUPPS_HIGH: {
3998 LLVMTypeRef t = simd_op_to_llvm_type (ins->opcode);
3999 LLVMValueRef v1, v2, val;
4002 if (ins->opcode == OP_DUPPS_LOW) {
4003 v1 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
4004 v2 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 2, FALSE), "");
4006 v1 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 1, FALSE), "");
4007 v2 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 3, FALSE), "");
4009 val = LLVMConstNull (t);
4010 val = LLVMBuildInsertElement (builder, val, v1, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
4011 val = LLVMBuildInsertElement (builder, val, v1, LLVMConstInt (LLVMInt32Type (), 1, FALSE), "");
4012 val = LLVMBuildInsertElement (builder, val, v2, LLVMConstInt (LLVMInt32Type (), 2, FALSE), "");
4013 val = LLVMBuildInsertElement (builder, val, v2, LLVMConstInt (LLVMInt32Type (), 3, FALSE), "");
4015 values [ins->dreg] = val;
4025 * EXCEPTION HANDLING
4027 case OP_IMPLICIT_EXCEPTION:
4028 /* This marks a place where an implicit exception can happen */
4029 if (bb->region != -1)
4030 LLVM_FAILURE (ctx, "implicit-exception");
4034 MonoMethodSignature *throw_sig;
4035 LLVMValueRef callee, arg;
4036 gboolean rethrow = (ins->opcode == OP_RETHROW);
4037 const char *icall_name;
4039 callee = rethrow ? ctx->lmodule->rethrow : ctx->lmodule->throw;
4040 icall_name = rethrow ? "mono_arch_rethrow_exception" : "mono_arch_throw_exception";
4043 throw_sig = mono_metadata_signature_alloc (mono_get_corlib (), 1);
4044 throw_sig->ret = &mono_get_void_class ()->byval_arg;
4045 throw_sig->params [0] = &mono_get_object_class ()->byval_arg;
4046 if (cfg->compile_aot) {
4047 callee = get_plt_entry (ctx, sig_to_llvm_sig (ctx, throw_sig), MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
4049 callee = LLVMAddFunction (module, icall_name, sig_to_llvm_sig (ctx, throw_sig));
4053 * LLVM doesn't push the exception argument, so we need a different
4056 LLVMAddGlobalMapping (ee, callee, resolve_patch (cfg, MONO_PATCH_INFO_INTERNAL_METHOD, rethrow ? "llvm_rethrow_exception_trampoline" : "llvm_throw_exception_trampoline"));
4058 LLVMAddGlobalMapping (ee, callee, resolve_patch (cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name));
4062 mono_memory_barrier ();
4064 ctx->lmodule->rethrow = callee;
4066 ctx->lmodule->throw = callee;
4068 arg = convert (ctx, lhs, type_to_llvm_type (ctx, &mono_get_object_class ()->byval_arg));
4069 emit_call (ctx, bb, &builder, callee, &arg, 1);
4072 case OP_CALL_HANDLER: {
4074 * We don't 'call' handlers, but instead simply branch to them.
4075 * The code generated by ENDFINALLY will branch back to us.
4077 LLVMBasicBlockRef noex_bb;
4079 BBInfo *info = &bblocks [ins->inst_target_bb->block_num];
4081 bb_list = info->call_handler_return_bbs;
4084 * Set the indicator variable for the finally clause.
4086 lhs = info->finally_ind;
4088 LLVMBuildStore (builder, LLVMConstInt (LLVMInt32Type (), g_slist_length (bb_list) + 1, FALSE), lhs);
4090 /* Branch to the finally clause */
4091 LLVMBuildBr (builder, info->call_handler_target_bb);
4093 noex_bb = gen_bb (ctx, "CALL_HANDLER_CONT_BB");
4094 info->call_handler_return_bbs = g_slist_append_mempool (cfg->mempool, info->call_handler_return_bbs, noex_bb);
4096 builder = ctx->builder = create_builder (ctx);
4097 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
4099 bblocks [bb->block_num].end_bblock = noex_bb;
4102 case OP_START_HANDLER: {
4105 case OP_ENDFINALLY: {
4106 LLVMBasicBlockRef resume_bb;
4107 MonoBasicBlock *handler_bb;
4108 LLVMValueRef val, switch_ins, callee;
4112 handler_bb = g_hash_table_lookup (ctx->region_to_handler, GUINT_TO_POINTER (mono_get_block_region_notry (cfg, bb->region)));
4113 g_assert (handler_bb);
4114 info = &bblocks [handler_bb->block_num];
4115 lhs = info->finally_ind;
4118 bb_list = info->call_handler_return_bbs;
4120 resume_bb = gen_bb (ctx, "ENDFINALLY_RESUME_BB");
4122 /* Load the finally variable */
4123 val = LLVMBuildLoad (builder, lhs, "");
4125 /* Reset the variable */
4126 LLVMBuildStore (builder, LLVMConstInt (LLVMInt32Type (), 0, FALSE), lhs);
4128 /* Branch to either resume_bb, or to the bblocks in bb_list */
4129 switch_ins = LLVMBuildSwitch (builder, val, resume_bb, g_slist_length (bb_list));
4131 * The other targets are added at the end to handle OP_CALL_HANDLER
4132 * opcodes processed later.
4134 info->endfinally_switch_ins_list = g_slist_append_mempool (cfg->mempool, info->endfinally_switch_ins_list, switch_ins);
4136 builder = ctx->builder = create_builder (ctx);
4137 LLVMPositionBuilderAtEnd (ctx->builder, resume_bb);
4139 if (ctx->cfg->compile_aot) {
4140 callee = get_plt_entry (ctx, LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE), MONO_PATCH_INFO_INTERNAL_METHOD, "llvm_resume_unwind_trampoline");
4142 callee = LLVMGetNamedFunction (module, "llvm_resume_unwind_trampoline");
4144 LLVMBuildCall (builder, callee, NULL, 0, "");
4146 LLVMBuildUnreachable (builder);
4147 has_terminator = TRUE;
4153 sprintf (reason, "opcode %s", mono_inst_name (ins->opcode));
4154 LLVM_FAILURE (ctx, reason);
4159 /* Convert the value to the type required by phi nodes */
4160 if (spec [MONO_INST_DEST] != ' ' && !MONO_IS_STORE_MEMBASE (ins) && ctx->vreg_types [ins->dreg]) {
4161 if (!values [ins->dreg])
4163 values [ins->dreg] = addresses [ins->dreg];
4165 values [ins->dreg] = convert (ctx, values [ins->dreg], ctx->vreg_types [ins->dreg]);
4168 /* Add stores for volatile variables */
4169 if (spec [MONO_INST_DEST] != ' ' && spec [MONO_INST_DEST] != 'v' && !MONO_IS_STORE_MEMBASE (ins))
4170 emit_volatile_store (ctx, ins->dreg);
4173 if (!has_terminator && bb->next_bb && (bb == cfg->bb_entry || bb->in_count > 0))
4174 LLVMBuildBr (builder, get_bb (ctx, bb->next_bb));
4176 if (bb == cfg->bb_exit && sig->ret->type == MONO_TYPE_VOID)
4177 LLVMBuildRetVoid (builder);
4179 if (bb == cfg->bb_entry)
4180 ctx->last_alloca = LLVMGetLastInstruction (get_bb (ctx, cfg->bb_entry));
4189 * mono_llvm_check_method_supported:
4191 * Do some quick checks to decide whenever cfg->method can be compiled by LLVM, to avoid
4192 * compiling a method twice.
4195 mono_llvm_check_method_supported (MonoCompile *cfg)
4197 MonoMethodHeader *header = cfg->header;
4198 MonoExceptionClause *clause;
4201 if (cfg->method->save_lmf) {
4202 cfg->exception_message = g_strdup ("lmf");
4203 cfg->disable_llvm = TRUE;
4207 for (i = 0; i < header->num_clauses; ++i) {
4208 clause = &header->clauses [i];
4210 if (i > 0 && clause->try_offset <= header->clauses [i - 1].handler_offset + header->clauses [i - 1].handler_len) {
4212 * FIXME: Some tests still fail with nested clauses.
4214 cfg->exception_message = g_strdup ("nested clauses");
4215 cfg->disable_llvm = TRUE;
4221 if (cfg->method->dynamic) {
4222 cfg->exception_message = g_strdup ("dynamic.");
4223 cfg->disable_llvm = TRUE;
4228 * mono_llvm_emit_method:
4230 * Emit LLVM IL from the mono IL, and compile it to native code using LLVM.
4233 mono_llvm_emit_method (MonoCompile *cfg)
4236 MonoMethodSignature *sig;
4238 LLVMTypeRef method_type;
4239 LLVMValueRef method = NULL;
4241 LLVMValueRef *values;
4242 int i, max_block_num, bb_index;
4243 gboolean last = FALSE;
4244 GPtrArray *phi_values;
4245 LLVMCallInfo *linfo;
4247 LLVMModuleRef module;
4249 GPtrArray *bblock_list;
4250 MonoMethodHeader *header;
4251 MonoExceptionClause *clause;
4255 /* The code below might acquire the loader lock, so use it for global locking */
4256 mono_loader_lock ();
4258 /* Used to communicate with the callbacks */
4259 mono_native_tls_set_value (current_cfg_tls_id, cfg);
4261 ctx = g_new0 (EmitContext, 1);
4263 ctx->mempool = cfg->mempool;
4266 * This maps vregs to the LLVM instruction defining them
4268 values = g_new0 (LLVMValueRef, cfg->next_vreg);
4270 * This maps vregs for volatile variables to the LLVM instruction defining their
4273 ctx->addresses = g_new0 (LLVMValueRef, cfg->next_vreg);
4274 ctx->vreg_types = g_new0 (LLVMTypeRef, cfg->next_vreg);
4275 ctx->vreg_cli_types = g_new0 (MonoType*, cfg->next_vreg);
4276 phi_values = g_ptr_array_sized_new (256);
4278 * This signals whenever the vreg was defined by a phi node with no input vars
4279 * (i.e. all its input bblocks end with NOT_REACHABLE).
4281 ctx->is_dead = g_new0 (gboolean, cfg->next_vreg);
4282 /* Whenever the bblock is unreachable */
4283 ctx->unreachable = g_new0 (gboolean, cfg->max_block_num);
4285 bblock_list = g_ptr_array_sized_new (256);
4287 ctx->values = values;
4288 ctx->region_to_handler = g_hash_table_new (NULL, NULL);
4290 if (cfg->compile_aot) {
4291 ctx->lmodule = &aot_module;
4292 method_name = mono_aot_get_method_name (cfg);
4293 cfg->llvm_method_name = g_strdup (method_name);
4296 ctx->lmodule = &jit_module;
4297 method_name = mono_method_full_name (cfg->method, TRUE);
4300 module = ctx->module = ctx->lmodule->module;
4303 LLVM_FAILURE (ctx, "gsharedvt");
4307 static int count = 0;
4310 if (g_getenv ("LLVM_COUNT")) {
4311 if (count == atoi (g_getenv ("LLVM_COUNT"))) {
4312 printf ("LAST: %s\n", mono_method_full_name (cfg->method, TRUE));
4316 if (count > atoi (g_getenv ("LLVM_COUNT")))
4317 LLVM_FAILURE (ctx, "");
4322 sig = mono_method_signature (cfg->method);
4325 linfo = mono_arch_get_llvm_call_info (cfg, sig);
4327 CHECK_FAILURE (ctx);
4330 linfo->rgctx_arg = TRUE;
4331 method_type = sig_to_llvm_sig_full (ctx, sig, linfo, &sinfo);
4332 CHECK_FAILURE (ctx);
4335 * This maps parameter indexes in the original signature to the indexes in
4336 * the LLVM signature.
4338 ctx->pindexes = sinfo.pindexes;
4340 method = LLVMAddFunction (module, method_name, method_type);
4341 ctx->lmethod = method;
4343 LLVMSetFunctionCallConv (method, LLVMMono1CallConv);
4344 LLVMSetLinkage (method, LLVMPrivateLinkage);
4346 LLVMAddFunctionAttr (method, LLVMUWTable);
4348 if (cfg->compile_aot) {
4349 LLVMSetLinkage (method, LLVMInternalLinkage);
4350 LLVMSetVisibility (method, LLVMHiddenVisibility);
4352 LLVMSetLinkage (method, LLVMPrivateLinkage);
4355 if (cfg->method->save_lmf)
4356 LLVM_FAILURE (ctx, "lmf");
4358 if (sig->pinvoke && cfg->method->wrapper_type != MONO_WRAPPER_RUNTIME_INVOKE)
4359 LLVM_FAILURE (ctx, "pinvoke signature");
4361 header = cfg->header;
4362 for (i = 0; i < header->num_clauses; ++i) {
4363 clause = &header->clauses [i];
4364 if (clause->flags != MONO_EXCEPTION_CLAUSE_FINALLY && clause->flags != MONO_EXCEPTION_CLAUSE_NONE)
4365 LLVM_FAILURE (ctx, "non-finally/catch clause.");
4368 if (linfo->rgctx_arg) {
4369 ctx->rgctx_arg = LLVMGetParam (method, sinfo.rgctx_arg_pindex);
4371 * We mark the rgctx parameter with the inreg attribute, which is mapped to
4372 * MONO_ARCH_RGCTX_REG in the Mono calling convention in llvm, i.e.
4373 * CC_X86_64_Mono in X86CallingConv.td.
4375 LLVMAddAttribute (ctx->rgctx_arg, LLVMInRegAttribute);
4376 LLVMSetValueName (ctx->rgctx_arg, "rgctx");
4378 if (cfg->vret_addr) {
4379 values [cfg->vret_addr->dreg] = LLVMGetParam (method, sinfo.vret_arg_pindex);
4380 LLVMSetValueName (values [cfg->vret_addr->dreg], "vret");
4383 values [cfg->args [0]->dreg] = LLVMGetParam (method, sinfo.this_arg_pindex);
4384 LLVMSetValueName (values [cfg->args [0]->dreg], "this");
4387 names = g_new (char *, sig->param_count);
4388 mono_method_get_param_names (cfg->method, (const char **) names);
4390 for (i = 0; i < sig->param_count; ++i) {
4393 values [cfg->args [i + sig->hasthis]->dreg] = LLVMGetParam (method, sinfo.pindexes [i]);
4394 if (names [i] && names [i][0] != '\0')
4395 name = g_strdup_printf ("arg_%s", names [i]);
4397 name = g_strdup_printf ("arg_%d", i);
4398 LLVMSetValueName (values [cfg->args [i + sig->hasthis]->dreg], name);
4400 if (linfo->args [i + sig->hasthis].storage == LLVMArgVtypeByVal)
4401 LLVMAddAttribute (LLVMGetParam (method, sinfo.pindexes [i]), LLVMByValAttribute);
4406 for (bb = cfg->bb_entry; bb; bb = bb->next_bb)
4407 max_block_num = MAX (max_block_num, bb->block_num);
4408 ctx->bblocks = bblocks = g_new0 (BBInfo, max_block_num + 1);
4410 /* Add branches between non-consecutive bblocks */
4411 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
4412 if (bb->last_ins && MONO_IS_COND_BRANCH_OP (bb->last_ins) &&
4413 bb->next_bb != bb->last_ins->inst_false_bb) {
4415 MonoInst *inst = mono_mempool_alloc0 (cfg->mempool, sizeof (MonoInst));
4416 inst->opcode = OP_BR;
4417 inst->inst_target_bb = bb->last_ins->inst_false_bb;
4418 mono_bblock_add_inst (bb, inst);
4423 * The INDIRECT flag added by OP_LDADDR inhibits optimizations, even if the LDADDR
4424 * was later optimized away, so clear these flags, and add them back for the still
4425 * present OP_LDADDR instructions.
4427 for (i = 0; i < cfg->next_vreg; ++i) {
4430 ins = get_vreg_to_inst (cfg, i);
4431 if (ins && ins != cfg->rgctx_var)
4432 ins->flags &= ~MONO_INST_INDIRECT;
4436 * Make a first pass over the code to precreate PHI nodes/set INDIRECT flags.
4438 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
4440 LLVMBuilderRef builder;
4442 char dname_buf[128];
4444 builder = create_builder (ctx);
4446 for (ins = bb->code; ins; ins = ins->next) {
4447 switch (ins->opcode) {
4452 LLVMTypeRef phi_type = llvm_type_to_stack_type (type_to_llvm_type (ctx, &ins->klass->byval_arg));
4454 CHECK_FAILURE (ctx);
4456 if (ins->opcode == OP_VPHI) {
4457 /* Treat valuetype PHI nodes as operating on the address itself */
4458 g_assert (ins->klass);
4459 phi_type = LLVMPointerType (type_to_llvm_type (ctx, &ins->klass->byval_arg), 0);
4463 * Have to precreate these, as they can be referenced by
4464 * earlier instructions.
4466 sprintf (dname_buf, "t%d", ins->dreg);
4468 values [ins->dreg] = LLVMBuildPhi (builder, phi_type, dname);
4470 if (ins->opcode == OP_VPHI)
4471 ctx->addresses [ins->dreg] = values [ins->dreg];
4473 g_ptr_array_add (phi_values, values [ins->dreg]);
4476 * Set the expected type of the incoming arguments since these have
4477 * to have the same type.
4479 for (i = 0; i < ins->inst_phi_args [0]; i++) {
4480 int sreg1 = ins->inst_phi_args [i + 1];
4483 ctx->vreg_types [sreg1] = phi_type;
4488 ((MonoInst*)ins->inst_p0)->flags |= MONO_INST_INDIRECT;
4497 * Create an ordering for bblocks, use the depth first order first, then
4498 * put the exception handling bblocks last.
4500 for (bb_index = 0; bb_index < cfg->num_bblocks; ++bb_index) {
4501 bb = cfg->bblocks [bb_index];
4502 if (!(bb->region != -1 && !MONO_BBLOCK_IS_IN_REGION (bb, MONO_REGION_TRY))) {
4503 g_ptr_array_add (bblock_list, bb);
4504 bblocks [bb->block_num].added = TRUE;
4508 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
4509 if (!bblocks [bb->block_num].added)
4510 g_ptr_array_add (bblock_list, bb);
4514 * Second pass: generate code.
4516 for (bb_index = 0; bb_index < bblock_list->len; ++bb_index) {
4517 bb = g_ptr_array_index (bblock_list, bb_index);
4519 if (!(bb == cfg->bb_entry || bb->in_count > 0))
4522 process_bb (ctx, bb);
4523 CHECK_FAILURE (ctx);
4526 /* Add incoming phi values */
4527 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
4528 GSList *l, *ins_list;
4530 ins_list = bblocks [bb->block_num].phi_nodes;
4532 for (l = ins_list; l; l = l->next) {
4533 PhiNode *node = l->data;
4534 MonoInst *phi = node->phi;
4535 int sreg1 = node->sreg;
4536 LLVMBasicBlockRef in_bb;
4541 in_bb = get_end_bb (ctx, node->in_bb);
4543 if (ctx->unreachable [node->in_bb->block_num])
4546 if (!values [sreg1])
4547 /* Can happen with values in EH clauses */
4548 LLVM_FAILURE (ctx, "incoming phi sreg1");
4550 if (phi->opcode == OP_VPHI) {
4551 g_assert (LLVMTypeOf (ctx->addresses [sreg1]) == LLVMTypeOf (values [phi->dreg]));
4552 LLVMAddIncoming (values [phi->dreg], &ctx->addresses [sreg1], &in_bb, 1);
4554 g_assert (LLVMTypeOf (values [sreg1]) == LLVMTypeOf (values [phi->dreg]));
4555 LLVMAddIncoming (values [phi->dreg], &values [sreg1], &in_bb, 1);
4560 /* Create the SWITCH statements for ENDFINALLY instructions */
4561 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
4562 BBInfo *info = &bblocks [bb->block_num];
4564 for (l = info->endfinally_switch_ins_list; l; l = l->next) {
4565 LLVMValueRef switch_ins = l->data;
4566 GSList *bb_list = info->call_handler_return_bbs;
4568 for (i = 0; i < g_slist_length (bb_list); ++i)
4569 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), i + 1, FALSE), g_slist_nth (bb_list, i)->data);
4573 if (cfg->verbose_level > 1)
4574 mono_llvm_dump_value (method);
4576 if (cfg->compile_aot)
4577 mark_as_used (ctx->lmodule, method);
4579 if (cfg->compile_aot) {
4580 LLVMValueRef md_args [16];
4581 LLVMValueRef md_node;
4584 method_index = mono_aot_get_method_index (cfg->orig_method);
4585 md_args [0] = LLVMMDString (method_name, strlen (method_name));
4586 md_args [1] = LLVMConstInt (LLVMInt32Type (), method_index, FALSE);
4587 md_node = LLVMMDNode (md_args, 2);
4588 LLVMAddNamedMetadataOperand (module, "mono.function_indexes", md_node);
4589 //LLVMSetMetadata (method, md_kind, LLVMMDNode (&md_arg, 1));
4592 if (cfg->compile_aot) {
4593 /* Don't generate native code, keep the LLVM IR */
4594 if (cfg->compile_aot && cfg->verbose_level)
4595 printf ("%s emitted as %s\n", mono_method_full_name (cfg->method, TRUE), method_name);
4597 //LLVMVerifyFunction(method, 0);
4599 mono_llvm_optimize_method (method);
4601 if (cfg->verbose_level > 1)
4602 mono_llvm_dump_value (method);
4604 cfg->native_code = LLVMGetPointerToGlobal (ee, method);
4606 /* Set by emit_cb */
4607 g_assert (cfg->code_len);
4609 /* FIXME: Free the LLVM IL for the function */
4617 /* Need to add unused phi nodes as they can be referenced by other values */
4618 LLVMBasicBlockRef phi_bb = LLVMAppendBasicBlock (method, "PHI_BB");
4619 LLVMBuilderRef builder;
4621 builder = create_builder (ctx);
4622 LLVMPositionBuilderAtEnd (builder, phi_bb);
4624 for (i = 0; i < phi_values->len; ++i) {
4625 LLVMValueRef v = g_ptr_array_index (phi_values, i);
4626 if (LLVMGetInstructionParent (v) == NULL)
4627 LLVMInsertIntoBuilder (builder, v);
4630 LLVMDeleteFunction (method);
4635 g_free (ctx->addresses);
4636 g_free (ctx->vreg_types);
4637 g_free (ctx->vreg_cli_types);
4638 g_free (ctx->pindexes);
4639 g_free (ctx->is_dead);
4640 g_free (ctx->unreachable);
4641 g_ptr_array_free (phi_values, TRUE);
4642 g_free (ctx->bblocks);
4643 g_hash_table_destroy (ctx->region_to_handler);
4644 g_free (method_name);
4645 g_ptr_array_free (bblock_list, TRUE);
4647 for (l = ctx->builders; l; l = l->next) {
4648 LLVMBuilderRef builder = l->data;
4649 LLVMDisposeBuilder (builder);
4654 mono_native_tls_set_value (current_cfg_tls_id, NULL);
4656 mono_loader_unlock ();
4660 * mono_llvm_emit_call:
4662 * Same as mono_arch_emit_call () for LLVM.
4665 mono_llvm_emit_call (MonoCompile *cfg, MonoCallInst *call)
4668 MonoMethodSignature *sig;
4669 int i, n, stack_size;
4674 sig = call->signature;
4675 n = sig->param_count + sig->hasthis;
4677 call->cinfo = mono_arch_get_llvm_call_info (cfg, sig);
4679 if (cfg->disable_llvm)
4682 if (sig->call_convention == MONO_CALL_VARARG) {
4683 cfg->exception_message = g_strdup ("varargs");
4684 cfg->disable_llvm = TRUE;
4687 for (i = 0; i < n; ++i) {
4690 ainfo = call->cinfo->args + i;
4692 in = call->args [i];
4694 /* Simply remember the arguments */
4695 switch (ainfo->storage) {
4697 case LLVMArgInFPReg: {
4698 MonoType *t = (sig->hasthis && i == 0) ? &mono_get_intptr_class ()->byval_arg : sig->params [i - sig->hasthis];
4700 if (!t->byref && (t->type == MONO_TYPE_R8 || t->type == MONO_TYPE_R4)) {
4701 MONO_INST_NEW (cfg, ins, OP_FMOVE);
4702 ins->dreg = mono_alloc_freg (cfg);
4704 MONO_INST_NEW (cfg, ins, OP_MOVE);
4705 ins->dreg = mono_alloc_ireg (cfg);
4707 ins->sreg1 = in->dreg;
4710 case LLVMArgVtypeByVal:
4711 case LLVMArgVtypeInReg:
4712 MONO_INST_NEW (cfg, ins, OP_LLVM_OUTARG_VT);
4713 ins->dreg = mono_alloc_ireg (cfg);
4714 ins->sreg1 = in->dreg;
4715 ins->klass = mono_class_from_mono_type (sig->params [i - sig->hasthis]);
4718 call->cinfo = mono_arch_get_llvm_call_info (cfg, sig);
4719 cfg->exception_message = g_strdup ("ainfo->storage");
4720 cfg->disable_llvm = TRUE;
4724 if (!cfg->disable_llvm) {
4725 MONO_ADD_INS (cfg->cbb, ins);
4726 mono_call_inst_add_outarg_reg (cfg, call, ins->dreg, 0, FALSE);
4731 static unsigned char*
4732 alloc_cb (LLVMValueRef function, int size)
4736 cfg = mono_native_tls_get_value (current_cfg_tls_id);
4740 return mono_domain_code_reserve (cfg->domain, size);
4742 return mono_domain_code_reserve (mono_domain_get (), size);
4747 emitted_cb (LLVMValueRef function, void *start, void *end)
4751 cfg = mono_native_tls_get_value (current_cfg_tls_id);
4753 cfg->code_len = (guint8*)end - (guint8*)start;
4757 exception_cb (void *data)
4760 MonoJitExceptionInfo *ei;
4761 guint32 ei_len, i, j, nested_len, nindex;
4762 gpointer *type_info;
4763 int this_reg, this_offset;
4765 cfg = mono_native_tls_get_value (current_cfg_tls_id);
4769 * data points to a DWARF FDE structure, convert it to our unwind format and
4771 * An alternative would be to save it directly, and modify our unwinder to work
4774 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);
4775 if (cfg->verbose_level > 1)
4776 mono_print_unwind_info (cfg->encoded_unwind_ops, cfg->encoded_unwind_ops_len);
4778 /* Count nested clauses */
4780 for (i = 0; i < ei_len; ++i) {
4781 for (j = 0; j < ei_len; ++j) {
4782 gint32 cindex1 = *(gint32*)type_info [i];
4783 MonoExceptionClause *clause1 = &cfg->header->clauses [cindex1];
4784 gint32 cindex2 = *(gint32*)type_info [j];
4785 MonoExceptionClause *clause2 = &cfg->header->clauses [cindex2];
4787 if (cindex1 != cindex2 && clause1->try_offset >= clause2->try_offset && clause1->handler_offset <= clause2->handler_offset) {
4793 cfg->llvm_ex_info = mono_mempool_alloc0 (cfg->mempool, (ei_len + nested_len) * sizeof (MonoJitExceptionInfo));
4794 cfg->llvm_ex_info_len = ei_len + nested_len;
4795 memcpy (cfg->llvm_ex_info, ei, ei_len * sizeof (MonoJitExceptionInfo));
4796 /* Fill the rest of the information from the type info */
4797 for (i = 0; i < ei_len; ++i) {
4798 gint32 clause_index = *(gint32*)type_info [i];
4799 MonoExceptionClause *clause = &cfg->header->clauses [clause_index];
4801 cfg->llvm_ex_info [i].flags = clause->flags;
4802 cfg->llvm_ex_info [i].data.catch_class = clause->data.catch_class;
4806 * For nested clauses, the LLVM produced exception info associates the try interval with
4807 * the innermost handler, while mono expects it to be associated with all nesting clauses.
4809 /* FIXME: These should be order with the normal clauses */
4811 for (i = 0; i < ei_len; ++i) {
4812 for (j = 0; j < ei_len; ++j) {
4813 gint32 cindex1 = *(gint32*)type_info [i];
4814 MonoExceptionClause *clause1 = &cfg->header->clauses [cindex1];
4815 gint32 cindex2 = *(gint32*)type_info [j];
4816 MonoExceptionClause *clause2 = &cfg->header->clauses [cindex2];
4818 if (cindex1 != cindex2 && clause1->try_offset >= clause2->try_offset && clause1->handler_offset <= clause2->handler_offset) {
4820 * The try interval comes from the nested clause, everything else from the
4823 memcpy (&cfg->llvm_ex_info [nindex], &cfg->llvm_ex_info [j], sizeof (MonoJitExceptionInfo));
4824 cfg->llvm_ex_info [nindex].try_start = cfg->llvm_ex_info [i].try_start;
4825 cfg->llvm_ex_info [nindex].try_end = cfg->llvm_ex_info [i].try_end;
4830 g_assert (nindex == ei_len + nested_len);
4831 cfg->llvm_this_reg = this_reg;
4832 cfg->llvm_this_offset = this_offset;
4834 /* type_info [i] is cfg mempool allocated, no need to free it */
4841 dlsym_cb (const char *name, void **symbol)
4847 if (!strcmp (name, "__bzero")) {
4848 *symbol = (void*)bzero;
4850 current = mono_dl_open (NULL, 0, NULL);
4853 err = mono_dl_symbol (current, name, symbol);
4855 #ifdef MONO_ARCH_HAVE_CREATE_LLVM_NATIVE_THUNK
4856 *symbol = (char*)mono_arch_create_llvm_native_thunk (mono_domain_get (), (guint8*)(*symbol));
4862 AddFunc (LLVMModuleRef module, const char *name, LLVMTypeRef ret_type, LLVMTypeRef *param_types, int nparams)
4864 LLVMAddFunction (module, name, LLVMFunctionType (ret_type, param_types, nparams, FALSE));
4868 AddFunc2 (LLVMModuleRef module, const char *name, LLVMTypeRef ret_type, LLVMTypeRef param_type1, LLVMTypeRef param_type2)
4870 LLVMTypeRef param_types [4];
4872 param_types [0] = param_type1;
4873 param_types [1] = param_type2;
4875 AddFunc (module, name, ret_type, param_types, 2);
4879 add_intrinsics (LLVMModuleRef module)
4881 /* Emit declarations of instrinsics */
4883 * It would be nicer to emit only the intrinsics actually used, but LLVM's Module
4884 * type doesn't seem to do any locking.
4887 LLVMTypeRef memset_params [] = { LLVMPointerType (LLVMInt8Type (), 0), LLVMInt8Type (), LLVMInt32Type (), LLVMInt32Type (), LLVMInt1Type () };
4889 memset_param_count = 5;
4890 memset_func_name = "llvm.memset.p0i8.i32";
4892 LLVMAddFunction (module, memset_func_name, LLVMFunctionType (LLVMVoidType (), memset_params, memset_param_count, FALSE));
4896 LLVMTypeRef memcpy_params [] = { LLVMPointerType (LLVMInt8Type (), 0), LLVMPointerType (LLVMInt8Type (), 0), LLVMInt32Type (), LLVMInt32Type (), LLVMInt1Type () };
4898 memcpy_param_count = 5;
4899 memcpy_func_name = "llvm.memcpy.p0i8.p0i8.i32";
4901 LLVMAddFunction (module, memcpy_func_name, LLVMFunctionType (LLVMVoidType (), memcpy_params, memcpy_param_count, FALSE));
4905 LLVMTypeRef params [] = { LLVMDoubleType () };
4907 LLVMAddFunction (module, "llvm.sin.f64", LLVMFunctionType (LLVMDoubleType (), params, 1, FALSE));
4908 LLVMAddFunction (module, "llvm.cos.f64", LLVMFunctionType (LLVMDoubleType (), params, 1, FALSE));
4909 LLVMAddFunction (module, "llvm.sqrt.f64", LLVMFunctionType (LLVMDoubleType (), params, 1, FALSE));
4911 /* This isn't an intrinsic, instead llvm seems to special case it by name */
4912 LLVMAddFunction (module, "fabs", LLVMFunctionType (LLVMDoubleType (), params, 1, FALSE));
4916 LLVMTypeRef ovf_res_i32 [] = { LLVMInt32Type (), LLVMInt1Type () };
4917 LLVMTypeRef ovf_params_i32 [] = { LLVMInt32Type (), LLVMInt32Type () };
4919 LLVMAddFunction (module, "llvm.sadd.with.overflow.i32", LLVMFunctionType (LLVMStructType (ovf_res_i32, 2, FALSE), ovf_params_i32, 2, FALSE));
4920 LLVMAddFunction (module, "llvm.uadd.with.overflow.i32", LLVMFunctionType (LLVMStructType (ovf_res_i32, 2, FALSE), ovf_params_i32, 2, FALSE));
4921 LLVMAddFunction (module, "llvm.ssub.with.overflow.i32", LLVMFunctionType (LLVMStructType (ovf_res_i32, 2, FALSE), ovf_params_i32, 2, FALSE));
4922 LLVMAddFunction (module, "llvm.usub.with.overflow.i32", LLVMFunctionType (LLVMStructType (ovf_res_i32, 2, FALSE), ovf_params_i32, 2, FALSE));
4923 LLVMAddFunction (module, "llvm.smul.with.overflow.i32", LLVMFunctionType (LLVMStructType (ovf_res_i32, 2, FALSE), ovf_params_i32, 2, FALSE));
4924 LLVMAddFunction (module, "llvm.umul.with.overflow.i32", LLVMFunctionType (LLVMStructType (ovf_res_i32, 2, FALSE), ovf_params_i32, 2, FALSE));
4928 LLVMTypeRef ovf_res_i64 [] = { LLVMInt64Type (), LLVMInt1Type () };
4929 LLVMTypeRef ovf_params_i64 [] = { LLVMInt64Type (), LLVMInt64Type () };
4931 LLVMAddFunction (module, "llvm.sadd.with.overflow.i64", LLVMFunctionType (LLVMStructType (ovf_res_i64, 2, FALSE), ovf_params_i64, 2, FALSE));
4932 LLVMAddFunction (module, "llvm.uadd.with.overflow.i64", LLVMFunctionType (LLVMStructType (ovf_res_i64, 2, FALSE), ovf_params_i64, 2, FALSE));
4933 LLVMAddFunction (module, "llvm.ssub.with.overflow.i64", LLVMFunctionType (LLVMStructType (ovf_res_i64, 2, FALSE), ovf_params_i64, 2, FALSE));
4934 LLVMAddFunction (module, "llvm.usub.with.overflow.i64", LLVMFunctionType (LLVMStructType (ovf_res_i64, 2, FALSE), ovf_params_i64, 2, FALSE));
4935 LLVMAddFunction (module, "llvm.smul.with.overflow.i64", LLVMFunctionType (LLVMStructType (ovf_res_i64, 2, FALSE), ovf_params_i64, 2, FALSE));
4936 LLVMAddFunction (module, "llvm.umul.with.overflow.i64", LLVMFunctionType (LLVMStructType (ovf_res_i64, 2, FALSE), ovf_params_i64, 2, FALSE));
4941 LLVMTypeRef arg_types [2];
4942 LLVMTypeRef ret_type;
4944 arg_types [0] = LLVMPointerType (LLVMInt8Type (), 0);
4945 arg_types [1] = LLVMPointerType (LLVMInt8Type (), 0);
4946 ret_type = LLVMInt32Type ();
4948 LLVMAddFunction (module, "mono_personality", LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE));
4950 LLVMAddFunction (module, "llvm_resume_unwind_trampoline", LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE));
4953 /* SSE intrinsics */
4954 #if defined(TARGET_X86) || defined(TARGET_AMD64)
4956 LLVMTypeRef ret_type, arg_types [16];
4959 ret_type = type_to_simd_type (MONO_TYPE_I4);
4960 arg_types [0] = ret_type;
4961 arg_types [1] = ret_type;
4962 AddFunc (module, "llvm.x86.sse41.pminud", ret_type, arg_types, 2);
4963 AddFunc (module, "llvm.x86.sse41.pmaxud", ret_type, arg_types, 2);
4965 ret_type = type_to_simd_type (MONO_TYPE_I2);
4966 arg_types [0] = ret_type;
4967 arg_types [1] = ret_type;
4968 AddFunc (module, "llvm.x86.sse41.pminuw", ret_type, arg_types, 2);
4969 AddFunc (module, "llvm.x86.sse2.pmins.w", ret_type, arg_types, 2);
4970 AddFunc (module, "llvm.x86.sse41.pmaxuw", ret_type, arg_types, 2);
4971 AddFunc (module, "llvm.x86.sse2.padds.w", ret_type, arg_types, 2);
4972 AddFunc (module, "llvm.x86.sse2.psubs.w", ret_type, arg_types, 2);
4973 AddFunc (module, "llvm.x86.sse2.paddus.w", ret_type, arg_types, 2);
4974 AddFunc (module, "llvm.x86.sse2.psubus.w", ret_type, arg_types, 2);
4975 AddFunc (module, "llvm.x86.sse2.pavg.w", ret_type, arg_types, 2);
4976 AddFunc (module, "llvm.x86.sse2.pmulh.w", ret_type, arg_types, 2);
4977 AddFunc (module, "llvm.x86.sse2.pmulhu.w", ret_type, arg_types, 2);
4979 ret_type = type_to_simd_type (MONO_TYPE_I1);
4980 arg_types [0] = ret_type;
4981 arg_types [1] = ret_type;
4982 AddFunc (module, "llvm.x86.sse2.pminu.b", ret_type, arg_types, 2);
4983 AddFunc (module, "llvm.x86.sse2.pmaxu.b", ret_type, arg_types, 2);
4984 AddFunc (module, "llvm.x86.sse2.padds.b", ret_type, arg_types, 2);
4985 AddFunc (module, "llvm.x86.sse2.psubs.b", ret_type, arg_types, 2);
4986 AddFunc (module, "llvm.x86.sse2.paddus.b", ret_type, arg_types, 2);
4987 AddFunc (module, "llvm.x86.sse2.psubus.b", ret_type, arg_types, 2);
4988 AddFunc (module, "llvm.x86.sse2.pavg.b", ret_type, arg_types, 2);
4990 ret_type = type_to_simd_type (MONO_TYPE_R8);
4991 arg_types [0] = ret_type;
4992 arg_types [1] = ret_type;
4993 AddFunc (module, "llvm.x86.sse2.min.pd", ret_type, arg_types, 2);
4994 AddFunc (module, "llvm.x86.sse2.max.pd", ret_type, arg_types, 2);
4995 AddFunc (module, "llvm.x86.sse3.hadd.pd", ret_type, arg_types, 2);
4996 AddFunc (module, "llvm.x86.sse3.hsub.pd", ret_type, arg_types, 2);
4997 AddFunc (module, "llvm.x86.sse3.addsub.pd", ret_type, arg_types, 2);
4999 ret_type = type_to_simd_type (MONO_TYPE_R4);
5000 arg_types [0] = ret_type;
5001 arg_types [1] = ret_type;
5002 AddFunc (module, "llvm.x86.sse.min.ps", ret_type, arg_types, 2);
5003 AddFunc (module, "llvm.x86.sse.max.ps", ret_type, arg_types, 2);
5004 AddFunc (module, "llvm.x86.sse3.hadd.ps", ret_type, arg_types, 2);
5005 AddFunc (module, "llvm.x86.sse3.hsub.ps", ret_type, arg_types, 2);
5006 AddFunc (module, "llvm.x86.sse3.addsub.ps", ret_type, arg_types, 2);
5009 ret_type = type_to_simd_type (MONO_TYPE_I1);
5010 arg_types [0] = type_to_simd_type (MONO_TYPE_I2);
5011 arg_types [1] = type_to_simd_type (MONO_TYPE_I2);
5012 AddFunc (module, "llvm.x86.sse2.packsswb.128", ret_type, arg_types, 2);
5013 AddFunc (module, "llvm.x86.sse2.packuswb.128", ret_type, arg_types, 2);
5014 ret_type = type_to_simd_type (MONO_TYPE_I2);
5015 arg_types [0] = type_to_simd_type (MONO_TYPE_I4);
5016 arg_types [1] = type_to_simd_type (MONO_TYPE_I4);
5017 AddFunc (module, "llvm.x86.sse2.packssdw.128", ret_type, arg_types, 2);
5018 AddFunc (module, "llvm.x86.sse41.packusdw", ret_type, arg_types, 2);
5021 ret_type = type_to_simd_type (MONO_TYPE_R8);
5022 arg_types [0] = ret_type;
5023 arg_types [1] = ret_type;
5024 arg_types [2] = LLVMInt8Type ();
5025 AddFunc (module, "llvm.x86.sse2.cmp.pd", ret_type, arg_types, 3);
5026 ret_type = type_to_simd_type (MONO_TYPE_R4);
5027 arg_types [0] = ret_type;
5028 arg_types [1] = ret_type;
5029 arg_types [2] = LLVMInt8Type ();
5030 AddFunc (module, "llvm.x86.sse.cmp.ps", ret_type, arg_types, 3);
5032 /* Conversion ops */
5033 ret_type = type_to_simd_type (MONO_TYPE_R8);
5034 arg_types [0] = type_to_simd_type (MONO_TYPE_I4);
5035 AddFunc (module, "llvm.x86.sse2.cvtdq2pd", ret_type, arg_types, 1);
5036 ret_type = type_to_simd_type (MONO_TYPE_R4);
5037 arg_types [0] = type_to_simd_type (MONO_TYPE_I4);
5038 AddFunc (module, "llvm.x86.sse2.cvtdq2ps", ret_type, arg_types, 1);
5039 ret_type = type_to_simd_type (MONO_TYPE_I4);
5040 arg_types [0] = type_to_simd_type (MONO_TYPE_R8);
5041 AddFunc (module, "llvm.x86.sse2.cvtpd2dq", ret_type, arg_types, 1);
5042 ret_type = type_to_simd_type (MONO_TYPE_I4);
5043 arg_types [0] = type_to_simd_type (MONO_TYPE_R4);
5044 AddFunc (module, "llvm.x86.sse2.cvtps2dq", ret_type, arg_types, 1);
5045 ret_type = type_to_simd_type (MONO_TYPE_R4);
5046 arg_types [0] = type_to_simd_type (MONO_TYPE_R8);
5047 AddFunc (module, "llvm.x86.sse2.cvtpd2ps", ret_type, arg_types, 1);
5048 ret_type = type_to_simd_type (MONO_TYPE_R8);
5049 arg_types [0] = type_to_simd_type (MONO_TYPE_R4);
5050 AddFunc (module, "llvm.x86.sse2.cvtps2pd", ret_type, arg_types, 1);
5052 ret_type = type_to_simd_type (MONO_TYPE_I4);
5053 arg_types [0] = type_to_simd_type (MONO_TYPE_R8);
5054 AddFunc (module, "llvm.x86.sse2.cvttpd2dq", ret_type, arg_types, 1);
5055 ret_type = type_to_simd_type (MONO_TYPE_I4);
5056 arg_types [0] = type_to_simd_type (MONO_TYPE_R4);
5057 AddFunc (module, "llvm.x86.sse2.cvttps2dq", ret_type, arg_types, 1);
5060 ret_type = type_to_simd_type (MONO_TYPE_R8);
5061 arg_types [0] = ret_type;
5062 AddFunc (module, "llvm.x86.sse2.sqrt.pd", ret_type, arg_types, 1);
5063 ret_type = type_to_simd_type (MONO_TYPE_R4);
5064 arg_types [0] = ret_type;
5065 AddFunc (module, "llvm.x86.sse.sqrt.ps", ret_type, arg_types, 1);
5066 ret_type = type_to_simd_type (MONO_TYPE_R4);
5067 arg_types [0] = ret_type;
5068 AddFunc (module, "llvm.x86.sse.rsqrt.ps", ret_type, arg_types, 1);
5069 ret_type = type_to_simd_type (MONO_TYPE_R4);
5070 arg_types [0] = ret_type;
5071 AddFunc (module, "llvm.x86.sse.rcp.ps", ret_type, arg_types, 1);
5074 ret_type = type_to_simd_type (MONO_TYPE_I2);
5075 arg_types [0] = ret_type;
5076 arg_types [1] = LLVMInt32Type ();
5077 AddFunc (module, "llvm.x86.sse2.psrli.w", ret_type, arg_types, 2);
5078 AddFunc (module, "llvm.x86.sse2.psrai.w", ret_type, arg_types, 2);
5079 AddFunc (module, "llvm.x86.sse2.pslli.w", ret_type, arg_types, 2);
5080 ret_type = type_to_simd_type (MONO_TYPE_I4);
5081 arg_types [0] = ret_type;
5082 arg_types [1] = LLVMInt32Type ();
5083 AddFunc (module, "llvm.x86.sse2.psrli.d", ret_type, arg_types, 2);
5084 AddFunc (module, "llvm.x86.sse2.psrai.d", ret_type, arg_types, 2);
5085 AddFunc (module, "llvm.x86.sse2.pslli.d", ret_type, arg_types, 2);
5086 ret_type = type_to_simd_type (MONO_TYPE_I8);
5087 arg_types [0] = ret_type;
5088 arg_types [1] = LLVMInt32Type ();
5089 AddFunc (module, "llvm.x86.sse2.psrli.q", ret_type, arg_types, 2);
5090 AddFunc (module, "llvm.x86.sse2.pslli.q", ret_type, arg_types, 2);
5093 ret_type = LLVMInt32Type ();
5094 arg_types [0] = type_to_simd_type (MONO_TYPE_I1);
5095 AddFunc (module, "llvm.x86.sse2.pmovmskb.128", ret_type, arg_types, 1);
5098 AddFunc (module, "llvm.x86.sse2.pause", LLVMVoidType (), NULL, 0);
5101 /* Load/Store intrinsics */
5103 LLVMTypeRef arg_types [5];
5107 for (i = 1; i <= 8; i *= 2) {
5108 arg_types [0] = LLVMPointerType (LLVMIntType (i * 8), 0);
5109 arg_types [1] = LLVMInt32Type ();
5110 arg_types [2] = LLVMInt1Type ();
5111 sprintf (name, "llvm.mono.load.i%d.p0i%d", i * 8, i * 8);
5112 LLVMAddFunction (module, name, LLVMFunctionType (LLVMIntType (i * 8), arg_types, 3, FALSE));
5114 arg_types [0] = LLVMIntType (i * 8);
5115 arg_types [1] = LLVMPointerType (LLVMIntType (i * 8), 0);
5116 arg_types [2] = LLVMInt32Type ();
5117 arg_types [3] = LLVMInt1Type ();
5118 sprintf (name, "llvm.mono.store.i%d.p0i%d", i * 8, i * 8);
5119 LLVMAddFunction (module, name, LLVMFunctionType (LLVMVoidType (), arg_types, 4, FALSE));
5125 add_types (MonoLLVMModule *lmodule)
5127 lmodule->ptr_type = LLVMPointerType (sizeof (gpointer) == 8 ? LLVMInt64Type () : LLVMInt32Type (), 0);
5131 mono_llvm_init (void)
5133 mono_native_tls_alloc (¤t_cfg_tls_id, NULL);
5137 init_jit_module (void)
5139 MonoJitICallInfo *info;
5141 if (jit_module_inited)
5144 mono_loader_lock ();
5146 if (jit_module_inited) {
5147 mono_loader_unlock ();
5151 jit_module.module = LLVMModuleCreateWithName ("mono");
5153 ee = mono_llvm_create_ee (LLVMCreateModuleProviderForExistingModule (jit_module.module), alloc_cb, emitted_cb, exception_cb, dlsym_cb);
5155 add_intrinsics (jit_module.module);
5156 add_types (&jit_module);
5158 jit_module.llvm_types = g_hash_table_new (NULL, NULL);
5160 info = mono_find_jit_icall_by_name ("llvm_resume_unwind_trampoline");
5162 LLVMAddGlobalMapping (ee, LLVMGetNamedFunction (jit_module.module, "llvm_resume_unwind_trampoline"), (void*)info->func);
5164 jit_module_inited = TRUE;
5166 mono_loader_unlock ();
5170 mono_llvm_cleanup (void)
5173 mono_llvm_dispose_ee (ee);
5175 if (jit_module.llvm_types)
5176 g_hash_table_destroy (jit_module.llvm_types);
5178 if (aot_module.module)
5179 LLVMDisposeModule (aot_module.module);
5181 LLVMContextDispose (LLVMGetGlobalContext ());
5185 mono_llvm_create_aot_module (const char *got_symbol)
5187 /* Delete previous module */
5188 if (aot_module.plt_entries)
5189 g_hash_table_destroy (aot_module.plt_entries);
5190 if (aot_module.module)
5191 LLVMDisposeModule (aot_module.module);
5193 memset (&aot_module, 0, sizeof (aot_module));
5195 aot_module.module = LLVMModuleCreateWithName ("aot");
5196 aot_module.got_symbol = got_symbol;
5198 add_intrinsics (aot_module.module);
5199 add_types (&aot_module);
5203 * We couldn't compute the type of the LLVM global representing the got because
5204 * its size is only known after all the methods have been emitted. So create
5205 * a dummy variable, and replace all uses it with the real got variable when
5206 * its size is known in mono_llvm_emit_aot_module ().
5209 LLVMTypeRef got_type = LLVMArrayType (aot_module.ptr_type, 0);
5211 aot_module.got_var = LLVMAddGlobal (aot_module.module, got_type, "mono_dummy_got");
5212 LLVMSetInitializer (aot_module.got_var, LLVMConstNull (got_type));
5215 /* Add a dummy personality function */
5217 LLVMBasicBlockRef lbb;
5218 LLVMBuilderRef lbuilder;
5219 LLVMValueRef personality;
5221 personality = LLVMAddFunction (aot_module.module, "mono_aot_personality", LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE));
5222 LLVMSetLinkage (personality, LLVMInternalLinkage);
5223 lbb = LLVMAppendBasicBlock (personality, "BB0");
5224 lbuilder = LLVMCreateBuilder ();
5225 LLVMPositionBuilderAtEnd (lbuilder, lbb);
5226 LLVMBuildRetVoid (lbuilder);
5229 aot_module.llvm_types = g_hash_table_new (NULL, NULL);
5230 aot_module.plt_entries = g_hash_table_new (g_str_hash, g_str_equal);
5234 * Emit the aot module into the LLVM bitcode file FILENAME.
5237 mono_llvm_emit_aot_module (const char *filename, int got_size)
5239 LLVMTypeRef got_type;
5240 LLVMValueRef real_got;
5243 * Create the real got variable and replace all uses of the dummy variable with
5246 got_type = LLVMArrayType (aot_module.ptr_type, got_size);
5247 real_got = LLVMAddGlobal (aot_module.module, got_type, aot_module.got_symbol);
5248 LLVMSetInitializer (real_got, LLVMConstNull (got_type));
5249 LLVMSetLinkage (real_got, LLVMInternalLinkage);
5251 mono_llvm_replace_uses_of (aot_module.got_var, real_got);
5253 mark_as_used (&aot_module, real_got);
5255 /* Delete the dummy got so it doesn't become a global */
5256 LLVMDeleteGlobal (aot_module.got_var);
5258 emit_llvm_used (&aot_module);
5264 if (LLVMVerifyModule (aot_module.module, LLVMReturnStatusAction, &verifier_err)) {
5265 g_assert_not_reached ();
5270 LLVMWriteBitcodeToFile (aot_module.module, filename);
5275 - Emit LLVM IR from the mono IR using the LLVM C API.
5276 - The original arch specific code remains, so we can fall back to it if we run
5277 into something we can't handle.
5281 A partial list of issues:
5282 - Handling of opcodes which can throw exceptions.
5284 In the mono JIT, these are implemented using code like this:
5291 push throw_pos - method
5292 call <exception trampoline>
5294 The problematic part is push throw_pos - method, which cannot be represented
5295 in the LLVM IR, since it does not support label values.
5296 -> this can be implemented in AOT mode using inline asm + labels, but cannot
5297 be implemented in JIT mode ?
5298 -> a possible but slower implementation would use the normal exception
5299 throwing code but it would need to control the placement of the throw code
5300 (it needs to be exactly after the compare+branch).
5301 -> perhaps add a PC offset intrinsics ?
5303 - efficient implementation of .ovf opcodes.
5305 These are currently implemented as:
5306 <ins which sets the condition codes>
5309 Some overflow opcodes are now supported by LLVM SVN.
5311 - exception handling, unwinding.
5312 - SSA is disabled for methods with exception handlers
5313 - How to obtain unwind info for LLVM compiled methods ?
5314 -> this is now solved by converting the unwind info generated by LLVM
5316 - LLVM uses the c++ exception handling framework, while we use our home grown
5317 code, and couldn't use the c++ one:
5318 - its not supported under VC++, other exotic platforms.
5319 - it might be impossible to support filter clauses with it.
5323 The trampolines need a predictable call sequence, since they need to disasm
5324 the calling code to obtain register numbers / offsets.
5326 LLVM currently generates this code in non-JIT mode:
5327 mov -0x98(%rax),%eax
5329 Here, the vtable pointer is lost.
5330 -> solution: use one vtable trampoline per class.
5332 - passing/receiving the IMT pointer/RGCTX.
5333 -> solution: pass them as normal arguments ?
5337 LLVM does not allow the specification of argument registers etc. This means
5338 that all calls are made according to the platform ABI.
5340 - passing/receiving vtypes.
5342 Vtypes passed/received in registers are handled by the front end by using
5343 a signature with scalar arguments, and loading the parts of the vtype into those
5346 Vtypes passed on the stack are handled using the 'byval' attribute.
5350 Supported though alloca, we need to emit the load/store code.
5354 The mono JIT uses pointer sized iregs/double fregs, while LLVM uses precisely
5355 typed registers, so we have to keep track of the precise LLVM type of each vreg.
5356 This is made easier because the IR is already in SSA form.
5357 An additional problem is that our IR is not consistent with types, i.e. i32/ia64
5358 types are frequently used incorrectly.
5363 Emit LLVM bytecode into a .bc file, compile it using llc into a .s file, then
5364 append the AOT data structures to that file. For methods which cannot be
5365 handled by LLVM, the normal JIT compiled versions are used.
5368 /* FIXME: Normalize some aspects of the mono IR to allow easier translation, like:
5369 * - each bblock should end with a branch
5370 * - setting the return value, making cfg->ret non-volatile
5371 * - avoid some transformations in the JIT which make it harder for us to generate
5373 * - use pointer types to help optimizations.