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;
1077 memset (sinfo, 0, sizeof (LLVMSigInfo));
1079 rtype = mini_replace_type (sig->ret);
1080 ret_type = type_to_llvm_type (ctx, rtype);
1081 CHECK_FAILURE (ctx);
1083 if (cinfo && cinfo->ret.storage == LLVMArgVtypeInReg) {
1084 /* LLVM models this by returning an aggregate value */
1085 if (cinfo->ret.pair_storage [0] == LLVMArgInIReg && cinfo->ret.pair_storage [1] == LLVMArgNone) {
1086 LLVMTypeRef members [2];
1088 members [0] = IntPtrType ();
1089 ret_type = LLVMStructType (members, 1, FALSE);
1091 g_assert_not_reached ();
1093 } else if (cinfo && mini_type_is_vtype (ctx->cfg, rtype)) {
1094 g_assert (cinfo->ret.storage == LLVMArgVtypeRetAddr);
1096 ret_type = LLVMVoidType ();
1099 pindexes = g_new0 (int, sig->param_count);
1100 param_types = g_new0 (LLVMTypeRef, (sig->param_count * 2) + 3);
1102 if (cinfo && cinfo->rgctx_arg) {
1104 sinfo->rgctx_arg_pindex = pindex;
1105 param_types [pindex] = ctx->lmodule->ptr_type;
1108 if (cinfo && cinfo->imt_arg) {
1110 sinfo->imt_arg_pindex = pindex;
1111 param_types [pindex] = ctx->lmodule->ptr_type;
1115 /* Compute the index in the LLVM signature where the vret arg needs to be passed */
1116 vret_arg_pindex = pindex;
1117 if (cinfo->vret_arg_index == 1) {
1118 /* Add the slots consumed by the first argument */
1119 LLVMArgInfo *ainfo = &cinfo->args [0];
1120 switch (ainfo->storage) {
1121 case LLVMArgVtypeInReg:
1122 for (j = 0; j < 2; ++j) {
1123 if (ainfo->pair_storage [j] == LLVMArgInIReg)
1133 sinfo->vret_arg_pindex = vret_arg_pindex;
1136 if (vretaddr && vret_arg_pindex == pindex)
1137 param_types [pindex ++] = IntPtrType ();
1140 sinfo->this_arg_pindex = pindex;
1141 param_types [pindex ++] = ThisType ();
1143 if (vretaddr && vret_arg_pindex == pindex)
1144 param_types [pindex ++] = IntPtrType ();
1145 for (i = 0; i < sig->param_count; ++i) {
1146 if (vretaddr && vret_arg_pindex == pindex)
1147 param_types [pindex ++] = IntPtrType ();
1148 pindexes [i] = pindex;
1149 if (cinfo && cinfo->args [i + sig->hasthis].storage == LLVMArgVtypeInReg) {
1150 for (j = 0; j < 2; ++j) {
1151 switch (cinfo->args [i + sig->hasthis].pair_storage [j]) {
1153 param_types [pindex ++] = LLVMIntType (sizeof (gpointer) * 8);
1158 g_assert_not_reached ();
1161 } else if (cinfo && cinfo->args [i + sig->hasthis].storage == LLVMArgVtypeByVal) {
1162 param_types [pindex] = type_to_llvm_arg_type (ctx, sig->params [i]);
1163 CHECK_FAILURE (ctx);
1164 param_types [pindex] = LLVMPointerType (param_types [pindex], 0);
1167 param_types [pindex ++] = type_to_llvm_arg_type (ctx, sig->params [i]);
1170 if (vretaddr && vret_arg_pindex == pindex)
1171 param_types [pindex ++] = IntPtrType ();
1173 CHECK_FAILURE (ctx);
1175 res = LLVMFunctionType (ret_type, param_types, pindex, FALSE);
1176 g_free (param_types);
1179 sinfo->pindexes = pindexes;
1187 g_free (param_types);
1193 sig_to_llvm_sig (EmitContext *ctx, MonoMethodSignature *sig)
1195 return sig_to_llvm_sig_full (ctx, sig, NULL, NULL);
1199 * LLVMFunctionType1:
1201 * Create an LLVM function type from the arguments.
1203 static G_GNUC_UNUSED LLVMTypeRef
1204 LLVMFunctionType1(LLVMTypeRef ReturnType,
1205 LLVMTypeRef ParamType1,
1208 LLVMTypeRef param_types [1];
1210 param_types [0] = ParamType1;
1212 return LLVMFunctionType (ReturnType, param_types, 1, IsVarArg);
1216 * LLVMFunctionType2:
1218 * Create an LLVM function type from the arguments.
1220 static G_GNUC_UNUSED LLVMTypeRef
1221 LLVMFunctionType2(LLVMTypeRef ReturnType,
1222 LLVMTypeRef ParamType1,
1223 LLVMTypeRef ParamType2,
1226 LLVMTypeRef param_types [2];
1228 param_types [0] = ParamType1;
1229 param_types [1] = ParamType2;
1231 return LLVMFunctionType (ReturnType, param_types, 2, IsVarArg);
1235 * LLVMFunctionType3:
1237 * Create an LLVM function type from the arguments.
1239 static G_GNUC_UNUSED LLVMTypeRef
1240 LLVMFunctionType3(LLVMTypeRef ReturnType,
1241 LLVMTypeRef ParamType1,
1242 LLVMTypeRef ParamType2,
1243 LLVMTypeRef ParamType3,
1246 LLVMTypeRef param_types [3];
1248 param_types [0] = ParamType1;
1249 param_types [1] = ParamType2;
1250 param_types [2] = ParamType3;
1252 return LLVMFunctionType (ReturnType, param_types, 3, IsVarArg);
1258 * Create an LLVM builder and remember it so it can be freed later.
1260 static LLVMBuilderRef
1261 create_builder (EmitContext *ctx)
1263 LLVMBuilderRef builder = LLVMCreateBuilder ();
1265 ctx->builders = g_slist_prepend_mempool (ctx->cfg->mempool, ctx->builders, builder);
1271 get_plt_entry (EmitContext *ctx, LLVMTypeRef llvm_sig, MonoJumpInfoType type, gconstpointer data)
1273 char *callee_name = mono_aot_get_plt_symbol (type, data);
1274 LLVMValueRef callee;
1279 if (ctx->cfg->compile_aot)
1280 /* Add a patch so referenced wrappers can be compiled in full aot mode */
1281 mono_add_patch_info (ctx->cfg, 0, type, data);
1284 callee = g_hash_table_lookup (ctx->lmodule->plt_entries, callee_name);
1286 callee = LLVMAddFunction (ctx->module, callee_name, llvm_sig);
1288 LLVMSetVisibility (callee, LLVMHiddenVisibility);
1290 g_hash_table_insert (ctx->lmodule->plt_entries, (char*)callee_name, callee);
1297 get_handler_clause (MonoCompile *cfg, MonoBasicBlock *bb)
1299 MonoMethodHeader *header = cfg->header;
1300 MonoExceptionClause *clause;
1304 if (bb->region != -1 && MONO_BBLOCK_IS_IN_REGION (bb, MONO_REGION_TRY))
1305 return (bb->region >> 8) - 1;
1308 for (i = 0; i < header->num_clauses; ++i) {
1309 clause = &header->clauses [i];
1311 if (MONO_OFFSET_IN_CLAUSE (clause, bb->real_offset) && clause->flags == MONO_EXCEPTION_CLAUSE_NONE)
1319 set_metadata_flag (LLVMValueRef v, const char *flag_name)
1321 LLVMValueRef md_arg;
1324 md_kind = LLVMGetMDKindID (flag_name, strlen (flag_name));
1325 md_arg = LLVMMDString ("mono", 4);
1326 LLVMSetMetadata (v, md_kind, LLVMMDNode (&md_arg, 1));
1330 set_invariant_load_flag (LLVMValueRef v)
1332 LLVMValueRef md_arg;
1334 const char *flag_name;
1336 // FIXME: Cache this
1337 flag_name = "invariant.load";
1338 md_kind = LLVMGetMDKindID (flag_name, strlen (flag_name));
1339 md_arg = LLVMMDString ("<index>", strlen ("<index>"));
1340 LLVMSetMetadata (v, md_kind, LLVMMDNode (&md_arg, 1));
1346 * Emit an LLVM call or invoke instruction depending on whenever the call is inside
1350 emit_call (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, LLVMValueRef callee, LLVMValueRef *args, int pindex)
1352 MonoCompile *cfg = ctx->cfg;
1354 LLVMBuilderRef builder = *builder_ref;
1357 clause_index = get_handler_clause (cfg, bb);
1359 if (clause_index != -1) {
1360 MonoMethodHeader *header = cfg->header;
1361 MonoExceptionClause *ec = &header->clauses [clause_index];
1362 MonoBasicBlock *tblock;
1363 LLVMBasicBlockRef ex_bb, noex_bb;
1366 * Have to use an invoke instead of a call, branching to the
1367 * handler bblock of the clause containing this bblock.
1370 g_assert (ec->flags == MONO_EXCEPTION_CLAUSE_NONE || ec->flags == MONO_EXCEPTION_CLAUSE_FINALLY);
1372 tblock = cfg->cil_offset_to_bb [ec->handler_offset];
1375 ctx->bblocks [tblock->block_num].invoke_target = TRUE;
1377 ex_bb = get_bb (ctx, tblock);
1379 noex_bb = gen_bb (ctx, "NOEX_BB");
1382 lcall = LLVMBuildInvoke (builder, callee, args, pindex, noex_bb, ex_bb, "");
1384 builder = ctx->builder = create_builder (ctx);
1385 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
1387 ctx->bblocks [bb->block_num].end_bblock = noex_bb;
1389 lcall = LLVMBuildCall (builder, callee, args, pindex, "");
1390 ctx->builder = builder;
1393 *builder_ref = ctx->builder;
1399 emit_load (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, int size, LLVMValueRef addr, const char *name, gboolean is_faulting)
1401 const char *intrins_name;
1402 LLVMValueRef args [16], res;
1403 LLVMTypeRef addr_type;
1405 if (is_faulting && bb->region != -1) {
1407 * We handle loads which can fault by calling a mono specific intrinsic
1408 * using an invoke, so they are handled properly inside try blocks.
1409 * We can't use this outside clauses, since LLVM optimizes intrinsics which
1410 * are marked with IntrReadArgMem.
1414 intrins_name = "llvm.mono.load.i8.p0i8";
1417 intrins_name = "llvm.mono.load.i16.p0i16";
1420 intrins_name = "llvm.mono.load.i32.p0i32";
1423 intrins_name = "llvm.mono.load.i64.p0i64";
1426 g_assert_not_reached ();
1429 addr_type = LLVMTypeOf (addr);
1430 if (addr_type == LLVMPointerType (LLVMDoubleType (), 0) || addr_type == LLVMPointerType (LLVMFloatType (), 0))
1431 addr = LLVMBuildBitCast (*builder_ref, addr, LLVMPointerType (LLVMIntType (size * 8), 0), "");
1434 args [1] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
1435 args [2] = LLVMConstInt (LLVMInt1Type (), TRUE, FALSE);
1436 res = emit_call (ctx, bb, builder_ref, LLVMGetNamedFunction (ctx->module, intrins_name), args, 3);
1438 if (addr_type == LLVMPointerType (LLVMDoubleType (), 0))
1439 res = LLVMBuildBitCast (*builder_ref, res, LLVMDoubleType (), "");
1440 else if (addr_type == LLVMPointerType (LLVMFloatType (), 0))
1441 res = LLVMBuildBitCast (*builder_ref, res, LLVMFloatType (), "");
1448 * We emit volatile loads for loads which can fault, because otherwise
1449 * LLVM will generate invalid code when encountering a load from a
1452 res = mono_llvm_build_load (*builder_ref, addr, name, is_faulting);
1454 /* Mark it with a custom metadata */
1457 set_metadata_flag (res, "mono.faulting.load");
1465 emit_store (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, int size, LLVMValueRef value, LLVMValueRef addr, gboolean is_faulting)
1467 const char *intrins_name;
1468 LLVMValueRef args [16];
1470 if (is_faulting && bb->region != -1) {
1473 intrins_name = "llvm.mono.store.i8.p0i8";
1476 intrins_name = "llvm.mono.store.i16.p0i16";
1479 intrins_name = "llvm.mono.store.i32.p0i32";
1482 intrins_name = "llvm.mono.store.i64.p0i64";
1485 g_assert_not_reached ();
1488 if (LLVMTypeOf (value) == LLVMDoubleType () || LLVMTypeOf (value) == LLVMFloatType ()) {
1489 value = LLVMBuildBitCast (*builder_ref, value, LLVMIntType (size * 8), "");
1490 addr = LLVMBuildBitCast (*builder_ref, addr, LLVMPointerType (LLVMIntType (size * 8), 0), "");
1495 args [2] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
1496 args [3] = LLVMConstInt (LLVMInt1Type (), TRUE, FALSE);
1497 emit_call (ctx, bb, builder_ref, LLVMGetNamedFunction (ctx->module, intrins_name), args, 4);
1499 LLVMBuildStore (*builder_ref, value, addr);
1504 * emit_cond_system_exception:
1506 * Emit code to throw the exception EXC_TYPE if the condition CMP is false.
1507 * Might set the ctx exception.
1510 emit_cond_system_exception (EmitContext *ctx, MonoBasicBlock *bb, const char *exc_type, LLVMValueRef cmp)
1512 LLVMBasicBlockRef ex_bb, noex_bb;
1513 LLVMBuilderRef builder;
1514 MonoClass *exc_class;
1515 LLVMValueRef args [2];
1517 ex_bb = gen_bb (ctx, "EX_BB");
1518 noex_bb = gen_bb (ctx, "NOEX_BB");
1520 LLVMBuildCondBr (ctx->builder, cmp, ex_bb, noex_bb);
1522 exc_class = mono_class_from_name (mono_get_corlib (), "System", exc_type);
1523 g_assert (exc_class);
1525 /* Emit exception throwing code */
1526 builder = create_builder (ctx);
1527 LLVMPositionBuilderAtEnd (builder, ex_bb);
1529 if (!ctx->lmodule->throw_corlib_exception) {
1530 LLVMValueRef callee;
1532 const char *icall_name;
1534 MonoMethodSignature *throw_sig = mono_metadata_signature_alloc (mono_get_corlib (), 2);
1535 throw_sig->ret = &mono_get_void_class ()->byval_arg;
1536 throw_sig->params [0] = &mono_get_int32_class ()->byval_arg;
1537 icall_name = "llvm_throw_corlib_exception_abs_trampoline";
1538 /* This will become i8* */
1539 throw_sig->params [1] = &mono_get_byte_class ()->this_arg;
1540 sig = sig_to_llvm_sig (ctx, throw_sig);
1542 if (ctx->cfg->compile_aot) {
1543 callee = get_plt_entry (ctx, sig, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
1545 callee = LLVMAddFunction (ctx->module, "llvm_throw_corlib_exception_trampoline", sig_to_llvm_sig (ctx, throw_sig));
1548 * Differences between the LLVM/non-LLVM throw corlib exception trampoline:
1549 * - On x86, LLVM generated code doesn't push the arguments
1550 * - The trampoline takes the throw address as an arguments, not a pc offset.
1552 LLVMAddGlobalMapping (ctx->lmodule->ee, callee, resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name));
1555 mono_memory_barrier ();
1556 ctx->lmodule->throw_corlib_exception = callee;
1559 if (IS_TARGET_X86 || IS_TARGET_AMD64)
1560 args [0] = LLVMConstInt (LLVMInt32Type (), exc_class->type_token - MONO_TOKEN_TYPE_DEF, FALSE);
1562 args [0] = LLVMConstInt (LLVMInt32Type (), exc_class->type_token, FALSE);
1565 * The LLVM mono branch contains changes so a block address can be passed as an
1566 * argument to a call.
1568 args [1] = LLVMBlockAddress (ctx->lmethod, ex_bb);
1569 emit_call (ctx, bb, &builder, ctx->lmodule->throw_corlib_exception, args, 2);
1571 LLVMBuildUnreachable (builder);
1573 ctx->builder = create_builder (ctx);
1574 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
1576 ctx->bblocks [bb->block_num].end_bblock = noex_bb;
1583 * emit_reg_to_vtype:
1585 * Emit code to store the vtype in the registers REGS to the address ADDRESS.
1588 emit_reg_to_vtype (EmitContext *ctx, LLVMBuilderRef builder, MonoType *t, LLVMValueRef address, LLVMArgInfo *ainfo, LLVMValueRef *regs)
1592 size = get_vtype_size (t);
1594 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (t))) {
1595 address = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (LLVMInt8Type (), 0), "");
1598 for (j = 0; j < 2; ++j) {
1599 LLVMValueRef index [2], addr;
1600 int part_size = size > sizeof (gpointer) ? sizeof (gpointer) : size;
1601 LLVMTypeRef part_type;
1603 if (ainfo->pair_storage [j] == LLVMArgNone)
1606 part_type = LLVMIntType (part_size * 8);
1607 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (t))) {
1608 index [0] = LLVMConstInt (LLVMInt32Type (), j * sizeof (gpointer), FALSE);
1609 addr = LLVMBuildGEP (builder, address, index, 1, "");
1611 index [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
1612 index [1] = LLVMConstInt (LLVMInt32Type (), j * sizeof (gpointer), FALSE);
1613 addr = LLVMBuildGEP (builder, address, index, 2, "");
1615 switch (ainfo->pair_storage [j]) {
1617 LLVMBuildStore (builder, convert (ctx, regs [j], part_type), LLVMBuildBitCast (ctx->builder, addr, LLVMPointerType (part_type, 0), ""));
1622 g_assert_not_reached ();
1625 size -= sizeof (gpointer);
1630 * emit_vtype_to_reg:
1632 * Emit code to load a vtype at address ADDRESS into registers. Store the registers
1633 * into REGS, and the number of registers into NREGS.
1636 emit_vtype_to_reg (EmitContext *ctx, LLVMBuilderRef builder, MonoType *t, LLVMValueRef address, LLVMArgInfo *ainfo, LLVMValueRef *regs, guint32 *nregs)
1641 size = get_vtype_size (t);
1643 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (t))) {
1644 address = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (LLVMInt8Type (), 0), "");
1647 for (j = 0; j < 2; ++j) {
1648 LLVMValueRef index [2], addr;
1649 int partsize = size > sizeof (gpointer) ? sizeof (gpointer) : size;
1651 if (ainfo->pair_storage [j] == LLVMArgNone)
1654 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (t))) {
1655 index [0] = LLVMConstInt (LLVMInt32Type (), j * sizeof (gpointer), FALSE);
1656 addr = LLVMBuildGEP (builder, address, index, 1, "");
1658 index [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
1659 index [1] = LLVMConstInt (LLVMInt32Type (), j * sizeof (gpointer), FALSE);
1660 addr = LLVMBuildGEP (builder, address, index, 2, "");
1662 switch (ainfo->pair_storage [j]) {
1664 regs [pindex ++] = convert (ctx, LLVMBuildLoad (builder, LLVMBuildBitCast (ctx->builder, addr, LLVMPointerType (LLVMIntType (partsize * 8), 0), ""), ""), IntPtrType ());
1669 g_assert_not_reached ();
1671 size -= sizeof (gpointer);
1678 build_alloca_llvm_type (EmitContext *ctx, LLVMTypeRef t, int align)
1681 * Have to place all alloca's at the end of the entry bb, since otherwise they would
1682 * get executed every time control reaches them.
1684 LLVMPositionBuilder (ctx->alloca_builder, get_bb (ctx, ctx->cfg->bb_entry), ctx->last_alloca);
1686 ctx->last_alloca = mono_llvm_build_alloca (ctx->alloca_builder, t, NULL, align, "");
1687 return ctx->last_alloca;
1691 build_alloca (EmitContext *ctx, MonoType *t)
1693 MonoClass *k = mono_class_from_mono_type (t);
1696 if (MONO_CLASS_IS_SIMD (ctx->cfg, k))
1699 align = mono_class_min_align (k);
1701 /* Sometimes align is not a power of 2 */
1702 while (mono_is_power_of_two (align) == -1)
1705 return build_alloca_llvm_type (ctx, type_to_llvm_type (ctx, t), align);
1709 * Put the global into the 'llvm.used' array to prevent it from being optimized away.
1712 mark_as_used (MonoLLVMModule *lmodule, LLVMValueRef global)
1715 lmodule->used = g_ptr_array_sized_new (16);
1716 g_ptr_array_add (lmodule->used, global);
1720 emit_llvm_used (MonoLLVMModule *lmodule)
1722 LLVMModuleRef module = lmodule->module;
1723 LLVMTypeRef used_type;
1724 LLVMValueRef used, *used_elem;
1730 used_type = LLVMArrayType (LLVMPointerType (LLVMInt8Type (), 0), lmodule->used->len);
1731 used = LLVMAddGlobal (module, used_type, "llvm.used");
1732 used_elem = g_new0 (LLVMValueRef, lmodule->used->len);
1733 for (i = 0; i < lmodule->used->len; ++i)
1734 used_elem [i] = LLVMConstBitCast (g_ptr_array_index (lmodule->used, i), LLVMPointerType (LLVMInt8Type (), 0));
1735 LLVMSetInitializer (used, LLVMConstArray (LLVMPointerType (LLVMInt8Type (), 0), used_elem, lmodule->used->len));
1736 LLVMSetLinkage (used, LLVMAppendingLinkage);
1737 LLVMSetSection (used, "llvm.metadata");
1743 * Emit code to load/convert arguments.
1746 emit_entry_bb (EmitContext *ctx, LLVMBuilderRef builder)
1749 MonoCompile *cfg = ctx->cfg;
1750 MonoMethodSignature *sig = ctx->sig;
1751 LLVMCallInfo *linfo = ctx->linfo;
1754 ctx->alloca_builder = create_builder (ctx);
1757 * Handle indirect/volatile variables by allocating memory for them
1758 * using 'alloca', and storing their address in a temporary.
1760 for (i = 0; i < cfg->num_varinfo; ++i) {
1761 MonoInst *var = cfg->varinfo [i];
1764 if (var->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT) || mini_type_is_vtype (cfg, var->inst_vtype)) {
1765 vtype = type_to_llvm_type (ctx, var->inst_vtype);
1766 CHECK_FAILURE (ctx);
1767 /* Could be already created by an OP_VPHI */
1768 if (!ctx->addresses [var->dreg])
1769 ctx->addresses [var->dreg] = build_alloca (ctx, var->inst_vtype);
1770 ctx->vreg_cli_types [var->dreg] = var->inst_vtype;
1774 for (i = 0; i < sig->param_count; ++i) {
1775 LLVMArgInfo *ainfo = &linfo->args [i + sig->hasthis];
1776 int reg = cfg->args [i + sig->hasthis]->dreg;
1778 if (ainfo->storage == LLVMArgVtypeInReg) {
1779 LLVMValueRef regs [2];
1782 * Emit code to save the argument from the registers to
1783 * the real argument.
1785 pindex = ctx->pindexes [i];
1786 regs [0] = LLVMGetParam (ctx->lmethod, pindex);
1787 if (ainfo->pair_storage [1] != LLVMArgNone)
1788 regs [1] = LLVMGetParam (ctx->lmethod, pindex + 1);
1792 ctx->addresses [reg] = build_alloca (ctx, sig->params [i]);
1794 emit_reg_to_vtype (ctx, builder, sig->params [i], ctx->addresses [reg], ainfo, regs);
1796 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (sig->params [i]))) {
1797 /* Treat these as normal values */
1798 ctx->values [reg] = LLVMBuildLoad (builder, ctx->addresses [reg], "");
1800 } else if (ainfo->storage == LLVMArgVtypeByVal) {
1801 ctx->addresses [reg] = LLVMGetParam (ctx->lmethod, ctx->pindexes [i]);
1803 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (sig->params [i]))) {
1804 /* Treat these as normal values */
1805 ctx->values [reg] = LLVMBuildLoad (builder, ctx->addresses [reg], "");
1808 ctx->values [reg] = convert (ctx, ctx->values [reg], llvm_type_to_stack_type (type_to_llvm_type (ctx, sig->params [i])));
1813 emit_volatile_store (ctx, cfg->vret_addr->dreg);
1815 emit_volatile_store (ctx, cfg->args [0]->dreg);
1816 for (i = 0; i < sig->param_count; ++i)
1817 if (!mini_type_is_vtype (cfg, sig->params [i]))
1818 emit_volatile_store (ctx, cfg->args [i + sig->hasthis]->dreg);
1820 if (sig->hasthis && !cfg->rgctx_var && cfg->generic_sharing_context) {
1821 LLVMValueRef this_alloc;
1824 * The exception handling code needs the location where the this argument was
1825 * stored for gshared methods. We create a separate alloca to hold it, and mark it
1826 * with the "mono.this" custom metadata to tell llvm that it needs to save its
1827 * location into the LSDA.
1829 this_alloc = mono_llvm_build_alloca (builder, ThisType (), LLVMConstInt (LLVMInt32Type (), 1, FALSE), 0, "");
1830 /* This volatile store will keep the alloca alive */
1831 mono_llvm_build_store (builder, ctx->values [cfg->args [0]->dreg], this_alloc, TRUE);
1833 set_metadata_flag (this_alloc, "mono.this");
1836 if (cfg->rgctx_var) {
1837 LLVMValueRef rgctx_alloc, store;
1840 * We handle the rgctx arg similarly to the this pointer.
1842 g_assert (ctx->addresses [cfg->rgctx_var->dreg]);
1843 rgctx_alloc = ctx->addresses [cfg->rgctx_var->dreg];
1844 /* This volatile store will keep the alloca alive */
1845 store = mono_llvm_build_store (builder, convert (ctx, ctx->rgctx_arg, IntPtrType ()), rgctx_alloc, TRUE);
1847 set_metadata_flag (rgctx_alloc, "mono.this");
1851 * For finally clauses, create an indicator variable telling OP_ENDFINALLY whenever
1852 * it needs to continue normally, or return back to the exception handling system.
1854 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
1855 if (bb->region != -1 && (bb->flags & BB_EXCEPTION_HANDLER))
1856 g_hash_table_insert (ctx->region_to_handler, GUINT_TO_POINTER (mono_get_block_region_notry (cfg, bb->region)), bb);
1857 if (bb->region != -1 && (bb->flags & BB_EXCEPTION_HANDLER) && bb->in_scount == 0) {
1861 sprintf (name, "finally_ind_bb%d", bb->block_num);
1862 val = LLVMBuildAlloca (builder, LLVMInt32Type (), name);
1863 LLVMBuildStore (builder, LLVMConstInt (LLVMInt32Type (), 0, FALSE), val);
1865 ctx->bblocks [bb->block_num].finally_ind = val;
1868 * Create a new bblock which CALL_HANDLER can branch to, because branching to the
1869 * LLVM bblock containing the call to llvm.eh.selector causes problems for the
1870 * LLVM optimizer passes.
1872 sprintf (name, "BB_%d_CALL_HANDLER_TARGET", bb->block_num);
1873 ctx->bblocks [bb->block_num].call_handler_target_bb = LLVMAppendBasicBlock (ctx->lmethod, name);
1881 /* Have to export this for AOT */
1883 mono_personality (void);
1886 mono_personality (void)
1889 g_assert_not_reached ();
1893 process_call (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, MonoInst *ins)
1895 MonoCompile *cfg = ctx->cfg;
1896 LLVMModuleRef module = ctx->module;
1897 LLVMValueRef *values = ctx->values;
1898 LLVMValueRef *addresses = ctx->addresses;
1899 MonoCallInst *call = (MonoCallInst*)ins;
1900 MonoMethodSignature *sig = call->signature;
1901 LLVMValueRef callee = NULL, lcall;
1903 LLVMCallInfo *cinfo;
1907 LLVMTypeRef llvm_sig;
1909 gboolean virtual, calli;
1910 LLVMBuilderRef builder = *builder_ref;
1913 if (call->signature->call_convention != MONO_CALL_DEFAULT)
1914 LLVM_FAILURE (ctx, "non-default callconv");
1916 cinfo = call->cinfo;
1917 if (call->rgctx_arg_reg)
1918 cinfo->rgctx_arg = TRUE;
1919 if (call->imt_arg_reg)
1920 cinfo->imt_arg = TRUE;
1922 vretaddr = cinfo && cinfo->ret.storage == LLVMArgVtypeRetAddr;
1924 llvm_sig = sig_to_llvm_sig_full (ctx, sig, cinfo, &sinfo);
1925 CHECK_FAILURE (ctx);
1927 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);
1928 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);
1930 /* FIXME: Avoid creating duplicate methods */
1932 if (ins->flags & MONO_INST_HAS_METHOD) {
1936 if (cfg->compile_aot) {
1937 callee = get_plt_entry (ctx, llvm_sig, MONO_PATCH_INFO_METHOD, call->method);
1939 LLVM_FAILURE (ctx, "can't encode patch");
1941 callee = LLVMAddFunction (module, "", llvm_sig);
1944 mono_create_jit_trampoline_in_domain (mono_domain_get (),
1946 LLVMAddGlobalMapping (ctx->lmodule->ee, callee, target);
1950 if (call->method && strstr (call->method->klass->name, "AsyncVoidMethodBuilder"))
1951 /* LLVM miscompiles async methods */
1952 LLVM_FAILURE (ctx, "#13734");
1955 MonoJitICallInfo *info = mono_find_jit_icall_by_addr (call->fptr);
1961 memset (&ji, 0, sizeof (ji));
1962 ji.type = MONO_PATCH_INFO_JIT_ICALL_ADDR;
1963 ji.data.target = info->name;
1965 target = mono_resolve_patch_target (cfg->method, cfg->domain, NULL, &ji, FALSE);
1967 if (cfg->compile_aot) {
1968 callee = get_plt_entry (ctx, llvm_sig, MONO_PATCH_INFO_INTERNAL_METHOD, (char*)info->name);
1970 LLVM_FAILURE (ctx, "can't encode patch");
1972 callee = LLVMAddFunction (module, "", llvm_sig);
1973 target = (gpointer)mono_icall_get_wrapper (info);
1974 LLVMAddGlobalMapping (ctx->lmodule->ee, callee, target);
1977 if (cfg->compile_aot) {
1979 if (cfg->abs_patches) {
1980 MonoJumpInfo *abs_ji = g_hash_table_lookup (cfg->abs_patches, call->fptr);
1982 callee = get_plt_entry (ctx, llvm_sig, abs_ji->type, abs_ji->data.target);
1984 LLVM_FAILURE (ctx, "can't encode patch");
1988 LLVM_FAILURE (ctx, "aot");
1990 callee = LLVMAddFunction (module, "", llvm_sig);
1992 if (cfg->abs_patches) {
1993 MonoJumpInfo *abs_ji = g_hash_table_lookup (cfg->abs_patches, call->fptr);
1996 * FIXME: Some trampolines might have
1997 * their own calling convention on some platforms.
1999 #ifndef TARGET_AMD64
2000 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)
2001 LLVM_FAILURE (ctx, "trampoline with own cconv");
2003 target = mono_resolve_patch_target (cfg->method, cfg->domain, NULL, abs_ji, FALSE);
2004 LLVMAddGlobalMapping (ctx->lmodule->ee, callee, target);
2008 LLVMAddGlobalMapping (ctx->lmodule->ee, callee, (gpointer)call->fptr);
2014 int size = sizeof (gpointer);
2017 g_assert (ins->inst_offset % size == 0);
2018 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
2020 callee = convert (ctx, LLVMBuildLoad (builder, LLVMBuildGEP (builder, convert (ctx, values [ins->inst_basereg], LLVMPointerType (LLVMPointerType (IntPtrType (), 0), 0)), &index, 1, ""), ""), LLVMPointerType (llvm_sig, 0));
2022 callee = convert (ctx, values [ins->sreg1], LLVMPointerType (llvm_sig, 0));
2024 if (ins->flags & MONO_INST_HAS_METHOD) {
2029 * Collect and convert arguments
2031 nargs = (sig->param_count * 2) + sig->hasthis + vretaddr + call->rgctx_reg + call->imt_arg_reg;
2032 len = sizeof (LLVMValueRef) * nargs;
2033 args = alloca (len);
2034 memset (args, 0, len);
2035 l = call->out_ireg_args;
2037 if (call->rgctx_arg_reg) {
2038 g_assert (values [call->rgctx_arg_reg]);
2039 g_assert (sinfo.rgctx_arg_pindex < nargs);
2041 * On ARM, the imt/rgctx argument is passed in a caller save register, but some of our trampolines etc. clobber it, leading to
2042 * problems is LLVM moves the arg assignment earlier. To work around this, save the argument into a stack slot and load
2043 * it using a volatile load.
2046 if (!ctx->imt_rgctx_loc)
2047 ctx->imt_rgctx_loc = build_alloca_llvm_type (ctx, ctx->lmodule->ptr_type, sizeof (gpointer));
2048 LLVMBuildStore (builder, convert (ctx, ctx->values [call->rgctx_arg_reg], ctx->lmodule->ptr_type), ctx->imt_rgctx_loc);
2049 args [sinfo.rgctx_arg_pindex] = mono_llvm_build_load (builder, ctx->imt_rgctx_loc, "", TRUE);
2051 args [sinfo.rgctx_arg_pindex] = convert (ctx, values [call->rgctx_arg_reg], ctx->lmodule->ptr_type);
2054 if (call->imt_arg_reg) {
2055 g_assert (values [call->imt_arg_reg]);
2056 g_assert (sinfo.imt_arg_pindex < nargs);
2058 if (!ctx->imt_rgctx_loc)
2059 ctx->imt_rgctx_loc = build_alloca_llvm_type (ctx, ctx->lmodule->ptr_type, sizeof (gpointer));
2060 LLVMBuildStore (builder, convert (ctx, ctx->values [call->imt_arg_reg], ctx->lmodule->ptr_type), ctx->imt_rgctx_loc);
2061 args [sinfo.imt_arg_pindex] = mono_llvm_build_load (builder, ctx->imt_rgctx_loc, "", TRUE);
2063 args [sinfo.imt_arg_pindex] = convert (ctx, values [call->imt_arg_reg], ctx->lmodule->ptr_type);
2068 if (!addresses [call->inst.dreg])
2069 addresses [call->inst.dreg] = build_alloca (ctx, sig->ret);
2070 g_assert (sinfo.vret_arg_pindex < nargs);
2071 args [sinfo.vret_arg_pindex] = LLVMBuildPtrToInt (builder, addresses [call->inst.dreg], IntPtrType (), "");
2074 for (i = 0; i < sig->param_count + sig->hasthis; ++i) {
2077 LLVMArgInfo *ainfo = call->cinfo ? &call->cinfo->args [i] : NULL;
2081 pindex = sinfo.this_arg_pindex;
2083 pindex = sinfo.pindexes [i - 1];
2085 pindex = sinfo.pindexes [i];
2088 regpair = (guint32)(gssize)(l->data);
2089 reg = regpair & 0xffffff;
2090 args [pindex] = values [reg];
2091 if (ainfo->storage == LLVMArgVtypeInReg) {
2093 LLVMValueRef regs [2];
2098 g_assert (addresses [reg]);
2100 emit_vtype_to_reg (ctx, builder, sig->params [i - sig->hasthis], addresses [reg], ainfo, regs, &nregs);
2101 for (j = 0; j < nregs; ++j)
2102 args [pindex ++] = regs [j];
2105 // FIXME: Get rid of the VMOVE
2106 } else if (ainfo->storage == LLVMArgVtypeByVal) {
2107 g_assert (addresses [reg]);
2108 args [pindex] = addresses [reg];
2110 g_assert (args [pindex]);
2111 if (i == 0 && sig->hasthis)
2112 args [pindex] = convert (ctx, args [pindex], ThisType ());
2114 args [pindex] = convert (ctx, args [pindex], type_to_llvm_arg_type (ctx, sig->params [i - sig->hasthis]));
2120 // FIXME: Align call sites
2126 lcall = emit_call (ctx, bb, &builder, callee, args, LLVMCountParamTypes (llvm_sig));
2129 * Modify cconv and parameter attributes to pass rgctx/imt correctly.
2131 #if defined(MONO_ARCH_IMT_REG) && defined(MONO_ARCH_RGCTX_REG)
2132 g_assert (MONO_ARCH_IMT_REG == MONO_ARCH_RGCTX_REG);
2134 /* The two can't be used together, so use only one LLVM calling conv to pass them */
2135 g_assert (!(call->rgctx_arg_reg && call->imt_arg_reg));
2137 LLVMSetInstructionCallConv (lcall, LLVMMono1CallConv);
2139 if (call->rgctx_arg_reg)
2140 LLVMAddInstrAttribute (lcall, 1 + sinfo.rgctx_arg_pindex, LLVMInRegAttribute);
2141 if (call->imt_arg_reg)
2142 LLVMAddInstrAttribute (lcall, 1 + sinfo.imt_arg_pindex, LLVMInRegAttribute);
2144 /* Add byval attributes if needed */
2145 for (i = 0; i < sig->param_count; ++i) {
2146 LLVMArgInfo *ainfo = call->cinfo ? &call->cinfo->args [i + sig->hasthis] : NULL;
2148 if (ainfo && ainfo->storage == LLVMArgVtypeByVal) {
2149 LLVMAddInstrAttribute (lcall, 1 + sinfo.pindexes [i], LLVMByValAttribute);
2154 * Convert the result
2156 if (cinfo && cinfo->ret.storage == LLVMArgVtypeInReg) {
2157 LLVMValueRef regs [2];
2159 if (!addresses [ins->dreg])
2160 addresses [ins->dreg] = build_alloca (ctx, sig->ret);
2162 regs [0] = LLVMBuildExtractValue (builder, lcall, 0, "");
2163 if (cinfo->ret.pair_storage [1] != LLVMArgNone)
2164 regs [1] = LLVMBuildExtractValue (builder, lcall, 1, "");
2166 emit_reg_to_vtype (ctx, builder, sig->ret, addresses [ins->dreg], &cinfo->ret, regs);
2167 } else if (sig->ret->type != MONO_TYPE_VOID && !vretaddr) {
2168 /* If the method returns an unsigned value, need to zext it */
2170 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));
2173 *builder_ref = ctx->builder;
2175 g_free (sinfo.pindexes);
2183 process_bb (EmitContext *ctx, MonoBasicBlock *bb)
2185 MonoCompile *cfg = ctx->cfg;
2186 MonoMethodSignature *sig = ctx->sig;
2187 LLVMValueRef method = ctx->lmethod;
2188 LLVMValueRef *values = ctx->values;
2189 LLVMValueRef *addresses = ctx->addresses;
2191 LLVMCallInfo *linfo = ctx->linfo;
2192 LLVMModuleRef module = ctx->module;
2193 BBInfo *bblocks = ctx->bblocks;
2195 LLVMBasicBlockRef cbb;
2196 LLVMBuilderRef builder, starting_builder;
2197 gboolean has_terminator;
2199 LLVMValueRef lhs, rhs;
2202 cbb = get_bb (ctx, bb);
2203 builder = create_builder (ctx);
2204 ctx->builder = builder;
2205 LLVMPositionBuilderAtEnd (builder, cbb);
2207 if (bb == cfg->bb_entry)
2208 emit_entry_bb (ctx, builder);
2209 CHECK_FAILURE (ctx);
2211 if (bb->flags & BB_EXCEPTION_HANDLER) {
2213 LLVMValueRef personality;
2214 LLVMBasicBlockRef target_bb;
2216 static gint32 mapping_inited;
2217 static int ti_generator;
2220 LLVMValueRef type_info;
2223 if (!bblocks [bb->block_num].invoke_target) {
2225 * LLVM asserts if llvm.eh.selector is called from a bblock which
2226 * doesn't have an invoke pointing at it.
2227 * Update: LLVM no longer asserts, but some tests in exceptions.exe now fail.
2229 LLVM_FAILURE (ctx, "handler without invokes");
2232 // <resultval> = landingpad <somety> personality <type> <pers_fn> <clause>+
2234 if (cfg->compile_aot) {
2235 /* Use a dummy personality function */
2236 personality = LLVMGetNamedFunction (module, "mono_aot_personality");
2237 g_assert (personality);
2239 personality = LLVMGetNamedFunction (module, "mono_personality");
2240 if (InterlockedCompareExchange (&mapping_inited, 1, 0) == 0)
2241 LLVMAddGlobalMapping (ctx->lmodule->ee, personality, mono_personality);
2244 i8ptr = LLVMPointerType (LLVMInt8Type (), 0);
2246 clause_index = (mono_get_block_region_notry (cfg, bb->region) >> 8) - 1;
2249 * Create the type info
2251 sprintf (ti_name, "type_info_%d", ti_generator);
2254 if (cfg->compile_aot) {
2255 /* decode_eh_frame () in aot-runtime.c will decode this */
2256 type_info = LLVMAddGlobal (module, LLVMInt32Type (), ti_name);
2257 LLVMSetInitializer (type_info, LLVMConstInt (LLVMInt32Type (), clause_index, FALSE));
2260 * These symbols are not really used, the clause_index is embedded into the EH tables generated by DwarfMonoException in LLVM.
2262 LLVMSetLinkage (type_info, LLVMInternalLinkage);
2265 * Enabling this causes llc to crash:
2266 * http://llvm.org/bugs/show_bug.cgi?id=6102
2268 //LLVM_FAILURE (ctx, "aot+clauses");
2270 // test_0_invalid_unbox_arrays () fails
2271 LLVM_FAILURE (ctx, "aot+clauses");
2275 * After the cfg mempool is freed, the type info will point to stale memory,
2276 * but this is not a problem, since we decode it once in exception_cb during
2279 ti = mono_mempool_alloc (cfg->mempool, sizeof (gint32));
2280 *(gint32*)ti = clause_index;
2282 type_info = LLVMAddGlobal (module, i8ptr, ti_name);
2284 LLVMAddGlobalMapping (ctx->lmodule->ee, type_info, ti);
2288 LLVMTypeRef members [2], ret_type;
2289 LLVMValueRef landing_pad;
2291 members [0] = i8ptr;
2292 members [1] = LLVMInt32Type ();
2293 ret_type = LLVMStructType (members, 2, FALSE);
2295 landing_pad = LLVMBuildLandingPad (builder, ret_type, personality, 1, "");
2296 LLVMAddClause (landing_pad, type_info);
2298 /* Store the exception into the exvar */
2299 if (bb->in_scount == 1) {
2300 g_assert (bb->in_scount == 1);
2301 exvar = bb->in_stack [0];
2303 // FIXME: This is shared with filter clauses ?
2304 g_assert (!values [exvar->dreg]);
2306 values [exvar->dreg] = LLVMBuildExtractValue (builder, landing_pad, 0, "ex_obj");
2307 emit_volatile_store (ctx, exvar->dreg);
2311 /* Start a new bblock which CALL_HANDLER can branch to */
2312 target_bb = bblocks [bb->block_num].call_handler_target_bb;
2314 LLVMBuildBr (builder, target_bb);
2316 ctx->builder = builder = create_builder (ctx);
2317 LLVMPositionBuilderAtEnd (ctx->builder, target_bb);
2319 ctx->bblocks [bb->block_num].end_bblock = target_bb;
2323 has_terminator = FALSE;
2324 starting_builder = builder;
2325 for (ins = bb->code; ins; ins = ins->next) {
2326 const char *spec = LLVM_INS_INFO (ins->opcode);
2328 char dname_buf [128];
2331 if (nins > 5000 && builder == starting_builder) {
2332 /* some steps in llc are non-linear in the size of basic blocks, see #5714 */
2333 LLVM_FAILURE (ctx, "basic block too long");
2337 /* There could be instructions after a terminator, skip them */
2340 if (spec [MONO_INST_DEST] != ' ' && !MONO_IS_STORE_MEMBASE (ins)) {
2341 sprintf (dname_buf, "t%d", ins->dreg);
2345 if (spec [MONO_INST_SRC1] != ' ' && spec [MONO_INST_SRC1] != 'v') {
2346 MonoInst *var = get_vreg_to_inst (cfg, ins->sreg1);
2348 if (var && var->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT)) {
2349 lhs = emit_volatile_load (ctx, ins->sreg1);
2351 /* It is ok for SETRET to have an uninitialized argument */
2352 if (!values [ins->sreg1] && ins->opcode != OP_SETRET)
2353 LLVM_FAILURE (ctx, "sreg1");
2354 lhs = values [ins->sreg1];
2360 if (spec [MONO_INST_SRC2] != ' ' && spec [MONO_INST_SRC2] != ' ') {
2361 MonoInst *var = get_vreg_to_inst (cfg, ins->sreg2);
2362 if (var && var->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT)) {
2363 rhs = emit_volatile_load (ctx, ins->sreg2);
2365 if (!values [ins->sreg2])
2366 LLVM_FAILURE (ctx, "sreg2");
2367 rhs = values [ins->sreg2];
2373 //mono_print_ins (ins);
2374 switch (ins->opcode) {
2377 case OP_LIVERANGE_START:
2378 case OP_LIVERANGE_END:
2381 values [ins->dreg] = LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE);
2384 #if SIZEOF_VOID_P == 4
2385 values [ins->dreg] = LLVMConstInt (LLVMInt64Type (), GET_LONG_IMM (ins), FALSE);
2387 values [ins->dreg] = LLVMConstInt (LLVMInt64Type (), (gint64)ins->inst_c0, FALSE);
2391 values [ins->dreg] = LLVMConstReal (LLVMDoubleType (), *(double*)ins->inst_p0);
2394 values [ins->dreg] = LLVMConstFPExt (LLVMConstReal (LLVMFloatType (), *(float*)ins->inst_p0), LLVMDoubleType ());
2396 case OP_DUMMY_ICONST:
2397 values [ins->dreg] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
2399 case OP_DUMMY_I8CONST:
2400 values [ins->dreg] = LLVMConstInt (LLVMInt64Type (), 0, FALSE);
2402 case OP_DUMMY_R8CONST:
2403 values [ins->dreg] = LLVMConstReal (LLVMDoubleType (), 0.0f);
2406 LLVMBuildBr (builder, get_bb (ctx, ins->inst_target_bb));
2407 has_terminator = TRUE;
2413 LLVMBasicBlockRef new_bb;
2414 LLVMBuilderRef new_builder;
2416 // The default branch is already handled
2417 // FIXME: Handle it here
2419 /* Start new bblock */
2420 sprintf (bb_name, "SWITCH_DEFAULT_BB%d", ctx->default_index ++);
2421 new_bb = LLVMAppendBasicBlock (ctx->lmethod, bb_name);
2423 lhs = convert (ctx, lhs, LLVMInt32Type ());
2424 v = LLVMBuildSwitch (builder, lhs, new_bb, GPOINTER_TO_UINT (ins->klass));
2425 for (i = 0; i < GPOINTER_TO_UINT (ins->klass); ++i) {
2426 MonoBasicBlock *target_bb = ins->inst_many_bb [i];
2428 LLVMAddCase (v, LLVMConstInt (LLVMInt32Type (), i, FALSE), get_bb (ctx, target_bb));
2431 new_builder = create_builder (ctx);
2432 LLVMPositionBuilderAtEnd (new_builder, new_bb);
2433 LLVMBuildUnreachable (new_builder);
2435 has_terminator = TRUE;
2436 g_assert (!ins->next);
2442 if (linfo->ret.storage == LLVMArgVtypeInReg) {
2443 LLVMTypeRef ret_type = LLVMGetReturnType (LLVMGetElementType (LLVMTypeOf (method)));
2444 LLVMValueRef part1, retval;
2447 size = get_vtype_size (sig->ret);
2449 g_assert (addresses [ins->sreg1]);
2451 g_assert (linfo->ret.pair_storage [0] == LLVMArgInIReg);
2452 g_assert (linfo->ret.pair_storage [1] == LLVMArgNone);
2454 part1 = convert (ctx, LLVMBuildLoad (builder, LLVMBuildBitCast (builder, addresses [ins->sreg1], LLVMPointerType (LLVMIntType (size * 8), 0), ""), ""), IntPtrType ());
2456 retval = LLVMBuildInsertValue (builder, LLVMGetUndef (ret_type), part1, 0, "");
2458 LLVMBuildRet (builder, retval);
2462 if (linfo->ret.storage == LLVMArgVtypeRetAddr) {
2463 LLVMBuildRetVoid (builder);
2467 if (!lhs || ctx->is_dead [ins->sreg1]) {
2469 * The method did not set its return value, probably because it
2470 * ends with a throw.
2473 LLVMBuildRetVoid (builder);
2475 LLVMBuildRet (builder, LLVMConstNull (type_to_llvm_type (ctx, sig->ret)));
2477 LLVMBuildRet (builder, convert (ctx, lhs, type_to_llvm_type (ctx, sig->ret)));
2479 has_terminator = TRUE;
2485 case OP_ICOMPARE_IMM:
2486 case OP_LCOMPARE_IMM:
2487 case OP_COMPARE_IMM: {
2491 if (ins->next->opcode == OP_NOP)
2494 if (ins->next->opcode == OP_BR)
2495 /* The comparison result is not needed */
2498 rel = mono_opcode_to_cond (ins->next->opcode);
2500 if (ins->opcode == OP_ICOMPARE_IMM) {
2501 lhs = convert (ctx, lhs, LLVMInt32Type ());
2502 rhs = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
2504 if (ins->opcode == OP_LCOMPARE_IMM) {
2505 lhs = convert (ctx, lhs, LLVMInt64Type ());
2506 rhs = LLVMConstInt (LLVMInt64Type (), GET_LONG_IMM (ins), FALSE);
2508 if (ins->opcode == OP_LCOMPARE) {
2509 lhs = convert (ctx, lhs, LLVMInt64Type ());
2510 rhs = convert (ctx, rhs, LLVMInt64Type ());
2512 if (ins->opcode == OP_ICOMPARE) {
2513 lhs = convert (ctx, lhs, LLVMInt32Type ());
2514 rhs = convert (ctx, rhs, LLVMInt32Type ());
2518 if (LLVMGetTypeKind (LLVMTypeOf (lhs)) == LLVMPointerTypeKind)
2519 rhs = convert (ctx, rhs, LLVMTypeOf (lhs));
2520 else if (LLVMGetTypeKind (LLVMTypeOf (rhs)) == LLVMPointerTypeKind)
2521 lhs = convert (ctx, lhs, LLVMTypeOf (rhs));
2524 /* We use COMPARE+SETcc/Bcc, llvm uses SETcc+br cond */
2525 if (ins->opcode == OP_FCOMPARE)
2526 cmp = LLVMBuildFCmp (builder, fpcond_to_llvm_cond [rel], convert (ctx, lhs, LLVMDoubleType ()), convert (ctx, rhs, LLVMDoubleType ()), "");
2527 else if (ins->opcode == OP_COMPARE_IMM) {
2528 if (LLVMGetTypeKind (LLVMTypeOf (lhs)) == LLVMPointerTypeKind && ins->inst_imm == 0)
2529 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], lhs, LLVMConstNull (LLVMTypeOf (lhs)), "");
2531 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE), "");
2532 } else if (ins->opcode == OP_LCOMPARE_IMM) {
2533 if (SIZEOF_REGISTER == 4 && COMPILE_LLVM (cfg)) {
2534 /* The immediate is encoded in two fields */
2535 guint64 l = ((guint64)(guint32)ins->inst_offset << 32) | ((guint32)ins->inst_imm);
2536 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, LLVMInt64Type ()), LLVMConstInt (LLVMInt64Type (), l, FALSE), "");
2538 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, LLVMInt64Type ()), LLVMConstInt (LLVMInt64Type (), ins->inst_imm, FALSE), "");
2541 else if (ins->opcode == OP_COMPARE) {
2542 if (LLVMGetTypeKind (LLVMTypeOf (lhs)) == LLVMPointerTypeKind && LLVMTypeOf (lhs) == LLVMTypeOf (rhs))
2543 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], lhs, rhs, "");
2545 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, IntPtrType ()), convert (ctx, rhs, IntPtrType ()), "");
2547 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], lhs, rhs, "");
2549 if (MONO_IS_COND_BRANCH_OP (ins->next)) {
2550 if (ins->next->inst_true_bb == ins->next->inst_false_bb) {
2552 * If the target bb contains PHI instructions, LLVM requires
2553 * two PHI entries for this bblock, while we only generate one.
2554 * So convert this to an unconditional bblock. (bxc #171).
2556 LLVMBuildBr (builder, get_bb (ctx, ins->next->inst_true_bb));
2558 LLVMBuildCondBr (builder, cmp, get_bb (ctx, ins->next->inst_true_bb), get_bb (ctx, ins->next->inst_false_bb));
2560 has_terminator = TRUE;
2561 } else if (MONO_IS_SETCC (ins->next)) {
2562 sprintf (dname_buf, "t%d", ins->next->dreg);
2564 values [ins->next->dreg] = LLVMBuildZExt (builder, cmp, LLVMInt32Type (), dname);
2566 /* Add stores for volatile variables */
2567 emit_volatile_store (ctx, ins->next->dreg);
2568 } else if (MONO_IS_COND_EXC (ins->next)) {
2569 emit_cond_system_exception (ctx, bb, ins->next->inst_p1, cmp);
2570 CHECK_FAILURE (ctx);
2571 builder = ctx->builder;
2573 LLVM_FAILURE (ctx, "next");
2587 rel = mono_opcode_to_cond (ins->opcode);
2589 cmp = LLVMBuildFCmp (builder, fpcond_to_llvm_cond [rel], convert (ctx, lhs, LLVMDoubleType ()), convert (ctx, rhs, LLVMDoubleType ()), "");
2590 values [ins->dreg] = LLVMBuildZExt (builder, cmp, LLVMInt32Type (), dname);
2598 gboolean empty = TRUE;
2600 /* Check that all input bblocks really branch to us */
2601 for (i = 0; i < bb->in_count; ++i) {
2602 if (bb->in_bb [i]->last_ins && bb->in_bb [i]->last_ins->opcode == OP_NOT_REACHED)
2603 ins->inst_phi_args [i + 1] = -1;
2609 /* LLVM doesn't like phi instructions with zero operands */
2610 ctx->is_dead [ins->dreg] = TRUE;
2614 /* Created earlier, insert it now */
2615 LLVMInsertIntoBuilder (builder, values [ins->dreg]);
2617 for (i = 0; i < ins->inst_phi_args [0]; i++) {
2618 int sreg1 = ins->inst_phi_args [i + 1];
2622 * Count the number of times the incoming bblock branches to us,
2623 * since llvm requires a separate entry for each.
2625 if (bb->in_bb [i]->last_ins && bb->in_bb [i]->last_ins->opcode == OP_SWITCH) {
2626 MonoInst *switch_ins = bb->in_bb [i]->last_ins;
2629 for (j = 0; j < GPOINTER_TO_UINT (switch_ins->klass); ++j) {
2630 if (switch_ins->inst_many_bb [j] == bb)
2637 /* Remember for later */
2638 for (j = 0; j < count; ++j) {
2639 PhiNode *node = mono_mempool_alloc0 (ctx->mempool, sizeof (PhiNode));
2642 node->in_bb = bb->in_bb [i];
2644 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);
2654 values [ins->dreg] = lhs;
2657 MonoInst *var = get_vreg_to_inst (cfg, ins->dreg);
2660 values [ins->dreg] = lhs;
2662 if (var && var->klass->byval_arg.type == MONO_TYPE_R4) {
2664 * This is added by the spilling pass in case of the JIT,
2665 * but we have to do it ourselves.
2667 values [ins->dreg] = convert (ctx, values [ins->dreg], LLVMFloatType ());
2701 lhs = convert (ctx, lhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
2702 rhs = convert (ctx, rhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
2704 switch (ins->opcode) {
2707 values [ins->dreg] = LLVMBuildAdd (builder, lhs, rhs, dname);
2711 values [ins->dreg] = LLVMBuildSub (builder, lhs, rhs, dname);
2715 values [ins->dreg] = LLVMBuildMul (builder, lhs, rhs, dname);
2719 values [ins->dreg] = LLVMBuildSRem (builder, lhs, rhs, dname);
2723 values [ins->dreg] = LLVMBuildURem (builder, lhs, rhs, dname);
2727 values [ins->dreg] = LLVMBuildSDiv (builder, lhs, rhs, dname);
2731 values [ins->dreg] = LLVMBuildUDiv (builder, lhs, rhs, dname);
2734 values [ins->dreg] = LLVMBuildFDiv (builder, lhs, rhs, dname);
2738 values [ins->dreg] = LLVMBuildAnd (builder, lhs, rhs, dname);
2742 values [ins->dreg] = LLVMBuildOr (builder, lhs, rhs, dname);
2746 values [ins->dreg] = LLVMBuildXor (builder, lhs, rhs, dname);
2750 values [ins->dreg] = LLVMBuildShl (builder, lhs, rhs, dname);
2754 values [ins->dreg] = LLVMBuildAShr (builder, lhs, rhs, dname);
2758 values [ins->dreg] = LLVMBuildLShr (builder, lhs, rhs, dname);
2762 values [ins->dreg] = LLVMBuildFAdd (builder, lhs, rhs, dname);
2765 values [ins->dreg] = LLVMBuildFSub (builder, lhs, rhs, dname);
2768 values [ins->dreg] = LLVMBuildFMul (builder, lhs, rhs, dname);
2772 g_assert_not_reached ();
2779 case OP_IREM_UN_IMM:
2781 case OP_IDIV_UN_IMM:
2787 case OP_ISHR_UN_IMM:
2796 case OP_LSHR_UN_IMM:
2802 case OP_SHR_UN_IMM: {
2805 if (spec [MONO_INST_SRC1] == 'l') {
2806 imm = LLVMConstInt (LLVMInt64Type (), GET_LONG_IMM (ins), FALSE);
2808 imm = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
2811 #if SIZEOF_VOID_P == 4
2812 if (ins->opcode == OP_LSHL_IMM || ins->opcode == OP_LSHR_IMM || ins->opcode == OP_LSHR_UN_IMM)
2813 imm = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
2816 if (LLVMGetTypeKind (LLVMTypeOf (lhs)) == LLVMPointerTypeKind)
2817 lhs = convert (ctx, lhs, IntPtrType ());
2818 imm = convert (ctx, imm, LLVMTypeOf (lhs));
2819 switch (ins->opcode) {
2823 values [ins->dreg] = LLVMBuildAdd (builder, lhs, imm, dname);
2827 values [ins->dreg] = LLVMBuildSub (builder, lhs, imm, dname);
2831 values [ins->dreg] = LLVMBuildMul (builder, lhs, imm, dname);
2835 values [ins->dreg] = LLVMBuildSDiv (builder, lhs, imm, dname);
2837 case OP_IDIV_UN_IMM:
2838 case OP_LDIV_UN_IMM:
2839 values [ins->dreg] = LLVMBuildUDiv (builder, lhs, imm, dname);
2843 values [ins->dreg] = LLVMBuildSRem (builder, lhs, imm, dname);
2845 case OP_IREM_UN_IMM:
2846 values [ins->dreg] = LLVMBuildURem (builder, lhs, imm, dname);
2851 values [ins->dreg] = LLVMBuildAnd (builder, lhs, imm, dname);
2855 values [ins->dreg] = LLVMBuildOr (builder, lhs, imm, dname);
2859 values [ins->dreg] = LLVMBuildXor (builder, lhs, imm, dname);
2864 values [ins->dreg] = LLVMBuildShl (builder, lhs, imm, dname);
2869 values [ins->dreg] = LLVMBuildAShr (builder, lhs, imm, dname);
2871 case OP_ISHR_UN_IMM:
2872 /* This is used to implement conv.u4, so the lhs could be an i8 */
2873 lhs = convert (ctx, lhs, LLVMInt32Type ());
2874 imm = convert (ctx, imm, LLVMInt32Type ());
2875 values [ins->dreg] = LLVMBuildLShr (builder, lhs, imm, dname);
2877 case OP_LSHR_UN_IMM:
2879 values [ins->dreg] = LLVMBuildLShr (builder, lhs, imm, dname);
2882 g_assert_not_reached ();
2887 values [ins->dreg] = LLVMBuildSub (builder, LLVMConstInt (LLVMInt32Type (), 0, FALSE), convert (ctx, lhs, LLVMInt32Type ()), dname);
2890 values [ins->dreg] = LLVMBuildSub (builder, LLVMConstInt (LLVMInt64Type (), 0, FALSE), lhs, dname);
2893 lhs = convert (ctx, lhs, LLVMDoubleType ());
2894 values [ins->dreg] = LLVMBuildFSub (builder, LLVMConstReal (LLVMDoubleType (), 0.0), lhs, dname);
2897 guint32 v = 0xffffffff;
2898 values [ins->dreg] = LLVMBuildXor (builder, LLVMConstInt (LLVMInt32Type (), v, FALSE), convert (ctx, lhs, LLVMInt32Type ()), dname);
2902 guint64 v = 0xffffffffffffffffLL;
2903 values [ins->dreg] = LLVMBuildXor (builder, LLVMConstInt (LLVMInt64Type (), v, FALSE), lhs, dname);
2906 #if defined(TARGET_X86) || defined(TARGET_AMD64)
2908 LLVMValueRef v1, v2;
2910 v1 = LLVMBuildMul (builder, convert (ctx, rhs, IntPtrType ()), LLVMConstInt (IntPtrType (), (1 << ins->backend.shift_amount), FALSE), "");
2911 v2 = LLVMBuildAdd (builder, convert (ctx, lhs, IntPtrType ()), v1, "");
2912 values [ins->dreg] = LLVMBuildAdd (builder, v2, LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE), dname);
2917 case OP_ICONV_TO_I1:
2918 case OP_ICONV_TO_I2:
2919 case OP_ICONV_TO_I4:
2920 case OP_ICONV_TO_U1:
2921 case OP_ICONV_TO_U2:
2922 case OP_ICONV_TO_U4:
2923 case OP_LCONV_TO_I1:
2924 case OP_LCONV_TO_I2:
2925 case OP_LCONV_TO_U1:
2926 case OP_LCONV_TO_U2:
2927 case OP_LCONV_TO_U4: {
2930 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);
2932 /* Have to do two casts since our vregs have type int */
2933 v = LLVMBuildTrunc (builder, lhs, op_to_llvm_type (ins->opcode), "");
2935 values [ins->dreg] = LLVMBuildSExt (builder, v, LLVMInt32Type (), dname);
2937 values [ins->dreg] = LLVMBuildZExt (builder, v, LLVMInt32Type (), dname);
2940 case OP_ICONV_TO_I8:
2941 values [ins->dreg] = LLVMBuildSExt (builder, lhs, LLVMInt64Type (), dname);
2943 case OP_ICONV_TO_U8:
2944 values [ins->dreg] = LLVMBuildZExt (builder, lhs, LLVMInt64Type (), dname);
2946 case OP_FCONV_TO_I4:
2947 values [ins->dreg] = LLVMBuildFPToSI (builder, lhs, LLVMInt32Type (), dname);
2949 case OP_FCONV_TO_I1:
2950 values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildFPToSI (builder, lhs, LLVMInt8Type (), dname), LLVMInt32Type (), "");
2952 case OP_FCONV_TO_U1:
2953 values [ins->dreg] = LLVMBuildZExt (builder, LLVMBuildFPToUI (builder, lhs, LLVMInt8Type (), dname), LLVMInt32Type (), "");
2955 case OP_FCONV_TO_I2:
2956 values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildFPToSI (builder, lhs, LLVMInt16Type (), dname), LLVMInt32Type (), "");
2958 case OP_FCONV_TO_U2:
2959 values [ins->dreg] = LLVMBuildZExt (builder, LLVMBuildFPToUI (builder, lhs, LLVMInt16Type (), dname), LLVMInt32Type (), "");
2961 case OP_FCONV_TO_I8:
2962 values [ins->dreg] = LLVMBuildFPToSI (builder, lhs, LLVMInt64Type (), dname);
2965 values [ins->dreg] = LLVMBuildFPToSI (builder, lhs, IntPtrType (), dname);
2967 case OP_ICONV_TO_R8:
2968 case OP_LCONV_TO_R8:
2969 values [ins->dreg] = LLVMBuildSIToFP (builder, lhs, LLVMDoubleType (), dname);
2971 case OP_LCONV_TO_R_UN:
2972 values [ins->dreg] = LLVMBuildUIToFP (builder, lhs, LLVMDoubleType (), dname);
2974 #if SIZEOF_VOID_P == 4
2977 case OP_LCONV_TO_I4:
2978 values [ins->dreg] = LLVMBuildTrunc (builder, lhs, LLVMInt32Type (), dname);
2980 case OP_ICONV_TO_R4:
2981 case OP_LCONV_TO_R4:
2982 v = LLVMBuildSIToFP (builder, lhs, LLVMFloatType (), "");
2983 values [ins->dreg] = LLVMBuildFPExt (builder, v, LLVMDoubleType (), dname);
2985 case OP_FCONV_TO_R4:
2986 v = LLVMBuildFPTrunc (builder, lhs, LLVMFloatType (), "");
2987 values [ins->dreg] = LLVMBuildFPExt (builder, v, LLVMDoubleType (), dname);
2990 values [ins->dreg] = LLVMBuildSExt (builder, convert (ctx, lhs, LLVMInt32Type ()), LLVMInt64Type (), dname);
2993 values [ins->dreg] = LLVMBuildZExt (builder, convert (ctx, lhs, LLVMInt32Type ()), LLVMInt64Type (), dname);
2996 values [ins->dreg] = LLVMBuildTrunc (builder, lhs, LLVMInt32Type (), dname);
2998 case OP_LOCALLOC_IMM: {
3001 guint32 size = ins->inst_imm;
3002 size = (size + (MONO_ARCH_FRAME_ALIGNMENT - 1)) & ~ (MONO_ARCH_FRAME_ALIGNMENT - 1);
3004 v = mono_llvm_build_alloca (builder, LLVMInt8Type (), LLVMConstInt (LLVMInt32Type (), size, FALSE), MONO_ARCH_FRAME_ALIGNMENT, "");
3006 if (ins->flags & MONO_INST_INIT) {
3007 LLVMValueRef args [5];
3010 args [1] = LLVMConstInt (LLVMInt8Type (), 0, FALSE);
3011 args [2] = LLVMConstInt (LLVMInt32Type (), size, FALSE);
3012 args [3] = LLVMConstInt (LLVMInt32Type (), MONO_ARCH_FRAME_ALIGNMENT, FALSE);
3013 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
3014 LLVMBuildCall (builder, LLVMGetNamedFunction (module, memset_func_name), args, memset_param_count, "");
3017 values [ins->dreg] = v;
3021 LLVMValueRef v, size;
3023 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), "");
3025 v = mono_llvm_build_alloca (builder, LLVMInt8Type (), size, MONO_ARCH_FRAME_ALIGNMENT, "");
3027 if (ins->flags & MONO_INST_INIT) {
3028 LLVMValueRef args [5];
3031 args [1] = LLVMConstInt (LLVMInt8Type (), 0, FALSE);
3033 args [3] = LLVMConstInt (LLVMInt32Type (), MONO_ARCH_FRAME_ALIGNMENT, FALSE);
3034 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
3035 LLVMBuildCall (builder, LLVMGetNamedFunction (module, memset_func_name), args, memset_param_count, "");
3037 values [ins->dreg] = v;
3041 case OP_LOADI1_MEMBASE:
3042 case OP_LOADU1_MEMBASE:
3043 case OP_LOADI2_MEMBASE:
3044 case OP_LOADU2_MEMBASE:
3045 case OP_LOADI4_MEMBASE:
3046 case OP_LOADU4_MEMBASE:
3047 case OP_LOADI8_MEMBASE:
3048 case OP_LOADR4_MEMBASE:
3049 case OP_LOADR8_MEMBASE:
3050 case OP_LOAD_MEMBASE:
3058 LLVMValueRef base, index, addr;
3060 gboolean sext = FALSE, zext = FALSE;
3061 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
3063 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
3068 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)) {
3069 addr = LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE);
3074 if (ins->inst_offset == 0) {
3076 } else if (ins->inst_offset % size != 0) {
3077 /* Unaligned load */
3078 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset, FALSE);
3079 addr = LLVMBuildGEP (builder, convert (ctx, base, LLVMPointerType (LLVMInt8Type (), 0)), &index, 1, "");
3081 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
3082 addr = LLVMBuildGEP (builder, convert (ctx, base, LLVMPointerType (t, 0)), &index, 1, "");
3086 addr = convert (ctx, addr, LLVMPointerType (t, 0));
3088 values [ins->dreg] = emit_load (ctx, bb, &builder, size, addr, dname, is_volatile);
3090 if (!is_volatile && (ins->flags & MONO_INST_INVARIANT_LOAD)) {
3092 * These will signal LLVM that these loads do not alias any stores, and
3093 * they can't fail, allowing them to be hoisted out of loops.
3095 set_invariant_load_flag (values [ins->dreg]);
3096 set_metadata_flag (values [ins->dreg], "mono.nofail.load");
3100 values [ins->dreg] = LLVMBuildSExt (builder, values [ins->dreg], LLVMInt32Type (), dname);
3102 values [ins->dreg] = LLVMBuildZExt (builder, values [ins->dreg], LLVMInt32Type (), dname);
3103 else if (ins->opcode == OP_LOADR4_MEMBASE)
3104 values [ins->dreg] = LLVMBuildFPExt (builder, values [ins->dreg], LLVMDoubleType (), dname);
3108 case OP_STOREI1_MEMBASE_REG:
3109 case OP_STOREI2_MEMBASE_REG:
3110 case OP_STOREI4_MEMBASE_REG:
3111 case OP_STOREI8_MEMBASE_REG:
3112 case OP_STORER4_MEMBASE_REG:
3113 case OP_STORER8_MEMBASE_REG:
3114 case OP_STORE_MEMBASE_REG: {
3116 LLVMValueRef index, addr;
3118 gboolean sext = FALSE, zext = FALSE;
3119 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
3121 if (!values [ins->inst_destbasereg])
3122 LLVM_FAILURE (ctx, "inst_destbasereg");
3124 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
3126 if (ins->inst_offset % size != 0) {
3127 /* Unaligned store */
3128 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset, FALSE);
3129 addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (LLVMInt8Type (), 0)), &index, 1, "");
3131 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
3132 addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (t, 0)), &index, 1, "");
3134 emit_store (ctx, bb, &builder, size, convert (ctx, values [ins->sreg1], t), convert (ctx, addr, LLVMPointerType (t, 0)), is_volatile);
3138 case OP_STOREI1_MEMBASE_IMM:
3139 case OP_STOREI2_MEMBASE_IMM:
3140 case OP_STOREI4_MEMBASE_IMM:
3141 case OP_STOREI8_MEMBASE_IMM:
3142 case OP_STORE_MEMBASE_IMM: {
3144 LLVMValueRef index, addr;
3146 gboolean sext = FALSE, zext = FALSE;
3147 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
3149 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
3151 if (ins->inst_offset % size != 0) {
3152 /* Unaligned store */
3153 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset, FALSE);
3154 addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (LLVMInt8Type (), 0)), &index, 1, "");
3156 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
3157 addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (t, 0)), &index, 1, "");
3159 emit_store (ctx, bb, &builder, size, convert (ctx, LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE), t), convert (ctx, addr, LLVMPointerType (t, 0)), is_volatile);
3164 emit_load (ctx, bb, &builder, sizeof (gpointer), convert (ctx, lhs, LLVMPointerType (IntPtrType (), 0)), "", TRUE);
3166 case OP_OUTARG_VTRETADDR:
3173 case OP_VOIDCALL_MEMBASE:
3174 case OP_CALL_MEMBASE:
3175 case OP_LCALL_MEMBASE:
3176 case OP_FCALL_MEMBASE:
3177 case OP_VCALL_MEMBASE:
3178 case OP_VOIDCALL_REG:
3182 case OP_VCALL_REG: {
3183 process_call (ctx, bb, &builder, ins);
3184 CHECK_FAILURE (ctx);
3189 LLVMValueRef indexes [2];
3191 LLVMValueRef got_entry_addr;
3194 * FIXME: Can't allocate from the cfg mempool since that is freed if
3195 * the LLVM compile fails.
3197 ji = g_new0 (MonoJumpInfo, 1);
3198 ji->type = (MonoJumpInfoType)ins->inst_i1;
3199 ji->data.target = ins->inst_p0;
3201 ji = mono_aot_patch_info_dup (ji);
3203 ji->next = cfg->patch_info;
3204 cfg->patch_info = ji;
3206 //mono_add_patch_info (cfg, 0, (MonoJumpInfoType)ins->inst_i1, ins->inst_p0);
3207 got_offset = mono_aot_get_got_offset (cfg->patch_info);
3209 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
3210 indexes [1] = LLVMConstInt (LLVMInt32Type (), (gssize)got_offset, FALSE);
3211 got_entry_addr = LLVMBuildGEP (builder, ctx->lmodule->got_var, indexes, 2, "");
3213 values [ins->dreg] = LLVMBuildLoad (builder, got_entry_addr, dname);
3214 set_invariant_load_flag (values [ins->dreg]);
3217 case OP_NOT_REACHED:
3218 LLVMBuildUnreachable (builder);
3219 has_terminator = TRUE;
3220 g_assert (bb->block_num < cfg->max_block_num);
3221 ctx->unreachable [bb->block_num] = TRUE;
3222 /* Might have instructions after this */
3224 MonoInst *next = ins->next;
3226 * FIXME: If later code uses the regs defined by these instructions,
3227 * compilation will fail.
3229 MONO_DELETE_INS (bb, next);
3233 MonoInst *var = ins->inst_p0;
3235 values [ins->dreg] = addresses [var->dreg];
3239 LLVMValueRef args [1];
3241 args [0] = convert (ctx, lhs, LLVMDoubleType ());
3242 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, "llvm.sin.f64"), args, 1, dname);
3246 LLVMValueRef args [1];
3248 args [0] = convert (ctx, lhs, LLVMDoubleType ());
3249 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, "llvm.cos.f64"), args, 1, dname);
3253 LLVMValueRef args [1];
3256 /* This no longer seems to happen */
3258 * LLVM optimizes sqrt(nan) into undefined in
3259 * lib/Analysis/ConstantFolding.cpp
3260 * Also, sqrt(NegativeInfinity) is optimized into 0.
3262 LLVM_FAILURE (ctx, "sqrt");
3264 args [0] = convert (ctx, lhs, LLVMDoubleType ());
3265 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, "llvm.sqrt.f64"), args, 1, dname);
3269 LLVMValueRef args [1];
3271 args [0] = convert (ctx, lhs, LLVMDoubleType ());
3272 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, "fabs"), args, 1, dname);
3286 lhs = convert (ctx, lhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
3287 rhs = convert (ctx, rhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
3289 switch (ins->opcode) {
3292 v = LLVMBuildICmp (builder, LLVMIntSLE, lhs, rhs, "");
3296 v = LLVMBuildICmp (builder, LLVMIntSGE, lhs, rhs, "");
3300 v = LLVMBuildICmp (builder, LLVMIntULE, lhs, rhs, "");
3304 v = LLVMBuildICmp (builder, LLVMIntUGE, lhs, rhs, "");
3307 g_assert_not_reached ();
3310 values [ins->dreg] = LLVMBuildSelect (builder, v, lhs, rhs, dname);
3313 case OP_ATOMIC_EXCHANGE_I4:
3314 case OP_ATOMIC_EXCHANGE_I8: {
3315 LLVMValueRef args [2];
3318 if (ins->opcode == OP_ATOMIC_EXCHANGE_I4)
3319 t = LLVMInt32Type ();
3321 t = LLVMInt64Type ();
3323 g_assert (ins->inst_offset == 0);
3325 args [0] = convert (ctx, lhs, LLVMPointerType (t, 0));
3326 args [1] = convert (ctx, rhs, t);
3328 values [ins->dreg] = mono_llvm_build_atomic_rmw (builder, LLVM_ATOMICRMW_OP_XCHG, args [0], args [1]);
3331 case OP_ATOMIC_ADD_I4:
3332 case OP_ATOMIC_ADD_I8: {
3333 LLVMValueRef args [2];
3336 if (ins->opcode == OP_ATOMIC_ADD_I4)
3337 t = LLVMInt32Type ();
3339 t = LLVMInt64Type ();
3341 g_assert (ins->inst_offset == 0);
3343 args [0] = convert (ctx, lhs, LLVMPointerType (t, 0));
3344 args [1] = convert (ctx, rhs, t);
3345 values [ins->dreg] = LLVMBuildAdd (builder, mono_llvm_build_atomic_rmw (builder, LLVM_ATOMICRMW_OP_ADD, args [0], args [1]), args [1], dname);
3348 case OP_ATOMIC_CAS_I4:
3349 case OP_ATOMIC_CAS_I8: {
3350 LLVMValueRef args [3], val;
3353 if (ins->opcode == OP_ATOMIC_CAS_I4)
3354 t = LLVMInt32Type ();
3356 t = LLVMInt64Type ();
3358 args [0] = convert (ctx, lhs, LLVMPointerType (t, 0));
3360 args [1] = convert (ctx, values [ins->sreg3], t);
3362 args [2] = convert (ctx, values [ins->sreg2], t);
3363 val = mono_llvm_build_cmpxchg (builder, args [0], args [1], args [2]);
3364 #if LLVM_API_VERSION >= 1
3365 /* cmpxchg returns a pair */
3366 values [ins->dreg] = LLVMBuildExtractValue (builder, val, 0, "");
3368 values [ins->dreg] = val;
3372 case OP_MEMORY_BARRIER: {
3373 mono_llvm_build_fence (builder);
3376 case OP_RELAXED_NOP: {
3377 #if defined(TARGET_AMD64) || defined(TARGET_X86)
3378 emit_call (ctx, bb, &builder, LLVMGetNamedFunction (ctx->module, "llvm.x86.sse2.pause"), NULL, 0);
3385 #if (defined(TARGET_AMD64) || defined(TARGET_X86)) && defined(__linux__)
3387 // 257 == FS segment register
3388 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 257);
3390 // 256 == GS segment register
3391 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 256);
3394 values [ins->dreg] = LLVMBuildLoad (builder, LLVMBuildIntToPtr (builder, LLVMConstInt (IntPtrType (), ins->inst_offset, TRUE), ptrtype, ""), "");
3395 #elif defined(TARGET_AMD64) && defined(TARGET_OSX)
3396 /* See mono_amd64_emit_tls_get () */
3397 int offset = mono_amd64_get_tls_gs_offset () + (ins->inst_offset * 8);
3399 // 256 == GS segment register
3400 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 256);
3401 values [ins->dreg] = LLVMBuildLoad (builder, LLVMBuildIntToPtr (builder, LLVMConstInt (IntPtrType (), offset, TRUE), ptrtype, ""), "");
3403 LLVM_FAILURE (ctx, "opcode tls-get");
3408 case OP_TLS_GET_REG: {
3409 #if defined(TARGET_AMD64) && defined(TARGET_OSX)
3410 /* See emit_tls_get_reg () */
3411 // 256 == GS segment register
3412 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 256);
3413 values [ins->dreg] = LLVMBuildLoad (builder, LLVMBuildIntToPtr (builder, convert (ctx, lhs, LLVMInt32Type ()), ptrtype, ""), "");
3415 LLVM_FAILURE (ctx, "opcode tls-get");
3424 case OP_IADD_OVF_UN:
3426 case OP_ISUB_OVF_UN:
3428 case OP_IMUL_OVF_UN:
3429 #if SIZEOF_VOID_P == 8
3431 case OP_LADD_OVF_UN:
3433 case OP_LSUB_OVF_UN:
3435 case OP_LMUL_OVF_UN:
3438 LLVMValueRef args [2], val, ovf, func;
3440 args [0] = convert (ctx, lhs, op_to_llvm_type (ins->opcode));
3441 args [1] = convert (ctx, rhs, op_to_llvm_type (ins->opcode));
3442 func = LLVMGetNamedFunction (module, ovf_op_to_intrins (ins->opcode));
3444 val = LLVMBuildCall (builder, func, args, 2, "");
3445 values [ins->dreg] = LLVMBuildExtractValue (builder, val, 0, dname);
3446 ovf = LLVMBuildExtractValue (builder, val, 1, "");
3447 emit_cond_system_exception (ctx, bb, "OverflowException", ovf);
3448 CHECK_FAILURE (ctx);
3449 builder = ctx->builder;
3455 * We currently model them using arrays. Promotion to local vregs is
3456 * disabled for them in mono_handle_global_vregs () in the LLVM case,
3457 * so we always have an entry in cfg->varinfo for them.
3458 * FIXME: Is this needed ?
3461 MonoClass *klass = ins->klass;
3462 LLVMValueRef args [5];
3466 LLVM_FAILURE (ctx, "!klass");
3470 if (!addresses [ins->dreg])
3471 addresses [ins->dreg] = build_alloca (ctx, &klass->byval_arg);
3472 args [0] = LLVMBuildBitCast (builder, addresses [ins->dreg], LLVMPointerType (LLVMInt8Type (), 0), "");
3473 args [1] = LLVMConstInt (LLVMInt8Type (), 0, FALSE);
3474 args [2] = LLVMConstInt (LLVMInt32Type (), mono_class_value_size (klass, NULL), FALSE);
3476 args [3] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
3477 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
3478 LLVMBuildCall (builder, LLVMGetNamedFunction (module, memset_func_name), args, memset_param_count, "");
3481 case OP_DUMMY_VZERO:
3484 case OP_STOREV_MEMBASE:
3485 case OP_LOADV_MEMBASE:
3487 MonoClass *klass = ins->klass;
3488 LLVMValueRef src = NULL, dst, args [5];
3489 gboolean done = FALSE;
3493 LLVM_FAILURE (ctx, "!klass");
3497 if (mini_is_gsharedvt_klass (cfg, klass)) {
3499 LLVM_FAILURE (ctx, "gsharedvt");
3503 switch (ins->opcode) {
3504 case OP_STOREV_MEMBASE:
3505 if (cfg->gen_write_barriers && klass->has_references && ins->inst_destbasereg != cfg->frame_reg &&
3506 LLVMGetInstructionOpcode (values [ins->inst_destbasereg]) != LLVMAlloca) {
3507 /* Decomposed earlier */
3508 g_assert_not_reached ();
3511 if (!addresses [ins->sreg1]) {
3513 g_assert (values [ins->sreg1]);
3514 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));
3515 LLVMBuildStore (builder, values [ins->sreg1], dst);
3518 src = LLVMBuildBitCast (builder, addresses [ins->sreg1], LLVMPointerType (LLVMInt8Type (), 0), "");
3519 dst = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_destbasereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (LLVMInt8Type (), 0));
3522 case OP_LOADV_MEMBASE:
3523 if (!addresses [ins->dreg])
3524 addresses [ins->dreg] = build_alloca (ctx, &klass->byval_arg);
3525 src = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_basereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (LLVMInt8Type (), 0));
3526 dst = LLVMBuildBitCast (builder, addresses [ins->dreg], LLVMPointerType (LLVMInt8Type (), 0), "");
3529 if (!addresses [ins->sreg1])
3530 addresses [ins->sreg1] = build_alloca (ctx, &klass->byval_arg);
3531 if (!addresses [ins->dreg])
3532 addresses [ins->dreg] = build_alloca (ctx, &klass->byval_arg);
3533 src = LLVMBuildBitCast (builder, addresses [ins->sreg1], LLVMPointerType (LLVMInt8Type (), 0), "");
3534 dst = LLVMBuildBitCast (builder, addresses [ins->dreg], LLVMPointerType (LLVMInt8Type (), 0), "");
3537 g_assert_not_reached ();
3539 CHECK_FAILURE (ctx);
3546 args [2] = LLVMConstInt (LLVMInt32Type (), mono_class_value_size (klass, NULL), FALSE);
3547 args [3] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
3549 args [3] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
3550 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
3551 LLVMBuildCall (builder, LLVMGetNamedFunction (module, memcpy_func_name), args, memcpy_param_count, "");
3554 case OP_LLVM_OUTARG_VT:
3555 if (!addresses [ins->sreg1]) {
3556 addresses [ins->sreg1] = build_alloca (ctx, &ins->klass->byval_arg);
3557 g_assert (values [ins->sreg1]);
3558 LLVMBuildStore (builder, values [ins->sreg1], addresses [ins->sreg1]);
3560 addresses [ins->dreg] = addresses [ins->sreg1];
3566 #if defined(TARGET_X86) || defined(TARGET_AMD64)
3568 values [ins->dreg] = LLVMConstNull (type_to_llvm_type (ctx, &ins->klass->byval_arg));
3571 case OP_LOADX_MEMBASE: {
3572 LLVMTypeRef t = type_to_llvm_type (ctx, &ins->klass->byval_arg);
3575 src = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_basereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (t, 0));
3576 values [ins->dreg] = mono_llvm_build_aligned_load (builder, src, "", FALSE, 1);
3579 case OP_STOREX_MEMBASE: {
3580 LLVMTypeRef t = LLVMTypeOf (values [ins->sreg1]);
3583 dest = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_destbasereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (t, 0));
3584 mono_llvm_build_aligned_store (builder, values [ins->sreg1], dest, FALSE, 1);
3591 values [ins->dreg] = LLVMBuildAdd (builder, lhs, rhs, "");
3595 values [ins->dreg] = LLVMBuildFAdd (builder, lhs, rhs, "");
3601 values [ins->dreg] = LLVMBuildSub (builder, lhs, rhs, "");
3605 values [ins->dreg] = LLVMBuildFSub (builder, lhs, rhs, "");
3609 values [ins->dreg] = LLVMBuildFMul (builder, lhs, rhs, "");
3613 values [ins->dreg] = LLVMBuildFDiv (builder, lhs, rhs, "");
3616 values [ins->dreg] = LLVMBuildAnd (builder, lhs, rhs, "");
3619 values [ins->dreg] = LLVMBuildOr (builder, lhs, rhs, "");
3622 values [ins->dreg] = LLVMBuildXor (builder, lhs, rhs, "");
3626 values [ins->dreg] = LLVMBuildMul (builder, lhs, rhs, "");
3637 LLVMValueRef v = NULL;
3639 switch (ins->opcode) {
3644 t = LLVMVectorType (LLVMInt32Type (), 4);
3645 rt = LLVMVectorType (LLVMFloatType (), 4);
3651 t = LLVMVectorType (LLVMInt64Type (), 2);
3652 rt = LLVMVectorType (LLVMDoubleType (), 2);
3655 t = LLVMInt32Type ();
3656 rt = LLVMInt32Type ();
3657 g_assert_not_reached ();
3660 lhs = LLVMBuildBitCast (builder, lhs, t, "");
3661 rhs = LLVMBuildBitCast (builder, rhs, t, "");
3662 switch (ins->opcode) {
3665 v = LLVMBuildAnd (builder, lhs, rhs, "");
3669 v = LLVMBuildOr (builder, lhs, rhs, "");
3673 v = LLVMBuildXor (builder, lhs, rhs, "");
3677 v = LLVMBuildAnd (builder, rhs, LLVMBuildNot (builder, lhs, ""), "");
3680 values [ins->dreg] = LLVMBuildBitCast (builder, v, rt, "");
3704 case OP_PADDB_SAT_UN:
3705 case OP_PADDW_SAT_UN:
3706 case OP_PSUBB_SAT_UN:
3707 case OP_PSUBW_SAT_UN:
3715 case OP_PMULW_HIGH_UN: {
3716 LLVMValueRef args [2];
3721 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, simd_op_to_intrins (ins->opcode)), args, 2, dname);
3728 values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildICmp (builder, LLVMIntEQ, lhs, rhs, ""), LLVMTypeOf (lhs), "");
3732 values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildICmp (builder, LLVMIntSGT, lhs, rhs, ""), LLVMTypeOf (lhs), "");
3740 case OP_EXTRACTX_U2:
3742 case OP_EXTRACT_U1: {
3744 gboolean zext = FALSE;
3746 t = simd_op_to_llvm_type (ins->opcode);
3748 switch (ins->opcode) {
3756 case OP_EXTRACTX_U2:
3761 t = LLVMInt32Type ();
3762 g_assert_not_reached ();
3765 lhs = LLVMBuildBitCast (builder, lhs, t, "");
3766 values [ins->dreg] = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), "");
3768 values [ins->dreg] = LLVMBuildZExt (builder, values [ins->dreg], LLVMInt32Type (), "");
3777 case OP_EXPAND_R8: {
3778 LLVMTypeRef t = simd_op_to_llvm_type (ins->opcode);
3779 LLVMValueRef mask [16], v;
3781 for (i = 0; i < 16; ++i)
3782 mask [i] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
3784 v = convert (ctx, values [ins->sreg1], LLVMGetElementType (t));
3786 values [ins->dreg] = LLVMBuildInsertElement (builder, LLVMConstNull (t), v, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
3787 values [ins->dreg] = LLVMBuildShuffleVector (builder, values [ins->dreg], LLVMGetUndef (t), LLVMConstVector (mask, LLVMGetVectorSize (t)), "");
3792 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt8Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
3795 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt16Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
3798 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt32Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
3801 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt64Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
3804 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMFloatType ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
3807 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMDoubleType ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
3818 case OP_EXTRACT_MASK:
3825 v = convert (ctx, values [ins->sreg1], simd_op_to_llvm_type (ins->opcode));
3827 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, simd_op_to_intrins (ins->opcode)), &v, 1, dname);
3831 case OP_ICONV_TO_R8_RAW:
3832 /* Same as OP_ICONV_TO_R8 */
3833 values [ins->dreg] = convert (ctx, LLVMBuildBitCast (builder, lhs, LLVMFloatType (), ""), LLVMDoubleType ());
3838 LLVMValueRef args [3];
3842 args [2] = LLVMConstInt (LLVMInt8Type (), ins->inst_c0, FALSE);
3844 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, simd_op_to_intrins (ins->opcode)), args, 3, dname);
3849 /* This is only used for implementing shifts by non-immediate */
3850 values [ins->dreg] = lhs;
3861 LLVMValueRef args [3];
3864 args [1] = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
3866 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, simd_op_to_intrins (ins->opcode)), args, 2, dname);
3877 case OP_PSHLQ_REG: {
3878 LLVMValueRef args [3];
3881 args [1] = values [ins->sreg2];
3883 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, simd_op_to_intrins (ins->opcode)), args, 2, dname);
3890 case OP_PSHUFLEW_LOW:
3891 case OP_PSHUFLEW_HIGH: {
3893 LLVMValueRef v1 = NULL, v2 = NULL, mask_values [16];
3894 int i, mask_size = 0;
3895 int imask = ins->inst_c0;
3897 /* Convert the x86 shuffle mask to LLVM's */
3898 switch (ins->opcode) {
3901 mask [0] = ((imask >> 0) & 3);
3902 mask [1] = ((imask >> 2) & 3);
3903 mask [2] = ((imask >> 4) & 3) + 4;
3904 mask [3] = ((imask >> 6) & 3) + 4;
3905 v1 = values [ins->sreg1];
3906 v2 = values [ins->sreg2];
3910 mask [0] = ((imask >> 0) & 1);
3911 mask [1] = ((imask >> 1) & 1) + 2;
3912 v1 = values [ins->sreg1];
3913 v2 = values [ins->sreg2];
3915 case OP_PSHUFLEW_LOW:
3917 mask [0] = ((imask >> 0) & 3);
3918 mask [1] = ((imask >> 2) & 3);
3919 mask [2] = ((imask >> 4) & 3);
3920 mask [3] = ((imask >> 6) & 3);
3925 v1 = values [ins->sreg1];
3926 v2 = LLVMGetUndef (LLVMTypeOf (v1));
3928 case OP_PSHUFLEW_HIGH:
3934 mask [4] = 4 + ((imask >> 0) & 3);
3935 mask [5] = 4 + ((imask >> 2) & 3);
3936 mask [6] = 4 + ((imask >> 4) & 3);
3937 mask [7] = 4 + ((imask >> 6) & 3);
3938 v1 = values [ins->sreg1];
3939 v2 = LLVMGetUndef (LLVMTypeOf (v1));
3943 mask [0] = ((imask >> 0) & 3);
3944 mask [1] = ((imask >> 2) & 3);
3945 mask [2] = ((imask >> 4) & 3);
3946 mask [3] = ((imask >> 6) & 3);
3947 v1 = values [ins->sreg1];
3948 v2 = LLVMGetUndef (LLVMTypeOf (v1));
3951 g_assert_not_reached ();
3953 for (i = 0; i < mask_size; ++i)
3954 mask_values [i] = LLVMConstInt (LLVMInt32Type (), mask [i], FALSE);
3956 values [ins->dreg] =
3957 LLVMBuildShuffleVector (builder, v1, v2,
3958 LLVMConstVector (mask_values, mask_size), dname);
3962 case OP_UNPACK_LOWB:
3963 case OP_UNPACK_LOWW:
3964 case OP_UNPACK_LOWD:
3965 case OP_UNPACK_LOWQ:
3966 case OP_UNPACK_LOWPS:
3967 case OP_UNPACK_LOWPD:
3968 case OP_UNPACK_HIGHB:
3969 case OP_UNPACK_HIGHW:
3970 case OP_UNPACK_HIGHD:
3971 case OP_UNPACK_HIGHQ:
3972 case OP_UNPACK_HIGHPS:
3973 case OP_UNPACK_HIGHPD: {
3975 LLVMValueRef mask_values [16];
3976 int i, mask_size = 0;
3977 gboolean low = FALSE;
3979 switch (ins->opcode) {
3980 case OP_UNPACK_LOWB:
3984 case OP_UNPACK_LOWW:
3988 case OP_UNPACK_LOWD:
3989 case OP_UNPACK_LOWPS:
3993 case OP_UNPACK_LOWQ:
3994 case OP_UNPACK_LOWPD:
3998 case OP_UNPACK_HIGHB:
4001 case OP_UNPACK_HIGHW:
4004 case OP_UNPACK_HIGHD:
4005 case OP_UNPACK_HIGHPS:
4008 case OP_UNPACK_HIGHQ:
4009 case OP_UNPACK_HIGHPD:
4013 g_assert_not_reached ();
4017 for (i = 0; i < (mask_size / 2); ++i) {
4019 mask [(i * 2) + 1] = mask_size + i;
4022 for (i = 0; i < (mask_size / 2); ++i) {
4023 mask [(i * 2)] = (mask_size / 2) + i;
4024 mask [(i * 2) + 1] = mask_size + (mask_size / 2) + i;
4028 for (i = 0; i < mask_size; ++i)
4029 mask_values [i] = LLVMConstInt (LLVMInt32Type (), mask [i], FALSE);
4031 values [ins->dreg] =
4032 LLVMBuildShuffleVector (builder, values [ins->sreg1], values [ins->sreg2],
4033 LLVMConstVector (mask_values, mask_size), dname);
4038 LLVMTypeRef t = simd_op_to_llvm_type (ins->opcode);
4039 LLVMValueRef v, val;
4041 v = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
4042 val = LLVMConstNull (t);
4043 val = LLVMBuildInsertElement (builder, val, v, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
4044 val = LLVMBuildInsertElement (builder, val, v, LLVMConstInt (LLVMInt32Type (), 1, FALSE), dname);
4046 values [ins->dreg] = val;
4050 case OP_DUPPS_HIGH: {
4051 LLVMTypeRef t = simd_op_to_llvm_type (ins->opcode);
4052 LLVMValueRef v1, v2, val;
4055 if (ins->opcode == OP_DUPPS_LOW) {
4056 v1 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
4057 v2 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 2, FALSE), "");
4059 v1 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 1, FALSE), "");
4060 v2 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 3, FALSE), "");
4062 val = LLVMConstNull (t);
4063 val = LLVMBuildInsertElement (builder, val, v1, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
4064 val = LLVMBuildInsertElement (builder, val, v1, LLVMConstInt (LLVMInt32Type (), 1, FALSE), "");
4065 val = LLVMBuildInsertElement (builder, val, v2, LLVMConstInt (LLVMInt32Type (), 2, FALSE), "");
4066 val = LLVMBuildInsertElement (builder, val, v2, LLVMConstInt (LLVMInt32Type (), 3, FALSE), "");
4068 values [ins->dreg] = val;
4078 * EXCEPTION HANDLING
4080 case OP_IMPLICIT_EXCEPTION:
4081 /* This marks a place where an implicit exception can happen */
4082 if (bb->region != -1)
4083 LLVM_FAILURE (ctx, "implicit-exception");
4087 MonoMethodSignature *throw_sig;
4088 LLVMValueRef callee, arg;
4089 gboolean rethrow = (ins->opcode == OP_RETHROW);
4090 const char *icall_name;
4092 callee = rethrow ? ctx->lmodule->rethrow : ctx->lmodule->throw;
4093 icall_name = rethrow ? "mono_arch_rethrow_exception" : "mono_arch_throw_exception";
4096 throw_sig = mono_metadata_signature_alloc (mono_get_corlib (), 1);
4097 throw_sig->ret = &mono_get_void_class ()->byval_arg;
4098 throw_sig->params [0] = &mono_get_object_class ()->byval_arg;
4099 if (cfg->compile_aot) {
4100 callee = get_plt_entry (ctx, sig_to_llvm_sig (ctx, throw_sig), MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
4102 callee = LLVMAddFunction (module, icall_name, sig_to_llvm_sig (ctx, throw_sig));
4106 * LLVM doesn't push the exception argument, so we need a different
4109 LLVMAddGlobalMapping (ctx->lmodule->ee, callee, resolve_patch (cfg, MONO_PATCH_INFO_INTERNAL_METHOD, rethrow ? "llvm_rethrow_exception_trampoline" : "llvm_throw_exception_trampoline"));
4111 LLVMAddGlobalMapping (ctx->lmodule->ee, callee, resolve_patch (cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name));
4115 mono_memory_barrier ();
4117 ctx->lmodule->rethrow = callee;
4119 ctx->lmodule->throw = callee;
4121 arg = convert (ctx, lhs, type_to_llvm_type (ctx, &mono_get_object_class ()->byval_arg));
4122 emit_call (ctx, bb, &builder, callee, &arg, 1);
4125 case OP_CALL_HANDLER: {
4127 * We don't 'call' handlers, but instead simply branch to them.
4128 * The code generated by ENDFINALLY will branch back to us.
4130 LLVMBasicBlockRef noex_bb;
4132 BBInfo *info = &bblocks [ins->inst_target_bb->block_num];
4134 bb_list = info->call_handler_return_bbs;
4137 * Set the indicator variable for the finally clause.
4139 lhs = info->finally_ind;
4141 LLVMBuildStore (builder, LLVMConstInt (LLVMInt32Type (), g_slist_length (bb_list) + 1, FALSE), lhs);
4143 /* Branch to the finally clause */
4144 LLVMBuildBr (builder, info->call_handler_target_bb);
4146 noex_bb = gen_bb (ctx, "CALL_HANDLER_CONT_BB");
4147 info->call_handler_return_bbs = g_slist_append_mempool (cfg->mempool, info->call_handler_return_bbs, noex_bb);
4149 builder = ctx->builder = create_builder (ctx);
4150 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
4152 bblocks [bb->block_num].end_bblock = noex_bb;
4155 case OP_START_HANDLER: {
4158 case OP_ENDFINALLY: {
4159 LLVMBasicBlockRef resume_bb;
4160 MonoBasicBlock *handler_bb;
4161 LLVMValueRef val, switch_ins, callee;
4165 handler_bb = g_hash_table_lookup (ctx->region_to_handler, GUINT_TO_POINTER (mono_get_block_region_notry (cfg, bb->region)));
4166 g_assert (handler_bb);
4167 info = &bblocks [handler_bb->block_num];
4168 lhs = info->finally_ind;
4171 bb_list = info->call_handler_return_bbs;
4173 resume_bb = gen_bb (ctx, "ENDFINALLY_RESUME_BB");
4175 /* Load the finally variable */
4176 val = LLVMBuildLoad (builder, lhs, "");
4178 /* Reset the variable */
4179 LLVMBuildStore (builder, LLVMConstInt (LLVMInt32Type (), 0, FALSE), lhs);
4181 /* Branch to either resume_bb, or to the bblocks in bb_list */
4182 switch_ins = LLVMBuildSwitch (builder, val, resume_bb, g_slist_length (bb_list));
4184 * The other targets are added at the end to handle OP_CALL_HANDLER
4185 * opcodes processed later.
4187 info->endfinally_switch_ins_list = g_slist_append_mempool (cfg->mempool, info->endfinally_switch_ins_list, switch_ins);
4189 builder = ctx->builder = create_builder (ctx);
4190 LLVMPositionBuilderAtEnd (ctx->builder, resume_bb);
4192 if (ctx->cfg->compile_aot) {
4193 callee = get_plt_entry (ctx, LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE), MONO_PATCH_INFO_INTERNAL_METHOD, "llvm_resume_unwind_trampoline");
4195 callee = LLVMGetNamedFunction (module, "llvm_resume_unwind_trampoline");
4197 LLVMBuildCall (builder, callee, NULL, 0, "");
4199 LLVMBuildUnreachable (builder);
4200 has_terminator = TRUE;
4206 sprintf (reason, "opcode %s", mono_inst_name (ins->opcode));
4207 LLVM_FAILURE (ctx, reason);
4212 /* Convert the value to the type required by phi nodes */
4213 if (spec [MONO_INST_DEST] != ' ' && !MONO_IS_STORE_MEMBASE (ins) && ctx->vreg_types [ins->dreg]) {
4214 if (!values [ins->dreg])
4216 values [ins->dreg] = addresses [ins->dreg];
4218 values [ins->dreg] = convert (ctx, values [ins->dreg], ctx->vreg_types [ins->dreg]);
4221 /* Add stores for volatile variables */
4222 if (spec [MONO_INST_DEST] != ' ' && spec [MONO_INST_DEST] != 'v' && !MONO_IS_STORE_MEMBASE (ins))
4223 emit_volatile_store (ctx, ins->dreg);
4226 if (!has_terminator && bb->next_bb && (bb == cfg->bb_entry || bb->in_count > 0))
4227 LLVMBuildBr (builder, get_bb (ctx, bb->next_bb));
4229 if (bb == cfg->bb_exit && sig->ret->type == MONO_TYPE_VOID)
4230 LLVMBuildRetVoid (builder);
4232 if (bb == cfg->bb_entry)
4233 ctx->last_alloca = LLVMGetLastInstruction (get_bb (ctx, cfg->bb_entry));
4242 * mono_llvm_check_method_supported:
4244 * Do some quick checks to decide whenever cfg->method can be compiled by LLVM, to avoid
4245 * compiling a method twice.
4248 mono_llvm_check_method_supported (MonoCompile *cfg)
4250 MonoMethodHeader *header = cfg->header;
4251 MonoExceptionClause *clause;
4254 if (cfg->method->save_lmf) {
4255 cfg->exception_message = g_strdup ("lmf");
4256 cfg->disable_llvm = TRUE;
4258 if (cfg->disable_llvm)
4262 for (i = 0; i < header->num_clauses; ++i) {
4263 clause = &header->clauses [i];
4265 if (i > 0 && clause->try_offset <= header->clauses [i - 1].handler_offset + header->clauses [i - 1].handler_len) {
4267 * FIXME: Some tests still fail with nested clauses.
4269 cfg->exception_message = g_strdup ("nested clauses");
4270 cfg->disable_llvm = TRUE;
4274 if (cfg->disable_llvm)
4279 if (cfg->method->dynamic) {
4280 cfg->exception_message = g_strdup ("dynamic.");
4281 cfg->disable_llvm = TRUE;
4283 if (cfg->disable_llvm)
4288 * mono_llvm_emit_method:
4290 * Emit LLVM IL from the mono IL, and compile it to native code using LLVM.
4293 mono_llvm_emit_method (MonoCompile *cfg)
4296 MonoMethodSignature *sig;
4298 LLVMTypeRef method_type;
4299 LLVMValueRef method = NULL;
4301 LLVMValueRef *values;
4302 int i, max_block_num, bb_index;
4303 gboolean last = FALSE;
4304 GPtrArray *phi_values;
4305 LLVMCallInfo *linfo;
4307 LLVMModuleRef module;
4309 GPtrArray *bblock_list;
4310 MonoMethodHeader *header;
4311 MonoExceptionClause *clause;
4315 /* The code below might acquire the loader lock, so use it for global locking */
4316 mono_loader_lock ();
4318 /* Used to communicate with the callbacks */
4319 mono_native_tls_set_value (current_cfg_tls_id, cfg);
4321 ctx = g_new0 (EmitContext, 1);
4323 ctx->mempool = cfg->mempool;
4326 * This maps vregs to the LLVM instruction defining them
4328 values = g_new0 (LLVMValueRef, cfg->next_vreg);
4330 * This maps vregs for volatile variables to the LLVM instruction defining their
4333 ctx->addresses = g_new0 (LLVMValueRef, cfg->next_vreg);
4334 ctx->vreg_types = g_new0 (LLVMTypeRef, cfg->next_vreg);
4335 ctx->vreg_cli_types = g_new0 (MonoType*, cfg->next_vreg);
4336 phi_values = g_ptr_array_sized_new (256);
4338 * This signals whenever the vreg was defined by a phi node with no input vars
4339 * (i.e. all its input bblocks end with NOT_REACHABLE).
4341 ctx->is_dead = g_new0 (gboolean, cfg->next_vreg);
4342 /* Whenever the bblock is unreachable */
4343 ctx->unreachable = g_new0 (gboolean, cfg->max_block_num);
4345 bblock_list = g_ptr_array_sized_new (256);
4347 ctx->values = values;
4348 ctx->region_to_handler = g_hash_table_new (NULL, NULL);
4350 if (cfg->compile_aot) {
4351 ctx->lmodule = &aot_module;
4352 method_name = mono_aot_get_method_name (cfg);
4353 cfg->llvm_method_name = g_strdup (method_name);
4355 init_jit_module (cfg->domain);
4356 ctx->lmodule = domain_jit_info (cfg->domain)->llvm_module;
4357 method_name = mono_method_full_name (cfg->method, TRUE);
4360 module = ctx->module = ctx->lmodule->module;
4363 LLVM_FAILURE (ctx, "gsharedvt");
4367 static int count = 0;
4370 if (g_getenv ("LLVM_COUNT")) {
4371 if (count == atoi (g_getenv ("LLVM_COUNT"))) {
4372 printf ("LAST: %s\n", mono_method_full_name (cfg->method, TRUE));
4376 if (count > atoi (g_getenv ("LLVM_COUNT")))
4377 LLVM_FAILURE (ctx, "");
4382 sig = mono_method_signature (cfg->method);
4385 linfo = mono_arch_get_llvm_call_info (cfg, sig);
4387 CHECK_FAILURE (ctx);
4390 linfo->rgctx_arg = TRUE;
4391 method_type = sig_to_llvm_sig_full (ctx, sig, linfo, &sinfo);
4392 CHECK_FAILURE (ctx);
4395 * This maps parameter indexes in the original signature to the indexes in
4396 * the LLVM signature.
4398 ctx->pindexes = sinfo.pindexes;
4400 method = LLVMAddFunction (module, method_name, method_type);
4401 ctx->lmethod = method;
4403 LLVMSetFunctionCallConv (method, LLVMMono1CallConv);
4404 LLVMSetLinkage (method, LLVMPrivateLinkage);
4406 LLVMAddFunctionAttr (method, LLVMUWTable);
4408 if (cfg->compile_aot) {
4409 LLVMSetLinkage (method, LLVMInternalLinkage);
4410 #if LLVM_API_VERSION == 0
4411 /* This causes an assertion in later LLVM versions */
4412 LLVMSetVisibility (method, LLVMHiddenVisibility);
4415 LLVMSetLinkage (method, LLVMPrivateLinkage);
4418 if (cfg->method->save_lmf)
4419 LLVM_FAILURE (ctx, "lmf");
4421 if (sig->pinvoke && cfg->method->wrapper_type != MONO_WRAPPER_RUNTIME_INVOKE)
4422 LLVM_FAILURE (ctx, "pinvoke signature");
4424 header = cfg->header;
4425 for (i = 0; i < header->num_clauses; ++i) {
4426 clause = &header->clauses [i];
4427 if (clause->flags != MONO_EXCEPTION_CLAUSE_FINALLY && clause->flags != MONO_EXCEPTION_CLAUSE_NONE)
4428 LLVM_FAILURE (ctx, "non-finally/catch clause.");
4431 if (linfo->rgctx_arg) {
4432 ctx->rgctx_arg = LLVMGetParam (method, sinfo.rgctx_arg_pindex);
4434 * We mark the rgctx parameter with the inreg attribute, which is mapped to
4435 * MONO_ARCH_RGCTX_REG in the Mono calling convention in llvm, i.e.
4436 * CC_X86_64_Mono in X86CallingConv.td.
4438 LLVMAddAttribute (ctx->rgctx_arg, LLVMInRegAttribute);
4439 LLVMSetValueName (ctx->rgctx_arg, "rgctx");
4441 if (cfg->vret_addr) {
4442 values [cfg->vret_addr->dreg] = LLVMGetParam (method, sinfo.vret_arg_pindex);
4443 LLVMSetValueName (values [cfg->vret_addr->dreg], "vret");
4446 values [cfg->args [0]->dreg] = LLVMGetParam (method, sinfo.this_arg_pindex);
4447 LLVMSetValueName (values [cfg->args [0]->dreg], "this");
4450 names = g_new (char *, sig->param_count);
4451 mono_method_get_param_names (cfg->method, (const char **) names);
4453 for (i = 0; i < sig->param_count; ++i) {
4456 values [cfg->args [i + sig->hasthis]->dreg] = LLVMGetParam (method, sinfo.pindexes [i]);
4457 if (names [i] && names [i][0] != '\0')
4458 name = g_strdup_printf ("arg_%s", names [i]);
4460 name = g_strdup_printf ("arg_%d", i);
4461 LLVMSetValueName (values [cfg->args [i + sig->hasthis]->dreg], name);
4463 if (linfo->args [i + sig->hasthis].storage == LLVMArgVtypeByVal)
4464 LLVMAddAttribute (LLVMGetParam (method, sinfo.pindexes [i]), LLVMByValAttribute);
4469 for (bb = cfg->bb_entry; bb; bb = bb->next_bb)
4470 max_block_num = MAX (max_block_num, bb->block_num);
4471 ctx->bblocks = bblocks = g_new0 (BBInfo, max_block_num + 1);
4473 /* Add branches between non-consecutive bblocks */
4474 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
4475 if (bb->last_ins && MONO_IS_COND_BRANCH_OP (bb->last_ins) &&
4476 bb->next_bb != bb->last_ins->inst_false_bb) {
4478 MonoInst *inst = mono_mempool_alloc0 (cfg->mempool, sizeof (MonoInst));
4479 inst->opcode = OP_BR;
4480 inst->inst_target_bb = bb->last_ins->inst_false_bb;
4481 mono_bblock_add_inst (bb, inst);
4486 * The INDIRECT flag added by OP_LDADDR inhibits optimizations, even if the LDADDR
4487 * was later optimized away, so clear these flags, and add them back for the still
4488 * present OP_LDADDR instructions.
4490 for (i = 0; i < cfg->next_vreg; ++i) {
4493 ins = get_vreg_to_inst (cfg, i);
4494 if (ins && ins != cfg->rgctx_var)
4495 ins->flags &= ~MONO_INST_INDIRECT;
4499 * Make a first pass over the code to precreate PHI nodes/set INDIRECT flags.
4501 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
4503 LLVMBuilderRef builder;
4505 char dname_buf[128];
4507 builder = create_builder (ctx);
4509 for (ins = bb->code; ins; ins = ins->next) {
4510 switch (ins->opcode) {
4515 LLVMTypeRef phi_type = llvm_type_to_stack_type (type_to_llvm_type (ctx, &ins->klass->byval_arg));
4517 CHECK_FAILURE (ctx);
4519 if (ins->opcode == OP_VPHI) {
4520 /* Treat valuetype PHI nodes as operating on the address itself */
4521 g_assert (ins->klass);
4522 phi_type = LLVMPointerType (type_to_llvm_type (ctx, &ins->klass->byval_arg), 0);
4526 * Have to precreate these, as they can be referenced by
4527 * earlier instructions.
4529 sprintf (dname_buf, "t%d", ins->dreg);
4531 values [ins->dreg] = LLVMBuildPhi (builder, phi_type, dname);
4533 if (ins->opcode == OP_VPHI)
4534 ctx->addresses [ins->dreg] = values [ins->dreg];
4536 g_ptr_array_add (phi_values, values [ins->dreg]);
4539 * Set the expected type of the incoming arguments since these have
4540 * to have the same type.
4542 for (i = 0; i < ins->inst_phi_args [0]; i++) {
4543 int sreg1 = ins->inst_phi_args [i + 1];
4546 ctx->vreg_types [sreg1] = phi_type;
4551 ((MonoInst*)ins->inst_p0)->flags |= MONO_INST_INDIRECT;
4560 * Create an ordering for bblocks, use the depth first order first, then
4561 * put the exception handling bblocks last.
4563 for (bb_index = 0; bb_index < cfg->num_bblocks; ++bb_index) {
4564 bb = cfg->bblocks [bb_index];
4565 if (!(bb->region != -1 && !MONO_BBLOCK_IS_IN_REGION (bb, MONO_REGION_TRY))) {
4566 g_ptr_array_add (bblock_list, bb);
4567 bblocks [bb->block_num].added = TRUE;
4571 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
4572 if (!bblocks [bb->block_num].added)
4573 g_ptr_array_add (bblock_list, bb);
4577 * Second pass: generate code.
4579 for (bb_index = 0; bb_index < bblock_list->len; ++bb_index) {
4580 bb = g_ptr_array_index (bblock_list, bb_index);
4582 if (!(bb == cfg->bb_entry || bb->in_count > 0))
4585 process_bb (ctx, bb);
4586 CHECK_FAILURE (ctx);
4589 /* Add incoming phi values */
4590 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
4591 GSList *l, *ins_list;
4593 ins_list = bblocks [bb->block_num].phi_nodes;
4595 for (l = ins_list; l; l = l->next) {
4596 PhiNode *node = l->data;
4597 MonoInst *phi = node->phi;
4598 int sreg1 = node->sreg;
4599 LLVMBasicBlockRef in_bb;
4604 in_bb = get_end_bb (ctx, node->in_bb);
4606 if (ctx->unreachable [node->in_bb->block_num])
4609 if (!values [sreg1])
4610 /* Can happen with values in EH clauses */
4611 LLVM_FAILURE (ctx, "incoming phi sreg1");
4613 if (phi->opcode == OP_VPHI) {
4614 g_assert (LLVMTypeOf (ctx->addresses [sreg1]) == LLVMTypeOf (values [phi->dreg]));
4615 LLVMAddIncoming (values [phi->dreg], &ctx->addresses [sreg1], &in_bb, 1);
4617 if (LLVMTypeOf (values [sreg1]) != LLVMTypeOf (values [phi->dreg]))
4619 LLVM_FAILURE (ctx, "incoming phi arg type mismatch");
4620 g_assert (LLVMTypeOf (values [sreg1]) == LLVMTypeOf (values [phi->dreg]));
4621 LLVMAddIncoming (values [phi->dreg], &values [sreg1], &in_bb, 1);
4626 /* Create the SWITCH statements for ENDFINALLY instructions */
4627 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
4628 BBInfo *info = &bblocks [bb->block_num];
4630 for (l = info->endfinally_switch_ins_list; l; l = l->next) {
4631 LLVMValueRef switch_ins = l->data;
4632 GSList *bb_list = info->call_handler_return_bbs;
4634 for (i = 0; i < g_slist_length (bb_list); ++i)
4635 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), i + 1, FALSE), g_slist_nth (bb_list, i)->data);
4639 if (cfg->verbose_level > 1)
4640 mono_llvm_dump_value (method);
4642 if (cfg->compile_aot)
4643 mark_as_used (ctx->lmodule, method);
4645 if (cfg->compile_aot) {
4646 LLVMValueRef md_args [16];
4647 LLVMValueRef md_node;
4650 method_index = mono_aot_get_method_index (cfg->orig_method);
4651 md_args [0] = LLVMMDString (method_name, strlen (method_name));
4652 md_args [1] = LLVMConstInt (LLVMInt32Type (), method_index, FALSE);
4653 md_node = LLVMMDNode (md_args, 2);
4654 LLVMAddNamedMetadataOperand (module, "mono.function_indexes", md_node);
4655 //LLVMSetMetadata (method, md_kind, LLVMMDNode (&md_arg, 1));
4658 if (cfg->compile_aot) {
4659 /* Don't generate native code, keep the LLVM IR */
4660 if (cfg->compile_aot && cfg->verbose_level)
4661 printf ("%s emitted as %s\n", mono_method_full_name (cfg->method, TRUE), method_name);
4663 //LLVMVerifyFunction(method, 0);
4665 mono_llvm_optimize_method (ctx->lmodule->mono_ee, method);
4667 if (cfg->verbose_level > 1)
4668 mono_llvm_dump_value (method);
4670 cfg->native_code = LLVMGetPointerToGlobal (ctx->lmodule->ee, method);
4672 /* Set by emit_cb */
4673 g_assert (cfg->code_len);
4675 /* FIXME: Free the LLVM IL for the function */
4683 /* Need to add unused phi nodes as they can be referenced by other values */
4684 LLVMBasicBlockRef phi_bb = LLVMAppendBasicBlock (method, "PHI_BB");
4685 LLVMBuilderRef builder;
4687 builder = create_builder (ctx);
4688 LLVMPositionBuilderAtEnd (builder, phi_bb);
4690 for (i = 0; i < phi_values->len; ++i) {
4691 LLVMValueRef v = g_ptr_array_index (phi_values, i);
4692 if (LLVMGetInstructionParent (v) == NULL)
4693 LLVMInsertIntoBuilder (builder, v);
4696 LLVMDeleteFunction (method);
4701 g_free (ctx->addresses);
4702 g_free (ctx->vreg_types);
4703 g_free (ctx->vreg_cli_types);
4704 g_free (ctx->pindexes);
4705 g_free (ctx->is_dead);
4706 g_free (ctx->unreachable);
4707 g_ptr_array_free (phi_values, TRUE);
4708 g_free (ctx->bblocks);
4709 g_hash_table_destroy (ctx->region_to_handler);
4710 g_free (method_name);
4711 g_ptr_array_free (bblock_list, TRUE);
4713 for (l = ctx->builders; l; l = l->next) {
4714 LLVMBuilderRef builder = l->data;
4715 LLVMDisposeBuilder (builder);
4720 mono_native_tls_set_value (current_cfg_tls_id, NULL);
4722 mono_loader_unlock ();
4726 * mono_llvm_emit_call:
4728 * Same as mono_arch_emit_call () for LLVM.
4731 mono_llvm_emit_call (MonoCompile *cfg, MonoCallInst *call)
4734 MonoMethodSignature *sig;
4735 int i, n, stack_size;
4740 sig = call->signature;
4741 n = sig->param_count + sig->hasthis;
4743 call->cinfo = mono_arch_get_llvm_call_info (cfg, sig);
4745 if (cfg->disable_llvm)
4748 if (sig->call_convention == MONO_CALL_VARARG) {
4749 cfg->exception_message = g_strdup ("varargs");
4750 cfg->disable_llvm = TRUE;
4753 for (i = 0; i < n; ++i) {
4756 ainfo = call->cinfo->args + i;
4758 in = call->args [i];
4760 /* Simply remember the arguments */
4761 switch (ainfo->storage) {
4763 case LLVMArgInFPReg: {
4764 MonoType *t = (sig->hasthis && i == 0) ? &mono_get_intptr_class ()->byval_arg : sig->params [i - sig->hasthis];
4767 opcode = mono_type_to_regmove (cfg, t);
4768 if (opcode == OP_FMOVE) {
4769 MONO_INST_NEW (cfg, ins, OP_FMOVE);
4770 ins->dreg = mono_alloc_freg (cfg);
4771 } else if (opcode == OP_LMOVE) {
4772 MONO_INST_NEW (cfg, ins, OP_LMOVE);
4773 ins->dreg = mono_alloc_lreg (cfg);
4775 MONO_INST_NEW (cfg, ins, OP_MOVE);
4776 ins->dreg = mono_alloc_ireg (cfg);
4778 ins->sreg1 = in->dreg;
4781 case LLVMArgVtypeByVal:
4782 case LLVMArgVtypeInReg:
4783 MONO_INST_NEW (cfg, ins, OP_LLVM_OUTARG_VT);
4784 ins->dreg = mono_alloc_ireg (cfg);
4785 ins->sreg1 = in->dreg;
4786 ins->klass = mono_class_from_mono_type (sig->params [i - sig->hasthis]);
4789 call->cinfo = mono_arch_get_llvm_call_info (cfg, sig);
4790 cfg->exception_message = g_strdup ("ainfo->storage");
4791 cfg->disable_llvm = TRUE;
4795 if (!cfg->disable_llvm) {
4796 MONO_ADD_INS (cfg->cbb, ins);
4797 mono_call_inst_add_outarg_reg (cfg, call, ins->dreg, 0, FALSE);
4802 static unsigned char*
4803 alloc_cb (LLVMValueRef function, int size)
4807 cfg = mono_native_tls_get_value (current_cfg_tls_id);
4811 return mono_domain_code_reserve (cfg->domain, size);
4813 return mono_domain_code_reserve (mono_domain_get (), size);
4818 emitted_cb (LLVMValueRef function, void *start, void *end)
4822 cfg = mono_native_tls_get_value (current_cfg_tls_id);
4824 cfg->code_len = (guint8*)end - (guint8*)start;
4828 exception_cb (void *data)
4831 MonoJitExceptionInfo *ei;
4832 guint32 ei_len, i, j, nested_len, nindex;
4833 gpointer *type_info;
4834 int this_reg, this_offset;
4836 cfg = mono_native_tls_get_value (current_cfg_tls_id);
4840 * data points to a DWARF FDE structure, convert it to our unwind format and
4842 * An alternative would be to save it directly, and modify our unwinder to work
4845 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);
4846 if (cfg->verbose_level > 1)
4847 mono_print_unwind_info (cfg->encoded_unwind_ops, cfg->encoded_unwind_ops_len);
4849 /* Count nested clauses */
4851 for (i = 0; i < ei_len; ++i) {
4852 for (j = 0; j < ei_len; ++j) {
4853 gint32 cindex1 = *(gint32*)type_info [i];
4854 MonoExceptionClause *clause1 = &cfg->header->clauses [cindex1];
4855 gint32 cindex2 = *(gint32*)type_info [j];
4856 MonoExceptionClause *clause2 = &cfg->header->clauses [cindex2];
4858 if (cindex1 != cindex2 && clause1->try_offset >= clause2->try_offset && clause1->handler_offset <= clause2->handler_offset) {
4864 cfg->llvm_ex_info = mono_mempool_alloc0 (cfg->mempool, (ei_len + nested_len) * sizeof (MonoJitExceptionInfo));
4865 cfg->llvm_ex_info_len = ei_len + nested_len;
4866 memcpy (cfg->llvm_ex_info, ei, ei_len * sizeof (MonoJitExceptionInfo));
4867 /* Fill the rest of the information from the type info */
4868 for (i = 0; i < ei_len; ++i) {
4869 gint32 clause_index = *(gint32*)type_info [i];
4870 MonoExceptionClause *clause = &cfg->header->clauses [clause_index];
4872 cfg->llvm_ex_info [i].flags = clause->flags;
4873 cfg->llvm_ex_info [i].data.catch_class = clause->data.catch_class;
4877 * For nested clauses, the LLVM produced exception info associates the try interval with
4878 * the innermost handler, while mono expects it to be associated with all nesting clauses.
4880 /* FIXME: These should be order with the normal clauses */
4882 for (i = 0; i < ei_len; ++i) {
4883 for (j = 0; j < ei_len; ++j) {
4884 gint32 cindex1 = *(gint32*)type_info [i];
4885 MonoExceptionClause *clause1 = &cfg->header->clauses [cindex1];
4886 gint32 cindex2 = *(gint32*)type_info [j];
4887 MonoExceptionClause *clause2 = &cfg->header->clauses [cindex2];
4889 if (cindex1 != cindex2 && clause1->try_offset >= clause2->try_offset && clause1->handler_offset <= clause2->handler_offset) {
4891 * The try interval comes from the nested clause, everything else from the
4894 memcpy (&cfg->llvm_ex_info [nindex], &cfg->llvm_ex_info [j], sizeof (MonoJitExceptionInfo));
4895 cfg->llvm_ex_info [nindex].try_start = cfg->llvm_ex_info [i].try_start;
4896 cfg->llvm_ex_info [nindex].try_end = cfg->llvm_ex_info [i].try_end;
4901 g_assert (nindex == ei_len + nested_len);
4902 cfg->llvm_this_reg = this_reg;
4903 cfg->llvm_this_offset = this_offset;
4905 /* type_info [i] is cfg mempool allocated, no need to free it */
4912 dlsym_cb (const char *name, void **symbol)
4918 if (!strcmp (name, "__bzero")) {
4919 *symbol = (void*)bzero;
4921 current = mono_dl_open (NULL, 0, NULL);
4924 err = mono_dl_symbol (current, name, symbol);
4926 mono_dl_close (current);
4928 #ifdef MONO_ARCH_HAVE_CREATE_LLVM_NATIVE_THUNK
4929 *symbol = (char*)mono_arch_create_llvm_native_thunk (mono_domain_get (), (guint8*)(*symbol));
4935 AddFunc (LLVMModuleRef module, const char *name, LLVMTypeRef ret_type, LLVMTypeRef *param_types, int nparams)
4937 LLVMAddFunction (module, name, LLVMFunctionType (ret_type, param_types, nparams, FALSE));
4941 AddFunc2 (LLVMModuleRef module, const char *name, LLVMTypeRef ret_type, LLVMTypeRef param_type1, LLVMTypeRef param_type2)
4943 LLVMTypeRef param_types [4];
4945 param_types [0] = param_type1;
4946 param_types [1] = param_type2;
4948 AddFunc (module, name, ret_type, param_types, 2);
4952 add_intrinsics (LLVMModuleRef module)
4954 /* Emit declarations of instrinsics */
4956 * It would be nicer to emit only the intrinsics actually used, but LLVM's Module
4957 * type doesn't seem to do any locking.
4960 LLVMTypeRef memset_params [] = { LLVMPointerType (LLVMInt8Type (), 0), LLVMInt8Type (), LLVMInt32Type (), LLVMInt32Type (), LLVMInt1Type () };
4962 memset_param_count = 5;
4963 memset_func_name = "llvm.memset.p0i8.i32";
4965 LLVMAddFunction (module, memset_func_name, LLVMFunctionType (LLVMVoidType (), memset_params, memset_param_count, FALSE));
4969 LLVMTypeRef memcpy_params [] = { LLVMPointerType (LLVMInt8Type (), 0), LLVMPointerType (LLVMInt8Type (), 0), LLVMInt32Type (), LLVMInt32Type (), LLVMInt1Type () };
4971 memcpy_param_count = 5;
4972 memcpy_func_name = "llvm.memcpy.p0i8.p0i8.i32";
4974 LLVMAddFunction (module, memcpy_func_name, LLVMFunctionType (LLVMVoidType (), memcpy_params, memcpy_param_count, FALSE));
4978 LLVMTypeRef params [] = { LLVMDoubleType () };
4980 LLVMAddFunction (module, "llvm.sin.f64", LLVMFunctionType (LLVMDoubleType (), params, 1, FALSE));
4981 LLVMAddFunction (module, "llvm.cos.f64", LLVMFunctionType (LLVMDoubleType (), params, 1, FALSE));
4982 LLVMAddFunction (module, "llvm.sqrt.f64", LLVMFunctionType (LLVMDoubleType (), params, 1, FALSE));
4984 /* This isn't an intrinsic, instead llvm seems to special case it by name */
4985 LLVMAddFunction (module, "fabs", LLVMFunctionType (LLVMDoubleType (), params, 1, FALSE));
4989 LLVMTypeRef ovf_res_i32 [] = { LLVMInt32Type (), LLVMInt1Type () };
4990 LLVMTypeRef ovf_params_i32 [] = { LLVMInt32Type (), LLVMInt32Type () };
4992 LLVMAddFunction (module, "llvm.sadd.with.overflow.i32", LLVMFunctionType (LLVMStructType (ovf_res_i32, 2, FALSE), ovf_params_i32, 2, FALSE));
4993 LLVMAddFunction (module, "llvm.uadd.with.overflow.i32", LLVMFunctionType (LLVMStructType (ovf_res_i32, 2, FALSE), ovf_params_i32, 2, FALSE));
4994 LLVMAddFunction (module, "llvm.ssub.with.overflow.i32", LLVMFunctionType (LLVMStructType (ovf_res_i32, 2, FALSE), ovf_params_i32, 2, FALSE));
4995 LLVMAddFunction (module, "llvm.usub.with.overflow.i32", LLVMFunctionType (LLVMStructType (ovf_res_i32, 2, FALSE), ovf_params_i32, 2, FALSE));
4996 LLVMAddFunction (module, "llvm.smul.with.overflow.i32", LLVMFunctionType (LLVMStructType (ovf_res_i32, 2, FALSE), ovf_params_i32, 2, FALSE));
4997 LLVMAddFunction (module, "llvm.umul.with.overflow.i32", LLVMFunctionType (LLVMStructType (ovf_res_i32, 2, FALSE), ovf_params_i32, 2, FALSE));
5001 LLVMTypeRef ovf_res_i64 [] = { LLVMInt64Type (), LLVMInt1Type () };
5002 LLVMTypeRef ovf_params_i64 [] = { LLVMInt64Type (), LLVMInt64Type () };
5004 LLVMAddFunction (module, "llvm.sadd.with.overflow.i64", LLVMFunctionType (LLVMStructType (ovf_res_i64, 2, FALSE), ovf_params_i64, 2, FALSE));
5005 LLVMAddFunction (module, "llvm.uadd.with.overflow.i64", LLVMFunctionType (LLVMStructType (ovf_res_i64, 2, FALSE), ovf_params_i64, 2, FALSE));
5006 LLVMAddFunction (module, "llvm.ssub.with.overflow.i64", LLVMFunctionType (LLVMStructType (ovf_res_i64, 2, FALSE), ovf_params_i64, 2, FALSE));
5007 LLVMAddFunction (module, "llvm.usub.with.overflow.i64", LLVMFunctionType (LLVMStructType (ovf_res_i64, 2, FALSE), ovf_params_i64, 2, FALSE));
5008 LLVMAddFunction (module, "llvm.smul.with.overflow.i64", LLVMFunctionType (LLVMStructType (ovf_res_i64, 2, FALSE), ovf_params_i64, 2, FALSE));
5009 LLVMAddFunction (module, "llvm.umul.with.overflow.i64", LLVMFunctionType (LLVMStructType (ovf_res_i64, 2, FALSE), ovf_params_i64, 2, FALSE));
5014 LLVMTypeRef arg_types [2];
5015 LLVMTypeRef ret_type;
5017 arg_types [0] = LLVMPointerType (LLVMInt8Type (), 0);
5018 arg_types [1] = LLVMPointerType (LLVMInt8Type (), 0);
5019 ret_type = LLVMInt32Type ();
5021 LLVMAddFunction (module, "mono_personality", LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE));
5023 LLVMAddFunction (module, "llvm_resume_unwind_trampoline", LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE));
5026 /* SSE intrinsics */
5027 #if defined(TARGET_X86) || defined(TARGET_AMD64)
5029 LLVMTypeRef ret_type, arg_types [16];
5032 ret_type = type_to_simd_type (MONO_TYPE_I4);
5033 arg_types [0] = ret_type;
5034 arg_types [1] = ret_type;
5035 AddFunc (module, "llvm.x86.sse41.pminud", ret_type, arg_types, 2);
5036 AddFunc (module, "llvm.x86.sse41.pmaxud", ret_type, arg_types, 2);
5038 ret_type = type_to_simd_type (MONO_TYPE_I2);
5039 arg_types [0] = ret_type;
5040 arg_types [1] = ret_type;
5041 AddFunc (module, "llvm.x86.sse41.pminuw", ret_type, arg_types, 2);
5042 AddFunc (module, "llvm.x86.sse2.pmins.w", ret_type, arg_types, 2);
5043 AddFunc (module, "llvm.x86.sse41.pmaxuw", ret_type, arg_types, 2);
5044 AddFunc (module, "llvm.x86.sse2.padds.w", ret_type, arg_types, 2);
5045 AddFunc (module, "llvm.x86.sse2.psubs.w", ret_type, arg_types, 2);
5046 AddFunc (module, "llvm.x86.sse2.paddus.w", ret_type, arg_types, 2);
5047 AddFunc (module, "llvm.x86.sse2.psubus.w", ret_type, arg_types, 2);
5048 AddFunc (module, "llvm.x86.sse2.pavg.w", ret_type, arg_types, 2);
5049 AddFunc (module, "llvm.x86.sse2.pmulh.w", ret_type, arg_types, 2);
5050 AddFunc (module, "llvm.x86.sse2.pmulhu.w", ret_type, arg_types, 2);
5052 ret_type = type_to_simd_type (MONO_TYPE_I1);
5053 arg_types [0] = ret_type;
5054 arg_types [1] = ret_type;
5055 AddFunc (module, "llvm.x86.sse2.pminu.b", ret_type, arg_types, 2);
5056 AddFunc (module, "llvm.x86.sse2.pmaxu.b", ret_type, arg_types, 2);
5057 AddFunc (module, "llvm.x86.sse2.padds.b", ret_type, arg_types, 2);
5058 AddFunc (module, "llvm.x86.sse2.psubs.b", ret_type, arg_types, 2);
5059 AddFunc (module, "llvm.x86.sse2.paddus.b", ret_type, arg_types, 2);
5060 AddFunc (module, "llvm.x86.sse2.psubus.b", ret_type, arg_types, 2);
5061 AddFunc (module, "llvm.x86.sse2.pavg.b", ret_type, arg_types, 2);
5063 ret_type = type_to_simd_type (MONO_TYPE_R8);
5064 arg_types [0] = ret_type;
5065 arg_types [1] = ret_type;
5066 AddFunc (module, "llvm.x86.sse2.min.pd", ret_type, arg_types, 2);
5067 AddFunc (module, "llvm.x86.sse2.max.pd", ret_type, arg_types, 2);
5068 AddFunc (module, "llvm.x86.sse3.hadd.pd", ret_type, arg_types, 2);
5069 AddFunc (module, "llvm.x86.sse3.hsub.pd", ret_type, arg_types, 2);
5070 AddFunc (module, "llvm.x86.sse3.addsub.pd", ret_type, arg_types, 2);
5072 ret_type = type_to_simd_type (MONO_TYPE_R4);
5073 arg_types [0] = ret_type;
5074 arg_types [1] = ret_type;
5075 AddFunc (module, "llvm.x86.sse.min.ps", ret_type, arg_types, 2);
5076 AddFunc (module, "llvm.x86.sse.max.ps", ret_type, arg_types, 2);
5077 AddFunc (module, "llvm.x86.sse3.hadd.ps", ret_type, arg_types, 2);
5078 AddFunc (module, "llvm.x86.sse3.hsub.ps", ret_type, arg_types, 2);
5079 AddFunc (module, "llvm.x86.sse3.addsub.ps", ret_type, arg_types, 2);
5082 ret_type = type_to_simd_type (MONO_TYPE_I1);
5083 arg_types [0] = type_to_simd_type (MONO_TYPE_I2);
5084 arg_types [1] = type_to_simd_type (MONO_TYPE_I2);
5085 AddFunc (module, "llvm.x86.sse2.packsswb.128", ret_type, arg_types, 2);
5086 AddFunc (module, "llvm.x86.sse2.packuswb.128", ret_type, arg_types, 2);
5087 ret_type = type_to_simd_type (MONO_TYPE_I2);
5088 arg_types [0] = type_to_simd_type (MONO_TYPE_I4);
5089 arg_types [1] = type_to_simd_type (MONO_TYPE_I4);
5090 AddFunc (module, "llvm.x86.sse2.packssdw.128", ret_type, arg_types, 2);
5091 AddFunc (module, "llvm.x86.sse41.packusdw", ret_type, arg_types, 2);
5094 ret_type = type_to_simd_type (MONO_TYPE_R8);
5095 arg_types [0] = ret_type;
5096 arg_types [1] = ret_type;
5097 arg_types [2] = LLVMInt8Type ();
5098 AddFunc (module, "llvm.x86.sse2.cmp.pd", ret_type, arg_types, 3);
5099 ret_type = type_to_simd_type (MONO_TYPE_R4);
5100 arg_types [0] = ret_type;
5101 arg_types [1] = ret_type;
5102 arg_types [2] = LLVMInt8Type ();
5103 AddFunc (module, "llvm.x86.sse.cmp.ps", ret_type, arg_types, 3);
5105 /* Conversion ops */
5106 ret_type = type_to_simd_type (MONO_TYPE_R8);
5107 arg_types [0] = type_to_simd_type (MONO_TYPE_I4);
5108 AddFunc (module, "llvm.x86.sse2.cvtdq2pd", ret_type, arg_types, 1);
5109 ret_type = type_to_simd_type (MONO_TYPE_R4);
5110 arg_types [0] = type_to_simd_type (MONO_TYPE_I4);
5111 AddFunc (module, "llvm.x86.sse2.cvtdq2ps", ret_type, arg_types, 1);
5112 ret_type = type_to_simd_type (MONO_TYPE_I4);
5113 arg_types [0] = type_to_simd_type (MONO_TYPE_R8);
5114 AddFunc (module, "llvm.x86.sse2.cvtpd2dq", ret_type, arg_types, 1);
5115 ret_type = type_to_simd_type (MONO_TYPE_I4);
5116 arg_types [0] = type_to_simd_type (MONO_TYPE_R4);
5117 AddFunc (module, "llvm.x86.sse2.cvtps2dq", ret_type, arg_types, 1);
5118 ret_type = type_to_simd_type (MONO_TYPE_R4);
5119 arg_types [0] = type_to_simd_type (MONO_TYPE_R8);
5120 AddFunc (module, "llvm.x86.sse2.cvtpd2ps", ret_type, arg_types, 1);
5121 ret_type = type_to_simd_type (MONO_TYPE_R8);
5122 arg_types [0] = type_to_simd_type (MONO_TYPE_R4);
5123 AddFunc (module, "llvm.x86.sse2.cvtps2pd", ret_type, arg_types, 1);
5125 ret_type = type_to_simd_type (MONO_TYPE_I4);
5126 arg_types [0] = type_to_simd_type (MONO_TYPE_R8);
5127 AddFunc (module, "llvm.x86.sse2.cvttpd2dq", ret_type, arg_types, 1);
5128 ret_type = type_to_simd_type (MONO_TYPE_I4);
5129 arg_types [0] = type_to_simd_type (MONO_TYPE_R4);
5130 AddFunc (module, "llvm.x86.sse2.cvttps2dq", ret_type, arg_types, 1);
5133 ret_type = type_to_simd_type (MONO_TYPE_R8);
5134 arg_types [0] = ret_type;
5135 AddFunc (module, "llvm.x86.sse2.sqrt.pd", ret_type, arg_types, 1);
5136 ret_type = type_to_simd_type (MONO_TYPE_R4);
5137 arg_types [0] = ret_type;
5138 AddFunc (module, "llvm.x86.sse.sqrt.ps", ret_type, arg_types, 1);
5139 ret_type = type_to_simd_type (MONO_TYPE_R4);
5140 arg_types [0] = ret_type;
5141 AddFunc (module, "llvm.x86.sse.rsqrt.ps", ret_type, arg_types, 1);
5142 ret_type = type_to_simd_type (MONO_TYPE_R4);
5143 arg_types [0] = ret_type;
5144 AddFunc (module, "llvm.x86.sse.rcp.ps", ret_type, arg_types, 1);
5147 ret_type = type_to_simd_type (MONO_TYPE_I2);
5148 arg_types [0] = ret_type;
5149 arg_types [1] = LLVMInt32Type ();
5150 AddFunc (module, "llvm.x86.sse2.psrli.w", ret_type, arg_types, 2);
5151 AddFunc (module, "llvm.x86.sse2.psrai.w", ret_type, arg_types, 2);
5152 AddFunc (module, "llvm.x86.sse2.pslli.w", ret_type, arg_types, 2);
5153 ret_type = type_to_simd_type (MONO_TYPE_I4);
5154 arg_types [0] = ret_type;
5155 arg_types [1] = LLVMInt32Type ();
5156 AddFunc (module, "llvm.x86.sse2.psrli.d", ret_type, arg_types, 2);
5157 AddFunc (module, "llvm.x86.sse2.psrai.d", ret_type, arg_types, 2);
5158 AddFunc (module, "llvm.x86.sse2.pslli.d", ret_type, arg_types, 2);
5159 ret_type = type_to_simd_type (MONO_TYPE_I8);
5160 arg_types [0] = ret_type;
5161 arg_types [1] = LLVMInt32Type ();
5162 AddFunc (module, "llvm.x86.sse2.psrli.q", ret_type, arg_types, 2);
5163 AddFunc (module, "llvm.x86.sse2.pslli.q", ret_type, arg_types, 2);
5166 ret_type = LLVMInt32Type ();
5167 arg_types [0] = type_to_simd_type (MONO_TYPE_I1);
5168 AddFunc (module, "llvm.x86.sse2.pmovmskb.128", ret_type, arg_types, 1);
5171 AddFunc (module, "llvm.x86.sse2.pause", LLVMVoidType (), NULL, 0);
5174 /* Load/Store intrinsics */
5176 LLVMTypeRef arg_types [5];
5180 for (i = 1; i <= 8; i *= 2) {
5181 arg_types [0] = LLVMPointerType (LLVMIntType (i * 8), 0);
5182 arg_types [1] = LLVMInt32Type ();
5183 arg_types [2] = LLVMInt1Type ();
5184 sprintf (name, "llvm.mono.load.i%d.p0i%d", i * 8, i * 8);
5185 LLVMAddFunction (module, name, LLVMFunctionType (LLVMIntType (i * 8), arg_types, 3, FALSE));
5187 arg_types [0] = LLVMIntType (i * 8);
5188 arg_types [1] = LLVMPointerType (LLVMIntType (i * 8), 0);
5189 arg_types [2] = LLVMInt32Type ();
5190 arg_types [3] = LLVMInt1Type ();
5191 sprintf (name, "llvm.mono.store.i%d.p0i%d", i * 8, i * 8);
5192 LLVMAddFunction (module, name, LLVMFunctionType (LLVMVoidType (), arg_types, 4, FALSE));
5198 add_types (MonoLLVMModule *lmodule)
5200 lmodule->ptr_type = LLVMPointerType (sizeof (gpointer) == 8 ? LLVMInt64Type () : LLVMInt32Type (), 0);
5204 mono_llvm_init (void)
5206 mono_native_tls_alloc (¤t_cfg_tls_id, NULL);
5210 init_jit_module (MonoDomain *domain)
5212 MonoJitICallInfo *info;
5213 MonoJitDomainInfo *dinfo;
5214 MonoLLVMModule *module;
5217 dinfo = domain_jit_info (domain);
5218 if (dinfo->llvm_module)
5221 mono_loader_lock ();
5223 if (dinfo->llvm_module) {
5224 mono_loader_unlock ();
5228 module = g_new0 (MonoLLVMModule, 1);
5230 name = g_strdup_printf ("mono-%s", domain->friendly_name);
5231 module->module = LLVMModuleCreateWithName (name);
5233 module->mono_ee = mono_llvm_create_ee (LLVMCreateModuleProviderForExistingModule (module->module), alloc_cb, emitted_cb, exception_cb, dlsym_cb, &module->ee);
5235 add_intrinsics (module->module);
5238 module->llvm_types = g_hash_table_new (NULL, NULL);
5240 info = mono_find_jit_icall_by_name ("llvm_resume_unwind_trampoline");
5242 LLVMAddGlobalMapping (module->ee, LLVMGetNamedFunction (module->module, "llvm_resume_unwind_trampoline"), (void*)info->func);
5244 mono_memory_barrier ();
5246 dinfo->llvm_module = module;
5248 mono_loader_unlock ();
5252 mono_llvm_cleanup (void)
5254 if (aot_module.module)
5255 LLVMDisposeModule (aot_module.module);
5257 LLVMContextDispose (LLVMGetGlobalContext ());
5261 mono_llvm_free_domain_info (MonoDomain *domain)
5263 MonoJitDomainInfo *info = domain_jit_info (domain);
5264 MonoLLVMModule *module = info->llvm_module;
5270 if (module->llvm_types)
5271 g_hash_table_destroy (module->llvm_types);
5273 mono_llvm_dispose_ee (module->mono_ee);
5275 if (module->bb_names) {
5276 for (i = 0; i < module->bb_names_len; ++i)
5277 g_free (module->bb_names [i]);
5278 g_free (module->bb_names);
5280 //LLVMDisposeModule (module->module);
5284 info->llvm_module = NULL;
5288 mono_llvm_create_aot_module (const char *got_symbol)
5290 /* Delete previous module */
5291 if (aot_module.plt_entries)
5292 g_hash_table_destroy (aot_module.plt_entries);
5293 if (aot_module.module)
5294 LLVMDisposeModule (aot_module.module);
5296 memset (&aot_module, 0, sizeof (aot_module));
5298 aot_module.module = LLVMModuleCreateWithName ("aot");
5299 aot_module.got_symbol = got_symbol;
5301 add_intrinsics (aot_module.module);
5302 add_types (&aot_module);
5306 * We couldn't compute the type of the LLVM global representing the got because
5307 * its size is only known after all the methods have been emitted. So create
5308 * a dummy variable, and replace all uses it with the real got variable when
5309 * its size is known in mono_llvm_emit_aot_module ().
5312 LLVMTypeRef got_type = LLVMArrayType (aot_module.ptr_type, 0);
5314 aot_module.got_var = LLVMAddGlobal (aot_module.module, got_type, "mono_dummy_got");
5315 LLVMSetInitializer (aot_module.got_var, LLVMConstNull (got_type));
5318 /* Add a dummy personality function */
5320 LLVMBasicBlockRef lbb;
5321 LLVMBuilderRef lbuilder;
5322 LLVMValueRef personality;
5324 personality = LLVMAddFunction (aot_module.module, "mono_aot_personality", LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE));
5325 LLVMSetLinkage (personality, LLVMInternalLinkage);
5326 lbb = LLVMAppendBasicBlock (personality, "BB0");
5327 lbuilder = LLVMCreateBuilder ();
5328 LLVMPositionBuilderAtEnd (lbuilder, lbb);
5329 LLVMBuildRetVoid (lbuilder);
5332 aot_module.llvm_types = g_hash_table_new (NULL, NULL);
5333 aot_module.plt_entries = g_hash_table_new (g_str_hash, g_str_equal);
5337 * Emit the aot module into the LLVM bitcode file FILENAME.
5340 mono_llvm_emit_aot_module (const char *filename, int got_size)
5342 LLVMTypeRef got_type;
5343 LLVMValueRef real_got;
5346 * Create the real got variable and replace all uses of the dummy variable with
5349 got_type = LLVMArrayType (aot_module.ptr_type, got_size);
5350 real_got = LLVMAddGlobal (aot_module.module, got_type, aot_module.got_symbol);
5351 LLVMSetInitializer (real_got, LLVMConstNull (got_type));
5352 LLVMSetLinkage (real_got, LLVMInternalLinkage);
5354 mono_llvm_replace_uses_of (aot_module.got_var, real_got);
5356 mark_as_used (&aot_module, real_got);
5358 /* Delete the dummy got so it doesn't become a global */
5359 LLVMDeleteGlobal (aot_module.got_var);
5361 emit_llvm_used (&aot_module);
5367 if (LLVMVerifyModule (aot_module.module, LLVMReturnStatusAction, &verifier_err)) {
5368 g_assert_not_reached ();
5373 LLVMWriteBitcodeToFile (aot_module.module, filename);
5378 - Emit LLVM IR from the mono IR using the LLVM C API.
5379 - The original arch specific code remains, so we can fall back to it if we run
5380 into something we can't handle.
5384 A partial list of issues:
5385 - Handling of opcodes which can throw exceptions.
5387 In the mono JIT, these are implemented using code like this:
5394 push throw_pos - method
5395 call <exception trampoline>
5397 The problematic part is push throw_pos - method, which cannot be represented
5398 in the LLVM IR, since it does not support label values.
5399 -> this can be implemented in AOT mode using inline asm + labels, but cannot
5400 be implemented in JIT mode ?
5401 -> a possible but slower implementation would use the normal exception
5402 throwing code but it would need to control the placement of the throw code
5403 (it needs to be exactly after the compare+branch).
5404 -> perhaps add a PC offset intrinsics ?
5406 - efficient implementation of .ovf opcodes.
5408 These are currently implemented as:
5409 <ins which sets the condition codes>
5412 Some overflow opcodes are now supported by LLVM SVN.
5414 - exception handling, unwinding.
5415 - SSA is disabled for methods with exception handlers
5416 - How to obtain unwind info for LLVM compiled methods ?
5417 -> this is now solved by converting the unwind info generated by LLVM
5419 - LLVM uses the c++ exception handling framework, while we use our home grown
5420 code, and couldn't use the c++ one:
5421 - its not supported under VC++, other exotic platforms.
5422 - it might be impossible to support filter clauses with it.
5426 The trampolines need a predictable call sequence, since they need to disasm
5427 the calling code to obtain register numbers / offsets.
5429 LLVM currently generates this code in non-JIT mode:
5430 mov -0x98(%rax),%eax
5432 Here, the vtable pointer is lost.
5433 -> solution: use one vtable trampoline per class.
5435 - passing/receiving the IMT pointer/RGCTX.
5436 -> solution: pass them as normal arguments ?
5440 LLVM does not allow the specification of argument registers etc. This means
5441 that all calls are made according to the platform ABI.
5443 - passing/receiving vtypes.
5445 Vtypes passed/received in registers are handled by the front end by using
5446 a signature with scalar arguments, and loading the parts of the vtype into those
5449 Vtypes passed on the stack are handled using the 'byval' attribute.
5453 Supported though alloca, we need to emit the load/store code.
5457 The mono JIT uses pointer sized iregs/double fregs, while LLVM uses precisely
5458 typed registers, so we have to keep track of the precise LLVM type of each vreg.
5459 This is made easier because the IR is already in SSA form.
5460 An additional problem is that our IR is not consistent with types, i.e. i32/ia64
5461 types are frequently used incorrectly.
5466 Emit LLVM bytecode into a .bc file, compile it using llc into a .s file, then
5467 append the AOT data structures to that file. For methods which cannot be
5468 handled by LLVM, the normal JIT compiled versions are used.
5471 /* FIXME: Normalize some aspects of the mono IR to allow easier translation, like:
5472 * - each bblock should end with a branch
5473 * - setting the return value, making cfg->ret non-volatile
5474 * - avoid some transformations in the JIT which make it harder for us to generate
5476 * - use pointer types to help optimizations.