2 * mini-llvm.c: llvm "Backend" for the mono JIT
4 * Copyright 2009-2011 Novell Inc (http://www.novell.com)
5 * Copyright 2011 Xamarin Inc (http://www.xamarin.com)
9 #include <mono/metadata/debug-helpers.h>
10 #include <mono/metadata/mempool-internals.h>
11 #include <mono/utils/mono-tls.h>
12 #include <mono/utils/mono-dl.h>
14 #ifndef __STDC_LIMIT_MACROS
15 #define __STDC_LIMIT_MACROS
17 #ifndef __STDC_CONSTANT_MACROS
18 #define __STDC_CONSTANT_MACROS
21 #include "llvm-c/Core.h"
22 #include "llvm-c/ExecutionEngine.h"
23 #include "llvm-c/BitWriter.h"
24 #include "llvm-c/Analysis.h"
26 #include "mini-llvm-cpp.h"
29 * Information associated by mono with LLVM modules.
33 LLVMValueRef throw, rethrow, throw_corlib_exception;
34 GHashTable *llvm_types;
36 const char *got_symbol;
37 GHashTable *plt_entries;
44 * Information associated by the backend with mono basic blocks.
47 LLVMBasicBlockRef bblock, end_bblock;
48 LLVMValueRef finally_ind;
49 gboolean added, invoke_target;
51 * If this bblock is the start of a finally clause, this is a list of bblocks it
52 * needs to branch to in ENDFINALLY.
54 GSList *call_handler_return_bbs;
56 * If this bblock is the start of a finally clause, this is the bblock that
57 * CALL_HANDLER needs to branch to.
59 LLVMBasicBlockRef call_handler_target_bb;
60 /* The list of switch statements generated by ENDFINALLY instructions */
61 GSList *endfinally_switch_ins_list;
66 * Structure containing emit state
71 /* Maps method names to the corresponding LLVMValueRef */
72 GHashTable *emitted_method_decls;
76 MonoLLVMModule *lmodule;
79 int sindex, default_index, ex_index;
80 LLVMBuilderRef builder;
81 LLVMValueRef *values, *addresses;
82 MonoType **vreg_cli_types;
84 MonoMethodSignature *sig;
86 GHashTable *region_to_handler;
87 LLVMBuilderRef alloca_builder;
88 LLVMValueRef last_alloca;
89 LLVMValueRef rgctx_arg;
90 LLVMTypeRef *vreg_types;
92 gboolean *unreachable;
94 LLVMValueRef imt_rgctx_loc;
102 MonoBasicBlock *in_bb;
107 * Instruction metadata
108 * This is the same as ins_info, but LREG != IREG.
116 #define MINI_OP(a,b,dest,src1,src2) dest, src1, src2, ' ',
117 #define MINI_OP3(a,b,dest,src1,src2,src3) dest, src1, src2, src3,
124 /* keep in sync with the enum in mini.h */
127 #include "mini-ops.h"
132 #if SIZEOF_VOID_P == 4
133 #define GET_LONG_IMM(ins) (((guint64)(ins)->inst_ms_word << 32) | (guint64)(guint32)(ins)->inst_ls_word)
135 #define GET_LONG_IMM(ins) ((ins)->inst_imm)
138 #define LLVM_INS_INFO(opcode) (&llvm_ins_info [((opcode) - OP_START - 1) * 4])
141 #define TRACE_FAILURE(msg) do { printf ("%s\n", msg); } while (0)
143 #define TRACE_FAILURE(msg)
147 #define IS_TARGET_X86 1
149 #define IS_TARGET_X86 0
153 #define IS_TARGET_AMD64 1
155 #define IS_TARGET_AMD64 0
158 #define LLVM_FAILURE(ctx, reason) do { \
159 TRACE_FAILURE (reason); \
160 (ctx)->cfg->exception_message = g_strdup (reason); \
161 (ctx)->cfg->disable_llvm = TRUE; \
165 #define CHECK_FAILURE(ctx) do { \
166 if ((ctx)->cfg->disable_llvm) \
170 static LLVMIntPredicate cond_to_llvm_cond [] = {
183 static LLVMRealPredicate fpcond_to_llvm_cond [] = {
196 static LLVMExecutionEngineRef ee;
197 static MonoNativeTlsKey current_cfg_tls_id;
199 static MonoLLVMModule jit_module, aot_module;
200 static gboolean jit_module_inited;
201 static int memset_param_count, memcpy_param_count;
202 static const char *memset_func_name;
203 static const char *memcpy_func_name;
205 static void init_jit_module (void);
210 * The LLVM type with width == sizeof (gpointer)
215 return sizeof (gpointer) == 8 ? LLVMInt64Type () : LLVMInt32Type ();
221 return sizeof (gpointer) == 8 ? LLVMPointerType (LLVMInt64Type (), 0) : LLVMPointerType (LLVMInt32Type (), 0);
227 return sizeof (gpointer) == 8 ? LLVMPointerType (LLVMInt64Type (), 0) : LLVMPointerType (LLVMInt32Type (), 0);
233 * Return the size of the LLVM representation of the vtype T.
236 get_vtype_size (MonoType *t)
240 size = mono_class_value_size (mono_class_from_mono_type (t), NULL);
242 while (size < 2 * sizeof (gpointer) && mono_is_power_of_two (size) == -1)
249 * simd_class_to_llvm_type:
251 * Return the LLVM type corresponding to the Mono.SIMD class KLASS
254 simd_class_to_llvm_type (EmitContext *ctx, MonoClass *klass)
256 if (!strcmp (klass->name, "Vector2d")) {
257 return LLVMVectorType (LLVMDoubleType (), 2);
258 } else if (!strcmp (klass->name, "Vector2l")) {
259 return LLVMVectorType (LLVMInt64Type (), 2);
260 } else if (!strcmp (klass->name, "Vector2ul")) {
261 return LLVMVectorType (LLVMInt64Type (), 2);
262 } else if (!strcmp (klass->name, "Vector4i")) {
263 return LLVMVectorType (LLVMInt32Type (), 4);
264 } else if (!strcmp (klass->name, "Vector4ui")) {
265 return LLVMVectorType (LLVMInt32Type (), 4);
266 } else if (!strcmp (klass->name, "Vector4f")) {
267 return LLVMVectorType (LLVMFloatType (), 4);
268 } else if (!strcmp (klass->name, "Vector8s")) {
269 return LLVMVectorType (LLVMInt16Type (), 8);
270 } else if (!strcmp (klass->name, "Vector8us")) {
271 return LLVMVectorType (LLVMInt16Type (), 8);
272 } else if (!strcmp (klass->name, "Vector16sb")) {
273 return LLVMVectorType (LLVMInt8Type (), 16);
274 } else if (!strcmp (klass->name, "Vector16b")) {
275 return LLVMVectorType (LLVMInt8Type (), 16);
277 printf ("%s\n", klass->name);
283 /* Return the 128 bit SIMD type corresponding to the mono type TYPE */
284 static inline G_GNUC_UNUSED LLVMTypeRef
285 type_to_simd_type (int type)
289 return LLVMVectorType (LLVMInt8Type (), 16);
291 return LLVMVectorType (LLVMInt16Type (), 8);
293 return LLVMVectorType (LLVMInt32Type (), 4);
295 return LLVMVectorType (LLVMInt64Type (), 2);
297 return LLVMVectorType (LLVMDoubleType (), 2);
299 return LLVMVectorType (LLVMFloatType (), 4);
301 g_assert_not_reached ();
309 * Return the LLVM type corresponding to T.
312 type_to_llvm_type (EmitContext *ctx, MonoType *t)
315 return LLVMPointerType (LLVMInt8Type (), 0);
318 return LLVMVoidType ();
320 return LLVMInt8Type ();
322 return LLVMInt16Type ();
324 return LLVMInt32Type ();
326 return LLVMInt8Type ();
328 return LLVMInt16Type ();
330 return LLVMInt32Type ();
331 case MONO_TYPE_BOOLEAN:
332 return LLVMInt8Type ();
335 return LLVMInt64Type ();
337 return LLVMInt16Type ();
339 return LLVMFloatType ();
341 return LLVMDoubleType ();
344 return IntPtrType ();
345 case MONO_TYPE_OBJECT:
346 case MONO_TYPE_CLASS:
347 case MONO_TYPE_ARRAY:
348 case MONO_TYPE_SZARRAY:
349 case MONO_TYPE_STRING:
351 return ObjRefType ();
354 /* Because of generic sharing */
355 return ObjRefType ();
356 case MONO_TYPE_GENERICINST:
357 if (!mono_type_generic_inst_is_valuetype (t))
358 return ObjRefType ();
360 case MONO_TYPE_VALUETYPE:
361 case MONO_TYPE_TYPEDBYREF: {
365 klass = mono_class_from_mono_type (t);
367 if (MONO_CLASS_IS_SIMD (ctx->cfg, klass))
368 return simd_class_to_llvm_type (ctx, klass);
371 return type_to_llvm_type (ctx, mono_class_enum_basetype (klass));
372 ltype = g_hash_table_lookup (ctx->lmodule->llvm_types, klass);
375 LLVMTypeRef *eltypes;
378 size = get_vtype_size (t);
380 eltypes = g_new (LLVMTypeRef, size);
381 for (i = 0; i < size; ++i)
382 eltypes [i] = LLVMInt8Type ();
384 name = mono_type_full_name (&klass->byval_arg);
385 ltype = LLVMStructCreateNamed (LLVMGetGlobalContext (), name);
386 LLVMStructSetBody (ltype, eltypes, size, FALSE);
387 g_hash_table_insert (ctx->lmodule->llvm_types, klass, ltype);
394 printf ("X: %d\n", t->type);
395 ctx->cfg->exception_message = g_strdup_printf ("type %s", mono_type_full_name (t));
396 ctx->cfg->disable_llvm = TRUE;
404 * Return whenever T is an unsigned int type.
407 type_is_unsigned (EmitContext *ctx, MonoType *t)
423 * type_to_llvm_arg_type:
425 * Same as type_to_llvm_type, but treat i8/i16 as i32.
428 type_to_llvm_arg_type (EmitContext *ctx, MonoType *t)
430 LLVMTypeRef ptype = type_to_llvm_type (ctx, t);
432 if (ptype == LLVMInt8Type () || ptype == LLVMInt16Type ()) {
434 * LLVM generates code which only sets the lower bits, while JITted
435 * code expects all the bits to be set.
437 ptype = LLVMInt32Type ();
444 * llvm_type_to_stack_type:
446 * Return the LLVM type which needs to be used when a value of type TYPE is pushed
449 static G_GNUC_UNUSED LLVMTypeRef
450 llvm_type_to_stack_type (LLVMTypeRef type)
454 if (type == LLVMInt8Type ())
455 return LLVMInt32Type ();
456 else if (type == LLVMInt16Type ())
457 return LLVMInt32Type ();
458 else if (type == LLVMFloatType ())
459 return LLVMDoubleType ();
465 * regtype_to_llvm_type:
467 * Return the LLVM type corresponding to the regtype C used in instruction
471 regtype_to_llvm_type (char c)
475 return LLVMInt32Type ();
477 return LLVMInt64Type ();
479 return LLVMDoubleType ();
488 * Return the LLVM type corresponding to the unary/binary opcode OPCODE.
491 op_to_llvm_type (int opcode)
496 return LLVMInt8Type ();
499 return LLVMInt8Type ();
502 return LLVMInt16Type ();
505 return LLVMInt16Type ();
508 return LLVMInt32Type ();
511 return LLVMInt32Type ();
513 return LLVMInt64Type ();
515 return LLVMFloatType ();
517 return LLVMDoubleType ();
519 return LLVMInt64Type ();
521 return LLVMInt32Type ();
523 return LLVMInt64Type ();
526 return LLVMInt8Type ();
529 return LLVMInt16Type ();
532 return sizeof (gpointer) == 8 ? LLVMInt64Type () : LLVMInt32Type ();
539 return LLVMInt32Type ();
546 return LLVMInt64Type ();
548 printf ("%s\n", mono_inst_name (opcode));
549 g_assert_not_reached ();
555 * load_store_to_llvm_type:
557 * Return the size/sign/zero extension corresponding to the load/store opcode
561 load_store_to_llvm_type (int opcode, int *size, gboolean *sext, gboolean *zext)
567 case OP_LOADI1_MEMBASE:
568 case OP_STOREI1_MEMBASE_REG:
569 case OP_STOREI1_MEMBASE_IMM:
572 return LLVMInt8Type ();
573 case OP_LOADU1_MEMBASE:
577 return LLVMInt8Type ();
578 case OP_LOADI2_MEMBASE:
579 case OP_STOREI2_MEMBASE_REG:
580 case OP_STOREI2_MEMBASE_IMM:
583 return LLVMInt16Type ();
584 case OP_LOADU2_MEMBASE:
588 return LLVMInt16Type ();
589 case OP_LOADI4_MEMBASE:
590 case OP_LOADU4_MEMBASE:
593 case OP_STOREI4_MEMBASE_REG:
594 case OP_STOREI4_MEMBASE_IMM:
596 return LLVMInt32Type ();
597 case OP_LOADI8_MEMBASE:
599 case OP_STOREI8_MEMBASE_REG:
600 case OP_STOREI8_MEMBASE_IMM:
602 return LLVMInt64Type ();
603 case OP_LOADR4_MEMBASE:
604 case OP_STORER4_MEMBASE_REG:
606 return LLVMFloatType ();
607 case OP_LOADR8_MEMBASE:
608 case OP_STORER8_MEMBASE_REG:
610 return LLVMDoubleType ();
611 case OP_LOAD_MEMBASE:
613 case OP_STORE_MEMBASE_REG:
614 case OP_STORE_MEMBASE_IMM:
615 *size = sizeof (gpointer);
616 return IntPtrType ();
618 g_assert_not_reached ();
626 * Return the LLVM intrinsics corresponding to the overflow opcode OPCODE.
629 ovf_op_to_intrins (int opcode)
633 return "llvm.sadd.with.overflow.i32";
635 return "llvm.uadd.with.overflow.i32";
637 return "llvm.ssub.with.overflow.i32";
639 return "llvm.usub.with.overflow.i32";
641 return "llvm.smul.with.overflow.i32";
643 return "llvm.umul.with.overflow.i32";
645 return "llvm.sadd.with.overflow.i64";
647 return "llvm.uadd.with.overflow.i64";
649 return "llvm.ssub.with.overflow.i64";
651 return "llvm.usub.with.overflow.i64";
653 return "llvm.smul.with.overflow.i64";
655 return "llvm.umul.with.overflow.i64";
657 g_assert_not_reached ();
663 simd_op_to_intrins (int opcode)
666 #if defined(TARGET_X86) || defined(TARGET_AMD64)
668 return "llvm.x86.sse2.min.pd";
670 return "llvm.x86.sse.min.ps";
672 return "llvm.x86.sse41.pminud";
674 return "llvm.x86.sse41.pminuw";
676 return "llvm.x86.sse2.pminu.b";
678 return "llvm.x86.sse2.pmins.w";
680 return "llvm.x86.sse2.max.pd";
682 return "llvm.x86.sse.max.ps";
684 return "llvm.x86.sse3.hadd.pd";
686 return "llvm.x86.sse3.hadd.ps";
688 return "llvm.x86.sse3.hsub.pd";
690 return "llvm.x86.sse3.hsub.ps";
692 return "llvm.x86.sse41.pmaxud";
694 return "llvm.x86.sse41.pmaxuw";
696 return "llvm.x86.sse2.pmaxu.b";
698 return "llvm.x86.sse3.addsub.ps";
700 return "llvm.x86.sse3.addsub.pd";
701 case OP_EXTRACT_MASK:
702 return "llvm.x86.sse2.pmovmskb.128";
705 return "llvm.x86.sse2.psrli.w";
708 return "llvm.x86.sse2.psrli.d";
711 return "llvm.x86.sse2.psrli.q";
714 return "llvm.x86.sse2.pslli.w";
717 return "llvm.x86.sse2.pslli.d";
720 return "llvm.x86.sse2.pslli.q";
723 return "llvm.x86.sse2.psrai.w";
726 return "llvm.x86.sse2.psrai.d";
728 return "llvm.x86.sse2.padds.b";
730 return "llvm.x86.sse2.padds.w";
732 return "llvm.x86.sse2.psubs.b";
734 return "llvm.x86.sse2.psubs.w";
735 case OP_PADDB_SAT_UN:
736 return "llvm.x86.sse2.paddus.b";
737 case OP_PADDW_SAT_UN:
738 return "llvm.x86.sse2.paddus.w";
739 case OP_PSUBB_SAT_UN:
740 return "llvm.x86.sse2.psubus.b";
741 case OP_PSUBW_SAT_UN:
742 return "llvm.x86.sse2.psubus.w";
744 return "llvm.x86.sse2.pavg.b";
746 return "llvm.x86.sse2.pavg.w";
748 return "llvm.x86.sse.sqrt.ps";
750 return "llvm.x86.sse2.sqrt.pd";
752 return "llvm.x86.sse.rsqrt.ps";
754 return "llvm.x86.sse.rcp.ps";
756 return "llvm.x86.sse2.cvtdq2pd";
758 return "llvm.x86.sse2.cvtdq2ps";
760 return "llvm.x86.sse2.cvtpd2dq";
762 return "llvm.x86.sse2.cvtps2dq";
764 return "llvm.x86.sse2.cvtpd2ps";
766 return "llvm.x86.sse2.cvtps2pd";
768 return "llvm.x86.sse2.cvttpd2dq";
770 return "llvm.x86.sse2.cvttps2dq";
772 return "llvm.x86.sse.cmp.ps";
774 return "llvm.x86.sse2.cmp.pd";
776 return "llvm.x86.sse2.packsswb.128";
778 return "llvm.x86.sse2.packssdw.128";
780 return "llvm.x86.sse2.packuswb.128";
782 return "llvm.x86.sse41.packusdw";
784 return "llvm.x86.sse2.pmulh.w";
785 case OP_PMULW_HIGH_UN:
786 return "llvm.x86.sse2.pmulhu.w";
789 g_assert_not_reached ();
795 simd_op_to_llvm_type (int opcode)
797 #if defined(TARGET_X86) || defined(TARGET_AMD64)
801 return type_to_simd_type (MONO_TYPE_R8);
804 return type_to_simd_type (MONO_TYPE_I8);
807 return type_to_simd_type (MONO_TYPE_I4);
812 return type_to_simd_type (MONO_TYPE_I2);
816 return type_to_simd_type (MONO_TYPE_I1);
818 return type_to_simd_type (MONO_TYPE_R4);
821 return type_to_simd_type (MONO_TYPE_I4);
825 return type_to_simd_type (MONO_TYPE_R8);
829 return type_to_simd_type (MONO_TYPE_R4);
830 case OP_EXTRACT_MASK:
831 return type_to_simd_type (MONO_TYPE_I1);
837 return type_to_simd_type (MONO_TYPE_R4);
840 return type_to_simd_type (MONO_TYPE_R8);
842 g_assert_not_reached ();
853 * Return the LLVM basic block corresponding to BB.
855 static LLVMBasicBlockRef
856 get_bb (EmitContext *ctx, MonoBasicBlock *bb)
858 char bb_name_buf [128];
861 if (ctx->bblocks [bb->block_num].bblock == NULL) {
862 if (bb->flags & BB_EXCEPTION_HANDLER) {
863 int clause_index = (mono_get_block_region_notry (ctx->cfg, bb->region) >> 8) - 1;
864 sprintf (bb_name_buf, "EH_CLAUSE%d_BB%d", clause_index, bb->block_num);
865 bb_name = bb_name_buf;
866 } else if (bb->block_num < 256) {
867 if (!ctx->lmodule->bb_names)
868 ctx->lmodule->bb_names = g_new0 (char*, 256);
869 if (!ctx->lmodule->bb_names [bb->block_num]) {
872 n = g_strdup_printf ("BB%d", bb->block_num);
873 mono_memory_barrier ();
874 ctx->lmodule->bb_names [bb->block_num] = n;
876 bb_name = ctx->lmodule->bb_names [bb->block_num];
878 sprintf (bb_name_buf, "BB%d", bb->block_num);
879 bb_name = bb_name_buf;
882 ctx->bblocks [bb->block_num].bblock = LLVMAppendBasicBlock (ctx->lmethod, bb_name);
883 ctx->bblocks [bb->block_num].end_bblock = ctx->bblocks [bb->block_num].bblock;
886 return ctx->bblocks [bb->block_num].bblock;
892 * Return the last LLVM bblock corresponding to BB.
893 * This might not be equal to the bb returned by get_bb () since we need to generate
894 * multiple LLVM bblocks for a mono bblock to handle throwing exceptions.
896 static LLVMBasicBlockRef
897 get_end_bb (EmitContext *ctx, MonoBasicBlock *bb)
900 return ctx->bblocks [bb->block_num].end_bblock;
903 static LLVMBasicBlockRef
904 gen_bb (EmitContext *ctx, const char *prefix)
908 sprintf (bb_name, "%s%d", prefix, ++ ctx->ex_index);
909 return LLVMAppendBasicBlock (ctx->lmethod, bb_name);
915 * Return the target of the patch identified by TYPE and TARGET.
918 resolve_patch (MonoCompile *cfg, MonoJumpInfoType type, gconstpointer target)
922 memset (&ji, 0, sizeof (ji));
924 ji.data.target = target;
926 return mono_resolve_patch_target (cfg->method, cfg->domain, NULL, &ji, FALSE);
932 * Emit code to convert the LLVM value V to DTYPE.
935 convert_full (EmitContext *ctx, LLVMValueRef v, LLVMTypeRef dtype, gboolean is_unsigned)
937 LLVMTypeRef stype = LLVMTypeOf (v);
939 if (stype != dtype) {
940 gboolean ext = FALSE;
943 if (dtype == LLVMInt64Type () && (stype == LLVMInt32Type () || stype == LLVMInt16Type () || stype == LLVMInt8Type ()))
945 else if (dtype == LLVMInt32Type () && (stype == LLVMInt16Type () || stype == LLVMInt8Type ()))
947 else if (dtype == LLVMInt16Type () && (stype == LLVMInt8Type ()))
951 return is_unsigned ? LLVMBuildZExt (ctx->builder, v, dtype, "") : LLVMBuildSExt (ctx->builder, v, dtype, "");
953 if (dtype == LLVMDoubleType () && stype == LLVMFloatType ())
954 return LLVMBuildFPExt (ctx->builder, v, dtype, "");
957 if (stype == LLVMInt64Type () && (dtype == LLVMInt32Type () || dtype == LLVMInt16Type () || dtype == LLVMInt8Type ()))
958 return LLVMBuildTrunc (ctx->builder, v, dtype, "");
959 if (stype == LLVMInt32Type () && (dtype == LLVMInt16Type () || dtype == LLVMInt8Type ()))
960 return LLVMBuildTrunc (ctx->builder, v, dtype, "");
961 if (stype == LLVMInt16Type () && dtype == LLVMInt8Type ())
962 return LLVMBuildTrunc (ctx->builder, v, dtype, "");
963 if (stype == LLVMDoubleType () && dtype == LLVMFloatType ())
964 return LLVMBuildFPTrunc (ctx->builder, v, dtype, "");
966 if (LLVMGetTypeKind (stype) == LLVMPointerTypeKind && LLVMGetTypeKind (dtype) == LLVMPointerTypeKind)
967 return LLVMBuildBitCast (ctx->builder, v, dtype, "");
968 if (LLVMGetTypeKind (dtype) == LLVMPointerTypeKind)
969 return LLVMBuildIntToPtr (ctx->builder, v, dtype, "");
970 if (LLVMGetTypeKind (stype) == LLVMPointerTypeKind)
971 return LLVMBuildPtrToInt (ctx->builder, v, dtype, "");
973 if (mono_arch_is_soft_float ()) {
974 if (stype == LLVMInt32Type () && dtype == LLVMFloatType ())
975 return LLVMBuildBitCast (ctx->builder, v, dtype, "");
976 if (stype == LLVMInt32Type () && dtype == LLVMDoubleType ())
977 return LLVMBuildBitCast (ctx->builder, LLVMBuildZExt (ctx->builder, v, LLVMInt64Type (), ""), dtype, "");
980 if (LLVMGetTypeKind (stype) == LLVMVectorTypeKind && LLVMGetTypeKind (dtype) == LLVMVectorTypeKind)
981 return LLVMBuildBitCast (ctx->builder, v, dtype, "");
984 LLVMDumpValue (LLVMConstNull (dtype));
985 g_assert_not_reached ();
993 convert (EmitContext *ctx, LLVMValueRef v, LLVMTypeRef dtype)
995 return convert_full (ctx, v, dtype, FALSE);
999 * emit_volatile_load:
1001 * If vreg is volatile, emit a load from its address.
1004 emit_volatile_load (EmitContext *ctx, int vreg)
1008 LLVMValueRef v = LLVMBuildLoad (ctx->builder, ctx->addresses [vreg], "");
1009 t = ctx->vreg_cli_types [vreg];
1010 if (t && !t->byref) {
1012 * Might have to zero extend since llvm doesn't have
1015 if (t->type == MONO_TYPE_U1 || t->type == MONO_TYPE_U2 || t->type == MONO_TYPE_CHAR || t->type == MONO_TYPE_BOOLEAN)
1016 v = LLVMBuildZExt (ctx->builder, v, LLVMInt32Type (), "");
1017 else if (t->type == MONO_TYPE_U8)
1018 v = LLVMBuildZExt (ctx->builder, v, LLVMInt64Type (), "");
1025 * emit_volatile_store:
1027 * If VREG is volatile, emit a store from its value to its address.
1030 emit_volatile_store (EmitContext *ctx, int vreg)
1032 MonoInst *var = get_vreg_to_inst (ctx->cfg, vreg);
1034 if (var && var->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT)) {
1035 g_assert (ctx->addresses [vreg]);
1036 LLVMBuildStore (ctx->builder, convert (ctx, ctx->values [vreg], type_to_llvm_type (ctx, var->inst_vtype)), ctx->addresses [vreg]);
1042 * Maps parameter indexes in the original signature to parameter indexes
1043 * in the LLVM signature.
1046 /* The indexes of various special arguments in the LLVM signature */
1047 int vret_arg_pindex, this_arg_pindex, rgctx_arg_pindex, imt_arg_pindex;
1051 * sig_to_llvm_sig_full:
1053 * Return the LLVM signature corresponding to the mono signature SIG using the
1054 * calling convention information in CINFO. Return parameter mapping information in SINFO.
1057 sig_to_llvm_sig_full (EmitContext *ctx, MonoMethodSignature *sig, LLVMCallInfo *cinfo,
1060 LLVMTypeRef ret_type;
1061 LLVMTypeRef *param_types = NULL;
1063 int i, j, pindex, vret_arg_pindex = 0;
1065 gboolean vretaddr = FALSE;
1068 memset (sinfo, 0, sizeof (LLVMSigInfo));
1070 ret_type = type_to_llvm_type (ctx, sig->ret);
1071 CHECK_FAILURE (ctx);
1073 if (cinfo && cinfo->ret.storage == LLVMArgVtypeInReg) {
1074 /* LLVM models this by returning an aggregate value */
1075 if (cinfo->ret.pair_storage [0] == LLVMArgInIReg && cinfo->ret.pair_storage [1] == LLVMArgNone) {
1076 LLVMTypeRef members [2];
1078 members [0] = IntPtrType ();
1079 ret_type = LLVMStructType (members, 1, FALSE);
1081 g_assert_not_reached ();
1083 } else if (cinfo && mini_type_is_vtype (ctx->cfg, sig->ret)) {
1084 g_assert (cinfo->ret.storage == LLVMArgVtypeRetAddr);
1086 ret_type = LLVMVoidType ();
1089 pindexes = g_new0 (int, sig->param_count);
1090 param_types = g_new0 (LLVMTypeRef, (sig->param_count * 2) + 3);
1092 if (cinfo && cinfo->rgctx_arg) {
1094 sinfo->rgctx_arg_pindex = pindex;
1095 param_types [pindex] = ctx->lmodule->ptr_type;
1098 if (cinfo && cinfo->imt_arg) {
1100 sinfo->imt_arg_pindex = pindex;
1101 param_types [pindex] = ctx->lmodule->ptr_type;
1105 /* Compute the index in the LLVM signature where the vret arg needs to be passed */
1106 vret_arg_pindex = pindex;
1107 if (cinfo->vret_arg_index == 1) {
1108 /* Add the slots consumed by the first argument */
1109 LLVMArgInfo *ainfo = &cinfo->args [0];
1110 switch (ainfo->storage) {
1111 case LLVMArgVtypeInReg:
1112 for (j = 0; j < 2; ++j) {
1113 if (ainfo->pair_storage [j] == LLVMArgInIReg)
1123 sinfo->vret_arg_pindex = vret_arg_pindex;
1126 if (vretaddr && vret_arg_pindex == pindex)
1127 param_types [pindex ++] = IntPtrType ();
1130 sinfo->this_arg_pindex = pindex;
1131 param_types [pindex ++] = ThisType ();
1133 if (vretaddr && vret_arg_pindex == pindex)
1134 param_types [pindex ++] = IntPtrType ();
1135 for (i = 0; i < sig->param_count; ++i) {
1136 if (vretaddr && vret_arg_pindex == pindex)
1137 param_types [pindex ++] = IntPtrType ();
1138 pindexes [i] = pindex;
1139 if (cinfo && cinfo->args [i + sig->hasthis].storage == LLVMArgVtypeInReg) {
1140 for (j = 0; j < 2; ++j) {
1141 switch (cinfo->args [i + sig->hasthis].pair_storage [j]) {
1143 param_types [pindex ++] = LLVMIntType (sizeof (gpointer) * 8);
1148 g_assert_not_reached ();
1151 } else if (cinfo && cinfo->args [i + sig->hasthis].storage == LLVMArgVtypeByVal) {
1152 param_types [pindex] = type_to_llvm_arg_type (ctx, sig->params [i]);
1153 CHECK_FAILURE (ctx);
1154 param_types [pindex] = LLVMPointerType (param_types [pindex], 0);
1157 param_types [pindex ++] = type_to_llvm_arg_type (ctx, sig->params [i]);
1160 if (vretaddr && vret_arg_pindex == pindex)
1161 param_types [pindex ++] = IntPtrType ();
1163 CHECK_FAILURE (ctx);
1165 res = LLVMFunctionType (ret_type, param_types, pindex, FALSE);
1166 g_free (param_types);
1169 sinfo->pindexes = pindexes;
1177 g_free (param_types);
1183 sig_to_llvm_sig (EmitContext *ctx, MonoMethodSignature *sig)
1185 return sig_to_llvm_sig_full (ctx, sig, NULL, NULL);
1189 * LLVMFunctionType1:
1191 * Create an LLVM function type from the arguments.
1193 static G_GNUC_UNUSED LLVMTypeRef
1194 LLVMFunctionType1(LLVMTypeRef ReturnType,
1195 LLVMTypeRef ParamType1,
1198 LLVMTypeRef param_types [1];
1200 param_types [0] = ParamType1;
1202 return LLVMFunctionType (ReturnType, param_types, 1, IsVarArg);
1206 * LLVMFunctionType2:
1208 * Create an LLVM function type from the arguments.
1210 static G_GNUC_UNUSED LLVMTypeRef
1211 LLVMFunctionType2(LLVMTypeRef ReturnType,
1212 LLVMTypeRef ParamType1,
1213 LLVMTypeRef ParamType2,
1216 LLVMTypeRef param_types [2];
1218 param_types [0] = ParamType1;
1219 param_types [1] = ParamType2;
1221 return LLVMFunctionType (ReturnType, param_types, 2, IsVarArg);
1225 * LLVMFunctionType3:
1227 * Create an LLVM function type from the arguments.
1229 static G_GNUC_UNUSED LLVMTypeRef
1230 LLVMFunctionType3(LLVMTypeRef ReturnType,
1231 LLVMTypeRef ParamType1,
1232 LLVMTypeRef ParamType2,
1233 LLVMTypeRef ParamType3,
1236 LLVMTypeRef param_types [3];
1238 param_types [0] = ParamType1;
1239 param_types [1] = ParamType2;
1240 param_types [2] = ParamType3;
1242 return LLVMFunctionType (ReturnType, param_types, 3, IsVarArg);
1248 * Create an LLVM builder and remember it so it can be freed later.
1250 static LLVMBuilderRef
1251 create_builder (EmitContext *ctx)
1253 LLVMBuilderRef builder = LLVMCreateBuilder ();
1255 ctx->builders = g_slist_prepend_mempool (ctx->cfg->mempool, ctx->builders, builder);
1261 get_plt_entry (EmitContext *ctx, LLVMTypeRef llvm_sig, MonoJumpInfoType type, gconstpointer data)
1263 char *callee_name = mono_aot_get_plt_symbol (type, data);
1264 LLVMValueRef callee;
1269 if (ctx->cfg->compile_aot)
1270 /* Add a patch so referenced wrappers can be compiled in full aot mode */
1271 mono_add_patch_info (ctx->cfg, 0, type, data);
1274 callee = g_hash_table_lookup (ctx->lmodule->plt_entries, callee_name);
1276 callee = LLVMAddFunction (ctx->module, callee_name, llvm_sig);
1278 LLVMSetVisibility (callee, LLVMHiddenVisibility);
1280 g_hash_table_insert (ctx->lmodule->plt_entries, (char*)callee_name, callee);
1287 get_handler_clause (MonoCompile *cfg, MonoBasicBlock *bb)
1289 MonoMethodHeader *header = cfg->header;
1290 MonoExceptionClause *clause;
1294 if (bb->region != -1 && MONO_BBLOCK_IS_IN_REGION (bb, MONO_REGION_TRY))
1295 return (bb->region >> 8) - 1;
1298 for (i = 0; i < header->num_clauses; ++i) {
1299 clause = &header->clauses [i];
1301 if (MONO_OFFSET_IN_CLAUSE (clause, bb->real_offset) && clause->flags == MONO_EXCEPTION_CLAUSE_NONE)
1309 set_metadata_flag (LLVMValueRef v, const char *flag_name)
1311 LLVMValueRef md_arg;
1314 md_kind = LLVMGetMDKindID (flag_name, strlen (flag_name));
1315 md_arg = LLVMMDString ("mono", 4);
1316 LLVMSetMetadata (v, md_kind, LLVMMDNode (&md_arg, 1));
1320 set_invariant_load_flag (LLVMValueRef v)
1322 LLVMValueRef md_arg;
1324 const char *flag_name;
1326 // FIXME: Cache this
1327 flag_name = "invariant.load";
1328 md_kind = LLVMGetMDKindID (flag_name, strlen (flag_name));
1329 md_arg = LLVMMDString ("<index>", strlen ("<index>"));
1330 LLVMSetMetadata (v, md_kind, LLVMMDNode (&md_arg, 1));
1336 * Emit an LLVM call or invoke instruction depending on whenever the call is inside
1340 emit_call (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, LLVMValueRef callee, LLVMValueRef *args, int pindex)
1342 MonoCompile *cfg = ctx->cfg;
1344 LLVMBuilderRef builder = *builder_ref;
1347 clause_index = get_handler_clause (cfg, bb);
1349 if (clause_index != -1) {
1350 MonoMethodHeader *header = cfg->header;
1351 MonoExceptionClause *ec = &header->clauses [clause_index];
1352 MonoBasicBlock *tblock;
1353 LLVMBasicBlockRef ex_bb, noex_bb;
1356 * Have to use an invoke instead of a call, branching to the
1357 * handler bblock of the clause containing this bblock.
1360 g_assert (ec->flags == MONO_EXCEPTION_CLAUSE_NONE || ec->flags == MONO_EXCEPTION_CLAUSE_FINALLY);
1362 tblock = cfg->cil_offset_to_bb [ec->handler_offset];
1365 ctx->bblocks [tblock->block_num].invoke_target = TRUE;
1367 ex_bb = get_bb (ctx, tblock);
1369 noex_bb = gen_bb (ctx, "NOEX_BB");
1372 lcall = LLVMBuildInvoke (builder, callee, args, pindex, noex_bb, ex_bb, "");
1374 builder = ctx->builder = create_builder (ctx);
1375 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
1377 ctx->bblocks [bb->block_num].end_bblock = noex_bb;
1379 lcall = LLVMBuildCall (builder, callee, args, pindex, "");
1380 ctx->builder = builder;
1383 *builder_ref = ctx->builder;
1389 emit_load (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, int size, LLVMValueRef addr, const char *name, gboolean is_faulting)
1391 const char *intrins_name;
1392 LLVMValueRef args [16], res;
1393 LLVMTypeRef addr_type;
1395 if (is_faulting && bb->region != -1) {
1397 * We handle loads which can fault by calling a mono specific intrinsic
1398 * using an invoke, so they are handled properly inside try blocks.
1399 * We can't use this outside clauses, since LLVM optimizes intrinsics which
1400 * are marked with IntrReadArgMem.
1404 intrins_name = "llvm.mono.load.i8.p0i8";
1407 intrins_name = "llvm.mono.load.i16.p0i16";
1410 intrins_name = "llvm.mono.load.i32.p0i32";
1413 intrins_name = "llvm.mono.load.i64.p0i64";
1416 g_assert_not_reached ();
1419 addr_type = LLVMTypeOf (addr);
1420 if (addr_type == LLVMPointerType (LLVMDoubleType (), 0) || addr_type == LLVMPointerType (LLVMFloatType (), 0))
1421 addr = LLVMBuildBitCast (*builder_ref, addr, LLVMPointerType (LLVMIntType (size * 8), 0), "");
1424 args [1] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
1425 args [2] = LLVMConstInt (LLVMInt1Type (), TRUE, FALSE);
1426 res = emit_call (ctx, bb, builder_ref, LLVMGetNamedFunction (ctx->module, intrins_name), args, 3);
1428 if (addr_type == LLVMPointerType (LLVMDoubleType (), 0))
1429 res = LLVMBuildBitCast (*builder_ref, res, LLVMDoubleType (), "");
1430 else if (addr_type == LLVMPointerType (LLVMFloatType (), 0))
1431 res = LLVMBuildBitCast (*builder_ref, res, LLVMFloatType (), "");
1438 * We emit volatile loads for loads which can fault, because otherwise
1439 * LLVM will generate invalid code when encountering a load from a
1442 res = mono_llvm_build_load (*builder_ref, addr, name, is_faulting);
1444 /* Mark it with a custom metadata */
1447 set_metadata_flag (res, "mono.faulting.load");
1455 emit_store (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, int size, LLVMValueRef value, LLVMValueRef addr, gboolean is_faulting)
1457 const char *intrins_name;
1458 LLVMValueRef args [16];
1460 if (is_faulting && bb->region != -1) {
1463 intrins_name = "llvm.mono.store.i8.p0i8";
1466 intrins_name = "llvm.mono.store.i16.p0i16";
1469 intrins_name = "llvm.mono.store.i32.p0i32";
1472 intrins_name = "llvm.mono.store.i64.p0i64";
1475 g_assert_not_reached ();
1478 if (LLVMTypeOf (value) == LLVMDoubleType () || LLVMTypeOf (value) == LLVMFloatType ()) {
1479 value = LLVMBuildBitCast (*builder_ref, value, LLVMIntType (size * 8), "");
1480 addr = LLVMBuildBitCast (*builder_ref, addr, LLVMPointerType (LLVMIntType (size * 8), 0), "");
1485 args [2] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
1486 args [3] = LLVMConstInt (LLVMInt1Type (), TRUE, FALSE);
1487 emit_call (ctx, bb, builder_ref, LLVMGetNamedFunction (ctx->module, intrins_name), args, 4);
1489 LLVMBuildStore (*builder_ref, value, addr);
1494 * emit_cond_system_exception:
1496 * Emit code to throw the exception EXC_TYPE if the condition CMP is false.
1497 * Might set the ctx exception.
1500 emit_cond_system_exception (EmitContext *ctx, MonoBasicBlock *bb, const char *exc_type, LLVMValueRef cmp)
1502 LLVMBasicBlockRef ex_bb, noex_bb;
1503 LLVMBuilderRef builder;
1504 MonoClass *exc_class;
1505 LLVMValueRef args [2];
1507 ex_bb = gen_bb (ctx, "EX_BB");
1508 noex_bb = gen_bb (ctx, "NOEX_BB");
1510 LLVMBuildCondBr (ctx->builder, cmp, ex_bb, noex_bb);
1512 exc_class = mono_class_from_name (mono_get_corlib (), "System", exc_type);
1513 g_assert (exc_class);
1515 /* Emit exception throwing code */
1516 builder = create_builder (ctx);
1517 LLVMPositionBuilderAtEnd (builder, ex_bb);
1519 if (!ctx->lmodule->throw_corlib_exception) {
1520 LLVMValueRef callee;
1522 const char *icall_name;
1524 MonoMethodSignature *throw_sig = mono_metadata_signature_alloc (mono_get_corlib (), 2);
1525 throw_sig->ret = &mono_get_void_class ()->byval_arg;
1526 throw_sig->params [0] = &mono_get_int32_class ()->byval_arg;
1527 icall_name = "llvm_throw_corlib_exception_abs_trampoline";
1528 /* This will become i8* */
1529 throw_sig->params [1] = &mono_get_byte_class ()->this_arg;
1530 sig = sig_to_llvm_sig (ctx, throw_sig);
1532 if (ctx->cfg->compile_aot) {
1533 callee = get_plt_entry (ctx, sig, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
1535 callee = LLVMAddFunction (ctx->module, "llvm_throw_corlib_exception_trampoline", sig_to_llvm_sig (ctx, throw_sig));
1538 * Differences between the LLVM/non-LLVM throw corlib exception trampoline:
1539 * - On x86, LLVM generated code doesn't push the arguments
1540 * - The trampoline takes the throw address as an arguments, not a pc offset.
1542 LLVMAddGlobalMapping (ee, callee, resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name));
1545 mono_memory_barrier ();
1546 ctx->lmodule->throw_corlib_exception = callee;
1549 if (IS_TARGET_X86 || IS_TARGET_AMD64)
1550 args [0] = LLVMConstInt (LLVMInt32Type (), exc_class->type_token - MONO_TOKEN_TYPE_DEF, FALSE);
1552 args [0] = LLVMConstInt (LLVMInt32Type (), exc_class->type_token, FALSE);
1555 * The LLVM mono branch contains changes so a block address can be passed as an
1556 * argument to a call.
1558 args [1] = LLVMBlockAddress (ctx->lmethod, ex_bb);
1559 emit_call (ctx, bb, &builder, ctx->lmodule->throw_corlib_exception, args, 2);
1561 LLVMBuildUnreachable (builder);
1563 ctx->builder = create_builder (ctx);
1564 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
1566 ctx->bblocks [bb->block_num].end_bblock = noex_bb;
1573 * emit_reg_to_vtype:
1575 * Emit code to store the vtype in the registers REGS to the address ADDRESS.
1578 emit_reg_to_vtype (EmitContext *ctx, LLVMBuilderRef builder, MonoType *t, LLVMValueRef address, LLVMArgInfo *ainfo, LLVMValueRef *regs)
1582 size = get_vtype_size (t);
1584 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (t))) {
1585 address = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (LLVMInt8Type (), 0), "");
1588 for (j = 0; j < 2; ++j) {
1589 LLVMValueRef index [2], addr;
1590 int part_size = size > sizeof (gpointer) ? sizeof (gpointer) : size;
1591 LLVMTypeRef part_type;
1593 if (ainfo->pair_storage [j] == LLVMArgNone)
1596 part_type = LLVMIntType (part_size * 8);
1597 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (t))) {
1598 index [0] = LLVMConstInt (LLVMInt32Type (), j * sizeof (gpointer), FALSE);
1599 addr = LLVMBuildGEP (builder, address, index, 1, "");
1601 index [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
1602 index [1] = LLVMConstInt (LLVMInt32Type (), j * sizeof (gpointer), FALSE);
1603 addr = LLVMBuildGEP (builder, address, index, 2, "");
1605 switch (ainfo->pair_storage [j]) {
1607 LLVMBuildStore (builder, convert (ctx, regs [j], part_type), LLVMBuildBitCast (ctx->builder, addr, LLVMPointerType (part_type, 0), ""));
1612 g_assert_not_reached ();
1615 size -= sizeof (gpointer);
1620 * emit_vtype_to_reg:
1622 * Emit code to load a vtype at address ADDRESS into registers. Store the registers
1623 * into REGS, and the number of registers into NREGS.
1626 emit_vtype_to_reg (EmitContext *ctx, LLVMBuilderRef builder, MonoType *t, LLVMValueRef address, LLVMArgInfo *ainfo, LLVMValueRef *regs, guint32 *nregs)
1631 size = get_vtype_size (t);
1633 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (t))) {
1634 address = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (LLVMInt8Type (), 0), "");
1637 for (j = 0; j < 2; ++j) {
1638 LLVMValueRef index [2], addr;
1639 int partsize = size > sizeof (gpointer) ? sizeof (gpointer) : size;
1641 if (ainfo->pair_storage [j] == LLVMArgNone)
1644 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (t))) {
1645 index [0] = LLVMConstInt (LLVMInt32Type (), j * sizeof (gpointer), FALSE);
1646 addr = LLVMBuildGEP (builder, address, index, 1, "");
1648 index [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
1649 index [1] = LLVMConstInt (LLVMInt32Type (), j * sizeof (gpointer), FALSE);
1650 addr = LLVMBuildGEP (builder, address, index, 2, "");
1652 switch (ainfo->pair_storage [j]) {
1654 regs [pindex ++] = convert (ctx, LLVMBuildLoad (builder, LLVMBuildBitCast (ctx->builder, addr, LLVMPointerType (LLVMIntType (partsize * 8), 0), ""), ""), IntPtrType ());
1659 g_assert_not_reached ();
1661 size -= sizeof (gpointer);
1668 build_alloca_llvm_type (EmitContext *ctx, LLVMTypeRef t, int align)
1671 * Have to place all alloca's at the end of the entry bb, since otherwise they would
1672 * get executed every time control reaches them.
1674 LLVMPositionBuilder (ctx->alloca_builder, get_bb (ctx, ctx->cfg->bb_entry), ctx->last_alloca);
1676 ctx->last_alloca = mono_llvm_build_alloca (ctx->alloca_builder, t, NULL, align, "");
1677 return ctx->last_alloca;
1681 build_alloca (EmitContext *ctx, MonoType *t)
1683 MonoClass *k = mono_class_from_mono_type (t);
1686 if (MONO_CLASS_IS_SIMD (ctx->cfg, k))
1689 align = mono_class_min_align (k);
1691 /* Sometimes align is not a power of 2 */
1692 while (mono_is_power_of_two (align) == -1)
1695 return build_alloca_llvm_type (ctx, type_to_llvm_type (ctx, t), align);
1699 * Put the global into the 'llvm.used' array to prevent it from being optimized away.
1702 mark_as_used (MonoLLVMModule *lmodule, LLVMValueRef global)
1705 lmodule->used = g_ptr_array_sized_new (16);
1706 g_ptr_array_add (lmodule->used, global);
1710 emit_llvm_used (MonoLLVMModule *lmodule)
1712 LLVMModuleRef module = lmodule->module;
1713 LLVMTypeRef used_type;
1714 LLVMValueRef used, *used_elem;
1720 used_type = LLVMArrayType (LLVMPointerType (LLVMInt8Type (), 0), lmodule->used->len);
1721 used = LLVMAddGlobal (module, used_type, "llvm.used");
1722 used_elem = g_new0 (LLVMValueRef, lmodule->used->len);
1723 for (i = 0; i < lmodule->used->len; ++i)
1724 used_elem [i] = LLVMConstBitCast (g_ptr_array_index (lmodule->used, i), LLVMPointerType (LLVMInt8Type (), 0));
1725 LLVMSetInitializer (used, LLVMConstArray (LLVMPointerType (LLVMInt8Type (), 0), used_elem, lmodule->used->len));
1726 LLVMSetLinkage (used, LLVMAppendingLinkage);
1727 LLVMSetSection (used, "llvm.metadata");
1733 * Emit code to load/convert arguments.
1736 emit_entry_bb (EmitContext *ctx, LLVMBuilderRef builder)
1739 MonoCompile *cfg = ctx->cfg;
1740 MonoMethodSignature *sig = ctx->sig;
1741 LLVMCallInfo *linfo = ctx->linfo;
1744 ctx->alloca_builder = create_builder (ctx);
1747 * Handle indirect/volatile variables by allocating memory for them
1748 * using 'alloca', and storing their address in a temporary.
1750 for (i = 0; i < cfg->num_varinfo; ++i) {
1751 MonoInst *var = cfg->varinfo [i];
1754 if (var->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT) || mini_type_is_vtype (cfg, var->inst_vtype)) {
1755 vtype = type_to_llvm_type (ctx, var->inst_vtype);
1756 CHECK_FAILURE (ctx);
1757 /* Could be already created by an OP_VPHI */
1758 if (!ctx->addresses [var->dreg])
1759 ctx->addresses [var->dreg] = build_alloca (ctx, var->inst_vtype);
1760 ctx->vreg_cli_types [var->dreg] = var->inst_vtype;
1764 for (i = 0; i < sig->param_count; ++i) {
1765 LLVMArgInfo *ainfo = &linfo->args [i + sig->hasthis];
1766 int reg = cfg->args [i + sig->hasthis]->dreg;
1768 if (ainfo->storage == LLVMArgVtypeInReg) {
1769 LLVMValueRef regs [2];
1772 * Emit code to save the argument from the registers to
1773 * the real argument.
1775 pindex = ctx->pindexes [i];
1776 regs [0] = LLVMGetParam (ctx->lmethod, pindex);
1777 if (ainfo->pair_storage [1] != LLVMArgNone)
1778 regs [1] = LLVMGetParam (ctx->lmethod, pindex + 1);
1782 ctx->addresses [reg] = build_alloca (ctx, sig->params [i]);
1784 emit_reg_to_vtype (ctx, builder, sig->params [i], ctx->addresses [reg], ainfo, regs);
1786 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (sig->params [i]))) {
1787 /* Treat these as normal values */
1788 ctx->values [reg] = LLVMBuildLoad (builder, ctx->addresses [reg], "");
1790 } else if (ainfo->storage == LLVMArgVtypeByVal) {
1791 ctx->addresses [reg] = LLVMGetParam (ctx->lmethod, ctx->pindexes [i]);
1793 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (sig->params [i]))) {
1794 /* Treat these as normal values */
1795 ctx->values [reg] = LLVMBuildLoad (builder, ctx->addresses [reg], "");
1798 ctx->values [reg] = convert (ctx, ctx->values [reg], llvm_type_to_stack_type (type_to_llvm_type (ctx, sig->params [i])));
1803 emit_volatile_store (ctx, cfg->vret_addr->dreg);
1805 emit_volatile_store (ctx, cfg->args [0]->dreg);
1806 for (i = 0; i < sig->param_count; ++i)
1807 if (!mini_type_is_vtype (cfg, sig->params [i]))
1808 emit_volatile_store (ctx, cfg->args [i + sig->hasthis]->dreg);
1810 if (sig->hasthis && !cfg->rgctx_var && cfg->generic_sharing_context) {
1811 LLVMValueRef this_alloc;
1814 * The exception handling code needs the location where the this argument was
1815 * stored for gshared methods. We create a separate alloca to hold it, and mark it
1816 * with the "mono.this" custom metadata to tell llvm that it needs to save its
1817 * location into the LSDA.
1819 this_alloc = mono_llvm_build_alloca (builder, ThisType (), LLVMConstInt (LLVMInt32Type (), 1, FALSE), 0, "");
1820 /* This volatile store will keep the alloca alive */
1821 mono_llvm_build_store (builder, ctx->values [cfg->args [0]->dreg], this_alloc, TRUE);
1823 set_metadata_flag (this_alloc, "mono.this");
1826 if (cfg->rgctx_var) {
1827 LLVMValueRef rgctx_alloc, store;
1830 * We handle the rgctx arg similarly to the this pointer.
1832 g_assert (ctx->addresses [cfg->rgctx_var->dreg]);
1833 rgctx_alloc = ctx->addresses [cfg->rgctx_var->dreg];
1834 /* This volatile store will keep the alloca alive */
1835 store = mono_llvm_build_store (builder, convert (ctx, ctx->rgctx_arg, IntPtrType ()), rgctx_alloc, TRUE);
1837 set_metadata_flag (rgctx_alloc, "mono.this");
1841 * For finally clauses, create an indicator variable telling OP_ENDFINALLY whenever
1842 * it needs to continue normally, or return back to the exception handling system.
1844 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
1845 if (bb->region != -1 && (bb->flags & BB_EXCEPTION_HANDLER))
1846 g_hash_table_insert (ctx->region_to_handler, GUINT_TO_POINTER (mono_get_block_region_notry (cfg, bb->region)), bb);
1847 if (bb->region != -1 && (bb->flags & BB_EXCEPTION_HANDLER) && bb->in_scount == 0) {
1851 sprintf (name, "finally_ind_bb%d", bb->block_num);
1852 val = LLVMBuildAlloca (builder, LLVMInt32Type (), name);
1853 LLVMBuildStore (builder, LLVMConstInt (LLVMInt32Type (), 0, FALSE), val);
1855 ctx->bblocks [bb->block_num].finally_ind = val;
1858 * Create a new bblock which CALL_HANDLER can branch to, because branching to the
1859 * LLVM bblock containing the call to llvm.eh.selector causes problems for the
1860 * LLVM optimizer passes.
1862 sprintf (name, "BB_%d_CALL_HANDLER_TARGET", bb->block_num);
1863 ctx->bblocks [bb->block_num].call_handler_target_bb = LLVMAppendBasicBlock (ctx->lmethod, name);
1871 /* Have to export this for AOT */
1873 mono_personality (void);
1876 mono_personality (void)
1879 g_assert_not_reached ();
1883 process_call (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, MonoInst *ins)
1885 MonoCompile *cfg = ctx->cfg;
1886 LLVMModuleRef module = ctx->module;
1887 LLVMValueRef *values = ctx->values;
1888 LLVMValueRef *addresses = ctx->addresses;
1889 MonoCallInst *call = (MonoCallInst*)ins;
1890 MonoMethodSignature *sig = call->signature;
1891 LLVMValueRef callee = NULL, lcall;
1893 LLVMCallInfo *cinfo;
1897 LLVMTypeRef llvm_sig;
1899 gboolean virtual, calli;
1900 LLVMBuilderRef builder = *builder_ref;
1903 if (call->signature->call_convention != MONO_CALL_DEFAULT)
1904 LLVM_FAILURE (ctx, "non-default callconv");
1906 cinfo = call->cinfo;
1907 if (call->rgctx_arg_reg)
1908 cinfo->rgctx_arg = TRUE;
1909 if (call->imt_arg_reg)
1910 cinfo->imt_arg = TRUE;
1912 vretaddr = cinfo && cinfo->ret.storage == LLVMArgVtypeRetAddr;
1914 llvm_sig = sig_to_llvm_sig_full (ctx, sig, cinfo, &sinfo);
1915 CHECK_FAILURE (ctx);
1917 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);
1918 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);
1920 /* FIXME: Avoid creating duplicate methods */
1922 if (ins->flags & MONO_INST_HAS_METHOD) {
1926 if (cfg->compile_aot) {
1927 callee = get_plt_entry (ctx, llvm_sig, MONO_PATCH_INFO_METHOD, call->method);
1929 LLVM_FAILURE (ctx, "can't encode patch");
1931 callee = LLVMAddFunction (module, "", llvm_sig);
1934 mono_create_jit_trampoline_in_domain (mono_domain_get (),
1936 LLVMAddGlobalMapping (ee, callee, target);
1940 if (call->method && strstr (call->method->klass->name, "AsyncVoidMethodBuilder"))
1941 /* LLVM miscompiles async methods */
1942 LLVM_FAILURE (ctx, "#13734");
1945 MonoJitICallInfo *info = mono_find_jit_icall_by_addr (call->fptr);
1951 memset (&ji, 0, sizeof (ji));
1952 ji.type = MONO_PATCH_INFO_JIT_ICALL_ADDR;
1953 ji.data.target = info->name;
1955 target = mono_resolve_patch_target (cfg->method, cfg->domain, NULL, &ji, FALSE);
1957 if (cfg->compile_aot) {
1958 callee = get_plt_entry (ctx, llvm_sig, MONO_PATCH_INFO_INTERNAL_METHOD, (char*)info->name);
1960 LLVM_FAILURE (ctx, "can't encode patch");
1962 callee = LLVMAddFunction (module, "", llvm_sig);
1963 target = (gpointer)mono_icall_get_wrapper (info);
1964 LLVMAddGlobalMapping (ee, callee, target);
1967 if (cfg->compile_aot) {
1969 if (cfg->abs_patches) {
1970 MonoJumpInfo *abs_ji = g_hash_table_lookup (cfg->abs_patches, call->fptr);
1972 callee = get_plt_entry (ctx, llvm_sig, abs_ji->type, abs_ji->data.target);
1974 LLVM_FAILURE (ctx, "can't encode patch");
1978 LLVM_FAILURE (ctx, "aot");
1980 callee = LLVMAddFunction (module, "", llvm_sig);
1982 if (cfg->abs_patches) {
1983 MonoJumpInfo *abs_ji = g_hash_table_lookup (cfg->abs_patches, call->fptr);
1986 * FIXME: Some trampolines might have
1987 * their own calling convention on some platforms.
1989 #ifndef TARGET_AMD64
1990 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)
1991 LLVM_FAILURE (ctx, "trampoline with own cconv");
1993 target = mono_resolve_patch_target (cfg->method, cfg->domain, NULL, abs_ji, FALSE);
1994 LLVMAddGlobalMapping (ee, callee, target);
1998 LLVMAddGlobalMapping (ee, callee, (gpointer)call->fptr);
2004 int size = sizeof (gpointer);
2007 g_assert (ins->inst_offset % size == 0);
2008 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
2010 callee = convert (ctx, LLVMBuildLoad (builder, LLVMBuildGEP (builder, convert (ctx, values [ins->inst_basereg], LLVMPointerType (LLVMPointerType (IntPtrType (), 0), 0)), &index, 1, ""), ""), LLVMPointerType (llvm_sig, 0));
2012 callee = convert (ctx, values [ins->sreg1], LLVMPointerType (llvm_sig, 0));
2014 if (ins->flags & MONO_INST_HAS_METHOD) {
2019 * Collect and convert arguments
2021 nargs = (sig->param_count * 2) + sig->hasthis + vretaddr + call->rgctx_reg + call->imt_arg_reg;
2022 len = sizeof (LLVMValueRef) * nargs;
2023 args = alloca (len);
2024 memset (args, 0, len);
2025 l = call->out_ireg_args;
2027 if (call->rgctx_arg_reg) {
2028 g_assert (values [call->rgctx_arg_reg]);
2029 g_assert (sinfo.rgctx_arg_pindex < nargs);
2031 * On ARM, the imt/rgctx argument is passed in a caller save register, but some of our trampolines etc. clobber it, leading to
2032 * problems is LLVM moves the arg assignment earlier. To work around this, save the argument into a stack slot and load
2033 * it using a volatile load.
2036 if (!ctx->imt_rgctx_loc)
2037 ctx->imt_rgctx_loc = build_alloca_llvm_type (ctx, ctx->lmodule->ptr_type, sizeof (gpointer));
2038 LLVMBuildStore (builder, convert (ctx, ctx->values [call->rgctx_arg_reg], ctx->lmodule->ptr_type), ctx->imt_rgctx_loc);
2039 args [sinfo.rgctx_arg_pindex] = mono_llvm_build_load (builder, ctx->imt_rgctx_loc, "", TRUE);
2041 args [sinfo.rgctx_arg_pindex] = convert (ctx, values [call->rgctx_arg_reg], ctx->lmodule->ptr_type);
2044 if (call->imt_arg_reg) {
2045 g_assert (values [call->imt_arg_reg]);
2046 g_assert (sinfo.imt_arg_pindex < nargs);
2048 if (!ctx->imt_rgctx_loc)
2049 ctx->imt_rgctx_loc = build_alloca_llvm_type (ctx, ctx->lmodule->ptr_type, sizeof (gpointer));
2050 LLVMBuildStore (builder, convert (ctx, ctx->values [call->imt_arg_reg], ctx->lmodule->ptr_type), ctx->imt_rgctx_loc);
2051 args [sinfo.imt_arg_pindex] = mono_llvm_build_load (builder, ctx->imt_rgctx_loc, "", TRUE);
2053 args [sinfo.imt_arg_pindex] = convert (ctx, values [call->imt_arg_reg], ctx->lmodule->ptr_type);
2058 if (!addresses [call->inst.dreg])
2059 addresses [call->inst.dreg] = build_alloca (ctx, sig->ret);
2060 g_assert (sinfo.vret_arg_pindex < nargs);
2061 args [sinfo.vret_arg_pindex] = LLVMBuildPtrToInt (builder, addresses [call->inst.dreg], IntPtrType (), "");
2064 for (i = 0; i < sig->param_count + sig->hasthis; ++i) {
2067 LLVMArgInfo *ainfo = call->cinfo ? &call->cinfo->args [i] : NULL;
2071 pindex = sinfo.this_arg_pindex;
2073 pindex = sinfo.pindexes [i - 1];
2075 pindex = sinfo.pindexes [i];
2078 regpair = (guint32)(gssize)(l->data);
2079 reg = regpair & 0xffffff;
2080 args [pindex] = values [reg];
2081 if (ainfo->storage == LLVMArgVtypeInReg) {
2083 LLVMValueRef regs [2];
2088 g_assert (addresses [reg]);
2090 emit_vtype_to_reg (ctx, builder, sig->params [i - sig->hasthis], addresses [reg], ainfo, regs, &nregs);
2091 for (j = 0; j < nregs; ++j)
2092 args [pindex ++] = regs [j];
2095 // FIXME: Get rid of the VMOVE
2096 } else if (ainfo->storage == LLVMArgVtypeByVal) {
2097 g_assert (addresses [reg]);
2098 args [pindex] = addresses [reg];
2100 g_assert (args [pindex]);
2101 if (i == 0 && sig->hasthis)
2102 args [pindex] = convert (ctx, args [pindex], ThisType ());
2104 args [pindex] = convert (ctx, args [pindex], type_to_llvm_arg_type (ctx, sig->params [i - sig->hasthis]));
2110 // FIXME: Align call sites
2116 lcall = emit_call (ctx, bb, &builder, callee, args, LLVMCountParamTypes (llvm_sig));
2119 * Modify cconv and parameter attributes to pass rgctx/imt correctly.
2121 #if defined(MONO_ARCH_IMT_REG) && defined(MONO_ARCH_RGCTX_REG)
2122 g_assert (MONO_ARCH_IMT_REG == MONO_ARCH_RGCTX_REG);
2124 /* The two can't be used together, so use only one LLVM calling conv to pass them */
2125 g_assert (!(call->rgctx_arg_reg && call->imt_arg_reg));
2127 LLVMSetInstructionCallConv (lcall, LLVMMono1CallConv);
2129 if (call->rgctx_arg_reg)
2130 LLVMAddInstrAttribute (lcall, 1 + sinfo.rgctx_arg_pindex, LLVMInRegAttribute);
2131 if (call->imt_arg_reg)
2132 LLVMAddInstrAttribute (lcall, 1 + sinfo.imt_arg_pindex, LLVMInRegAttribute);
2134 /* Add byval attributes if needed */
2135 for (i = 0; i < sig->param_count; ++i) {
2136 LLVMArgInfo *ainfo = call->cinfo ? &call->cinfo->args [i + sig->hasthis] : NULL;
2138 if (ainfo && ainfo->storage == LLVMArgVtypeByVal) {
2139 LLVMAddInstrAttribute (lcall, 1 + sinfo.pindexes [i], LLVMByValAttribute);
2144 * Convert the result
2146 if (cinfo && cinfo->ret.storage == LLVMArgVtypeInReg) {
2147 LLVMValueRef regs [2];
2149 if (!addresses [ins->dreg])
2150 addresses [ins->dreg] = build_alloca (ctx, sig->ret);
2152 regs [0] = LLVMBuildExtractValue (builder, lcall, 0, "");
2153 if (cinfo->ret.pair_storage [1] != LLVMArgNone)
2154 regs [1] = LLVMBuildExtractValue (builder, lcall, 1, "");
2156 emit_reg_to_vtype (ctx, builder, sig->ret, addresses [ins->dreg], &cinfo->ret, regs);
2157 } else if (sig->ret->type != MONO_TYPE_VOID && !vretaddr) {
2158 /* If the method returns an unsigned value, need to zext it */
2160 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));
2163 *builder_ref = ctx->builder;
2165 g_free (sinfo.pindexes);
2173 process_bb (EmitContext *ctx, MonoBasicBlock *bb)
2175 MonoCompile *cfg = ctx->cfg;
2176 MonoMethodSignature *sig = ctx->sig;
2177 LLVMValueRef method = ctx->lmethod;
2178 LLVMValueRef *values = ctx->values;
2179 LLVMValueRef *addresses = ctx->addresses;
2181 LLVMCallInfo *linfo = ctx->linfo;
2182 LLVMModuleRef module = ctx->module;
2183 BBInfo *bblocks = ctx->bblocks;
2185 LLVMBasicBlockRef cbb;
2186 LLVMBuilderRef builder, starting_builder;
2187 gboolean has_terminator;
2189 LLVMValueRef lhs, rhs;
2192 cbb = get_bb (ctx, bb);
2193 builder = create_builder (ctx);
2194 ctx->builder = builder;
2195 LLVMPositionBuilderAtEnd (builder, cbb);
2197 if (bb == cfg->bb_entry)
2198 emit_entry_bb (ctx, builder);
2199 CHECK_FAILURE (ctx);
2201 if (bb->flags & BB_EXCEPTION_HANDLER) {
2203 LLVMValueRef personality;
2204 LLVMBasicBlockRef target_bb;
2206 static gint32 mapping_inited;
2207 static int ti_generator;
2210 LLVMValueRef type_info;
2213 if (!bblocks [bb->block_num].invoke_target) {
2215 * LLVM asserts if llvm.eh.selector is called from a bblock which
2216 * doesn't have an invoke pointing at it.
2217 * Update: LLVM no longer asserts, but some tests in exceptions.exe now fail.
2219 LLVM_FAILURE (ctx, "handler without invokes");
2222 // <resultval> = landingpad <somety> personality <type> <pers_fn> <clause>+
2224 if (cfg->compile_aot) {
2225 /* Use a dummy personality function */
2226 personality = LLVMGetNamedFunction (module, "mono_aot_personality");
2227 g_assert (personality);
2229 personality = LLVMGetNamedFunction (module, "mono_personality");
2230 if (InterlockedCompareExchange (&mapping_inited, 1, 0) == 0)
2231 LLVMAddGlobalMapping (ee, personality, mono_personality);
2234 i8ptr = LLVMPointerType (LLVMInt8Type (), 0);
2236 clause_index = (mono_get_block_region_notry (cfg, bb->region) >> 8) - 1;
2239 * Create the type info
2241 sprintf (ti_name, "type_info_%d", ti_generator);
2244 if (cfg->compile_aot) {
2245 /* decode_eh_frame () in aot-runtime.c will decode this */
2246 type_info = LLVMAddGlobal (module, LLVMInt32Type (), ti_name);
2247 LLVMSetInitializer (type_info, LLVMConstInt (LLVMInt32Type (), clause_index, FALSE));
2250 * These symbols are not really used, the clause_index is embedded into the EH tables generated by DwarfMonoException in LLVM.
2252 LLVMSetLinkage (type_info, LLVMInternalLinkage);
2255 * Enabling this causes llc to crash:
2256 * http://llvm.org/bugs/show_bug.cgi?id=6102
2258 //LLVM_FAILURE (ctx, "aot+clauses");
2260 // test_0_invalid_unbox_arrays () fails
2261 LLVM_FAILURE (ctx, "aot+clauses");
2265 * After the cfg mempool is freed, the type info will point to stale memory,
2266 * but this is not a problem, since we decode it once in exception_cb during
2269 ti = mono_mempool_alloc (cfg->mempool, sizeof (gint32));
2270 *(gint32*)ti = clause_index;
2272 type_info = LLVMAddGlobal (module, i8ptr, ti_name);
2274 LLVMAddGlobalMapping (ee, type_info, ti);
2278 LLVMTypeRef members [2], ret_type;
2279 LLVMValueRef landing_pad;
2281 members [0] = i8ptr;
2282 members [1] = LLVMInt32Type ();
2283 ret_type = LLVMStructType (members, 2, FALSE);
2285 landing_pad = LLVMBuildLandingPad (builder, ret_type, personality, 1, "");
2286 LLVMAddClause (landing_pad, type_info);
2288 /* Store the exception into the exvar */
2289 if (bb->in_scount == 1) {
2290 g_assert (bb->in_scount == 1);
2291 exvar = bb->in_stack [0];
2293 // FIXME: This is shared with filter clauses ?
2294 g_assert (!values [exvar->dreg]);
2296 values [exvar->dreg] = LLVMBuildExtractValue (builder, landing_pad, 0, "ex_obj");
2297 emit_volatile_store (ctx, exvar->dreg);
2301 /* Start a new bblock which CALL_HANDLER can branch to */
2302 target_bb = bblocks [bb->block_num].call_handler_target_bb;
2304 LLVMBuildBr (builder, target_bb);
2306 ctx->builder = builder = create_builder (ctx);
2307 LLVMPositionBuilderAtEnd (ctx->builder, target_bb);
2309 ctx->bblocks [bb->block_num].end_bblock = target_bb;
2313 has_terminator = FALSE;
2314 starting_builder = builder;
2315 for (ins = bb->code; ins; ins = ins->next) {
2316 const char *spec = LLVM_INS_INFO (ins->opcode);
2318 char dname_buf [128];
2321 if (nins > 5000 && builder == starting_builder) {
2322 /* some steps in llc are non-linear in the size of basic blocks, see #5714 */
2323 LLVM_FAILURE (ctx, "basic block too long");
2327 /* There could be instructions after a terminator, skip them */
2330 if (spec [MONO_INST_DEST] != ' ' && !MONO_IS_STORE_MEMBASE (ins)) {
2331 sprintf (dname_buf, "t%d", ins->dreg);
2335 if (spec [MONO_INST_SRC1] != ' ' && spec [MONO_INST_SRC1] != 'v') {
2336 MonoInst *var = get_vreg_to_inst (cfg, ins->sreg1);
2338 if (var && var->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT)) {
2339 lhs = emit_volatile_load (ctx, ins->sreg1);
2341 /* It is ok for SETRET to have an uninitialized argument */
2342 if (!values [ins->sreg1] && ins->opcode != OP_SETRET)
2343 LLVM_FAILURE (ctx, "sreg1");
2344 lhs = values [ins->sreg1];
2350 if (spec [MONO_INST_SRC2] != ' ' && spec [MONO_INST_SRC2] != ' ') {
2351 MonoInst *var = get_vreg_to_inst (cfg, ins->sreg2);
2352 if (var && var->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT)) {
2353 rhs = emit_volatile_load (ctx, ins->sreg2);
2355 if (!values [ins->sreg2])
2356 LLVM_FAILURE (ctx, "sreg2");
2357 rhs = values [ins->sreg2];
2363 //mono_print_ins (ins);
2364 switch (ins->opcode) {
2367 case OP_LIVERANGE_START:
2368 case OP_LIVERANGE_END:
2371 values [ins->dreg] = LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE);
2374 #if SIZEOF_VOID_P == 4
2375 values [ins->dreg] = LLVMConstInt (LLVMInt64Type (), GET_LONG_IMM (ins), FALSE);
2377 values [ins->dreg] = LLVMConstInt (LLVMInt64Type (), (gint64)ins->inst_c0, FALSE);
2381 values [ins->dreg] = LLVMConstReal (LLVMDoubleType (), *(double*)ins->inst_p0);
2384 values [ins->dreg] = LLVMConstFPExt (LLVMConstReal (LLVMFloatType (), *(float*)ins->inst_p0), LLVMDoubleType ());
2387 LLVMBuildBr (builder, get_bb (ctx, ins->inst_target_bb));
2388 has_terminator = TRUE;
2394 LLVMBasicBlockRef new_bb;
2395 LLVMBuilderRef new_builder;
2397 // The default branch is already handled
2398 // FIXME: Handle it here
2400 /* Start new bblock */
2401 sprintf (bb_name, "SWITCH_DEFAULT_BB%d", ctx->default_index ++);
2402 new_bb = LLVMAppendBasicBlock (ctx->lmethod, bb_name);
2404 lhs = convert (ctx, lhs, LLVMInt32Type ());
2405 v = LLVMBuildSwitch (builder, lhs, new_bb, GPOINTER_TO_UINT (ins->klass));
2406 for (i = 0; i < GPOINTER_TO_UINT (ins->klass); ++i) {
2407 MonoBasicBlock *target_bb = ins->inst_many_bb [i];
2409 LLVMAddCase (v, LLVMConstInt (LLVMInt32Type (), i, FALSE), get_bb (ctx, target_bb));
2412 new_builder = create_builder (ctx);
2413 LLVMPositionBuilderAtEnd (new_builder, new_bb);
2414 LLVMBuildUnreachable (new_builder);
2416 has_terminator = TRUE;
2417 g_assert (!ins->next);
2423 if (linfo->ret.storage == LLVMArgVtypeInReg) {
2424 LLVMTypeRef ret_type = LLVMGetReturnType (LLVMGetElementType (LLVMTypeOf (method)));
2425 LLVMValueRef part1, retval;
2428 size = get_vtype_size (sig->ret);
2430 g_assert (addresses [ins->sreg1]);
2432 g_assert (linfo->ret.pair_storage [0] == LLVMArgInIReg);
2433 g_assert (linfo->ret.pair_storage [1] == LLVMArgNone);
2435 part1 = convert (ctx, LLVMBuildLoad (builder, LLVMBuildBitCast (builder, addresses [ins->sreg1], LLVMPointerType (LLVMIntType (size * 8), 0), ""), ""), IntPtrType ());
2437 retval = LLVMBuildInsertValue (builder, LLVMGetUndef (ret_type), part1, 0, "");
2439 LLVMBuildRet (builder, retval);
2443 if (linfo->ret.storage == LLVMArgVtypeRetAddr) {
2444 LLVMBuildRetVoid (builder);
2448 if (!lhs || ctx->is_dead [ins->sreg1]) {
2450 * The method did not set its return value, probably because it
2451 * ends with a throw.
2454 LLVMBuildRetVoid (builder);
2456 LLVMBuildRet (builder, LLVMConstNull (type_to_llvm_type (ctx, sig->ret)));
2458 LLVMBuildRet (builder, convert (ctx, lhs, type_to_llvm_type (ctx, sig->ret)));
2460 has_terminator = TRUE;
2466 case OP_ICOMPARE_IMM:
2467 case OP_LCOMPARE_IMM:
2468 case OP_COMPARE_IMM: {
2472 if (ins->next->opcode == OP_NOP)
2475 if (ins->next->opcode == OP_BR)
2476 /* The comparison result is not needed */
2479 rel = mono_opcode_to_cond (ins->next->opcode);
2481 if (ins->opcode == OP_ICOMPARE_IMM) {
2482 lhs = convert (ctx, lhs, LLVMInt32Type ());
2483 rhs = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
2485 if (ins->opcode == OP_LCOMPARE_IMM) {
2486 lhs = convert (ctx, lhs, LLVMInt64Type ());
2487 rhs = LLVMConstInt (LLVMInt64Type (), GET_LONG_IMM (ins), FALSE);
2489 if (ins->opcode == OP_LCOMPARE) {
2490 lhs = convert (ctx, lhs, LLVMInt64Type ());
2491 rhs = convert (ctx, rhs, LLVMInt64Type ());
2493 if (ins->opcode == OP_ICOMPARE) {
2494 lhs = convert (ctx, lhs, LLVMInt32Type ());
2495 rhs = convert (ctx, rhs, LLVMInt32Type ());
2499 if (LLVMGetTypeKind (LLVMTypeOf (lhs)) == LLVMPointerTypeKind)
2500 rhs = convert (ctx, rhs, LLVMTypeOf (lhs));
2501 else if (LLVMGetTypeKind (LLVMTypeOf (rhs)) == LLVMPointerTypeKind)
2502 lhs = convert (ctx, lhs, LLVMTypeOf (rhs));
2505 /* We use COMPARE+SETcc/Bcc, llvm uses SETcc+br cond */
2506 if (ins->opcode == OP_FCOMPARE)
2507 cmp = LLVMBuildFCmp (builder, fpcond_to_llvm_cond [rel], convert (ctx, lhs, LLVMDoubleType ()), convert (ctx, rhs, LLVMDoubleType ()), "");
2508 else if (ins->opcode == OP_COMPARE_IMM) {
2509 if (LLVMGetTypeKind (LLVMTypeOf (lhs)) == LLVMPointerTypeKind && ins->inst_imm == 0)
2510 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], lhs, LLVMConstNull (LLVMTypeOf (lhs)), "");
2512 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE), "");
2513 } else if (ins->opcode == OP_LCOMPARE_IMM) {
2514 if (SIZEOF_REGISTER == 4 && COMPILE_LLVM (cfg)) {
2515 /* The immediate is encoded in two fields */
2516 guint64 l = ((guint64)(guint32)ins->inst_offset << 32) | ((guint32)ins->inst_imm);
2517 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, LLVMInt64Type ()), LLVMConstInt (LLVMInt64Type (), l, FALSE), "");
2519 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, LLVMInt64Type ()), LLVMConstInt (LLVMInt64Type (), ins->inst_imm, FALSE), "");
2522 else if (ins->opcode == OP_COMPARE) {
2523 if (LLVMGetTypeKind (LLVMTypeOf (lhs)) == LLVMPointerTypeKind && LLVMTypeOf (lhs) == LLVMTypeOf (rhs))
2524 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], lhs, rhs, "");
2526 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, IntPtrType ()), convert (ctx, rhs, IntPtrType ()), "");
2528 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], lhs, rhs, "");
2530 if (MONO_IS_COND_BRANCH_OP (ins->next)) {
2531 if (ins->next->inst_true_bb == ins->next->inst_false_bb) {
2533 * If the target bb contains PHI instructions, LLVM requires
2534 * two PHI entries for this bblock, while we only generate one.
2535 * So convert this to an unconditional bblock. (bxc #171).
2537 LLVMBuildBr (builder, get_bb (ctx, ins->next->inst_true_bb));
2539 LLVMBuildCondBr (builder, cmp, get_bb (ctx, ins->next->inst_true_bb), get_bb (ctx, ins->next->inst_false_bb));
2541 has_terminator = TRUE;
2542 } else if (MONO_IS_SETCC (ins->next)) {
2543 sprintf (dname_buf, "t%d", ins->next->dreg);
2545 values [ins->next->dreg] = LLVMBuildZExt (builder, cmp, LLVMInt32Type (), dname);
2547 /* Add stores for volatile variables */
2548 emit_volatile_store (ctx, ins->next->dreg);
2549 } else if (MONO_IS_COND_EXC (ins->next)) {
2550 emit_cond_system_exception (ctx, bb, ins->next->inst_p1, cmp);
2551 CHECK_FAILURE (ctx);
2552 builder = ctx->builder;
2554 LLVM_FAILURE (ctx, "next");
2568 rel = mono_opcode_to_cond (ins->opcode);
2570 cmp = LLVMBuildFCmp (builder, fpcond_to_llvm_cond [rel], convert (ctx, lhs, LLVMDoubleType ()), convert (ctx, rhs, LLVMDoubleType ()), "");
2571 values [ins->dreg] = LLVMBuildZExt (builder, cmp, LLVMInt32Type (), dname);
2579 gboolean empty = TRUE;
2581 /* Check that all input bblocks really branch to us */
2582 for (i = 0; i < bb->in_count; ++i) {
2583 if (bb->in_bb [i]->last_ins && bb->in_bb [i]->last_ins->opcode == OP_NOT_REACHED)
2584 ins->inst_phi_args [i + 1] = -1;
2590 /* LLVM doesn't like phi instructions with zero operands */
2591 ctx->is_dead [ins->dreg] = TRUE;
2595 /* Created earlier, insert it now */
2596 LLVMInsertIntoBuilder (builder, values [ins->dreg]);
2598 for (i = 0; i < ins->inst_phi_args [0]; i++) {
2599 int sreg1 = ins->inst_phi_args [i + 1];
2603 * Count the number of times the incoming bblock branches to us,
2604 * since llvm requires a separate entry for each.
2606 if (bb->in_bb [i]->last_ins && bb->in_bb [i]->last_ins->opcode == OP_SWITCH) {
2607 MonoInst *switch_ins = bb->in_bb [i]->last_ins;
2610 for (j = 0; j < GPOINTER_TO_UINT (switch_ins->klass); ++j) {
2611 if (switch_ins->inst_many_bb [j] == bb)
2618 /* Remember for later */
2619 for (j = 0; j < count; ++j) {
2620 PhiNode *node = mono_mempool_alloc0 (ctx->mempool, sizeof (PhiNode));
2623 node->in_bb = bb->in_bb [i];
2625 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);
2635 values [ins->dreg] = lhs;
2638 MonoInst *var = get_vreg_to_inst (cfg, ins->dreg);
2641 values [ins->dreg] = lhs;
2643 if (var && var->klass->byval_arg.type == MONO_TYPE_R4) {
2645 * This is added by the spilling pass in case of the JIT,
2646 * but we have to do it ourselves.
2648 values [ins->dreg] = convert (ctx, values [ins->dreg], LLVMFloatType ());
2682 lhs = convert (ctx, lhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
2683 rhs = convert (ctx, rhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
2685 switch (ins->opcode) {
2688 values [ins->dreg] = LLVMBuildAdd (builder, lhs, rhs, dname);
2692 values [ins->dreg] = LLVMBuildSub (builder, lhs, rhs, dname);
2696 values [ins->dreg] = LLVMBuildMul (builder, lhs, rhs, dname);
2700 values [ins->dreg] = LLVMBuildSRem (builder, lhs, rhs, dname);
2704 values [ins->dreg] = LLVMBuildURem (builder, lhs, rhs, dname);
2708 values [ins->dreg] = LLVMBuildSDiv (builder, lhs, rhs, dname);
2712 values [ins->dreg] = LLVMBuildUDiv (builder, lhs, rhs, dname);
2715 values [ins->dreg] = LLVMBuildFDiv (builder, lhs, rhs, dname);
2719 values [ins->dreg] = LLVMBuildAnd (builder, lhs, rhs, dname);
2723 values [ins->dreg] = LLVMBuildOr (builder, lhs, rhs, dname);
2727 values [ins->dreg] = LLVMBuildXor (builder, lhs, rhs, dname);
2731 values [ins->dreg] = LLVMBuildShl (builder, lhs, rhs, dname);
2735 values [ins->dreg] = LLVMBuildAShr (builder, lhs, rhs, dname);
2739 values [ins->dreg] = LLVMBuildLShr (builder, lhs, rhs, dname);
2743 values [ins->dreg] = LLVMBuildFAdd (builder, lhs, rhs, dname);
2746 values [ins->dreg] = LLVMBuildFSub (builder, lhs, rhs, dname);
2749 values [ins->dreg] = LLVMBuildFMul (builder, lhs, rhs, dname);
2753 g_assert_not_reached ();
2760 case OP_IREM_UN_IMM:
2762 case OP_IDIV_UN_IMM:
2768 case OP_ISHR_UN_IMM:
2777 case OP_LSHR_UN_IMM:
2783 case OP_SHR_UN_IMM: {
2786 if (spec [MONO_INST_SRC1] == 'l') {
2787 imm = LLVMConstInt (LLVMInt64Type (), GET_LONG_IMM (ins), FALSE);
2789 imm = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
2792 #if SIZEOF_VOID_P == 4
2793 if (ins->opcode == OP_LSHL_IMM || ins->opcode == OP_LSHR_IMM || ins->opcode == OP_LSHR_UN_IMM)
2794 imm = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
2797 if (LLVMGetTypeKind (LLVMTypeOf (lhs)) == LLVMPointerTypeKind)
2798 lhs = convert (ctx, lhs, IntPtrType ());
2799 imm = convert (ctx, imm, LLVMTypeOf (lhs));
2800 switch (ins->opcode) {
2804 values [ins->dreg] = LLVMBuildAdd (builder, lhs, imm, dname);
2808 values [ins->dreg] = LLVMBuildSub (builder, lhs, imm, dname);
2812 values [ins->dreg] = LLVMBuildMul (builder, lhs, imm, dname);
2816 values [ins->dreg] = LLVMBuildSDiv (builder, lhs, imm, dname);
2818 case OP_IDIV_UN_IMM:
2819 case OP_LDIV_UN_IMM:
2820 values [ins->dreg] = LLVMBuildUDiv (builder, lhs, imm, dname);
2824 values [ins->dreg] = LLVMBuildSRem (builder, lhs, imm, dname);
2826 case OP_IREM_UN_IMM:
2827 values [ins->dreg] = LLVMBuildURem (builder, lhs, imm, dname);
2832 values [ins->dreg] = LLVMBuildAnd (builder, lhs, imm, dname);
2836 values [ins->dreg] = LLVMBuildOr (builder, lhs, imm, dname);
2840 values [ins->dreg] = LLVMBuildXor (builder, lhs, imm, dname);
2845 values [ins->dreg] = LLVMBuildShl (builder, lhs, imm, dname);
2850 values [ins->dreg] = LLVMBuildAShr (builder, lhs, imm, dname);
2852 case OP_ISHR_UN_IMM:
2853 /* This is used to implement conv.u4, so the lhs could be an i8 */
2854 lhs = convert (ctx, lhs, LLVMInt32Type ());
2855 imm = convert (ctx, imm, LLVMInt32Type ());
2856 values [ins->dreg] = LLVMBuildLShr (builder, lhs, imm, dname);
2858 case OP_LSHR_UN_IMM:
2860 values [ins->dreg] = LLVMBuildLShr (builder, lhs, imm, dname);
2863 g_assert_not_reached ();
2868 values [ins->dreg] = LLVMBuildSub (builder, LLVMConstInt (LLVMInt32Type (), 0, FALSE), convert (ctx, lhs, LLVMInt32Type ()), dname);
2871 values [ins->dreg] = LLVMBuildSub (builder, LLVMConstInt (LLVMInt64Type (), 0, FALSE), lhs, dname);
2874 lhs = convert (ctx, lhs, LLVMDoubleType ());
2875 values [ins->dreg] = LLVMBuildFSub (builder, LLVMConstReal (LLVMDoubleType (), 0.0), lhs, dname);
2878 guint32 v = 0xffffffff;
2879 values [ins->dreg] = LLVMBuildXor (builder, LLVMConstInt (LLVMInt32Type (), v, FALSE), convert (ctx, lhs, LLVMInt32Type ()), dname);
2883 guint64 v = 0xffffffffffffffffLL;
2884 values [ins->dreg] = LLVMBuildXor (builder, LLVMConstInt (LLVMInt64Type (), v, FALSE), lhs, dname);
2887 #if defined(TARGET_X86) || defined(TARGET_AMD64)
2889 LLVMValueRef v1, v2;
2891 v1 = LLVMBuildMul (builder, convert (ctx, rhs, IntPtrType ()), LLVMConstInt (IntPtrType (), (1 << ins->backend.shift_amount), FALSE), "");
2892 v2 = LLVMBuildAdd (builder, convert (ctx, lhs, IntPtrType ()), v1, "");
2893 values [ins->dreg] = LLVMBuildAdd (builder, v2, LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE), dname);
2898 case OP_ICONV_TO_I1:
2899 case OP_ICONV_TO_I2:
2900 case OP_ICONV_TO_I4:
2901 case OP_ICONV_TO_U1:
2902 case OP_ICONV_TO_U2:
2903 case OP_ICONV_TO_U4:
2904 case OP_LCONV_TO_I1:
2905 case OP_LCONV_TO_I2:
2906 case OP_LCONV_TO_U1:
2907 case OP_LCONV_TO_U2:
2908 case OP_LCONV_TO_U4: {
2911 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);
2913 /* Have to do two casts since our vregs have type int */
2914 v = LLVMBuildTrunc (builder, lhs, op_to_llvm_type (ins->opcode), "");
2916 values [ins->dreg] = LLVMBuildSExt (builder, v, LLVMInt32Type (), dname);
2918 values [ins->dreg] = LLVMBuildZExt (builder, v, LLVMInt32Type (), dname);
2921 case OP_ICONV_TO_I8:
2922 values [ins->dreg] = LLVMBuildSExt (builder, lhs, LLVMInt64Type (), dname);
2924 case OP_ICONV_TO_U8:
2925 values [ins->dreg] = LLVMBuildZExt (builder, lhs, LLVMInt64Type (), dname);
2927 case OP_FCONV_TO_I4:
2928 values [ins->dreg] = LLVMBuildFPToSI (builder, lhs, LLVMInt32Type (), dname);
2930 case OP_FCONV_TO_I1:
2931 values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildFPToSI (builder, lhs, LLVMInt8Type (), dname), LLVMInt32Type (), "");
2933 case OP_FCONV_TO_U1:
2934 values [ins->dreg] = LLVMBuildZExt (builder, LLVMBuildFPToUI (builder, lhs, LLVMInt8Type (), dname), LLVMInt32Type (), "");
2936 case OP_FCONV_TO_I2:
2937 values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildFPToSI (builder, lhs, LLVMInt16Type (), dname), LLVMInt32Type (), "");
2939 case OP_FCONV_TO_U2:
2940 values [ins->dreg] = LLVMBuildZExt (builder, LLVMBuildFPToUI (builder, lhs, LLVMInt16Type (), dname), LLVMInt32Type (), "");
2942 case OP_FCONV_TO_I8:
2943 values [ins->dreg] = LLVMBuildFPToSI (builder, lhs, LLVMInt64Type (), dname);
2946 values [ins->dreg] = LLVMBuildFPToSI (builder, lhs, IntPtrType (), dname);
2948 case OP_ICONV_TO_R8:
2949 case OP_LCONV_TO_R8:
2950 values [ins->dreg] = LLVMBuildSIToFP (builder, lhs, LLVMDoubleType (), dname);
2952 case OP_LCONV_TO_R_UN:
2953 values [ins->dreg] = LLVMBuildUIToFP (builder, lhs, LLVMDoubleType (), dname);
2955 #if SIZEOF_VOID_P == 4
2958 case OP_LCONV_TO_I4:
2959 values [ins->dreg] = LLVMBuildTrunc (builder, lhs, LLVMInt32Type (), dname);
2961 case OP_ICONV_TO_R4:
2962 case OP_LCONV_TO_R4:
2963 v = LLVMBuildSIToFP (builder, lhs, LLVMFloatType (), "");
2964 values [ins->dreg] = LLVMBuildFPExt (builder, v, LLVMDoubleType (), dname);
2966 case OP_FCONV_TO_R4:
2967 v = LLVMBuildFPTrunc (builder, lhs, LLVMFloatType (), "");
2968 values [ins->dreg] = LLVMBuildFPExt (builder, v, LLVMDoubleType (), dname);
2971 values [ins->dreg] = LLVMBuildSExt (builder, convert (ctx, lhs, LLVMInt32Type ()), LLVMInt64Type (), dname);
2974 values [ins->dreg] = LLVMBuildZExt (builder, convert (ctx, lhs, LLVMInt32Type ()), LLVMInt64Type (), dname);
2977 values [ins->dreg] = LLVMBuildTrunc (builder, lhs, LLVMInt32Type (), dname);
2979 case OP_LOCALLOC_IMM: {
2982 guint32 size = ins->inst_imm;
2983 size = (size + (MONO_ARCH_FRAME_ALIGNMENT - 1)) & ~ (MONO_ARCH_FRAME_ALIGNMENT - 1);
2985 v = mono_llvm_build_alloca (builder, LLVMInt8Type (), LLVMConstInt (LLVMInt32Type (), size, FALSE), MONO_ARCH_FRAME_ALIGNMENT, "");
2987 if (ins->flags & MONO_INST_INIT) {
2988 LLVMValueRef args [5];
2991 args [1] = LLVMConstInt (LLVMInt8Type (), 0, FALSE);
2992 args [2] = LLVMConstInt (LLVMInt32Type (), size, FALSE);
2993 args [3] = LLVMConstInt (LLVMInt32Type (), MONO_ARCH_FRAME_ALIGNMENT, FALSE);
2994 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
2995 LLVMBuildCall (builder, LLVMGetNamedFunction (module, memset_func_name), args, memset_param_count, "");
2998 values [ins->dreg] = v;
3002 LLVMValueRef v, size;
3004 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), "");
3006 v = mono_llvm_build_alloca (builder, LLVMInt8Type (), size, MONO_ARCH_FRAME_ALIGNMENT, "");
3008 if (ins->flags & MONO_INST_INIT) {
3009 LLVMValueRef args [5];
3012 args [1] = LLVMConstInt (LLVMInt8Type (), 0, FALSE);
3014 args [3] = LLVMConstInt (LLVMInt32Type (), MONO_ARCH_FRAME_ALIGNMENT, FALSE);
3015 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
3016 LLVMBuildCall (builder, LLVMGetNamedFunction (module, memset_func_name), args, memset_param_count, "");
3018 values [ins->dreg] = v;
3022 case OP_LOADI1_MEMBASE:
3023 case OP_LOADU1_MEMBASE:
3024 case OP_LOADI2_MEMBASE:
3025 case OP_LOADU2_MEMBASE:
3026 case OP_LOADI4_MEMBASE:
3027 case OP_LOADU4_MEMBASE:
3028 case OP_LOADI8_MEMBASE:
3029 case OP_LOADR4_MEMBASE:
3030 case OP_LOADR8_MEMBASE:
3031 case OP_LOAD_MEMBASE:
3039 LLVMValueRef base, index, addr;
3041 gboolean sext = FALSE, zext = FALSE;
3042 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
3044 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
3049 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)) {
3050 addr = LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE);
3055 if (ins->inst_offset == 0) {
3057 } else if (ins->inst_offset % size != 0) {
3058 /* Unaligned load */
3059 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset, FALSE);
3060 addr = LLVMBuildGEP (builder, convert (ctx, base, LLVMPointerType (LLVMInt8Type (), 0)), &index, 1, "");
3062 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
3063 addr = LLVMBuildGEP (builder, convert (ctx, base, LLVMPointerType (t, 0)), &index, 1, "");
3067 addr = convert (ctx, addr, LLVMPointerType (t, 0));
3069 values [ins->dreg] = emit_load (ctx, bb, &builder, size, addr, dname, is_volatile);
3071 if (!is_volatile && (ins->flags & MONO_INST_INVARIANT_LOAD)) {
3073 * These will signal LLVM that these loads do not alias any stores, and
3074 * they can't fail, allowing them to be hoisted out of loops.
3076 set_invariant_load_flag (values [ins->dreg]);
3077 set_metadata_flag (values [ins->dreg], "mono.nofail.load");
3081 values [ins->dreg] = LLVMBuildSExt (builder, values [ins->dreg], LLVMInt32Type (), dname);
3083 values [ins->dreg] = LLVMBuildZExt (builder, values [ins->dreg], LLVMInt32Type (), dname);
3084 else if (ins->opcode == OP_LOADR4_MEMBASE)
3085 values [ins->dreg] = LLVMBuildFPExt (builder, values [ins->dreg], LLVMDoubleType (), dname);
3089 case OP_STOREI1_MEMBASE_REG:
3090 case OP_STOREI2_MEMBASE_REG:
3091 case OP_STOREI4_MEMBASE_REG:
3092 case OP_STOREI8_MEMBASE_REG:
3093 case OP_STORER4_MEMBASE_REG:
3094 case OP_STORER8_MEMBASE_REG:
3095 case OP_STORE_MEMBASE_REG: {
3097 LLVMValueRef index, addr;
3099 gboolean sext = FALSE, zext = FALSE;
3100 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
3102 if (!values [ins->inst_destbasereg])
3103 LLVM_FAILURE (ctx, "inst_destbasereg");
3105 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
3107 if (ins->inst_offset % size != 0) {
3108 /* Unaligned store */
3109 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset, FALSE);
3110 addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (LLVMInt8Type (), 0)), &index, 1, "");
3112 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
3113 addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (t, 0)), &index, 1, "");
3115 emit_store (ctx, bb, &builder, size, convert (ctx, values [ins->sreg1], t), convert (ctx, addr, LLVMPointerType (t, 0)), is_volatile);
3119 case OP_STOREI1_MEMBASE_IMM:
3120 case OP_STOREI2_MEMBASE_IMM:
3121 case OP_STOREI4_MEMBASE_IMM:
3122 case OP_STOREI8_MEMBASE_IMM:
3123 case OP_STORE_MEMBASE_IMM: {
3125 LLVMValueRef index, addr;
3127 gboolean sext = FALSE, zext = FALSE;
3128 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
3130 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
3132 if (ins->inst_offset % size != 0) {
3133 /* Unaligned store */
3134 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset, FALSE);
3135 addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (LLVMInt8Type (), 0)), &index, 1, "");
3137 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
3138 addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (t, 0)), &index, 1, "");
3140 emit_store (ctx, bb, &builder, size, convert (ctx, LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE), t), addr, is_volatile);
3145 emit_load (ctx, bb, &builder, sizeof (gpointer), convert (ctx, lhs, LLVMPointerType (IntPtrType (), 0)), "", TRUE);
3147 case OP_OUTARG_VTRETADDR:
3154 case OP_VOIDCALL_MEMBASE:
3155 case OP_CALL_MEMBASE:
3156 case OP_LCALL_MEMBASE:
3157 case OP_FCALL_MEMBASE:
3158 case OP_VCALL_MEMBASE:
3159 case OP_VOIDCALL_REG:
3163 case OP_VCALL_REG: {
3164 process_call (ctx, bb, &builder, ins);
3165 CHECK_FAILURE (ctx);
3170 LLVMValueRef indexes [2];
3172 LLVMValueRef got_entry_addr;
3175 * FIXME: Can't allocate from the cfg mempool since that is freed if
3176 * the LLVM compile fails.
3178 ji = g_new0 (MonoJumpInfo, 1);
3179 ji->type = (MonoJumpInfoType)ins->inst_i1;
3180 ji->data.target = ins->inst_p0;
3182 ji = mono_aot_patch_info_dup (ji);
3184 ji->next = cfg->patch_info;
3185 cfg->patch_info = ji;
3187 //mono_add_patch_info (cfg, 0, (MonoJumpInfoType)ins->inst_i1, ins->inst_p0);
3188 got_offset = mono_aot_get_got_offset (cfg->patch_info);
3190 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
3191 indexes [1] = LLVMConstInt (LLVMInt32Type (), (gssize)got_offset, FALSE);
3192 got_entry_addr = LLVMBuildGEP (builder, ctx->lmodule->got_var, indexes, 2, "");
3194 values [ins->dreg] = LLVMBuildLoad (builder, got_entry_addr, dname);
3195 set_invariant_load_flag (values [ins->dreg]);
3198 case OP_NOT_REACHED:
3199 LLVMBuildUnreachable (builder);
3200 has_terminator = TRUE;
3201 g_assert (bb->block_num < cfg->max_block_num);
3202 ctx->unreachable [bb->block_num] = TRUE;
3203 /* Might have instructions after this */
3205 MonoInst *next = ins->next;
3207 * FIXME: If later code uses the regs defined by these instructions,
3208 * compilation will fail.
3210 MONO_DELETE_INS (bb, next);
3214 MonoInst *var = ins->inst_p0;
3216 values [ins->dreg] = addresses [var->dreg];
3220 LLVMValueRef args [1];
3222 args [0] = convert (ctx, lhs, LLVMDoubleType ());
3223 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, "llvm.sin.f64"), args, 1, dname);
3227 LLVMValueRef args [1];
3229 args [0] = convert (ctx, lhs, LLVMDoubleType ());
3230 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, "llvm.cos.f64"), args, 1, dname);
3234 LLVMValueRef args [1];
3237 /* This no longer seems to happen */
3239 * LLVM optimizes sqrt(nan) into undefined in
3240 * lib/Analysis/ConstantFolding.cpp
3241 * Also, sqrt(NegativeInfinity) is optimized into 0.
3243 LLVM_FAILURE (ctx, "sqrt");
3245 args [0] = convert (ctx, lhs, LLVMDoubleType ());
3246 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, "llvm.sqrt.f64"), args, 1, dname);
3250 LLVMValueRef args [1];
3252 args [0] = convert (ctx, lhs, LLVMDoubleType ());
3253 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, "fabs"), args, 1, dname);
3267 lhs = convert (ctx, lhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
3268 rhs = convert (ctx, rhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
3270 switch (ins->opcode) {
3273 v = LLVMBuildICmp (builder, LLVMIntSLE, lhs, rhs, "");
3277 v = LLVMBuildICmp (builder, LLVMIntSGE, lhs, rhs, "");
3281 v = LLVMBuildICmp (builder, LLVMIntULE, lhs, rhs, "");
3285 v = LLVMBuildICmp (builder, LLVMIntUGE, lhs, rhs, "");
3288 g_assert_not_reached ();
3291 values [ins->dreg] = LLVMBuildSelect (builder, v, lhs, rhs, dname);
3294 case OP_ATOMIC_EXCHANGE_I4:
3295 case OP_ATOMIC_EXCHANGE_I8: {
3296 LLVMValueRef args [2];
3299 if (ins->opcode == OP_ATOMIC_EXCHANGE_I4)
3300 t = LLVMInt32Type ();
3302 t = LLVMInt64Type ();
3304 g_assert (ins->inst_offset == 0);
3306 args [0] = convert (ctx, lhs, LLVMPointerType (t, 0));
3307 args [1] = convert (ctx, rhs, t);
3309 values [ins->dreg] = mono_llvm_build_atomic_rmw (builder, LLVM_ATOMICRMW_OP_XCHG, args [0], args [1]);
3312 case OP_ATOMIC_ADD_NEW_I4:
3313 case OP_ATOMIC_ADD_NEW_I8: {
3314 LLVMValueRef args [2];
3317 if (ins->opcode == OP_ATOMIC_ADD_NEW_I4)
3318 t = LLVMInt32Type ();
3320 t = LLVMInt64Type ();
3322 g_assert (ins->inst_offset == 0);
3324 args [0] = convert (ctx, lhs, LLVMPointerType (t, 0));
3325 args [1] = convert (ctx, rhs, t);
3326 values [ins->dreg] = LLVMBuildAdd (builder, mono_llvm_build_atomic_rmw (builder, LLVM_ATOMICRMW_OP_ADD, args [0], args [1]), args [1], dname);
3329 case OP_ATOMIC_CAS_I4:
3330 case OP_ATOMIC_CAS_I8: {
3331 LLVMValueRef args [3];
3334 if (ins->opcode == OP_ATOMIC_CAS_I4)
3335 t = LLVMInt32Type ();
3337 t = LLVMInt64Type ();
3339 args [0] = convert (ctx, lhs, LLVMPointerType (t, 0));
3341 args [1] = convert (ctx, values [ins->sreg3], t);
3343 args [2] = convert (ctx, values [ins->sreg2], t);
3344 values [ins->dreg] = mono_llvm_build_cmpxchg (builder, args [0], args [1], args [2]);
3347 case OP_MEMORY_BARRIER: {
3348 mono_llvm_build_fence (builder);
3351 case OP_RELAXED_NOP: {
3352 #if defined(TARGET_AMD64) || defined(TARGET_X86)
3353 emit_call (ctx, bb, &builder, LLVMGetNamedFunction (ctx->module, "llvm.x86.sse2.pause"), NULL, 0);
3360 #if (defined(TARGET_AMD64) || defined(TARGET_X86)) && defined(__linux__)
3362 // 257 == FS segment register
3363 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 257);
3365 // 256 == GS segment register
3366 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 256);
3369 values [ins->dreg] = LLVMBuildLoad (builder, LLVMBuildIntToPtr (builder, LLVMConstInt (IntPtrType (), ins->inst_offset, TRUE), ptrtype, ""), "");
3370 #elif defined(TARGET_AMD64) && defined(TARGET_OSX)
3371 /* See mono_amd64_emit_tls_get () */
3372 int offset = mono_amd64_get_tls_gs_offset () + (ins->inst_offset * 8);
3374 // 256 == GS segment register
3375 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 256);
3376 values [ins->dreg] = LLVMBuildLoad (builder, LLVMBuildIntToPtr (builder, LLVMConstInt (IntPtrType (), offset, TRUE), ptrtype, ""), "");
3378 LLVM_FAILURE (ctx, "opcode tls-get");
3383 case OP_TLS_GET_REG: {
3384 #if defined(TARGET_AMD64) && defined(TARGET_OSX)
3385 /* See emit_tls_get_reg () */
3386 // 256 == GS segment register
3387 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 256);
3388 values [ins->dreg] = LLVMBuildLoad (builder, LLVMBuildIntToPtr (builder, convert (ctx, lhs, LLVMInt32Type ()), ptrtype, ""), "");
3390 LLVM_FAILURE (ctx, "opcode tls-get");
3399 case OP_IADD_OVF_UN:
3401 case OP_ISUB_OVF_UN:
3403 case OP_IMUL_OVF_UN:
3404 #if SIZEOF_VOID_P == 8
3406 case OP_LADD_OVF_UN:
3408 case OP_LSUB_OVF_UN:
3410 case OP_LMUL_OVF_UN:
3413 LLVMValueRef args [2], val, ovf, func;
3415 args [0] = convert (ctx, lhs, op_to_llvm_type (ins->opcode));
3416 args [1] = convert (ctx, rhs, op_to_llvm_type (ins->opcode));
3417 func = LLVMGetNamedFunction (module, ovf_op_to_intrins (ins->opcode));
3419 val = LLVMBuildCall (builder, func, args, 2, "");
3420 values [ins->dreg] = LLVMBuildExtractValue (builder, val, 0, dname);
3421 ovf = LLVMBuildExtractValue (builder, val, 1, "");
3422 emit_cond_system_exception (ctx, bb, "OverflowException", ovf);
3423 CHECK_FAILURE (ctx);
3424 builder = ctx->builder;
3430 * We currently model them using arrays. Promotion to local vregs is
3431 * disabled for them in mono_handle_global_vregs () in the LLVM case,
3432 * so we always have an entry in cfg->varinfo for them.
3433 * FIXME: Is this needed ?
3436 MonoClass *klass = ins->klass;
3437 LLVMValueRef args [5];
3441 LLVM_FAILURE (ctx, "!klass");
3445 if (!addresses [ins->dreg])
3446 addresses [ins->dreg] = build_alloca (ctx, &klass->byval_arg);
3447 args [0] = LLVMBuildBitCast (builder, addresses [ins->dreg], LLVMPointerType (LLVMInt8Type (), 0), "");
3448 args [1] = LLVMConstInt (LLVMInt8Type (), 0, FALSE);
3449 args [2] = LLVMConstInt (LLVMInt32Type (), mono_class_value_size (klass, NULL), FALSE);
3451 args [3] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
3452 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
3453 LLVMBuildCall (builder, LLVMGetNamedFunction (module, memset_func_name), args, memset_param_count, "");
3457 case OP_STOREV_MEMBASE:
3458 case OP_LOADV_MEMBASE:
3460 MonoClass *klass = ins->klass;
3461 LLVMValueRef src = NULL, dst, args [5];
3462 gboolean done = FALSE;
3466 LLVM_FAILURE (ctx, "!klass");
3470 if (mini_is_gsharedvt_klass (cfg, klass)) {
3472 LLVM_FAILURE (ctx, "gsharedvt");
3476 switch (ins->opcode) {
3477 case OP_STOREV_MEMBASE:
3478 if (cfg->gen_write_barriers && klass->has_references && ins->inst_destbasereg != cfg->frame_reg &&
3479 LLVMGetInstructionOpcode (values [ins->inst_destbasereg]) != LLVMAlloca) {
3480 /* Decomposed earlier */
3481 g_assert_not_reached ();
3484 if (!addresses [ins->sreg1]) {
3486 g_assert (values [ins->sreg1]);
3487 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));
3488 LLVMBuildStore (builder, values [ins->sreg1], dst);
3491 src = LLVMBuildBitCast (builder, addresses [ins->sreg1], LLVMPointerType (LLVMInt8Type (), 0), "");
3492 dst = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_destbasereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (LLVMInt8Type (), 0));
3495 case OP_LOADV_MEMBASE:
3496 if (!addresses [ins->dreg])
3497 addresses [ins->dreg] = build_alloca (ctx, &klass->byval_arg);
3498 src = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_basereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (LLVMInt8Type (), 0));
3499 dst = LLVMBuildBitCast (builder, addresses [ins->dreg], LLVMPointerType (LLVMInt8Type (), 0), "");
3502 if (!addresses [ins->sreg1])
3503 addresses [ins->sreg1] = build_alloca (ctx, &klass->byval_arg);
3504 if (!addresses [ins->dreg])
3505 addresses [ins->dreg] = build_alloca (ctx, &klass->byval_arg);
3506 src = LLVMBuildBitCast (builder, addresses [ins->sreg1], LLVMPointerType (LLVMInt8Type (), 0), "");
3507 dst = LLVMBuildBitCast (builder, addresses [ins->dreg], LLVMPointerType (LLVMInt8Type (), 0), "");
3510 g_assert_not_reached ();
3512 CHECK_FAILURE (ctx);
3519 args [2] = LLVMConstInt (LLVMInt32Type (), mono_class_value_size (klass, NULL), FALSE);
3520 args [3] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
3522 args [3] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
3523 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
3524 LLVMBuildCall (builder, LLVMGetNamedFunction (module, memcpy_func_name), args, memcpy_param_count, "");
3527 case OP_LLVM_OUTARG_VT:
3528 if (!addresses [ins->sreg1]) {
3529 addresses [ins->sreg1] = build_alloca (ctx, &ins->klass->byval_arg);
3530 g_assert (values [ins->sreg1]);
3531 LLVMBuildStore (builder, values [ins->sreg1], addresses [ins->sreg1]);
3533 addresses [ins->dreg] = addresses [ins->sreg1];
3539 #if defined(TARGET_X86) || defined(TARGET_AMD64)
3541 values [ins->dreg] = LLVMConstNull (type_to_llvm_type (ctx, &ins->klass->byval_arg));
3544 case OP_LOADX_MEMBASE: {
3545 LLVMTypeRef t = type_to_llvm_type (ctx, &ins->klass->byval_arg);
3548 src = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_basereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (t, 0));
3549 values [ins->dreg] = mono_llvm_build_aligned_load (builder, src, "", FALSE, 1);
3552 case OP_STOREX_MEMBASE: {
3553 LLVMTypeRef t = LLVMTypeOf (values [ins->sreg1]);
3556 dest = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_destbasereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (t, 0));
3557 mono_llvm_build_aligned_store (builder, values [ins->sreg1], dest, FALSE, 1);
3564 values [ins->dreg] = LLVMBuildAdd (builder, lhs, rhs, "");
3568 values [ins->dreg] = LLVMBuildFAdd (builder, lhs, rhs, "");
3574 values [ins->dreg] = LLVMBuildSub (builder, lhs, rhs, "");
3578 values [ins->dreg] = LLVMBuildFSub (builder, lhs, rhs, "");
3582 values [ins->dreg] = LLVMBuildFMul (builder, lhs, rhs, "");
3586 values [ins->dreg] = LLVMBuildFDiv (builder, lhs, rhs, "");
3589 values [ins->dreg] = LLVMBuildAnd (builder, lhs, rhs, "");
3592 values [ins->dreg] = LLVMBuildOr (builder, lhs, rhs, "");
3595 values [ins->dreg] = LLVMBuildXor (builder, lhs, rhs, "");
3599 values [ins->dreg] = LLVMBuildMul (builder, lhs, rhs, "");
3610 LLVMValueRef v = NULL;
3612 switch (ins->opcode) {
3617 t = LLVMVectorType (LLVMInt32Type (), 4);
3618 rt = LLVMVectorType (LLVMFloatType (), 4);
3624 t = LLVMVectorType (LLVMInt64Type (), 2);
3625 rt = LLVMVectorType (LLVMDoubleType (), 2);
3628 t = LLVMInt32Type ();
3629 rt = LLVMInt32Type ();
3630 g_assert_not_reached ();
3633 lhs = LLVMBuildBitCast (builder, lhs, t, "");
3634 rhs = LLVMBuildBitCast (builder, rhs, t, "");
3635 switch (ins->opcode) {
3638 v = LLVMBuildAnd (builder, lhs, rhs, "");
3642 v = LLVMBuildOr (builder, lhs, rhs, "");
3646 v = LLVMBuildXor (builder, lhs, rhs, "");
3650 v = LLVMBuildAnd (builder, rhs, LLVMBuildNot (builder, lhs, ""), "");
3653 values [ins->dreg] = LLVMBuildBitCast (builder, v, rt, "");
3677 case OP_PADDB_SAT_UN:
3678 case OP_PADDW_SAT_UN:
3679 case OP_PSUBB_SAT_UN:
3680 case OP_PSUBW_SAT_UN:
3688 case OP_PMULW_HIGH_UN: {
3689 LLVMValueRef args [2];
3694 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, simd_op_to_intrins (ins->opcode)), args, 2, dname);
3701 values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildICmp (builder, LLVMIntEQ, lhs, rhs, ""), LLVMTypeOf (lhs), "");
3705 values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildICmp (builder, LLVMIntSGT, lhs, rhs, ""), LLVMTypeOf (lhs), "");
3713 case OP_EXTRACTX_U2:
3715 case OP_EXTRACT_U1: {
3717 gboolean zext = FALSE;
3719 t = simd_op_to_llvm_type (ins->opcode);
3721 switch (ins->opcode) {
3729 case OP_EXTRACTX_U2:
3734 t = LLVMInt32Type ();
3735 g_assert_not_reached ();
3738 lhs = LLVMBuildBitCast (builder, lhs, t, "");
3739 values [ins->dreg] = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), "");
3741 values [ins->dreg] = LLVMBuildZExt (builder, values [ins->dreg], LLVMInt32Type (), "");
3750 case OP_EXPAND_R8: {
3751 LLVMTypeRef t = simd_op_to_llvm_type (ins->opcode);
3752 LLVMValueRef mask [16], v;
3754 for (i = 0; i < 16; ++i)
3755 mask [i] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
3757 v = convert (ctx, values [ins->sreg1], LLVMGetElementType (t));
3759 values [ins->dreg] = LLVMBuildInsertElement (builder, LLVMConstNull (t), v, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
3760 values [ins->dreg] = LLVMBuildShuffleVector (builder, values [ins->dreg], LLVMGetUndef (t), LLVMConstVector (mask, LLVMGetVectorSize (t)), "");
3765 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt8Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
3768 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt16Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
3771 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt32Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
3774 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt64Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
3777 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMFloatType ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
3780 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMDoubleType ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
3791 case OP_EXTRACT_MASK:
3798 v = convert (ctx, values [ins->sreg1], simd_op_to_llvm_type (ins->opcode));
3800 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, simd_op_to_intrins (ins->opcode)), &v, 1, dname);
3804 case OP_ICONV_TO_R8_RAW:
3805 /* Same as OP_ICONV_TO_R8 */
3806 values [ins->dreg] = convert (ctx, LLVMBuildBitCast (builder, lhs, LLVMFloatType (), ""), LLVMDoubleType ());
3811 LLVMValueRef args [3];
3815 args [2] = LLVMConstInt (LLVMInt8Type (), ins->inst_c0, FALSE);
3817 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, simd_op_to_intrins (ins->opcode)), args, 3, dname);
3822 /* This is only used for implementing shifts by non-immediate */
3823 values [ins->dreg] = lhs;
3834 LLVMValueRef args [3];
3837 args [1] = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
3839 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, simd_op_to_intrins (ins->opcode)), args, 2, dname);
3850 case OP_PSHLQ_REG: {
3851 LLVMValueRef args [3];
3854 args [1] = values [ins->sreg2];
3856 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, simd_op_to_intrins (ins->opcode)), args, 2, dname);
3863 case OP_PSHUFLEW_LOW:
3864 case OP_PSHUFLEW_HIGH: {
3866 LLVMValueRef v1 = NULL, v2 = NULL, mask_values [16];
3867 int i, mask_size = 0;
3868 int imask = ins->inst_c0;
3870 /* Convert the x86 shuffle mask to LLVM's */
3871 switch (ins->opcode) {
3874 mask [0] = ((imask >> 0) & 3);
3875 mask [1] = ((imask >> 2) & 3);
3876 mask [2] = ((imask >> 4) & 3) + 4;
3877 mask [3] = ((imask >> 6) & 3) + 4;
3878 v1 = values [ins->sreg1];
3879 v2 = values [ins->sreg2];
3883 mask [0] = ((imask >> 0) & 1);
3884 mask [1] = ((imask >> 1) & 1) + 2;
3885 v1 = values [ins->sreg1];
3886 v2 = values [ins->sreg2];
3888 case OP_PSHUFLEW_LOW:
3890 mask [0] = ((imask >> 0) & 3);
3891 mask [1] = ((imask >> 2) & 3);
3892 mask [2] = ((imask >> 4) & 3);
3893 mask [3] = ((imask >> 6) & 3);
3898 v1 = values [ins->sreg1];
3899 v2 = LLVMGetUndef (LLVMTypeOf (v1));
3901 case OP_PSHUFLEW_HIGH:
3907 mask [4] = 4 + ((imask >> 0) & 3);
3908 mask [5] = 4 + ((imask >> 2) & 3);
3909 mask [6] = 4 + ((imask >> 4) & 3);
3910 mask [7] = 4 + ((imask >> 6) & 3);
3911 v1 = values [ins->sreg1];
3912 v2 = LLVMGetUndef (LLVMTypeOf (v1));
3916 mask [0] = ((imask >> 0) & 3);
3917 mask [1] = ((imask >> 2) & 3);
3918 mask [2] = ((imask >> 4) & 3);
3919 mask [3] = ((imask >> 6) & 3);
3920 v1 = values [ins->sreg1];
3921 v2 = LLVMGetUndef (LLVMTypeOf (v1));
3924 g_assert_not_reached ();
3926 for (i = 0; i < mask_size; ++i)
3927 mask_values [i] = LLVMConstInt (LLVMInt32Type (), mask [i], FALSE);
3929 values [ins->dreg] =
3930 LLVMBuildShuffleVector (builder, v1, v2,
3931 LLVMConstVector (mask_values, mask_size), dname);
3935 case OP_UNPACK_LOWB:
3936 case OP_UNPACK_LOWW:
3937 case OP_UNPACK_LOWD:
3938 case OP_UNPACK_LOWQ:
3939 case OP_UNPACK_LOWPS:
3940 case OP_UNPACK_LOWPD:
3941 case OP_UNPACK_HIGHB:
3942 case OP_UNPACK_HIGHW:
3943 case OP_UNPACK_HIGHD:
3944 case OP_UNPACK_HIGHQ:
3945 case OP_UNPACK_HIGHPS:
3946 case OP_UNPACK_HIGHPD: {
3948 LLVMValueRef mask_values [16];
3949 int i, mask_size = 0;
3950 gboolean low = FALSE;
3952 switch (ins->opcode) {
3953 case OP_UNPACK_LOWB:
3957 case OP_UNPACK_LOWW:
3961 case OP_UNPACK_LOWD:
3962 case OP_UNPACK_LOWPS:
3966 case OP_UNPACK_LOWQ:
3967 case OP_UNPACK_LOWPD:
3971 case OP_UNPACK_HIGHB:
3974 case OP_UNPACK_HIGHW:
3977 case OP_UNPACK_HIGHD:
3978 case OP_UNPACK_HIGHPS:
3981 case OP_UNPACK_HIGHQ:
3982 case OP_UNPACK_HIGHPD:
3986 g_assert_not_reached ();
3990 for (i = 0; i < (mask_size / 2); ++i) {
3992 mask [(i * 2) + 1] = mask_size + i;
3995 for (i = 0; i < (mask_size / 2); ++i) {
3996 mask [(i * 2)] = (mask_size / 2) + i;
3997 mask [(i * 2) + 1] = mask_size + (mask_size / 2) + i;
4001 for (i = 0; i < mask_size; ++i)
4002 mask_values [i] = LLVMConstInt (LLVMInt32Type (), mask [i], FALSE);
4004 values [ins->dreg] =
4005 LLVMBuildShuffleVector (builder, values [ins->sreg1], values [ins->sreg2],
4006 LLVMConstVector (mask_values, mask_size), dname);
4011 LLVMTypeRef t = simd_op_to_llvm_type (ins->opcode);
4012 LLVMValueRef v, val;
4014 v = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
4015 val = LLVMConstNull (t);
4016 val = LLVMBuildInsertElement (builder, val, v, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
4017 val = LLVMBuildInsertElement (builder, val, v, LLVMConstInt (LLVMInt32Type (), 1, FALSE), dname);
4019 values [ins->dreg] = val;
4023 case OP_DUPPS_HIGH: {
4024 LLVMTypeRef t = simd_op_to_llvm_type (ins->opcode);
4025 LLVMValueRef v1, v2, val;
4028 if (ins->opcode == OP_DUPPS_LOW) {
4029 v1 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
4030 v2 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 2, FALSE), "");
4032 v1 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 1, FALSE), "");
4033 v2 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 3, FALSE), "");
4035 val = LLVMConstNull (t);
4036 val = LLVMBuildInsertElement (builder, val, v1, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
4037 val = LLVMBuildInsertElement (builder, val, v1, LLVMConstInt (LLVMInt32Type (), 1, FALSE), "");
4038 val = LLVMBuildInsertElement (builder, val, v2, LLVMConstInt (LLVMInt32Type (), 2, FALSE), "");
4039 val = LLVMBuildInsertElement (builder, val, v2, LLVMConstInt (LLVMInt32Type (), 3, FALSE), "");
4041 values [ins->dreg] = val;
4051 * EXCEPTION HANDLING
4053 case OP_IMPLICIT_EXCEPTION:
4054 /* This marks a place where an implicit exception can happen */
4055 if (bb->region != -1)
4056 LLVM_FAILURE (ctx, "implicit-exception");
4060 MonoMethodSignature *throw_sig;
4061 LLVMValueRef callee, arg;
4062 gboolean rethrow = (ins->opcode == OP_RETHROW);
4063 const char *icall_name;
4065 callee = rethrow ? ctx->lmodule->rethrow : ctx->lmodule->throw;
4066 icall_name = rethrow ? "mono_arch_rethrow_exception" : "mono_arch_throw_exception";
4069 throw_sig = mono_metadata_signature_alloc (mono_get_corlib (), 1);
4070 throw_sig->ret = &mono_get_void_class ()->byval_arg;
4071 throw_sig->params [0] = &mono_get_object_class ()->byval_arg;
4072 if (cfg->compile_aot) {
4073 callee = get_plt_entry (ctx, sig_to_llvm_sig (ctx, throw_sig), MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
4075 callee = LLVMAddFunction (module, icall_name, sig_to_llvm_sig (ctx, throw_sig));
4079 * LLVM doesn't push the exception argument, so we need a different
4082 LLVMAddGlobalMapping (ee, callee, resolve_patch (cfg, MONO_PATCH_INFO_INTERNAL_METHOD, rethrow ? "llvm_rethrow_exception_trampoline" : "llvm_throw_exception_trampoline"));
4084 LLVMAddGlobalMapping (ee, callee, resolve_patch (cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name));
4088 mono_memory_barrier ();
4090 ctx->lmodule->rethrow = callee;
4092 ctx->lmodule->throw = callee;
4094 arg = convert (ctx, lhs, type_to_llvm_type (ctx, &mono_get_object_class ()->byval_arg));
4095 emit_call (ctx, bb, &builder, callee, &arg, 1);
4098 case OP_CALL_HANDLER: {
4100 * We don't 'call' handlers, but instead simply branch to them.
4101 * The code generated by ENDFINALLY will branch back to us.
4103 LLVMBasicBlockRef noex_bb;
4105 BBInfo *info = &bblocks [ins->inst_target_bb->block_num];
4107 bb_list = info->call_handler_return_bbs;
4110 * Set the indicator variable for the finally clause.
4112 lhs = info->finally_ind;
4114 LLVMBuildStore (builder, LLVMConstInt (LLVMInt32Type (), g_slist_length (bb_list) + 1, FALSE), lhs);
4116 /* Branch to the finally clause */
4117 LLVMBuildBr (builder, info->call_handler_target_bb);
4119 noex_bb = gen_bb (ctx, "CALL_HANDLER_CONT_BB");
4120 info->call_handler_return_bbs = g_slist_append_mempool (cfg->mempool, info->call_handler_return_bbs, noex_bb);
4122 builder = ctx->builder = create_builder (ctx);
4123 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
4125 bblocks [bb->block_num].end_bblock = noex_bb;
4128 case OP_START_HANDLER: {
4131 case OP_ENDFINALLY: {
4132 LLVMBasicBlockRef resume_bb;
4133 MonoBasicBlock *handler_bb;
4134 LLVMValueRef val, switch_ins, callee;
4138 handler_bb = g_hash_table_lookup (ctx->region_to_handler, GUINT_TO_POINTER (mono_get_block_region_notry (cfg, bb->region)));
4139 g_assert (handler_bb);
4140 info = &bblocks [handler_bb->block_num];
4141 lhs = info->finally_ind;
4144 bb_list = info->call_handler_return_bbs;
4146 resume_bb = gen_bb (ctx, "ENDFINALLY_RESUME_BB");
4148 /* Load the finally variable */
4149 val = LLVMBuildLoad (builder, lhs, "");
4151 /* Reset the variable */
4152 LLVMBuildStore (builder, LLVMConstInt (LLVMInt32Type (), 0, FALSE), lhs);
4154 /* Branch to either resume_bb, or to the bblocks in bb_list */
4155 switch_ins = LLVMBuildSwitch (builder, val, resume_bb, g_slist_length (bb_list));
4157 * The other targets are added at the end to handle OP_CALL_HANDLER
4158 * opcodes processed later.
4160 info->endfinally_switch_ins_list = g_slist_append_mempool (cfg->mempool, info->endfinally_switch_ins_list, switch_ins);
4162 builder = ctx->builder = create_builder (ctx);
4163 LLVMPositionBuilderAtEnd (ctx->builder, resume_bb);
4165 if (ctx->cfg->compile_aot) {
4166 callee = get_plt_entry (ctx, LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE), MONO_PATCH_INFO_INTERNAL_METHOD, "llvm_resume_unwind_trampoline");
4168 callee = LLVMGetNamedFunction (module, "llvm_resume_unwind_trampoline");
4170 LLVMBuildCall (builder, callee, NULL, 0, "");
4172 LLVMBuildUnreachable (builder);
4173 has_terminator = TRUE;
4179 sprintf (reason, "opcode %s", mono_inst_name (ins->opcode));
4180 LLVM_FAILURE (ctx, reason);
4185 /* Convert the value to the type required by phi nodes */
4186 if (spec [MONO_INST_DEST] != ' ' && !MONO_IS_STORE_MEMBASE (ins) && ctx->vreg_types [ins->dreg]) {
4187 if (!values [ins->dreg])
4189 values [ins->dreg] = addresses [ins->dreg];
4191 values [ins->dreg] = convert (ctx, values [ins->dreg], ctx->vreg_types [ins->dreg]);
4194 /* Add stores for volatile variables */
4195 if (spec [MONO_INST_DEST] != ' ' && spec [MONO_INST_DEST] != 'v' && !MONO_IS_STORE_MEMBASE (ins))
4196 emit_volatile_store (ctx, ins->dreg);
4199 if (!has_terminator && bb->next_bb && (bb == cfg->bb_entry || bb->in_count > 0))
4200 LLVMBuildBr (builder, get_bb (ctx, bb->next_bb));
4202 if (bb == cfg->bb_exit && sig->ret->type == MONO_TYPE_VOID)
4203 LLVMBuildRetVoid (builder);
4205 if (bb == cfg->bb_entry)
4206 ctx->last_alloca = LLVMGetLastInstruction (get_bb (ctx, cfg->bb_entry));
4215 * mono_llvm_check_method_supported:
4217 * Do some quick checks to decide whenever cfg->method can be compiled by LLVM, to avoid
4218 * compiling a method twice.
4221 mono_llvm_check_method_supported (MonoCompile *cfg)
4223 MonoMethodHeader *header = cfg->header;
4224 MonoExceptionClause *clause;
4227 if (cfg->method->save_lmf) {
4228 cfg->exception_message = g_strdup ("lmf");
4229 cfg->disable_llvm = TRUE;
4233 for (i = 0; i < header->num_clauses; ++i) {
4234 clause = &header->clauses [i];
4236 if (i > 0 && clause->try_offset <= header->clauses [i - 1].handler_offset + header->clauses [i - 1].handler_len) {
4238 * FIXME: Some tests still fail with nested clauses.
4240 cfg->exception_message = g_strdup ("nested clauses");
4241 cfg->disable_llvm = TRUE;
4247 if (cfg->method->dynamic) {
4248 cfg->exception_message = g_strdup ("dynamic.");
4249 cfg->disable_llvm = TRUE;
4254 * mono_llvm_emit_method:
4256 * Emit LLVM IL from the mono IL, and compile it to native code using LLVM.
4259 mono_llvm_emit_method (MonoCompile *cfg)
4262 MonoMethodSignature *sig;
4264 LLVMTypeRef method_type;
4265 LLVMValueRef method = NULL;
4267 LLVMValueRef *values;
4268 int i, max_block_num, bb_index;
4269 gboolean last = FALSE;
4270 GPtrArray *phi_values;
4271 LLVMCallInfo *linfo;
4273 LLVMModuleRef module;
4275 GPtrArray *bblock_list;
4276 MonoMethodHeader *header;
4277 MonoExceptionClause *clause;
4281 /* The code below might acquire the loader lock, so use it for global locking */
4282 mono_loader_lock ();
4284 /* Used to communicate with the callbacks */
4285 mono_native_tls_set_value (current_cfg_tls_id, cfg);
4287 ctx = g_new0 (EmitContext, 1);
4289 ctx->mempool = cfg->mempool;
4292 * This maps vregs to the LLVM instruction defining them
4294 values = g_new0 (LLVMValueRef, cfg->next_vreg);
4296 * This maps vregs for volatile variables to the LLVM instruction defining their
4299 ctx->addresses = g_new0 (LLVMValueRef, cfg->next_vreg);
4300 ctx->vreg_types = g_new0 (LLVMTypeRef, cfg->next_vreg);
4301 ctx->vreg_cli_types = g_new0 (MonoType*, cfg->next_vreg);
4302 phi_values = g_ptr_array_sized_new (256);
4304 * This signals whenever the vreg was defined by a phi node with no input vars
4305 * (i.e. all its input bblocks end with NOT_REACHABLE).
4307 ctx->is_dead = g_new0 (gboolean, cfg->next_vreg);
4308 /* Whenever the bblock is unreachable */
4309 ctx->unreachable = g_new0 (gboolean, cfg->max_block_num);
4311 bblock_list = g_ptr_array_sized_new (256);
4313 ctx->values = values;
4314 ctx->region_to_handler = g_hash_table_new (NULL, NULL);
4316 if (cfg->compile_aot) {
4317 ctx->lmodule = &aot_module;
4318 method_name = mono_aot_get_method_name (cfg);
4319 cfg->llvm_method_name = g_strdup (method_name);
4322 ctx->lmodule = &jit_module;
4323 method_name = mono_method_full_name (cfg->method, TRUE);
4326 module = ctx->module = ctx->lmodule->module;
4329 LLVM_FAILURE (ctx, "gsharedvt");
4333 static int count = 0;
4336 if (g_getenv ("LLVM_COUNT")) {
4337 if (count == atoi (g_getenv ("LLVM_COUNT"))) {
4338 printf ("LAST: %s\n", mono_method_full_name (cfg->method, TRUE));
4342 if (count > atoi (g_getenv ("LLVM_COUNT")))
4343 LLVM_FAILURE (ctx, "");
4348 sig = mono_method_signature (cfg->method);
4351 linfo = mono_arch_get_llvm_call_info (cfg, sig);
4353 CHECK_FAILURE (ctx);
4356 linfo->rgctx_arg = TRUE;
4357 method_type = sig_to_llvm_sig_full (ctx, sig, linfo, &sinfo);
4358 CHECK_FAILURE (ctx);
4361 * This maps parameter indexes in the original signature to the indexes in
4362 * the LLVM signature.
4364 ctx->pindexes = sinfo.pindexes;
4366 method = LLVMAddFunction (module, method_name, method_type);
4367 ctx->lmethod = method;
4369 LLVMSetFunctionCallConv (method, LLVMMono1CallConv);
4370 LLVMSetLinkage (method, LLVMPrivateLinkage);
4372 LLVMAddFunctionAttr (method, LLVMUWTable);
4374 if (cfg->compile_aot) {
4375 LLVMSetLinkage (method, LLVMInternalLinkage);
4376 LLVMSetVisibility (method, LLVMHiddenVisibility);
4378 LLVMSetLinkage (method, LLVMPrivateLinkage);
4381 if (cfg->method->save_lmf)
4382 LLVM_FAILURE (ctx, "lmf");
4384 if (sig->pinvoke && cfg->method->wrapper_type != MONO_WRAPPER_RUNTIME_INVOKE)
4385 LLVM_FAILURE (ctx, "pinvoke signature");
4387 header = cfg->header;
4388 for (i = 0; i < header->num_clauses; ++i) {
4389 clause = &header->clauses [i];
4390 if (clause->flags != MONO_EXCEPTION_CLAUSE_FINALLY && clause->flags != MONO_EXCEPTION_CLAUSE_NONE)
4391 LLVM_FAILURE (ctx, "non-finally/catch clause.");
4394 if (linfo->rgctx_arg) {
4395 ctx->rgctx_arg = LLVMGetParam (method, sinfo.rgctx_arg_pindex);
4397 * We mark the rgctx parameter with the inreg attribute, which is mapped to
4398 * MONO_ARCH_RGCTX_REG in the Mono calling convention in llvm, i.e.
4399 * CC_X86_64_Mono in X86CallingConv.td.
4401 LLVMAddAttribute (ctx->rgctx_arg, LLVMInRegAttribute);
4402 LLVMSetValueName (ctx->rgctx_arg, "rgctx");
4404 if (cfg->vret_addr) {
4405 values [cfg->vret_addr->dreg] = LLVMGetParam (method, sinfo.vret_arg_pindex);
4406 LLVMSetValueName (values [cfg->vret_addr->dreg], "vret");
4409 values [cfg->args [0]->dreg] = LLVMGetParam (method, sinfo.this_arg_pindex);
4410 LLVMSetValueName (values [cfg->args [0]->dreg], "this");
4413 names = g_new (char *, sig->param_count);
4414 mono_method_get_param_names (cfg->method, (const char **) names);
4416 for (i = 0; i < sig->param_count; ++i) {
4419 values [cfg->args [i + sig->hasthis]->dreg] = LLVMGetParam (method, sinfo.pindexes [i]);
4420 if (names [i] && names [i][0] != '\0')
4421 name = g_strdup_printf ("arg_%s", names [i]);
4423 name = g_strdup_printf ("arg_%d", i);
4424 LLVMSetValueName (values [cfg->args [i + sig->hasthis]->dreg], name);
4426 if (linfo->args [i + sig->hasthis].storage == LLVMArgVtypeByVal)
4427 LLVMAddAttribute (LLVMGetParam (method, sinfo.pindexes [i]), LLVMByValAttribute);
4432 for (bb = cfg->bb_entry; bb; bb = bb->next_bb)
4433 max_block_num = MAX (max_block_num, bb->block_num);
4434 ctx->bblocks = bblocks = g_new0 (BBInfo, max_block_num + 1);
4436 /* Add branches between non-consecutive bblocks */
4437 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
4438 if (bb->last_ins && MONO_IS_COND_BRANCH_OP (bb->last_ins) &&
4439 bb->next_bb != bb->last_ins->inst_false_bb) {
4441 MonoInst *inst = mono_mempool_alloc0 (cfg->mempool, sizeof (MonoInst));
4442 inst->opcode = OP_BR;
4443 inst->inst_target_bb = bb->last_ins->inst_false_bb;
4444 mono_bblock_add_inst (bb, inst);
4449 * The INDIRECT flag added by OP_LDADDR inhibits optimizations, even if the LDADDR
4450 * was later optimized away, so clear these flags, and add them back for the still
4451 * present OP_LDADDR instructions.
4453 for (i = 0; i < cfg->next_vreg; ++i) {
4456 ins = get_vreg_to_inst (cfg, i);
4457 if (ins && ins != cfg->rgctx_var)
4458 ins->flags &= ~MONO_INST_INDIRECT;
4462 * Make a first pass over the code to precreate PHI nodes/set INDIRECT flags.
4464 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
4466 LLVMBuilderRef builder;
4468 char dname_buf[128];
4470 builder = create_builder (ctx);
4472 for (ins = bb->code; ins; ins = ins->next) {
4473 switch (ins->opcode) {
4478 LLVMTypeRef phi_type = llvm_type_to_stack_type (type_to_llvm_type (ctx, &ins->klass->byval_arg));
4480 CHECK_FAILURE (ctx);
4482 if (ins->opcode == OP_VPHI) {
4483 /* Treat valuetype PHI nodes as operating on the address itself */
4484 g_assert (ins->klass);
4485 phi_type = LLVMPointerType (type_to_llvm_type (ctx, &ins->klass->byval_arg), 0);
4489 * Have to precreate these, as they can be referenced by
4490 * earlier instructions.
4492 sprintf (dname_buf, "t%d", ins->dreg);
4494 values [ins->dreg] = LLVMBuildPhi (builder, phi_type, dname);
4496 if (ins->opcode == OP_VPHI)
4497 ctx->addresses [ins->dreg] = values [ins->dreg];
4499 g_ptr_array_add (phi_values, values [ins->dreg]);
4502 * Set the expected type of the incoming arguments since these have
4503 * to have the same type.
4505 for (i = 0; i < ins->inst_phi_args [0]; i++) {
4506 int sreg1 = ins->inst_phi_args [i + 1];
4509 ctx->vreg_types [sreg1] = phi_type;
4514 ((MonoInst*)ins->inst_p0)->flags |= MONO_INST_INDIRECT;
4523 * Create an ordering for bblocks, use the depth first order first, then
4524 * put the exception handling bblocks last.
4526 for (bb_index = 0; bb_index < cfg->num_bblocks; ++bb_index) {
4527 bb = cfg->bblocks [bb_index];
4528 if (!(bb->region != -1 && !MONO_BBLOCK_IS_IN_REGION (bb, MONO_REGION_TRY))) {
4529 g_ptr_array_add (bblock_list, bb);
4530 bblocks [bb->block_num].added = TRUE;
4534 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
4535 if (!bblocks [bb->block_num].added)
4536 g_ptr_array_add (bblock_list, bb);
4540 * Second pass: generate code.
4542 for (bb_index = 0; bb_index < bblock_list->len; ++bb_index) {
4543 bb = g_ptr_array_index (bblock_list, bb_index);
4545 if (!(bb == cfg->bb_entry || bb->in_count > 0))
4548 process_bb (ctx, bb);
4549 CHECK_FAILURE (ctx);
4552 /* Add incoming phi values */
4553 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
4554 GSList *l, *ins_list;
4556 ins_list = bblocks [bb->block_num].phi_nodes;
4558 for (l = ins_list; l; l = l->next) {
4559 PhiNode *node = l->data;
4560 MonoInst *phi = node->phi;
4561 int sreg1 = node->sreg;
4562 LLVMBasicBlockRef in_bb;
4567 in_bb = get_end_bb (ctx, node->in_bb);
4569 if (ctx->unreachable [node->in_bb->block_num])
4572 if (!values [sreg1])
4573 /* Can happen with values in EH clauses */
4574 LLVM_FAILURE (ctx, "incoming phi sreg1");
4576 if (phi->opcode == OP_VPHI) {
4577 g_assert (LLVMTypeOf (ctx->addresses [sreg1]) == LLVMTypeOf (values [phi->dreg]));
4578 LLVMAddIncoming (values [phi->dreg], &ctx->addresses [sreg1], &in_bb, 1);
4580 if (LLVMTypeOf (values [sreg1]) != LLVMTypeOf (values [phi->dreg]))
4582 LLVM_FAILURE (ctx, "incoming phi arg type mismatch");
4583 g_assert (LLVMTypeOf (values [sreg1]) == LLVMTypeOf (values [phi->dreg]));
4584 LLVMAddIncoming (values [phi->dreg], &values [sreg1], &in_bb, 1);
4589 /* Create the SWITCH statements for ENDFINALLY instructions */
4590 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
4591 BBInfo *info = &bblocks [bb->block_num];
4593 for (l = info->endfinally_switch_ins_list; l; l = l->next) {
4594 LLVMValueRef switch_ins = l->data;
4595 GSList *bb_list = info->call_handler_return_bbs;
4597 for (i = 0; i < g_slist_length (bb_list); ++i)
4598 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), i + 1, FALSE), g_slist_nth (bb_list, i)->data);
4602 if (cfg->verbose_level > 1)
4603 mono_llvm_dump_value (method);
4605 if (cfg->compile_aot)
4606 mark_as_used (ctx->lmodule, method);
4608 if (cfg->compile_aot) {
4609 LLVMValueRef md_args [16];
4610 LLVMValueRef md_node;
4613 method_index = mono_aot_get_method_index (cfg->orig_method);
4614 md_args [0] = LLVMMDString (method_name, strlen (method_name));
4615 md_args [1] = LLVMConstInt (LLVMInt32Type (), method_index, FALSE);
4616 md_node = LLVMMDNode (md_args, 2);
4617 LLVMAddNamedMetadataOperand (module, "mono.function_indexes", md_node);
4618 //LLVMSetMetadata (method, md_kind, LLVMMDNode (&md_arg, 1));
4621 if (cfg->compile_aot) {
4622 /* Don't generate native code, keep the LLVM IR */
4623 if (cfg->compile_aot && cfg->verbose_level)
4624 printf ("%s emitted as %s\n", mono_method_full_name (cfg->method, TRUE), method_name);
4626 //LLVMVerifyFunction(method, 0);
4628 mono_llvm_optimize_method (method);
4630 if (cfg->verbose_level > 1)
4631 mono_llvm_dump_value (method);
4633 cfg->native_code = LLVMGetPointerToGlobal (ee, method);
4635 /* Set by emit_cb */
4636 g_assert (cfg->code_len);
4638 /* FIXME: Free the LLVM IL for the function */
4646 /* Need to add unused phi nodes as they can be referenced by other values */
4647 LLVMBasicBlockRef phi_bb = LLVMAppendBasicBlock (method, "PHI_BB");
4648 LLVMBuilderRef builder;
4650 builder = create_builder (ctx);
4651 LLVMPositionBuilderAtEnd (builder, phi_bb);
4653 for (i = 0; i < phi_values->len; ++i) {
4654 LLVMValueRef v = g_ptr_array_index (phi_values, i);
4655 if (LLVMGetInstructionParent (v) == NULL)
4656 LLVMInsertIntoBuilder (builder, v);
4659 LLVMDeleteFunction (method);
4664 g_free (ctx->addresses);
4665 g_free (ctx->vreg_types);
4666 g_free (ctx->vreg_cli_types);
4667 g_free (ctx->pindexes);
4668 g_free (ctx->is_dead);
4669 g_free (ctx->unreachable);
4670 g_ptr_array_free (phi_values, TRUE);
4671 g_free (ctx->bblocks);
4672 g_hash_table_destroy (ctx->region_to_handler);
4673 g_free (method_name);
4674 g_ptr_array_free (bblock_list, TRUE);
4676 for (l = ctx->builders; l; l = l->next) {
4677 LLVMBuilderRef builder = l->data;
4678 LLVMDisposeBuilder (builder);
4683 mono_native_tls_set_value (current_cfg_tls_id, NULL);
4685 mono_loader_unlock ();
4689 * mono_llvm_emit_call:
4691 * Same as mono_arch_emit_call () for LLVM.
4694 mono_llvm_emit_call (MonoCompile *cfg, MonoCallInst *call)
4697 MonoMethodSignature *sig;
4698 int i, n, stack_size;
4703 sig = call->signature;
4704 n = sig->param_count + sig->hasthis;
4706 call->cinfo = mono_arch_get_llvm_call_info (cfg, sig);
4708 if (cfg->disable_llvm)
4711 if (sig->call_convention == MONO_CALL_VARARG) {
4712 cfg->exception_message = g_strdup ("varargs");
4713 cfg->disable_llvm = TRUE;
4716 for (i = 0; i < n; ++i) {
4719 ainfo = call->cinfo->args + i;
4721 in = call->args [i];
4723 /* Simply remember the arguments */
4724 switch (ainfo->storage) {
4726 case LLVMArgInFPReg: {
4727 MonoType *t = (sig->hasthis && i == 0) ? &mono_get_intptr_class ()->byval_arg : sig->params [i - sig->hasthis];
4729 if (!t->byref && (t->type == MONO_TYPE_R8 || t->type == MONO_TYPE_R4)) {
4730 MONO_INST_NEW (cfg, ins, OP_FMOVE);
4731 ins->dreg = mono_alloc_freg (cfg);
4733 MONO_INST_NEW (cfg, ins, OP_MOVE);
4734 ins->dreg = mono_alloc_ireg (cfg);
4736 ins->sreg1 = in->dreg;
4739 case LLVMArgVtypeByVal:
4740 case LLVMArgVtypeInReg:
4741 MONO_INST_NEW (cfg, ins, OP_LLVM_OUTARG_VT);
4742 ins->dreg = mono_alloc_ireg (cfg);
4743 ins->sreg1 = in->dreg;
4744 ins->klass = mono_class_from_mono_type (sig->params [i - sig->hasthis]);
4747 call->cinfo = mono_arch_get_llvm_call_info (cfg, sig);
4748 cfg->exception_message = g_strdup ("ainfo->storage");
4749 cfg->disable_llvm = TRUE;
4753 if (!cfg->disable_llvm) {
4754 MONO_ADD_INS (cfg->cbb, ins);
4755 mono_call_inst_add_outarg_reg (cfg, call, ins->dreg, 0, FALSE);
4760 static unsigned char*
4761 alloc_cb (LLVMValueRef function, int size)
4765 cfg = mono_native_tls_get_value (current_cfg_tls_id);
4769 return mono_domain_code_reserve (cfg->domain, size);
4771 return mono_domain_code_reserve (mono_domain_get (), size);
4776 emitted_cb (LLVMValueRef function, void *start, void *end)
4780 cfg = mono_native_tls_get_value (current_cfg_tls_id);
4782 cfg->code_len = (guint8*)end - (guint8*)start;
4786 exception_cb (void *data)
4789 MonoJitExceptionInfo *ei;
4790 guint32 ei_len, i, j, nested_len, nindex;
4791 gpointer *type_info;
4792 int this_reg, this_offset;
4794 cfg = mono_native_tls_get_value (current_cfg_tls_id);
4798 * data points to a DWARF FDE structure, convert it to our unwind format and
4800 * An alternative would be to save it directly, and modify our unwinder to work
4803 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);
4804 if (cfg->verbose_level > 1)
4805 mono_print_unwind_info (cfg->encoded_unwind_ops, cfg->encoded_unwind_ops_len);
4807 /* Count nested clauses */
4809 for (i = 0; i < ei_len; ++i) {
4810 for (j = 0; j < ei_len; ++j) {
4811 gint32 cindex1 = *(gint32*)type_info [i];
4812 MonoExceptionClause *clause1 = &cfg->header->clauses [cindex1];
4813 gint32 cindex2 = *(gint32*)type_info [j];
4814 MonoExceptionClause *clause2 = &cfg->header->clauses [cindex2];
4816 if (cindex1 != cindex2 && clause1->try_offset >= clause2->try_offset && clause1->handler_offset <= clause2->handler_offset) {
4822 cfg->llvm_ex_info = mono_mempool_alloc0 (cfg->mempool, (ei_len + nested_len) * sizeof (MonoJitExceptionInfo));
4823 cfg->llvm_ex_info_len = ei_len + nested_len;
4824 memcpy (cfg->llvm_ex_info, ei, ei_len * sizeof (MonoJitExceptionInfo));
4825 /* Fill the rest of the information from the type info */
4826 for (i = 0; i < ei_len; ++i) {
4827 gint32 clause_index = *(gint32*)type_info [i];
4828 MonoExceptionClause *clause = &cfg->header->clauses [clause_index];
4830 cfg->llvm_ex_info [i].flags = clause->flags;
4831 cfg->llvm_ex_info [i].data.catch_class = clause->data.catch_class;
4835 * For nested clauses, the LLVM produced exception info associates the try interval with
4836 * the innermost handler, while mono expects it to be associated with all nesting clauses.
4838 /* FIXME: These should be order with the normal clauses */
4840 for (i = 0; i < ei_len; ++i) {
4841 for (j = 0; j < ei_len; ++j) {
4842 gint32 cindex1 = *(gint32*)type_info [i];
4843 MonoExceptionClause *clause1 = &cfg->header->clauses [cindex1];
4844 gint32 cindex2 = *(gint32*)type_info [j];
4845 MonoExceptionClause *clause2 = &cfg->header->clauses [cindex2];
4847 if (cindex1 != cindex2 && clause1->try_offset >= clause2->try_offset && clause1->handler_offset <= clause2->handler_offset) {
4849 * The try interval comes from the nested clause, everything else from the
4852 memcpy (&cfg->llvm_ex_info [nindex], &cfg->llvm_ex_info [j], sizeof (MonoJitExceptionInfo));
4853 cfg->llvm_ex_info [nindex].try_start = cfg->llvm_ex_info [i].try_start;
4854 cfg->llvm_ex_info [nindex].try_end = cfg->llvm_ex_info [i].try_end;
4859 g_assert (nindex == ei_len + nested_len);
4860 cfg->llvm_this_reg = this_reg;
4861 cfg->llvm_this_offset = this_offset;
4863 /* type_info [i] is cfg mempool allocated, no need to free it */
4870 dlsym_cb (const char *name, void **symbol)
4876 if (!strcmp (name, "__bzero")) {
4877 *symbol = (void*)bzero;
4879 current = mono_dl_open (NULL, 0, NULL);
4882 err = mono_dl_symbol (current, name, symbol);
4884 #ifdef MONO_ARCH_HAVE_CREATE_LLVM_NATIVE_THUNK
4885 *symbol = (char*)mono_arch_create_llvm_native_thunk (mono_domain_get (), (guint8*)(*symbol));
4891 AddFunc (LLVMModuleRef module, const char *name, LLVMTypeRef ret_type, LLVMTypeRef *param_types, int nparams)
4893 LLVMAddFunction (module, name, LLVMFunctionType (ret_type, param_types, nparams, FALSE));
4897 AddFunc2 (LLVMModuleRef module, const char *name, LLVMTypeRef ret_type, LLVMTypeRef param_type1, LLVMTypeRef param_type2)
4899 LLVMTypeRef param_types [4];
4901 param_types [0] = param_type1;
4902 param_types [1] = param_type2;
4904 AddFunc (module, name, ret_type, param_types, 2);
4908 add_intrinsics (LLVMModuleRef module)
4910 /* Emit declarations of instrinsics */
4912 * It would be nicer to emit only the intrinsics actually used, but LLVM's Module
4913 * type doesn't seem to do any locking.
4916 LLVMTypeRef memset_params [] = { LLVMPointerType (LLVMInt8Type (), 0), LLVMInt8Type (), LLVMInt32Type (), LLVMInt32Type (), LLVMInt1Type () };
4918 memset_param_count = 5;
4919 memset_func_name = "llvm.memset.p0i8.i32";
4921 LLVMAddFunction (module, memset_func_name, LLVMFunctionType (LLVMVoidType (), memset_params, memset_param_count, FALSE));
4925 LLVMTypeRef memcpy_params [] = { LLVMPointerType (LLVMInt8Type (), 0), LLVMPointerType (LLVMInt8Type (), 0), LLVMInt32Type (), LLVMInt32Type (), LLVMInt1Type () };
4927 memcpy_param_count = 5;
4928 memcpy_func_name = "llvm.memcpy.p0i8.p0i8.i32";
4930 LLVMAddFunction (module, memcpy_func_name, LLVMFunctionType (LLVMVoidType (), memcpy_params, memcpy_param_count, FALSE));
4934 LLVMTypeRef params [] = { LLVMDoubleType () };
4936 LLVMAddFunction (module, "llvm.sin.f64", LLVMFunctionType (LLVMDoubleType (), params, 1, FALSE));
4937 LLVMAddFunction (module, "llvm.cos.f64", LLVMFunctionType (LLVMDoubleType (), params, 1, FALSE));
4938 LLVMAddFunction (module, "llvm.sqrt.f64", LLVMFunctionType (LLVMDoubleType (), params, 1, FALSE));
4940 /* This isn't an intrinsic, instead llvm seems to special case it by name */
4941 LLVMAddFunction (module, "fabs", LLVMFunctionType (LLVMDoubleType (), params, 1, FALSE));
4945 LLVMTypeRef ovf_res_i32 [] = { LLVMInt32Type (), LLVMInt1Type () };
4946 LLVMTypeRef ovf_params_i32 [] = { LLVMInt32Type (), LLVMInt32Type () };
4948 LLVMAddFunction (module, "llvm.sadd.with.overflow.i32", LLVMFunctionType (LLVMStructType (ovf_res_i32, 2, FALSE), ovf_params_i32, 2, FALSE));
4949 LLVMAddFunction (module, "llvm.uadd.with.overflow.i32", LLVMFunctionType (LLVMStructType (ovf_res_i32, 2, FALSE), ovf_params_i32, 2, FALSE));
4950 LLVMAddFunction (module, "llvm.ssub.with.overflow.i32", LLVMFunctionType (LLVMStructType (ovf_res_i32, 2, FALSE), ovf_params_i32, 2, FALSE));
4951 LLVMAddFunction (module, "llvm.usub.with.overflow.i32", LLVMFunctionType (LLVMStructType (ovf_res_i32, 2, FALSE), ovf_params_i32, 2, FALSE));
4952 LLVMAddFunction (module, "llvm.smul.with.overflow.i32", LLVMFunctionType (LLVMStructType (ovf_res_i32, 2, FALSE), ovf_params_i32, 2, FALSE));
4953 LLVMAddFunction (module, "llvm.umul.with.overflow.i32", LLVMFunctionType (LLVMStructType (ovf_res_i32, 2, FALSE), ovf_params_i32, 2, FALSE));
4957 LLVMTypeRef ovf_res_i64 [] = { LLVMInt64Type (), LLVMInt1Type () };
4958 LLVMTypeRef ovf_params_i64 [] = { LLVMInt64Type (), LLVMInt64Type () };
4960 LLVMAddFunction (module, "llvm.sadd.with.overflow.i64", LLVMFunctionType (LLVMStructType (ovf_res_i64, 2, FALSE), ovf_params_i64, 2, FALSE));
4961 LLVMAddFunction (module, "llvm.uadd.with.overflow.i64", LLVMFunctionType (LLVMStructType (ovf_res_i64, 2, FALSE), ovf_params_i64, 2, FALSE));
4962 LLVMAddFunction (module, "llvm.ssub.with.overflow.i64", LLVMFunctionType (LLVMStructType (ovf_res_i64, 2, FALSE), ovf_params_i64, 2, FALSE));
4963 LLVMAddFunction (module, "llvm.usub.with.overflow.i64", LLVMFunctionType (LLVMStructType (ovf_res_i64, 2, FALSE), ovf_params_i64, 2, FALSE));
4964 LLVMAddFunction (module, "llvm.smul.with.overflow.i64", LLVMFunctionType (LLVMStructType (ovf_res_i64, 2, FALSE), ovf_params_i64, 2, FALSE));
4965 LLVMAddFunction (module, "llvm.umul.with.overflow.i64", LLVMFunctionType (LLVMStructType (ovf_res_i64, 2, FALSE), ovf_params_i64, 2, FALSE));
4970 LLVMTypeRef arg_types [2];
4971 LLVMTypeRef ret_type;
4973 arg_types [0] = LLVMPointerType (LLVMInt8Type (), 0);
4974 arg_types [1] = LLVMPointerType (LLVMInt8Type (), 0);
4975 ret_type = LLVMInt32Type ();
4977 LLVMAddFunction (module, "mono_personality", LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE));
4979 LLVMAddFunction (module, "llvm_resume_unwind_trampoline", LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE));
4982 /* SSE intrinsics */
4983 #if defined(TARGET_X86) || defined(TARGET_AMD64)
4985 LLVMTypeRef ret_type, arg_types [16];
4988 ret_type = type_to_simd_type (MONO_TYPE_I4);
4989 arg_types [0] = ret_type;
4990 arg_types [1] = ret_type;
4991 AddFunc (module, "llvm.x86.sse41.pminud", ret_type, arg_types, 2);
4992 AddFunc (module, "llvm.x86.sse41.pmaxud", ret_type, arg_types, 2);
4994 ret_type = type_to_simd_type (MONO_TYPE_I2);
4995 arg_types [0] = ret_type;
4996 arg_types [1] = ret_type;
4997 AddFunc (module, "llvm.x86.sse41.pminuw", ret_type, arg_types, 2);
4998 AddFunc (module, "llvm.x86.sse2.pmins.w", ret_type, arg_types, 2);
4999 AddFunc (module, "llvm.x86.sse41.pmaxuw", ret_type, arg_types, 2);
5000 AddFunc (module, "llvm.x86.sse2.padds.w", ret_type, arg_types, 2);
5001 AddFunc (module, "llvm.x86.sse2.psubs.w", ret_type, arg_types, 2);
5002 AddFunc (module, "llvm.x86.sse2.paddus.w", ret_type, arg_types, 2);
5003 AddFunc (module, "llvm.x86.sse2.psubus.w", ret_type, arg_types, 2);
5004 AddFunc (module, "llvm.x86.sse2.pavg.w", ret_type, arg_types, 2);
5005 AddFunc (module, "llvm.x86.sse2.pmulh.w", ret_type, arg_types, 2);
5006 AddFunc (module, "llvm.x86.sse2.pmulhu.w", ret_type, arg_types, 2);
5008 ret_type = type_to_simd_type (MONO_TYPE_I1);
5009 arg_types [0] = ret_type;
5010 arg_types [1] = ret_type;
5011 AddFunc (module, "llvm.x86.sse2.pminu.b", ret_type, arg_types, 2);
5012 AddFunc (module, "llvm.x86.sse2.pmaxu.b", ret_type, arg_types, 2);
5013 AddFunc (module, "llvm.x86.sse2.padds.b", ret_type, arg_types, 2);
5014 AddFunc (module, "llvm.x86.sse2.psubs.b", ret_type, arg_types, 2);
5015 AddFunc (module, "llvm.x86.sse2.paddus.b", ret_type, arg_types, 2);
5016 AddFunc (module, "llvm.x86.sse2.psubus.b", ret_type, arg_types, 2);
5017 AddFunc (module, "llvm.x86.sse2.pavg.b", ret_type, arg_types, 2);
5019 ret_type = type_to_simd_type (MONO_TYPE_R8);
5020 arg_types [0] = ret_type;
5021 arg_types [1] = ret_type;
5022 AddFunc (module, "llvm.x86.sse2.min.pd", ret_type, arg_types, 2);
5023 AddFunc (module, "llvm.x86.sse2.max.pd", ret_type, arg_types, 2);
5024 AddFunc (module, "llvm.x86.sse3.hadd.pd", ret_type, arg_types, 2);
5025 AddFunc (module, "llvm.x86.sse3.hsub.pd", ret_type, arg_types, 2);
5026 AddFunc (module, "llvm.x86.sse3.addsub.pd", ret_type, arg_types, 2);
5028 ret_type = type_to_simd_type (MONO_TYPE_R4);
5029 arg_types [0] = ret_type;
5030 arg_types [1] = ret_type;
5031 AddFunc (module, "llvm.x86.sse.min.ps", ret_type, arg_types, 2);
5032 AddFunc (module, "llvm.x86.sse.max.ps", ret_type, arg_types, 2);
5033 AddFunc (module, "llvm.x86.sse3.hadd.ps", ret_type, arg_types, 2);
5034 AddFunc (module, "llvm.x86.sse3.hsub.ps", ret_type, arg_types, 2);
5035 AddFunc (module, "llvm.x86.sse3.addsub.ps", ret_type, arg_types, 2);
5038 ret_type = type_to_simd_type (MONO_TYPE_I1);
5039 arg_types [0] = type_to_simd_type (MONO_TYPE_I2);
5040 arg_types [1] = type_to_simd_type (MONO_TYPE_I2);
5041 AddFunc (module, "llvm.x86.sse2.packsswb.128", ret_type, arg_types, 2);
5042 AddFunc (module, "llvm.x86.sse2.packuswb.128", ret_type, arg_types, 2);
5043 ret_type = type_to_simd_type (MONO_TYPE_I2);
5044 arg_types [0] = type_to_simd_type (MONO_TYPE_I4);
5045 arg_types [1] = type_to_simd_type (MONO_TYPE_I4);
5046 AddFunc (module, "llvm.x86.sse2.packssdw.128", ret_type, arg_types, 2);
5047 AddFunc (module, "llvm.x86.sse41.packusdw", ret_type, arg_types, 2);
5050 ret_type = type_to_simd_type (MONO_TYPE_R8);
5051 arg_types [0] = ret_type;
5052 arg_types [1] = ret_type;
5053 arg_types [2] = LLVMInt8Type ();
5054 AddFunc (module, "llvm.x86.sse2.cmp.pd", ret_type, arg_types, 3);
5055 ret_type = type_to_simd_type (MONO_TYPE_R4);
5056 arg_types [0] = ret_type;
5057 arg_types [1] = ret_type;
5058 arg_types [2] = LLVMInt8Type ();
5059 AddFunc (module, "llvm.x86.sse.cmp.ps", ret_type, arg_types, 3);
5061 /* Conversion ops */
5062 ret_type = type_to_simd_type (MONO_TYPE_R8);
5063 arg_types [0] = type_to_simd_type (MONO_TYPE_I4);
5064 AddFunc (module, "llvm.x86.sse2.cvtdq2pd", ret_type, arg_types, 1);
5065 ret_type = type_to_simd_type (MONO_TYPE_R4);
5066 arg_types [0] = type_to_simd_type (MONO_TYPE_I4);
5067 AddFunc (module, "llvm.x86.sse2.cvtdq2ps", ret_type, arg_types, 1);
5068 ret_type = type_to_simd_type (MONO_TYPE_I4);
5069 arg_types [0] = type_to_simd_type (MONO_TYPE_R8);
5070 AddFunc (module, "llvm.x86.sse2.cvtpd2dq", ret_type, arg_types, 1);
5071 ret_type = type_to_simd_type (MONO_TYPE_I4);
5072 arg_types [0] = type_to_simd_type (MONO_TYPE_R4);
5073 AddFunc (module, "llvm.x86.sse2.cvtps2dq", ret_type, arg_types, 1);
5074 ret_type = type_to_simd_type (MONO_TYPE_R4);
5075 arg_types [0] = type_to_simd_type (MONO_TYPE_R8);
5076 AddFunc (module, "llvm.x86.sse2.cvtpd2ps", ret_type, arg_types, 1);
5077 ret_type = type_to_simd_type (MONO_TYPE_R8);
5078 arg_types [0] = type_to_simd_type (MONO_TYPE_R4);
5079 AddFunc (module, "llvm.x86.sse2.cvtps2pd", ret_type, arg_types, 1);
5081 ret_type = type_to_simd_type (MONO_TYPE_I4);
5082 arg_types [0] = type_to_simd_type (MONO_TYPE_R8);
5083 AddFunc (module, "llvm.x86.sse2.cvttpd2dq", ret_type, arg_types, 1);
5084 ret_type = type_to_simd_type (MONO_TYPE_I4);
5085 arg_types [0] = type_to_simd_type (MONO_TYPE_R4);
5086 AddFunc (module, "llvm.x86.sse2.cvttps2dq", ret_type, arg_types, 1);
5089 ret_type = type_to_simd_type (MONO_TYPE_R8);
5090 arg_types [0] = ret_type;
5091 AddFunc (module, "llvm.x86.sse2.sqrt.pd", ret_type, arg_types, 1);
5092 ret_type = type_to_simd_type (MONO_TYPE_R4);
5093 arg_types [0] = ret_type;
5094 AddFunc (module, "llvm.x86.sse.sqrt.ps", ret_type, arg_types, 1);
5095 ret_type = type_to_simd_type (MONO_TYPE_R4);
5096 arg_types [0] = ret_type;
5097 AddFunc (module, "llvm.x86.sse.rsqrt.ps", ret_type, arg_types, 1);
5098 ret_type = type_to_simd_type (MONO_TYPE_R4);
5099 arg_types [0] = ret_type;
5100 AddFunc (module, "llvm.x86.sse.rcp.ps", ret_type, arg_types, 1);
5103 ret_type = type_to_simd_type (MONO_TYPE_I2);
5104 arg_types [0] = ret_type;
5105 arg_types [1] = LLVMInt32Type ();
5106 AddFunc (module, "llvm.x86.sse2.psrli.w", ret_type, arg_types, 2);
5107 AddFunc (module, "llvm.x86.sse2.psrai.w", ret_type, arg_types, 2);
5108 AddFunc (module, "llvm.x86.sse2.pslli.w", ret_type, arg_types, 2);
5109 ret_type = type_to_simd_type (MONO_TYPE_I4);
5110 arg_types [0] = ret_type;
5111 arg_types [1] = LLVMInt32Type ();
5112 AddFunc (module, "llvm.x86.sse2.psrli.d", ret_type, arg_types, 2);
5113 AddFunc (module, "llvm.x86.sse2.psrai.d", ret_type, arg_types, 2);
5114 AddFunc (module, "llvm.x86.sse2.pslli.d", ret_type, arg_types, 2);
5115 ret_type = type_to_simd_type (MONO_TYPE_I8);
5116 arg_types [0] = ret_type;
5117 arg_types [1] = LLVMInt32Type ();
5118 AddFunc (module, "llvm.x86.sse2.psrli.q", ret_type, arg_types, 2);
5119 AddFunc (module, "llvm.x86.sse2.pslli.q", ret_type, arg_types, 2);
5122 ret_type = LLVMInt32Type ();
5123 arg_types [0] = type_to_simd_type (MONO_TYPE_I1);
5124 AddFunc (module, "llvm.x86.sse2.pmovmskb.128", ret_type, arg_types, 1);
5127 AddFunc (module, "llvm.x86.sse2.pause", LLVMVoidType (), NULL, 0);
5130 /* Load/Store intrinsics */
5132 LLVMTypeRef arg_types [5];
5136 for (i = 1; i <= 8; i *= 2) {
5137 arg_types [0] = LLVMPointerType (LLVMIntType (i * 8), 0);
5138 arg_types [1] = LLVMInt32Type ();
5139 arg_types [2] = LLVMInt1Type ();
5140 sprintf (name, "llvm.mono.load.i%d.p0i%d", i * 8, i * 8);
5141 LLVMAddFunction (module, name, LLVMFunctionType (LLVMIntType (i * 8), arg_types, 3, FALSE));
5143 arg_types [0] = LLVMIntType (i * 8);
5144 arg_types [1] = LLVMPointerType (LLVMIntType (i * 8), 0);
5145 arg_types [2] = LLVMInt32Type ();
5146 arg_types [3] = LLVMInt1Type ();
5147 sprintf (name, "llvm.mono.store.i%d.p0i%d", i * 8, i * 8);
5148 LLVMAddFunction (module, name, LLVMFunctionType (LLVMVoidType (), arg_types, 4, FALSE));
5154 add_types (MonoLLVMModule *lmodule)
5156 lmodule->ptr_type = LLVMPointerType (sizeof (gpointer) == 8 ? LLVMInt64Type () : LLVMInt32Type (), 0);
5160 mono_llvm_init (void)
5162 mono_native_tls_alloc (¤t_cfg_tls_id, NULL);
5166 init_jit_module (void)
5168 MonoJitICallInfo *info;
5170 if (jit_module_inited)
5173 mono_loader_lock ();
5175 if (jit_module_inited) {
5176 mono_loader_unlock ();
5180 jit_module.module = LLVMModuleCreateWithName ("mono");
5182 ee = mono_llvm_create_ee (LLVMCreateModuleProviderForExistingModule (jit_module.module), alloc_cb, emitted_cb, exception_cb, dlsym_cb);
5184 add_intrinsics (jit_module.module);
5185 add_types (&jit_module);
5187 jit_module.llvm_types = g_hash_table_new (NULL, NULL);
5189 info = mono_find_jit_icall_by_name ("llvm_resume_unwind_trampoline");
5191 LLVMAddGlobalMapping (ee, LLVMGetNamedFunction (jit_module.module, "llvm_resume_unwind_trampoline"), (void*)info->func);
5193 jit_module_inited = TRUE;
5195 mono_loader_unlock ();
5199 mono_llvm_cleanup (void)
5202 mono_llvm_dispose_ee (ee);
5204 if (jit_module.llvm_types)
5205 g_hash_table_destroy (jit_module.llvm_types);
5207 if (aot_module.module)
5208 LLVMDisposeModule (aot_module.module);
5210 LLVMContextDispose (LLVMGetGlobalContext ());
5214 mono_llvm_create_aot_module (const char *got_symbol)
5216 /* Delete previous module */
5217 if (aot_module.plt_entries)
5218 g_hash_table_destroy (aot_module.plt_entries);
5219 if (aot_module.module)
5220 LLVMDisposeModule (aot_module.module);
5222 memset (&aot_module, 0, sizeof (aot_module));
5224 aot_module.module = LLVMModuleCreateWithName ("aot");
5225 aot_module.got_symbol = got_symbol;
5227 add_intrinsics (aot_module.module);
5228 add_types (&aot_module);
5232 * We couldn't compute the type of the LLVM global representing the got because
5233 * its size is only known after all the methods have been emitted. So create
5234 * a dummy variable, and replace all uses it with the real got variable when
5235 * its size is known in mono_llvm_emit_aot_module ().
5238 LLVMTypeRef got_type = LLVMArrayType (aot_module.ptr_type, 0);
5240 aot_module.got_var = LLVMAddGlobal (aot_module.module, got_type, "mono_dummy_got");
5241 LLVMSetInitializer (aot_module.got_var, LLVMConstNull (got_type));
5244 /* Add a dummy personality function */
5246 LLVMBasicBlockRef lbb;
5247 LLVMBuilderRef lbuilder;
5248 LLVMValueRef personality;
5250 personality = LLVMAddFunction (aot_module.module, "mono_aot_personality", LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE));
5251 LLVMSetLinkage (personality, LLVMInternalLinkage);
5252 lbb = LLVMAppendBasicBlock (personality, "BB0");
5253 lbuilder = LLVMCreateBuilder ();
5254 LLVMPositionBuilderAtEnd (lbuilder, lbb);
5255 LLVMBuildRetVoid (lbuilder);
5258 aot_module.llvm_types = g_hash_table_new (NULL, NULL);
5259 aot_module.plt_entries = g_hash_table_new (g_str_hash, g_str_equal);
5263 * Emit the aot module into the LLVM bitcode file FILENAME.
5266 mono_llvm_emit_aot_module (const char *filename, int got_size)
5268 LLVMTypeRef got_type;
5269 LLVMValueRef real_got;
5272 * Create the real got variable and replace all uses of the dummy variable with
5275 got_type = LLVMArrayType (aot_module.ptr_type, got_size);
5276 real_got = LLVMAddGlobal (aot_module.module, got_type, aot_module.got_symbol);
5277 LLVMSetInitializer (real_got, LLVMConstNull (got_type));
5278 LLVMSetLinkage (real_got, LLVMInternalLinkage);
5280 mono_llvm_replace_uses_of (aot_module.got_var, real_got);
5282 mark_as_used (&aot_module, real_got);
5284 /* Delete the dummy got so it doesn't become a global */
5285 LLVMDeleteGlobal (aot_module.got_var);
5287 emit_llvm_used (&aot_module);
5293 if (LLVMVerifyModule (aot_module.module, LLVMReturnStatusAction, &verifier_err)) {
5294 g_assert_not_reached ();
5299 LLVMWriteBitcodeToFile (aot_module.module, filename);
5304 - Emit LLVM IR from the mono IR using the LLVM C API.
5305 - The original arch specific code remains, so we can fall back to it if we run
5306 into something we can't handle.
5310 A partial list of issues:
5311 - Handling of opcodes which can throw exceptions.
5313 In the mono JIT, these are implemented using code like this:
5320 push throw_pos - method
5321 call <exception trampoline>
5323 The problematic part is push throw_pos - method, which cannot be represented
5324 in the LLVM IR, since it does not support label values.
5325 -> this can be implemented in AOT mode using inline asm + labels, but cannot
5326 be implemented in JIT mode ?
5327 -> a possible but slower implementation would use the normal exception
5328 throwing code but it would need to control the placement of the throw code
5329 (it needs to be exactly after the compare+branch).
5330 -> perhaps add a PC offset intrinsics ?
5332 - efficient implementation of .ovf opcodes.
5334 These are currently implemented as:
5335 <ins which sets the condition codes>
5338 Some overflow opcodes are now supported by LLVM SVN.
5340 - exception handling, unwinding.
5341 - SSA is disabled for methods with exception handlers
5342 - How to obtain unwind info for LLVM compiled methods ?
5343 -> this is now solved by converting the unwind info generated by LLVM
5345 - LLVM uses the c++ exception handling framework, while we use our home grown
5346 code, and couldn't use the c++ one:
5347 - its not supported under VC++, other exotic platforms.
5348 - it might be impossible to support filter clauses with it.
5352 The trampolines need a predictable call sequence, since they need to disasm
5353 the calling code to obtain register numbers / offsets.
5355 LLVM currently generates this code in non-JIT mode:
5356 mov -0x98(%rax),%eax
5358 Here, the vtable pointer is lost.
5359 -> solution: use one vtable trampoline per class.
5361 - passing/receiving the IMT pointer/RGCTX.
5362 -> solution: pass them as normal arguments ?
5366 LLVM does not allow the specification of argument registers etc. This means
5367 that all calls are made according to the platform ABI.
5369 - passing/receiving vtypes.
5371 Vtypes passed/received in registers are handled by the front end by using
5372 a signature with scalar arguments, and loading the parts of the vtype into those
5375 Vtypes passed on the stack are handled using the 'byval' attribute.
5379 Supported though alloca, we need to emit the load/store code.
5383 The mono JIT uses pointer sized iregs/double fregs, while LLVM uses precisely
5384 typed registers, so we have to keep track of the precise LLVM type of each vreg.
5385 This is made easier because the IR is already in SSA form.
5386 An additional problem is that our IR is not consistent with types, i.e. i32/ia64
5387 types are frequently used incorrectly.
5392 Emit LLVM bytecode into a .bc file, compile it using llc into a .s file, then
5393 append the AOT data structures to that file. For methods which cannot be
5394 handled by LLVM, the normal JIT compiled versions are used.
5397 /* FIXME: Normalize some aspects of the mono IR to allow easier translation, like:
5398 * - each bblock should end with a branch
5399 * - setting the return value, making cfg->ret non-volatile
5400 * - avoid some transformations in the JIT which make it harder for us to generate
5402 * - use pointer types to help optimizations.