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), addr, 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_NEW_I4:
3332 case OP_ATOMIC_ADD_NEW_I8: {
3333 LLVMValueRef args [2];
3336 if (ins->opcode == OP_ATOMIC_ADD_NEW_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];
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 values [ins->dreg] = mono_llvm_build_cmpxchg (builder, args [0], args [1], args [2]);
3366 case OP_MEMORY_BARRIER: {
3367 mono_llvm_build_fence (builder);
3370 case OP_RELAXED_NOP: {
3371 #if defined(TARGET_AMD64) || defined(TARGET_X86)
3372 emit_call (ctx, bb, &builder, LLVMGetNamedFunction (ctx->module, "llvm.x86.sse2.pause"), NULL, 0);
3379 #if (defined(TARGET_AMD64) || defined(TARGET_X86)) && defined(__linux__)
3381 // 257 == FS segment register
3382 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 257);
3384 // 256 == GS segment register
3385 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 256);
3388 values [ins->dreg] = LLVMBuildLoad (builder, LLVMBuildIntToPtr (builder, LLVMConstInt (IntPtrType (), ins->inst_offset, TRUE), ptrtype, ""), "");
3389 #elif defined(TARGET_AMD64) && defined(TARGET_OSX)
3390 /* See mono_amd64_emit_tls_get () */
3391 int offset = mono_amd64_get_tls_gs_offset () + (ins->inst_offset * 8);
3393 // 256 == GS segment register
3394 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 256);
3395 values [ins->dreg] = LLVMBuildLoad (builder, LLVMBuildIntToPtr (builder, LLVMConstInt (IntPtrType (), offset, TRUE), ptrtype, ""), "");
3397 LLVM_FAILURE (ctx, "opcode tls-get");
3402 case OP_TLS_GET_REG: {
3403 #if defined(TARGET_AMD64) && defined(TARGET_OSX)
3404 /* See emit_tls_get_reg () */
3405 // 256 == GS segment register
3406 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 256);
3407 values [ins->dreg] = LLVMBuildLoad (builder, LLVMBuildIntToPtr (builder, convert (ctx, lhs, LLVMInt32Type ()), ptrtype, ""), "");
3409 LLVM_FAILURE (ctx, "opcode tls-get");
3418 case OP_IADD_OVF_UN:
3420 case OP_ISUB_OVF_UN:
3422 case OP_IMUL_OVF_UN:
3423 #if SIZEOF_VOID_P == 8
3425 case OP_LADD_OVF_UN:
3427 case OP_LSUB_OVF_UN:
3429 case OP_LMUL_OVF_UN:
3432 LLVMValueRef args [2], val, ovf, func;
3434 args [0] = convert (ctx, lhs, op_to_llvm_type (ins->opcode));
3435 args [1] = convert (ctx, rhs, op_to_llvm_type (ins->opcode));
3436 func = LLVMGetNamedFunction (module, ovf_op_to_intrins (ins->opcode));
3438 val = LLVMBuildCall (builder, func, args, 2, "");
3439 values [ins->dreg] = LLVMBuildExtractValue (builder, val, 0, dname);
3440 ovf = LLVMBuildExtractValue (builder, val, 1, "");
3441 emit_cond_system_exception (ctx, bb, "OverflowException", ovf);
3442 CHECK_FAILURE (ctx);
3443 builder = ctx->builder;
3449 * We currently model them using arrays. Promotion to local vregs is
3450 * disabled for them in mono_handle_global_vregs () in the LLVM case,
3451 * so we always have an entry in cfg->varinfo for them.
3452 * FIXME: Is this needed ?
3455 MonoClass *klass = ins->klass;
3456 LLVMValueRef args [5];
3460 LLVM_FAILURE (ctx, "!klass");
3464 if (!addresses [ins->dreg])
3465 addresses [ins->dreg] = build_alloca (ctx, &klass->byval_arg);
3466 args [0] = LLVMBuildBitCast (builder, addresses [ins->dreg], LLVMPointerType (LLVMInt8Type (), 0), "");
3467 args [1] = LLVMConstInt (LLVMInt8Type (), 0, FALSE);
3468 args [2] = LLVMConstInt (LLVMInt32Type (), mono_class_value_size (klass, NULL), FALSE);
3470 args [3] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
3471 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
3472 LLVMBuildCall (builder, LLVMGetNamedFunction (module, memset_func_name), args, memset_param_count, "");
3475 case OP_DUMMY_VZERO:
3478 case OP_STOREV_MEMBASE:
3479 case OP_LOADV_MEMBASE:
3481 MonoClass *klass = ins->klass;
3482 LLVMValueRef src = NULL, dst, args [5];
3483 gboolean done = FALSE;
3487 LLVM_FAILURE (ctx, "!klass");
3491 if (mini_is_gsharedvt_klass (cfg, klass)) {
3493 LLVM_FAILURE (ctx, "gsharedvt");
3497 switch (ins->opcode) {
3498 case OP_STOREV_MEMBASE:
3499 if (cfg->gen_write_barriers && klass->has_references && ins->inst_destbasereg != cfg->frame_reg &&
3500 LLVMGetInstructionOpcode (values [ins->inst_destbasereg]) != LLVMAlloca) {
3501 /* Decomposed earlier */
3502 g_assert_not_reached ();
3505 if (!addresses [ins->sreg1]) {
3507 g_assert (values [ins->sreg1]);
3508 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));
3509 LLVMBuildStore (builder, values [ins->sreg1], dst);
3512 src = LLVMBuildBitCast (builder, addresses [ins->sreg1], LLVMPointerType (LLVMInt8Type (), 0), "");
3513 dst = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_destbasereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (LLVMInt8Type (), 0));
3516 case OP_LOADV_MEMBASE:
3517 if (!addresses [ins->dreg])
3518 addresses [ins->dreg] = build_alloca (ctx, &klass->byval_arg);
3519 src = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_basereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (LLVMInt8Type (), 0));
3520 dst = LLVMBuildBitCast (builder, addresses [ins->dreg], LLVMPointerType (LLVMInt8Type (), 0), "");
3523 if (!addresses [ins->sreg1])
3524 addresses [ins->sreg1] = build_alloca (ctx, &klass->byval_arg);
3525 if (!addresses [ins->dreg])
3526 addresses [ins->dreg] = build_alloca (ctx, &klass->byval_arg);
3527 src = LLVMBuildBitCast (builder, addresses [ins->sreg1], LLVMPointerType (LLVMInt8Type (), 0), "");
3528 dst = LLVMBuildBitCast (builder, addresses [ins->dreg], LLVMPointerType (LLVMInt8Type (), 0), "");
3531 g_assert_not_reached ();
3533 CHECK_FAILURE (ctx);
3540 args [2] = LLVMConstInt (LLVMInt32Type (), mono_class_value_size (klass, NULL), FALSE);
3541 args [3] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
3543 args [3] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
3544 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
3545 LLVMBuildCall (builder, LLVMGetNamedFunction (module, memcpy_func_name), args, memcpy_param_count, "");
3548 case OP_LLVM_OUTARG_VT:
3549 if (!addresses [ins->sreg1]) {
3550 addresses [ins->sreg1] = build_alloca (ctx, &ins->klass->byval_arg);
3551 g_assert (values [ins->sreg1]);
3552 LLVMBuildStore (builder, values [ins->sreg1], addresses [ins->sreg1]);
3554 addresses [ins->dreg] = addresses [ins->sreg1];
3560 #if defined(TARGET_X86) || defined(TARGET_AMD64)
3562 values [ins->dreg] = LLVMConstNull (type_to_llvm_type (ctx, &ins->klass->byval_arg));
3565 case OP_LOADX_MEMBASE: {
3566 LLVMTypeRef t = type_to_llvm_type (ctx, &ins->klass->byval_arg);
3569 src = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_basereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (t, 0));
3570 values [ins->dreg] = mono_llvm_build_aligned_load (builder, src, "", FALSE, 1);
3573 case OP_STOREX_MEMBASE: {
3574 LLVMTypeRef t = LLVMTypeOf (values [ins->sreg1]);
3577 dest = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_destbasereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (t, 0));
3578 mono_llvm_build_aligned_store (builder, values [ins->sreg1], dest, FALSE, 1);
3585 values [ins->dreg] = LLVMBuildAdd (builder, lhs, rhs, "");
3589 values [ins->dreg] = LLVMBuildFAdd (builder, lhs, rhs, "");
3595 values [ins->dreg] = LLVMBuildSub (builder, lhs, rhs, "");
3599 values [ins->dreg] = LLVMBuildFSub (builder, lhs, rhs, "");
3603 values [ins->dreg] = LLVMBuildFMul (builder, lhs, rhs, "");
3607 values [ins->dreg] = LLVMBuildFDiv (builder, lhs, rhs, "");
3610 values [ins->dreg] = LLVMBuildAnd (builder, lhs, rhs, "");
3613 values [ins->dreg] = LLVMBuildOr (builder, lhs, rhs, "");
3616 values [ins->dreg] = LLVMBuildXor (builder, lhs, rhs, "");
3620 values [ins->dreg] = LLVMBuildMul (builder, lhs, rhs, "");
3631 LLVMValueRef v = NULL;
3633 switch (ins->opcode) {
3638 t = LLVMVectorType (LLVMInt32Type (), 4);
3639 rt = LLVMVectorType (LLVMFloatType (), 4);
3645 t = LLVMVectorType (LLVMInt64Type (), 2);
3646 rt = LLVMVectorType (LLVMDoubleType (), 2);
3649 t = LLVMInt32Type ();
3650 rt = LLVMInt32Type ();
3651 g_assert_not_reached ();
3654 lhs = LLVMBuildBitCast (builder, lhs, t, "");
3655 rhs = LLVMBuildBitCast (builder, rhs, t, "");
3656 switch (ins->opcode) {
3659 v = LLVMBuildAnd (builder, lhs, rhs, "");
3663 v = LLVMBuildOr (builder, lhs, rhs, "");
3667 v = LLVMBuildXor (builder, lhs, rhs, "");
3671 v = LLVMBuildAnd (builder, rhs, LLVMBuildNot (builder, lhs, ""), "");
3674 values [ins->dreg] = LLVMBuildBitCast (builder, v, rt, "");
3698 case OP_PADDB_SAT_UN:
3699 case OP_PADDW_SAT_UN:
3700 case OP_PSUBB_SAT_UN:
3701 case OP_PSUBW_SAT_UN:
3709 case OP_PMULW_HIGH_UN: {
3710 LLVMValueRef args [2];
3715 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, simd_op_to_intrins (ins->opcode)), args, 2, dname);
3722 values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildICmp (builder, LLVMIntEQ, lhs, rhs, ""), LLVMTypeOf (lhs), "");
3726 values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildICmp (builder, LLVMIntSGT, lhs, rhs, ""), LLVMTypeOf (lhs), "");
3734 case OP_EXTRACTX_U2:
3736 case OP_EXTRACT_U1: {
3738 gboolean zext = FALSE;
3740 t = simd_op_to_llvm_type (ins->opcode);
3742 switch (ins->opcode) {
3750 case OP_EXTRACTX_U2:
3755 t = LLVMInt32Type ();
3756 g_assert_not_reached ();
3759 lhs = LLVMBuildBitCast (builder, lhs, t, "");
3760 values [ins->dreg] = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), "");
3762 values [ins->dreg] = LLVMBuildZExt (builder, values [ins->dreg], LLVMInt32Type (), "");
3771 case OP_EXPAND_R8: {
3772 LLVMTypeRef t = simd_op_to_llvm_type (ins->opcode);
3773 LLVMValueRef mask [16], v;
3775 for (i = 0; i < 16; ++i)
3776 mask [i] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
3778 v = convert (ctx, values [ins->sreg1], LLVMGetElementType (t));
3780 values [ins->dreg] = LLVMBuildInsertElement (builder, LLVMConstNull (t), v, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
3781 values [ins->dreg] = LLVMBuildShuffleVector (builder, values [ins->dreg], LLVMGetUndef (t), LLVMConstVector (mask, LLVMGetVectorSize (t)), "");
3786 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt8Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
3789 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt16Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
3792 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt32Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
3795 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt64Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
3798 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMFloatType ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
3801 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMDoubleType ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
3812 case OP_EXTRACT_MASK:
3819 v = convert (ctx, values [ins->sreg1], simd_op_to_llvm_type (ins->opcode));
3821 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, simd_op_to_intrins (ins->opcode)), &v, 1, dname);
3825 case OP_ICONV_TO_R8_RAW:
3826 /* Same as OP_ICONV_TO_R8 */
3827 values [ins->dreg] = convert (ctx, LLVMBuildBitCast (builder, lhs, LLVMFloatType (), ""), LLVMDoubleType ());
3832 LLVMValueRef args [3];
3836 args [2] = LLVMConstInt (LLVMInt8Type (), ins->inst_c0, FALSE);
3838 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, simd_op_to_intrins (ins->opcode)), args, 3, dname);
3843 /* This is only used for implementing shifts by non-immediate */
3844 values [ins->dreg] = lhs;
3855 LLVMValueRef args [3];
3858 args [1] = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
3860 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, simd_op_to_intrins (ins->opcode)), args, 2, dname);
3871 case OP_PSHLQ_REG: {
3872 LLVMValueRef args [3];
3875 args [1] = values [ins->sreg2];
3877 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, simd_op_to_intrins (ins->opcode)), args, 2, dname);
3884 case OP_PSHUFLEW_LOW:
3885 case OP_PSHUFLEW_HIGH: {
3887 LLVMValueRef v1 = NULL, v2 = NULL, mask_values [16];
3888 int i, mask_size = 0;
3889 int imask = ins->inst_c0;
3891 /* Convert the x86 shuffle mask to LLVM's */
3892 switch (ins->opcode) {
3895 mask [0] = ((imask >> 0) & 3);
3896 mask [1] = ((imask >> 2) & 3);
3897 mask [2] = ((imask >> 4) & 3) + 4;
3898 mask [3] = ((imask >> 6) & 3) + 4;
3899 v1 = values [ins->sreg1];
3900 v2 = values [ins->sreg2];
3904 mask [0] = ((imask >> 0) & 1);
3905 mask [1] = ((imask >> 1) & 1) + 2;
3906 v1 = values [ins->sreg1];
3907 v2 = values [ins->sreg2];
3909 case OP_PSHUFLEW_LOW:
3911 mask [0] = ((imask >> 0) & 3);
3912 mask [1] = ((imask >> 2) & 3);
3913 mask [2] = ((imask >> 4) & 3);
3914 mask [3] = ((imask >> 6) & 3);
3919 v1 = values [ins->sreg1];
3920 v2 = LLVMGetUndef (LLVMTypeOf (v1));
3922 case OP_PSHUFLEW_HIGH:
3928 mask [4] = 4 + ((imask >> 0) & 3);
3929 mask [5] = 4 + ((imask >> 2) & 3);
3930 mask [6] = 4 + ((imask >> 4) & 3);
3931 mask [7] = 4 + ((imask >> 6) & 3);
3932 v1 = values [ins->sreg1];
3933 v2 = LLVMGetUndef (LLVMTypeOf (v1));
3937 mask [0] = ((imask >> 0) & 3);
3938 mask [1] = ((imask >> 2) & 3);
3939 mask [2] = ((imask >> 4) & 3);
3940 mask [3] = ((imask >> 6) & 3);
3941 v1 = values [ins->sreg1];
3942 v2 = LLVMGetUndef (LLVMTypeOf (v1));
3945 g_assert_not_reached ();
3947 for (i = 0; i < mask_size; ++i)
3948 mask_values [i] = LLVMConstInt (LLVMInt32Type (), mask [i], FALSE);
3950 values [ins->dreg] =
3951 LLVMBuildShuffleVector (builder, v1, v2,
3952 LLVMConstVector (mask_values, mask_size), dname);
3956 case OP_UNPACK_LOWB:
3957 case OP_UNPACK_LOWW:
3958 case OP_UNPACK_LOWD:
3959 case OP_UNPACK_LOWQ:
3960 case OP_UNPACK_LOWPS:
3961 case OP_UNPACK_LOWPD:
3962 case OP_UNPACK_HIGHB:
3963 case OP_UNPACK_HIGHW:
3964 case OP_UNPACK_HIGHD:
3965 case OP_UNPACK_HIGHQ:
3966 case OP_UNPACK_HIGHPS:
3967 case OP_UNPACK_HIGHPD: {
3969 LLVMValueRef mask_values [16];
3970 int i, mask_size = 0;
3971 gboolean low = FALSE;
3973 switch (ins->opcode) {
3974 case OP_UNPACK_LOWB:
3978 case OP_UNPACK_LOWW:
3982 case OP_UNPACK_LOWD:
3983 case OP_UNPACK_LOWPS:
3987 case OP_UNPACK_LOWQ:
3988 case OP_UNPACK_LOWPD:
3992 case OP_UNPACK_HIGHB:
3995 case OP_UNPACK_HIGHW:
3998 case OP_UNPACK_HIGHD:
3999 case OP_UNPACK_HIGHPS:
4002 case OP_UNPACK_HIGHQ:
4003 case OP_UNPACK_HIGHPD:
4007 g_assert_not_reached ();
4011 for (i = 0; i < (mask_size / 2); ++i) {
4013 mask [(i * 2) + 1] = mask_size + i;
4016 for (i = 0; i < (mask_size / 2); ++i) {
4017 mask [(i * 2)] = (mask_size / 2) + i;
4018 mask [(i * 2) + 1] = mask_size + (mask_size / 2) + i;
4022 for (i = 0; i < mask_size; ++i)
4023 mask_values [i] = LLVMConstInt (LLVMInt32Type (), mask [i], FALSE);
4025 values [ins->dreg] =
4026 LLVMBuildShuffleVector (builder, values [ins->sreg1], values [ins->sreg2],
4027 LLVMConstVector (mask_values, mask_size), dname);
4032 LLVMTypeRef t = simd_op_to_llvm_type (ins->opcode);
4033 LLVMValueRef v, val;
4035 v = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
4036 val = LLVMConstNull (t);
4037 val = LLVMBuildInsertElement (builder, val, v, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
4038 val = LLVMBuildInsertElement (builder, val, v, LLVMConstInt (LLVMInt32Type (), 1, FALSE), dname);
4040 values [ins->dreg] = val;
4044 case OP_DUPPS_HIGH: {
4045 LLVMTypeRef t = simd_op_to_llvm_type (ins->opcode);
4046 LLVMValueRef v1, v2, val;
4049 if (ins->opcode == OP_DUPPS_LOW) {
4050 v1 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
4051 v2 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 2, FALSE), "");
4053 v1 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 1, FALSE), "");
4054 v2 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 3, FALSE), "");
4056 val = LLVMConstNull (t);
4057 val = LLVMBuildInsertElement (builder, val, v1, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
4058 val = LLVMBuildInsertElement (builder, val, v1, LLVMConstInt (LLVMInt32Type (), 1, FALSE), "");
4059 val = LLVMBuildInsertElement (builder, val, v2, LLVMConstInt (LLVMInt32Type (), 2, FALSE), "");
4060 val = LLVMBuildInsertElement (builder, val, v2, LLVMConstInt (LLVMInt32Type (), 3, FALSE), "");
4062 values [ins->dreg] = val;
4072 * EXCEPTION HANDLING
4074 case OP_IMPLICIT_EXCEPTION:
4075 /* This marks a place where an implicit exception can happen */
4076 if (bb->region != -1)
4077 LLVM_FAILURE (ctx, "implicit-exception");
4081 MonoMethodSignature *throw_sig;
4082 LLVMValueRef callee, arg;
4083 gboolean rethrow = (ins->opcode == OP_RETHROW);
4084 const char *icall_name;
4086 callee = rethrow ? ctx->lmodule->rethrow : ctx->lmodule->throw;
4087 icall_name = rethrow ? "mono_arch_rethrow_exception" : "mono_arch_throw_exception";
4090 throw_sig = mono_metadata_signature_alloc (mono_get_corlib (), 1);
4091 throw_sig->ret = &mono_get_void_class ()->byval_arg;
4092 throw_sig->params [0] = &mono_get_object_class ()->byval_arg;
4093 if (cfg->compile_aot) {
4094 callee = get_plt_entry (ctx, sig_to_llvm_sig (ctx, throw_sig), MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
4096 callee = LLVMAddFunction (module, icall_name, sig_to_llvm_sig (ctx, throw_sig));
4100 * LLVM doesn't push the exception argument, so we need a different
4103 LLVMAddGlobalMapping (ctx->lmodule->ee, callee, resolve_patch (cfg, MONO_PATCH_INFO_INTERNAL_METHOD, rethrow ? "llvm_rethrow_exception_trampoline" : "llvm_throw_exception_trampoline"));
4105 LLVMAddGlobalMapping (ctx->lmodule->ee, callee, resolve_patch (cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name));
4109 mono_memory_barrier ();
4111 ctx->lmodule->rethrow = callee;
4113 ctx->lmodule->throw = callee;
4115 arg = convert (ctx, lhs, type_to_llvm_type (ctx, &mono_get_object_class ()->byval_arg));
4116 emit_call (ctx, bb, &builder, callee, &arg, 1);
4119 case OP_CALL_HANDLER: {
4121 * We don't 'call' handlers, but instead simply branch to them.
4122 * The code generated by ENDFINALLY will branch back to us.
4124 LLVMBasicBlockRef noex_bb;
4126 BBInfo *info = &bblocks [ins->inst_target_bb->block_num];
4128 bb_list = info->call_handler_return_bbs;
4131 * Set the indicator variable for the finally clause.
4133 lhs = info->finally_ind;
4135 LLVMBuildStore (builder, LLVMConstInt (LLVMInt32Type (), g_slist_length (bb_list) + 1, FALSE), lhs);
4137 /* Branch to the finally clause */
4138 LLVMBuildBr (builder, info->call_handler_target_bb);
4140 noex_bb = gen_bb (ctx, "CALL_HANDLER_CONT_BB");
4141 info->call_handler_return_bbs = g_slist_append_mempool (cfg->mempool, info->call_handler_return_bbs, noex_bb);
4143 builder = ctx->builder = create_builder (ctx);
4144 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
4146 bblocks [bb->block_num].end_bblock = noex_bb;
4149 case OP_START_HANDLER: {
4152 case OP_ENDFINALLY: {
4153 LLVMBasicBlockRef resume_bb;
4154 MonoBasicBlock *handler_bb;
4155 LLVMValueRef val, switch_ins, callee;
4159 handler_bb = g_hash_table_lookup (ctx->region_to_handler, GUINT_TO_POINTER (mono_get_block_region_notry (cfg, bb->region)));
4160 g_assert (handler_bb);
4161 info = &bblocks [handler_bb->block_num];
4162 lhs = info->finally_ind;
4165 bb_list = info->call_handler_return_bbs;
4167 resume_bb = gen_bb (ctx, "ENDFINALLY_RESUME_BB");
4169 /* Load the finally variable */
4170 val = LLVMBuildLoad (builder, lhs, "");
4172 /* Reset the variable */
4173 LLVMBuildStore (builder, LLVMConstInt (LLVMInt32Type (), 0, FALSE), lhs);
4175 /* Branch to either resume_bb, or to the bblocks in bb_list */
4176 switch_ins = LLVMBuildSwitch (builder, val, resume_bb, g_slist_length (bb_list));
4178 * The other targets are added at the end to handle OP_CALL_HANDLER
4179 * opcodes processed later.
4181 info->endfinally_switch_ins_list = g_slist_append_mempool (cfg->mempool, info->endfinally_switch_ins_list, switch_ins);
4183 builder = ctx->builder = create_builder (ctx);
4184 LLVMPositionBuilderAtEnd (ctx->builder, resume_bb);
4186 if (ctx->cfg->compile_aot) {
4187 callee = get_plt_entry (ctx, LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE), MONO_PATCH_INFO_INTERNAL_METHOD, "llvm_resume_unwind_trampoline");
4189 callee = LLVMGetNamedFunction (module, "llvm_resume_unwind_trampoline");
4191 LLVMBuildCall (builder, callee, NULL, 0, "");
4193 LLVMBuildUnreachable (builder);
4194 has_terminator = TRUE;
4200 sprintf (reason, "opcode %s", mono_inst_name (ins->opcode));
4201 LLVM_FAILURE (ctx, reason);
4206 /* Convert the value to the type required by phi nodes */
4207 if (spec [MONO_INST_DEST] != ' ' && !MONO_IS_STORE_MEMBASE (ins) && ctx->vreg_types [ins->dreg]) {
4208 if (!values [ins->dreg])
4210 values [ins->dreg] = addresses [ins->dreg];
4212 values [ins->dreg] = convert (ctx, values [ins->dreg], ctx->vreg_types [ins->dreg]);
4215 /* Add stores for volatile variables */
4216 if (spec [MONO_INST_DEST] != ' ' && spec [MONO_INST_DEST] != 'v' && !MONO_IS_STORE_MEMBASE (ins))
4217 emit_volatile_store (ctx, ins->dreg);
4220 if (!has_terminator && bb->next_bb && (bb == cfg->bb_entry || bb->in_count > 0))
4221 LLVMBuildBr (builder, get_bb (ctx, bb->next_bb));
4223 if (bb == cfg->bb_exit && sig->ret->type == MONO_TYPE_VOID)
4224 LLVMBuildRetVoid (builder);
4226 if (bb == cfg->bb_entry)
4227 ctx->last_alloca = LLVMGetLastInstruction (get_bb (ctx, cfg->bb_entry));
4236 * mono_llvm_check_method_supported:
4238 * Do some quick checks to decide whenever cfg->method can be compiled by LLVM, to avoid
4239 * compiling a method twice.
4242 mono_llvm_check_method_supported (MonoCompile *cfg)
4244 MonoMethodHeader *header = cfg->header;
4245 MonoExceptionClause *clause;
4248 if (cfg->method->save_lmf) {
4249 cfg->exception_message = g_strdup ("lmf");
4250 cfg->disable_llvm = TRUE;
4252 if (cfg->disable_llvm)
4256 for (i = 0; i < header->num_clauses; ++i) {
4257 clause = &header->clauses [i];
4259 if (i > 0 && clause->try_offset <= header->clauses [i - 1].handler_offset + header->clauses [i - 1].handler_len) {
4261 * FIXME: Some tests still fail with nested clauses.
4263 cfg->exception_message = g_strdup ("nested clauses");
4264 cfg->disable_llvm = TRUE;
4268 if (cfg->disable_llvm)
4273 if (cfg->method->dynamic) {
4274 cfg->exception_message = g_strdup ("dynamic.");
4275 cfg->disable_llvm = TRUE;
4277 if (cfg->disable_llvm)
4282 * mono_llvm_emit_method:
4284 * Emit LLVM IL from the mono IL, and compile it to native code using LLVM.
4287 mono_llvm_emit_method (MonoCompile *cfg)
4290 MonoMethodSignature *sig;
4292 LLVMTypeRef method_type;
4293 LLVMValueRef method = NULL;
4295 LLVMValueRef *values;
4296 int i, max_block_num, bb_index;
4297 gboolean last = FALSE;
4298 GPtrArray *phi_values;
4299 LLVMCallInfo *linfo;
4301 LLVMModuleRef module;
4303 GPtrArray *bblock_list;
4304 MonoMethodHeader *header;
4305 MonoExceptionClause *clause;
4309 /* The code below might acquire the loader lock, so use it for global locking */
4310 mono_loader_lock ();
4312 /* Used to communicate with the callbacks */
4313 mono_native_tls_set_value (current_cfg_tls_id, cfg);
4315 ctx = g_new0 (EmitContext, 1);
4317 ctx->mempool = cfg->mempool;
4320 * This maps vregs to the LLVM instruction defining them
4322 values = g_new0 (LLVMValueRef, cfg->next_vreg);
4324 * This maps vregs for volatile variables to the LLVM instruction defining their
4327 ctx->addresses = g_new0 (LLVMValueRef, cfg->next_vreg);
4328 ctx->vreg_types = g_new0 (LLVMTypeRef, cfg->next_vreg);
4329 ctx->vreg_cli_types = g_new0 (MonoType*, cfg->next_vreg);
4330 phi_values = g_ptr_array_sized_new (256);
4332 * This signals whenever the vreg was defined by a phi node with no input vars
4333 * (i.e. all its input bblocks end with NOT_REACHABLE).
4335 ctx->is_dead = g_new0 (gboolean, cfg->next_vreg);
4336 /* Whenever the bblock is unreachable */
4337 ctx->unreachable = g_new0 (gboolean, cfg->max_block_num);
4339 bblock_list = g_ptr_array_sized_new (256);
4341 ctx->values = values;
4342 ctx->region_to_handler = g_hash_table_new (NULL, NULL);
4344 if (cfg->compile_aot) {
4345 ctx->lmodule = &aot_module;
4346 method_name = mono_aot_get_method_name (cfg);
4347 cfg->llvm_method_name = g_strdup (method_name);
4349 init_jit_module (cfg->domain);
4350 ctx->lmodule = domain_jit_info (cfg->domain)->llvm_module;
4351 method_name = mono_method_full_name (cfg->method, TRUE);
4354 module = ctx->module = ctx->lmodule->module;
4357 LLVM_FAILURE (ctx, "gsharedvt");
4361 static int count = 0;
4364 if (g_getenv ("LLVM_COUNT")) {
4365 if (count == atoi (g_getenv ("LLVM_COUNT"))) {
4366 printf ("LAST: %s\n", mono_method_full_name (cfg->method, TRUE));
4370 if (count > atoi (g_getenv ("LLVM_COUNT")))
4371 LLVM_FAILURE (ctx, "");
4376 sig = mono_method_signature (cfg->method);
4379 linfo = mono_arch_get_llvm_call_info (cfg, sig);
4381 CHECK_FAILURE (ctx);
4384 linfo->rgctx_arg = TRUE;
4385 method_type = sig_to_llvm_sig_full (ctx, sig, linfo, &sinfo);
4386 CHECK_FAILURE (ctx);
4389 * This maps parameter indexes in the original signature to the indexes in
4390 * the LLVM signature.
4392 ctx->pindexes = sinfo.pindexes;
4394 method = LLVMAddFunction (module, method_name, method_type);
4395 ctx->lmethod = method;
4397 LLVMSetFunctionCallConv (method, LLVMMono1CallConv);
4398 LLVMSetLinkage (method, LLVMPrivateLinkage);
4400 LLVMAddFunctionAttr (method, LLVMUWTable);
4402 if (cfg->compile_aot) {
4403 LLVMSetLinkage (method, LLVMInternalLinkage);
4404 #if LLVM_API_VERSION == 0
4405 /* This causes an assertion in later LLVM versions */
4406 LLVMSetVisibility (method, LLVMHiddenVisibility);
4409 LLVMSetLinkage (method, LLVMPrivateLinkage);
4412 if (cfg->method->save_lmf)
4413 LLVM_FAILURE (ctx, "lmf");
4415 if (sig->pinvoke && cfg->method->wrapper_type != MONO_WRAPPER_RUNTIME_INVOKE)
4416 LLVM_FAILURE (ctx, "pinvoke signature");
4418 header = cfg->header;
4419 for (i = 0; i < header->num_clauses; ++i) {
4420 clause = &header->clauses [i];
4421 if (clause->flags != MONO_EXCEPTION_CLAUSE_FINALLY && clause->flags != MONO_EXCEPTION_CLAUSE_NONE)
4422 LLVM_FAILURE (ctx, "non-finally/catch clause.");
4425 if (linfo->rgctx_arg) {
4426 ctx->rgctx_arg = LLVMGetParam (method, sinfo.rgctx_arg_pindex);
4428 * We mark the rgctx parameter with the inreg attribute, which is mapped to
4429 * MONO_ARCH_RGCTX_REG in the Mono calling convention in llvm, i.e.
4430 * CC_X86_64_Mono in X86CallingConv.td.
4432 LLVMAddAttribute (ctx->rgctx_arg, LLVMInRegAttribute);
4433 LLVMSetValueName (ctx->rgctx_arg, "rgctx");
4435 if (cfg->vret_addr) {
4436 values [cfg->vret_addr->dreg] = LLVMGetParam (method, sinfo.vret_arg_pindex);
4437 LLVMSetValueName (values [cfg->vret_addr->dreg], "vret");
4440 values [cfg->args [0]->dreg] = LLVMGetParam (method, sinfo.this_arg_pindex);
4441 LLVMSetValueName (values [cfg->args [0]->dreg], "this");
4444 names = g_new (char *, sig->param_count);
4445 mono_method_get_param_names (cfg->method, (const char **) names);
4447 for (i = 0; i < sig->param_count; ++i) {
4450 values [cfg->args [i + sig->hasthis]->dreg] = LLVMGetParam (method, sinfo.pindexes [i]);
4451 if (names [i] && names [i][0] != '\0')
4452 name = g_strdup_printf ("arg_%s", names [i]);
4454 name = g_strdup_printf ("arg_%d", i);
4455 LLVMSetValueName (values [cfg->args [i + sig->hasthis]->dreg], name);
4457 if (linfo->args [i + sig->hasthis].storage == LLVMArgVtypeByVal)
4458 LLVMAddAttribute (LLVMGetParam (method, sinfo.pindexes [i]), LLVMByValAttribute);
4463 for (bb = cfg->bb_entry; bb; bb = bb->next_bb)
4464 max_block_num = MAX (max_block_num, bb->block_num);
4465 ctx->bblocks = bblocks = g_new0 (BBInfo, max_block_num + 1);
4467 /* Add branches between non-consecutive bblocks */
4468 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
4469 if (bb->last_ins && MONO_IS_COND_BRANCH_OP (bb->last_ins) &&
4470 bb->next_bb != bb->last_ins->inst_false_bb) {
4472 MonoInst *inst = mono_mempool_alloc0 (cfg->mempool, sizeof (MonoInst));
4473 inst->opcode = OP_BR;
4474 inst->inst_target_bb = bb->last_ins->inst_false_bb;
4475 mono_bblock_add_inst (bb, inst);
4480 * The INDIRECT flag added by OP_LDADDR inhibits optimizations, even if the LDADDR
4481 * was later optimized away, so clear these flags, and add them back for the still
4482 * present OP_LDADDR instructions.
4484 for (i = 0; i < cfg->next_vreg; ++i) {
4487 ins = get_vreg_to_inst (cfg, i);
4488 if (ins && ins != cfg->rgctx_var)
4489 ins->flags &= ~MONO_INST_INDIRECT;
4493 * Make a first pass over the code to precreate PHI nodes/set INDIRECT flags.
4495 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
4497 LLVMBuilderRef builder;
4499 char dname_buf[128];
4501 builder = create_builder (ctx);
4503 for (ins = bb->code; ins; ins = ins->next) {
4504 switch (ins->opcode) {
4509 LLVMTypeRef phi_type = llvm_type_to_stack_type (type_to_llvm_type (ctx, &ins->klass->byval_arg));
4511 CHECK_FAILURE (ctx);
4513 if (ins->opcode == OP_VPHI) {
4514 /* Treat valuetype PHI nodes as operating on the address itself */
4515 g_assert (ins->klass);
4516 phi_type = LLVMPointerType (type_to_llvm_type (ctx, &ins->klass->byval_arg), 0);
4520 * Have to precreate these, as they can be referenced by
4521 * earlier instructions.
4523 sprintf (dname_buf, "t%d", ins->dreg);
4525 values [ins->dreg] = LLVMBuildPhi (builder, phi_type, dname);
4527 if (ins->opcode == OP_VPHI)
4528 ctx->addresses [ins->dreg] = values [ins->dreg];
4530 g_ptr_array_add (phi_values, values [ins->dreg]);
4533 * Set the expected type of the incoming arguments since these have
4534 * to have the same type.
4536 for (i = 0; i < ins->inst_phi_args [0]; i++) {
4537 int sreg1 = ins->inst_phi_args [i + 1];
4540 ctx->vreg_types [sreg1] = phi_type;
4545 ((MonoInst*)ins->inst_p0)->flags |= MONO_INST_INDIRECT;
4554 * Create an ordering for bblocks, use the depth first order first, then
4555 * put the exception handling bblocks last.
4557 for (bb_index = 0; bb_index < cfg->num_bblocks; ++bb_index) {
4558 bb = cfg->bblocks [bb_index];
4559 if (!(bb->region != -1 && !MONO_BBLOCK_IS_IN_REGION (bb, MONO_REGION_TRY))) {
4560 g_ptr_array_add (bblock_list, bb);
4561 bblocks [bb->block_num].added = TRUE;
4565 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
4566 if (!bblocks [bb->block_num].added)
4567 g_ptr_array_add (bblock_list, bb);
4571 * Second pass: generate code.
4573 for (bb_index = 0; bb_index < bblock_list->len; ++bb_index) {
4574 bb = g_ptr_array_index (bblock_list, bb_index);
4576 if (!(bb == cfg->bb_entry || bb->in_count > 0))
4579 process_bb (ctx, bb);
4580 CHECK_FAILURE (ctx);
4583 /* Add incoming phi values */
4584 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
4585 GSList *l, *ins_list;
4587 ins_list = bblocks [bb->block_num].phi_nodes;
4589 for (l = ins_list; l; l = l->next) {
4590 PhiNode *node = l->data;
4591 MonoInst *phi = node->phi;
4592 int sreg1 = node->sreg;
4593 LLVMBasicBlockRef in_bb;
4598 in_bb = get_end_bb (ctx, node->in_bb);
4600 if (ctx->unreachable [node->in_bb->block_num])
4603 if (!values [sreg1])
4604 /* Can happen with values in EH clauses */
4605 LLVM_FAILURE (ctx, "incoming phi sreg1");
4607 if (phi->opcode == OP_VPHI) {
4608 g_assert (LLVMTypeOf (ctx->addresses [sreg1]) == LLVMTypeOf (values [phi->dreg]));
4609 LLVMAddIncoming (values [phi->dreg], &ctx->addresses [sreg1], &in_bb, 1);
4611 if (LLVMTypeOf (values [sreg1]) != LLVMTypeOf (values [phi->dreg]))
4613 LLVM_FAILURE (ctx, "incoming phi arg type mismatch");
4614 g_assert (LLVMTypeOf (values [sreg1]) == LLVMTypeOf (values [phi->dreg]));
4615 LLVMAddIncoming (values [phi->dreg], &values [sreg1], &in_bb, 1);
4620 /* Create the SWITCH statements for ENDFINALLY instructions */
4621 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
4622 BBInfo *info = &bblocks [bb->block_num];
4624 for (l = info->endfinally_switch_ins_list; l; l = l->next) {
4625 LLVMValueRef switch_ins = l->data;
4626 GSList *bb_list = info->call_handler_return_bbs;
4628 for (i = 0; i < g_slist_length (bb_list); ++i)
4629 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), i + 1, FALSE), g_slist_nth (bb_list, i)->data);
4633 if (cfg->verbose_level > 1)
4634 mono_llvm_dump_value (method);
4636 if (cfg->compile_aot)
4637 mark_as_used (ctx->lmodule, method);
4639 if (cfg->compile_aot) {
4640 LLVMValueRef md_args [16];
4641 LLVMValueRef md_node;
4644 method_index = mono_aot_get_method_index (cfg->orig_method);
4645 md_args [0] = LLVMMDString (method_name, strlen (method_name));
4646 md_args [1] = LLVMConstInt (LLVMInt32Type (), method_index, FALSE);
4647 md_node = LLVMMDNode (md_args, 2);
4648 LLVMAddNamedMetadataOperand (module, "mono.function_indexes", md_node);
4649 //LLVMSetMetadata (method, md_kind, LLVMMDNode (&md_arg, 1));
4652 if (cfg->compile_aot) {
4653 /* Don't generate native code, keep the LLVM IR */
4654 if (cfg->compile_aot && cfg->verbose_level)
4655 printf ("%s emitted as %s\n", mono_method_full_name (cfg->method, TRUE), method_name);
4657 //LLVMVerifyFunction(method, 0);
4659 mono_llvm_optimize_method (ctx->lmodule->mono_ee, method);
4661 if (cfg->verbose_level > 1)
4662 mono_llvm_dump_value (method);
4664 cfg->native_code = LLVMGetPointerToGlobal (ctx->lmodule->ee, method);
4666 /* Set by emit_cb */
4667 g_assert (cfg->code_len);
4669 /* FIXME: Free the LLVM IL for the function */
4677 /* Need to add unused phi nodes as they can be referenced by other values */
4678 LLVMBasicBlockRef phi_bb = LLVMAppendBasicBlock (method, "PHI_BB");
4679 LLVMBuilderRef builder;
4681 builder = create_builder (ctx);
4682 LLVMPositionBuilderAtEnd (builder, phi_bb);
4684 for (i = 0; i < phi_values->len; ++i) {
4685 LLVMValueRef v = g_ptr_array_index (phi_values, i);
4686 if (LLVMGetInstructionParent (v) == NULL)
4687 LLVMInsertIntoBuilder (builder, v);
4690 LLVMDeleteFunction (method);
4695 g_free (ctx->addresses);
4696 g_free (ctx->vreg_types);
4697 g_free (ctx->vreg_cli_types);
4698 g_free (ctx->pindexes);
4699 g_free (ctx->is_dead);
4700 g_free (ctx->unreachable);
4701 g_ptr_array_free (phi_values, TRUE);
4702 g_free (ctx->bblocks);
4703 g_hash_table_destroy (ctx->region_to_handler);
4704 g_free (method_name);
4705 g_ptr_array_free (bblock_list, TRUE);
4707 for (l = ctx->builders; l; l = l->next) {
4708 LLVMBuilderRef builder = l->data;
4709 LLVMDisposeBuilder (builder);
4714 mono_native_tls_set_value (current_cfg_tls_id, NULL);
4716 mono_loader_unlock ();
4720 * mono_llvm_emit_call:
4722 * Same as mono_arch_emit_call () for LLVM.
4725 mono_llvm_emit_call (MonoCompile *cfg, MonoCallInst *call)
4728 MonoMethodSignature *sig;
4729 int i, n, stack_size;
4734 sig = call->signature;
4735 n = sig->param_count + sig->hasthis;
4737 call->cinfo = mono_arch_get_llvm_call_info (cfg, sig);
4739 if (cfg->disable_llvm)
4742 if (sig->call_convention == MONO_CALL_VARARG) {
4743 cfg->exception_message = g_strdup ("varargs");
4744 cfg->disable_llvm = TRUE;
4747 for (i = 0; i < n; ++i) {
4750 ainfo = call->cinfo->args + i;
4752 in = call->args [i];
4754 /* Simply remember the arguments */
4755 switch (ainfo->storage) {
4757 case LLVMArgInFPReg: {
4758 MonoType *t = (sig->hasthis && i == 0) ? &mono_get_intptr_class ()->byval_arg : sig->params [i - sig->hasthis];
4761 opcode = mono_type_to_regmove (cfg, t);
4762 if (opcode == OP_FMOVE) {
4763 MONO_INST_NEW (cfg, ins, OP_FMOVE);
4764 ins->dreg = mono_alloc_freg (cfg);
4765 } else if (opcode == OP_LMOVE) {
4766 MONO_INST_NEW (cfg, ins, OP_LMOVE);
4767 ins->dreg = mono_alloc_lreg (cfg);
4769 MONO_INST_NEW (cfg, ins, OP_MOVE);
4770 ins->dreg = mono_alloc_ireg (cfg);
4772 ins->sreg1 = in->dreg;
4775 case LLVMArgVtypeByVal:
4776 case LLVMArgVtypeInReg:
4777 MONO_INST_NEW (cfg, ins, OP_LLVM_OUTARG_VT);
4778 ins->dreg = mono_alloc_ireg (cfg);
4779 ins->sreg1 = in->dreg;
4780 ins->klass = mono_class_from_mono_type (sig->params [i - sig->hasthis]);
4783 call->cinfo = mono_arch_get_llvm_call_info (cfg, sig);
4784 cfg->exception_message = g_strdup ("ainfo->storage");
4785 cfg->disable_llvm = TRUE;
4789 if (!cfg->disable_llvm) {
4790 MONO_ADD_INS (cfg->cbb, ins);
4791 mono_call_inst_add_outarg_reg (cfg, call, ins->dreg, 0, FALSE);
4796 static unsigned char*
4797 alloc_cb (LLVMValueRef function, int size)
4801 cfg = mono_native_tls_get_value (current_cfg_tls_id);
4805 return mono_domain_code_reserve (cfg->domain, size);
4807 return mono_domain_code_reserve (mono_domain_get (), size);
4812 emitted_cb (LLVMValueRef function, void *start, void *end)
4816 cfg = mono_native_tls_get_value (current_cfg_tls_id);
4818 cfg->code_len = (guint8*)end - (guint8*)start;
4822 exception_cb (void *data)
4825 MonoJitExceptionInfo *ei;
4826 guint32 ei_len, i, j, nested_len, nindex;
4827 gpointer *type_info;
4828 int this_reg, this_offset;
4830 cfg = mono_native_tls_get_value (current_cfg_tls_id);
4834 * data points to a DWARF FDE structure, convert it to our unwind format and
4836 * An alternative would be to save it directly, and modify our unwinder to work
4839 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);
4840 if (cfg->verbose_level > 1)
4841 mono_print_unwind_info (cfg->encoded_unwind_ops, cfg->encoded_unwind_ops_len);
4843 /* Count nested clauses */
4845 for (i = 0; i < ei_len; ++i) {
4846 for (j = 0; j < ei_len; ++j) {
4847 gint32 cindex1 = *(gint32*)type_info [i];
4848 MonoExceptionClause *clause1 = &cfg->header->clauses [cindex1];
4849 gint32 cindex2 = *(gint32*)type_info [j];
4850 MonoExceptionClause *clause2 = &cfg->header->clauses [cindex2];
4852 if (cindex1 != cindex2 && clause1->try_offset >= clause2->try_offset && clause1->handler_offset <= clause2->handler_offset) {
4858 cfg->llvm_ex_info = mono_mempool_alloc0 (cfg->mempool, (ei_len + nested_len) * sizeof (MonoJitExceptionInfo));
4859 cfg->llvm_ex_info_len = ei_len + nested_len;
4860 memcpy (cfg->llvm_ex_info, ei, ei_len * sizeof (MonoJitExceptionInfo));
4861 /* Fill the rest of the information from the type info */
4862 for (i = 0; i < ei_len; ++i) {
4863 gint32 clause_index = *(gint32*)type_info [i];
4864 MonoExceptionClause *clause = &cfg->header->clauses [clause_index];
4866 cfg->llvm_ex_info [i].flags = clause->flags;
4867 cfg->llvm_ex_info [i].data.catch_class = clause->data.catch_class;
4871 * For nested clauses, the LLVM produced exception info associates the try interval with
4872 * the innermost handler, while mono expects it to be associated with all nesting clauses.
4874 /* FIXME: These should be order with the normal clauses */
4876 for (i = 0; i < ei_len; ++i) {
4877 for (j = 0; j < ei_len; ++j) {
4878 gint32 cindex1 = *(gint32*)type_info [i];
4879 MonoExceptionClause *clause1 = &cfg->header->clauses [cindex1];
4880 gint32 cindex2 = *(gint32*)type_info [j];
4881 MonoExceptionClause *clause2 = &cfg->header->clauses [cindex2];
4883 if (cindex1 != cindex2 && clause1->try_offset >= clause2->try_offset && clause1->handler_offset <= clause2->handler_offset) {
4885 * The try interval comes from the nested clause, everything else from the
4888 memcpy (&cfg->llvm_ex_info [nindex], &cfg->llvm_ex_info [j], sizeof (MonoJitExceptionInfo));
4889 cfg->llvm_ex_info [nindex].try_start = cfg->llvm_ex_info [i].try_start;
4890 cfg->llvm_ex_info [nindex].try_end = cfg->llvm_ex_info [i].try_end;
4895 g_assert (nindex == ei_len + nested_len);
4896 cfg->llvm_this_reg = this_reg;
4897 cfg->llvm_this_offset = this_offset;
4899 /* type_info [i] is cfg mempool allocated, no need to free it */
4906 dlsym_cb (const char *name, void **symbol)
4912 if (!strcmp (name, "__bzero")) {
4913 *symbol = (void*)bzero;
4915 current = mono_dl_open (NULL, 0, NULL);
4918 err = mono_dl_symbol (current, name, symbol);
4920 mono_dl_close (current);
4922 #ifdef MONO_ARCH_HAVE_CREATE_LLVM_NATIVE_THUNK
4923 *symbol = (char*)mono_arch_create_llvm_native_thunk (mono_domain_get (), (guint8*)(*symbol));
4929 AddFunc (LLVMModuleRef module, const char *name, LLVMTypeRef ret_type, LLVMTypeRef *param_types, int nparams)
4931 LLVMAddFunction (module, name, LLVMFunctionType (ret_type, param_types, nparams, FALSE));
4935 AddFunc2 (LLVMModuleRef module, const char *name, LLVMTypeRef ret_type, LLVMTypeRef param_type1, LLVMTypeRef param_type2)
4937 LLVMTypeRef param_types [4];
4939 param_types [0] = param_type1;
4940 param_types [1] = param_type2;
4942 AddFunc (module, name, ret_type, param_types, 2);
4946 add_intrinsics (LLVMModuleRef module)
4948 /* Emit declarations of instrinsics */
4950 * It would be nicer to emit only the intrinsics actually used, but LLVM's Module
4951 * type doesn't seem to do any locking.
4954 LLVMTypeRef memset_params [] = { LLVMPointerType (LLVMInt8Type (), 0), LLVMInt8Type (), LLVMInt32Type (), LLVMInt32Type (), LLVMInt1Type () };
4956 memset_param_count = 5;
4957 memset_func_name = "llvm.memset.p0i8.i32";
4959 LLVMAddFunction (module, memset_func_name, LLVMFunctionType (LLVMVoidType (), memset_params, memset_param_count, FALSE));
4963 LLVMTypeRef memcpy_params [] = { LLVMPointerType (LLVMInt8Type (), 0), LLVMPointerType (LLVMInt8Type (), 0), LLVMInt32Type (), LLVMInt32Type (), LLVMInt1Type () };
4965 memcpy_param_count = 5;
4966 memcpy_func_name = "llvm.memcpy.p0i8.p0i8.i32";
4968 LLVMAddFunction (module, memcpy_func_name, LLVMFunctionType (LLVMVoidType (), memcpy_params, memcpy_param_count, FALSE));
4972 LLVMTypeRef params [] = { LLVMDoubleType () };
4974 LLVMAddFunction (module, "llvm.sin.f64", LLVMFunctionType (LLVMDoubleType (), params, 1, FALSE));
4975 LLVMAddFunction (module, "llvm.cos.f64", LLVMFunctionType (LLVMDoubleType (), params, 1, FALSE));
4976 LLVMAddFunction (module, "llvm.sqrt.f64", LLVMFunctionType (LLVMDoubleType (), params, 1, FALSE));
4978 /* This isn't an intrinsic, instead llvm seems to special case it by name */
4979 LLVMAddFunction (module, "fabs", LLVMFunctionType (LLVMDoubleType (), params, 1, FALSE));
4983 LLVMTypeRef ovf_res_i32 [] = { LLVMInt32Type (), LLVMInt1Type () };
4984 LLVMTypeRef ovf_params_i32 [] = { LLVMInt32Type (), LLVMInt32Type () };
4986 LLVMAddFunction (module, "llvm.sadd.with.overflow.i32", LLVMFunctionType (LLVMStructType (ovf_res_i32, 2, FALSE), ovf_params_i32, 2, FALSE));
4987 LLVMAddFunction (module, "llvm.uadd.with.overflow.i32", LLVMFunctionType (LLVMStructType (ovf_res_i32, 2, FALSE), ovf_params_i32, 2, FALSE));
4988 LLVMAddFunction (module, "llvm.ssub.with.overflow.i32", LLVMFunctionType (LLVMStructType (ovf_res_i32, 2, FALSE), ovf_params_i32, 2, FALSE));
4989 LLVMAddFunction (module, "llvm.usub.with.overflow.i32", LLVMFunctionType (LLVMStructType (ovf_res_i32, 2, FALSE), ovf_params_i32, 2, FALSE));
4990 LLVMAddFunction (module, "llvm.smul.with.overflow.i32", LLVMFunctionType (LLVMStructType (ovf_res_i32, 2, FALSE), ovf_params_i32, 2, FALSE));
4991 LLVMAddFunction (module, "llvm.umul.with.overflow.i32", LLVMFunctionType (LLVMStructType (ovf_res_i32, 2, FALSE), ovf_params_i32, 2, FALSE));
4995 LLVMTypeRef ovf_res_i64 [] = { LLVMInt64Type (), LLVMInt1Type () };
4996 LLVMTypeRef ovf_params_i64 [] = { LLVMInt64Type (), LLVMInt64Type () };
4998 LLVMAddFunction (module, "llvm.sadd.with.overflow.i64", LLVMFunctionType (LLVMStructType (ovf_res_i64, 2, FALSE), ovf_params_i64, 2, FALSE));
4999 LLVMAddFunction (module, "llvm.uadd.with.overflow.i64", LLVMFunctionType (LLVMStructType (ovf_res_i64, 2, FALSE), ovf_params_i64, 2, FALSE));
5000 LLVMAddFunction (module, "llvm.ssub.with.overflow.i64", LLVMFunctionType (LLVMStructType (ovf_res_i64, 2, FALSE), ovf_params_i64, 2, FALSE));
5001 LLVMAddFunction (module, "llvm.usub.with.overflow.i64", LLVMFunctionType (LLVMStructType (ovf_res_i64, 2, FALSE), ovf_params_i64, 2, FALSE));
5002 LLVMAddFunction (module, "llvm.smul.with.overflow.i64", LLVMFunctionType (LLVMStructType (ovf_res_i64, 2, FALSE), ovf_params_i64, 2, FALSE));
5003 LLVMAddFunction (module, "llvm.umul.with.overflow.i64", LLVMFunctionType (LLVMStructType (ovf_res_i64, 2, FALSE), ovf_params_i64, 2, FALSE));
5008 LLVMTypeRef arg_types [2];
5009 LLVMTypeRef ret_type;
5011 arg_types [0] = LLVMPointerType (LLVMInt8Type (), 0);
5012 arg_types [1] = LLVMPointerType (LLVMInt8Type (), 0);
5013 ret_type = LLVMInt32Type ();
5015 LLVMAddFunction (module, "mono_personality", LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE));
5017 LLVMAddFunction (module, "llvm_resume_unwind_trampoline", LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE));
5020 /* SSE intrinsics */
5021 #if defined(TARGET_X86) || defined(TARGET_AMD64)
5023 LLVMTypeRef ret_type, arg_types [16];
5026 ret_type = type_to_simd_type (MONO_TYPE_I4);
5027 arg_types [0] = ret_type;
5028 arg_types [1] = ret_type;
5029 AddFunc (module, "llvm.x86.sse41.pminud", ret_type, arg_types, 2);
5030 AddFunc (module, "llvm.x86.sse41.pmaxud", ret_type, arg_types, 2);
5032 ret_type = type_to_simd_type (MONO_TYPE_I2);
5033 arg_types [0] = ret_type;
5034 arg_types [1] = ret_type;
5035 AddFunc (module, "llvm.x86.sse41.pminuw", ret_type, arg_types, 2);
5036 AddFunc (module, "llvm.x86.sse2.pmins.w", ret_type, arg_types, 2);
5037 AddFunc (module, "llvm.x86.sse41.pmaxuw", ret_type, arg_types, 2);
5038 AddFunc (module, "llvm.x86.sse2.padds.w", ret_type, arg_types, 2);
5039 AddFunc (module, "llvm.x86.sse2.psubs.w", ret_type, arg_types, 2);
5040 AddFunc (module, "llvm.x86.sse2.paddus.w", ret_type, arg_types, 2);
5041 AddFunc (module, "llvm.x86.sse2.psubus.w", ret_type, arg_types, 2);
5042 AddFunc (module, "llvm.x86.sse2.pavg.w", ret_type, arg_types, 2);
5043 AddFunc (module, "llvm.x86.sse2.pmulh.w", ret_type, arg_types, 2);
5044 AddFunc (module, "llvm.x86.sse2.pmulhu.w", ret_type, arg_types, 2);
5046 ret_type = type_to_simd_type (MONO_TYPE_I1);
5047 arg_types [0] = ret_type;
5048 arg_types [1] = ret_type;
5049 AddFunc (module, "llvm.x86.sse2.pminu.b", ret_type, arg_types, 2);
5050 AddFunc (module, "llvm.x86.sse2.pmaxu.b", ret_type, arg_types, 2);
5051 AddFunc (module, "llvm.x86.sse2.padds.b", ret_type, arg_types, 2);
5052 AddFunc (module, "llvm.x86.sse2.psubs.b", ret_type, arg_types, 2);
5053 AddFunc (module, "llvm.x86.sse2.paddus.b", ret_type, arg_types, 2);
5054 AddFunc (module, "llvm.x86.sse2.psubus.b", ret_type, arg_types, 2);
5055 AddFunc (module, "llvm.x86.sse2.pavg.b", ret_type, arg_types, 2);
5057 ret_type = type_to_simd_type (MONO_TYPE_R8);
5058 arg_types [0] = ret_type;
5059 arg_types [1] = ret_type;
5060 AddFunc (module, "llvm.x86.sse2.min.pd", ret_type, arg_types, 2);
5061 AddFunc (module, "llvm.x86.sse2.max.pd", ret_type, arg_types, 2);
5062 AddFunc (module, "llvm.x86.sse3.hadd.pd", ret_type, arg_types, 2);
5063 AddFunc (module, "llvm.x86.sse3.hsub.pd", ret_type, arg_types, 2);
5064 AddFunc (module, "llvm.x86.sse3.addsub.pd", ret_type, arg_types, 2);
5066 ret_type = type_to_simd_type (MONO_TYPE_R4);
5067 arg_types [0] = ret_type;
5068 arg_types [1] = ret_type;
5069 AddFunc (module, "llvm.x86.sse.min.ps", ret_type, arg_types, 2);
5070 AddFunc (module, "llvm.x86.sse.max.ps", ret_type, arg_types, 2);
5071 AddFunc (module, "llvm.x86.sse3.hadd.ps", ret_type, arg_types, 2);
5072 AddFunc (module, "llvm.x86.sse3.hsub.ps", ret_type, arg_types, 2);
5073 AddFunc (module, "llvm.x86.sse3.addsub.ps", ret_type, arg_types, 2);
5076 ret_type = type_to_simd_type (MONO_TYPE_I1);
5077 arg_types [0] = type_to_simd_type (MONO_TYPE_I2);
5078 arg_types [1] = type_to_simd_type (MONO_TYPE_I2);
5079 AddFunc (module, "llvm.x86.sse2.packsswb.128", ret_type, arg_types, 2);
5080 AddFunc (module, "llvm.x86.sse2.packuswb.128", ret_type, arg_types, 2);
5081 ret_type = type_to_simd_type (MONO_TYPE_I2);
5082 arg_types [0] = type_to_simd_type (MONO_TYPE_I4);
5083 arg_types [1] = type_to_simd_type (MONO_TYPE_I4);
5084 AddFunc (module, "llvm.x86.sse2.packssdw.128", ret_type, arg_types, 2);
5085 AddFunc (module, "llvm.x86.sse41.packusdw", ret_type, arg_types, 2);
5088 ret_type = type_to_simd_type (MONO_TYPE_R8);
5089 arg_types [0] = ret_type;
5090 arg_types [1] = ret_type;
5091 arg_types [2] = LLVMInt8Type ();
5092 AddFunc (module, "llvm.x86.sse2.cmp.pd", ret_type, arg_types, 3);
5093 ret_type = type_to_simd_type (MONO_TYPE_R4);
5094 arg_types [0] = ret_type;
5095 arg_types [1] = ret_type;
5096 arg_types [2] = LLVMInt8Type ();
5097 AddFunc (module, "llvm.x86.sse.cmp.ps", ret_type, arg_types, 3);
5099 /* Conversion ops */
5100 ret_type = type_to_simd_type (MONO_TYPE_R8);
5101 arg_types [0] = type_to_simd_type (MONO_TYPE_I4);
5102 AddFunc (module, "llvm.x86.sse2.cvtdq2pd", ret_type, arg_types, 1);
5103 ret_type = type_to_simd_type (MONO_TYPE_R4);
5104 arg_types [0] = type_to_simd_type (MONO_TYPE_I4);
5105 AddFunc (module, "llvm.x86.sse2.cvtdq2ps", ret_type, arg_types, 1);
5106 ret_type = type_to_simd_type (MONO_TYPE_I4);
5107 arg_types [0] = type_to_simd_type (MONO_TYPE_R8);
5108 AddFunc (module, "llvm.x86.sse2.cvtpd2dq", ret_type, arg_types, 1);
5109 ret_type = type_to_simd_type (MONO_TYPE_I4);
5110 arg_types [0] = type_to_simd_type (MONO_TYPE_R4);
5111 AddFunc (module, "llvm.x86.sse2.cvtps2dq", ret_type, arg_types, 1);
5112 ret_type = type_to_simd_type (MONO_TYPE_R4);
5113 arg_types [0] = type_to_simd_type (MONO_TYPE_R8);
5114 AddFunc (module, "llvm.x86.sse2.cvtpd2ps", ret_type, arg_types, 1);
5115 ret_type = type_to_simd_type (MONO_TYPE_R8);
5116 arg_types [0] = type_to_simd_type (MONO_TYPE_R4);
5117 AddFunc (module, "llvm.x86.sse2.cvtps2pd", ret_type, arg_types, 1);
5119 ret_type = type_to_simd_type (MONO_TYPE_I4);
5120 arg_types [0] = type_to_simd_type (MONO_TYPE_R8);
5121 AddFunc (module, "llvm.x86.sse2.cvttpd2dq", ret_type, arg_types, 1);
5122 ret_type = type_to_simd_type (MONO_TYPE_I4);
5123 arg_types [0] = type_to_simd_type (MONO_TYPE_R4);
5124 AddFunc (module, "llvm.x86.sse2.cvttps2dq", ret_type, arg_types, 1);
5127 ret_type = type_to_simd_type (MONO_TYPE_R8);
5128 arg_types [0] = ret_type;
5129 AddFunc (module, "llvm.x86.sse2.sqrt.pd", ret_type, arg_types, 1);
5130 ret_type = type_to_simd_type (MONO_TYPE_R4);
5131 arg_types [0] = ret_type;
5132 AddFunc (module, "llvm.x86.sse.sqrt.ps", ret_type, arg_types, 1);
5133 ret_type = type_to_simd_type (MONO_TYPE_R4);
5134 arg_types [0] = ret_type;
5135 AddFunc (module, "llvm.x86.sse.rsqrt.ps", 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.rcp.ps", ret_type, arg_types, 1);
5141 ret_type = type_to_simd_type (MONO_TYPE_I2);
5142 arg_types [0] = ret_type;
5143 arg_types [1] = LLVMInt32Type ();
5144 AddFunc (module, "llvm.x86.sse2.psrli.w", ret_type, arg_types, 2);
5145 AddFunc (module, "llvm.x86.sse2.psrai.w", ret_type, arg_types, 2);
5146 AddFunc (module, "llvm.x86.sse2.pslli.w", ret_type, arg_types, 2);
5147 ret_type = type_to_simd_type (MONO_TYPE_I4);
5148 arg_types [0] = ret_type;
5149 arg_types [1] = LLVMInt32Type ();
5150 AddFunc (module, "llvm.x86.sse2.psrli.d", ret_type, arg_types, 2);
5151 AddFunc (module, "llvm.x86.sse2.psrai.d", ret_type, arg_types, 2);
5152 AddFunc (module, "llvm.x86.sse2.pslli.d", ret_type, arg_types, 2);
5153 ret_type = type_to_simd_type (MONO_TYPE_I8);
5154 arg_types [0] = ret_type;
5155 arg_types [1] = LLVMInt32Type ();
5156 AddFunc (module, "llvm.x86.sse2.psrli.q", ret_type, arg_types, 2);
5157 AddFunc (module, "llvm.x86.sse2.pslli.q", ret_type, arg_types, 2);
5160 ret_type = LLVMInt32Type ();
5161 arg_types [0] = type_to_simd_type (MONO_TYPE_I1);
5162 AddFunc (module, "llvm.x86.sse2.pmovmskb.128", ret_type, arg_types, 1);
5165 AddFunc (module, "llvm.x86.sse2.pause", LLVMVoidType (), NULL, 0);
5168 /* Load/Store intrinsics */
5170 LLVMTypeRef arg_types [5];
5174 for (i = 1; i <= 8; i *= 2) {
5175 arg_types [0] = LLVMPointerType (LLVMIntType (i * 8), 0);
5176 arg_types [1] = LLVMInt32Type ();
5177 arg_types [2] = LLVMInt1Type ();
5178 sprintf (name, "llvm.mono.load.i%d.p0i%d", i * 8, i * 8);
5179 LLVMAddFunction (module, name, LLVMFunctionType (LLVMIntType (i * 8), arg_types, 3, FALSE));
5181 arg_types [0] = LLVMIntType (i * 8);
5182 arg_types [1] = LLVMPointerType (LLVMIntType (i * 8), 0);
5183 arg_types [2] = LLVMInt32Type ();
5184 arg_types [3] = LLVMInt1Type ();
5185 sprintf (name, "llvm.mono.store.i%d.p0i%d", i * 8, i * 8);
5186 LLVMAddFunction (module, name, LLVMFunctionType (LLVMVoidType (), arg_types, 4, FALSE));
5192 add_types (MonoLLVMModule *lmodule)
5194 lmodule->ptr_type = LLVMPointerType (sizeof (gpointer) == 8 ? LLVMInt64Type () : LLVMInt32Type (), 0);
5198 mono_llvm_init (void)
5200 mono_native_tls_alloc (¤t_cfg_tls_id, NULL);
5204 init_jit_module (MonoDomain *domain)
5206 MonoJitICallInfo *info;
5207 MonoJitDomainInfo *dinfo;
5208 MonoLLVMModule *module;
5211 dinfo = domain_jit_info (domain);
5212 if (dinfo->llvm_module)
5215 mono_loader_lock ();
5217 if (dinfo->llvm_module) {
5218 mono_loader_unlock ();
5222 module = g_new0 (MonoLLVMModule, 1);
5224 name = g_strdup_printf ("mono-%s", domain->friendly_name);
5225 module->module = LLVMModuleCreateWithName (name);
5227 module->mono_ee = mono_llvm_create_ee (LLVMCreateModuleProviderForExistingModule (module->module), alloc_cb, emitted_cb, exception_cb, dlsym_cb, &module->ee);
5229 add_intrinsics (module->module);
5232 module->llvm_types = g_hash_table_new (NULL, NULL);
5234 info = mono_find_jit_icall_by_name ("llvm_resume_unwind_trampoline");
5236 LLVMAddGlobalMapping (module->ee, LLVMGetNamedFunction (module->module, "llvm_resume_unwind_trampoline"), (void*)info->func);
5238 mono_memory_barrier ();
5240 dinfo->llvm_module = module;
5242 mono_loader_unlock ();
5246 mono_llvm_cleanup (void)
5248 if (aot_module.module)
5249 LLVMDisposeModule (aot_module.module);
5251 LLVMContextDispose (LLVMGetGlobalContext ());
5255 mono_llvm_free_domain_info (MonoDomain *domain)
5257 MonoJitDomainInfo *info = domain_jit_info (domain);
5258 MonoLLVMModule *module = info->llvm_module;
5264 if (module->llvm_types)
5265 g_hash_table_destroy (module->llvm_types);
5267 mono_llvm_dispose_ee (module->mono_ee);
5269 if (module->bb_names) {
5270 for (i = 0; i < module->bb_names_len; ++i)
5271 g_free (module->bb_names [i]);
5272 g_free (module->bb_names);
5274 //LLVMDisposeModule (module->module);
5278 info->llvm_module = NULL;
5282 mono_llvm_create_aot_module (const char *got_symbol)
5284 /* Delete previous module */
5285 if (aot_module.plt_entries)
5286 g_hash_table_destroy (aot_module.plt_entries);
5287 if (aot_module.module)
5288 LLVMDisposeModule (aot_module.module);
5290 memset (&aot_module, 0, sizeof (aot_module));
5292 aot_module.module = LLVMModuleCreateWithName ("aot");
5293 aot_module.got_symbol = got_symbol;
5295 add_intrinsics (aot_module.module);
5296 add_types (&aot_module);
5300 * We couldn't compute the type of the LLVM global representing the got because
5301 * its size is only known after all the methods have been emitted. So create
5302 * a dummy variable, and replace all uses it with the real got variable when
5303 * its size is known in mono_llvm_emit_aot_module ().
5306 LLVMTypeRef got_type = LLVMArrayType (aot_module.ptr_type, 0);
5308 aot_module.got_var = LLVMAddGlobal (aot_module.module, got_type, "mono_dummy_got");
5309 LLVMSetInitializer (aot_module.got_var, LLVMConstNull (got_type));
5312 /* Add a dummy personality function */
5314 LLVMBasicBlockRef lbb;
5315 LLVMBuilderRef lbuilder;
5316 LLVMValueRef personality;
5318 personality = LLVMAddFunction (aot_module.module, "mono_aot_personality", LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE));
5319 LLVMSetLinkage (personality, LLVMInternalLinkage);
5320 lbb = LLVMAppendBasicBlock (personality, "BB0");
5321 lbuilder = LLVMCreateBuilder ();
5322 LLVMPositionBuilderAtEnd (lbuilder, lbb);
5323 LLVMBuildRetVoid (lbuilder);
5326 aot_module.llvm_types = g_hash_table_new (NULL, NULL);
5327 aot_module.plt_entries = g_hash_table_new (g_str_hash, g_str_equal);
5331 * Emit the aot module into the LLVM bitcode file FILENAME.
5334 mono_llvm_emit_aot_module (const char *filename, int got_size)
5336 LLVMTypeRef got_type;
5337 LLVMValueRef real_got;
5340 * Create the real got variable and replace all uses of the dummy variable with
5343 got_type = LLVMArrayType (aot_module.ptr_type, got_size);
5344 real_got = LLVMAddGlobal (aot_module.module, got_type, aot_module.got_symbol);
5345 LLVMSetInitializer (real_got, LLVMConstNull (got_type));
5346 LLVMSetLinkage (real_got, LLVMInternalLinkage);
5348 mono_llvm_replace_uses_of (aot_module.got_var, real_got);
5350 mark_as_used (&aot_module, real_got);
5352 /* Delete the dummy got so it doesn't become a global */
5353 LLVMDeleteGlobal (aot_module.got_var);
5355 emit_llvm_used (&aot_module);
5361 if (LLVMVerifyModule (aot_module.module, LLVMReturnStatusAction, &verifier_err)) {
5362 g_assert_not_reached ();
5367 LLVMWriteBitcodeToFile (aot_module.module, filename);
5372 - Emit LLVM IR from the mono IR using the LLVM C API.
5373 - The original arch specific code remains, so we can fall back to it if we run
5374 into something we can't handle.
5378 A partial list of issues:
5379 - Handling of opcodes which can throw exceptions.
5381 In the mono JIT, these are implemented using code like this:
5388 push throw_pos - method
5389 call <exception trampoline>
5391 The problematic part is push throw_pos - method, which cannot be represented
5392 in the LLVM IR, since it does not support label values.
5393 -> this can be implemented in AOT mode using inline asm + labels, but cannot
5394 be implemented in JIT mode ?
5395 -> a possible but slower implementation would use the normal exception
5396 throwing code but it would need to control the placement of the throw code
5397 (it needs to be exactly after the compare+branch).
5398 -> perhaps add a PC offset intrinsics ?
5400 - efficient implementation of .ovf opcodes.
5402 These are currently implemented as:
5403 <ins which sets the condition codes>
5406 Some overflow opcodes are now supported by LLVM SVN.
5408 - exception handling, unwinding.
5409 - SSA is disabled for methods with exception handlers
5410 - How to obtain unwind info for LLVM compiled methods ?
5411 -> this is now solved by converting the unwind info generated by LLVM
5413 - LLVM uses the c++ exception handling framework, while we use our home grown
5414 code, and couldn't use the c++ one:
5415 - its not supported under VC++, other exotic platforms.
5416 - it might be impossible to support filter clauses with it.
5420 The trampolines need a predictable call sequence, since they need to disasm
5421 the calling code to obtain register numbers / offsets.
5423 LLVM currently generates this code in non-JIT mode:
5424 mov -0x98(%rax),%eax
5426 Here, the vtable pointer is lost.
5427 -> solution: use one vtable trampoline per class.
5429 - passing/receiving the IMT pointer/RGCTX.
5430 -> solution: pass them as normal arguments ?
5434 LLVM does not allow the specification of argument registers etc. This means
5435 that all calls are made according to the platform ABI.
5437 - passing/receiving vtypes.
5439 Vtypes passed/received in registers are handled by the front end by using
5440 a signature with scalar arguments, and loading the parts of the vtype into those
5443 Vtypes passed on the stack are handled using the 'byval' attribute.
5447 Supported though alloca, we need to emit the load/store code.
5451 The mono JIT uses pointer sized iregs/double fregs, while LLVM uses precisely
5452 typed registers, so we have to keep track of the precise LLVM type of each vreg.
5453 This is made easier because the IR is already in SSA form.
5454 An additional problem is that our IR is not consistent with types, i.e. i32/ia64
5455 types are frequently used incorrectly.
5460 Emit LLVM bytecode into a .bc file, compile it using llc into a .s file, then
5461 append the AOT data structures to that file. For methods which cannot be
5462 handled by LLVM, the normal JIT compiled versions are used.
5465 /* FIXME: Normalize some aspects of the mono IR to allow easier translation, like:
5466 * - each bblock should end with a branch
5467 * - setting the return value, making cfg->ret non-volatile
5468 * - avoid some transformations in the JIT which make it harder for us to generate
5470 * - use pointer types to help optimizations.