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;
43 LLVMExecutionEngineRef ee;
47 * Information associated by the backend with mono basic blocks.
50 LLVMBasicBlockRef bblock, end_bblock;
51 LLVMValueRef finally_ind;
52 gboolean added, invoke_target;
54 * If this bblock is the start of a finally clause, this is a list of bblocks it
55 * needs to branch to in ENDFINALLY.
57 GSList *call_handler_return_bbs;
59 * If this bblock is the start of a finally clause, this is the bblock that
60 * CALL_HANDLER needs to branch to.
62 LLVMBasicBlockRef call_handler_target_bb;
63 /* The list of switch statements generated by ENDFINALLY instructions */
64 GSList *endfinally_switch_ins_list;
69 * Structure containing emit state
74 /* Maps method names to the corresponding LLVMValueRef */
75 GHashTable *emitted_method_decls;
79 MonoLLVMModule *lmodule;
82 int sindex, default_index, ex_index;
83 LLVMBuilderRef builder;
84 LLVMValueRef *values, *addresses;
85 MonoType **vreg_cli_types;
87 MonoMethodSignature *sig;
89 GHashTable *region_to_handler;
90 LLVMBuilderRef alloca_builder;
91 LLVMValueRef last_alloca;
92 LLVMValueRef rgctx_arg;
93 LLVMTypeRef *vreg_types;
95 gboolean *unreachable;
97 LLVMValueRef imt_rgctx_loc;
98 GHashTable *llvm_types;
106 MonoBasicBlock *in_bb;
111 * Instruction metadata
112 * This is the same as ins_info, but LREG != IREG.
120 #define MINI_OP(a,b,dest,src1,src2) dest, src1, src2, ' ',
121 #define MINI_OP3(a,b,dest,src1,src2,src3) dest, src1, src2, src3,
128 /* keep in sync with the enum in mini.h */
131 #include "mini-ops.h"
136 #if SIZEOF_VOID_P == 4
137 #define GET_LONG_IMM(ins) (((guint64)(ins)->inst_ms_word << 32) | (guint64)(guint32)(ins)->inst_ls_word)
139 #define GET_LONG_IMM(ins) ((ins)->inst_imm)
142 #define LLVM_INS_INFO(opcode) (&llvm_ins_info [((opcode) - OP_START - 1) * 4])
145 #define TRACE_FAILURE(msg) do { printf ("%s\n", msg); } while (0)
147 #define TRACE_FAILURE(msg)
151 #define IS_TARGET_X86 1
153 #define IS_TARGET_X86 0
157 #define IS_TARGET_AMD64 1
159 #define IS_TARGET_AMD64 0
162 #define LLVM_FAILURE(ctx, reason) do { \
163 TRACE_FAILURE (reason); \
164 (ctx)->cfg->exception_message = g_strdup (reason); \
165 (ctx)->cfg->disable_llvm = TRUE; \
169 #define CHECK_FAILURE(ctx) do { \
170 if ((ctx)->cfg->disable_llvm) \
174 static LLVMIntPredicate cond_to_llvm_cond [] = {
187 static LLVMRealPredicate fpcond_to_llvm_cond [] = {
200 static MonoNativeTlsKey current_cfg_tls_id;
202 static MonoLLVMModule aot_module;
203 static int memset_param_count, memcpy_param_count;
204 static const char *memset_func_name;
205 static const char *memcpy_func_name;
207 static void init_jit_module (MonoDomain *domain);
212 * The LLVM type with width == sizeof (gpointer)
217 return sizeof (gpointer) == 8 ? LLVMInt64Type () : LLVMInt32Type ();
223 return sizeof (gpointer) == 8 ? LLVMPointerType (LLVMInt64Type (), 0) : LLVMPointerType (LLVMInt32Type (), 0);
229 return sizeof (gpointer) == 8 ? LLVMPointerType (LLVMInt64Type (), 0) : LLVMPointerType (LLVMInt32Type (), 0);
235 * Return the size of the LLVM representation of the vtype T.
238 get_vtype_size (MonoType *t)
242 size = mono_class_value_size (mono_class_from_mono_type (t), NULL);
244 while (size < 2 * sizeof (gpointer) && mono_is_power_of_two (size) == -1)
251 * simd_class_to_llvm_type:
253 * Return the LLVM type corresponding to the Mono.SIMD class KLASS
256 simd_class_to_llvm_type (EmitContext *ctx, MonoClass *klass)
258 if (!strcmp (klass->name, "Vector2d")) {
259 return LLVMVectorType (LLVMDoubleType (), 2);
260 } else if (!strcmp (klass->name, "Vector2l")) {
261 return LLVMVectorType (LLVMInt64Type (), 2);
262 } else if (!strcmp (klass->name, "Vector2ul")) {
263 return LLVMVectorType (LLVMInt64Type (), 2);
264 } else if (!strcmp (klass->name, "Vector4i")) {
265 return LLVMVectorType (LLVMInt32Type (), 4);
266 } else if (!strcmp (klass->name, "Vector4ui")) {
267 return LLVMVectorType (LLVMInt32Type (), 4);
268 } else if (!strcmp (klass->name, "Vector4f")) {
269 return LLVMVectorType (LLVMFloatType (), 4);
270 } else if (!strcmp (klass->name, "Vector8s")) {
271 return LLVMVectorType (LLVMInt16Type (), 8);
272 } else if (!strcmp (klass->name, "Vector8us")) {
273 return LLVMVectorType (LLVMInt16Type (), 8);
274 } else if (!strcmp (klass->name, "Vector16sb")) {
275 return LLVMVectorType (LLVMInt8Type (), 16);
276 } else if (!strcmp (klass->name, "Vector16b")) {
277 return LLVMVectorType (LLVMInt8Type (), 16);
279 printf ("%s\n", klass->name);
285 /* Return the 128 bit SIMD type corresponding to the mono type TYPE */
286 static inline G_GNUC_UNUSED LLVMTypeRef
287 type_to_simd_type (int type)
291 return LLVMVectorType (LLVMInt8Type (), 16);
293 return LLVMVectorType (LLVMInt16Type (), 8);
295 return LLVMVectorType (LLVMInt32Type (), 4);
297 return LLVMVectorType (LLVMInt64Type (), 2);
299 return LLVMVectorType (LLVMDoubleType (), 2);
301 return LLVMVectorType (LLVMFloatType (), 4);
303 g_assert_not_reached ();
311 * Return the LLVM type corresponding to T.
314 type_to_llvm_type (EmitContext *ctx, MonoType *t)
316 t = mini_replace_type (t);
319 return LLVMPointerType (LLVMInt8Type (), 0);
322 return LLVMVoidType ();
324 return LLVMInt8Type ();
326 return LLVMInt16Type ();
328 return LLVMInt32Type ();
330 return LLVMInt8Type ();
332 return LLVMInt16Type ();
334 return LLVMInt32Type ();
335 case MONO_TYPE_BOOLEAN:
336 return LLVMInt8Type ();
339 return LLVMInt64Type ();
341 return LLVMInt16Type ();
343 return LLVMFloatType ();
345 return LLVMDoubleType ();
348 return IntPtrType ();
349 case MONO_TYPE_OBJECT:
350 case MONO_TYPE_CLASS:
351 case MONO_TYPE_ARRAY:
352 case MONO_TYPE_SZARRAY:
353 case MONO_TYPE_STRING:
355 return ObjRefType ();
358 /* Because of generic sharing */
359 return ObjRefType ();
360 case MONO_TYPE_GENERICINST:
361 if (!mono_type_generic_inst_is_valuetype (t))
362 return ObjRefType ();
364 case MONO_TYPE_VALUETYPE:
365 case MONO_TYPE_TYPEDBYREF: {
369 klass = mono_class_from_mono_type (t);
371 if (MONO_CLASS_IS_SIMD (ctx->cfg, klass))
372 return simd_class_to_llvm_type (ctx, klass);
375 return type_to_llvm_type (ctx, mono_class_enum_basetype (klass));
377 ltype = g_hash_table_lookup (ctx->lmodule->llvm_types, klass);
380 LLVMTypeRef *eltypes;
383 size = get_vtype_size (t);
385 eltypes = g_new (LLVMTypeRef, size);
386 for (i = 0; i < size; ++i)
387 eltypes [i] = LLVMInt8Type ();
389 name = mono_type_full_name (&klass->byval_arg);
390 ltype = LLVMStructCreateNamed (LLVMGetGlobalContext (), name);
391 LLVMStructSetBody (ltype, eltypes, size, FALSE);
392 g_hash_table_insert (ctx->lmodule->llvm_types, klass, ltype);
400 printf ("X: %d\n", t->type);
401 ctx->cfg->exception_message = g_strdup_printf ("type %s", mono_type_full_name (t));
402 ctx->cfg->disable_llvm = TRUE;
410 * Return whenever T is an unsigned int type.
413 type_is_unsigned (EmitContext *ctx, MonoType *t)
429 * type_to_llvm_arg_type:
431 * Same as type_to_llvm_type, but treat i8/i16 as i32.
434 type_to_llvm_arg_type (EmitContext *ctx, MonoType *t)
436 LLVMTypeRef ptype = type_to_llvm_type (ctx, t);
438 if (ptype == LLVMInt8Type () || ptype == LLVMInt16Type ()) {
440 * LLVM generates code which only sets the lower bits, while JITted
441 * code expects all the bits to be set.
443 ptype = LLVMInt32Type ();
450 * llvm_type_to_stack_type:
452 * Return the LLVM type which needs to be used when a value of type TYPE is pushed
455 static G_GNUC_UNUSED LLVMTypeRef
456 llvm_type_to_stack_type (LLVMTypeRef type)
460 if (type == LLVMInt8Type ())
461 return LLVMInt32Type ();
462 else if (type == LLVMInt16Type ())
463 return LLVMInt32Type ();
464 else if (type == LLVMFloatType ())
465 return LLVMDoubleType ();
471 * regtype_to_llvm_type:
473 * Return the LLVM type corresponding to the regtype C used in instruction
477 regtype_to_llvm_type (char c)
481 return LLVMInt32Type ();
483 return LLVMInt64Type ();
485 return LLVMDoubleType ();
494 * Return the LLVM type corresponding to the unary/binary opcode OPCODE.
497 op_to_llvm_type (int opcode)
502 return LLVMInt8Type ();
505 return LLVMInt8Type ();
508 return LLVMInt16Type ();
511 return LLVMInt16Type ();
514 return LLVMInt32Type ();
517 return LLVMInt32Type ();
519 return LLVMInt64Type ();
521 return LLVMFloatType ();
523 return LLVMDoubleType ();
525 return LLVMInt64Type ();
527 return LLVMInt32Type ();
529 return LLVMInt64Type ();
532 return LLVMInt8Type ();
535 return LLVMInt16Type ();
538 return sizeof (gpointer) == 8 ? LLVMInt64Type () : LLVMInt32Type ();
545 return LLVMInt32Type ();
552 return LLVMInt64Type ();
554 printf ("%s\n", mono_inst_name (opcode));
555 g_assert_not_reached ();
561 * load_store_to_llvm_type:
563 * Return the size/sign/zero extension corresponding to the load/store opcode
567 load_store_to_llvm_type (int opcode, int *size, gboolean *sext, gboolean *zext)
573 case OP_LOADI1_MEMBASE:
574 case OP_STOREI1_MEMBASE_REG:
575 case OP_STOREI1_MEMBASE_IMM:
578 return LLVMInt8Type ();
579 case OP_LOADU1_MEMBASE:
583 return LLVMInt8Type ();
584 case OP_LOADI2_MEMBASE:
585 case OP_STOREI2_MEMBASE_REG:
586 case OP_STOREI2_MEMBASE_IMM:
589 return LLVMInt16Type ();
590 case OP_LOADU2_MEMBASE:
594 return LLVMInt16Type ();
595 case OP_LOADI4_MEMBASE:
596 case OP_LOADU4_MEMBASE:
599 case OP_STOREI4_MEMBASE_REG:
600 case OP_STOREI4_MEMBASE_IMM:
602 return LLVMInt32Type ();
603 case OP_LOADI8_MEMBASE:
605 case OP_STOREI8_MEMBASE_REG:
606 case OP_STOREI8_MEMBASE_IMM:
608 return LLVMInt64Type ();
609 case OP_LOADR4_MEMBASE:
610 case OP_STORER4_MEMBASE_REG:
612 return LLVMFloatType ();
613 case OP_LOADR8_MEMBASE:
614 case OP_STORER8_MEMBASE_REG:
616 return LLVMDoubleType ();
617 case OP_LOAD_MEMBASE:
619 case OP_STORE_MEMBASE_REG:
620 case OP_STORE_MEMBASE_IMM:
621 *size = sizeof (gpointer);
622 return IntPtrType ();
624 g_assert_not_reached ();
632 * Return the LLVM intrinsics corresponding to the overflow opcode OPCODE.
635 ovf_op_to_intrins (int opcode)
639 return "llvm.sadd.with.overflow.i32";
641 return "llvm.uadd.with.overflow.i32";
643 return "llvm.ssub.with.overflow.i32";
645 return "llvm.usub.with.overflow.i32";
647 return "llvm.smul.with.overflow.i32";
649 return "llvm.umul.with.overflow.i32";
651 return "llvm.sadd.with.overflow.i64";
653 return "llvm.uadd.with.overflow.i64";
655 return "llvm.ssub.with.overflow.i64";
657 return "llvm.usub.with.overflow.i64";
659 return "llvm.smul.with.overflow.i64";
661 return "llvm.umul.with.overflow.i64";
663 g_assert_not_reached ();
669 simd_op_to_intrins (int opcode)
672 #if defined(TARGET_X86) || defined(TARGET_AMD64)
674 return "llvm.x86.sse2.min.pd";
676 return "llvm.x86.sse.min.ps";
678 return "llvm.x86.sse41.pminud";
680 return "llvm.x86.sse41.pminuw";
682 return "llvm.x86.sse2.pminu.b";
684 return "llvm.x86.sse2.pmins.w";
686 return "llvm.x86.sse2.max.pd";
688 return "llvm.x86.sse.max.ps";
690 return "llvm.x86.sse3.hadd.pd";
692 return "llvm.x86.sse3.hadd.ps";
694 return "llvm.x86.sse3.hsub.pd";
696 return "llvm.x86.sse3.hsub.ps";
698 return "llvm.x86.sse41.pmaxud";
700 return "llvm.x86.sse41.pmaxuw";
702 return "llvm.x86.sse2.pmaxu.b";
704 return "llvm.x86.sse3.addsub.ps";
706 return "llvm.x86.sse3.addsub.pd";
707 case OP_EXTRACT_MASK:
708 return "llvm.x86.sse2.pmovmskb.128";
711 return "llvm.x86.sse2.psrli.w";
714 return "llvm.x86.sse2.psrli.d";
717 return "llvm.x86.sse2.psrli.q";
720 return "llvm.x86.sse2.pslli.w";
723 return "llvm.x86.sse2.pslli.d";
726 return "llvm.x86.sse2.pslli.q";
729 return "llvm.x86.sse2.psrai.w";
732 return "llvm.x86.sse2.psrai.d";
734 return "llvm.x86.sse2.padds.b";
736 return "llvm.x86.sse2.padds.w";
738 return "llvm.x86.sse2.psubs.b";
740 return "llvm.x86.sse2.psubs.w";
741 case OP_PADDB_SAT_UN:
742 return "llvm.x86.sse2.paddus.b";
743 case OP_PADDW_SAT_UN:
744 return "llvm.x86.sse2.paddus.w";
745 case OP_PSUBB_SAT_UN:
746 return "llvm.x86.sse2.psubus.b";
747 case OP_PSUBW_SAT_UN:
748 return "llvm.x86.sse2.psubus.w";
750 return "llvm.x86.sse2.pavg.b";
752 return "llvm.x86.sse2.pavg.w";
754 return "llvm.x86.sse.sqrt.ps";
756 return "llvm.x86.sse2.sqrt.pd";
758 return "llvm.x86.sse.rsqrt.ps";
760 return "llvm.x86.sse.rcp.ps";
762 return "llvm.x86.sse2.cvtdq2pd";
764 return "llvm.x86.sse2.cvtdq2ps";
766 return "llvm.x86.sse2.cvtpd2dq";
768 return "llvm.x86.sse2.cvtps2dq";
770 return "llvm.x86.sse2.cvtpd2ps";
772 return "llvm.x86.sse2.cvtps2pd";
774 return "llvm.x86.sse2.cvttpd2dq";
776 return "llvm.x86.sse2.cvttps2dq";
778 return "llvm.x86.sse.cmp.ps";
780 return "llvm.x86.sse2.cmp.pd";
782 return "llvm.x86.sse2.packsswb.128";
784 return "llvm.x86.sse2.packssdw.128";
786 return "llvm.x86.sse2.packuswb.128";
788 return "llvm.x86.sse41.packusdw";
790 return "llvm.x86.sse2.pmulh.w";
791 case OP_PMULW_HIGH_UN:
792 return "llvm.x86.sse2.pmulhu.w";
795 g_assert_not_reached ();
801 simd_op_to_llvm_type (int opcode)
803 #if defined(TARGET_X86) || defined(TARGET_AMD64)
807 return type_to_simd_type (MONO_TYPE_R8);
810 return type_to_simd_type (MONO_TYPE_I8);
813 return type_to_simd_type (MONO_TYPE_I4);
818 return type_to_simd_type (MONO_TYPE_I2);
822 return type_to_simd_type (MONO_TYPE_I1);
824 return type_to_simd_type (MONO_TYPE_R4);
827 return type_to_simd_type (MONO_TYPE_I4);
831 return type_to_simd_type (MONO_TYPE_R8);
835 return type_to_simd_type (MONO_TYPE_R4);
836 case OP_EXTRACT_MASK:
837 return type_to_simd_type (MONO_TYPE_I1);
843 return type_to_simd_type (MONO_TYPE_R4);
846 return type_to_simd_type (MONO_TYPE_R8);
848 g_assert_not_reached ();
859 * Return the LLVM basic block corresponding to BB.
861 static LLVMBasicBlockRef
862 get_bb (EmitContext *ctx, MonoBasicBlock *bb)
864 char bb_name_buf [128];
867 if (ctx->bblocks [bb->block_num].bblock == NULL) {
868 if (bb->flags & BB_EXCEPTION_HANDLER) {
869 int clause_index = (mono_get_block_region_notry (ctx->cfg, bb->region) >> 8) - 1;
870 sprintf (bb_name_buf, "EH_CLAUSE%d_BB%d", clause_index, bb->block_num);
871 bb_name = bb_name_buf;
872 } else if (bb->block_num < 256) {
873 if (!ctx->lmodule->bb_names) {
874 ctx->lmodule->bb_names_len = 256;
875 ctx->lmodule->bb_names = g_new0 (char*, ctx->lmodule->bb_names_len);
877 if (!ctx->lmodule->bb_names [bb->block_num]) {
880 n = g_strdup_printf ("BB%d", bb->block_num);
881 mono_memory_barrier ();
882 ctx->lmodule->bb_names [bb->block_num] = n;
884 bb_name = ctx->lmodule->bb_names [bb->block_num];
886 sprintf (bb_name_buf, "BB%d", bb->block_num);
887 bb_name = bb_name_buf;
890 ctx->bblocks [bb->block_num].bblock = LLVMAppendBasicBlock (ctx->lmethod, bb_name);
891 ctx->bblocks [bb->block_num].end_bblock = ctx->bblocks [bb->block_num].bblock;
894 return ctx->bblocks [bb->block_num].bblock;
900 * Return the last LLVM bblock corresponding to BB.
901 * This might not be equal to the bb returned by get_bb () since we need to generate
902 * multiple LLVM bblocks for a mono bblock to handle throwing exceptions.
904 static LLVMBasicBlockRef
905 get_end_bb (EmitContext *ctx, MonoBasicBlock *bb)
908 return ctx->bblocks [bb->block_num].end_bblock;
911 static LLVMBasicBlockRef
912 gen_bb (EmitContext *ctx, const char *prefix)
916 sprintf (bb_name, "%s%d", prefix, ++ ctx->ex_index);
917 return LLVMAppendBasicBlock (ctx->lmethod, bb_name);
923 * Return the target of the patch identified by TYPE and TARGET.
926 resolve_patch (MonoCompile *cfg, MonoJumpInfoType type, gconstpointer target)
930 memset (&ji, 0, sizeof (ji));
932 ji.data.target = target;
934 return mono_resolve_patch_target (cfg->method, cfg->domain, NULL, &ji, FALSE);
940 * Emit code to convert the LLVM value V to DTYPE.
943 convert_full (EmitContext *ctx, LLVMValueRef v, LLVMTypeRef dtype, gboolean is_unsigned)
945 LLVMTypeRef stype = LLVMTypeOf (v);
947 if (stype != dtype) {
948 gboolean ext = FALSE;
951 if (dtype == LLVMInt64Type () && (stype == LLVMInt32Type () || stype == LLVMInt16Type () || stype == LLVMInt8Type ()))
953 else if (dtype == LLVMInt32Type () && (stype == LLVMInt16Type () || stype == LLVMInt8Type ()))
955 else if (dtype == LLVMInt16Type () && (stype == LLVMInt8Type ()))
959 return is_unsigned ? LLVMBuildZExt (ctx->builder, v, dtype, "") : LLVMBuildSExt (ctx->builder, v, dtype, "");
961 if (dtype == LLVMDoubleType () && stype == LLVMFloatType ())
962 return LLVMBuildFPExt (ctx->builder, v, dtype, "");
965 if (stype == LLVMInt64Type () && (dtype == LLVMInt32Type () || dtype == LLVMInt16Type () || dtype == LLVMInt8Type ()))
966 return LLVMBuildTrunc (ctx->builder, v, dtype, "");
967 if (stype == LLVMInt32Type () && (dtype == LLVMInt16Type () || dtype == LLVMInt8Type ()))
968 return LLVMBuildTrunc (ctx->builder, v, dtype, "");
969 if (stype == LLVMInt16Type () && dtype == LLVMInt8Type ())
970 return LLVMBuildTrunc (ctx->builder, v, dtype, "");
971 if (stype == LLVMDoubleType () && dtype == LLVMFloatType ())
972 return LLVMBuildFPTrunc (ctx->builder, v, dtype, "");
974 if (LLVMGetTypeKind (stype) == LLVMPointerTypeKind && LLVMGetTypeKind (dtype) == LLVMPointerTypeKind)
975 return LLVMBuildBitCast (ctx->builder, v, dtype, "");
976 if (LLVMGetTypeKind (dtype) == LLVMPointerTypeKind)
977 return LLVMBuildIntToPtr (ctx->builder, v, dtype, "");
978 if (LLVMGetTypeKind (stype) == LLVMPointerTypeKind)
979 return LLVMBuildPtrToInt (ctx->builder, v, dtype, "");
981 if (mono_arch_is_soft_float ()) {
982 if (stype == LLVMInt32Type () && dtype == LLVMFloatType ())
983 return LLVMBuildBitCast (ctx->builder, v, dtype, "");
984 if (stype == LLVMInt32Type () && dtype == LLVMDoubleType ())
985 return LLVMBuildBitCast (ctx->builder, LLVMBuildZExt (ctx->builder, v, LLVMInt64Type (), ""), dtype, "");
988 if (LLVMGetTypeKind (stype) == LLVMVectorTypeKind && LLVMGetTypeKind (dtype) == LLVMVectorTypeKind)
989 return LLVMBuildBitCast (ctx->builder, v, dtype, "");
992 LLVMDumpValue (LLVMConstNull (dtype));
993 g_assert_not_reached ();
1001 convert (EmitContext *ctx, LLVMValueRef v, LLVMTypeRef dtype)
1003 return convert_full (ctx, v, dtype, FALSE);
1007 * emit_volatile_load:
1009 * If vreg is volatile, emit a load from its address.
1012 emit_volatile_load (EmitContext *ctx, int vreg)
1016 LLVMValueRef v = LLVMBuildLoad (ctx->builder, ctx->addresses [vreg], "");
1017 t = ctx->vreg_cli_types [vreg];
1018 if (t && !t->byref) {
1020 * Might have to zero extend since llvm doesn't have
1023 if (t->type == MONO_TYPE_U1 || t->type == MONO_TYPE_U2 || t->type == MONO_TYPE_CHAR || t->type == MONO_TYPE_BOOLEAN)
1024 v = LLVMBuildZExt (ctx->builder, v, LLVMInt32Type (), "");
1025 else if (t->type == MONO_TYPE_U8)
1026 v = LLVMBuildZExt (ctx->builder, v, LLVMInt64Type (), "");
1033 * emit_volatile_store:
1035 * If VREG is volatile, emit a store from its value to its address.
1038 emit_volatile_store (EmitContext *ctx, int vreg)
1040 MonoInst *var = get_vreg_to_inst (ctx->cfg, vreg);
1042 if (var && var->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT)) {
1043 g_assert (ctx->addresses [vreg]);
1044 LLVMBuildStore (ctx->builder, convert (ctx, ctx->values [vreg], type_to_llvm_type (ctx, var->inst_vtype)), ctx->addresses [vreg]);
1050 * Maps parameter indexes in the original signature to parameter indexes
1051 * in the LLVM signature.
1054 /* The indexes of various special arguments in the LLVM signature */
1055 int vret_arg_pindex, this_arg_pindex, rgctx_arg_pindex, imt_arg_pindex;
1059 * sig_to_llvm_sig_full:
1061 * Return the LLVM signature corresponding to the mono signature SIG using the
1062 * calling convention information in CINFO. Return parameter mapping information in SINFO.
1065 sig_to_llvm_sig_full (EmitContext *ctx, MonoMethodSignature *sig, LLVMCallInfo *cinfo,
1068 LLVMTypeRef ret_type;
1069 LLVMTypeRef *param_types = NULL;
1071 int i, j, pindex, vret_arg_pindex = 0;
1073 gboolean vretaddr = FALSE;
1076 memset (sinfo, 0, sizeof (LLVMSigInfo));
1078 ret_type = type_to_llvm_type (ctx, sig->ret);
1079 CHECK_FAILURE (ctx);
1081 if (cinfo && cinfo->ret.storage == LLVMArgVtypeInReg) {
1082 /* LLVM models this by returning an aggregate value */
1083 if (cinfo->ret.pair_storage [0] == LLVMArgInIReg && cinfo->ret.pair_storage [1] == LLVMArgNone) {
1084 LLVMTypeRef members [2];
1086 members [0] = IntPtrType ();
1087 ret_type = LLVMStructType (members, 1, FALSE);
1089 g_assert_not_reached ();
1091 } else if (cinfo && mini_type_is_vtype (ctx->cfg, sig->ret)) {
1092 g_assert (cinfo->ret.storage == LLVMArgVtypeRetAddr);
1094 ret_type = LLVMVoidType ();
1097 pindexes = g_new0 (int, sig->param_count);
1098 param_types = g_new0 (LLVMTypeRef, (sig->param_count * 2) + 3);
1100 if (cinfo && cinfo->rgctx_arg) {
1102 sinfo->rgctx_arg_pindex = pindex;
1103 param_types [pindex] = ctx->lmodule->ptr_type;
1106 if (cinfo && cinfo->imt_arg) {
1108 sinfo->imt_arg_pindex = pindex;
1109 param_types [pindex] = ctx->lmodule->ptr_type;
1113 /* Compute the index in the LLVM signature where the vret arg needs to be passed */
1114 vret_arg_pindex = pindex;
1115 if (cinfo->vret_arg_index == 1) {
1116 /* Add the slots consumed by the first argument */
1117 LLVMArgInfo *ainfo = &cinfo->args [0];
1118 switch (ainfo->storage) {
1119 case LLVMArgVtypeInReg:
1120 for (j = 0; j < 2; ++j) {
1121 if (ainfo->pair_storage [j] == LLVMArgInIReg)
1131 sinfo->vret_arg_pindex = vret_arg_pindex;
1134 if (vretaddr && vret_arg_pindex == pindex)
1135 param_types [pindex ++] = IntPtrType ();
1138 sinfo->this_arg_pindex = pindex;
1139 param_types [pindex ++] = ThisType ();
1141 if (vretaddr && vret_arg_pindex == pindex)
1142 param_types [pindex ++] = IntPtrType ();
1143 for (i = 0; i < sig->param_count; ++i) {
1144 if (vretaddr && vret_arg_pindex == pindex)
1145 param_types [pindex ++] = IntPtrType ();
1146 pindexes [i] = pindex;
1147 if (cinfo && cinfo->args [i + sig->hasthis].storage == LLVMArgVtypeInReg) {
1148 for (j = 0; j < 2; ++j) {
1149 switch (cinfo->args [i + sig->hasthis].pair_storage [j]) {
1151 param_types [pindex ++] = LLVMIntType (sizeof (gpointer) * 8);
1156 g_assert_not_reached ();
1159 } else if (cinfo && cinfo->args [i + sig->hasthis].storage == LLVMArgVtypeByVal) {
1160 param_types [pindex] = type_to_llvm_arg_type (ctx, sig->params [i]);
1161 CHECK_FAILURE (ctx);
1162 param_types [pindex] = LLVMPointerType (param_types [pindex], 0);
1165 param_types [pindex ++] = type_to_llvm_arg_type (ctx, sig->params [i]);
1168 if (vretaddr && vret_arg_pindex == pindex)
1169 param_types [pindex ++] = IntPtrType ();
1171 CHECK_FAILURE (ctx);
1173 res = LLVMFunctionType (ret_type, param_types, pindex, FALSE);
1174 g_free (param_types);
1177 sinfo->pindexes = pindexes;
1185 g_free (param_types);
1191 sig_to_llvm_sig (EmitContext *ctx, MonoMethodSignature *sig)
1193 return sig_to_llvm_sig_full (ctx, sig, NULL, NULL);
1197 * LLVMFunctionType1:
1199 * Create an LLVM function type from the arguments.
1201 static G_GNUC_UNUSED LLVMTypeRef
1202 LLVMFunctionType1(LLVMTypeRef ReturnType,
1203 LLVMTypeRef ParamType1,
1206 LLVMTypeRef param_types [1];
1208 param_types [0] = ParamType1;
1210 return LLVMFunctionType (ReturnType, param_types, 1, IsVarArg);
1214 * LLVMFunctionType2:
1216 * Create an LLVM function type from the arguments.
1218 static G_GNUC_UNUSED LLVMTypeRef
1219 LLVMFunctionType2(LLVMTypeRef ReturnType,
1220 LLVMTypeRef ParamType1,
1221 LLVMTypeRef ParamType2,
1224 LLVMTypeRef param_types [2];
1226 param_types [0] = ParamType1;
1227 param_types [1] = ParamType2;
1229 return LLVMFunctionType (ReturnType, param_types, 2, IsVarArg);
1233 * LLVMFunctionType3:
1235 * Create an LLVM function type from the arguments.
1237 static G_GNUC_UNUSED LLVMTypeRef
1238 LLVMFunctionType3(LLVMTypeRef ReturnType,
1239 LLVMTypeRef ParamType1,
1240 LLVMTypeRef ParamType2,
1241 LLVMTypeRef ParamType3,
1244 LLVMTypeRef param_types [3];
1246 param_types [0] = ParamType1;
1247 param_types [1] = ParamType2;
1248 param_types [2] = ParamType3;
1250 return LLVMFunctionType (ReturnType, param_types, 3, IsVarArg);
1256 * Create an LLVM builder and remember it so it can be freed later.
1258 static LLVMBuilderRef
1259 create_builder (EmitContext *ctx)
1261 LLVMBuilderRef builder = LLVMCreateBuilder ();
1263 ctx->builders = g_slist_prepend_mempool (ctx->cfg->mempool, ctx->builders, builder);
1269 get_plt_entry (EmitContext *ctx, LLVMTypeRef llvm_sig, MonoJumpInfoType type, gconstpointer data)
1271 char *callee_name = mono_aot_get_plt_symbol (type, data);
1272 LLVMValueRef callee;
1277 if (ctx->cfg->compile_aot)
1278 /* Add a patch so referenced wrappers can be compiled in full aot mode */
1279 mono_add_patch_info (ctx->cfg, 0, type, data);
1282 callee = g_hash_table_lookup (ctx->lmodule->plt_entries, callee_name);
1284 callee = LLVMAddFunction (ctx->module, callee_name, llvm_sig);
1286 LLVMSetVisibility (callee, LLVMHiddenVisibility);
1288 g_hash_table_insert (ctx->lmodule->plt_entries, (char*)callee_name, callee);
1295 get_handler_clause (MonoCompile *cfg, MonoBasicBlock *bb)
1297 MonoMethodHeader *header = cfg->header;
1298 MonoExceptionClause *clause;
1302 if (bb->region != -1 && MONO_BBLOCK_IS_IN_REGION (bb, MONO_REGION_TRY))
1303 return (bb->region >> 8) - 1;
1306 for (i = 0; i < header->num_clauses; ++i) {
1307 clause = &header->clauses [i];
1309 if (MONO_OFFSET_IN_CLAUSE (clause, bb->real_offset) && clause->flags == MONO_EXCEPTION_CLAUSE_NONE)
1317 set_metadata_flag (LLVMValueRef v, const char *flag_name)
1319 LLVMValueRef md_arg;
1322 md_kind = LLVMGetMDKindID (flag_name, strlen (flag_name));
1323 md_arg = LLVMMDString ("mono", 4);
1324 LLVMSetMetadata (v, md_kind, LLVMMDNode (&md_arg, 1));
1328 set_invariant_load_flag (LLVMValueRef v)
1330 LLVMValueRef md_arg;
1332 const char *flag_name;
1334 // FIXME: Cache this
1335 flag_name = "invariant.load";
1336 md_kind = LLVMGetMDKindID (flag_name, strlen (flag_name));
1337 md_arg = LLVMMDString ("<index>", strlen ("<index>"));
1338 LLVMSetMetadata (v, md_kind, LLVMMDNode (&md_arg, 1));
1344 * Emit an LLVM call or invoke instruction depending on whenever the call is inside
1348 emit_call (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, LLVMValueRef callee, LLVMValueRef *args, int pindex)
1350 MonoCompile *cfg = ctx->cfg;
1352 LLVMBuilderRef builder = *builder_ref;
1355 clause_index = get_handler_clause (cfg, bb);
1357 if (clause_index != -1) {
1358 MonoMethodHeader *header = cfg->header;
1359 MonoExceptionClause *ec = &header->clauses [clause_index];
1360 MonoBasicBlock *tblock;
1361 LLVMBasicBlockRef ex_bb, noex_bb;
1364 * Have to use an invoke instead of a call, branching to the
1365 * handler bblock of the clause containing this bblock.
1368 g_assert (ec->flags == MONO_EXCEPTION_CLAUSE_NONE || ec->flags == MONO_EXCEPTION_CLAUSE_FINALLY);
1370 tblock = cfg->cil_offset_to_bb [ec->handler_offset];
1373 ctx->bblocks [tblock->block_num].invoke_target = TRUE;
1375 ex_bb = get_bb (ctx, tblock);
1377 noex_bb = gen_bb (ctx, "NOEX_BB");
1380 lcall = LLVMBuildInvoke (builder, callee, args, pindex, noex_bb, ex_bb, "");
1382 builder = ctx->builder = create_builder (ctx);
1383 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
1385 ctx->bblocks [bb->block_num].end_bblock = noex_bb;
1387 lcall = LLVMBuildCall (builder, callee, args, pindex, "");
1388 ctx->builder = builder;
1391 *builder_ref = ctx->builder;
1397 emit_load (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, int size, LLVMValueRef addr, const char *name, gboolean is_faulting)
1399 const char *intrins_name;
1400 LLVMValueRef args [16], res;
1401 LLVMTypeRef addr_type;
1403 if (is_faulting && bb->region != -1) {
1405 * We handle loads which can fault by calling a mono specific intrinsic
1406 * using an invoke, so they are handled properly inside try blocks.
1407 * We can't use this outside clauses, since LLVM optimizes intrinsics which
1408 * are marked with IntrReadArgMem.
1412 intrins_name = "llvm.mono.load.i8.p0i8";
1415 intrins_name = "llvm.mono.load.i16.p0i16";
1418 intrins_name = "llvm.mono.load.i32.p0i32";
1421 intrins_name = "llvm.mono.load.i64.p0i64";
1424 g_assert_not_reached ();
1427 addr_type = LLVMTypeOf (addr);
1428 if (addr_type == LLVMPointerType (LLVMDoubleType (), 0) || addr_type == LLVMPointerType (LLVMFloatType (), 0))
1429 addr = LLVMBuildBitCast (*builder_ref, addr, LLVMPointerType (LLVMIntType (size * 8), 0), "");
1432 args [1] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
1433 args [2] = LLVMConstInt (LLVMInt1Type (), TRUE, FALSE);
1434 res = emit_call (ctx, bb, builder_ref, LLVMGetNamedFunction (ctx->module, intrins_name), args, 3);
1436 if (addr_type == LLVMPointerType (LLVMDoubleType (), 0))
1437 res = LLVMBuildBitCast (*builder_ref, res, LLVMDoubleType (), "");
1438 else if (addr_type == LLVMPointerType (LLVMFloatType (), 0))
1439 res = LLVMBuildBitCast (*builder_ref, res, LLVMFloatType (), "");
1446 * We emit volatile loads for loads which can fault, because otherwise
1447 * LLVM will generate invalid code when encountering a load from a
1450 res = mono_llvm_build_load (*builder_ref, addr, name, is_faulting);
1452 /* Mark it with a custom metadata */
1455 set_metadata_flag (res, "mono.faulting.load");
1463 emit_store (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, int size, LLVMValueRef value, LLVMValueRef addr, gboolean is_faulting)
1465 const char *intrins_name;
1466 LLVMValueRef args [16];
1468 if (is_faulting && bb->region != -1) {
1471 intrins_name = "llvm.mono.store.i8.p0i8";
1474 intrins_name = "llvm.mono.store.i16.p0i16";
1477 intrins_name = "llvm.mono.store.i32.p0i32";
1480 intrins_name = "llvm.mono.store.i64.p0i64";
1483 g_assert_not_reached ();
1486 if (LLVMTypeOf (value) == LLVMDoubleType () || LLVMTypeOf (value) == LLVMFloatType ()) {
1487 value = LLVMBuildBitCast (*builder_ref, value, LLVMIntType (size * 8), "");
1488 addr = LLVMBuildBitCast (*builder_ref, addr, LLVMPointerType (LLVMIntType (size * 8), 0), "");
1493 args [2] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
1494 args [3] = LLVMConstInt (LLVMInt1Type (), TRUE, FALSE);
1495 emit_call (ctx, bb, builder_ref, LLVMGetNamedFunction (ctx->module, intrins_name), args, 4);
1497 LLVMBuildStore (*builder_ref, value, addr);
1502 * emit_cond_system_exception:
1504 * Emit code to throw the exception EXC_TYPE if the condition CMP is false.
1505 * Might set the ctx exception.
1508 emit_cond_system_exception (EmitContext *ctx, MonoBasicBlock *bb, const char *exc_type, LLVMValueRef cmp)
1510 LLVMBasicBlockRef ex_bb, noex_bb;
1511 LLVMBuilderRef builder;
1512 MonoClass *exc_class;
1513 LLVMValueRef args [2];
1515 ex_bb = gen_bb (ctx, "EX_BB");
1516 noex_bb = gen_bb (ctx, "NOEX_BB");
1518 LLVMBuildCondBr (ctx->builder, cmp, ex_bb, noex_bb);
1520 exc_class = mono_class_from_name (mono_get_corlib (), "System", exc_type);
1521 g_assert (exc_class);
1523 /* Emit exception throwing code */
1524 builder = create_builder (ctx);
1525 LLVMPositionBuilderAtEnd (builder, ex_bb);
1527 if (!ctx->lmodule->throw_corlib_exception) {
1528 LLVMValueRef callee;
1530 const char *icall_name;
1532 MonoMethodSignature *throw_sig = mono_metadata_signature_alloc (mono_get_corlib (), 2);
1533 throw_sig->ret = &mono_get_void_class ()->byval_arg;
1534 throw_sig->params [0] = &mono_get_int32_class ()->byval_arg;
1535 icall_name = "llvm_throw_corlib_exception_abs_trampoline";
1536 /* This will become i8* */
1537 throw_sig->params [1] = &mono_get_byte_class ()->this_arg;
1538 sig = sig_to_llvm_sig (ctx, throw_sig);
1540 if (ctx->cfg->compile_aot) {
1541 callee = get_plt_entry (ctx, sig, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
1543 callee = LLVMAddFunction (ctx->module, "llvm_throw_corlib_exception_trampoline", sig_to_llvm_sig (ctx, throw_sig));
1546 * Differences between the LLVM/non-LLVM throw corlib exception trampoline:
1547 * - On x86, LLVM generated code doesn't push the arguments
1548 * - The trampoline takes the throw address as an arguments, not a pc offset.
1550 LLVMAddGlobalMapping (ctx->lmodule->ee, callee, resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name));
1553 mono_memory_barrier ();
1554 ctx->lmodule->throw_corlib_exception = callee;
1557 if (IS_TARGET_X86 || IS_TARGET_AMD64)
1558 args [0] = LLVMConstInt (LLVMInt32Type (), exc_class->type_token - MONO_TOKEN_TYPE_DEF, FALSE);
1560 args [0] = LLVMConstInt (LLVMInt32Type (), exc_class->type_token, FALSE);
1563 * The LLVM mono branch contains changes so a block address can be passed as an
1564 * argument to a call.
1566 args [1] = LLVMBlockAddress (ctx->lmethod, ex_bb);
1567 emit_call (ctx, bb, &builder, ctx->lmodule->throw_corlib_exception, args, 2);
1569 LLVMBuildUnreachable (builder);
1571 ctx->builder = create_builder (ctx);
1572 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
1574 ctx->bblocks [bb->block_num].end_bblock = noex_bb;
1581 * emit_reg_to_vtype:
1583 * Emit code to store the vtype in the registers REGS to the address ADDRESS.
1586 emit_reg_to_vtype (EmitContext *ctx, LLVMBuilderRef builder, MonoType *t, LLVMValueRef address, LLVMArgInfo *ainfo, LLVMValueRef *regs)
1590 size = get_vtype_size (t);
1592 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (t))) {
1593 address = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (LLVMInt8Type (), 0), "");
1596 for (j = 0; j < 2; ++j) {
1597 LLVMValueRef index [2], addr;
1598 int part_size = size > sizeof (gpointer) ? sizeof (gpointer) : size;
1599 LLVMTypeRef part_type;
1601 if (ainfo->pair_storage [j] == LLVMArgNone)
1604 part_type = LLVMIntType (part_size * 8);
1605 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (t))) {
1606 index [0] = LLVMConstInt (LLVMInt32Type (), j * sizeof (gpointer), FALSE);
1607 addr = LLVMBuildGEP (builder, address, index, 1, "");
1609 index [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
1610 index [1] = LLVMConstInt (LLVMInt32Type (), j * sizeof (gpointer), FALSE);
1611 addr = LLVMBuildGEP (builder, address, index, 2, "");
1613 switch (ainfo->pair_storage [j]) {
1615 LLVMBuildStore (builder, convert (ctx, regs [j], part_type), LLVMBuildBitCast (ctx->builder, addr, LLVMPointerType (part_type, 0), ""));
1620 g_assert_not_reached ();
1623 size -= sizeof (gpointer);
1628 * emit_vtype_to_reg:
1630 * Emit code to load a vtype at address ADDRESS into registers. Store the registers
1631 * into REGS, and the number of registers into NREGS.
1634 emit_vtype_to_reg (EmitContext *ctx, LLVMBuilderRef builder, MonoType *t, LLVMValueRef address, LLVMArgInfo *ainfo, LLVMValueRef *regs, guint32 *nregs)
1639 size = get_vtype_size (t);
1641 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (t))) {
1642 address = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (LLVMInt8Type (), 0), "");
1645 for (j = 0; j < 2; ++j) {
1646 LLVMValueRef index [2], addr;
1647 int partsize = size > sizeof (gpointer) ? sizeof (gpointer) : size;
1649 if (ainfo->pair_storage [j] == LLVMArgNone)
1652 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (t))) {
1653 index [0] = LLVMConstInt (LLVMInt32Type (), j * sizeof (gpointer), FALSE);
1654 addr = LLVMBuildGEP (builder, address, index, 1, "");
1656 index [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
1657 index [1] = LLVMConstInt (LLVMInt32Type (), j * sizeof (gpointer), FALSE);
1658 addr = LLVMBuildGEP (builder, address, index, 2, "");
1660 switch (ainfo->pair_storage [j]) {
1662 regs [pindex ++] = convert (ctx, LLVMBuildLoad (builder, LLVMBuildBitCast (ctx->builder, addr, LLVMPointerType (LLVMIntType (partsize * 8), 0), ""), ""), IntPtrType ());
1667 g_assert_not_reached ();
1669 size -= sizeof (gpointer);
1676 build_alloca_llvm_type (EmitContext *ctx, LLVMTypeRef t, int align)
1679 * Have to place all alloca's at the end of the entry bb, since otherwise they would
1680 * get executed every time control reaches them.
1682 LLVMPositionBuilder (ctx->alloca_builder, get_bb (ctx, ctx->cfg->bb_entry), ctx->last_alloca);
1684 ctx->last_alloca = mono_llvm_build_alloca (ctx->alloca_builder, t, NULL, align, "");
1685 return ctx->last_alloca;
1689 build_alloca (EmitContext *ctx, MonoType *t)
1691 MonoClass *k = mono_class_from_mono_type (t);
1694 if (MONO_CLASS_IS_SIMD (ctx->cfg, k))
1697 align = mono_class_min_align (k);
1699 /* Sometimes align is not a power of 2 */
1700 while (mono_is_power_of_two (align) == -1)
1703 return build_alloca_llvm_type (ctx, type_to_llvm_type (ctx, t), align);
1707 * Put the global into the 'llvm.used' array to prevent it from being optimized away.
1710 mark_as_used (MonoLLVMModule *lmodule, LLVMValueRef global)
1713 lmodule->used = g_ptr_array_sized_new (16);
1714 g_ptr_array_add (lmodule->used, global);
1718 emit_llvm_used (MonoLLVMModule *lmodule)
1720 LLVMModuleRef module = lmodule->module;
1721 LLVMTypeRef used_type;
1722 LLVMValueRef used, *used_elem;
1728 used_type = LLVMArrayType (LLVMPointerType (LLVMInt8Type (), 0), lmodule->used->len);
1729 used = LLVMAddGlobal (module, used_type, "llvm.used");
1730 used_elem = g_new0 (LLVMValueRef, lmodule->used->len);
1731 for (i = 0; i < lmodule->used->len; ++i)
1732 used_elem [i] = LLVMConstBitCast (g_ptr_array_index (lmodule->used, i), LLVMPointerType (LLVMInt8Type (), 0));
1733 LLVMSetInitializer (used, LLVMConstArray (LLVMPointerType (LLVMInt8Type (), 0), used_elem, lmodule->used->len));
1734 LLVMSetLinkage (used, LLVMAppendingLinkage);
1735 LLVMSetSection (used, "llvm.metadata");
1741 * Emit code to load/convert arguments.
1744 emit_entry_bb (EmitContext *ctx, LLVMBuilderRef builder)
1747 MonoCompile *cfg = ctx->cfg;
1748 MonoMethodSignature *sig = ctx->sig;
1749 LLVMCallInfo *linfo = ctx->linfo;
1752 ctx->alloca_builder = create_builder (ctx);
1755 * Handle indirect/volatile variables by allocating memory for them
1756 * using 'alloca', and storing their address in a temporary.
1758 for (i = 0; i < cfg->num_varinfo; ++i) {
1759 MonoInst *var = cfg->varinfo [i];
1762 if (var->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT) || mini_type_is_vtype (cfg, var->inst_vtype)) {
1763 vtype = type_to_llvm_type (ctx, var->inst_vtype);
1764 CHECK_FAILURE (ctx);
1765 /* Could be already created by an OP_VPHI */
1766 if (!ctx->addresses [var->dreg])
1767 ctx->addresses [var->dreg] = build_alloca (ctx, var->inst_vtype);
1768 ctx->vreg_cli_types [var->dreg] = var->inst_vtype;
1772 for (i = 0; i < sig->param_count; ++i) {
1773 LLVMArgInfo *ainfo = &linfo->args [i + sig->hasthis];
1774 int reg = cfg->args [i + sig->hasthis]->dreg;
1776 if (ainfo->storage == LLVMArgVtypeInReg) {
1777 LLVMValueRef regs [2];
1780 * Emit code to save the argument from the registers to
1781 * the real argument.
1783 pindex = ctx->pindexes [i];
1784 regs [0] = LLVMGetParam (ctx->lmethod, pindex);
1785 if (ainfo->pair_storage [1] != LLVMArgNone)
1786 regs [1] = LLVMGetParam (ctx->lmethod, pindex + 1);
1790 ctx->addresses [reg] = build_alloca (ctx, sig->params [i]);
1792 emit_reg_to_vtype (ctx, builder, sig->params [i], ctx->addresses [reg], ainfo, regs);
1794 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (sig->params [i]))) {
1795 /* Treat these as normal values */
1796 ctx->values [reg] = LLVMBuildLoad (builder, ctx->addresses [reg], "");
1798 } else if (ainfo->storage == LLVMArgVtypeByVal) {
1799 ctx->addresses [reg] = LLVMGetParam (ctx->lmethod, ctx->pindexes [i]);
1801 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (sig->params [i]))) {
1802 /* Treat these as normal values */
1803 ctx->values [reg] = LLVMBuildLoad (builder, ctx->addresses [reg], "");
1806 ctx->values [reg] = convert (ctx, ctx->values [reg], llvm_type_to_stack_type (type_to_llvm_type (ctx, sig->params [i])));
1811 emit_volatile_store (ctx, cfg->vret_addr->dreg);
1813 emit_volatile_store (ctx, cfg->args [0]->dreg);
1814 for (i = 0; i < sig->param_count; ++i)
1815 if (!mini_type_is_vtype (cfg, sig->params [i]))
1816 emit_volatile_store (ctx, cfg->args [i + sig->hasthis]->dreg);
1818 if (sig->hasthis && !cfg->rgctx_var && cfg->generic_sharing_context) {
1819 LLVMValueRef this_alloc;
1822 * The exception handling code needs the location where the this argument was
1823 * stored for gshared methods. We create a separate alloca to hold it, and mark it
1824 * with the "mono.this" custom metadata to tell llvm that it needs to save its
1825 * location into the LSDA.
1827 this_alloc = mono_llvm_build_alloca (builder, ThisType (), LLVMConstInt (LLVMInt32Type (), 1, FALSE), 0, "");
1828 /* This volatile store will keep the alloca alive */
1829 mono_llvm_build_store (builder, ctx->values [cfg->args [0]->dreg], this_alloc, TRUE);
1831 set_metadata_flag (this_alloc, "mono.this");
1834 if (cfg->rgctx_var) {
1835 LLVMValueRef rgctx_alloc, store;
1838 * We handle the rgctx arg similarly to the this pointer.
1840 g_assert (ctx->addresses [cfg->rgctx_var->dreg]);
1841 rgctx_alloc = ctx->addresses [cfg->rgctx_var->dreg];
1842 /* This volatile store will keep the alloca alive */
1843 store = mono_llvm_build_store (builder, convert (ctx, ctx->rgctx_arg, IntPtrType ()), rgctx_alloc, TRUE);
1845 set_metadata_flag (rgctx_alloc, "mono.this");
1849 * For finally clauses, create an indicator variable telling OP_ENDFINALLY whenever
1850 * it needs to continue normally, or return back to the exception handling system.
1852 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
1853 if (bb->region != -1 && (bb->flags & BB_EXCEPTION_HANDLER))
1854 g_hash_table_insert (ctx->region_to_handler, GUINT_TO_POINTER (mono_get_block_region_notry (cfg, bb->region)), bb);
1855 if (bb->region != -1 && (bb->flags & BB_EXCEPTION_HANDLER) && bb->in_scount == 0) {
1859 sprintf (name, "finally_ind_bb%d", bb->block_num);
1860 val = LLVMBuildAlloca (builder, LLVMInt32Type (), name);
1861 LLVMBuildStore (builder, LLVMConstInt (LLVMInt32Type (), 0, FALSE), val);
1863 ctx->bblocks [bb->block_num].finally_ind = val;
1866 * Create a new bblock which CALL_HANDLER can branch to, because branching to the
1867 * LLVM bblock containing the call to llvm.eh.selector causes problems for the
1868 * LLVM optimizer passes.
1870 sprintf (name, "BB_%d_CALL_HANDLER_TARGET", bb->block_num);
1871 ctx->bblocks [bb->block_num].call_handler_target_bb = LLVMAppendBasicBlock (ctx->lmethod, name);
1879 /* Have to export this for AOT */
1881 mono_personality (void);
1884 mono_personality (void)
1887 g_assert_not_reached ();
1891 process_call (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, MonoInst *ins)
1893 MonoCompile *cfg = ctx->cfg;
1894 LLVMModuleRef module = ctx->module;
1895 LLVMValueRef *values = ctx->values;
1896 LLVMValueRef *addresses = ctx->addresses;
1897 MonoCallInst *call = (MonoCallInst*)ins;
1898 MonoMethodSignature *sig = call->signature;
1899 LLVMValueRef callee = NULL, lcall;
1901 LLVMCallInfo *cinfo;
1905 LLVMTypeRef llvm_sig;
1907 gboolean virtual, calli;
1908 LLVMBuilderRef builder = *builder_ref;
1911 if (call->signature->call_convention != MONO_CALL_DEFAULT)
1912 LLVM_FAILURE (ctx, "non-default callconv");
1914 cinfo = call->cinfo;
1915 if (call->rgctx_arg_reg)
1916 cinfo->rgctx_arg = TRUE;
1917 if (call->imt_arg_reg)
1918 cinfo->imt_arg = TRUE;
1920 vretaddr = cinfo && cinfo->ret.storage == LLVMArgVtypeRetAddr;
1922 llvm_sig = sig_to_llvm_sig_full (ctx, sig, cinfo, &sinfo);
1923 CHECK_FAILURE (ctx);
1925 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);
1926 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);
1928 /* FIXME: Avoid creating duplicate methods */
1930 if (ins->flags & MONO_INST_HAS_METHOD) {
1934 if (cfg->compile_aot) {
1935 callee = get_plt_entry (ctx, llvm_sig, MONO_PATCH_INFO_METHOD, call->method);
1937 LLVM_FAILURE (ctx, "can't encode patch");
1939 callee = LLVMAddFunction (module, "", llvm_sig);
1942 mono_create_jit_trampoline_in_domain (mono_domain_get (),
1944 LLVMAddGlobalMapping (ctx->lmodule->ee, callee, target);
1948 if (call->method && strstr (call->method->klass->name, "AsyncVoidMethodBuilder"))
1949 /* LLVM miscompiles async methods */
1950 LLVM_FAILURE (ctx, "#13734");
1953 MonoJitICallInfo *info = mono_find_jit_icall_by_addr (call->fptr);
1959 memset (&ji, 0, sizeof (ji));
1960 ji.type = MONO_PATCH_INFO_JIT_ICALL_ADDR;
1961 ji.data.target = info->name;
1963 target = mono_resolve_patch_target (cfg->method, cfg->domain, NULL, &ji, FALSE);
1965 if (cfg->compile_aot) {
1966 callee = get_plt_entry (ctx, llvm_sig, MONO_PATCH_INFO_INTERNAL_METHOD, (char*)info->name);
1968 LLVM_FAILURE (ctx, "can't encode patch");
1970 callee = LLVMAddFunction (module, "", llvm_sig);
1971 target = (gpointer)mono_icall_get_wrapper (info);
1972 LLVMAddGlobalMapping (ctx->lmodule->ee, callee, target);
1975 if (cfg->compile_aot) {
1977 if (cfg->abs_patches) {
1978 MonoJumpInfo *abs_ji = g_hash_table_lookup (cfg->abs_patches, call->fptr);
1980 callee = get_plt_entry (ctx, llvm_sig, abs_ji->type, abs_ji->data.target);
1982 LLVM_FAILURE (ctx, "can't encode patch");
1986 LLVM_FAILURE (ctx, "aot");
1988 callee = LLVMAddFunction (module, "", llvm_sig);
1990 if (cfg->abs_patches) {
1991 MonoJumpInfo *abs_ji = g_hash_table_lookup (cfg->abs_patches, call->fptr);
1994 * FIXME: Some trampolines might have
1995 * their own calling convention on some platforms.
1997 #ifndef TARGET_AMD64
1998 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)
1999 LLVM_FAILURE (ctx, "trampoline with own cconv");
2001 target = mono_resolve_patch_target (cfg->method, cfg->domain, NULL, abs_ji, FALSE);
2002 LLVMAddGlobalMapping (ctx->lmodule->ee, callee, target);
2006 LLVMAddGlobalMapping (ctx->lmodule->ee, callee, (gpointer)call->fptr);
2012 int size = sizeof (gpointer);
2015 g_assert (ins->inst_offset % size == 0);
2016 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
2018 callee = convert (ctx, LLVMBuildLoad (builder, LLVMBuildGEP (builder, convert (ctx, values [ins->inst_basereg], LLVMPointerType (LLVMPointerType (IntPtrType (), 0), 0)), &index, 1, ""), ""), LLVMPointerType (llvm_sig, 0));
2020 callee = convert (ctx, values [ins->sreg1], LLVMPointerType (llvm_sig, 0));
2022 if (ins->flags & MONO_INST_HAS_METHOD) {
2027 * Collect and convert arguments
2029 nargs = (sig->param_count * 2) + sig->hasthis + vretaddr + call->rgctx_reg + call->imt_arg_reg;
2030 len = sizeof (LLVMValueRef) * nargs;
2031 args = alloca (len);
2032 memset (args, 0, len);
2033 l = call->out_ireg_args;
2035 if (call->rgctx_arg_reg) {
2036 g_assert (values [call->rgctx_arg_reg]);
2037 g_assert (sinfo.rgctx_arg_pindex < nargs);
2039 * On ARM, the imt/rgctx argument is passed in a caller save register, but some of our trampolines etc. clobber it, leading to
2040 * problems is LLVM moves the arg assignment earlier. To work around this, save the argument into a stack slot and load
2041 * it using a volatile load.
2044 if (!ctx->imt_rgctx_loc)
2045 ctx->imt_rgctx_loc = build_alloca_llvm_type (ctx, ctx->lmodule->ptr_type, sizeof (gpointer));
2046 LLVMBuildStore (builder, convert (ctx, ctx->values [call->rgctx_arg_reg], ctx->lmodule->ptr_type), ctx->imt_rgctx_loc);
2047 args [sinfo.rgctx_arg_pindex] = mono_llvm_build_load (builder, ctx->imt_rgctx_loc, "", TRUE);
2049 args [sinfo.rgctx_arg_pindex] = convert (ctx, values [call->rgctx_arg_reg], ctx->lmodule->ptr_type);
2052 if (call->imt_arg_reg) {
2053 g_assert (values [call->imt_arg_reg]);
2054 g_assert (sinfo.imt_arg_pindex < nargs);
2056 if (!ctx->imt_rgctx_loc)
2057 ctx->imt_rgctx_loc = build_alloca_llvm_type (ctx, ctx->lmodule->ptr_type, sizeof (gpointer));
2058 LLVMBuildStore (builder, convert (ctx, ctx->values [call->imt_arg_reg], ctx->lmodule->ptr_type), ctx->imt_rgctx_loc);
2059 args [sinfo.imt_arg_pindex] = mono_llvm_build_load (builder, ctx->imt_rgctx_loc, "", TRUE);
2061 args [sinfo.imt_arg_pindex] = convert (ctx, values [call->imt_arg_reg], ctx->lmodule->ptr_type);
2066 if (!addresses [call->inst.dreg])
2067 addresses [call->inst.dreg] = build_alloca (ctx, sig->ret);
2068 g_assert (sinfo.vret_arg_pindex < nargs);
2069 args [sinfo.vret_arg_pindex] = LLVMBuildPtrToInt (builder, addresses [call->inst.dreg], IntPtrType (), "");
2072 for (i = 0; i < sig->param_count + sig->hasthis; ++i) {
2075 LLVMArgInfo *ainfo = call->cinfo ? &call->cinfo->args [i] : NULL;
2079 pindex = sinfo.this_arg_pindex;
2081 pindex = sinfo.pindexes [i - 1];
2083 pindex = sinfo.pindexes [i];
2086 regpair = (guint32)(gssize)(l->data);
2087 reg = regpair & 0xffffff;
2088 args [pindex] = values [reg];
2089 if (ainfo->storage == LLVMArgVtypeInReg) {
2091 LLVMValueRef regs [2];
2096 g_assert (addresses [reg]);
2098 emit_vtype_to_reg (ctx, builder, sig->params [i - sig->hasthis], addresses [reg], ainfo, regs, &nregs);
2099 for (j = 0; j < nregs; ++j)
2100 args [pindex ++] = regs [j];
2103 // FIXME: Get rid of the VMOVE
2104 } else if (ainfo->storage == LLVMArgVtypeByVal) {
2105 g_assert (addresses [reg]);
2106 args [pindex] = addresses [reg];
2108 g_assert (args [pindex]);
2109 if (i == 0 && sig->hasthis)
2110 args [pindex] = convert (ctx, args [pindex], ThisType ());
2112 args [pindex] = convert (ctx, args [pindex], type_to_llvm_arg_type (ctx, sig->params [i - sig->hasthis]));
2118 // FIXME: Align call sites
2124 lcall = emit_call (ctx, bb, &builder, callee, args, LLVMCountParamTypes (llvm_sig));
2127 * Modify cconv and parameter attributes to pass rgctx/imt correctly.
2129 #if defined(MONO_ARCH_IMT_REG) && defined(MONO_ARCH_RGCTX_REG)
2130 g_assert (MONO_ARCH_IMT_REG == MONO_ARCH_RGCTX_REG);
2132 /* The two can't be used together, so use only one LLVM calling conv to pass them */
2133 g_assert (!(call->rgctx_arg_reg && call->imt_arg_reg));
2135 LLVMSetInstructionCallConv (lcall, LLVMMono1CallConv);
2137 if (call->rgctx_arg_reg)
2138 LLVMAddInstrAttribute (lcall, 1 + sinfo.rgctx_arg_pindex, LLVMInRegAttribute);
2139 if (call->imt_arg_reg)
2140 LLVMAddInstrAttribute (lcall, 1 + sinfo.imt_arg_pindex, LLVMInRegAttribute);
2142 /* Add byval attributes if needed */
2143 for (i = 0; i < sig->param_count; ++i) {
2144 LLVMArgInfo *ainfo = call->cinfo ? &call->cinfo->args [i + sig->hasthis] : NULL;
2146 if (ainfo && ainfo->storage == LLVMArgVtypeByVal) {
2147 LLVMAddInstrAttribute (lcall, 1 + sinfo.pindexes [i], LLVMByValAttribute);
2152 * Convert the result
2154 if (cinfo && cinfo->ret.storage == LLVMArgVtypeInReg) {
2155 LLVMValueRef regs [2];
2157 if (!addresses [ins->dreg])
2158 addresses [ins->dreg] = build_alloca (ctx, sig->ret);
2160 regs [0] = LLVMBuildExtractValue (builder, lcall, 0, "");
2161 if (cinfo->ret.pair_storage [1] != LLVMArgNone)
2162 regs [1] = LLVMBuildExtractValue (builder, lcall, 1, "");
2164 emit_reg_to_vtype (ctx, builder, sig->ret, addresses [ins->dreg], &cinfo->ret, regs);
2165 } else if (sig->ret->type != MONO_TYPE_VOID && !vretaddr) {
2166 /* If the method returns an unsigned value, need to zext it */
2168 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));
2171 *builder_ref = ctx->builder;
2173 g_free (sinfo.pindexes);
2181 process_bb (EmitContext *ctx, MonoBasicBlock *bb)
2183 MonoCompile *cfg = ctx->cfg;
2184 MonoMethodSignature *sig = ctx->sig;
2185 LLVMValueRef method = ctx->lmethod;
2186 LLVMValueRef *values = ctx->values;
2187 LLVMValueRef *addresses = ctx->addresses;
2189 LLVMCallInfo *linfo = ctx->linfo;
2190 LLVMModuleRef module = ctx->module;
2191 BBInfo *bblocks = ctx->bblocks;
2193 LLVMBasicBlockRef cbb;
2194 LLVMBuilderRef builder, starting_builder;
2195 gboolean has_terminator;
2197 LLVMValueRef lhs, rhs;
2200 cbb = get_bb (ctx, bb);
2201 builder = create_builder (ctx);
2202 ctx->builder = builder;
2203 LLVMPositionBuilderAtEnd (builder, cbb);
2205 if (bb == cfg->bb_entry)
2206 emit_entry_bb (ctx, builder);
2207 CHECK_FAILURE (ctx);
2209 if (bb->flags & BB_EXCEPTION_HANDLER) {
2211 LLVMValueRef personality;
2212 LLVMBasicBlockRef target_bb;
2214 static gint32 mapping_inited;
2215 static int ti_generator;
2218 LLVMValueRef type_info;
2221 if (!bblocks [bb->block_num].invoke_target) {
2223 * LLVM asserts if llvm.eh.selector is called from a bblock which
2224 * doesn't have an invoke pointing at it.
2225 * Update: LLVM no longer asserts, but some tests in exceptions.exe now fail.
2227 LLVM_FAILURE (ctx, "handler without invokes");
2230 // <resultval> = landingpad <somety> personality <type> <pers_fn> <clause>+
2232 if (cfg->compile_aot) {
2233 /* Use a dummy personality function */
2234 personality = LLVMGetNamedFunction (module, "mono_aot_personality");
2235 g_assert (personality);
2237 personality = LLVMGetNamedFunction (module, "mono_personality");
2238 if (InterlockedCompareExchange (&mapping_inited, 1, 0) == 0)
2239 LLVMAddGlobalMapping (ctx->lmodule->ee, personality, mono_personality);
2242 i8ptr = LLVMPointerType (LLVMInt8Type (), 0);
2244 clause_index = (mono_get_block_region_notry (cfg, bb->region) >> 8) - 1;
2247 * Create the type info
2249 sprintf (ti_name, "type_info_%d", ti_generator);
2252 if (cfg->compile_aot) {
2253 /* decode_eh_frame () in aot-runtime.c will decode this */
2254 type_info = LLVMAddGlobal (module, LLVMInt32Type (), ti_name);
2255 LLVMSetInitializer (type_info, LLVMConstInt (LLVMInt32Type (), clause_index, FALSE));
2258 * These symbols are not really used, the clause_index is embedded into the EH tables generated by DwarfMonoException in LLVM.
2260 LLVMSetLinkage (type_info, LLVMInternalLinkage);
2263 * Enabling this causes llc to crash:
2264 * http://llvm.org/bugs/show_bug.cgi?id=6102
2266 //LLVM_FAILURE (ctx, "aot+clauses");
2268 // test_0_invalid_unbox_arrays () fails
2269 LLVM_FAILURE (ctx, "aot+clauses");
2273 * After the cfg mempool is freed, the type info will point to stale memory,
2274 * but this is not a problem, since we decode it once in exception_cb during
2277 ti = mono_mempool_alloc (cfg->mempool, sizeof (gint32));
2278 *(gint32*)ti = clause_index;
2280 type_info = LLVMAddGlobal (module, i8ptr, ti_name);
2282 LLVMAddGlobalMapping (ctx->lmodule->ee, type_info, ti);
2286 LLVMTypeRef members [2], ret_type;
2287 LLVMValueRef landing_pad;
2289 members [0] = i8ptr;
2290 members [1] = LLVMInt32Type ();
2291 ret_type = LLVMStructType (members, 2, FALSE);
2293 landing_pad = LLVMBuildLandingPad (builder, ret_type, personality, 1, "");
2294 LLVMAddClause (landing_pad, type_info);
2296 /* Store the exception into the exvar */
2297 if (bb->in_scount == 1) {
2298 g_assert (bb->in_scount == 1);
2299 exvar = bb->in_stack [0];
2301 // FIXME: This is shared with filter clauses ?
2302 g_assert (!values [exvar->dreg]);
2304 values [exvar->dreg] = LLVMBuildExtractValue (builder, landing_pad, 0, "ex_obj");
2305 emit_volatile_store (ctx, exvar->dreg);
2309 /* Start a new bblock which CALL_HANDLER can branch to */
2310 target_bb = bblocks [bb->block_num].call_handler_target_bb;
2312 LLVMBuildBr (builder, target_bb);
2314 ctx->builder = builder = create_builder (ctx);
2315 LLVMPositionBuilderAtEnd (ctx->builder, target_bb);
2317 ctx->bblocks [bb->block_num].end_bblock = target_bb;
2321 has_terminator = FALSE;
2322 starting_builder = builder;
2323 for (ins = bb->code; ins; ins = ins->next) {
2324 const char *spec = LLVM_INS_INFO (ins->opcode);
2326 char dname_buf [128];
2329 if (nins > 5000 && builder == starting_builder) {
2330 /* some steps in llc are non-linear in the size of basic blocks, see #5714 */
2331 LLVM_FAILURE (ctx, "basic block too long");
2335 /* There could be instructions after a terminator, skip them */
2338 if (spec [MONO_INST_DEST] != ' ' && !MONO_IS_STORE_MEMBASE (ins)) {
2339 sprintf (dname_buf, "t%d", ins->dreg);
2343 if (spec [MONO_INST_SRC1] != ' ' && spec [MONO_INST_SRC1] != 'v') {
2344 MonoInst *var = get_vreg_to_inst (cfg, ins->sreg1);
2346 if (var && var->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT)) {
2347 lhs = emit_volatile_load (ctx, ins->sreg1);
2349 /* It is ok for SETRET to have an uninitialized argument */
2350 if (!values [ins->sreg1] && ins->opcode != OP_SETRET)
2351 LLVM_FAILURE (ctx, "sreg1");
2352 lhs = values [ins->sreg1];
2358 if (spec [MONO_INST_SRC2] != ' ' && spec [MONO_INST_SRC2] != ' ') {
2359 MonoInst *var = get_vreg_to_inst (cfg, ins->sreg2);
2360 if (var && var->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT)) {
2361 rhs = emit_volatile_load (ctx, ins->sreg2);
2363 if (!values [ins->sreg2])
2364 LLVM_FAILURE (ctx, "sreg2");
2365 rhs = values [ins->sreg2];
2371 //mono_print_ins (ins);
2372 switch (ins->opcode) {
2375 case OP_LIVERANGE_START:
2376 case OP_LIVERANGE_END:
2379 values [ins->dreg] = LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE);
2382 #if SIZEOF_VOID_P == 4
2383 values [ins->dreg] = LLVMConstInt (LLVMInt64Type (), GET_LONG_IMM (ins), FALSE);
2385 values [ins->dreg] = LLVMConstInt (LLVMInt64Type (), (gint64)ins->inst_c0, FALSE);
2389 values [ins->dreg] = LLVMConstReal (LLVMDoubleType (), *(double*)ins->inst_p0);
2392 values [ins->dreg] = LLVMConstFPExt (LLVMConstReal (LLVMFloatType (), *(float*)ins->inst_p0), LLVMDoubleType ());
2394 case OP_DUMMY_ICONST:
2395 values [ins->dreg] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
2397 case OP_DUMMY_I8CONST:
2398 values [ins->dreg] = LLVMConstInt (LLVMInt64Type (), 0, FALSE);
2400 case OP_DUMMY_R8CONST:
2401 values [ins->dreg] = LLVMConstReal (LLVMDoubleType (), 0.0f);
2404 LLVMBuildBr (builder, get_bb (ctx, ins->inst_target_bb));
2405 has_terminator = TRUE;
2411 LLVMBasicBlockRef new_bb;
2412 LLVMBuilderRef new_builder;
2414 // The default branch is already handled
2415 // FIXME: Handle it here
2417 /* Start new bblock */
2418 sprintf (bb_name, "SWITCH_DEFAULT_BB%d", ctx->default_index ++);
2419 new_bb = LLVMAppendBasicBlock (ctx->lmethod, bb_name);
2421 lhs = convert (ctx, lhs, LLVMInt32Type ());
2422 v = LLVMBuildSwitch (builder, lhs, new_bb, GPOINTER_TO_UINT (ins->klass));
2423 for (i = 0; i < GPOINTER_TO_UINT (ins->klass); ++i) {
2424 MonoBasicBlock *target_bb = ins->inst_many_bb [i];
2426 LLVMAddCase (v, LLVMConstInt (LLVMInt32Type (), i, FALSE), get_bb (ctx, target_bb));
2429 new_builder = create_builder (ctx);
2430 LLVMPositionBuilderAtEnd (new_builder, new_bb);
2431 LLVMBuildUnreachable (new_builder);
2433 has_terminator = TRUE;
2434 g_assert (!ins->next);
2440 if (linfo->ret.storage == LLVMArgVtypeInReg) {
2441 LLVMTypeRef ret_type = LLVMGetReturnType (LLVMGetElementType (LLVMTypeOf (method)));
2442 LLVMValueRef part1, retval;
2445 size = get_vtype_size (sig->ret);
2447 g_assert (addresses [ins->sreg1]);
2449 g_assert (linfo->ret.pair_storage [0] == LLVMArgInIReg);
2450 g_assert (linfo->ret.pair_storage [1] == LLVMArgNone);
2452 part1 = convert (ctx, LLVMBuildLoad (builder, LLVMBuildBitCast (builder, addresses [ins->sreg1], LLVMPointerType (LLVMIntType (size * 8), 0), ""), ""), IntPtrType ());
2454 retval = LLVMBuildInsertValue (builder, LLVMGetUndef (ret_type), part1, 0, "");
2456 LLVMBuildRet (builder, retval);
2460 if (linfo->ret.storage == LLVMArgVtypeRetAddr) {
2461 LLVMBuildRetVoid (builder);
2465 if (!lhs || ctx->is_dead [ins->sreg1]) {
2467 * The method did not set its return value, probably because it
2468 * ends with a throw.
2471 LLVMBuildRetVoid (builder);
2473 LLVMBuildRet (builder, LLVMConstNull (type_to_llvm_type (ctx, sig->ret)));
2475 LLVMBuildRet (builder, convert (ctx, lhs, type_to_llvm_type (ctx, sig->ret)));
2477 has_terminator = TRUE;
2483 case OP_ICOMPARE_IMM:
2484 case OP_LCOMPARE_IMM:
2485 case OP_COMPARE_IMM: {
2489 if (ins->next->opcode == OP_NOP)
2492 if (ins->next->opcode == OP_BR)
2493 /* The comparison result is not needed */
2496 rel = mono_opcode_to_cond (ins->next->opcode);
2498 if (ins->opcode == OP_ICOMPARE_IMM) {
2499 lhs = convert (ctx, lhs, LLVMInt32Type ());
2500 rhs = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
2502 if (ins->opcode == OP_LCOMPARE_IMM) {
2503 lhs = convert (ctx, lhs, LLVMInt64Type ());
2504 rhs = LLVMConstInt (LLVMInt64Type (), GET_LONG_IMM (ins), FALSE);
2506 if (ins->opcode == OP_LCOMPARE) {
2507 lhs = convert (ctx, lhs, LLVMInt64Type ());
2508 rhs = convert (ctx, rhs, LLVMInt64Type ());
2510 if (ins->opcode == OP_ICOMPARE) {
2511 lhs = convert (ctx, lhs, LLVMInt32Type ());
2512 rhs = convert (ctx, rhs, LLVMInt32Type ());
2516 if (LLVMGetTypeKind (LLVMTypeOf (lhs)) == LLVMPointerTypeKind)
2517 rhs = convert (ctx, rhs, LLVMTypeOf (lhs));
2518 else if (LLVMGetTypeKind (LLVMTypeOf (rhs)) == LLVMPointerTypeKind)
2519 lhs = convert (ctx, lhs, LLVMTypeOf (rhs));
2522 /* We use COMPARE+SETcc/Bcc, llvm uses SETcc+br cond */
2523 if (ins->opcode == OP_FCOMPARE)
2524 cmp = LLVMBuildFCmp (builder, fpcond_to_llvm_cond [rel], convert (ctx, lhs, LLVMDoubleType ()), convert (ctx, rhs, LLVMDoubleType ()), "");
2525 else if (ins->opcode == OP_COMPARE_IMM) {
2526 if (LLVMGetTypeKind (LLVMTypeOf (lhs)) == LLVMPointerTypeKind && ins->inst_imm == 0)
2527 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], lhs, LLVMConstNull (LLVMTypeOf (lhs)), "");
2529 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE), "");
2530 } else if (ins->opcode == OP_LCOMPARE_IMM) {
2531 if (SIZEOF_REGISTER == 4 && COMPILE_LLVM (cfg)) {
2532 /* The immediate is encoded in two fields */
2533 guint64 l = ((guint64)(guint32)ins->inst_offset << 32) | ((guint32)ins->inst_imm);
2534 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, LLVMInt64Type ()), LLVMConstInt (LLVMInt64Type (), l, FALSE), "");
2536 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, LLVMInt64Type ()), LLVMConstInt (LLVMInt64Type (), ins->inst_imm, FALSE), "");
2539 else if (ins->opcode == OP_COMPARE) {
2540 if (LLVMGetTypeKind (LLVMTypeOf (lhs)) == LLVMPointerTypeKind && LLVMTypeOf (lhs) == LLVMTypeOf (rhs))
2541 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], lhs, rhs, "");
2543 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, IntPtrType ()), convert (ctx, rhs, IntPtrType ()), "");
2545 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], lhs, rhs, "");
2547 if (MONO_IS_COND_BRANCH_OP (ins->next)) {
2548 if (ins->next->inst_true_bb == ins->next->inst_false_bb) {
2550 * If the target bb contains PHI instructions, LLVM requires
2551 * two PHI entries for this bblock, while we only generate one.
2552 * So convert this to an unconditional bblock. (bxc #171).
2554 LLVMBuildBr (builder, get_bb (ctx, ins->next->inst_true_bb));
2556 LLVMBuildCondBr (builder, cmp, get_bb (ctx, ins->next->inst_true_bb), get_bb (ctx, ins->next->inst_false_bb));
2558 has_terminator = TRUE;
2559 } else if (MONO_IS_SETCC (ins->next)) {
2560 sprintf (dname_buf, "t%d", ins->next->dreg);
2562 values [ins->next->dreg] = LLVMBuildZExt (builder, cmp, LLVMInt32Type (), dname);
2564 /* Add stores for volatile variables */
2565 emit_volatile_store (ctx, ins->next->dreg);
2566 } else if (MONO_IS_COND_EXC (ins->next)) {
2567 emit_cond_system_exception (ctx, bb, ins->next->inst_p1, cmp);
2568 CHECK_FAILURE (ctx);
2569 builder = ctx->builder;
2571 LLVM_FAILURE (ctx, "next");
2585 rel = mono_opcode_to_cond (ins->opcode);
2587 cmp = LLVMBuildFCmp (builder, fpcond_to_llvm_cond [rel], convert (ctx, lhs, LLVMDoubleType ()), convert (ctx, rhs, LLVMDoubleType ()), "");
2588 values [ins->dreg] = LLVMBuildZExt (builder, cmp, LLVMInt32Type (), dname);
2596 gboolean empty = TRUE;
2598 /* Check that all input bblocks really branch to us */
2599 for (i = 0; i < bb->in_count; ++i) {
2600 if (bb->in_bb [i]->last_ins && bb->in_bb [i]->last_ins->opcode == OP_NOT_REACHED)
2601 ins->inst_phi_args [i + 1] = -1;
2607 /* LLVM doesn't like phi instructions with zero operands */
2608 ctx->is_dead [ins->dreg] = TRUE;
2612 /* Created earlier, insert it now */
2613 LLVMInsertIntoBuilder (builder, values [ins->dreg]);
2615 for (i = 0; i < ins->inst_phi_args [0]; i++) {
2616 int sreg1 = ins->inst_phi_args [i + 1];
2620 * Count the number of times the incoming bblock branches to us,
2621 * since llvm requires a separate entry for each.
2623 if (bb->in_bb [i]->last_ins && bb->in_bb [i]->last_ins->opcode == OP_SWITCH) {
2624 MonoInst *switch_ins = bb->in_bb [i]->last_ins;
2627 for (j = 0; j < GPOINTER_TO_UINT (switch_ins->klass); ++j) {
2628 if (switch_ins->inst_many_bb [j] == bb)
2635 /* Remember for later */
2636 for (j = 0; j < count; ++j) {
2637 PhiNode *node = mono_mempool_alloc0 (ctx->mempool, sizeof (PhiNode));
2640 node->in_bb = bb->in_bb [i];
2642 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);
2652 values [ins->dreg] = lhs;
2655 MonoInst *var = get_vreg_to_inst (cfg, ins->dreg);
2658 values [ins->dreg] = lhs;
2660 if (var && var->klass->byval_arg.type == MONO_TYPE_R4) {
2662 * This is added by the spilling pass in case of the JIT,
2663 * but we have to do it ourselves.
2665 values [ins->dreg] = convert (ctx, values [ins->dreg], LLVMFloatType ());
2699 lhs = convert (ctx, lhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
2700 rhs = convert (ctx, rhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
2702 switch (ins->opcode) {
2705 values [ins->dreg] = LLVMBuildAdd (builder, lhs, rhs, dname);
2709 values [ins->dreg] = LLVMBuildSub (builder, lhs, rhs, dname);
2713 values [ins->dreg] = LLVMBuildMul (builder, lhs, rhs, dname);
2717 values [ins->dreg] = LLVMBuildSRem (builder, lhs, rhs, dname);
2721 values [ins->dreg] = LLVMBuildURem (builder, lhs, rhs, dname);
2725 values [ins->dreg] = LLVMBuildSDiv (builder, lhs, rhs, dname);
2729 values [ins->dreg] = LLVMBuildUDiv (builder, lhs, rhs, dname);
2732 values [ins->dreg] = LLVMBuildFDiv (builder, lhs, rhs, dname);
2736 values [ins->dreg] = LLVMBuildAnd (builder, lhs, rhs, dname);
2740 values [ins->dreg] = LLVMBuildOr (builder, lhs, rhs, dname);
2744 values [ins->dreg] = LLVMBuildXor (builder, lhs, rhs, dname);
2748 values [ins->dreg] = LLVMBuildShl (builder, lhs, rhs, dname);
2752 values [ins->dreg] = LLVMBuildAShr (builder, lhs, rhs, dname);
2756 values [ins->dreg] = LLVMBuildLShr (builder, lhs, rhs, dname);
2760 values [ins->dreg] = LLVMBuildFAdd (builder, lhs, rhs, dname);
2763 values [ins->dreg] = LLVMBuildFSub (builder, lhs, rhs, dname);
2766 values [ins->dreg] = LLVMBuildFMul (builder, lhs, rhs, dname);
2770 g_assert_not_reached ();
2777 case OP_IREM_UN_IMM:
2779 case OP_IDIV_UN_IMM:
2785 case OP_ISHR_UN_IMM:
2794 case OP_LSHR_UN_IMM:
2800 case OP_SHR_UN_IMM: {
2803 if (spec [MONO_INST_SRC1] == 'l') {
2804 imm = LLVMConstInt (LLVMInt64Type (), GET_LONG_IMM (ins), FALSE);
2806 imm = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
2809 #if SIZEOF_VOID_P == 4
2810 if (ins->opcode == OP_LSHL_IMM || ins->opcode == OP_LSHR_IMM || ins->opcode == OP_LSHR_UN_IMM)
2811 imm = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
2814 if (LLVMGetTypeKind (LLVMTypeOf (lhs)) == LLVMPointerTypeKind)
2815 lhs = convert (ctx, lhs, IntPtrType ());
2816 imm = convert (ctx, imm, LLVMTypeOf (lhs));
2817 switch (ins->opcode) {
2821 values [ins->dreg] = LLVMBuildAdd (builder, lhs, imm, dname);
2825 values [ins->dreg] = LLVMBuildSub (builder, lhs, imm, dname);
2829 values [ins->dreg] = LLVMBuildMul (builder, lhs, imm, dname);
2833 values [ins->dreg] = LLVMBuildSDiv (builder, lhs, imm, dname);
2835 case OP_IDIV_UN_IMM:
2836 case OP_LDIV_UN_IMM:
2837 values [ins->dreg] = LLVMBuildUDiv (builder, lhs, imm, dname);
2841 values [ins->dreg] = LLVMBuildSRem (builder, lhs, imm, dname);
2843 case OP_IREM_UN_IMM:
2844 values [ins->dreg] = LLVMBuildURem (builder, lhs, imm, dname);
2849 values [ins->dreg] = LLVMBuildAnd (builder, lhs, imm, dname);
2853 values [ins->dreg] = LLVMBuildOr (builder, lhs, imm, dname);
2857 values [ins->dreg] = LLVMBuildXor (builder, lhs, imm, dname);
2862 values [ins->dreg] = LLVMBuildShl (builder, lhs, imm, dname);
2867 values [ins->dreg] = LLVMBuildAShr (builder, lhs, imm, dname);
2869 case OP_ISHR_UN_IMM:
2870 /* This is used to implement conv.u4, so the lhs could be an i8 */
2871 lhs = convert (ctx, lhs, LLVMInt32Type ());
2872 imm = convert (ctx, imm, LLVMInt32Type ());
2873 values [ins->dreg] = LLVMBuildLShr (builder, lhs, imm, dname);
2875 case OP_LSHR_UN_IMM:
2877 values [ins->dreg] = LLVMBuildLShr (builder, lhs, imm, dname);
2880 g_assert_not_reached ();
2885 values [ins->dreg] = LLVMBuildSub (builder, LLVMConstInt (LLVMInt32Type (), 0, FALSE), convert (ctx, lhs, LLVMInt32Type ()), dname);
2888 values [ins->dreg] = LLVMBuildSub (builder, LLVMConstInt (LLVMInt64Type (), 0, FALSE), lhs, dname);
2891 lhs = convert (ctx, lhs, LLVMDoubleType ());
2892 values [ins->dreg] = LLVMBuildFSub (builder, LLVMConstReal (LLVMDoubleType (), 0.0), lhs, dname);
2895 guint32 v = 0xffffffff;
2896 values [ins->dreg] = LLVMBuildXor (builder, LLVMConstInt (LLVMInt32Type (), v, FALSE), convert (ctx, lhs, LLVMInt32Type ()), dname);
2900 guint64 v = 0xffffffffffffffffLL;
2901 values [ins->dreg] = LLVMBuildXor (builder, LLVMConstInt (LLVMInt64Type (), v, FALSE), lhs, dname);
2904 #if defined(TARGET_X86) || defined(TARGET_AMD64)
2906 LLVMValueRef v1, v2;
2908 v1 = LLVMBuildMul (builder, convert (ctx, rhs, IntPtrType ()), LLVMConstInt (IntPtrType (), (1 << ins->backend.shift_amount), FALSE), "");
2909 v2 = LLVMBuildAdd (builder, convert (ctx, lhs, IntPtrType ()), v1, "");
2910 values [ins->dreg] = LLVMBuildAdd (builder, v2, LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE), dname);
2915 case OP_ICONV_TO_I1:
2916 case OP_ICONV_TO_I2:
2917 case OP_ICONV_TO_I4:
2918 case OP_ICONV_TO_U1:
2919 case OP_ICONV_TO_U2:
2920 case OP_ICONV_TO_U4:
2921 case OP_LCONV_TO_I1:
2922 case OP_LCONV_TO_I2:
2923 case OP_LCONV_TO_U1:
2924 case OP_LCONV_TO_U2:
2925 case OP_LCONV_TO_U4: {
2928 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);
2930 /* Have to do two casts since our vregs have type int */
2931 v = LLVMBuildTrunc (builder, lhs, op_to_llvm_type (ins->opcode), "");
2933 values [ins->dreg] = LLVMBuildSExt (builder, v, LLVMInt32Type (), dname);
2935 values [ins->dreg] = LLVMBuildZExt (builder, v, LLVMInt32Type (), dname);
2938 case OP_ICONV_TO_I8:
2939 values [ins->dreg] = LLVMBuildSExt (builder, lhs, LLVMInt64Type (), dname);
2941 case OP_ICONV_TO_U8:
2942 values [ins->dreg] = LLVMBuildZExt (builder, lhs, LLVMInt64Type (), dname);
2944 case OP_FCONV_TO_I4:
2945 values [ins->dreg] = LLVMBuildFPToSI (builder, lhs, LLVMInt32Type (), dname);
2947 case OP_FCONV_TO_I1:
2948 values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildFPToSI (builder, lhs, LLVMInt8Type (), dname), LLVMInt32Type (), "");
2950 case OP_FCONV_TO_U1:
2951 values [ins->dreg] = LLVMBuildZExt (builder, LLVMBuildFPToUI (builder, lhs, LLVMInt8Type (), dname), LLVMInt32Type (), "");
2953 case OP_FCONV_TO_I2:
2954 values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildFPToSI (builder, lhs, LLVMInt16Type (), dname), LLVMInt32Type (), "");
2956 case OP_FCONV_TO_U2:
2957 values [ins->dreg] = LLVMBuildZExt (builder, LLVMBuildFPToUI (builder, lhs, LLVMInt16Type (), dname), LLVMInt32Type (), "");
2959 case OP_FCONV_TO_I8:
2960 values [ins->dreg] = LLVMBuildFPToSI (builder, lhs, LLVMInt64Type (), dname);
2963 values [ins->dreg] = LLVMBuildFPToSI (builder, lhs, IntPtrType (), dname);
2965 case OP_ICONV_TO_R8:
2966 case OP_LCONV_TO_R8:
2967 values [ins->dreg] = LLVMBuildSIToFP (builder, lhs, LLVMDoubleType (), dname);
2969 case OP_LCONV_TO_R_UN:
2970 values [ins->dreg] = LLVMBuildUIToFP (builder, lhs, LLVMDoubleType (), dname);
2972 #if SIZEOF_VOID_P == 4
2975 case OP_LCONV_TO_I4:
2976 values [ins->dreg] = LLVMBuildTrunc (builder, lhs, LLVMInt32Type (), dname);
2978 case OP_ICONV_TO_R4:
2979 case OP_LCONV_TO_R4:
2980 v = LLVMBuildSIToFP (builder, lhs, LLVMFloatType (), "");
2981 values [ins->dreg] = LLVMBuildFPExt (builder, v, LLVMDoubleType (), dname);
2983 case OP_FCONV_TO_R4:
2984 v = LLVMBuildFPTrunc (builder, lhs, LLVMFloatType (), "");
2985 values [ins->dreg] = LLVMBuildFPExt (builder, v, LLVMDoubleType (), dname);
2988 values [ins->dreg] = LLVMBuildSExt (builder, convert (ctx, lhs, LLVMInt32Type ()), LLVMInt64Type (), dname);
2991 values [ins->dreg] = LLVMBuildZExt (builder, convert (ctx, lhs, LLVMInt32Type ()), LLVMInt64Type (), dname);
2994 values [ins->dreg] = LLVMBuildTrunc (builder, lhs, LLVMInt32Type (), dname);
2996 case OP_LOCALLOC_IMM: {
2999 guint32 size = ins->inst_imm;
3000 size = (size + (MONO_ARCH_FRAME_ALIGNMENT - 1)) & ~ (MONO_ARCH_FRAME_ALIGNMENT - 1);
3002 v = mono_llvm_build_alloca (builder, LLVMInt8Type (), LLVMConstInt (LLVMInt32Type (), size, FALSE), MONO_ARCH_FRAME_ALIGNMENT, "");
3004 if (ins->flags & MONO_INST_INIT) {
3005 LLVMValueRef args [5];
3008 args [1] = LLVMConstInt (LLVMInt8Type (), 0, FALSE);
3009 args [2] = LLVMConstInt (LLVMInt32Type (), size, FALSE);
3010 args [3] = LLVMConstInt (LLVMInt32Type (), MONO_ARCH_FRAME_ALIGNMENT, FALSE);
3011 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
3012 LLVMBuildCall (builder, LLVMGetNamedFunction (module, memset_func_name), args, memset_param_count, "");
3015 values [ins->dreg] = v;
3019 LLVMValueRef v, size;
3021 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), "");
3023 v = mono_llvm_build_alloca (builder, LLVMInt8Type (), size, MONO_ARCH_FRAME_ALIGNMENT, "");
3025 if (ins->flags & MONO_INST_INIT) {
3026 LLVMValueRef args [5];
3029 args [1] = LLVMConstInt (LLVMInt8Type (), 0, FALSE);
3031 args [3] = LLVMConstInt (LLVMInt32Type (), MONO_ARCH_FRAME_ALIGNMENT, FALSE);
3032 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
3033 LLVMBuildCall (builder, LLVMGetNamedFunction (module, memset_func_name), args, memset_param_count, "");
3035 values [ins->dreg] = v;
3039 case OP_LOADI1_MEMBASE:
3040 case OP_LOADU1_MEMBASE:
3041 case OP_LOADI2_MEMBASE:
3042 case OP_LOADU2_MEMBASE:
3043 case OP_LOADI4_MEMBASE:
3044 case OP_LOADU4_MEMBASE:
3045 case OP_LOADI8_MEMBASE:
3046 case OP_LOADR4_MEMBASE:
3047 case OP_LOADR8_MEMBASE:
3048 case OP_LOAD_MEMBASE:
3056 LLVMValueRef base, index, addr;
3058 gboolean sext = FALSE, zext = FALSE;
3059 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
3061 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
3066 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)) {
3067 addr = LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE);
3072 if (ins->inst_offset == 0) {
3074 } else if (ins->inst_offset % size != 0) {
3075 /* Unaligned load */
3076 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset, FALSE);
3077 addr = LLVMBuildGEP (builder, convert (ctx, base, LLVMPointerType (LLVMInt8Type (), 0)), &index, 1, "");
3079 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
3080 addr = LLVMBuildGEP (builder, convert (ctx, base, LLVMPointerType (t, 0)), &index, 1, "");
3084 addr = convert (ctx, addr, LLVMPointerType (t, 0));
3086 values [ins->dreg] = emit_load (ctx, bb, &builder, size, addr, dname, is_volatile);
3088 if (!is_volatile && (ins->flags & MONO_INST_INVARIANT_LOAD)) {
3090 * These will signal LLVM that these loads do not alias any stores, and
3091 * they can't fail, allowing them to be hoisted out of loops.
3093 set_invariant_load_flag (values [ins->dreg]);
3094 set_metadata_flag (values [ins->dreg], "mono.nofail.load");
3098 values [ins->dreg] = LLVMBuildSExt (builder, values [ins->dreg], LLVMInt32Type (), dname);
3100 values [ins->dreg] = LLVMBuildZExt (builder, values [ins->dreg], LLVMInt32Type (), dname);
3101 else if (ins->opcode == OP_LOADR4_MEMBASE)
3102 values [ins->dreg] = LLVMBuildFPExt (builder, values [ins->dreg], LLVMDoubleType (), dname);
3106 case OP_STOREI1_MEMBASE_REG:
3107 case OP_STOREI2_MEMBASE_REG:
3108 case OP_STOREI4_MEMBASE_REG:
3109 case OP_STOREI8_MEMBASE_REG:
3110 case OP_STORER4_MEMBASE_REG:
3111 case OP_STORER8_MEMBASE_REG:
3112 case OP_STORE_MEMBASE_REG: {
3114 LLVMValueRef index, addr;
3116 gboolean sext = FALSE, zext = FALSE;
3117 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
3119 if (!values [ins->inst_destbasereg])
3120 LLVM_FAILURE (ctx, "inst_destbasereg");
3122 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
3124 if (ins->inst_offset % size != 0) {
3125 /* Unaligned store */
3126 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset, FALSE);
3127 addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (LLVMInt8Type (), 0)), &index, 1, "");
3129 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
3130 addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (t, 0)), &index, 1, "");
3132 emit_store (ctx, bb, &builder, size, convert (ctx, values [ins->sreg1], t), convert (ctx, addr, LLVMPointerType (t, 0)), is_volatile);
3136 case OP_STOREI1_MEMBASE_IMM:
3137 case OP_STOREI2_MEMBASE_IMM:
3138 case OP_STOREI4_MEMBASE_IMM:
3139 case OP_STOREI8_MEMBASE_IMM:
3140 case OP_STORE_MEMBASE_IMM: {
3142 LLVMValueRef index, addr;
3144 gboolean sext = FALSE, zext = FALSE;
3145 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
3147 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
3149 if (ins->inst_offset % size != 0) {
3150 /* Unaligned store */
3151 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset, FALSE);
3152 addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (LLVMInt8Type (), 0)), &index, 1, "");
3154 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
3155 addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (t, 0)), &index, 1, "");
3157 emit_store (ctx, bb, &builder, size, convert (ctx, LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE), t), addr, is_volatile);
3162 emit_load (ctx, bb, &builder, sizeof (gpointer), convert (ctx, lhs, LLVMPointerType (IntPtrType (), 0)), "", TRUE);
3164 case OP_OUTARG_VTRETADDR:
3171 case OP_VOIDCALL_MEMBASE:
3172 case OP_CALL_MEMBASE:
3173 case OP_LCALL_MEMBASE:
3174 case OP_FCALL_MEMBASE:
3175 case OP_VCALL_MEMBASE:
3176 case OP_VOIDCALL_REG:
3180 case OP_VCALL_REG: {
3181 process_call (ctx, bb, &builder, ins);
3182 CHECK_FAILURE (ctx);
3187 LLVMValueRef indexes [2];
3189 LLVMValueRef got_entry_addr;
3192 * FIXME: Can't allocate from the cfg mempool since that is freed if
3193 * the LLVM compile fails.
3195 ji = g_new0 (MonoJumpInfo, 1);
3196 ji->type = (MonoJumpInfoType)ins->inst_i1;
3197 ji->data.target = ins->inst_p0;
3199 ji = mono_aot_patch_info_dup (ji);
3201 ji->next = cfg->patch_info;
3202 cfg->patch_info = ji;
3204 //mono_add_patch_info (cfg, 0, (MonoJumpInfoType)ins->inst_i1, ins->inst_p0);
3205 got_offset = mono_aot_get_got_offset (cfg->patch_info);
3207 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
3208 indexes [1] = LLVMConstInt (LLVMInt32Type (), (gssize)got_offset, FALSE);
3209 got_entry_addr = LLVMBuildGEP (builder, ctx->lmodule->got_var, indexes, 2, "");
3211 values [ins->dreg] = LLVMBuildLoad (builder, got_entry_addr, dname);
3212 set_invariant_load_flag (values [ins->dreg]);
3215 case OP_NOT_REACHED:
3216 LLVMBuildUnreachable (builder);
3217 has_terminator = TRUE;
3218 g_assert (bb->block_num < cfg->max_block_num);
3219 ctx->unreachable [bb->block_num] = TRUE;
3220 /* Might have instructions after this */
3222 MonoInst *next = ins->next;
3224 * FIXME: If later code uses the regs defined by these instructions,
3225 * compilation will fail.
3227 MONO_DELETE_INS (bb, next);
3231 MonoInst *var = ins->inst_p0;
3233 values [ins->dreg] = addresses [var->dreg];
3237 LLVMValueRef args [1];
3239 args [0] = convert (ctx, lhs, LLVMDoubleType ());
3240 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, "llvm.sin.f64"), args, 1, dname);
3244 LLVMValueRef args [1];
3246 args [0] = convert (ctx, lhs, LLVMDoubleType ());
3247 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, "llvm.cos.f64"), args, 1, dname);
3251 LLVMValueRef args [1];
3254 /* This no longer seems to happen */
3256 * LLVM optimizes sqrt(nan) into undefined in
3257 * lib/Analysis/ConstantFolding.cpp
3258 * Also, sqrt(NegativeInfinity) is optimized into 0.
3260 LLVM_FAILURE (ctx, "sqrt");
3262 args [0] = convert (ctx, lhs, LLVMDoubleType ());
3263 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, "llvm.sqrt.f64"), args, 1, dname);
3267 LLVMValueRef args [1];
3269 args [0] = convert (ctx, lhs, LLVMDoubleType ());
3270 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, "fabs"), args, 1, dname);
3284 lhs = convert (ctx, lhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
3285 rhs = convert (ctx, rhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
3287 switch (ins->opcode) {
3290 v = LLVMBuildICmp (builder, LLVMIntSLE, lhs, rhs, "");
3294 v = LLVMBuildICmp (builder, LLVMIntSGE, lhs, rhs, "");
3298 v = LLVMBuildICmp (builder, LLVMIntULE, lhs, rhs, "");
3302 v = LLVMBuildICmp (builder, LLVMIntUGE, lhs, rhs, "");
3305 g_assert_not_reached ();
3308 values [ins->dreg] = LLVMBuildSelect (builder, v, lhs, rhs, dname);
3311 case OP_ATOMIC_EXCHANGE_I4:
3312 case OP_ATOMIC_EXCHANGE_I8: {
3313 LLVMValueRef args [2];
3316 if (ins->opcode == OP_ATOMIC_EXCHANGE_I4)
3317 t = LLVMInt32Type ();
3319 t = LLVMInt64Type ();
3321 g_assert (ins->inst_offset == 0);
3323 args [0] = convert (ctx, lhs, LLVMPointerType (t, 0));
3324 args [1] = convert (ctx, rhs, t);
3326 values [ins->dreg] = mono_llvm_build_atomic_rmw (builder, LLVM_ATOMICRMW_OP_XCHG, args [0], args [1]);
3329 case OP_ATOMIC_ADD_NEW_I4:
3330 case OP_ATOMIC_ADD_NEW_I8: {
3331 LLVMValueRef args [2];
3334 if (ins->opcode == OP_ATOMIC_ADD_NEW_I4)
3335 t = LLVMInt32Type ();
3337 t = LLVMInt64Type ();
3339 g_assert (ins->inst_offset == 0);
3341 args [0] = convert (ctx, lhs, LLVMPointerType (t, 0));
3342 args [1] = convert (ctx, rhs, t);
3343 values [ins->dreg] = LLVMBuildAdd (builder, mono_llvm_build_atomic_rmw (builder, LLVM_ATOMICRMW_OP_ADD, args [0], args [1]), args [1], dname);
3346 case OP_ATOMIC_CAS_I4:
3347 case OP_ATOMIC_CAS_I8: {
3348 LLVMValueRef args [3];
3351 if (ins->opcode == OP_ATOMIC_CAS_I4)
3352 t = LLVMInt32Type ();
3354 t = LLVMInt64Type ();
3356 args [0] = convert (ctx, lhs, LLVMPointerType (t, 0));
3358 args [1] = convert (ctx, values [ins->sreg3], t);
3360 args [2] = convert (ctx, values [ins->sreg2], t);
3361 values [ins->dreg] = mono_llvm_build_cmpxchg (builder, args [0], args [1], args [2]);
3364 case OP_MEMORY_BARRIER: {
3365 mono_llvm_build_fence (builder);
3368 case OP_RELAXED_NOP: {
3369 #if defined(TARGET_AMD64) || defined(TARGET_X86)
3370 emit_call (ctx, bb, &builder, LLVMGetNamedFunction (ctx->module, "llvm.x86.sse2.pause"), NULL, 0);
3377 #if (defined(TARGET_AMD64) || defined(TARGET_X86)) && defined(__linux__)
3379 // 257 == FS segment register
3380 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 257);
3382 // 256 == GS segment register
3383 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 256);
3386 values [ins->dreg] = LLVMBuildLoad (builder, LLVMBuildIntToPtr (builder, LLVMConstInt (IntPtrType (), ins->inst_offset, TRUE), ptrtype, ""), "");
3387 #elif defined(TARGET_AMD64) && defined(TARGET_OSX)
3388 /* See mono_amd64_emit_tls_get () */
3389 int offset = mono_amd64_get_tls_gs_offset () + (ins->inst_offset * 8);
3391 // 256 == GS segment register
3392 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 256);
3393 values [ins->dreg] = LLVMBuildLoad (builder, LLVMBuildIntToPtr (builder, LLVMConstInt (IntPtrType (), offset, TRUE), ptrtype, ""), "");
3395 LLVM_FAILURE (ctx, "opcode tls-get");
3400 case OP_TLS_GET_REG: {
3401 #if defined(TARGET_AMD64) && defined(TARGET_OSX)
3402 /* See emit_tls_get_reg () */
3403 // 256 == GS segment register
3404 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 256);
3405 values [ins->dreg] = LLVMBuildLoad (builder, LLVMBuildIntToPtr (builder, convert (ctx, lhs, LLVMInt32Type ()), ptrtype, ""), "");
3407 LLVM_FAILURE (ctx, "opcode tls-get");
3416 case OP_IADD_OVF_UN:
3418 case OP_ISUB_OVF_UN:
3420 case OP_IMUL_OVF_UN:
3421 #if SIZEOF_VOID_P == 8
3423 case OP_LADD_OVF_UN:
3425 case OP_LSUB_OVF_UN:
3427 case OP_LMUL_OVF_UN:
3430 LLVMValueRef args [2], val, ovf, func;
3432 args [0] = convert (ctx, lhs, op_to_llvm_type (ins->opcode));
3433 args [1] = convert (ctx, rhs, op_to_llvm_type (ins->opcode));
3434 func = LLVMGetNamedFunction (module, ovf_op_to_intrins (ins->opcode));
3436 val = LLVMBuildCall (builder, func, args, 2, "");
3437 values [ins->dreg] = LLVMBuildExtractValue (builder, val, 0, dname);
3438 ovf = LLVMBuildExtractValue (builder, val, 1, "");
3439 emit_cond_system_exception (ctx, bb, "OverflowException", ovf);
3440 CHECK_FAILURE (ctx);
3441 builder = ctx->builder;
3447 * We currently model them using arrays. Promotion to local vregs is
3448 * disabled for them in mono_handle_global_vregs () in the LLVM case,
3449 * so we always have an entry in cfg->varinfo for them.
3450 * FIXME: Is this needed ?
3453 MonoClass *klass = ins->klass;
3454 LLVMValueRef args [5];
3458 LLVM_FAILURE (ctx, "!klass");
3462 if (!addresses [ins->dreg])
3463 addresses [ins->dreg] = build_alloca (ctx, &klass->byval_arg);
3464 args [0] = LLVMBuildBitCast (builder, addresses [ins->dreg], LLVMPointerType (LLVMInt8Type (), 0), "");
3465 args [1] = LLVMConstInt (LLVMInt8Type (), 0, FALSE);
3466 args [2] = LLVMConstInt (LLVMInt32Type (), mono_class_value_size (klass, NULL), FALSE);
3468 args [3] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
3469 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
3470 LLVMBuildCall (builder, LLVMGetNamedFunction (module, memset_func_name), args, memset_param_count, "");
3473 case OP_DUMMY_VZERO:
3476 case OP_STOREV_MEMBASE:
3477 case OP_LOADV_MEMBASE:
3479 MonoClass *klass = ins->klass;
3480 LLVMValueRef src = NULL, dst, args [5];
3481 gboolean done = FALSE;
3485 LLVM_FAILURE (ctx, "!klass");
3489 if (mini_is_gsharedvt_klass (cfg, klass)) {
3491 LLVM_FAILURE (ctx, "gsharedvt");
3495 switch (ins->opcode) {
3496 case OP_STOREV_MEMBASE:
3497 if (cfg->gen_write_barriers && klass->has_references && ins->inst_destbasereg != cfg->frame_reg &&
3498 LLVMGetInstructionOpcode (values [ins->inst_destbasereg]) != LLVMAlloca) {
3499 /* Decomposed earlier */
3500 g_assert_not_reached ();
3503 if (!addresses [ins->sreg1]) {
3505 g_assert (values [ins->sreg1]);
3506 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));
3507 LLVMBuildStore (builder, values [ins->sreg1], dst);
3510 src = LLVMBuildBitCast (builder, addresses [ins->sreg1], LLVMPointerType (LLVMInt8Type (), 0), "");
3511 dst = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_destbasereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (LLVMInt8Type (), 0));
3514 case OP_LOADV_MEMBASE:
3515 if (!addresses [ins->dreg])
3516 addresses [ins->dreg] = build_alloca (ctx, &klass->byval_arg);
3517 src = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_basereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (LLVMInt8Type (), 0));
3518 dst = LLVMBuildBitCast (builder, addresses [ins->dreg], LLVMPointerType (LLVMInt8Type (), 0), "");
3521 if (!addresses [ins->sreg1])
3522 addresses [ins->sreg1] = build_alloca (ctx, &klass->byval_arg);
3523 if (!addresses [ins->dreg])
3524 addresses [ins->dreg] = build_alloca (ctx, &klass->byval_arg);
3525 src = LLVMBuildBitCast (builder, addresses [ins->sreg1], LLVMPointerType (LLVMInt8Type (), 0), "");
3526 dst = LLVMBuildBitCast (builder, addresses [ins->dreg], LLVMPointerType (LLVMInt8Type (), 0), "");
3529 g_assert_not_reached ();
3531 CHECK_FAILURE (ctx);
3538 args [2] = LLVMConstInt (LLVMInt32Type (), mono_class_value_size (klass, NULL), FALSE);
3539 args [3] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
3541 args [3] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
3542 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
3543 LLVMBuildCall (builder, LLVMGetNamedFunction (module, memcpy_func_name), args, memcpy_param_count, "");
3546 case OP_LLVM_OUTARG_VT:
3547 if (!addresses [ins->sreg1]) {
3548 addresses [ins->sreg1] = build_alloca (ctx, &ins->klass->byval_arg);
3549 g_assert (values [ins->sreg1]);
3550 LLVMBuildStore (builder, values [ins->sreg1], addresses [ins->sreg1]);
3552 addresses [ins->dreg] = addresses [ins->sreg1];
3558 #if defined(TARGET_X86) || defined(TARGET_AMD64)
3560 values [ins->dreg] = LLVMConstNull (type_to_llvm_type (ctx, &ins->klass->byval_arg));
3563 case OP_LOADX_MEMBASE: {
3564 LLVMTypeRef t = type_to_llvm_type (ctx, &ins->klass->byval_arg);
3567 src = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_basereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (t, 0));
3568 values [ins->dreg] = mono_llvm_build_aligned_load (builder, src, "", FALSE, 1);
3571 case OP_STOREX_MEMBASE: {
3572 LLVMTypeRef t = LLVMTypeOf (values [ins->sreg1]);
3575 dest = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_destbasereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (t, 0));
3576 mono_llvm_build_aligned_store (builder, values [ins->sreg1], dest, FALSE, 1);
3583 values [ins->dreg] = LLVMBuildAdd (builder, lhs, rhs, "");
3587 values [ins->dreg] = LLVMBuildFAdd (builder, lhs, rhs, "");
3593 values [ins->dreg] = LLVMBuildSub (builder, lhs, rhs, "");
3597 values [ins->dreg] = LLVMBuildFSub (builder, lhs, rhs, "");
3601 values [ins->dreg] = LLVMBuildFMul (builder, lhs, rhs, "");
3605 values [ins->dreg] = LLVMBuildFDiv (builder, lhs, rhs, "");
3608 values [ins->dreg] = LLVMBuildAnd (builder, lhs, rhs, "");
3611 values [ins->dreg] = LLVMBuildOr (builder, lhs, rhs, "");
3614 values [ins->dreg] = LLVMBuildXor (builder, lhs, rhs, "");
3618 values [ins->dreg] = LLVMBuildMul (builder, lhs, rhs, "");
3629 LLVMValueRef v = NULL;
3631 switch (ins->opcode) {
3636 t = LLVMVectorType (LLVMInt32Type (), 4);
3637 rt = LLVMVectorType (LLVMFloatType (), 4);
3643 t = LLVMVectorType (LLVMInt64Type (), 2);
3644 rt = LLVMVectorType (LLVMDoubleType (), 2);
3647 t = LLVMInt32Type ();
3648 rt = LLVMInt32Type ();
3649 g_assert_not_reached ();
3652 lhs = LLVMBuildBitCast (builder, lhs, t, "");
3653 rhs = LLVMBuildBitCast (builder, rhs, t, "");
3654 switch (ins->opcode) {
3657 v = LLVMBuildAnd (builder, lhs, rhs, "");
3661 v = LLVMBuildOr (builder, lhs, rhs, "");
3665 v = LLVMBuildXor (builder, lhs, rhs, "");
3669 v = LLVMBuildAnd (builder, rhs, LLVMBuildNot (builder, lhs, ""), "");
3672 values [ins->dreg] = LLVMBuildBitCast (builder, v, rt, "");
3696 case OP_PADDB_SAT_UN:
3697 case OP_PADDW_SAT_UN:
3698 case OP_PSUBB_SAT_UN:
3699 case OP_PSUBW_SAT_UN:
3707 case OP_PMULW_HIGH_UN: {
3708 LLVMValueRef args [2];
3713 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, simd_op_to_intrins (ins->opcode)), args, 2, dname);
3720 values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildICmp (builder, LLVMIntEQ, lhs, rhs, ""), LLVMTypeOf (lhs), "");
3724 values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildICmp (builder, LLVMIntSGT, lhs, rhs, ""), LLVMTypeOf (lhs), "");
3732 case OP_EXTRACTX_U2:
3734 case OP_EXTRACT_U1: {
3736 gboolean zext = FALSE;
3738 t = simd_op_to_llvm_type (ins->opcode);
3740 switch (ins->opcode) {
3748 case OP_EXTRACTX_U2:
3753 t = LLVMInt32Type ();
3754 g_assert_not_reached ();
3757 lhs = LLVMBuildBitCast (builder, lhs, t, "");
3758 values [ins->dreg] = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), "");
3760 values [ins->dreg] = LLVMBuildZExt (builder, values [ins->dreg], LLVMInt32Type (), "");
3769 case OP_EXPAND_R8: {
3770 LLVMTypeRef t = simd_op_to_llvm_type (ins->opcode);
3771 LLVMValueRef mask [16], v;
3773 for (i = 0; i < 16; ++i)
3774 mask [i] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
3776 v = convert (ctx, values [ins->sreg1], LLVMGetElementType (t));
3778 values [ins->dreg] = LLVMBuildInsertElement (builder, LLVMConstNull (t), v, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
3779 values [ins->dreg] = LLVMBuildShuffleVector (builder, values [ins->dreg], LLVMGetUndef (t), LLVMConstVector (mask, LLVMGetVectorSize (t)), "");
3784 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt8Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
3787 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt16Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
3790 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt32Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
3793 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt64Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
3796 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMFloatType ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
3799 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMDoubleType ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
3810 case OP_EXTRACT_MASK:
3817 v = convert (ctx, values [ins->sreg1], simd_op_to_llvm_type (ins->opcode));
3819 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, simd_op_to_intrins (ins->opcode)), &v, 1, dname);
3823 case OP_ICONV_TO_R8_RAW:
3824 /* Same as OP_ICONV_TO_R8 */
3825 values [ins->dreg] = convert (ctx, LLVMBuildBitCast (builder, lhs, LLVMFloatType (), ""), LLVMDoubleType ());
3830 LLVMValueRef args [3];
3834 args [2] = LLVMConstInt (LLVMInt8Type (), ins->inst_c0, FALSE);
3836 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, simd_op_to_intrins (ins->opcode)), args, 3, dname);
3841 /* This is only used for implementing shifts by non-immediate */
3842 values [ins->dreg] = lhs;
3853 LLVMValueRef args [3];
3856 args [1] = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
3858 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, simd_op_to_intrins (ins->opcode)), args, 2, dname);
3869 case OP_PSHLQ_REG: {
3870 LLVMValueRef args [3];
3873 args [1] = values [ins->sreg2];
3875 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, simd_op_to_intrins (ins->opcode)), args, 2, dname);
3882 case OP_PSHUFLEW_LOW:
3883 case OP_PSHUFLEW_HIGH: {
3885 LLVMValueRef v1 = NULL, v2 = NULL, mask_values [16];
3886 int i, mask_size = 0;
3887 int imask = ins->inst_c0;
3889 /* Convert the x86 shuffle mask to LLVM's */
3890 switch (ins->opcode) {
3893 mask [0] = ((imask >> 0) & 3);
3894 mask [1] = ((imask >> 2) & 3);
3895 mask [2] = ((imask >> 4) & 3) + 4;
3896 mask [3] = ((imask >> 6) & 3) + 4;
3897 v1 = values [ins->sreg1];
3898 v2 = values [ins->sreg2];
3902 mask [0] = ((imask >> 0) & 1);
3903 mask [1] = ((imask >> 1) & 1) + 2;
3904 v1 = values [ins->sreg1];
3905 v2 = values [ins->sreg2];
3907 case OP_PSHUFLEW_LOW:
3909 mask [0] = ((imask >> 0) & 3);
3910 mask [1] = ((imask >> 2) & 3);
3911 mask [2] = ((imask >> 4) & 3);
3912 mask [3] = ((imask >> 6) & 3);
3917 v1 = values [ins->sreg1];
3918 v2 = LLVMGetUndef (LLVMTypeOf (v1));
3920 case OP_PSHUFLEW_HIGH:
3926 mask [4] = 4 + ((imask >> 0) & 3);
3927 mask [5] = 4 + ((imask >> 2) & 3);
3928 mask [6] = 4 + ((imask >> 4) & 3);
3929 mask [7] = 4 + ((imask >> 6) & 3);
3930 v1 = values [ins->sreg1];
3931 v2 = LLVMGetUndef (LLVMTypeOf (v1));
3935 mask [0] = ((imask >> 0) & 3);
3936 mask [1] = ((imask >> 2) & 3);
3937 mask [2] = ((imask >> 4) & 3);
3938 mask [3] = ((imask >> 6) & 3);
3939 v1 = values [ins->sreg1];
3940 v2 = LLVMGetUndef (LLVMTypeOf (v1));
3943 g_assert_not_reached ();
3945 for (i = 0; i < mask_size; ++i)
3946 mask_values [i] = LLVMConstInt (LLVMInt32Type (), mask [i], FALSE);
3948 values [ins->dreg] =
3949 LLVMBuildShuffleVector (builder, v1, v2,
3950 LLVMConstVector (mask_values, mask_size), dname);
3954 case OP_UNPACK_LOWB:
3955 case OP_UNPACK_LOWW:
3956 case OP_UNPACK_LOWD:
3957 case OP_UNPACK_LOWQ:
3958 case OP_UNPACK_LOWPS:
3959 case OP_UNPACK_LOWPD:
3960 case OP_UNPACK_HIGHB:
3961 case OP_UNPACK_HIGHW:
3962 case OP_UNPACK_HIGHD:
3963 case OP_UNPACK_HIGHQ:
3964 case OP_UNPACK_HIGHPS:
3965 case OP_UNPACK_HIGHPD: {
3967 LLVMValueRef mask_values [16];
3968 int i, mask_size = 0;
3969 gboolean low = FALSE;
3971 switch (ins->opcode) {
3972 case OP_UNPACK_LOWB:
3976 case OP_UNPACK_LOWW:
3980 case OP_UNPACK_LOWD:
3981 case OP_UNPACK_LOWPS:
3985 case OP_UNPACK_LOWQ:
3986 case OP_UNPACK_LOWPD:
3990 case OP_UNPACK_HIGHB:
3993 case OP_UNPACK_HIGHW:
3996 case OP_UNPACK_HIGHD:
3997 case OP_UNPACK_HIGHPS:
4000 case OP_UNPACK_HIGHQ:
4001 case OP_UNPACK_HIGHPD:
4005 g_assert_not_reached ();
4009 for (i = 0; i < (mask_size / 2); ++i) {
4011 mask [(i * 2) + 1] = mask_size + i;
4014 for (i = 0; i < (mask_size / 2); ++i) {
4015 mask [(i * 2)] = (mask_size / 2) + i;
4016 mask [(i * 2) + 1] = mask_size + (mask_size / 2) + i;
4020 for (i = 0; i < mask_size; ++i)
4021 mask_values [i] = LLVMConstInt (LLVMInt32Type (), mask [i], FALSE);
4023 values [ins->dreg] =
4024 LLVMBuildShuffleVector (builder, values [ins->sreg1], values [ins->sreg2],
4025 LLVMConstVector (mask_values, mask_size), dname);
4030 LLVMTypeRef t = simd_op_to_llvm_type (ins->opcode);
4031 LLVMValueRef v, val;
4033 v = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
4034 val = LLVMConstNull (t);
4035 val = LLVMBuildInsertElement (builder, val, v, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
4036 val = LLVMBuildInsertElement (builder, val, v, LLVMConstInt (LLVMInt32Type (), 1, FALSE), dname);
4038 values [ins->dreg] = val;
4042 case OP_DUPPS_HIGH: {
4043 LLVMTypeRef t = simd_op_to_llvm_type (ins->opcode);
4044 LLVMValueRef v1, v2, val;
4047 if (ins->opcode == OP_DUPPS_LOW) {
4048 v1 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
4049 v2 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 2, FALSE), "");
4051 v1 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 1, FALSE), "");
4052 v2 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 3, FALSE), "");
4054 val = LLVMConstNull (t);
4055 val = LLVMBuildInsertElement (builder, val, v1, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
4056 val = LLVMBuildInsertElement (builder, val, v1, LLVMConstInt (LLVMInt32Type (), 1, FALSE), "");
4057 val = LLVMBuildInsertElement (builder, val, v2, LLVMConstInt (LLVMInt32Type (), 2, FALSE), "");
4058 val = LLVMBuildInsertElement (builder, val, v2, LLVMConstInt (LLVMInt32Type (), 3, FALSE), "");
4060 values [ins->dreg] = val;
4070 * EXCEPTION HANDLING
4072 case OP_IMPLICIT_EXCEPTION:
4073 /* This marks a place where an implicit exception can happen */
4074 if (bb->region != -1)
4075 LLVM_FAILURE (ctx, "implicit-exception");
4079 MonoMethodSignature *throw_sig;
4080 LLVMValueRef callee, arg;
4081 gboolean rethrow = (ins->opcode == OP_RETHROW);
4082 const char *icall_name;
4084 callee = rethrow ? ctx->lmodule->rethrow : ctx->lmodule->throw;
4085 icall_name = rethrow ? "mono_arch_rethrow_exception" : "mono_arch_throw_exception";
4088 throw_sig = mono_metadata_signature_alloc (mono_get_corlib (), 1);
4089 throw_sig->ret = &mono_get_void_class ()->byval_arg;
4090 throw_sig->params [0] = &mono_get_object_class ()->byval_arg;
4091 if (cfg->compile_aot) {
4092 callee = get_plt_entry (ctx, sig_to_llvm_sig (ctx, throw_sig), MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
4094 callee = LLVMAddFunction (module, icall_name, sig_to_llvm_sig (ctx, throw_sig));
4098 * LLVM doesn't push the exception argument, so we need a different
4101 LLVMAddGlobalMapping (ctx->lmodule->ee, callee, resolve_patch (cfg, MONO_PATCH_INFO_INTERNAL_METHOD, rethrow ? "llvm_rethrow_exception_trampoline" : "llvm_throw_exception_trampoline"));
4103 LLVMAddGlobalMapping (ctx->lmodule->ee, callee, resolve_patch (cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name));
4107 mono_memory_barrier ();
4109 ctx->lmodule->rethrow = callee;
4111 ctx->lmodule->throw = callee;
4113 arg = convert (ctx, lhs, type_to_llvm_type (ctx, &mono_get_object_class ()->byval_arg));
4114 emit_call (ctx, bb, &builder, callee, &arg, 1);
4117 case OP_CALL_HANDLER: {
4119 * We don't 'call' handlers, but instead simply branch to them.
4120 * The code generated by ENDFINALLY will branch back to us.
4122 LLVMBasicBlockRef noex_bb;
4124 BBInfo *info = &bblocks [ins->inst_target_bb->block_num];
4126 bb_list = info->call_handler_return_bbs;
4129 * Set the indicator variable for the finally clause.
4131 lhs = info->finally_ind;
4133 LLVMBuildStore (builder, LLVMConstInt (LLVMInt32Type (), g_slist_length (bb_list) + 1, FALSE), lhs);
4135 /* Branch to the finally clause */
4136 LLVMBuildBr (builder, info->call_handler_target_bb);
4138 noex_bb = gen_bb (ctx, "CALL_HANDLER_CONT_BB");
4139 info->call_handler_return_bbs = g_slist_append_mempool (cfg->mempool, info->call_handler_return_bbs, noex_bb);
4141 builder = ctx->builder = create_builder (ctx);
4142 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
4144 bblocks [bb->block_num].end_bblock = noex_bb;
4147 case OP_START_HANDLER: {
4150 case OP_ENDFINALLY: {
4151 LLVMBasicBlockRef resume_bb;
4152 MonoBasicBlock *handler_bb;
4153 LLVMValueRef val, switch_ins, callee;
4157 handler_bb = g_hash_table_lookup (ctx->region_to_handler, GUINT_TO_POINTER (mono_get_block_region_notry (cfg, bb->region)));
4158 g_assert (handler_bb);
4159 info = &bblocks [handler_bb->block_num];
4160 lhs = info->finally_ind;
4163 bb_list = info->call_handler_return_bbs;
4165 resume_bb = gen_bb (ctx, "ENDFINALLY_RESUME_BB");
4167 /* Load the finally variable */
4168 val = LLVMBuildLoad (builder, lhs, "");
4170 /* Reset the variable */
4171 LLVMBuildStore (builder, LLVMConstInt (LLVMInt32Type (), 0, FALSE), lhs);
4173 /* Branch to either resume_bb, or to the bblocks in bb_list */
4174 switch_ins = LLVMBuildSwitch (builder, val, resume_bb, g_slist_length (bb_list));
4176 * The other targets are added at the end to handle OP_CALL_HANDLER
4177 * opcodes processed later.
4179 info->endfinally_switch_ins_list = g_slist_append_mempool (cfg->mempool, info->endfinally_switch_ins_list, switch_ins);
4181 builder = ctx->builder = create_builder (ctx);
4182 LLVMPositionBuilderAtEnd (ctx->builder, resume_bb);
4184 if (ctx->cfg->compile_aot) {
4185 callee = get_plt_entry (ctx, LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE), MONO_PATCH_INFO_INTERNAL_METHOD, "llvm_resume_unwind_trampoline");
4187 callee = LLVMGetNamedFunction (module, "llvm_resume_unwind_trampoline");
4189 LLVMBuildCall (builder, callee, NULL, 0, "");
4191 LLVMBuildUnreachable (builder);
4192 has_terminator = TRUE;
4198 sprintf (reason, "opcode %s", mono_inst_name (ins->opcode));
4199 LLVM_FAILURE (ctx, reason);
4204 /* Convert the value to the type required by phi nodes */
4205 if (spec [MONO_INST_DEST] != ' ' && !MONO_IS_STORE_MEMBASE (ins) && ctx->vreg_types [ins->dreg]) {
4206 if (!values [ins->dreg])
4208 values [ins->dreg] = addresses [ins->dreg];
4210 values [ins->dreg] = convert (ctx, values [ins->dreg], ctx->vreg_types [ins->dreg]);
4213 /* Add stores for volatile variables */
4214 if (spec [MONO_INST_DEST] != ' ' && spec [MONO_INST_DEST] != 'v' && !MONO_IS_STORE_MEMBASE (ins))
4215 emit_volatile_store (ctx, ins->dreg);
4218 if (!has_terminator && bb->next_bb && (bb == cfg->bb_entry || bb->in_count > 0))
4219 LLVMBuildBr (builder, get_bb (ctx, bb->next_bb));
4221 if (bb == cfg->bb_exit && sig->ret->type == MONO_TYPE_VOID)
4222 LLVMBuildRetVoid (builder);
4224 if (bb == cfg->bb_entry)
4225 ctx->last_alloca = LLVMGetLastInstruction (get_bb (ctx, cfg->bb_entry));
4234 * mono_llvm_check_method_supported:
4236 * Do some quick checks to decide whenever cfg->method can be compiled by LLVM, to avoid
4237 * compiling a method twice.
4240 mono_llvm_check_method_supported (MonoCompile *cfg)
4242 MonoMethodHeader *header = cfg->header;
4243 MonoExceptionClause *clause;
4246 if (cfg->method->save_lmf) {
4247 cfg->exception_message = g_strdup ("lmf");
4248 cfg->disable_llvm = TRUE;
4250 if (cfg->disable_llvm)
4254 for (i = 0; i < header->num_clauses; ++i) {
4255 clause = &header->clauses [i];
4257 if (i > 0 && clause->try_offset <= header->clauses [i - 1].handler_offset + header->clauses [i - 1].handler_len) {
4259 * FIXME: Some tests still fail with nested clauses.
4261 cfg->exception_message = g_strdup ("nested clauses");
4262 cfg->disable_llvm = TRUE;
4266 if (cfg->disable_llvm)
4271 if (cfg->method->dynamic) {
4272 cfg->exception_message = g_strdup ("dynamic.");
4273 cfg->disable_llvm = TRUE;
4275 if (cfg->disable_llvm)
4280 * mono_llvm_emit_method:
4282 * Emit LLVM IL from the mono IL, and compile it to native code using LLVM.
4285 mono_llvm_emit_method (MonoCompile *cfg)
4288 MonoMethodSignature *sig;
4290 LLVMTypeRef method_type;
4291 LLVMValueRef method = NULL;
4293 LLVMValueRef *values;
4294 int i, max_block_num, bb_index;
4295 gboolean last = FALSE;
4296 GPtrArray *phi_values;
4297 LLVMCallInfo *linfo;
4299 LLVMModuleRef module;
4301 GPtrArray *bblock_list;
4302 MonoMethodHeader *header;
4303 MonoExceptionClause *clause;
4307 /* The code below might acquire the loader lock, so use it for global locking */
4308 mono_loader_lock ();
4310 /* Used to communicate with the callbacks */
4311 mono_native_tls_set_value (current_cfg_tls_id, cfg);
4313 ctx = g_new0 (EmitContext, 1);
4315 ctx->mempool = cfg->mempool;
4318 * This maps vregs to the LLVM instruction defining them
4320 values = g_new0 (LLVMValueRef, cfg->next_vreg);
4322 * This maps vregs for volatile variables to the LLVM instruction defining their
4325 ctx->addresses = g_new0 (LLVMValueRef, cfg->next_vreg);
4326 ctx->vreg_types = g_new0 (LLVMTypeRef, cfg->next_vreg);
4327 ctx->vreg_cli_types = g_new0 (MonoType*, cfg->next_vreg);
4328 phi_values = g_ptr_array_sized_new (256);
4330 * This signals whenever the vreg was defined by a phi node with no input vars
4331 * (i.e. all its input bblocks end with NOT_REACHABLE).
4333 ctx->is_dead = g_new0 (gboolean, cfg->next_vreg);
4334 /* Whenever the bblock is unreachable */
4335 ctx->unreachable = g_new0 (gboolean, cfg->max_block_num);
4337 bblock_list = g_ptr_array_sized_new (256);
4339 ctx->values = values;
4340 ctx->region_to_handler = g_hash_table_new (NULL, NULL);
4342 if (cfg->compile_aot) {
4343 ctx->lmodule = &aot_module;
4344 method_name = mono_aot_get_method_name (cfg);
4345 cfg->llvm_method_name = g_strdup (method_name);
4347 init_jit_module (cfg->domain);
4348 ctx->lmodule = domain_jit_info (cfg->domain)->llvm_module;
4349 method_name = mono_method_full_name (cfg->method, TRUE);
4352 module = ctx->module = ctx->lmodule->module;
4355 LLVM_FAILURE (ctx, "gsharedvt");
4359 static int count = 0;
4362 if (g_getenv ("LLVM_COUNT")) {
4363 if (count == atoi (g_getenv ("LLVM_COUNT"))) {
4364 printf ("LAST: %s\n", mono_method_full_name (cfg->method, TRUE));
4368 if (count > atoi (g_getenv ("LLVM_COUNT")))
4369 LLVM_FAILURE (ctx, "");
4374 sig = mono_method_signature (cfg->method);
4377 linfo = mono_arch_get_llvm_call_info (cfg, sig);
4379 CHECK_FAILURE (ctx);
4382 linfo->rgctx_arg = TRUE;
4383 method_type = sig_to_llvm_sig_full (ctx, sig, linfo, &sinfo);
4384 CHECK_FAILURE (ctx);
4387 * This maps parameter indexes in the original signature to the indexes in
4388 * the LLVM signature.
4390 ctx->pindexes = sinfo.pindexes;
4392 method = LLVMAddFunction (module, method_name, method_type);
4393 ctx->lmethod = method;
4395 LLVMSetFunctionCallConv (method, LLVMMono1CallConv);
4396 LLVMSetLinkage (method, LLVMPrivateLinkage);
4398 LLVMAddFunctionAttr (method, LLVMUWTable);
4400 if (cfg->compile_aot) {
4401 LLVMSetLinkage (method, LLVMInternalLinkage);
4402 #if LLVM_API_VERSION == 0
4403 /* This causes an assertion in later LLVM versions */
4404 LLVMSetVisibility (method, LLVMHiddenVisibility);
4407 LLVMSetLinkage (method, LLVMPrivateLinkage);
4410 if (cfg->method->save_lmf)
4411 LLVM_FAILURE (ctx, "lmf");
4413 if (sig->pinvoke && cfg->method->wrapper_type != MONO_WRAPPER_RUNTIME_INVOKE)
4414 LLVM_FAILURE (ctx, "pinvoke signature");
4416 header = cfg->header;
4417 for (i = 0; i < header->num_clauses; ++i) {
4418 clause = &header->clauses [i];
4419 if (clause->flags != MONO_EXCEPTION_CLAUSE_FINALLY && clause->flags != MONO_EXCEPTION_CLAUSE_NONE)
4420 LLVM_FAILURE (ctx, "non-finally/catch clause.");
4423 if (linfo->rgctx_arg) {
4424 ctx->rgctx_arg = LLVMGetParam (method, sinfo.rgctx_arg_pindex);
4426 * We mark the rgctx parameter with the inreg attribute, which is mapped to
4427 * MONO_ARCH_RGCTX_REG in the Mono calling convention in llvm, i.e.
4428 * CC_X86_64_Mono in X86CallingConv.td.
4430 LLVMAddAttribute (ctx->rgctx_arg, LLVMInRegAttribute);
4431 LLVMSetValueName (ctx->rgctx_arg, "rgctx");
4433 if (cfg->vret_addr) {
4434 values [cfg->vret_addr->dreg] = LLVMGetParam (method, sinfo.vret_arg_pindex);
4435 LLVMSetValueName (values [cfg->vret_addr->dreg], "vret");
4438 values [cfg->args [0]->dreg] = LLVMGetParam (method, sinfo.this_arg_pindex);
4439 LLVMSetValueName (values [cfg->args [0]->dreg], "this");
4442 names = g_new (char *, sig->param_count);
4443 mono_method_get_param_names (cfg->method, (const char **) names);
4445 for (i = 0; i < sig->param_count; ++i) {
4448 values [cfg->args [i + sig->hasthis]->dreg] = LLVMGetParam (method, sinfo.pindexes [i]);
4449 if (names [i] && names [i][0] != '\0')
4450 name = g_strdup_printf ("arg_%s", names [i]);
4452 name = g_strdup_printf ("arg_%d", i);
4453 LLVMSetValueName (values [cfg->args [i + sig->hasthis]->dreg], name);
4455 if (linfo->args [i + sig->hasthis].storage == LLVMArgVtypeByVal)
4456 LLVMAddAttribute (LLVMGetParam (method, sinfo.pindexes [i]), LLVMByValAttribute);
4461 for (bb = cfg->bb_entry; bb; bb = bb->next_bb)
4462 max_block_num = MAX (max_block_num, bb->block_num);
4463 ctx->bblocks = bblocks = g_new0 (BBInfo, max_block_num + 1);
4465 /* Add branches between non-consecutive bblocks */
4466 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
4467 if (bb->last_ins && MONO_IS_COND_BRANCH_OP (bb->last_ins) &&
4468 bb->next_bb != bb->last_ins->inst_false_bb) {
4470 MonoInst *inst = mono_mempool_alloc0 (cfg->mempool, sizeof (MonoInst));
4471 inst->opcode = OP_BR;
4472 inst->inst_target_bb = bb->last_ins->inst_false_bb;
4473 mono_bblock_add_inst (bb, inst);
4478 * The INDIRECT flag added by OP_LDADDR inhibits optimizations, even if the LDADDR
4479 * was later optimized away, so clear these flags, and add them back for the still
4480 * present OP_LDADDR instructions.
4482 for (i = 0; i < cfg->next_vreg; ++i) {
4485 ins = get_vreg_to_inst (cfg, i);
4486 if (ins && ins != cfg->rgctx_var)
4487 ins->flags &= ~MONO_INST_INDIRECT;
4491 * Make a first pass over the code to precreate PHI nodes/set INDIRECT flags.
4493 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
4495 LLVMBuilderRef builder;
4497 char dname_buf[128];
4499 builder = create_builder (ctx);
4501 for (ins = bb->code; ins; ins = ins->next) {
4502 switch (ins->opcode) {
4507 LLVMTypeRef phi_type = llvm_type_to_stack_type (type_to_llvm_type (ctx, &ins->klass->byval_arg));
4509 CHECK_FAILURE (ctx);
4511 if (ins->opcode == OP_VPHI) {
4512 /* Treat valuetype PHI nodes as operating on the address itself */
4513 g_assert (ins->klass);
4514 phi_type = LLVMPointerType (type_to_llvm_type (ctx, &ins->klass->byval_arg), 0);
4518 * Have to precreate these, as they can be referenced by
4519 * earlier instructions.
4521 sprintf (dname_buf, "t%d", ins->dreg);
4523 values [ins->dreg] = LLVMBuildPhi (builder, phi_type, dname);
4525 if (ins->opcode == OP_VPHI)
4526 ctx->addresses [ins->dreg] = values [ins->dreg];
4528 g_ptr_array_add (phi_values, values [ins->dreg]);
4531 * Set the expected type of the incoming arguments since these have
4532 * to have the same type.
4534 for (i = 0; i < ins->inst_phi_args [0]; i++) {
4535 int sreg1 = ins->inst_phi_args [i + 1];
4538 ctx->vreg_types [sreg1] = phi_type;
4543 ((MonoInst*)ins->inst_p0)->flags |= MONO_INST_INDIRECT;
4552 * Create an ordering for bblocks, use the depth first order first, then
4553 * put the exception handling bblocks last.
4555 for (bb_index = 0; bb_index < cfg->num_bblocks; ++bb_index) {
4556 bb = cfg->bblocks [bb_index];
4557 if (!(bb->region != -1 && !MONO_BBLOCK_IS_IN_REGION (bb, MONO_REGION_TRY))) {
4558 g_ptr_array_add (bblock_list, bb);
4559 bblocks [bb->block_num].added = TRUE;
4563 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
4564 if (!bblocks [bb->block_num].added)
4565 g_ptr_array_add (bblock_list, bb);
4569 * Second pass: generate code.
4571 for (bb_index = 0; bb_index < bblock_list->len; ++bb_index) {
4572 bb = g_ptr_array_index (bblock_list, bb_index);
4574 if (!(bb == cfg->bb_entry || bb->in_count > 0))
4577 process_bb (ctx, bb);
4578 CHECK_FAILURE (ctx);
4581 /* Add incoming phi values */
4582 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
4583 GSList *l, *ins_list;
4585 ins_list = bblocks [bb->block_num].phi_nodes;
4587 for (l = ins_list; l; l = l->next) {
4588 PhiNode *node = l->data;
4589 MonoInst *phi = node->phi;
4590 int sreg1 = node->sreg;
4591 LLVMBasicBlockRef in_bb;
4596 in_bb = get_end_bb (ctx, node->in_bb);
4598 if (ctx->unreachable [node->in_bb->block_num])
4601 if (!values [sreg1])
4602 /* Can happen with values in EH clauses */
4603 LLVM_FAILURE (ctx, "incoming phi sreg1");
4605 if (phi->opcode == OP_VPHI) {
4606 g_assert (LLVMTypeOf (ctx->addresses [sreg1]) == LLVMTypeOf (values [phi->dreg]));
4607 LLVMAddIncoming (values [phi->dreg], &ctx->addresses [sreg1], &in_bb, 1);
4609 if (LLVMTypeOf (values [sreg1]) != LLVMTypeOf (values [phi->dreg]))
4611 LLVM_FAILURE (ctx, "incoming phi arg type mismatch");
4612 g_assert (LLVMTypeOf (values [sreg1]) == LLVMTypeOf (values [phi->dreg]));
4613 LLVMAddIncoming (values [phi->dreg], &values [sreg1], &in_bb, 1);
4618 /* Create the SWITCH statements for ENDFINALLY instructions */
4619 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
4620 BBInfo *info = &bblocks [bb->block_num];
4622 for (l = info->endfinally_switch_ins_list; l; l = l->next) {
4623 LLVMValueRef switch_ins = l->data;
4624 GSList *bb_list = info->call_handler_return_bbs;
4626 for (i = 0; i < g_slist_length (bb_list); ++i)
4627 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), i + 1, FALSE), g_slist_nth (bb_list, i)->data);
4631 if (cfg->verbose_level > 1)
4632 mono_llvm_dump_value (method);
4634 if (cfg->compile_aot)
4635 mark_as_used (ctx->lmodule, method);
4637 if (cfg->compile_aot) {
4638 LLVMValueRef md_args [16];
4639 LLVMValueRef md_node;
4642 method_index = mono_aot_get_method_index (cfg->orig_method);
4643 md_args [0] = LLVMMDString (method_name, strlen (method_name));
4644 md_args [1] = LLVMConstInt (LLVMInt32Type (), method_index, FALSE);
4645 md_node = LLVMMDNode (md_args, 2);
4646 LLVMAddNamedMetadataOperand (module, "mono.function_indexes", md_node);
4647 //LLVMSetMetadata (method, md_kind, LLVMMDNode (&md_arg, 1));
4650 if (cfg->compile_aot) {
4651 /* Don't generate native code, keep the LLVM IR */
4652 if (cfg->compile_aot && cfg->verbose_level)
4653 printf ("%s emitted as %s\n", mono_method_full_name (cfg->method, TRUE), method_name);
4655 //LLVMVerifyFunction(method, 0);
4657 mono_llvm_optimize_method (ctx->lmodule->mono_ee, method);
4659 if (cfg->verbose_level > 1)
4660 mono_llvm_dump_value (method);
4662 cfg->native_code = LLVMGetPointerToGlobal (ctx->lmodule->ee, method);
4664 /* Set by emit_cb */
4665 g_assert (cfg->code_len);
4667 /* FIXME: Free the LLVM IL for the function */
4675 /* Need to add unused phi nodes as they can be referenced by other values */
4676 LLVMBasicBlockRef phi_bb = LLVMAppendBasicBlock (method, "PHI_BB");
4677 LLVMBuilderRef builder;
4679 builder = create_builder (ctx);
4680 LLVMPositionBuilderAtEnd (builder, phi_bb);
4682 for (i = 0; i < phi_values->len; ++i) {
4683 LLVMValueRef v = g_ptr_array_index (phi_values, i);
4684 if (LLVMGetInstructionParent (v) == NULL)
4685 LLVMInsertIntoBuilder (builder, v);
4688 LLVMDeleteFunction (method);
4693 g_free (ctx->addresses);
4694 g_free (ctx->vreg_types);
4695 g_free (ctx->vreg_cli_types);
4696 g_free (ctx->pindexes);
4697 g_free (ctx->is_dead);
4698 g_free (ctx->unreachable);
4699 g_ptr_array_free (phi_values, TRUE);
4700 g_free (ctx->bblocks);
4701 g_hash_table_destroy (ctx->region_to_handler);
4702 g_free (method_name);
4703 g_ptr_array_free (bblock_list, TRUE);
4705 for (l = ctx->builders; l; l = l->next) {
4706 LLVMBuilderRef builder = l->data;
4707 LLVMDisposeBuilder (builder);
4712 mono_native_tls_set_value (current_cfg_tls_id, NULL);
4714 mono_loader_unlock ();
4718 * mono_llvm_emit_call:
4720 * Same as mono_arch_emit_call () for LLVM.
4723 mono_llvm_emit_call (MonoCompile *cfg, MonoCallInst *call)
4726 MonoMethodSignature *sig;
4727 int i, n, stack_size;
4732 sig = call->signature;
4733 n = sig->param_count + sig->hasthis;
4735 call->cinfo = mono_arch_get_llvm_call_info (cfg, sig);
4737 if (cfg->disable_llvm)
4740 if (sig->call_convention == MONO_CALL_VARARG) {
4741 cfg->exception_message = g_strdup ("varargs");
4742 cfg->disable_llvm = TRUE;
4745 for (i = 0; i < n; ++i) {
4748 ainfo = call->cinfo->args + i;
4750 in = call->args [i];
4752 /* Simply remember the arguments */
4753 switch (ainfo->storage) {
4755 case LLVMArgInFPReg: {
4756 MonoType *t = (sig->hasthis && i == 0) ? &mono_get_intptr_class ()->byval_arg : sig->params [i - sig->hasthis];
4759 opcode = mono_type_to_regmove (cfg, t);
4760 if (opcode == OP_FMOVE) {
4761 MONO_INST_NEW (cfg, ins, OP_FMOVE);
4762 ins->dreg = mono_alloc_freg (cfg);
4763 } else if (opcode == OP_LMOVE) {
4764 MONO_INST_NEW (cfg, ins, OP_LMOVE);
4765 ins->dreg = mono_alloc_lreg (cfg);
4767 MONO_INST_NEW (cfg, ins, OP_MOVE);
4768 ins->dreg = mono_alloc_ireg (cfg);
4770 ins->sreg1 = in->dreg;
4773 case LLVMArgVtypeByVal:
4774 case LLVMArgVtypeInReg:
4775 MONO_INST_NEW (cfg, ins, OP_LLVM_OUTARG_VT);
4776 ins->dreg = mono_alloc_ireg (cfg);
4777 ins->sreg1 = in->dreg;
4778 ins->klass = mono_class_from_mono_type (sig->params [i - sig->hasthis]);
4781 call->cinfo = mono_arch_get_llvm_call_info (cfg, sig);
4782 cfg->exception_message = g_strdup ("ainfo->storage");
4783 cfg->disable_llvm = TRUE;
4787 if (!cfg->disable_llvm) {
4788 MONO_ADD_INS (cfg->cbb, ins);
4789 mono_call_inst_add_outarg_reg (cfg, call, ins->dreg, 0, FALSE);
4794 static unsigned char*
4795 alloc_cb (LLVMValueRef function, int size)
4799 cfg = mono_native_tls_get_value (current_cfg_tls_id);
4803 return mono_domain_code_reserve (cfg->domain, size);
4805 return mono_domain_code_reserve (mono_domain_get (), size);
4810 emitted_cb (LLVMValueRef function, void *start, void *end)
4814 cfg = mono_native_tls_get_value (current_cfg_tls_id);
4816 cfg->code_len = (guint8*)end - (guint8*)start;
4820 exception_cb (void *data)
4823 MonoJitExceptionInfo *ei;
4824 guint32 ei_len, i, j, nested_len, nindex;
4825 gpointer *type_info;
4826 int this_reg, this_offset;
4828 cfg = mono_native_tls_get_value (current_cfg_tls_id);
4832 * data points to a DWARF FDE structure, convert it to our unwind format and
4834 * An alternative would be to save it directly, and modify our unwinder to work
4837 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);
4838 if (cfg->verbose_level > 1)
4839 mono_print_unwind_info (cfg->encoded_unwind_ops, cfg->encoded_unwind_ops_len);
4841 /* Count nested clauses */
4843 for (i = 0; i < ei_len; ++i) {
4844 for (j = 0; j < ei_len; ++j) {
4845 gint32 cindex1 = *(gint32*)type_info [i];
4846 MonoExceptionClause *clause1 = &cfg->header->clauses [cindex1];
4847 gint32 cindex2 = *(gint32*)type_info [j];
4848 MonoExceptionClause *clause2 = &cfg->header->clauses [cindex2];
4850 if (cindex1 != cindex2 && clause1->try_offset >= clause2->try_offset && clause1->handler_offset <= clause2->handler_offset) {
4856 cfg->llvm_ex_info = mono_mempool_alloc0 (cfg->mempool, (ei_len + nested_len) * sizeof (MonoJitExceptionInfo));
4857 cfg->llvm_ex_info_len = ei_len + nested_len;
4858 memcpy (cfg->llvm_ex_info, ei, ei_len * sizeof (MonoJitExceptionInfo));
4859 /* Fill the rest of the information from the type info */
4860 for (i = 0; i < ei_len; ++i) {
4861 gint32 clause_index = *(gint32*)type_info [i];
4862 MonoExceptionClause *clause = &cfg->header->clauses [clause_index];
4864 cfg->llvm_ex_info [i].flags = clause->flags;
4865 cfg->llvm_ex_info [i].data.catch_class = clause->data.catch_class;
4869 * For nested clauses, the LLVM produced exception info associates the try interval with
4870 * the innermost handler, while mono expects it to be associated with all nesting clauses.
4872 /* FIXME: These should be order with the normal clauses */
4874 for (i = 0; i < ei_len; ++i) {
4875 for (j = 0; j < ei_len; ++j) {
4876 gint32 cindex1 = *(gint32*)type_info [i];
4877 MonoExceptionClause *clause1 = &cfg->header->clauses [cindex1];
4878 gint32 cindex2 = *(gint32*)type_info [j];
4879 MonoExceptionClause *clause2 = &cfg->header->clauses [cindex2];
4881 if (cindex1 != cindex2 && clause1->try_offset >= clause2->try_offset && clause1->handler_offset <= clause2->handler_offset) {
4883 * The try interval comes from the nested clause, everything else from the
4886 memcpy (&cfg->llvm_ex_info [nindex], &cfg->llvm_ex_info [j], sizeof (MonoJitExceptionInfo));
4887 cfg->llvm_ex_info [nindex].try_start = cfg->llvm_ex_info [i].try_start;
4888 cfg->llvm_ex_info [nindex].try_end = cfg->llvm_ex_info [i].try_end;
4893 g_assert (nindex == ei_len + nested_len);
4894 cfg->llvm_this_reg = this_reg;
4895 cfg->llvm_this_offset = this_offset;
4897 /* type_info [i] is cfg mempool allocated, no need to free it */
4904 dlsym_cb (const char *name, void **symbol)
4910 if (!strcmp (name, "__bzero")) {
4911 *symbol = (void*)bzero;
4913 current = mono_dl_open (NULL, 0, NULL);
4916 err = mono_dl_symbol (current, name, symbol);
4918 mono_dl_close (current);
4920 #ifdef MONO_ARCH_HAVE_CREATE_LLVM_NATIVE_THUNK
4921 *symbol = (char*)mono_arch_create_llvm_native_thunk (mono_domain_get (), (guint8*)(*symbol));
4927 AddFunc (LLVMModuleRef module, const char *name, LLVMTypeRef ret_type, LLVMTypeRef *param_types, int nparams)
4929 LLVMAddFunction (module, name, LLVMFunctionType (ret_type, param_types, nparams, FALSE));
4933 AddFunc2 (LLVMModuleRef module, const char *name, LLVMTypeRef ret_type, LLVMTypeRef param_type1, LLVMTypeRef param_type2)
4935 LLVMTypeRef param_types [4];
4937 param_types [0] = param_type1;
4938 param_types [1] = param_type2;
4940 AddFunc (module, name, ret_type, param_types, 2);
4944 add_intrinsics (LLVMModuleRef module)
4946 /* Emit declarations of instrinsics */
4948 * It would be nicer to emit only the intrinsics actually used, but LLVM's Module
4949 * type doesn't seem to do any locking.
4952 LLVMTypeRef memset_params [] = { LLVMPointerType (LLVMInt8Type (), 0), LLVMInt8Type (), LLVMInt32Type (), LLVMInt32Type (), LLVMInt1Type () };
4954 memset_param_count = 5;
4955 memset_func_name = "llvm.memset.p0i8.i32";
4957 LLVMAddFunction (module, memset_func_name, LLVMFunctionType (LLVMVoidType (), memset_params, memset_param_count, FALSE));
4961 LLVMTypeRef memcpy_params [] = { LLVMPointerType (LLVMInt8Type (), 0), LLVMPointerType (LLVMInt8Type (), 0), LLVMInt32Type (), LLVMInt32Type (), LLVMInt1Type () };
4963 memcpy_param_count = 5;
4964 memcpy_func_name = "llvm.memcpy.p0i8.p0i8.i32";
4966 LLVMAddFunction (module, memcpy_func_name, LLVMFunctionType (LLVMVoidType (), memcpy_params, memcpy_param_count, FALSE));
4970 LLVMTypeRef params [] = { LLVMDoubleType () };
4972 LLVMAddFunction (module, "llvm.sin.f64", LLVMFunctionType (LLVMDoubleType (), params, 1, FALSE));
4973 LLVMAddFunction (module, "llvm.cos.f64", LLVMFunctionType (LLVMDoubleType (), params, 1, FALSE));
4974 LLVMAddFunction (module, "llvm.sqrt.f64", LLVMFunctionType (LLVMDoubleType (), params, 1, FALSE));
4976 /* This isn't an intrinsic, instead llvm seems to special case it by name */
4977 LLVMAddFunction (module, "fabs", LLVMFunctionType (LLVMDoubleType (), params, 1, FALSE));
4981 LLVMTypeRef ovf_res_i32 [] = { LLVMInt32Type (), LLVMInt1Type () };
4982 LLVMTypeRef ovf_params_i32 [] = { LLVMInt32Type (), LLVMInt32Type () };
4984 LLVMAddFunction (module, "llvm.sadd.with.overflow.i32", LLVMFunctionType (LLVMStructType (ovf_res_i32, 2, FALSE), ovf_params_i32, 2, FALSE));
4985 LLVMAddFunction (module, "llvm.uadd.with.overflow.i32", LLVMFunctionType (LLVMStructType (ovf_res_i32, 2, FALSE), ovf_params_i32, 2, FALSE));
4986 LLVMAddFunction (module, "llvm.ssub.with.overflow.i32", LLVMFunctionType (LLVMStructType (ovf_res_i32, 2, FALSE), ovf_params_i32, 2, FALSE));
4987 LLVMAddFunction (module, "llvm.usub.with.overflow.i32", LLVMFunctionType (LLVMStructType (ovf_res_i32, 2, FALSE), ovf_params_i32, 2, FALSE));
4988 LLVMAddFunction (module, "llvm.smul.with.overflow.i32", LLVMFunctionType (LLVMStructType (ovf_res_i32, 2, FALSE), ovf_params_i32, 2, FALSE));
4989 LLVMAddFunction (module, "llvm.umul.with.overflow.i32", LLVMFunctionType (LLVMStructType (ovf_res_i32, 2, FALSE), ovf_params_i32, 2, FALSE));
4993 LLVMTypeRef ovf_res_i64 [] = { LLVMInt64Type (), LLVMInt1Type () };
4994 LLVMTypeRef ovf_params_i64 [] = { LLVMInt64Type (), LLVMInt64Type () };
4996 LLVMAddFunction (module, "llvm.sadd.with.overflow.i64", LLVMFunctionType (LLVMStructType (ovf_res_i64, 2, FALSE), ovf_params_i64, 2, FALSE));
4997 LLVMAddFunction (module, "llvm.uadd.with.overflow.i64", LLVMFunctionType (LLVMStructType (ovf_res_i64, 2, FALSE), ovf_params_i64, 2, FALSE));
4998 LLVMAddFunction (module, "llvm.ssub.with.overflow.i64", LLVMFunctionType (LLVMStructType (ovf_res_i64, 2, FALSE), ovf_params_i64, 2, FALSE));
4999 LLVMAddFunction (module, "llvm.usub.with.overflow.i64", LLVMFunctionType (LLVMStructType (ovf_res_i64, 2, FALSE), ovf_params_i64, 2, FALSE));
5000 LLVMAddFunction (module, "llvm.smul.with.overflow.i64", LLVMFunctionType (LLVMStructType (ovf_res_i64, 2, FALSE), ovf_params_i64, 2, FALSE));
5001 LLVMAddFunction (module, "llvm.umul.with.overflow.i64", LLVMFunctionType (LLVMStructType (ovf_res_i64, 2, FALSE), ovf_params_i64, 2, FALSE));
5006 LLVMTypeRef arg_types [2];
5007 LLVMTypeRef ret_type;
5009 arg_types [0] = LLVMPointerType (LLVMInt8Type (), 0);
5010 arg_types [1] = LLVMPointerType (LLVMInt8Type (), 0);
5011 ret_type = LLVMInt32Type ();
5013 LLVMAddFunction (module, "mono_personality", LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE));
5015 LLVMAddFunction (module, "llvm_resume_unwind_trampoline", LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE));
5018 /* SSE intrinsics */
5019 #if defined(TARGET_X86) || defined(TARGET_AMD64)
5021 LLVMTypeRef ret_type, arg_types [16];
5024 ret_type = type_to_simd_type (MONO_TYPE_I4);
5025 arg_types [0] = ret_type;
5026 arg_types [1] = ret_type;
5027 AddFunc (module, "llvm.x86.sse41.pminud", ret_type, arg_types, 2);
5028 AddFunc (module, "llvm.x86.sse41.pmaxud", ret_type, arg_types, 2);
5030 ret_type = type_to_simd_type (MONO_TYPE_I2);
5031 arg_types [0] = ret_type;
5032 arg_types [1] = ret_type;
5033 AddFunc (module, "llvm.x86.sse41.pminuw", ret_type, arg_types, 2);
5034 AddFunc (module, "llvm.x86.sse2.pmins.w", ret_type, arg_types, 2);
5035 AddFunc (module, "llvm.x86.sse41.pmaxuw", ret_type, arg_types, 2);
5036 AddFunc (module, "llvm.x86.sse2.padds.w", ret_type, arg_types, 2);
5037 AddFunc (module, "llvm.x86.sse2.psubs.w", ret_type, arg_types, 2);
5038 AddFunc (module, "llvm.x86.sse2.paddus.w", ret_type, arg_types, 2);
5039 AddFunc (module, "llvm.x86.sse2.psubus.w", ret_type, arg_types, 2);
5040 AddFunc (module, "llvm.x86.sse2.pavg.w", ret_type, arg_types, 2);
5041 AddFunc (module, "llvm.x86.sse2.pmulh.w", ret_type, arg_types, 2);
5042 AddFunc (module, "llvm.x86.sse2.pmulhu.w", ret_type, arg_types, 2);
5044 ret_type = type_to_simd_type (MONO_TYPE_I1);
5045 arg_types [0] = ret_type;
5046 arg_types [1] = ret_type;
5047 AddFunc (module, "llvm.x86.sse2.pminu.b", ret_type, arg_types, 2);
5048 AddFunc (module, "llvm.x86.sse2.pmaxu.b", ret_type, arg_types, 2);
5049 AddFunc (module, "llvm.x86.sse2.padds.b", ret_type, arg_types, 2);
5050 AddFunc (module, "llvm.x86.sse2.psubs.b", ret_type, arg_types, 2);
5051 AddFunc (module, "llvm.x86.sse2.paddus.b", ret_type, arg_types, 2);
5052 AddFunc (module, "llvm.x86.sse2.psubus.b", ret_type, arg_types, 2);
5053 AddFunc (module, "llvm.x86.sse2.pavg.b", ret_type, arg_types, 2);
5055 ret_type = type_to_simd_type (MONO_TYPE_R8);
5056 arg_types [0] = ret_type;
5057 arg_types [1] = ret_type;
5058 AddFunc (module, "llvm.x86.sse2.min.pd", ret_type, arg_types, 2);
5059 AddFunc (module, "llvm.x86.sse2.max.pd", ret_type, arg_types, 2);
5060 AddFunc (module, "llvm.x86.sse3.hadd.pd", ret_type, arg_types, 2);
5061 AddFunc (module, "llvm.x86.sse3.hsub.pd", ret_type, arg_types, 2);
5062 AddFunc (module, "llvm.x86.sse3.addsub.pd", ret_type, arg_types, 2);
5064 ret_type = type_to_simd_type (MONO_TYPE_R4);
5065 arg_types [0] = ret_type;
5066 arg_types [1] = ret_type;
5067 AddFunc (module, "llvm.x86.sse.min.ps", ret_type, arg_types, 2);
5068 AddFunc (module, "llvm.x86.sse.max.ps", ret_type, arg_types, 2);
5069 AddFunc (module, "llvm.x86.sse3.hadd.ps", ret_type, arg_types, 2);
5070 AddFunc (module, "llvm.x86.sse3.hsub.ps", ret_type, arg_types, 2);
5071 AddFunc (module, "llvm.x86.sse3.addsub.ps", ret_type, arg_types, 2);
5074 ret_type = type_to_simd_type (MONO_TYPE_I1);
5075 arg_types [0] = type_to_simd_type (MONO_TYPE_I2);
5076 arg_types [1] = type_to_simd_type (MONO_TYPE_I2);
5077 AddFunc (module, "llvm.x86.sse2.packsswb.128", ret_type, arg_types, 2);
5078 AddFunc (module, "llvm.x86.sse2.packuswb.128", ret_type, arg_types, 2);
5079 ret_type = type_to_simd_type (MONO_TYPE_I2);
5080 arg_types [0] = type_to_simd_type (MONO_TYPE_I4);
5081 arg_types [1] = type_to_simd_type (MONO_TYPE_I4);
5082 AddFunc (module, "llvm.x86.sse2.packssdw.128", ret_type, arg_types, 2);
5083 AddFunc (module, "llvm.x86.sse41.packusdw", ret_type, arg_types, 2);
5086 ret_type = type_to_simd_type (MONO_TYPE_R8);
5087 arg_types [0] = ret_type;
5088 arg_types [1] = ret_type;
5089 arg_types [2] = LLVMInt8Type ();
5090 AddFunc (module, "llvm.x86.sse2.cmp.pd", ret_type, arg_types, 3);
5091 ret_type = type_to_simd_type (MONO_TYPE_R4);
5092 arg_types [0] = ret_type;
5093 arg_types [1] = ret_type;
5094 arg_types [2] = LLVMInt8Type ();
5095 AddFunc (module, "llvm.x86.sse.cmp.ps", ret_type, arg_types, 3);
5097 /* Conversion ops */
5098 ret_type = type_to_simd_type (MONO_TYPE_R8);
5099 arg_types [0] = type_to_simd_type (MONO_TYPE_I4);
5100 AddFunc (module, "llvm.x86.sse2.cvtdq2pd", ret_type, arg_types, 1);
5101 ret_type = type_to_simd_type (MONO_TYPE_R4);
5102 arg_types [0] = type_to_simd_type (MONO_TYPE_I4);
5103 AddFunc (module, "llvm.x86.sse2.cvtdq2ps", ret_type, arg_types, 1);
5104 ret_type = type_to_simd_type (MONO_TYPE_I4);
5105 arg_types [0] = type_to_simd_type (MONO_TYPE_R8);
5106 AddFunc (module, "llvm.x86.sse2.cvtpd2dq", ret_type, arg_types, 1);
5107 ret_type = type_to_simd_type (MONO_TYPE_I4);
5108 arg_types [0] = type_to_simd_type (MONO_TYPE_R4);
5109 AddFunc (module, "llvm.x86.sse2.cvtps2dq", ret_type, arg_types, 1);
5110 ret_type = type_to_simd_type (MONO_TYPE_R4);
5111 arg_types [0] = type_to_simd_type (MONO_TYPE_R8);
5112 AddFunc (module, "llvm.x86.sse2.cvtpd2ps", ret_type, arg_types, 1);
5113 ret_type = type_to_simd_type (MONO_TYPE_R8);
5114 arg_types [0] = type_to_simd_type (MONO_TYPE_R4);
5115 AddFunc (module, "llvm.x86.sse2.cvtps2pd", ret_type, arg_types, 1);
5117 ret_type = type_to_simd_type (MONO_TYPE_I4);
5118 arg_types [0] = type_to_simd_type (MONO_TYPE_R8);
5119 AddFunc (module, "llvm.x86.sse2.cvttpd2dq", ret_type, arg_types, 1);
5120 ret_type = type_to_simd_type (MONO_TYPE_I4);
5121 arg_types [0] = type_to_simd_type (MONO_TYPE_R4);
5122 AddFunc (module, "llvm.x86.sse2.cvttps2dq", ret_type, arg_types, 1);
5125 ret_type = type_to_simd_type (MONO_TYPE_R8);
5126 arg_types [0] = ret_type;
5127 AddFunc (module, "llvm.x86.sse2.sqrt.pd", ret_type, arg_types, 1);
5128 ret_type = type_to_simd_type (MONO_TYPE_R4);
5129 arg_types [0] = ret_type;
5130 AddFunc (module, "llvm.x86.sse.sqrt.ps", ret_type, arg_types, 1);
5131 ret_type = type_to_simd_type (MONO_TYPE_R4);
5132 arg_types [0] = ret_type;
5133 AddFunc (module, "llvm.x86.sse.rsqrt.ps", ret_type, arg_types, 1);
5134 ret_type = type_to_simd_type (MONO_TYPE_R4);
5135 arg_types [0] = ret_type;
5136 AddFunc (module, "llvm.x86.sse.rcp.ps", ret_type, arg_types, 1);
5139 ret_type = type_to_simd_type (MONO_TYPE_I2);
5140 arg_types [0] = ret_type;
5141 arg_types [1] = LLVMInt32Type ();
5142 AddFunc (module, "llvm.x86.sse2.psrli.w", ret_type, arg_types, 2);
5143 AddFunc (module, "llvm.x86.sse2.psrai.w", ret_type, arg_types, 2);
5144 AddFunc (module, "llvm.x86.sse2.pslli.w", ret_type, arg_types, 2);
5145 ret_type = type_to_simd_type (MONO_TYPE_I4);
5146 arg_types [0] = ret_type;
5147 arg_types [1] = LLVMInt32Type ();
5148 AddFunc (module, "llvm.x86.sse2.psrli.d", ret_type, arg_types, 2);
5149 AddFunc (module, "llvm.x86.sse2.psrai.d", ret_type, arg_types, 2);
5150 AddFunc (module, "llvm.x86.sse2.pslli.d", ret_type, arg_types, 2);
5151 ret_type = type_to_simd_type (MONO_TYPE_I8);
5152 arg_types [0] = ret_type;
5153 arg_types [1] = LLVMInt32Type ();
5154 AddFunc (module, "llvm.x86.sse2.psrli.q", ret_type, arg_types, 2);
5155 AddFunc (module, "llvm.x86.sse2.pslli.q", ret_type, arg_types, 2);
5158 ret_type = LLVMInt32Type ();
5159 arg_types [0] = type_to_simd_type (MONO_TYPE_I1);
5160 AddFunc (module, "llvm.x86.sse2.pmovmskb.128", ret_type, arg_types, 1);
5163 AddFunc (module, "llvm.x86.sse2.pause", LLVMVoidType (), NULL, 0);
5166 /* Load/Store intrinsics */
5168 LLVMTypeRef arg_types [5];
5172 for (i = 1; i <= 8; i *= 2) {
5173 arg_types [0] = LLVMPointerType (LLVMIntType (i * 8), 0);
5174 arg_types [1] = LLVMInt32Type ();
5175 arg_types [2] = LLVMInt1Type ();
5176 sprintf (name, "llvm.mono.load.i%d.p0i%d", i * 8, i * 8);
5177 LLVMAddFunction (module, name, LLVMFunctionType (LLVMIntType (i * 8), arg_types, 3, FALSE));
5179 arg_types [0] = LLVMIntType (i * 8);
5180 arg_types [1] = LLVMPointerType (LLVMIntType (i * 8), 0);
5181 arg_types [2] = LLVMInt32Type ();
5182 arg_types [3] = LLVMInt1Type ();
5183 sprintf (name, "llvm.mono.store.i%d.p0i%d", i * 8, i * 8);
5184 LLVMAddFunction (module, name, LLVMFunctionType (LLVMVoidType (), arg_types, 4, FALSE));
5190 add_types (MonoLLVMModule *lmodule)
5192 lmodule->ptr_type = LLVMPointerType (sizeof (gpointer) == 8 ? LLVMInt64Type () : LLVMInt32Type (), 0);
5196 mono_llvm_init (void)
5198 mono_native_tls_alloc (¤t_cfg_tls_id, NULL);
5202 init_jit_module (MonoDomain *domain)
5204 MonoJitICallInfo *info;
5205 MonoJitDomainInfo *dinfo;
5206 MonoLLVMModule *module;
5209 dinfo = domain_jit_info (domain);
5210 if (dinfo->llvm_module)
5213 mono_loader_lock ();
5215 if (dinfo->llvm_module) {
5216 mono_loader_unlock ();
5220 module = g_new0 (MonoLLVMModule, 1);
5222 name = g_strdup_printf ("mono-%s", domain->friendly_name);
5223 module->module = LLVMModuleCreateWithName (name);
5225 module->mono_ee = mono_llvm_create_ee (LLVMCreateModuleProviderForExistingModule (module->module), alloc_cb, emitted_cb, exception_cb, dlsym_cb, &module->ee);
5227 add_intrinsics (module->module);
5230 module->llvm_types = g_hash_table_new (NULL, NULL);
5232 info = mono_find_jit_icall_by_name ("llvm_resume_unwind_trampoline");
5234 LLVMAddGlobalMapping (module->ee, LLVMGetNamedFunction (module->module, "llvm_resume_unwind_trampoline"), (void*)info->func);
5236 mono_memory_barrier ();
5238 dinfo->llvm_module = module;
5240 mono_loader_unlock ();
5244 mono_llvm_cleanup (void)
5246 if (aot_module.module)
5247 LLVMDisposeModule (aot_module.module);
5249 LLVMContextDispose (LLVMGetGlobalContext ());
5253 mono_llvm_free_domain_info (MonoDomain *domain)
5255 MonoJitDomainInfo *info = domain_jit_info (domain);
5256 MonoLLVMModule *module = info->llvm_module;
5262 if (module->llvm_types)
5263 g_hash_table_destroy (module->llvm_types);
5265 mono_llvm_dispose_ee (module->mono_ee);
5267 if (module->bb_names) {
5268 for (i = 0; i < module->bb_names_len; ++i)
5269 g_free (module->bb_names [i]);
5270 g_free (module->bb_names);
5272 //LLVMDisposeModule (module->module);
5276 info->llvm_module = NULL;
5280 mono_llvm_create_aot_module (const char *got_symbol)
5282 /* Delete previous module */
5283 if (aot_module.plt_entries)
5284 g_hash_table_destroy (aot_module.plt_entries);
5285 if (aot_module.module)
5286 LLVMDisposeModule (aot_module.module);
5288 memset (&aot_module, 0, sizeof (aot_module));
5290 aot_module.module = LLVMModuleCreateWithName ("aot");
5291 aot_module.got_symbol = got_symbol;
5293 add_intrinsics (aot_module.module);
5294 add_types (&aot_module);
5298 * We couldn't compute the type of the LLVM global representing the got because
5299 * its size is only known after all the methods have been emitted. So create
5300 * a dummy variable, and replace all uses it with the real got variable when
5301 * its size is known in mono_llvm_emit_aot_module ().
5304 LLVMTypeRef got_type = LLVMArrayType (aot_module.ptr_type, 0);
5306 aot_module.got_var = LLVMAddGlobal (aot_module.module, got_type, "mono_dummy_got");
5307 LLVMSetInitializer (aot_module.got_var, LLVMConstNull (got_type));
5310 /* Add a dummy personality function */
5312 LLVMBasicBlockRef lbb;
5313 LLVMBuilderRef lbuilder;
5314 LLVMValueRef personality;
5316 personality = LLVMAddFunction (aot_module.module, "mono_aot_personality", LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE));
5317 LLVMSetLinkage (personality, LLVMInternalLinkage);
5318 lbb = LLVMAppendBasicBlock (personality, "BB0");
5319 lbuilder = LLVMCreateBuilder ();
5320 LLVMPositionBuilderAtEnd (lbuilder, lbb);
5321 LLVMBuildRetVoid (lbuilder);
5324 aot_module.llvm_types = g_hash_table_new (NULL, NULL);
5325 aot_module.plt_entries = g_hash_table_new (g_str_hash, g_str_equal);
5329 * Emit the aot module into the LLVM bitcode file FILENAME.
5332 mono_llvm_emit_aot_module (const char *filename, int got_size)
5334 LLVMTypeRef got_type;
5335 LLVMValueRef real_got;
5338 * Create the real got variable and replace all uses of the dummy variable with
5341 got_type = LLVMArrayType (aot_module.ptr_type, got_size);
5342 real_got = LLVMAddGlobal (aot_module.module, got_type, aot_module.got_symbol);
5343 LLVMSetInitializer (real_got, LLVMConstNull (got_type));
5344 LLVMSetLinkage (real_got, LLVMInternalLinkage);
5346 mono_llvm_replace_uses_of (aot_module.got_var, real_got);
5348 mark_as_used (&aot_module, real_got);
5350 /* Delete the dummy got so it doesn't become a global */
5351 LLVMDeleteGlobal (aot_module.got_var);
5353 emit_llvm_used (&aot_module);
5359 if (LLVMVerifyModule (aot_module.module, LLVMReturnStatusAction, &verifier_err)) {
5360 g_assert_not_reached ();
5365 LLVMWriteBitcodeToFile (aot_module.module, filename);
5370 - Emit LLVM IR from the mono IR using the LLVM C API.
5371 - The original arch specific code remains, so we can fall back to it if we run
5372 into something we can't handle.
5376 A partial list of issues:
5377 - Handling of opcodes which can throw exceptions.
5379 In the mono JIT, these are implemented using code like this:
5386 push throw_pos - method
5387 call <exception trampoline>
5389 The problematic part is push throw_pos - method, which cannot be represented
5390 in the LLVM IR, since it does not support label values.
5391 -> this can be implemented in AOT mode using inline asm + labels, but cannot
5392 be implemented in JIT mode ?
5393 -> a possible but slower implementation would use the normal exception
5394 throwing code but it would need to control the placement of the throw code
5395 (it needs to be exactly after the compare+branch).
5396 -> perhaps add a PC offset intrinsics ?
5398 - efficient implementation of .ovf opcodes.
5400 These are currently implemented as:
5401 <ins which sets the condition codes>
5404 Some overflow opcodes are now supported by LLVM SVN.
5406 - exception handling, unwinding.
5407 - SSA is disabled for methods with exception handlers
5408 - How to obtain unwind info for LLVM compiled methods ?
5409 -> this is now solved by converting the unwind info generated by LLVM
5411 - LLVM uses the c++ exception handling framework, while we use our home grown
5412 code, and couldn't use the c++ one:
5413 - its not supported under VC++, other exotic platforms.
5414 - it might be impossible to support filter clauses with it.
5418 The trampolines need a predictable call sequence, since they need to disasm
5419 the calling code to obtain register numbers / offsets.
5421 LLVM currently generates this code in non-JIT mode:
5422 mov -0x98(%rax),%eax
5424 Here, the vtable pointer is lost.
5425 -> solution: use one vtable trampoline per class.
5427 - passing/receiving the IMT pointer/RGCTX.
5428 -> solution: pass them as normal arguments ?
5432 LLVM does not allow the specification of argument registers etc. This means
5433 that all calls are made according to the platform ABI.
5435 - passing/receiving vtypes.
5437 Vtypes passed/received in registers are handled by the front end by using
5438 a signature with scalar arguments, and loading the parts of the vtype into those
5441 Vtypes passed on the stack are handled using the 'byval' attribute.
5445 Supported though alloca, we need to emit the load/store code.
5449 The mono JIT uses pointer sized iregs/double fregs, while LLVM uses precisely
5450 typed registers, so we have to keep track of the precise LLVM type of each vreg.
5451 This is made easier because the IR is already in SSA form.
5452 An additional problem is that our IR is not consistent with types, i.e. i32/ia64
5453 types are frequently used incorrectly.
5458 Emit LLVM bytecode into a .bc file, compile it using llc into a .s file, then
5459 append the AOT data structures to that file. For methods which cannot be
5460 handled by LLVM, the normal JIT compiled versions are used.
5463 /* FIXME: Normalize some aspects of the mono IR to allow easier translation, like:
5464 * - each bblock should end with a branch
5465 * - setting the return value, making cfg->ret non-volatile
5466 * - avoid some transformations in the JIT which make it harder for us to generate
5468 * - use pointer types to help optimizations.