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>
13 #include <mono/utils/mono-time.h>
15 #ifndef __STDC_LIMIT_MACROS
16 #define __STDC_LIMIT_MACROS
18 #ifndef __STDC_CONSTANT_MACROS
19 #define __STDC_CONSTANT_MACROS
22 #include "llvm-c/Core.h"
23 #include "llvm-c/ExecutionEngine.h"
24 #include "llvm-c/BitWriter.h"
25 #include "llvm-c/Analysis.h"
27 #include "mini-llvm-cpp.h"
30 * Information associated by mono with LLVM modules.
34 LLVMValueRef throw, rethrow, throw_corlib_exception;
35 GHashTable *llvm_types;
37 const char *got_symbol;
38 GHashTable *plt_entries;
39 GHashTable *plt_entries_ji;
40 GHashTable *method_to_lmethod;
46 LLVMExecutionEngineRef ee;
50 * Information associated by the backend with mono basic blocks.
53 LLVMBasicBlockRef bblock, end_bblock;
54 LLVMValueRef finally_ind;
55 gboolean added, invoke_target;
57 * If this bblock is the start of a finally clause, this is a list of bblocks it
58 * needs to branch to in ENDFINALLY.
60 GSList *call_handler_return_bbs;
62 * If this bblock is the start of a finally clause, this is the bblock that
63 * CALL_HANDLER needs to branch to.
65 LLVMBasicBlockRef call_handler_target_bb;
66 /* The list of switch statements generated by ENDFINALLY instructions */
67 GSList *endfinally_switch_ins_list;
72 * Structure containing emit state
77 /* Maps method names to the corresponding LLVMValueRef */
78 GHashTable *emitted_method_decls;
82 MonoLLVMModule *lmodule;
85 int sindex, default_index, ex_index;
86 LLVMBuilderRef builder;
87 LLVMValueRef *values, *addresses;
88 MonoType **vreg_cli_types;
90 MonoMethodSignature *sig;
92 GHashTable *region_to_handler;
93 LLVMBuilderRef alloca_builder;
94 LLVMValueRef last_alloca;
95 LLVMValueRef rgctx_arg;
96 LLVMTypeRef *vreg_types;
98 gboolean *unreachable;
100 LLVMValueRef imt_rgctx_loc;
101 GHashTable *llvm_types;
109 MonoBasicBlock *in_bb;
114 * Instruction metadata
115 * This is the same as ins_info, but LREG != IREG.
123 #define MINI_OP(a,b,dest,src1,src2) dest, src1, src2, ' ',
124 #define MINI_OP3(a,b,dest,src1,src2,src3) dest, src1, src2, src3,
131 /* keep in sync with the enum in mini.h */
134 #include "mini-ops.h"
139 #if SIZEOF_VOID_P == 4
140 #define GET_LONG_IMM(ins) (((guint64)(ins)->inst_ms_word << 32) | (guint64)(guint32)(ins)->inst_ls_word)
142 #define GET_LONG_IMM(ins) ((ins)->inst_imm)
145 #define LLVM_INS_INFO(opcode) (&llvm_ins_info [((opcode) - OP_START - 1) * 4])
148 #define TRACE_FAILURE(msg) do { printf ("%s\n", msg); } while (0)
150 #define TRACE_FAILURE(msg)
154 #define IS_TARGET_X86 1
156 #define IS_TARGET_X86 0
160 #define IS_TARGET_AMD64 1
162 #define IS_TARGET_AMD64 0
165 #define LLVM_FAILURE(ctx, reason) do { \
166 TRACE_FAILURE (reason); \
167 (ctx)->cfg->exception_message = g_strdup (reason); \
168 (ctx)->cfg->disable_llvm = TRUE; \
172 #define CHECK_FAILURE(ctx) do { \
173 if ((ctx)->cfg->disable_llvm) \
177 static LLVMIntPredicate cond_to_llvm_cond [] = {
190 static LLVMRealPredicate fpcond_to_llvm_cond [] = {
203 static MonoNativeTlsKey current_cfg_tls_id;
205 static MonoLLVMModule aot_module;
206 static int memset_param_count, memcpy_param_count;
207 static const char *memset_func_name;
208 static const char *memcpy_func_name;
210 static void init_jit_module (MonoDomain *domain);
215 * The LLVM type with width == sizeof (gpointer)
220 return sizeof (gpointer) == 8 ? LLVMInt64Type () : LLVMInt32Type ();
226 return sizeof (gpointer) == 8 ? LLVMPointerType (LLVMInt64Type (), 0) : LLVMPointerType (LLVMInt32Type (), 0);
232 return sizeof (gpointer) == 8 ? LLVMPointerType (LLVMInt64Type (), 0) : LLVMPointerType (LLVMInt32Type (), 0);
238 * Return the size of the LLVM representation of the vtype T.
241 get_vtype_size (MonoType *t)
245 size = mono_class_value_size (mono_class_from_mono_type (t), NULL);
247 while (size < 2 * sizeof (gpointer) && mono_is_power_of_two (size) == -1)
254 * simd_class_to_llvm_type:
256 * Return the LLVM type corresponding to the Mono.SIMD class KLASS
259 simd_class_to_llvm_type (EmitContext *ctx, MonoClass *klass)
261 if (!strcmp (klass->name, "Vector2d")) {
262 return LLVMVectorType (LLVMDoubleType (), 2);
263 } else if (!strcmp (klass->name, "Vector2l")) {
264 return LLVMVectorType (LLVMInt64Type (), 2);
265 } else if (!strcmp (klass->name, "Vector2ul")) {
266 return LLVMVectorType (LLVMInt64Type (), 2);
267 } else if (!strcmp (klass->name, "Vector4i")) {
268 return LLVMVectorType (LLVMInt32Type (), 4);
269 } else if (!strcmp (klass->name, "Vector4ui")) {
270 return LLVMVectorType (LLVMInt32Type (), 4);
271 } else if (!strcmp (klass->name, "Vector4f")) {
272 return LLVMVectorType (LLVMFloatType (), 4);
273 } else if (!strcmp (klass->name, "Vector8s")) {
274 return LLVMVectorType (LLVMInt16Type (), 8);
275 } else if (!strcmp (klass->name, "Vector8us")) {
276 return LLVMVectorType (LLVMInt16Type (), 8);
277 } else if (!strcmp (klass->name, "Vector16sb")) {
278 return LLVMVectorType (LLVMInt8Type (), 16);
279 } else if (!strcmp (klass->name, "Vector16b")) {
280 return LLVMVectorType (LLVMInt8Type (), 16);
282 printf ("%s\n", klass->name);
288 /* Return the 128 bit SIMD type corresponding to the mono type TYPE */
289 static inline G_GNUC_UNUSED LLVMTypeRef
290 type_to_simd_type (int type)
294 return LLVMVectorType (LLVMInt8Type (), 16);
296 return LLVMVectorType (LLVMInt16Type (), 8);
298 return LLVMVectorType (LLVMInt32Type (), 4);
300 return LLVMVectorType (LLVMInt64Type (), 2);
302 return LLVMVectorType (LLVMDoubleType (), 2);
304 return LLVMVectorType (LLVMFloatType (), 4);
306 g_assert_not_reached ();
314 * Return the LLVM type corresponding to T.
317 type_to_llvm_type (EmitContext *ctx, MonoType *t)
319 t = mini_replace_type (t);
322 return LLVMPointerType (LLVMInt8Type (), 0);
325 return LLVMVoidType ();
327 return LLVMInt8Type ();
329 return LLVMInt16Type ();
331 return LLVMInt32Type ();
333 return LLVMInt8Type ();
335 return LLVMInt16Type ();
337 return LLVMInt32Type ();
338 case MONO_TYPE_BOOLEAN:
339 return LLVMInt8Type ();
342 return LLVMInt64Type ();
344 return LLVMInt16Type ();
346 return LLVMFloatType ();
348 return LLVMDoubleType ();
351 return IntPtrType ();
352 case MONO_TYPE_OBJECT:
353 case MONO_TYPE_CLASS:
354 case MONO_TYPE_ARRAY:
355 case MONO_TYPE_SZARRAY:
356 case MONO_TYPE_STRING:
358 return ObjRefType ();
361 /* Because of generic sharing */
362 return ObjRefType ();
363 case MONO_TYPE_GENERICINST:
364 if (!mono_type_generic_inst_is_valuetype (t))
365 return ObjRefType ();
367 case MONO_TYPE_VALUETYPE:
368 case MONO_TYPE_TYPEDBYREF: {
372 klass = mono_class_from_mono_type (t);
374 if (MONO_CLASS_IS_SIMD (ctx->cfg, klass))
375 return simd_class_to_llvm_type (ctx, klass);
378 return type_to_llvm_type (ctx, mono_class_enum_basetype (klass));
380 ltype = g_hash_table_lookup (ctx->lmodule->llvm_types, klass);
383 LLVMTypeRef *eltypes;
386 size = get_vtype_size (t);
388 eltypes = g_new (LLVMTypeRef, size);
389 for (i = 0; i < size; ++i)
390 eltypes [i] = LLVMInt8Type ();
392 name = mono_type_full_name (&klass->byval_arg);
393 ltype = LLVMStructCreateNamed (LLVMGetGlobalContext (), name);
394 LLVMStructSetBody (ltype, eltypes, size, FALSE);
395 g_hash_table_insert (ctx->lmodule->llvm_types, klass, ltype);
403 printf ("X: %d\n", t->type);
404 ctx->cfg->exception_message = g_strdup_printf ("type %s", mono_type_full_name (t));
405 ctx->cfg->disable_llvm = TRUE;
413 * Return whenever T is an unsigned int type.
416 type_is_unsigned (EmitContext *ctx, MonoType *t)
432 * type_to_llvm_arg_type:
434 * Same as type_to_llvm_type, but treat i8/i16 as i32.
437 type_to_llvm_arg_type (EmitContext *ctx, MonoType *t)
439 LLVMTypeRef ptype = type_to_llvm_type (ctx, t);
441 if (ptype == LLVMInt8Type () || ptype == LLVMInt16Type ()) {
443 * LLVM generates code which only sets the lower bits, while JITted
444 * code expects all the bits to be set.
446 ptype = LLVMInt32Type ();
453 * llvm_type_to_stack_type:
455 * Return the LLVM type which needs to be used when a value of type TYPE is pushed
458 static G_GNUC_UNUSED LLVMTypeRef
459 llvm_type_to_stack_type (LLVMTypeRef type)
463 if (type == LLVMInt8Type ())
464 return LLVMInt32Type ();
465 else if (type == LLVMInt16Type ())
466 return LLVMInt32Type ();
467 else if (type == LLVMFloatType ())
468 return LLVMDoubleType ();
474 * regtype_to_llvm_type:
476 * Return the LLVM type corresponding to the regtype C used in instruction
480 regtype_to_llvm_type (char c)
484 return LLVMInt32Type ();
486 return LLVMInt64Type ();
488 return LLVMDoubleType ();
497 * Return the LLVM type corresponding to the unary/binary opcode OPCODE.
500 op_to_llvm_type (int opcode)
505 return LLVMInt8Type ();
508 return LLVMInt8Type ();
511 return LLVMInt16Type ();
514 return LLVMInt16Type ();
517 return LLVMInt32Type ();
520 return LLVMInt32Type ();
522 return LLVMInt64Type ();
524 return LLVMFloatType ();
526 return LLVMDoubleType ();
528 return LLVMInt64Type ();
530 return LLVMInt32Type ();
532 return LLVMInt64Type ();
535 return LLVMInt8Type ();
538 return LLVMInt16Type ();
541 return sizeof (gpointer) == 8 ? LLVMInt64Type () : LLVMInt32Type ();
548 return LLVMInt32Type ();
555 return LLVMInt64Type ();
557 printf ("%s\n", mono_inst_name (opcode));
558 g_assert_not_reached ();
564 * load_store_to_llvm_type:
566 * Return the size/sign/zero extension corresponding to the load/store opcode
570 load_store_to_llvm_type (int opcode, int *size, gboolean *sext, gboolean *zext)
576 case OP_LOADI1_MEMBASE:
577 case OP_STOREI1_MEMBASE_REG:
578 case OP_STOREI1_MEMBASE_IMM:
581 return LLVMInt8Type ();
582 case OP_LOADU1_MEMBASE:
586 return LLVMInt8Type ();
587 case OP_LOADI2_MEMBASE:
588 case OP_STOREI2_MEMBASE_REG:
589 case OP_STOREI2_MEMBASE_IMM:
592 return LLVMInt16Type ();
593 case OP_LOADU2_MEMBASE:
597 return LLVMInt16Type ();
598 case OP_LOADI4_MEMBASE:
599 case OP_LOADU4_MEMBASE:
602 case OP_STOREI4_MEMBASE_REG:
603 case OP_STOREI4_MEMBASE_IMM:
605 return LLVMInt32Type ();
606 case OP_LOADI8_MEMBASE:
608 case OP_STOREI8_MEMBASE_REG:
609 case OP_STOREI8_MEMBASE_IMM:
611 return LLVMInt64Type ();
612 case OP_LOADR4_MEMBASE:
613 case OP_STORER4_MEMBASE_REG:
615 return LLVMFloatType ();
616 case OP_LOADR8_MEMBASE:
617 case OP_STORER8_MEMBASE_REG:
619 return LLVMDoubleType ();
620 case OP_LOAD_MEMBASE:
622 case OP_STORE_MEMBASE_REG:
623 case OP_STORE_MEMBASE_IMM:
624 *size = sizeof (gpointer);
625 return IntPtrType ();
627 g_assert_not_reached ();
635 * Return the LLVM intrinsics corresponding to the overflow opcode OPCODE.
638 ovf_op_to_intrins (int opcode)
642 return "llvm.sadd.with.overflow.i32";
644 return "llvm.uadd.with.overflow.i32";
646 return "llvm.ssub.with.overflow.i32";
648 return "llvm.usub.with.overflow.i32";
650 return "llvm.smul.with.overflow.i32";
652 return "llvm.umul.with.overflow.i32";
654 return "llvm.sadd.with.overflow.i64";
656 return "llvm.uadd.with.overflow.i64";
658 return "llvm.ssub.with.overflow.i64";
660 return "llvm.usub.with.overflow.i64";
662 return "llvm.smul.with.overflow.i64";
664 return "llvm.umul.with.overflow.i64";
666 g_assert_not_reached ();
672 simd_op_to_intrins (int opcode)
675 #if defined(TARGET_X86) || defined(TARGET_AMD64)
677 return "llvm.x86.sse2.min.pd";
679 return "llvm.x86.sse.min.ps";
681 return "llvm.x86.sse41.pminud";
683 return "llvm.x86.sse41.pminuw";
685 return "llvm.x86.sse2.pminu.b";
687 return "llvm.x86.sse2.pmins.w";
689 return "llvm.x86.sse2.max.pd";
691 return "llvm.x86.sse.max.ps";
693 return "llvm.x86.sse3.hadd.pd";
695 return "llvm.x86.sse3.hadd.ps";
697 return "llvm.x86.sse3.hsub.pd";
699 return "llvm.x86.sse3.hsub.ps";
701 return "llvm.x86.sse41.pmaxud";
703 return "llvm.x86.sse41.pmaxuw";
705 return "llvm.x86.sse2.pmaxu.b";
707 return "llvm.x86.sse3.addsub.ps";
709 return "llvm.x86.sse3.addsub.pd";
710 case OP_EXTRACT_MASK:
711 return "llvm.x86.sse2.pmovmskb.128";
714 return "llvm.x86.sse2.psrli.w";
717 return "llvm.x86.sse2.psrli.d";
720 return "llvm.x86.sse2.psrli.q";
723 return "llvm.x86.sse2.pslli.w";
726 return "llvm.x86.sse2.pslli.d";
729 return "llvm.x86.sse2.pslli.q";
732 return "llvm.x86.sse2.psrai.w";
735 return "llvm.x86.sse2.psrai.d";
737 return "llvm.x86.sse2.padds.b";
739 return "llvm.x86.sse2.padds.w";
741 return "llvm.x86.sse2.psubs.b";
743 return "llvm.x86.sse2.psubs.w";
744 case OP_PADDB_SAT_UN:
745 return "llvm.x86.sse2.paddus.b";
746 case OP_PADDW_SAT_UN:
747 return "llvm.x86.sse2.paddus.w";
748 case OP_PSUBB_SAT_UN:
749 return "llvm.x86.sse2.psubus.b";
750 case OP_PSUBW_SAT_UN:
751 return "llvm.x86.sse2.psubus.w";
753 return "llvm.x86.sse2.pavg.b";
755 return "llvm.x86.sse2.pavg.w";
757 return "llvm.x86.sse.sqrt.ps";
759 return "llvm.x86.sse2.sqrt.pd";
761 return "llvm.x86.sse.rsqrt.ps";
763 return "llvm.x86.sse.rcp.ps";
765 return "llvm.x86.sse2.cvtdq2pd";
767 return "llvm.x86.sse2.cvtdq2ps";
769 return "llvm.x86.sse2.cvtpd2dq";
771 return "llvm.x86.sse2.cvtps2dq";
773 return "llvm.x86.sse2.cvtpd2ps";
775 return "llvm.x86.sse2.cvtps2pd";
777 return "llvm.x86.sse2.cvttpd2dq";
779 return "llvm.x86.sse2.cvttps2dq";
781 return "llvm.x86.sse.cmp.ps";
783 return "llvm.x86.sse2.cmp.pd";
785 return "llvm.x86.sse2.packsswb.128";
787 return "llvm.x86.sse2.packssdw.128";
789 return "llvm.x86.sse2.packuswb.128";
791 return "llvm.x86.sse41.packusdw";
793 return "llvm.x86.sse2.pmulh.w";
794 case OP_PMULW_HIGH_UN:
795 return "llvm.x86.sse2.pmulhu.w";
798 g_assert_not_reached ();
804 simd_op_to_llvm_type (int opcode)
806 #if defined(TARGET_X86) || defined(TARGET_AMD64)
810 return type_to_simd_type (MONO_TYPE_R8);
813 return type_to_simd_type (MONO_TYPE_I8);
816 return type_to_simd_type (MONO_TYPE_I4);
821 return type_to_simd_type (MONO_TYPE_I2);
825 return type_to_simd_type (MONO_TYPE_I1);
827 return type_to_simd_type (MONO_TYPE_R4);
830 return type_to_simd_type (MONO_TYPE_I4);
834 return type_to_simd_type (MONO_TYPE_R8);
838 return type_to_simd_type (MONO_TYPE_R4);
839 case OP_EXTRACT_MASK:
840 return type_to_simd_type (MONO_TYPE_I1);
846 return type_to_simd_type (MONO_TYPE_R4);
849 return type_to_simd_type (MONO_TYPE_R8);
851 g_assert_not_reached ();
862 * Return the LLVM basic block corresponding to BB.
864 static LLVMBasicBlockRef
865 get_bb (EmitContext *ctx, MonoBasicBlock *bb)
867 char bb_name_buf [128];
870 if (ctx->bblocks [bb->block_num].bblock == NULL) {
871 if (bb->flags & BB_EXCEPTION_HANDLER) {
872 int clause_index = (mono_get_block_region_notry (ctx->cfg, bb->region) >> 8) - 1;
873 sprintf (bb_name_buf, "EH_CLAUSE%d_BB%d", clause_index, bb->block_num);
874 bb_name = bb_name_buf;
875 } else if (bb->block_num < 256) {
876 if (!ctx->lmodule->bb_names) {
877 ctx->lmodule->bb_names_len = 256;
878 ctx->lmodule->bb_names = g_new0 (char*, ctx->lmodule->bb_names_len);
880 if (!ctx->lmodule->bb_names [bb->block_num]) {
883 n = g_strdup_printf ("BB%d", bb->block_num);
884 mono_memory_barrier ();
885 ctx->lmodule->bb_names [bb->block_num] = n;
887 bb_name = ctx->lmodule->bb_names [bb->block_num];
889 sprintf (bb_name_buf, "BB%d", bb->block_num);
890 bb_name = bb_name_buf;
893 ctx->bblocks [bb->block_num].bblock = LLVMAppendBasicBlock (ctx->lmethod, bb_name);
894 ctx->bblocks [bb->block_num].end_bblock = ctx->bblocks [bb->block_num].bblock;
897 return ctx->bblocks [bb->block_num].bblock;
903 * Return the last LLVM bblock corresponding to BB.
904 * This might not be equal to the bb returned by get_bb () since we need to generate
905 * multiple LLVM bblocks for a mono bblock to handle throwing exceptions.
907 static LLVMBasicBlockRef
908 get_end_bb (EmitContext *ctx, MonoBasicBlock *bb)
911 return ctx->bblocks [bb->block_num].end_bblock;
914 static LLVMBasicBlockRef
915 gen_bb (EmitContext *ctx, const char *prefix)
919 sprintf (bb_name, "%s%d", prefix, ++ ctx->ex_index);
920 return LLVMAppendBasicBlock (ctx->lmethod, bb_name);
926 * Return the target of the patch identified by TYPE and TARGET.
929 resolve_patch (MonoCompile *cfg, MonoJumpInfoType type, gconstpointer target)
933 memset (&ji, 0, sizeof (ji));
935 ji.data.target = target;
937 return mono_resolve_patch_target (cfg->method, cfg->domain, NULL, &ji, FALSE);
943 * Emit code to convert the LLVM value V to DTYPE.
946 convert_full (EmitContext *ctx, LLVMValueRef v, LLVMTypeRef dtype, gboolean is_unsigned)
948 LLVMTypeRef stype = LLVMTypeOf (v);
950 if (stype != dtype) {
951 gboolean ext = FALSE;
954 if (dtype == LLVMInt64Type () && (stype == LLVMInt32Type () || stype == LLVMInt16Type () || stype == LLVMInt8Type ()))
956 else if (dtype == LLVMInt32Type () && (stype == LLVMInt16Type () || stype == LLVMInt8Type ()))
958 else if (dtype == LLVMInt16Type () && (stype == LLVMInt8Type ()))
962 return is_unsigned ? LLVMBuildZExt (ctx->builder, v, dtype, "") : LLVMBuildSExt (ctx->builder, v, dtype, "");
964 if (dtype == LLVMDoubleType () && stype == LLVMFloatType ())
965 return LLVMBuildFPExt (ctx->builder, v, dtype, "");
968 if (stype == LLVMInt64Type () && (dtype == LLVMInt32Type () || dtype == LLVMInt16Type () || dtype == LLVMInt8Type ()))
969 return LLVMBuildTrunc (ctx->builder, v, dtype, "");
970 if (stype == LLVMInt32Type () && (dtype == LLVMInt16Type () || dtype == LLVMInt8Type ()))
971 return LLVMBuildTrunc (ctx->builder, v, dtype, "");
972 if (stype == LLVMInt16Type () && dtype == LLVMInt8Type ())
973 return LLVMBuildTrunc (ctx->builder, v, dtype, "");
974 if (stype == LLVMDoubleType () && dtype == LLVMFloatType ())
975 return LLVMBuildFPTrunc (ctx->builder, v, dtype, "");
977 if (LLVMGetTypeKind (stype) == LLVMPointerTypeKind && LLVMGetTypeKind (dtype) == LLVMPointerTypeKind)
978 return LLVMBuildBitCast (ctx->builder, v, dtype, "");
979 if (LLVMGetTypeKind (dtype) == LLVMPointerTypeKind)
980 return LLVMBuildIntToPtr (ctx->builder, v, dtype, "");
981 if (LLVMGetTypeKind (stype) == LLVMPointerTypeKind)
982 return LLVMBuildPtrToInt (ctx->builder, v, dtype, "");
984 if (mono_arch_is_soft_float ()) {
985 if (stype == LLVMInt32Type () && dtype == LLVMFloatType ())
986 return LLVMBuildBitCast (ctx->builder, v, dtype, "");
987 if (stype == LLVMInt32Type () && dtype == LLVMDoubleType ())
988 return LLVMBuildBitCast (ctx->builder, LLVMBuildZExt (ctx->builder, v, LLVMInt64Type (), ""), dtype, "");
991 if (LLVMGetTypeKind (stype) == LLVMVectorTypeKind && LLVMGetTypeKind (dtype) == LLVMVectorTypeKind)
992 return LLVMBuildBitCast (ctx->builder, v, dtype, "");
995 LLVMDumpValue (LLVMConstNull (dtype));
996 g_assert_not_reached ();
1004 convert (EmitContext *ctx, LLVMValueRef v, LLVMTypeRef dtype)
1006 return convert_full (ctx, v, dtype, FALSE);
1010 * emit_volatile_load:
1012 * If vreg is volatile, emit a load from its address.
1015 emit_volatile_load (EmitContext *ctx, int vreg)
1019 LLVMValueRef v = LLVMBuildLoad (ctx->builder, ctx->addresses [vreg], "");
1020 t = ctx->vreg_cli_types [vreg];
1021 if (t && !t->byref) {
1023 * Might have to zero extend since llvm doesn't have
1026 if (t->type == MONO_TYPE_U1 || t->type == MONO_TYPE_U2 || t->type == MONO_TYPE_CHAR || t->type == MONO_TYPE_BOOLEAN)
1027 v = LLVMBuildZExt (ctx->builder, v, LLVMInt32Type (), "");
1028 else if (t->type == MONO_TYPE_U8)
1029 v = LLVMBuildZExt (ctx->builder, v, LLVMInt64Type (), "");
1036 * emit_volatile_store:
1038 * If VREG is volatile, emit a store from its value to its address.
1041 emit_volatile_store (EmitContext *ctx, int vreg)
1043 MonoInst *var = get_vreg_to_inst (ctx->cfg, vreg);
1045 if (var && var->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT)) {
1046 g_assert (ctx->addresses [vreg]);
1047 LLVMBuildStore (ctx->builder, convert (ctx, ctx->values [vreg], type_to_llvm_type (ctx, var->inst_vtype)), ctx->addresses [vreg]);
1053 * Maps parameter indexes in the original signature to parameter indexes
1054 * in the LLVM signature.
1057 /* The indexes of various special arguments in the LLVM signature */
1058 int vret_arg_pindex, this_arg_pindex, rgctx_arg_pindex, imt_arg_pindex;
1062 * sig_to_llvm_sig_full:
1064 * Return the LLVM signature corresponding to the mono signature SIG using the
1065 * calling convention information in CINFO. Return parameter mapping information in SINFO.
1068 sig_to_llvm_sig_full (EmitContext *ctx, MonoMethodSignature *sig, LLVMCallInfo *cinfo,
1071 LLVMTypeRef ret_type;
1072 LLVMTypeRef *param_types = NULL;
1074 int i, j, pindex, vret_arg_pindex = 0;
1076 gboolean vretaddr = FALSE;
1080 memset (sinfo, 0, sizeof (LLVMSigInfo));
1082 rtype = mini_replace_type (sig->ret);
1083 ret_type = type_to_llvm_type (ctx, rtype);
1084 CHECK_FAILURE (ctx);
1086 if (cinfo && cinfo->ret.storage == LLVMArgVtypeInReg) {
1087 /* LLVM models this by returning an aggregate value */
1088 if (cinfo->ret.pair_storage [0] == LLVMArgInIReg && cinfo->ret.pair_storage [1] == LLVMArgNone) {
1089 LLVMTypeRef members [2];
1091 members [0] = IntPtrType ();
1092 ret_type = LLVMStructType (members, 1, FALSE);
1094 g_assert_not_reached ();
1096 } else if (cinfo && mini_type_is_vtype (ctx->cfg, rtype)) {
1097 g_assert (cinfo->ret.storage == LLVMArgVtypeRetAddr);
1099 ret_type = LLVMVoidType ();
1102 pindexes = g_new0 (int, sig->param_count);
1103 param_types = g_new0 (LLVMTypeRef, (sig->param_count * 2) + 3);
1105 if (cinfo && cinfo->rgctx_arg) {
1107 sinfo->rgctx_arg_pindex = pindex;
1108 param_types [pindex] = ctx->lmodule->ptr_type;
1111 if (cinfo && cinfo->imt_arg) {
1113 sinfo->imt_arg_pindex = pindex;
1114 param_types [pindex] = ctx->lmodule->ptr_type;
1118 /* Compute the index in the LLVM signature where the vret arg needs to be passed */
1119 vret_arg_pindex = pindex;
1120 if (cinfo->vret_arg_index == 1) {
1121 /* Add the slots consumed by the first argument */
1122 LLVMArgInfo *ainfo = &cinfo->args [0];
1123 switch (ainfo->storage) {
1124 case LLVMArgVtypeInReg:
1125 for (j = 0; j < 2; ++j) {
1126 if (ainfo->pair_storage [j] == LLVMArgInIReg)
1136 sinfo->vret_arg_pindex = vret_arg_pindex;
1139 if (vretaddr && vret_arg_pindex == pindex)
1140 param_types [pindex ++] = IntPtrType ();
1143 sinfo->this_arg_pindex = pindex;
1144 param_types [pindex ++] = ThisType ();
1146 if (vretaddr && vret_arg_pindex == pindex)
1147 param_types [pindex ++] = IntPtrType ();
1148 for (i = 0; i < sig->param_count; ++i) {
1149 if (vretaddr && vret_arg_pindex == pindex)
1150 param_types [pindex ++] = IntPtrType ();
1151 pindexes [i] = pindex;
1152 if (cinfo && cinfo->args [i + sig->hasthis].storage == LLVMArgVtypeInReg) {
1153 for (j = 0; j < 2; ++j) {
1154 switch (cinfo->args [i + sig->hasthis].pair_storage [j]) {
1156 param_types [pindex ++] = LLVMIntType (sizeof (gpointer) * 8);
1161 g_assert_not_reached ();
1164 } else if (cinfo && cinfo->args [i + sig->hasthis].storage == LLVMArgVtypeByVal) {
1165 param_types [pindex] = type_to_llvm_arg_type (ctx, sig->params [i]);
1166 CHECK_FAILURE (ctx);
1167 param_types [pindex] = LLVMPointerType (param_types [pindex], 0);
1170 param_types [pindex ++] = type_to_llvm_arg_type (ctx, sig->params [i]);
1173 if (vretaddr && vret_arg_pindex == pindex)
1174 param_types [pindex ++] = IntPtrType ();
1176 CHECK_FAILURE (ctx);
1178 res = LLVMFunctionType (ret_type, param_types, pindex, FALSE);
1179 g_free (param_types);
1182 sinfo->pindexes = pindexes;
1190 g_free (param_types);
1196 sig_to_llvm_sig (EmitContext *ctx, MonoMethodSignature *sig)
1198 return sig_to_llvm_sig_full (ctx, sig, NULL, NULL);
1202 * LLVMFunctionType1:
1204 * Create an LLVM function type from the arguments.
1206 static G_GNUC_UNUSED LLVMTypeRef
1207 LLVMFunctionType1(LLVMTypeRef ReturnType,
1208 LLVMTypeRef ParamType1,
1211 LLVMTypeRef param_types [1];
1213 param_types [0] = ParamType1;
1215 return LLVMFunctionType (ReturnType, param_types, 1, IsVarArg);
1219 * LLVMFunctionType2:
1221 * Create an LLVM function type from the arguments.
1223 static G_GNUC_UNUSED LLVMTypeRef
1224 LLVMFunctionType2(LLVMTypeRef ReturnType,
1225 LLVMTypeRef ParamType1,
1226 LLVMTypeRef ParamType2,
1229 LLVMTypeRef param_types [2];
1231 param_types [0] = ParamType1;
1232 param_types [1] = ParamType2;
1234 return LLVMFunctionType (ReturnType, param_types, 2, IsVarArg);
1238 * LLVMFunctionType3:
1240 * Create an LLVM function type from the arguments.
1242 static G_GNUC_UNUSED LLVMTypeRef
1243 LLVMFunctionType3(LLVMTypeRef ReturnType,
1244 LLVMTypeRef ParamType1,
1245 LLVMTypeRef ParamType2,
1246 LLVMTypeRef ParamType3,
1249 LLVMTypeRef param_types [3];
1251 param_types [0] = ParamType1;
1252 param_types [1] = ParamType2;
1253 param_types [2] = ParamType3;
1255 return LLVMFunctionType (ReturnType, param_types, 3, IsVarArg);
1261 * Create an LLVM builder and remember it so it can be freed later.
1263 static LLVMBuilderRef
1264 create_builder (EmitContext *ctx)
1266 LLVMBuilderRef builder = LLVMCreateBuilder ();
1268 ctx->builders = g_slist_prepend_mempool (ctx->cfg->mempool, ctx->builders, builder);
1274 get_plt_entry (EmitContext *ctx, LLVMTypeRef llvm_sig, MonoJumpInfoType type, gconstpointer data)
1276 char *callee_name = mono_aot_get_plt_symbol (type, data);
1277 LLVMValueRef callee;
1278 MonoJumpInfo *ji = NULL;
1283 if (ctx->cfg->compile_aot)
1284 /* Add a patch so referenced wrappers can be compiled in full aot mode */
1285 mono_add_patch_info (ctx->cfg, 0, type, data);
1288 callee = g_hash_table_lookup (ctx->lmodule->plt_entries, callee_name);
1290 callee = LLVMAddFunction (ctx->module, callee_name, llvm_sig);
1292 LLVMSetVisibility (callee, LLVMHiddenVisibility);
1294 g_hash_table_insert (ctx->lmodule->plt_entries, (char*)callee_name, callee);
1297 if (ctx->cfg->compile_aot) {
1298 ji = g_new0 (MonoJumpInfo, 1);
1300 ji->data.target = data;
1302 g_hash_table_insert (ctx->lmodule->plt_entries_ji, ji, callee);
1309 get_handler_clause (MonoCompile *cfg, MonoBasicBlock *bb)
1311 MonoMethodHeader *header = cfg->header;
1312 MonoExceptionClause *clause;
1316 if (bb->region != -1 && MONO_BBLOCK_IS_IN_REGION (bb, MONO_REGION_TRY))
1317 return (bb->region >> 8) - 1;
1320 for (i = 0; i < header->num_clauses; ++i) {
1321 clause = &header->clauses [i];
1323 if (MONO_OFFSET_IN_CLAUSE (clause, bb->real_offset) && clause->flags == MONO_EXCEPTION_CLAUSE_NONE)
1331 set_metadata_flag (LLVMValueRef v, const char *flag_name)
1333 LLVMValueRef md_arg;
1336 md_kind = LLVMGetMDKindID (flag_name, strlen (flag_name));
1337 md_arg = LLVMMDString ("mono", 4);
1338 LLVMSetMetadata (v, md_kind, LLVMMDNode (&md_arg, 1));
1342 set_invariant_load_flag (LLVMValueRef v)
1344 LLVMValueRef md_arg;
1346 const char *flag_name;
1348 // FIXME: Cache this
1349 flag_name = "invariant.load";
1350 md_kind = LLVMGetMDKindID (flag_name, strlen (flag_name));
1351 md_arg = LLVMMDString ("<index>", strlen ("<index>"));
1352 LLVMSetMetadata (v, md_kind, LLVMMDNode (&md_arg, 1));
1358 * Emit an LLVM call or invoke instruction depending on whenever the call is inside
1362 emit_call (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, LLVMValueRef callee, LLVMValueRef *args, int pindex)
1364 MonoCompile *cfg = ctx->cfg;
1366 LLVMBuilderRef builder = *builder_ref;
1369 clause_index = get_handler_clause (cfg, bb);
1371 if (clause_index != -1) {
1372 MonoMethodHeader *header = cfg->header;
1373 MonoExceptionClause *ec = &header->clauses [clause_index];
1374 MonoBasicBlock *tblock;
1375 LLVMBasicBlockRef ex_bb, noex_bb;
1378 * Have to use an invoke instead of a call, branching to the
1379 * handler bblock of the clause containing this bblock.
1382 g_assert (ec->flags == MONO_EXCEPTION_CLAUSE_NONE || ec->flags == MONO_EXCEPTION_CLAUSE_FINALLY);
1384 tblock = cfg->cil_offset_to_bb [ec->handler_offset];
1387 ctx->bblocks [tblock->block_num].invoke_target = TRUE;
1389 ex_bb = get_bb (ctx, tblock);
1391 noex_bb = gen_bb (ctx, "NOEX_BB");
1394 lcall = LLVMBuildInvoke (builder, callee, args, pindex, noex_bb, ex_bb, "");
1396 builder = ctx->builder = create_builder (ctx);
1397 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
1399 ctx->bblocks [bb->block_num].end_bblock = noex_bb;
1401 lcall = LLVMBuildCall (builder, callee, args, pindex, "");
1402 ctx->builder = builder;
1405 *builder_ref = ctx->builder;
1411 emit_load (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, int size, LLVMValueRef addr, const char *name, gboolean is_faulting)
1413 const char *intrins_name;
1414 LLVMValueRef args [16], res;
1415 LLVMTypeRef addr_type;
1417 if (is_faulting && bb->region != -1) {
1419 * We handle loads which can fault by calling a mono specific intrinsic
1420 * using an invoke, so they are handled properly inside try blocks.
1421 * We can't use this outside clauses, since LLVM optimizes intrinsics which
1422 * are marked with IntrReadArgMem.
1426 intrins_name = "llvm.mono.load.i8.p0i8";
1429 intrins_name = "llvm.mono.load.i16.p0i16";
1432 intrins_name = "llvm.mono.load.i32.p0i32";
1435 intrins_name = "llvm.mono.load.i64.p0i64";
1438 g_assert_not_reached ();
1441 addr_type = LLVMTypeOf (addr);
1442 if (addr_type == LLVMPointerType (LLVMDoubleType (), 0) || addr_type == LLVMPointerType (LLVMFloatType (), 0))
1443 addr = LLVMBuildBitCast (*builder_ref, addr, LLVMPointerType (LLVMIntType (size * 8), 0), "");
1446 args [1] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
1447 args [2] = LLVMConstInt (LLVMInt1Type (), TRUE, FALSE);
1448 res = emit_call (ctx, bb, builder_ref, LLVMGetNamedFunction (ctx->module, intrins_name), args, 3);
1450 if (addr_type == LLVMPointerType (LLVMDoubleType (), 0))
1451 res = LLVMBuildBitCast (*builder_ref, res, LLVMDoubleType (), "");
1452 else if (addr_type == LLVMPointerType (LLVMFloatType (), 0))
1453 res = LLVMBuildBitCast (*builder_ref, res, LLVMFloatType (), "");
1460 * We emit volatile loads for loads which can fault, because otherwise
1461 * LLVM will generate invalid code when encountering a load from a
1464 res = mono_llvm_build_load (*builder_ref, addr, name, is_faulting);
1466 /* Mark it with a custom metadata */
1469 set_metadata_flag (res, "mono.faulting.load");
1477 emit_store (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, int size, LLVMValueRef value, LLVMValueRef addr, gboolean is_faulting)
1479 const char *intrins_name;
1480 LLVMValueRef args [16];
1482 if (is_faulting && bb->region != -1) {
1485 intrins_name = "llvm.mono.store.i8.p0i8";
1488 intrins_name = "llvm.mono.store.i16.p0i16";
1491 intrins_name = "llvm.mono.store.i32.p0i32";
1494 intrins_name = "llvm.mono.store.i64.p0i64";
1497 g_assert_not_reached ();
1500 if (LLVMTypeOf (value) == LLVMDoubleType () || LLVMTypeOf (value) == LLVMFloatType ()) {
1501 value = LLVMBuildBitCast (*builder_ref, value, LLVMIntType (size * 8), "");
1502 addr = LLVMBuildBitCast (*builder_ref, addr, LLVMPointerType (LLVMIntType (size * 8), 0), "");
1507 args [2] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
1508 args [3] = LLVMConstInt (LLVMInt1Type (), TRUE, FALSE);
1509 emit_call (ctx, bb, builder_ref, LLVMGetNamedFunction (ctx->module, intrins_name), args, 4);
1511 LLVMBuildStore (*builder_ref, value, addr);
1516 * emit_cond_system_exception:
1518 * Emit code to throw the exception EXC_TYPE if the condition CMP is false.
1519 * Might set the ctx exception.
1522 emit_cond_system_exception (EmitContext *ctx, MonoBasicBlock *bb, const char *exc_type, LLVMValueRef cmp)
1524 LLVMBasicBlockRef ex_bb, noex_bb;
1525 LLVMBuilderRef builder;
1526 MonoClass *exc_class;
1527 LLVMValueRef args [2];
1529 ex_bb = gen_bb (ctx, "EX_BB");
1530 noex_bb = gen_bb (ctx, "NOEX_BB");
1532 LLVMBuildCondBr (ctx->builder, cmp, ex_bb, noex_bb);
1534 exc_class = mono_class_from_name (mono_get_corlib (), "System", exc_type);
1535 g_assert (exc_class);
1537 /* Emit exception throwing code */
1538 builder = create_builder (ctx);
1539 LLVMPositionBuilderAtEnd (builder, ex_bb);
1541 if (!ctx->lmodule->throw_corlib_exception) {
1542 LLVMValueRef callee;
1544 const char *icall_name;
1546 MonoMethodSignature *throw_sig = mono_metadata_signature_alloc (mono_get_corlib (), 2);
1547 throw_sig->ret = &mono_get_void_class ()->byval_arg;
1548 throw_sig->params [0] = &mono_get_int32_class ()->byval_arg;
1549 icall_name = "llvm_throw_corlib_exception_abs_trampoline";
1550 /* This will become i8* */
1551 throw_sig->params [1] = &mono_get_byte_class ()->this_arg;
1552 sig = sig_to_llvm_sig (ctx, throw_sig);
1554 if (ctx->cfg->compile_aot) {
1555 callee = get_plt_entry (ctx, sig, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
1557 callee = LLVMAddFunction (ctx->module, "llvm_throw_corlib_exception_trampoline", sig_to_llvm_sig (ctx, throw_sig));
1560 * Differences between the LLVM/non-LLVM throw corlib exception trampoline:
1561 * - On x86, LLVM generated code doesn't push the arguments
1562 * - The trampoline takes the throw address as an arguments, not a pc offset.
1564 LLVMAddGlobalMapping (ctx->lmodule->ee, callee, resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name));
1567 mono_memory_barrier ();
1568 ctx->lmodule->throw_corlib_exception = callee;
1571 if (IS_TARGET_X86 || IS_TARGET_AMD64)
1572 args [0] = LLVMConstInt (LLVMInt32Type (), exc_class->type_token - MONO_TOKEN_TYPE_DEF, FALSE);
1574 args [0] = LLVMConstInt (LLVMInt32Type (), exc_class->type_token, FALSE);
1577 * The LLVM mono branch contains changes so a block address can be passed as an
1578 * argument to a call.
1580 args [1] = LLVMBlockAddress (ctx->lmethod, ex_bb);
1581 emit_call (ctx, bb, &builder, ctx->lmodule->throw_corlib_exception, args, 2);
1583 LLVMBuildUnreachable (builder);
1585 ctx->builder = create_builder (ctx);
1586 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
1588 ctx->bblocks [bb->block_num].end_bblock = noex_bb;
1595 * emit_reg_to_vtype:
1597 * Emit code to store the vtype in the registers REGS to the address ADDRESS.
1600 emit_reg_to_vtype (EmitContext *ctx, LLVMBuilderRef builder, MonoType *t, LLVMValueRef address, LLVMArgInfo *ainfo, LLVMValueRef *regs)
1604 size = get_vtype_size (t);
1606 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (t))) {
1607 address = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (LLVMInt8Type (), 0), "");
1610 for (j = 0; j < 2; ++j) {
1611 LLVMValueRef index [2], addr;
1612 int part_size = size > sizeof (gpointer) ? sizeof (gpointer) : size;
1613 LLVMTypeRef part_type;
1615 if (ainfo->pair_storage [j] == LLVMArgNone)
1618 part_type = LLVMIntType (part_size * 8);
1619 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (t))) {
1620 index [0] = LLVMConstInt (LLVMInt32Type (), j * sizeof (gpointer), FALSE);
1621 addr = LLVMBuildGEP (builder, address, index, 1, "");
1623 index [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
1624 index [1] = LLVMConstInt (LLVMInt32Type (), j * sizeof (gpointer), FALSE);
1625 addr = LLVMBuildGEP (builder, address, index, 2, "");
1627 switch (ainfo->pair_storage [j]) {
1629 LLVMBuildStore (builder, convert (ctx, regs [j], part_type), LLVMBuildBitCast (ctx->builder, addr, LLVMPointerType (part_type, 0), ""));
1634 g_assert_not_reached ();
1637 size -= sizeof (gpointer);
1642 * emit_vtype_to_reg:
1644 * Emit code to load a vtype at address ADDRESS into registers. Store the registers
1645 * into REGS, and the number of registers into NREGS.
1648 emit_vtype_to_reg (EmitContext *ctx, LLVMBuilderRef builder, MonoType *t, LLVMValueRef address, LLVMArgInfo *ainfo, LLVMValueRef *regs, guint32 *nregs)
1653 size = get_vtype_size (t);
1655 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (t))) {
1656 address = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (LLVMInt8Type (), 0), "");
1659 for (j = 0; j < 2; ++j) {
1660 LLVMValueRef index [2], addr;
1661 int partsize = size > sizeof (gpointer) ? sizeof (gpointer) : size;
1663 if (ainfo->pair_storage [j] == LLVMArgNone)
1666 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (t))) {
1667 index [0] = LLVMConstInt (LLVMInt32Type (), j * sizeof (gpointer), FALSE);
1668 addr = LLVMBuildGEP (builder, address, index, 1, "");
1670 index [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
1671 index [1] = LLVMConstInt (LLVMInt32Type (), j * sizeof (gpointer), FALSE);
1672 addr = LLVMBuildGEP (builder, address, index, 2, "");
1674 switch (ainfo->pair_storage [j]) {
1676 regs [pindex ++] = convert (ctx, LLVMBuildLoad (builder, LLVMBuildBitCast (ctx->builder, addr, LLVMPointerType (LLVMIntType (partsize * 8), 0), ""), ""), IntPtrType ());
1681 g_assert_not_reached ();
1683 size -= sizeof (gpointer);
1690 build_alloca_llvm_type (EmitContext *ctx, LLVMTypeRef t, int align)
1693 * Have to place all alloca's at the end of the entry bb, since otherwise they would
1694 * get executed every time control reaches them.
1696 LLVMPositionBuilder (ctx->alloca_builder, get_bb (ctx, ctx->cfg->bb_entry), ctx->last_alloca);
1698 ctx->last_alloca = mono_llvm_build_alloca (ctx->alloca_builder, t, NULL, align, "");
1699 return ctx->last_alloca;
1703 build_alloca (EmitContext *ctx, MonoType *t)
1705 MonoClass *k = mono_class_from_mono_type (t);
1708 if (MONO_CLASS_IS_SIMD (ctx->cfg, k))
1711 align = mono_class_min_align (k);
1713 /* Sometimes align is not a power of 2 */
1714 while (mono_is_power_of_two (align) == -1)
1717 return build_alloca_llvm_type (ctx, type_to_llvm_type (ctx, t), align);
1721 * Put the global into the 'llvm.used' array to prevent it from being optimized away.
1724 mark_as_used (MonoLLVMModule *lmodule, LLVMValueRef global)
1727 lmodule->used = g_ptr_array_sized_new (16);
1728 g_ptr_array_add (lmodule->used, global);
1732 emit_llvm_used (MonoLLVMModule *lmodule)
1734 LLVMModuleRef module = lmodule->module;
1735 LLVMTypeRef used_type;
1736 LLVMValueRef used, *used_elem;
1742 used_type = LLVMArrayType (LLVMPointerType (LLVMInt8Type (), 0), lmodule->used->len);
1743 used = LLVMAddGlobal (module, used_type, "llvm.used");
1744 used_elem = g_new0 (LLVMValueRef, lmodule->used->len);
1745 for (i = 0; i < lmodule->used->len; ++i)
1746 used_elem [i] = LLVMConstBitCast (g_ptr_array_index (lmodule->used, i), LLVMPointerType (LLVMInt8Type (), 0));
1747 LLVMSetInitializer (used, LLVMConstArray (LLVMPointerType (LLVMInt8Type (), 0), used_elem, lmodule->used->len));
1748 LLVMSetLinkage (used, LLVMAppendingLinkage);
1749 LLVMSetSection (used, "llvm.metadata");
1755 * Emit code to load/convert arguments.
1758 emit_entry_bb (EmitContext *ctx, LLVMBuilderRef builder)
1761 MonoCompile *cfg = ctx->cfg;
1762 MonoMethodSignature *sig = ctx->sig;
1763 LLVMCallInfo *linfo = ctx->linfo;
1766 ctx->alloca_builder = create_builder (ctx);
1769 * Handle indirect/volatile variables by allocating memory for them
1770 * using 'alloca', and storing their address in a temporary.
1772 for (i = 0; i < cfg->num_varinfo; ++i) {
1773 MonoInst *var = cfg->varinfo [i];
1776 if (var->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT) || mini_type_is_vtype (cfg, var->inst_vtype)) {
1777 vtype = type_to_llvm_type (ctx, var->inst_vtype);
1778 CHECK_FAILURE (ctx);
1779 /* Could be already created by an OP_VPHI */
1780 if (!ctx->addresses [var->dreg])
1781 ctx->addresses [var->dreg] = build_alloca (ctx, var->inst_vtype);
1782 ctx->vreg_cli_types [var->dreg] = var->inst_vtype;
1786 for (i = 0; i < sig->param_count; ++i) {
1787 LLVMArgInfo *ainfo = &linfo->args [i + sig->hasthis];
1788 int reg = cfg->args [i + sig->hasthis]->dreg;
1790 if (ainfo->storage == LLVMArgVtypeInReg) {
1791 LLVMValueRef regs [2];
1794 * Emit code to save the argument from the registers to
1795 * the real argument.
1797 pindex = ctx->pindexes [i];
1798 regs [0] = LLVMGetParam (ctx->lmethod, pindex);
1799 if (ainfo->pair_storage [1] != LLVMArgNone)
1800 regs [1] = LLVMGetParam (ctx->lmethod, pindex + 1);
1804 ctx->addresses [reg] = build_alloca (ctx, sig->params [i]);
1806 emit_reg_to_vtype (ctx, builder, sig->params [i], ctx->addresses [reg], ainfo, regs);
1808 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (sig->params [i]))) {
1809 /* Treat these as normal values */
1810 ctx->values [reg] = LLVMBuildLoad (builder, ctx->addresses [reg], "");
1812 } else if (ainfo->storage == LLVMArgVtypeByVal) {
1813 ctx->addresses [reg] = LLVMGetParam (ctx->lmethod, ctx->pindexes [i]);
1815 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (sig->params [i]))) {
1816 /* Treat these as normal values */
1817 ctx->values [reg] = LLVMBuildLoad (builder, ctx->addresses [reg], "");
1820 ctx->values [reg] = convert (ctx, ctx->values [reg], llvm_type_to_stack_type (type_to_llvm_type (ctx, sig->params [i])));
1825 emit_volatile_store (ctx, cfg->vret_addr->dreg);
1827 emit_volatile_store (ctx, cfg->args [0]->dreg);
1828 for (i = 0; i < sig->param_count; ++i)
1829 if (!mini_type_is_vtype (cfg, sig->params [i]))
1830 emit_volatile_store (ctx, cfg->args [i + sig->hasthis]->dreg);
1832 if (sig->hasthis && !cfg->rgctx_var && cfg->generic_sharing_context) {
1833 LLVMValueRef this_alloc;
1836 * The exception handling code needs the location where the this argument was
1837 * stored for gshared methods. We create a separate alloca to hold it, and mark it
1838 * with the "mono.this" custom metadata to tell llvm that it needs to save its
1839 * location into the LSDA.
1841 this_alloc = mono_llvm_build_alloca (builder, ThisType (), LLVMConstInt (LLVMInt32Type (), 1, FALSE), 0, "");
1842 /* This volatile store will keep the alloca alive */
1843 mono_llvm_build_store (builder, ctx->values [cfg->args [0]->dreg], this_alloc, TRUE);
1845 set_metadata_flag (this_alloc, "mono.this");
1848 if (cfg->rgctx_var) {
1849 LLVMValueRef rgctx_alloc, store;
1852 * We handle the rgctx arg similarly to the this pointer.
1854 g_assert (ctx->addresses [cfg->rgctx_var->dreg]);
1855 rgctx_alloc = ctx->addresses [cfg->rgctx_var->dreg];
1856 /* This volatile store will keep the alloca alive */
1857 store = mono_llvm_build_store (builder, convert (ctx, ctx->rgctx_arg, IntPtrType ()), rgctx_alloc, TRUE);
1859 set_metadata_flag (rgctx_alloc, "mono.this");
1863 * For finally clauses, create an indicator variable telling OP_ENDFINALLY whenever
1864 * it needs to continue normally, or return back to the exception handling system.
1866 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
1867 if (bb->region != -1 && (bb->flags & BB_EXCEPTION_HANDLER))
1868 g_hash_table_insert (ctx->region_to_handler, GUINT_TO_POINTER (mono_get_block_region_notry (cfg, bb->region)), bb);
1869 if (bb->region != -1 && (bb->flags & BB_EXCEPTION_HANDLER) && bb->in_scount == 0) {
1873 sprintf (name, "finally_ind_bb%d", bb->block_num);
1874 val = LLVMBuildAlloca (builder, LLVMInt32Type (), name);
1875 LLVMBuildStore (builder, LLVMConstInt (LLVMInt32Type (), 0, FALSE), val);
1877 ctx->bblocks [bb->block_num].finally_ind = val;
1880 * Create a new bblock which CALL_HANDLER can branch to, because branching to the
1881 * LLVM bblock containing the call to llvm.eh.selector causes problems for the
1882 * LLVM optimizer passes.
1884 sprintf (name, "BB_%d_CALL_HANDLER_TARGET", bb->block_num);
1885 ctx->bblocks [bb->block_num].call_handler_target_bb = LLVMAppendBasicBlock (ctx->lmethod, name);
1893 /* Have to export this for AOT */
1895 mono_personality (void);
1898 mono_personality (void)
1901 g_assert_not_reached ();
1905 process_call (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, MonoInst *ins)
1907 MonoCompile *cfg = ctx->cfg;
1908 LLVMModuleRef module = ctx->module;
1909 LLVMValueRef *values = ctx->values;
1910 LLVMValueRef *addresses = ctx->addresses;
1911 MonoCallInst *call = (MonoCallInst*)ins;
1912 MonoMethodSignature *sig = call->signature;
1913 LLVMValueRef callee = NULL, lcall;
1915 LLVMCallInfo *cinfo;
1919 LLVMTypeRef llvm_sig;
1921 gboolean virtual, calli;
1922 LLVMBuilderRef builder = *builder_ref;
1925 if (call->signature->call_convention != MONO_CALL_DEFAULT)
1926 LLVM_FAILURE (ctx, "non-default callconv");
1928 cinfo = call->cinfo;
1929 if (call->rgctx_arg_reg)
1930 cinfo->rgctx_arg = TRUE;
1931 if (call->imt_arg_reg)
1932 cinfo->imt_arg = TRUE;
1934 vretaddr = cinfo && cinfo->ret.storage == LLVMArgVtypeRetAddr;
1936 llvm_sig = sig_to_llvm_sig_full (ctx, sig, cinfo, &sinfo);
1937 CHECK_FAILURE (ctx);
1939 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);
1940 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);
1942 /* FIXME: Avoid creating duplicate methods */
1944 if (ins->flags & MONO_INST_HAS_METHOD) {
1948 if (cfg->compile_aot) {
1949 callee = get_plt_entry (ctx, llvm_sig, MONO_PATCH_INFO_METHOD, call->method);
1951 LLVM_FAILURE (ctx, "can't encode patch");
1953 callee = LLVMAddFunction (module, "", llvm_sig);
1956 mono_create_jit_trampoline_in_domain (mono_domain_get (),
1958 LLVMAddGlobalMapping (ctx->lmodule->ee, callee, target);
1962 if (call->method && strstr (call->method->klass->name, "AsyncVoidMethodBuilder"))
1963 /* LLVM miscompiles async methods */
1964 LLVM_FAILURE (ctx, "#13734");
1967 MonoJitICallInfo *info = mono_find_jit_icall_by_addr (call->fptr);
1973 memset (&ji, 0, sizeof (ji));
1974 ji.type = MONO_PATCH_INFO_JIT_ICALL_ADDR;
1975 ji.data.target = info->name;
1977 target = mono_resolve_patch_target (cfg->method, cfg->domain, NULL, &ji, FALSE);
1979 if (cfg->compile_aot) {
1980 callee = get_plt_entry (ctx, llvm_sig, MONO_PATCH_INFO_INTERNAL_METHOD, (char*)info->name);
1982 LLVM_FAILURE (ctx, "can't encode patch");
1984 callee = LLVMAddFunction (module, "", llvm_sig);
1985 target = (gpointer)mono_icall_get_wrapper (info);
1986 LLVMAddGlobalMapping (ctx->lmodule->ee, callee, target);
1989 if (cfg->compile_aot) {
1991 if (cfg->abs_patches) {
1992 MonoJumpInfo *abs_ji = g_hash_table_lookup (cfg->abs_patches, call->fptr);
1994 callee = get_plt_entry (ctx, llvm_sig, abs_ji->type, abs_ji->data.target);
1996 LLVM_FAILURE (ctx, "can't encode patch");
2000 LLVM_FAILURE (ctx, "aot");
2002 callee = LLVMAddFunction (module, "", llvm_sig);
2004 if (cfg->abs_patches) {
2005 MonoJumpInfo *abs_ji = g_hash_table_lookup (cfg->abs_patches, call->fptr);
2008 * FIXME: Some trampolines might have
2009 * their own calling convention on some platforms.
2011 #ifndef TARGET_AMD64
2012 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)
2013 LLVM_FAILURE (ctx, "trampoline with own cconv");
2015 target = mono_resolve_patch_target (cfg->method, cfg->domain, NULL, abs_ji, FALSE);
2016 LLVMAddGlobalMapping (ctx->lmodule->ee, callee, target);
2020 LLVMAddGlobalMapping (ctx->lmodule->ee, callee, (gpointer)call->fptr);
2026 int size = sizeof (gpointer);
2029 g_assert (ins->inst_offset % size == 0);
2030 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
2032 callee = convert (ctx, LLVMBuildLoad (builder, LLVMBuildGEP (builder, convert (ctx, values [ins->inst_basereg], LLVMPointerType (LLVMPointerType (IntPtrType (), 0), 0)), &index, 1, ""), ""), LLVMPointerType (llvm_sig, 0));
2034 callee = convert (ctx, values [ins->sreg1], LLVMPointerType (llvm_sig, 0));
2036 if (ins->flags & MONO_INST_HAS_METHOD) {
2041 * Collect and convert arguments
2043 nargs = (sig->param_count * 2) + sig->hasthis + vretaddr + call->rgctx_reg + call->imt_arg_reg;
2044 len = sizeof (LLVMValueRef) * nargs;
2045 args = alloca (len);
2046 memset (args, 0, len);
2047 l = call->out_ireg_args;
2049 if (call->rgctx_arg_reg) {
2050 g_assert (values [call->rgctx_arg_reg]);
2051 g_assert (sinfo.rgctx_arg_pindex < nargs);
2053 * On ARM, the imt/rgctx argument is passed in a caller save register, but some of our trampolines etc. clobber it, leading to
2054 * problems is LLVM moves the arg assignment earlier. To work around this, save the argument into a stack slot and load
2055 * it using a volatile load.
2058 if (!ctx->imt_rgctx_loc)
2059 ctx->imt_rgctx_loc = build_alloca_llvm_type (ctx, ctx->lmodule->ptr_type, sizeof (gpointer));
2060 LLVMBuildStore (builder, convert (ctx, ctx->values [call->rgctx_arg_reg], ctx->lmodule->ptr_type), ctx->imt_rgctx_loc);
2061 args [sinfo.rgctx_arg_pindex] = mono_llvm_build_load (builder, ctx->imt_rgctx_loc, "", TRUE);
2063 args [sinfo.rgctx_arg_pindex] = convert (ctx, values [call->rgctx_arg_reg], ctx->lmodule->ptr_type);
2066 if (call->imt_arg_reg) {
2067 g_assert (values [call->imt_arg_reg]);
2068 g_assert (sinfo.imt_arg_pindex < nargs);
2070 if (!ctx->imt_rgctx_loc)
2071 ctx->imt_rgctx_loc = build_alloca_llvm_type (ctx, ctx->lmodule->ptr_type, sizeof (gpointer));
2072 LLVMBuildStore (builder, convert (ctx, ctx->values [call->imt_arg_reg], ctx->lmodule->ptr_type), ctx->imt_rgctx_loc);
2073 args [sinfo.imt_arg_pindex] = mono_llvm_build_load (builder, ctx->imt_rgctx_loc, "", TRUE);
2075 args [sinfo.imt_arg_pindex] = convert (ctx, values [call->imt_arg_reg], ctx->lmodule->ptr_type);
2080 if (!addresses [call->inst.dreg])
2081 addresses [call->inst.dreg] = build_alloca (ctx, sig->ret);
2082 g_assert (sinfo.vret_arg_pindex < nargs);
2083 args [sinfo.vret_arg_pindex] = LLVMBuildPtrToInt (builder, addresses [call->inst.dreg], IntPtrType (), "");
2086 for (i = 0; i < sig->param_count + sig->hasthis; ++i) {
2089 LLVMArgInfo *ainfo = call->cinfo ? &call->cinfo->args [i] : NULL;
2093 pindex = sinfo.this_arg_pindex;
2095 pindex = sinfo.pindexes [i - 1];
2097 pindex = sinfo.pindexes [i];
2100 regpair = (guint32)(gssize)(l->data);
2101 reg = regpair & 0xffffff;
2102 args [pindex] = values [reg];
2103 if (ainfo->storage == LLVMArgVtypeInReg) {
2105 LLVMValueRef regs [2];
2110 g_assert (addresses [reg]);
2112 emit_vtype_to_reg (ctx, builder, sig->params [i - sig->hasthis], addresses [reg], ainfo, regs, &nregs);
2113 for (j = 0; j < nregs; ++j)
2114 args [pindex ++] = regs [j];
2117 // FIXME: Get rid of the VMOVE
2118 } else if (ainfo->storage == LLVMArgVtypeByVal) {
2119 g_assert (addresses [reg]);
2120 args [pindex] = addresses [reg];
2122 g_assert (args [pindex]);
2123 if (i == 0 && sig->hasthis)
2124 args [pindex] = convert (ctx, args [pindex], ThisType ());
2126 args [pindex] = convert (ctx, args [pindex], type_to_llvm_arg_type (ctx, sig->params [i - sig->hasthis]));
2132 // FIXME: Align call sites
2138 lcall = emit_call (ctx, bb, &builder, callee, args, LLVMCountParamTypes (llvm_sig));
2141 * Modify cconv and parameter attributes to pass rgctx/imt correctly.
2143 #if defined(MONO_ARCH_IMT_REG) && defined(MONO_ARCH_RGCTX_REG)
2144 g_assert (MONO_ARCH_IMT_REG == MONO_ARCH_RGCTX_REG);
2146 /* The two can't be used together, so use only one LLVM calling conv to pass them */
2147 g_assert (!(call->rgctx_arg_reg && call->imt_arg_reg));
2149 LLVMSetInstructionCallConv (lcall, LLVMMono1CallConv);
2151 if (call->rgctx_arg_reg)
2152 LLVMAddInstrAttribute (lcall, 1 + sinfo.rgctx_arg_pindex, LLVMInRegAttribute);
2153 if (call->imt_arg_reg)
2154 LLVMAddInstrAttribute (lcall, 1 + sinfo.imt_arg_pindex, LLVMInRegAttribute);
2156 /* Add byval attributes if needed */
2157 for (i = 0; i < sig->param_count; ++i) {
2158 LLVMArgInfo *ainfo = call->cinfo ? &call->cinfo->args [i + sig->hasthis] : NULL;
2160 if (ainfo && ainfo->storage == LLVMArgVtypeByVal) {
2161 LLVMAddInstrAttribute (lcall, 1 + sinfo.pindexes [i], LLVMByValAttribute);
2166 * Convert the result
2168 if (cinfo && cinfo->ret.storage == LLVMArgVtypeInReg) {
2169 LLVMValueRef regs [2];
2171 if (!addresses [ins->dreg])
2172 addresses [ins->dreg] = build_alloca (ctx, sig->ret);
2174 regs [0] = LLVMBuildExtractValue (builder, lcall, 0, "");
2175 if (cinfo->ret.pair_storage [1] != LLVMArgNone)
2176 regs [1] = LLVMBuildExtractValue (builder, lcall, 1, "");
2178 emit_reg_to_vtype (ctx, builder, sig->ret, addresses [ins->dreg], &cinfo->ret, regs);
2179 } else if (sig->ret->type != MONO_TYPE_VOID && !vretaddr) {
2180 /* If the method returns an unsigned value, need to zext it */
2182 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));
2185 *builder_ref = ctx->builder;
2187 g_free (sinfo.pindexes);
2195 process_bb (EmitContext *ctx, MonoBasicBlock *bb)
2197 MonoCompile *cfg = ctx->cfg;
2198 MonoMethodSignature *sig = ctx->sig;
2199 LLVMValueRef method = ctx->lmethod;
2200 LLVMValueRef *values = ctx->values;
2201 LLVMValueRef *addresses = ctx->addresses;
2203 LLVMCallInfo *linfo = ctx->linfo;
2204 LLVMModuleRef module = ctx->module;
2205 BBInfo *bblocks = ctx->bblocks;
2207 LLVMBasicBlockRef cbb;
2208 LLVMBuilderRef builder, starting_builder;
2209 gboolean has_terminator;
2211 LLVMValueRef lhs, rhs;
2214 cbb = get_bb (ctx, bb);
2215 builder = create_builder (ctx);
2216 ctx->builder = builder;
2217 LLVMPositionBuilderAtEnd (builder, cbb);
2219 if (bb == cfg->bb_entry)
2220 emit_entry_bb (ctx, builder);
2221 CHECK_FAILURE (ctx);
2223 if (bb->flags & BB_EXCEPTION_HANDLER) {
2225 LLVMValueRef personality;
2226 LLVMBasicBlockRef target_bb;
2228 static gint32 mapping_inited;
2229 static int ti_generator;
2232 LLVMValueRef type_info;
2235 if (!bblocks [bb->block_num].invoke_target) {
2237 * LLVM asserts if llvm.eh.selector is called from a bblock which
2238 * doesn't have an invoke pointing at it.
2239 * Update: LLVM no longer asserts, but some tests in exceptions.exe now fail.
2241 LLVM_FAILURE (ctx, "handler without invokes");
2244 // <resultval> = landingpad <somety> personality <type> <pers_fn> <clause>+
2246 if (cfg->compile_aot) {
2247 /* Use a dummy personality function */
2248 personality = LLVMGetNamedFunction (module, "mono_aot_personality");
2249 g_assert (personality);
2251 personality = LLVMGetNamedFunction (module, "mono_personality");
2252 if (InterlockedCompareExchange (&mapping_inited, 1, 0) == 0)
2253 LLVMAddGlobalMapping (ctx->lmodule->ee, personality, mono_personality);
2256 i8ptr = LLVMPointerType (LLVMInt8Type (), 0);
2258 clause_index = (mono_get_block_region_notry (cfg, bb->region) >> 8) - 1;
2261 * Create the type info
2263 sprintf (ti_name, "type_info_%d", ti_generator);
2266 if (cfg->compile_aot) {
2267 /* decode_eh_frame () in aot-runtime.c will decode this */
2268 type_info = LLVMAddGlobal (module, LLVMInt32Type (), ti_name);
2269 LLVMSetInitializer (type_info, LLVMConstInt (LLVMInt32Type (), clause_index, FALSE));
2272 * These symbols are not really used, the clause_index is embedded into the EH tables generated by DwarfMonoException in LLVM.
2274 LLVMSetLinkage (type_info, LLVMInternalLinkage);
2277 * Enabling this causes llc to crash:
2278 * http://llvm.org/bugs/show_bug.cgi?id=6102
2280 //LLVM_FAILURE (ctx, "aot+clauses");
2282 // test_0_invalid_unbox_arrays () fails
2283 LLVM_FAILURE (ctx, "aot+clauses");
2287 * After the cfg mempool is freed, the type info will point to stale memory,
2288 * but this is not a problem, since we decode it once in exception_cb during
2291 ti = mono_mempool_alloc (cfg->mempool, sizeof (gint32));
2292 *(gint32*)ti = clause_index;
2294 type_info = LLVMAddGlobal (module, i8ptr, ti_name);
2296 LLVMAddGlobalMapping (ctx->lmodule->ee, type_info, ti);
2300 LLVMTypeRef members [2], ret_type;
2301 LLVMValueRef landing_pad;
2303 members [0] = i8ptr;
2304 members [1] = LLVMInt32Type ();
2305 ret_type = LLVMStructType (members, 2, FALSE);
2307 landing_pad = LLVMBuildLandingPad (builder, ret_type, personality, 1, "");
2308 LLVMAddClause (landing_pad, type_info);
2310 /* Store the exception into the exvar */
2311 if (bb->in_scount == 1) {
2312 g_assert (bb->in_scount == 1);
2313 exvar = bb->in_stack [0];
2315 // FIXME: This is shared with filter clauses ?
2316 g_assert (!values [exvar->dreg]);
2318 values [exvar->dreg] = LLVMBuildExtractValue (builder, landing_pad, 0, "ex_obj");
2319 emit_volatile_store (ctx, exvar->dreg);
2323 /* Start a new bblock which CALL_HANDLER can branch to */
2324 target_bb = bblocks [bb->block_num].call_handler_target_bb;
2326 LLVMBuildBr (builder, target_bb);
2328 ctx->builder = builder = create_builder (ctx);
2329 LLVMPositionBuilderAtEnd (ctx->builder, target_bb);
2331 ctx->bblocks [bb->block_num].end_bblock = target_bb;
2335 has_terminator = FALSE;
2336 starting_builder = builder;
2337 for (ins = bb->code; ins; ins = ins->next) {
2338 const char *spec = LLVM_INS_INFO (ins->opcode);
2340 char dname_buf [128];
2343 if (nins > 5000 && builder == starting_builder) {
2344 /* some steps in llc are non-linear in the size of basic blocks, see #5714 */
2345 LLVM_FAILURE (ctx, "basic block too long");
2349 /* There could be instructions after a terminator, skip them */
2352 if (spec [MONO_INST_DEST] != ' ' && !MONO_IS_STORE_MEMBASE (ins)) {
2353 sprintf (dname_buf, "t%d", ins->dreg);
2357 if (spec [MONO_INST_SRC1] != ' ' && spec [MONO_INST_SRC1] != 'v') {
2358 MonoInst *var = get_vreg_to_inst (cfg, ins->sreg1);
2360 if (var && var->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT)) {
2361 lhs = emit_volatile_load (ctx, ins->sreg1);
2363 /* It is ok for SETRET to have an uninitialized argument */
2364 if (!values [ins->sreg1] && ins->opcode != OP_SETRET)
2365 LLVM_FAILURE (ctx, "sreg1");
2366 lhs = values [ins->sreg1];
2372 if (spec [MONO_INST_SRC2] != ' ' && spec [MONO_INST_SRC2] != ' ') {
2373 MonoInst *var = get_vreg_to_inst (cfg, ins->sreg2);
2374 if (var && var->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT)) {
2375 rhs = emit_volatile_load (ctx, ins->sreg2);
2377 if (!values [ins->sreg2])
2378 LLVM_FAILURE (ctx, "sreg2");
2379 rhs = values [ins->sreg2];
2385 //mono_print_ins (ins);
2386 switch (ins->opcode) {
2389 case OP_LIVERANGE_START:
2390 case OP_LIVERANGE_END:
2393 values [ins->dreg] = LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE);
2396 #if SIZEOF_VOID_P == 4
2397 values [ins->dreg] = LLVMConstInt (LLVMInt64Type (), GET_LONG_IMM (ins), FALSE);
2399 values [ins->dreg] = LLVMConstInt (LLVMInt64Type (), (gint64)ins->inst_c0, FALSE);
2403 values [ins->dreg] = LLVMConstReal (LLVMDoubleType (), *(double*)ins->inst_p0);
2406 values [ins->dreg] = LLVMConstFPExt (LLVMConstReal (LLVMFloatType (), *(float*)ins->inst_p0), LLVMDoubleType ());
2408 case OP_DUMMY_ICONST:
2409 values [ins->dreg] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
2411 case OP_DUMMY_I8CONST:
2412 values [ins->dreg] = LLVMConstInt (LLVMInt64Type (), 0, FALSE);
2414 case OP_DUMMY_R8CONST:
2415 values [ins->dreg] = LLVMConstReal (LLVMDoubleType (), 0.0f);
2418 LLVMBuildBr (builder, get_bb (ctx, ins->inst_target_bb));
2419 has_terminator = TRUE;
2425 LLVMBasicBlockRef new_bb;
2426 LLVMBuilderRef new_builder;
2428 // The default branch is already handled
2429 // FIXME: Handle it here
2431 /* Start new bblock */
2432 sprintf (bb_name, "SWITCH_DEFAULT_BB%d", ctx->default_index ++);
2433 new_bb = LLVMAppendBasicBlock (ctx->lmethod, bb_name);
2435 lhs = convert (ctx, lhs, LLVMInt32Type ());
2436 v = LLVMBuildSwitch (builder, lhs, new_bb, GPOINTER_TO_UINT (ins->klass));
2437 for (i = 0; i < GPOINTER_TO_UINT (ins->klass); ++i) {
2438 MonoBasicBlock *target_bb = ins->inst_many_bb [i];
2440 LLVMAddCase (v, LLVMConstInt (LLVMInt32Type (), i, FALSE), get_bb (ctx, target_bb));
2443 new_builder = create_builder (ctx);
2444 LLVMPositionBuilderAtEnd (new_builder, new_bb);
2445 LLVMBuildUnreachable (new_builder);
2447 has_terminator = TRUE;
2448 g_assert (!ins->next);
2454 if (linfo->ret.storage == LLVMArgVtypeInReg) {
2455 LLVMTypeRef ret_type = LLVMGetReturnType (LLVMGetElementType (LLVMTypeOf (method)));
2456 LLVMValueRef part1, retval;
2459 size = get_vtype_size (sig->ret);
2461 g_assert (addresses [ins->sreg1]);
2463 g_assert (linfo->ret.pair_storage [0] == LLVMArgInIReg);
2464 g_assert (linfo->ret.pair_storage [1] == LLVMArgNone);
2466 part1 = convert (ctx, LLVMBuildLoad (builder, LLVMBuildBitCast (builder, addresses [ins->sreg1], LLVMPointerType (LLVMIntType (size * 8), 0), ""), ""), IntPtrType ());
2468 retval = LLVMBuildInsertValue (builder, LLVMGetUndef (ret_type), part1, 0, "");
2470 LLVMBuildRet (builder, retval);
2474 if (linfo->ret.storage == LLVMArgVtypeRetAddr) {
2475 LLVMBuildRetVoid (builder);
2479 if (!lhs || ctx->is_dead [ins->sreg1]) {
2481 * The method did not set its return value, probably because it
2482 * ends with a throw.
2485 LLVMBuildRetVoid (builder);
2487 LLVMBuildRet (builder, LLVMConstNull (type_to_llvm_type (ctx, sig->ret)));
2489 LLVMBuildRet (builder, convert (ctx, lhs, type_to_llvm_type (ctx, sig->ret)));
2491 has_terminator = TRUE;
2497 case OP_ICOMPARE_IMM:
2498 case OP_LCOMPARE_IMM:
2499 case OP_COMPARE_IMM: {
2503 if (ins->next->opcode == OP_NOP)
2506 if (ins->next->opcode == OP_BR)
2507 /* The comparison result is not needed */
2510 rel = mono_opcode_to_cond (ins->next->opcode);
2512 if (ins->opcode == OP_ICOMPARE_IMM) {
2513 lhs = convert (ctx, lhs, LLVMInt32Type ());
2514 rhs = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
2516 if (ins->opcode == OP_LCOMPARE_IMM) {
2517 lhs = convert (ctx, lhs, LLVMInt64Type ());
2518 rhs = LLVMConstInt (LLVMInt64Type (), GET_LONG_IMM (ins), FALSE);
2520 if (ins->opcode == OP_LCOMPARE) {
2521 lhs = convert (ctx, lhs, LLVMInt64Type ());
2522 rhs = convert (ctx, rhs, LLVMInt64Type ());
2524 if (ins->opcode == OP_ICOMPARE) {
2525 lhs = convert (ctx, lhs, LLVMInt32Type ());
2526 rhs = convert (ctx, rhs, LLVMInt32Type ());
2530 if (LLVMGetTypeKind (LLVMTypeOf (lhs)) == LLVMPointerTypeKind)
2531 rhs = convert (ctx, rhs, LLVMTypeOf (lhs));
2532 else if (LLVMGetTypeKind (LLVMTypeOf (rhs)) == LLVMPointerTypeKind)
2533 lhs = convert (ctx, lhs, LLVMTypeOf (rhs));
2536 /* We use COMPARE+SETcc/Bcc, llvm uses SETcc+br cond */
2537 if (ins->opcode == OP_FCOMPARE)
2538 cmp = LLVMBuildFCmp (builder, fpcond_to_llvm_cond [rel], convert (ctx, lhs, LLVMDoubleType ()), convert (ctx, rhs, LLVMDoubleType ()), "");
2539 else if (ins->opcode == OP_COMPARE_IMM) {
2540 if (LLVMGetTypeKind (LLVMTypeOf (lhs)) == LLVMPointerTypeKind && ins->inst_imm == 0)
2541 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], lhs, LLVMConstNull (LLVMTypeOf (lhs)), "");
2543 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE), "");
2544 } else if (ins->opcode == OP_LCOMPARE_IMM) {
2545 if (SIZEOF_REGISTER == 4 && COMPILE_LLVM (cfg)) {
2546 /* The immediate is encoded in two fields */
2547 guint64 l = ((guint64)(guint32)ins->inst_offset << 32) | ((guint32)ins->inst_imm);
2548 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, LLVMInt64Type ()), LLVMConstInt (LLVMInt64Type (), l, FALSE), "");
2550 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, LLVMInt64Type ()), LLVMConstInt (LLVMInt64Type (), ins->inst_imm, FALSE), "");
2553 else if (ins->opcode == OP_COMPARE) {
2554 if (LLVMGetTypeKind (LLVMTypeOf (lhs)) == LLVMPointerTypeKind && LLVMTypeOf (lhs) == LLVMTypeOf (rhs))
2555 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], lhs, rhs, "");
2557 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, IntPtrType ()), convert (ctx, rhs, IntPtrType ()), "");
2559 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], lhs, rhs, "");
2561 if (MONO_IS_COND_BRANCH_OP (ins->next)) {
2562 if (ins->next->inst_true_bb == ins->next->inst_false_bb) {
2564 * If the target bb contains PHI instructions, LLVM requires
2565 * two PHI entries for this bblock, while we only generate one.
2566 * So convert this to an unconditional bblock. (bxc #171).
2568 LLVMBuildBr (builder, get_bb (ctx, ins->next->inst_true_bb));
2570 LLVMBuildCondBr (builder, cmp, get_bb (ctx, ins->next->inst_true_bb), get_bb (ctx, ins->next->inst_false_bb));
2572 has_terminator = TRUE;
2573 } else if (MONO_IS_SETCC (ins->next)) {
2574 sprintf (dname_buf, "t%d", ins->next->dreg);
2576 values [ins->next->dreg] = LLVMBuildZExt (builder, cmp, LLVMInt32Type (), dname);
2578 /* Add stores for volatile variables */
2579 emit_volatile_store (ctx, ins->next->dreg);
2580 } else if (MONO_IS_COND_EXC (ins->next)) {
2581 emit_cond_system_exception (ctx, bb, ins->next->inst_p1, cmp);
2582 CHECK_FAILURE (ctx);
2583 builder = ctx->builder;
2585 LLVM_FAILURE (ctx, "next");
2599 rel = mono_opcode_to_cond (ins->opcode);
2601 cmp = LLVMBuildFCmp (builder, fpcond_to_llvm_cond [rel], convert (ctx, lhs, LLVMDoubleType ()), convert (ctx, rhs, LLVMDoubleType ()), "");
2602 values [ins->dreg] = LLVMBuildZExt (builder, cmp, LLVMInt32Type (), dname);
2610 gboolean empty = TRUE;
2612 /* Check that all input bblocks really branch to us */
2613 for (i = 0; i < bb->in_count; ++i) {
2614 if (bb->in_bb [i]->last_ins && bb->in_bb [i]->last_ins->opcode == OP_NOT_REACHED)
2615 ins->inst_phi_args [i + 1] = -1;
2621 /* LLVM doesn't like phi instructions with zero operands */
2622 ctx->is_dead [ins->dreg] = TRUE;
2626 /* Created earlier, insert it now */
2627 LLVMInsertIntoBuilder (builder, values [ins->dreg]);
2629 for (i = 0; i < ins->inst_phi_args [0]; i++) {
2630 int sreg1 = ins->inst_phi_args [i + 1];
2634 * Count the number of times the incoming bblock branches to us,
2635 * since llvm requires a separate entry for each.
2637 if (bb->in_bb [i]->last_ins && bb->in_bb [i]->last_ins->opcode == OP_SWITCH) {
2638 MonoInst *switch_ins = bb->in_bb [i]->last_ins;
2641 for (j = 0; j < GPOINTER_TO_UINT (switch_ins->klass); ++j) {
2642 if (switch_ins->inst_many_bb [j] == bb)
2649 /* Remember for later */
2650 for (j = 0; j < count; ++j) {
2651 PhiNode *node = mono_mempool_alloc0 (ctx->mempool, sizeof (PhiNode));
2654 node->in_bb = bb->in_bb [i];
2656 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);
2666 values [ins->dreg] = lhs;
2669 MonoInst *var = get_vreg_to_inst (cfg, ins->dreg);
2672 values [ins->dreg] = lhs;
2674 if (var && var->klass->byval_arg.type == MONO_TYPE_R4) {
2676 * This is added by the spilling pass in case of the JIT,
2677 * but we have to do it ourselves.
2679 values [ins->dreg] = convert (ctx, values [ins->dreg], LLVMFloatType ());
2713 lhs = convert (ctx, lhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
2714 rhs = convert (ctx, rhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
2716 switch (ins->opcode) {
2719 values [ins->dreg] = LLVMBuildAdd (builder, lhs, rhs, dname);
2723 values [ins->dreg] = LLVMBuildSub (builder, lhs, rhs, dname);
2727 values [ins->dreg] = LLVMBuildMul (builder, lhs, rhs, dname);
2731 values [ins->dreg] = LLVMBuildSRem (builder, lhs, rhs, dname);
2735 values [ins->dreg] = LLVMBuildURem (builder, lhs, rhs, dname);
2739 values [ins->dreg] = LLVMBuildSDiv (builder, lhs, rhs, dname);
2743 values [ins->dreg] = LLVMBuildUDiv (builder, lhs, rhs, dname);
2746 values [ins->dreg] = LLVMBuildFDiv (builder, lhs, rhs, dname);
2750 values [ins->dreg] = LLVMBuildAnd (builder, lhs, rhs, dname);
2754 values [ins->dreg] = LLVMBuildOr (builder, lhs, rhs, dname);
2758 values [ins->dreg] = LLVMBuildXor (builder, lhs, rhs, dname);
2762 values [ins->dreg] = LLVMBuildShl (builder, lhs, rhs, dname);
2766 values [ins->dreg] = LLVMBuildAShr (builder, lhs, rhs, dname);
2770 values [ins->dreg] = LLVMBuildLShr (builder, lhs, rhs, dname);
2774 values [ins->dreg] = LLVMBuildFAdd (builder, lhs, rhs, dname);
2777 values [ins->dreg] = LLVMBuildFSub (builder, lhs, rhs, dname);
2780 values [ins->dreg] = LLVMBuildFMul (builder, lhs, rhs, dname);
2784 g_assert_not_reached ();
2791 case OP_IREM_UN_IMM:
2793 case OP_IDIV_UN_IMM:
2799 case OP_ISHR_UN_IMM:
2808 case OP_LSHR_UN_IMM:
2814 case OP_SHR_UN_IMM: {
2817 if (spec [MONO_INST_SRC1] == 'l') {
2818 imm = LLVMConstInt (LLVMInt64Type (), GET_LONG_IMM (ins), FALSE);
2820 imm = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
2823 #if SIZEOF_VOID_P == 4
2824 if (ins->opcode == OP_LSHL_IMM || ins->opcode == OP_LSHR_IMM || ins->opcode == OP_LSHR_UN_IMM)
2825 imm = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
2828 if (LLVMGetTypeKind (LLVMTypeOf (lhs)) == LLVMPointerTypeKind)
2829 lhs = convert (ctx, lhs, IntPtrType ());
2830 imm = convert (ctx, imm, LLVMTypeOf (lhs));
2831 switch (ins->opcode) {
2835 values [ins->dreg] = LLVMBuildAdd (builder, lhs, imm, dname);
2839 values [ins->dreg] = LLVMBuildSub (builder, lhs, imm, dname);
2843 values [ins->dreg] = LLVMBuildMul (builder, lhs, imm, dname);
2847 values [ins->dreg] = LLVMBuildSDiv (builder, lhs, imm, dname);
2849 case OP_IDIV_UN_IMM:
2850 case OP_LDIV_UN_IMM:
2851 values [ins->dreg] = LLVMBuildUDiv (builder, lhs, imm, dname);
2855 values [ins->dreg] = LLVMBuildSRem (builder, lhs, imm, dname);
2857 case OP_IREM_UN_IMM:
2858 values [ins->dreg] = LLVMBuildURem (builder, lhs, imm, dname);
2863 values [ins->dreg] = LLVMBuildAnd (builder, lhs, imm, dname);
2867 values [ins->dreg] = LLVMBuildOr (builder, lhs, imm, dname);
2871 values [ins->dreg] = LLVMBuildXor (builder, lhs, imm, dname);
2876 values [ins->dreg] = LLVMBuildShl (builder, lhs, imm, dname);
2881 values [ins->dreg] = LLVMBuildAShr (builder, lhs, imm, dname);
2883 case OP_ISHR_UN_IMM:
2884 /* This is used to implement conv.u4, so the lhs could be an i8 */
2885 lhs = convert (ctx, lhs, LLVMInt32Type ());
2886 imm = convert (ctx, imm, LLVMInt32Type ());
2887 values [ins->dreg] = LLVMBuildLShr (builder, lhs, imm, dname);
2889 case OP_LSHR_UN_IMM:
2891 values [ins->dreg] = LLVMBuildLShr (builder, lhs, imm, dname);
2894 g_assert_not_reached ();
2899 values [ins->dreg] = LLVMBuildSub (builder, LLVMConstInt (LLVMInt32Type (), 0, FALSE), convert (ctx, lhs, LLVMInt32Type ()), dname);
2902 values [ins->dreg] = LLVMBuildSub (builder, LLVMConstInt (LLVMInt64Type (), 0, FALSE), lhs, dname);
2905 lhs = convert (ctx, lhs, LLVMDoubleType ());
2906 values [ins->dreg] = LLVMBuildFSub (builder, LLVMConstReal (LLVMDoubleType (), 0.0), lhs, dname);
2909 guint32 v = 0xffffffff;
2910 values [ins->dreg] = LLVMBuildXor (builder, LLVMConstInt (LLVMInt32Type (), v, FALSE), convert (ctx, lhs, LLVMInt32Type ()), dname);
2914 guint64 v = 0xffffffffffffffffLL;
2915 values [ins->dreg] = LLVMBuildXor (builder, LLVMConstInt (LLVMInt64Type (), v, FALSE), lhs, dname);
2918 #if defined(TARGET_X86) || defined(TARGET_AMD64)
2920 LLVMValueRef v1, v2;
2922 v1 = LLVMBuildMul (builder, convert (ctx, rhs, IntPtrType ()), LLVMConstInt (IntPtrType (), (1 << ins->backend.shift_amount), FALSE), "");
2923 v2 = LLVMBuildAdd (builder, convert (ctx, lhs, IntPtrType ()), v1, "");
2924 values [ins->dreg] = LLVMBuildAdd (builder, v2, LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE), dname);
2929 case OP_ICONV_TO_I1:
2930 case OP_ICONV_TO_I2:
2931 case OP_ICONV_TO_I4:
2932 case OP_ICONV_TO_U1:
2933 case OP_ICONV_TO_U2:
2934 case OP_ICONV_TO_U4:
2935 case OP_LCONV_TO_I1:
2936 case OP_LCONV_TO_I2:
2937 case OP_LCONV_TO_U1:
2938 case OP_LCONV_TO_U2:
2939 case OP_LCONV_TO_U4: {
2942 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);
2944 /* Have to do two casts since our vregs have type int */
2945 v = LLVMBuildTrunc (builder, lhs, op_to_llvm_type (ins->opcode), "");
2947 values [ins->dreg] = LLVMBuildSExt (builder, v, LLVMInt32Type (), dname);
2949 values [ins->dreg] = LLVMBuildZExt (builder, v, LLVMInt32Type (), dname);
2952 case OP_ICONV_TO_I8:
2953 values [ins->dreg] = LLVMBuildSExt (builder, lhs, LLVMInt64Type (), dname);
2955 case OP_ICONV_TO_U8:
2956 values [ins->dreg] = LLVMBuildZExt (builder, lhs, LLVMInt64Type (), dname);
2958 case OP_FCONV_TO_I4:
2959 values [ins->dreg] = LLVMBuildFPToSI (builder, lhs, LLVMInt32Type (), dname);
2961 case OP_FCONV_TO_I1:
2962 values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildFPToSI (builder, lhs, LLVMInt8Type (), dname), LLVMInt32Type (), "");
2964 case OP_FCONV_TO_U1:
2965 values [ins->dreg] = LLVMBuildZExt (builder, LLVMBuildFPToUI (builder, lhs, LLVMInt8Type (), dname), LLVMInt32Type (), "");
2967 case OP_FCONV_TO_I2:
2968 values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildFPToSI (builder, lhs, LLVMInt16Type (), dname), LLVMInt32Type (), "");
2970 case OP_FCONV_TO_U2:
2971 values [ins->dreg] = LLVMBuildZExt (builder, LLVMBuildFPToUI (builder, lhs, LLVMInt16Type (), dname), LLVMInt32Type (), "");
2973 case OP_FCONV_TO_I8:
2974 values [ins->dreg] = LLVMBuildFPToSI (builder, lhs, LLVMInt64Type (), dname);
2977 values [ins->dreg] = LLVMBuildFPToSI (builder, lhs, IntPtrType (), dname);
2979 case OP_ICONV_TO_R8:
2980 case OP_LCONV_TO_R8:
2981 values [ins->dreg] = LLVMBuildSIToFP (builder, lhs, LLVMDoubleType (), dname);
2983 case OP_LCONV_TO_R_UN:
2984 values [ins->dreg] = LLVMBuildUIToFP (builder, lhs, LLVMDoubleType (), dname);
2986 #if SIZEOF_VOID_P == 4
2989 case OP_LCONV_TO_I4:
2990 values [ins->dreg] = LLVMBuildTrunc (builder, lhs, LLVMInt32Type (), dname);
2992 case OP_ICONV_TO_R4:
2993 case OP_LCONV_TO_R4:
2994 v = LLVMBuildSIToFP (builder, lhs, LLVMFloatType (), "");
2995 values [ins->dreg] = LLVMBuildFPExt (builder, v, LLVMDoubleType (), dname);
2997 case OP_FCONV_TO_R4:
2998 v = LLVMBuildFPTrunc (builder, lhs, LLVMFloatType (), "");
2999 values [ins->dreg] = LLVMBuildFPExt (builder, v, LLVMDoubleType (), dname);
3002 values [ins->dreg] = LLVMBuildSExt (builder, convert (ctx, lhs, LLVMInt32Type ()), LLVMInt64Type (), dname);
3005 values [ins->dreg] = LLVMBuildZExt (builder, convert (ctx, lhs, LLVMInt32Type ()), LLVMInt64Type (), dname);
3008 values [ins->dreg] = LLVMBuildTrunc (builder, lhs, LLVMInt32Type (), dname);
3010 case OP_LOCALLOC_IMM: {
3013 guint32 size = ins->inst_imm;
3014 size = (size + (MONO_ARCH_FRAME_ALIGNMENT - 1)) & ~ (MONO_ARCH_FRAME_ALIGNMENT - 1);
3016 v = mono_llvm_build_alloca (builder, LLVMInt8Type (), LLVMConstInt (LLVMInt32Type (), size, FALSE), MONO_ARCH_FRAME_ALIGNMENT, "");
3018 if (ins->flags & MONO_INST_INIT) {
3019 LLVMValueRef args [5];
3022 args [1] = LLVMConstInt (LLVMInt8Type (), 0, FALSE);
3023 args [2] = LLVMConstInt (LLVMInt32Type (), size, FALSE);
3024 args [3] = LLVMConstInt (LLVMInt32Type (), MONO_ARCH_FRAME_ALIGNMENT, FALSE);
3025 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
3026 LLVMBuildCall (builder, LLVMGetNamedFunction (module, memset_func_name), args, memset_param_count, "");
3029 values [ins->dreg] = v;
3033 LLVMValueRef v, size;
3035 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), "");
3037 v = mono_llvm_build_alloca (builder, LLVMInt8Type (), size, MONO_ARCH_FRAME_ALIGNMENT, "");
3039 if (ins->flags & MONO_INST_INIT) {
3040 LLVMValueRef args [5];
3043 args [1] = LLVMConstInt (LLVMInt8Type (), 0, FALSE);
3045 args [3] = LLVMConstInt (LLVMInt32Type (), MONO_ARCH_FRAME_ALIGNMENT, FALSE);
3046 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
3047 LLVMBuildCall (builder, LLVMGetNamedFunction (module, memset_func_name), args, memset_param_count, "");
3049 values [ins->dreg] = v;
3053 case OP_LOADI1_MEMBASE:
3054 case OP_LOADU1_MEMBASE:
3055 case OP_LOADI2_MEMBASE:
3056 case OP_LOADU2_MEMBASE:
3057 case OP_LOADI4_MEMBASE:
3058 case OP_LOADU4_MEMBASE:
3059 case OP_LOADI8_MEMBASE:
3060 case OP_LOADR4_MEMBASE:
3061 case OP_LOADR8_MEMBASE:
3062 case OP_LOAD_MEMBASE:
3070 LLVMValueRef base, index, addr;
3072 gboolean sext = FALSE, zext = FALSE;
3073 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
3075 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
3080 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)) {
3081 addr = LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE);
3086 if (ins->inst_offset == 0) {
3088 } else if (ins->inst_offset % size != 0) {
3089 /* Unaligned load */
3090 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset, FALSE);
3091 addr = LLVMBuildGEP (builder, convert (ctx, base, LLVMPointerType (LLVMInt8Type (), 0)), &index, 1, "");
3093 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
3094 addr = LLVMBuildGEP (builder, convert (ctx, base, LLVMPointerType (t, 0)), &index, 1, "");
3098 addr = convert (ctx, addr, LLVMPointerType (t, 0));
3100 values [ins->dreg] = emit_load (ctx, bb, &builder, size, addr, dname, is_volatile);
3102 if (!is_volatile && (ins->flags & MONO_INST_INVARIANT_LOAD)) {
3104 * These will signal LLVM that these loads do not alias any stores, and
3105 * they can't fail, allowing them to be hoisted out of loops.
3107 set_invariant_load_flag (values [ins->dreg]);
3108 set_metadata_flag (values [ins->dreg], "mono.nofail.load");
3112 values [ins->dreg] = LLVMBuildSExt (builder, values [ins->dreg], LLVMInt32Type (), dname);
3114 values [ins->dreg] = LLVMBuildZExt (builder, values [ins->dreg], LLVMInt32Type (), dname);
3115 else if (ins->opcode == OP_LOADR4_MEMBASE)
3116 values [ins->dreg] = LLVMBuildFPExt (builder, values [ins->dreg], LLVMDoubleType (), dname);
3120 case OP_STOREI1_MEMBASE_REG:
3121 case OP_STOREI2_MEMBASE_REG:
3122 case OP_STOREI4_MEMBASE_REG:
3123 case OP_STOREI8_MEMBASE_REG:
3124 case OP_STORER4_MEMBASE_REG:
3125 case OP_STORER8_MEMBASE_REG:
3126 case OP_STORE_MEMBASE_REG: {
3128 LLVMValueRef index, addr;
3130 gboolean sext = FALSE, zext = FALSE;
3131 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
3133 if (!values [ins->inst_destbasereg])
3134 LLVM_FAILURE (ctx, "inst_destbasereg");
3136 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
3138 if (ins->inst_offset % size != 0) {
3139 /* Unaligned store */
3140 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset, FALSE);
3141 addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (LLVMInt8Type (), 0)), &index, 1, "");
3143 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
3144 addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (t, 0)), &index, 1, "");
3146 emit_store (ctx, bb, &builder, size, convert (ctx, values [ins->sreg1], t), convert (ctx, addr, LLVMPointerType (t, 0)), is_volatile);
3150 case OP_STOREI1_MEMBASE_IMM:
3151 case OP_STOREI2_MEMBASE_IMM:
3152 case OP_STOREI4_MEMBASE_IMM:
3153 case OP_STOREI8_MEMBASE_IMM:
3154 case OP_STORE_MEMBASE_IMM: {
3156 LLVMValueRef index, addr;
3158 gboolean sext = FALSE, zext = FALSE;
3159 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
3161 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
3163 if (ins->inst_offset % size != 0) {
3164 /* Unaligned store */
3165 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset, FALSE);
3166 addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (LLVMInt8Type (), 0)), &index, 1, "");
3168 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
3169 addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (t, 0)), &index, 1, "");
3171 emit_store (ctx, bb, &builder, size, convert (ctx, LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE), t), convert (ctx, addr, LLVMPointerType (t, 0)), is_volatile);
3176 emit_load (ctx, bb, &builder, sizeof (gpointer), convert (ctx, lhs, LLVMPointerType (IntPtrType (), 0)), "", TRUE);
3178 case OP_OUTARG_VTRETADDR:
3185 case OP_VOIDCALL_MEMBASE:
3186 case OP_CALL_MEMBASE:
3187 case OP_LCALL_MEMBASE:
3188 case OP_FCALL_MEMBASE:
3189 case OP_VCALL_MEMBASE:
3190 case OP_VOIDCALL_REG:
3194 case OP_VCALL_REG: {
3195 process_call (ctx, bb, &builder, ins);
3196 CHECK_FAILURE (ctx);
3201 LLVMValueRef indexes [2];
3203 LLVMValueRef got_entry_addr;
3206 * FIXME: Can't allocate from the cfg mempool since that is freed if
3207 * the LLVM compile fails.
3209 ji = g_new0 (MonoJumpInfo, 1);
3210 ji->type = (MonoJumpInfoType)ins->inst_i1;
3211 ji->data.target = ins->inst_p0;
3213 ji = mono_aot_patch_info_dup (ji);
3215 ji->next = cfg->patch_info;
3216 cfg->patch_info = ji;
3218 //mono_add_patch_info (cfg, 0, (MonoJumpInfoType)ins->inst_i1, ins->inst_p0);
3219 got_offset = mono_aot_get_got_offset (cfg->patch_info);
3221 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
3222 indexes [1] = LLVMConstInt (LLVMInt32Type (), (gssize)got_offset, FALSE);
3223 got_entry_addr = LLVMBuildGEP (builder, ctx->lmodule->got_var, indexes, 2, "");
3225 values [ins->dreg] = LLVMBuildLoad (builder, got_entry_addr, dname);
3226 set_invariant_load_flag (values [ins->dreg]);
3229 case OP_NOT_REACHED:
3230 LLVMBuildUnreachable (builder);
3231 has_terminator = TRUE;
3232 g_assert (bb->block_num < cfg->max_block_num);
3233 ctx->unreachable [bb->block_num] = TRUE;
3234 /* Might have instructions after this */
3236 MonoInst *next = ins->next;
3238 * FIXME: If later code uses the regs defined by these instructions,
3239 * compilation will fail.
3241 MONO_DELETE_INS (bb, next);
3245 MonoInst *var = ins->inst_p0;
3247 values [ins->dreg] = addresses [var->dreg];
3251 LLVMValueRef args [1];
3253 args [0] = convert (ctx, lhs, LLVMDoubleType ());
3254 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, "llvm.sin.f64"), args, 1, dname);
3258 LLVMValueRef args [1];
3260 args [0] = convert (ctx, lhs, LLVMDoubleType ());
3261 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, "llvm.cos.f64"), args, 1, dname);
3265 LLVMValueRef args [1];
3268 /* This no longer seems to happen */
3270 * LLVM optimizes sqrt(nan) into undefined in
3271 * lib/Analysis/ConstantFolding.cpp
3272 * Also, sqrt(NegativeInfinity) is optimized into 0.
3274 LLVM_FAILURE (ctx, "sqrt");
3276 args [0] = convert (ctx, lhs, LLVMDoubleType ());
3277 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, "llvm.sqrt.f64"), args, 1, dname);
3281 LLVMValueRef args [1];
3283 args [0] = convert (ctx, lhs, LLVMDoubleType ());
3284 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, "fabs"), args, 1, dname);
3298 lhs = convert (ctx, lhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
3299 rhs = convert (ctx, rhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
3301 switch (ins->opcode) {
3304 v = LLVMBuildICmp (builder, LLVMIntSLE, lhs, rhs, "");
3308 v = LLVMBuildICmp (builder, LLVMIntSGE, lhs, rhs, "");
3312 v = LLVMBuildICmp (builder, LLVMIntULE, lhs, rhs, "");
3316 v = LLVMBuildICmp (builder, LLVMIntUGE, lhs, rhs, "");
3319 g_assert_not_reached ();
3322 values [ins->dreg] = LLVMBuildSelect (builder, v, lhs, rhs, dname);
3325 case OP_ATOMIC_EXCHANGE_I4:
3326 case OP_ATOMIC_EXCHANGE_I8: {
3327 LLVMValueRef args [2];
3330 if (ins->opcode == OP_ATOMIC_EXCHANGE_I4)
3331 t = LLVMInt32Type ();
3333 t = LLVMInt64Type ();
3335 g_assert (ins->inst_offset == 0);
3337 args [0] = convert (ctx, lhs, LLVMPointerType (t, 0));
3338 args [1] = convert (ctx, rhs, t);
3340 values [ins->dreg] = mono_llvm_build_atomic_rmw (builder, LLVM_ATOMICRMW_OP_XCHG, args [0], args [1]);
3343 case OP_ATOMIC_ADD_I4:
3344 case OP_ATOMIC_ADD_I8: {
3345 LLVMValueRef args [2];
3348 if (ins->opcode == OP_ATOMIC_ADD_I4)
3349 t = LLVMInt32Type ();
3351 t = LLVMInt64Type ();
3353 g_assert (ins->inst_offset == 0);
3355 args [0] = convert (ctx, lhs, LLVMPointerType (t, 0));
3356 args [1] = convert (ctx, rhs, t);
3357 values [ins->dreg] = LLVMBuildAdd (builder, mono_llvm_build_atomic_rmw (builder, LLVM_ATOMICRMW_OP_ADD, args [0], args [1]), args [1], dname);
3360 case OP_ATOMIC_CAS_I4:
3361 case OP_ATOMIC_CAS_I8: {
3362 LLVMValueRef args [3], val;
3365 if (ins->opcode == OP_ATOMIC_CAS_I4)
3366 t = LLVMInt32Type ();
3368 t = LLVMInt64Type ();
3370 args [0] = convert (ctx, lhs, LLVMPointerType (t, 0));
3372 args [1] = convert (ctx, values [ins->sreg3], t);
3374 args [2] = convert (ctx, values [ins->sreg2], t);
3375 val = mono_llvm_build_cmpxchg (builder, args [0], args [1], args [2]);
3376 #if LLVM_API_VERSION >= 1
3377 /* cmpxchg returns a pair */
3378 values [ins->dreg] = LLVMBuildExtractValue (builder, val, 0, "");
3380 values [ins->dreg] = val;
3384 case OP_MEMORY_BARRIER: {
3385 mono_llvm_build_fence (builder);
3388 case OP_RELAXED_NOP: {
3389 #if defined(TARGET_AMD64) || defined(TARGET_X86)
3390 emit_call (ctx, bb, &builder, LLVMGetNamedFunction (ctx->module, "llvm.x86.sse2.pause"), NULL, 0);
3397 #if (defined(TARGET_AMD64) || defined(TARGET_X86)) && defined(__linux__)
3399 // 257 == FS segment register
3400 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 257);
3402 // 256 == GS segment register
3403 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 256);
3406 values [ins->dreg] = LLVMBuildLoad (builder, LLVMBuildIntToPtr (builder, LLVMConstInt (IntPtrType (), ins->inst_offset, TRUE), ptrtype, ""), "");
3407 #elif defined(TARGET_AMD64) && defined(TARGET_OSX)
3408 /* See mono_amd64_emit_tls_get () */
3409 int offset = mono_amd64_get_tls_gs_offset () + (ins->inst_offset * 8);
3411 // 256 == GS segment register
3412 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 256);
3413 values [ins->dreg] = LLVMBuildLoad (builder, LLVMBuildIntToPtr (builder, LLVMConstInt (IntPtrType (), offset, TRUE), ptrtype, ""), "");
3415 LLVM_FAILURE (ctx, "opcode tls-get");
3420 case OP_TLS_GET_REG: {
3421 #if defined(TARGET_AMD64) && defined(TARGET_OSX)
3422 /* See emit_tls_get_reg () */
3423 // 256 == GS segment register
3424 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 256);
3425 values [ins->dreg] = LLVMBuildLoad (builder, LLVMBuildIntToPtr (builder, convert (ctx, lhs, LLVMInt32Type ()), ptrtype, ""), "");
3427 LLVM_FAILURE (ctx, "opcode tls-get");
3436 case OP_IADD_OVF_UN:
3438 case OP_ISUB_OVF_UN:
3440 case OP_IMUL_OVF_UN:
3441 #if SIZEOF_VOID_P == 8
3443 case OP_LADD_OVF_UN:
3445 case OP_LSUB_OVF_UN:
3447 case OP_LMUL_OVF_UN:
3450 LLVMValueRef args [2], val, ovf, func;
3452 args [0] = convert (ctx, lhs, op_to_llvm_type (ins->opcode));
3453 args [1] = convert (ctx, rhs, op_to_llvm_type (ins->opcode));
3454 func = LLVMGetNamedFunction (module, ovf_op_to_intrins (ins->opcode));
3456 val = LLVMBuildCall (builder, func, args, 2, "");
3457 values [ins->dreg] = LLVMBuildExtractValue (builder, val, 0, dname);
3458 ovf = LLVMBuildExtractValue (builder, val, 1, "");
3459 emit_cond_system_exception (ctx, bb, "OverflowException", ovf);
3460 CHECK_FAILURE (ctx);
3461 builder = ctx->builder;
3467 * We currently model them using arrays. Promotion to local vregs is
3468 * disabled for them in mono_handle_global_vregs () in the LLVM case,
3469 * so we always have an entry in cfg->varinfo for them.
3470 * FIXME: Is this needed ?
3473 MonoClass *klass = ins->klass;
3474 LLVMValueRef args [5];
3478 LLVM_FAILURE (ctx, "!klass");
3482 if (!addresses [ins->dreg])
3483 addresses [ins->dreg] = build_alloca (ctx, &klass->byval_arg);
3484 args [0] = LLVMBuildBitCast (builder, addresses [ins->dreg], LLVMPointerType (LLVMInt8Type (), 0), "");
3485 args [1] = LLVMConstInt (LLVMInt8Type (), 0, FALSE);
3486 args [2] = LLVMConstInt (LLVMInt32Type (), mono_class_value_size (klass, NULL), FALSE);
3488 args [3] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
3489 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
3490 LLVMBuildCall (builder, LLVMGetNamedFunction (module, memset_func_name), args, memset_param_count, "");
3493 case OP_DUMMY_VZERO:
3496 case OP_STOREV_MEMBASE:
3497 case OP_LOADV_MEMBASE:
3499 MonoClass *klass = ins->klass;
3500 LLVMValueRef src = NULL, dst, args [5];
3501 gboolean done = FALSE;
3505 LLVM_FAILURE (ctx, "!klass");
3509 if (mini_is_gsharedvt_klass (cfg, klass)) {
3511 LLVM_FAILURE (ctx, "gsharedvt");
3515 switch (ins->opcode) {
3516 case OP_STOREV_MEMBASE:
3517 if (cfg->gen_write_barriers && klass->has_references && ins->inst_destbasereg != cfg->frame_reg &&
3518 LLVMGetInstructionOpcode (values [ins->inst_destbasereg]) != LLVMAlloca) {
3519 /* Decomposed earlier */
3520 g_assert_not_reached ();
3523 if (!addresses [ins->sreg1]) {
3525 g_assert (values [ins->sreg1]);
3526 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));
3527 LLVMBuildStore (builder, values [ins->sreg1], dst);
3530 src = LLVMBuildBitCast (builder, addresses [ins->sreg1], LLVMPointerType (LLVMInt8Type (), 0), "");
3531 dst = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_destbasereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (LLVMInt8Type (), 0));
3534 case OP_LOADV_MEMBASE:
3535 if (!addresses [ins->dreg])
3536 addresses [ins->dreg] = build_alloca (ctx, &klass->byval_arg);
3537 src = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_basereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (LLVMInt8Type (), 0));
3538 dst = LLVMBuildBitCast (builder, addresses [ins->dreg], LLVMPointerType (LLVMInt8Type (), 0), "");
3541 if (!addresses [ins->sreg1])
3542 addresses [ins->sreg1] = build_alloca (ctx, &klass->byval_arg);
3543 if (!addresses [ins->dreg])
3544 addresses [ins->dreg] = build_alloca (ctx, &klass->byval_arg);
3545 src = LLVMBuildBitCast (builder, addresses [ins->sreg1], LLVMPointerType (LLVMInt8Type (), 0), "");
3546 dst = LLVMBuildBitCast (builder, addresses [ins->dreg], LLVMPointerType (LLVMInt8Type (), 0), "");
3549 g_assert_not_reached ();
3551 CHECK_FAILURE (ctx);
3558 args [2] = LLVMConstInt (LLVMInt32Type (), mono_class_value_size (klass, NULL), FALSE);
3559 args [3] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
3561 args [3] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
3562 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
3563 LLVMBuildCall (builder, LLVMGetNamedFunction (module, memcpy_func_name), args, memcpy_param_count, "");
3566 case OP_LLVM_OUTARG_VT:
3567 if (!addresses [ins->sreg1]) {
3568 addresses [ins->sreg1] = build_alloca (ctx, &ins->klass->byval_arg);
3569 g_assert (values [ins->sreg1]);
3570 LLVMBuildStore (builder, values [ins->sreg1], addresses [ins->sreg1]);
3572 addresses [ins->dreg] = addresses [ins->sreg1];
3578 #if defined(TARGET_X86) || defined(TARGET_AMD64)
3580 values [ins->dreg] = LLVMConstNull (type_to_llvm_type (ctx, &ins->klass->byval_arg));
3583 case OP_LOADX_MEMBASE: {
3584 LLVMTypeRef t = type_to_llvm_type (ctx, &ins->klass->byval_arg);
3587 src = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_basereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (t, 0));
3588 values [ins->dreg] = mono_llvm_build_aligned_load (builder, src, "", FALSE, 1);
3591 case OP_STOREX_MEMBASE: {
3592 LLVMTypeRef t = LLVMTypeOf (values [ins->sreg1]);
3595 dest = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_destbasereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (t, 0));
3596 mono_llvm_build_aligned_store (builder, values [ins->sreg1], dest, FALSE, 1);
3603 values [ins->dreg] = LLVMBuildAdd (builder, lhs, rhs, "");
3607 values [ins->dreg] = LLVMBuildFAdd (builder, lhs, rhs, "");
3613 values [ins->dreg] = LLVMBuildSub (builder, lhs, rhs, "");
3617 values [ins->dreg] = LLVMBuildFSub (builder, lhs, rhs, "");
3621 values [ins->dreg] = LLVMBuildFMul (builder, lhs, rhs, "");
3625 values [ins->dreg] = LLVMBuildFDiv (builder, lhs, rhs, "");
3628 values [ins->dreg] = LLVMBuildAnd (builder, lhs, rhs, "");
3631 values [ins->dreg] = LLVMBuildOr (builder, lhs, rhs, "");
3634 values [ins->dreg] = LLVMBuildXor (builder, lhs, rhs, "");
3638 values [ins->dreg] = LLVMBuildMul (builder, lhs, rhs, "");
3649 LLVMValueRef v = NULL;
3651 switch (ins->opcode) {
3656 t = LLVMVectorType (LLVMInt32Type (), 4);
3657 rt = LLVMVectorType (LLVMFloatType (), 4);
3663 t = LLVMVectorType (LLVMInt64Type (), 2);
3664 rt = LLVMVectorType (LLVMDoubleType (), 2);
3667 t = LLVMInt32Type ();
3668 rt = LLVMInt32Type ();
3669 g_assert_not_reached ();
3672 lhs = LLVMBuildBitCast (builder, lhs, t, "");
3673 rhs = LLVMBuildBitCast (builder, rhs, t, "");
3674 switch (ins->opcode) {
3677 v = LLVMBuildAnd (builder, lhs, rhs, "");
3681 v = LLVMBuildOr (builder, lhs, rhs, "");
3685 v = LLVMBuildXor (builder, lhs, rhs, "");
3689 v = LLVMBuildAnd (builder, rhs, LLVMBuildNot (builder, lhs, ""), "");
3692 values [ins->dreg] = LLVMBuildBitCast (builder, v, rt, "");
3716 case OP_PADDB_SAT_UN:
3717 case OP_PADDW_SAT_UN:
3718 case OP_PSUBB_SAT_UN:
3719 case OP_PSUBW_SAT_UN:
3727 case OP_PMULW_HIGH_UN: {
3728 LLVMValueRef args [2];
3733 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, simd_op_to_intrins (ins->opcode)), args, 2, dname);
3740 values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildICmp (builder, LLVMIntEQ, lhs, rhs, ""), LLVMTypeOf (lhs), "");
3744 values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildICmp (builder, LLVMIntSGT, lhs, rhs, ""), LLVMTypeOf (lhs), "");
3752 case OP_EXTRACTX_U2:
3754 case OP_EXTRACT_U1: {
3756 gboolean zext = FALSE;
3758 t = simd_op_to_llvm_type (ins->opcode);
3760 switch (ins->opcode) {
3768 case OP_EXTRACTX_U2:
3773 t = LLVMInt32Type ();
3774 g_assert_not_reached ();
3777 lhs = LLVMBuildBitCast (builder, lhs, t, "");
3778 values [ins->dreg] = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), "");
3780 values [ins->dreg] = LLVMBuildZExt (builder, values [ins->dreg], LLVMInt32Type (), "");
3789 case OP_EXPAND_R8: {
3790 LLVMTypeRef t = simd_op_to_llvm_type (ins->opcode);
3791 LLVMValueRef mask [16], v;
3793 for (i = 0; i < 16; ++i)
3794 mask [i] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
3796 v = convert (ctx, values [ins->sreg1], LLVMGetElementType (t));
3798 values [ins->dreg] = LLVMBuildInsertElement (builder, LLVMConstNull (t), v, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
3799 values [ins->dreg] = LLVMBuildShuffleVector (builder, values [ins->dreg], LLVMGetUndef (t), LLVMConstVector (mask, LLVMGetVectorSize (t)), "");
3804 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt8Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
3807 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt16Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
3810 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt32Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
3813 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt64Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
3816 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMFloatType ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
3819 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMDoubleType ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
3830 case OP_EXTRACT_MASK:
3837 v = convert (ctx, values [ins->sreg1], simd_op_to_llvm_type (ins->opcode));
3839 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, simd_op_to_intrins (ins->opcode)), &v, 1, dname);
3843 case OP_ICONV_TO_R8_RAW:
3844 /* Same as OP_ICONV_TO_R8 */
3845 values [ins->dreg] = convert (ctx, LLVMBuildBitCast (builder, lhs, LLVMFloatType (), ""), LLVMDoubleType ());
3850 LLVMValueRef args [3];
3854 args [2] = LLVMConstInt (LLVMInt8Type (), ins->inst_c0, FALSE);
3856 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, simd_op_to_intrins (ins->opcode)), args, 3, dname);
3861 /* This is only used for implementing shifts by non-immediate */
3862 values [ins->dreg] = lhs;
3873 LLVMValueRef args [3];
3876 args [1] = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
3878 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, simd_op_to_intrins (ins->opcode)), args, 2, dname);
3889 case OP_PSHLQ_REG: {
3890 LLVMValueRef args [3];
3893 args [1] = values [ins->sreg2];
3895 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, simd_op_to_intrins (ins->opcode)), args, 2, dname);
3902 case OP_PSHUFLEW_LOW:
3903 case OP_PSHUFLEW_HIGH: {
3905 LLVMValueRef v1 = NULL, v2 = NULL, mask_values [16];
3906 int i, mask_size = 0;
3907 int imask = ins->inst_c0;
3909 /* Convert the x86 shuffle mask to LLVM's */
3910 switch (ins->opcode) {
3913 mask [0] = ((imask >> 0) & 3);
3914 mask [1] = ((imask >> 2) & 3);
3915 mask [2] = ((imask >> 4) & 3) + 4;
3916 mask [3] = ((imask >> 6) & 3) + 4;
3917 v1 = values [ins->sreg1];
3918 v2 = values [ins->sreg2];
3922 mask [0] = ((imask >> 0) & 1);
3923 mask [1] = ((imask >> 1) & 1) + 2;
3924 v1 = values [ins->sreg1];
3925 v2 = values [ins->sreg2];
3927 case OP_PSHUFLEW_LOW:
3929 mask [0] = ((imask >> 0) & 3);
3930 mask [1] = ((imask >> 2) & 3);
3931 mask [2] = ((imask >> 4) & 3);
3932 mask [3] = ((imask >> 6) & 3);
3937 v1 = values [ins->sreg1];
3938 v2 = LLVMGetUndef (LLVMTypeOf (v1));
3940 case OP_PSHUFLEW_HIGH:
3946 mask [4] = 4 + ((imask >> 0) & 3);
3947 mask [5] = 4 + ((imask >> 2) & 3);
3948 mask [6] = 4 + ((imask >> 4) & 3);
3949 mask [7] = 4 + ((imask >> 6) & 3);
3950 v1 = values [ins->sreg1];
3951 v2 = LLVMGetUndef (LLVMTypeOf (v1));
3955 mask [0] = ((imask >> 0) & 3);
3956 mask [1] = ((imask >> 2) & 3);
3957 mask [2] = ((imask >> 4) & 3);
3958 mask [3] = ((imask >> 6) & 3);
3959 v1 = values [ins->sreg1];
3960 v2 = LLVMGetUndef (LLVMTypeOf (v1));
3963 g_assert_not_reached ();
3965 for (i = 0; i < mask_size; ++i)
3966 mask_values [i] = LLVMConstInt (LLVMInt32Type (), mask [i], FALSE);
3968 values [ins->dreg] =
3969 LLVMBuildShuffleVector (builder, v1, v2,
3970 LLVMConstVector (mask_values, mask_size), dname);
3974 case OP_UNPACK_LOWB:
3975 case OP_UNPACK_LOWW:
3976 case OP_UNPACK_LOWD:
3977 case OP_UNPACK_LOWQ:
3978 case OP_UNPACK_LOWPS:
3979 case OP_UNPACK_LOWPD:
3980 case OP_UNPACK_HIGHB:
3981 case OP_UNPACK_HIGHW:
3982 case OP_UNPACK_HIGHD:
3983 case OP_UNPACK_HIGHQ:
3984 case OP_UNPACK_HIGHPS:
3985 case OP_UNPACK_HIGHPD: {
3987 LLVMValueRef mask_values [16];
3988 int i, mask_size = 0;
3989 gboolean low = FALSE;
3991 switch (ins->opcode) {
3992 case OP_UNPACK_LOWB:
3996 case OP_UNPACK_LOWW:
4000 case OP_UNPACK_LOWD:
4001 case OP_UNPACK_LOWPS:
4005 case OP_UNPACK_LOWQ:
4006 case OP_UNPACK_LOWPD:
4010 case OP_UNPACK_HIGHB:
4013 case OP_UNPACK_HIGHW:
4016 case OP_UNPACK_HIGHD:
4017 case OP_UNPACK_HIGHPS:
4020 case OP_UNPACK_HIGHQ:
4021 case OP_UNPACK_HIGHPD:
4025 g_assert_not_reached ();
4029 for (i = 0; i < (mask_size / 2); ++i) {
4031 mask [(i * 2) + 1] = mask_size + i;
4034 for (i = 0; i < (mask_size / 2); ++i) {
4035 mask [(i * 2)] = (mask_size / 2) + i;
4036 mask [(i * 2) + 1] = mask_size + (mask_size / 2) + i;
4040 for (i = 0; i < mask_size; ++i)
4041 mask_values [i] = LLVMConstInt (LLVMInt32Type (), mask [i], FALSE);
4043 values [ins->dreg] =
4044 LLVMBuildShuffleVector (builder, values [ins->sreg1], values [ins->sreg2],
4045 LLVMConstVector (mask_values, mask_size), dname);
4050 LLVMTypeRef t = simd_op_to_llvm_type (ins->opcode);
4051 LLVMValueRef v, val;
4053 v = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
4054 val = LLVMConstNull (t);
4055 val = LLVMBuildInsertElement (builder, val, v, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
4056 val = LLVMBuildInsertElement (builder, val, v, LLVMConstInt (LLVMInt32Type (), 1, FALSE), dname);
4058 values [ins->dreg] = val;
4062 case OP_DUPPS_HIGH: {
4063 LLVMTypeRef t = simd_op_to_llvm_type (ins->opcode);
4064 LLVMValueRef v1, v2, val;
4067 if (ins->opcode == OP_DUPPS_LOW) {
4068 v1 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
4069 v2 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 2, FALSE), "");
4071 v1 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 1, FALSE), "");
4072 v2 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 3, FALSE), "");
4074 val = LLVMConstNull (t);
4075 val = LLVMBuildInsertElement (builder, val, v1, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
4076 val = LLVMBuildInsertElement (builder, val, v1, LLVMConstInt (LLVMInt32Type (), 1, FALSE), "");
4077 val = LLVMBuildInsertElement (builder, val, v2, LLVMConstInt (LLVMInt32Type (), 2, FALSE), "");
4078 val = LLVMBuildInsertElement (builder, val, v2, LLVMConstInt (LLVMInt32Type (), 3, FALSE), "");
4080 values [ins->dreg] = val;
4090 * EXCEPTION HANDLING
4092 case OP_IMPLICIT_EXCEPTION:
4093 /* This marks a place where an implicit exception can happen */
4094 if (bb->region != -1)
4095 LLVM_FAILURE (ctx, "implicit-exception");
4099 MonoMethodSignature *throw_sig;
4100 LLVMValueRef callee, arg;
4101 gboolean rethrow = (ins->opcode == OP_RETHROW);
4102 const char *icall_name;
4104 callee = rethrow ? ctx->lmodule->rethrow : ctx->lmodule->throw;
4105 icall_name = rethrow ? "mono_arch_rethrow_exception" : "mono_arch_throw_exception";
4108 throw_sig = mono_metadata_signature_alloc (mono_get_corlib (), 1);
4109 throw_sig->ret = &mono_get_void_class ()->byval_arg;
4110 throw_sig->params [0] = &mono_get_object_class ()->byval_arg;
4111 if (cfg->compile_aot) {
4112 callee = get_plt_entry (ctx, sig_to_llvm_sig (ctx, throw_sig), MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
4114 callee = LLVMAddFunction (module, icall_name, sig_to_llvm_sig (ctx, throw_sig));
4118 * LLVM doesn't push the exception argument, so we need a different
4121 LLVMAddGlobalMapping (ctx->lmodule->ee, callee, resolve_patch (cfg, MONO_PATCH_INFO_INTERNAL_METHOD, rethrow ? "llvm_rethrow_exception_trampoline" : "llvm_throw_exception_trampoline"));
4123 LLVMAddGlobalMapping (ctx->lmodule->ee, callee, resolve_patch (cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name));
4127 mono_memory_barrier ();
4129 ctx->lmodule->rethrow = callee;
4131 ctx->lmodule->throw = callee;
4133 arg = convert (ctx, lhs, type_to_llvm_type (ctx, &mono_get_object_class ()->byval_arg));
4134 emit_call (ctx, bb, &builder, callee, &arg, 1);
4137 case OP_CALL_HANDLER: {
4139 * We don't 'call' handlers, but instead simply branch to them.
4140 * The code generated by ENDFINALLY will branch back to us.
4142 LLVMBasicBlockRef noex_bb;
4144 BBInfo *info = &bblocks [ins->inst_target_bb->block_num];
4146 bb_list = info->call_handler_return_bbs;
4149 * Set the indicator variable for the finally clause.
4151 lhs = info->finally_ind;
4153 LLVMBuildStore (builder, LLVMConstInt (LLVMInt32Type (), g_slist_length (bb_list) + 1, FALSE), lhs);
4155 /* Branch to the finally clause */
4156 LLVMBuildBr (builder, info->call_handler_target_bb);
4158 noex_bb = gen_bb (ctx, "CALL_HANDLER_CONT_BB");
4159 info->call_handler_return_bbs = g_slist_append_mempool (cfg->mempool, info->call_handler_return_bbs, noex_bb);
4161 builder = ctx->builder = create_builder (ctx);
4162 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
4164 bblocks [bb->block_num].end_bblock = noex_bb;
4167 case OP_START_HANDLER: {
4170 case OP_ENDFINALLY: {
4171 LLVMBasicBlockRef resume_bb;
4172 MonoBasicBlock *handler_bb;
4173 LLVMValueRef val, switch_ins, callee;
4177 handler_bb = g_hash_table_lookup (ctx->region_to_handler, GUINT_TO_POINTER (mono_get_block_region_notry (cfg, bb->region)));
4178 g_assert (handler_bb);
4179 info = &bblocks [handler_bb->block_num];
4180 lhs = info->finally_ind;
4183 bb_list = info->call_handler_return_bbs;
4185 resume_bb = gen_bb (ctx, "ENDFINALLY_RESUME_BB");
4187 /* Load the finally variable */
4188 val = LLVMBuildLoad (builder, lhs, "");
4190 /* Reset the variable */
4191 LLVMBuildStore (builder, LLVMConstInt (LLVMInt32Type (), 0, FALSE), lhs);
4193 /* Branch to either resume_bb, or to the bblocks in bb_list */
4194 switch_ins = LLVMBuildSwitch (builder, val, resume_bb, g_slist_length (bb_list));
4196 * The other targets are added at the end to handle OP_CALL_HANDLER
4197 * opcodes processed later.
4199 info->endfinally_switch_ins_list = g_slist_append_mempool (cfg->mempool, info->endfinally_switch_ins_list, switch_ins);
4201 builder = ctx->builder = create_builder (ctx);
4202 LLVMPositionBuilderAtEnd (ctx->builder, resume_bb);
4204 if (ctx->cfg->compile_aot) {
4205 callee = get_plt_entry (ctx, LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE), MONO_PATCH_INFO_INTERNAL_METHOD, "llvm_resume_unwind_trampoline");
4207 callee = LLVMGetNamedFunction (module, "llvm_resume_unwind_trampoline");
4209 LLVMBuildCall (builder, callee, NULL, 0, "");
4211 LLVMBuildUnreachable (builder);
4212 has_terminator = TRUE;
4218 sprintf (reason, "opcode %s", mono_inst_name (ins->opcode));
4219 LLVM_FAILURE (ctx, reason);
4224 /* Convert the value to the type required by phi nodes */
4225 if (spec [MONO_INST_DEST] != ' ' && !MONO_IS_STORE_MEMBASE (ins) && ctx->vreg_types [ins->dreg]) {
4226 if (!values [ins->dreg])
4228 values [ins->dreg] = addresses [ins->dreg];
4230 values [ins->dreg] = convert (ctx, values [ins->dreg], ctx->vreg_types [ins->dreg]);
4233 /* Add stores for volatile variables */
4234 if (spec [MONO_INST_DEST] != ' ' && spec [MONO_INST_DEST] != 'v' && !MONO_IS_STORE_MEMBASE (ins))
4235 emit_volatile_store (ctx, ins->dreg);
4238 if (!has_terminator && bb->next_bb && (bb == cfg->bb_entry || bb->in_count > 0))
4239 LLVMBuildBr (builder, get_bb (ctx, bb->next_bb));
4241 if (bb == cfg->bb_exit && sig->ret->type == MONO_TYPE_VOID)
4242 LLVMBuildRetVoid (builder);
4244 if (bb == cfg->bb_entry)
4245 ctx->last_alloca = LLVMGetLastInstruction (get_bb (ctx, cfg->bb_entry));
4254 * mono_llvm_check_method_supported:
4256 * Do some quick checks to decide whenever cfg->method can be compiled by LLVM, to avoid
4257 * compiling a method twice.
4260 mono_llvm_check_method_supported (MonoCompile *cfg)
4262 MonoMethodHeader *header = cfg->header;
4263 MonoExceptionClause *clause;
4266 if (cfg->method->save_lmf) {
4267 cfg->exception_message = g_strdup ("lmf");
4268 cfg->disable_llvm = TRUE;
4270 if (cfg->disable_llvm)
4274 for (i = 0; i < header->num_clauses; ++i) {
4275 clause = &header->clauses [i];
4277 if (i > 0 && clause->try_offset <= header->clauses [i - 1].handler_offset + header->clauses [i - 1].handler_len) {
4279 * FIXME: Some tests still fail with nested clauses.
4281 cfg->exception_message = g_strdup ("nested clauses");
4282 cfg->disable_llvm = TRUE;
4286 if (cfg->disable_llvm)
4291 if (cfg->method->dynamic) {
4292 cfg->exception_message = g_strdup ("dynamic.");
4293 cfg->disable_llvm = TRUE;
4295 if (cfg->disable_llvm)
4300 * mono_llvm_emit_method:
4302 * Emit LLVM IL from the mono IL, and compile it to native code using LLVM.
4305 mono_llvm_emit_method (MonoCompile *cfg)
4308 MonoMethodSignature *sig;
4310 LLVMTypeRef method_type;
4311 LLVMValueRef method = NULL;
4313 LLVMValueRef *values;
4314 int i, max_block_num, bb_index;
4315 gboolean last = FALSE;
4316 GPtrArray *phi_values;
4317 LLVMCallInfo *linfo;
4319 LLVMModuleRef module;
4321 GPtrArray *bblock_list;
4322 MonoMethodHeader *header;
4323 MonoExceptionClause *clause;
4327 /* The code below might acquire the loader lock, so use it for global locking */
4328 mono_loader_lock ();
4330 /* Used to communicate with the callbacks */
4331 mono_native_tls_set_value (current_cfg_tls_id, cfg);
4333 ctx = g_new0 (EmitContext, 1);
4335 ctx->mempool = cfg->mempool;
4338 * This maps vregs to the LLVM instruction defining them
4340 values = g_new0 (LLVMValueRef, cfg->next_vreg);
4342 * This maps vregs for volatile variables to the LLVM instruction defining their
4345 ctx->addresses = g_new0 (LLVMValueRef, cfg->next_vreg);
4346 ctx->vreg_types = g_new0 (LLVMTypeRef, cfg->next_vreg);
4347 ctx->vreg_cli_types = g_new0 (MonoType*, cfg->next_vreg);
4348 phi_values = g_ptr_array_sized_new (256);
4350 * This signals whenever the vreg was defined by a phi node with no input vars
4351 * (i.e. all its input bblocks end with NOT_REACHABLE).
4353 ctx->is_dead = g_new0 (gboolean, cfg->next_vreg);
4354 /* Whenever the bblock is unreachable */
4355 ctx->unreachable = g_new0 (gboolean, cfg->max_block_num);
4357 bblock_list = g_ptr_array_sized_new (256);
4359 ctx->values = values;
4360 ctx->region_to_handler = g_hash_table_new (NULL, NULL);
4362 if (cfg->compile_aot) {
4363 ctx->lmodule = &aot_module;
4364 method_name = mono_aot_get_method_name (cfg);
4365 cfg->llvm_method_name = g_strdup (method_name);
4367 init_jit_module (cfg->domain);
4368 ctx->lmodule = domain_jit_info (cfg->domain)->llvm_module;
4369 method_name = mono_method_full_name (cfg->method, TRUE);
4372 module = ctx->module = ctx->lmodule->module;
4375 LLVM_FAILURE (ctx, "gsharedvt");
4379 static int count = 0;
4382 if (g_getenv ("LLVM_COUNT")) {
4383 if (count == atoi (g_getenv ("LLVM_COUNT"))) {
4384 printf ("LAST: %s\n", mono_method_full_name (cfg->method, TRUE));
4388 if (count > atoi (g_getenv ("LLVM_COUNT")))
4389 LLVM_FAILURE (ctx, "");
4394 sig = mono_method_signature (cfg->method);
4397 linfo = mono_arch_get_llvm_call_info (cfg, sig);
4399 CHECK_FAILURE (ctx);
4402 linfo->rgctx_arg = TRUE;
4403 method_type = sig_to_llvm_sig_full (ctx, sig, linfo, &sinfo);
4404 CHECK_FAILURE (ctx);
4407 * This maps parameter indexes in the original signature to the indexes in
4408 * the LLVM signature.
4410 ctx->pindexes = sinfo.pindexes;
4412 method = LLVMAddFunction (module, method_name, method_type);
4413 ctx->lmethod = method;
4415 LLVMSetFunctionCallConv (method, LLVMMono1CallConv);
4416 LLVMSetLinkage (method, LLVMPrivateLinkage);
4418 LLVMAddFunctionAttr (method, LLVMUWTable);
4420 if (cfg->compile_aot) {
4421 LLVMSetLinkage (method, LLVMInternalLinkage);
4422 #if LLVM_API_VERSION == 0
4423 /* This causes an assertion in later LLVM versions */
4424 LLVMSetVisibility (method, LLVMHiddenVisibility);
4427 LLVMSetLinkage (method, LLVMPrivateLinkage);
4430 if (cfg->method->save_lmf)
4431 LLVM_FAILURE (ctx, "lmf");
4433 if (sig->pinvoke && cfg->method->wrapper_type != MONO_WRAPPER_RUNTIME_INVOKE)
4434 LLVM_FAILURE (ctx, "pinvoke signature");
4436 header = cfg->header;
4437 for (i = 0; i < header->num_clauses; ++i) {
4438 clause = &header->clauses [i];
4439 if (clause->flags != MONO_EXCEPTION_CLAUSE_FINALLY && clause->flags != MONO_EXCEPTION_CLAUSE_NONE)
4440 LLVM_FAILURE (ctx, "non-finally/catch clause.");
4443 if (linfo->rgctx_arg) {
4444 ctx->rgctx_arg = LLVMGetParam (method, sinfo.rgctx_arg_pindex);
4446 * We mark the rgctx parameter with the inreg attribute, which is mapped to
4447 * MONO_ARCH_RGCTX_REG in the Mono calling convention in llvm, i.e.
4448 * CC_X86_64_Mono in X86CallingConv.td.
4450 LLVMAddAttribute (ctx->rgctx_arg, LLVMInRegAttribute);
4451 LLVMSetValueName (ctx->rgctx_arg, "rgctx");
4453 if (cfg->vret_addr) {
4454 values [cfg->vret_addr->dreg] = LLVMGetParam (method, sinfo.vret_arg_pindex);
4455 LLVMSetValueName (values [cfg->vret_addr->dreg], "vret");
4458 values [cfg->args [0]->dreg] = LLVMGetParam (method, sinfo.this_arg_pindex);
4459 LLVMSetValueName (values [cfg->args [0]->dreg], "this");
4462 names = g_new (char *, sig->param_count);
4463 mono_method_get_param_names (cfg->method, (const char **) names);
4465 for (i = 0; i < sig->param_count; ++i) {
4468 values [cfg->args [i + sig->hasthis]->dreg] = LLVMGetParam (method, sinfo.pindexes [i]);
4469 if (names [i] && names [i][0] != '\0')
4470 name = g_strdup_printf ("arg_%s", names [i]);
4472 name = g_strdup_printf ("arg_%d", i);
4473 LLVMSetValueName (values [cfg->args [i + sig->hasthis]->dreg], name);
4475 if (linfo->args [i + sig->hasthis].storage == LLVMArgVtypeByVal)
4476 LLVMAddAttribute (LLVMGetParam (method, sinfo.pindexes [i]), LLVMByValAttribute);
4481 for (bb = cfg->bb_entry; bb; bb = bb->next_bb)
4482 max_block_num = MAX (max_block_num, bb->block_num);
4483 ctx->bblocks = bblocks = g_new0 (BBInfo, max_block_num + 1);
4485 /* Add branches between non-consecutive bblocks */
4486 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
4487 if (bb->last_ins && MONO_IS_COND_BRANCH_OP (bb->last_ins) &&
4488 bb->next_bb != bb->last_ins->inst_false_bb) {
4490 MonoInst *inst = mono_mempool_alloc0 (cfg->mempool, sizeof (MonoInst));
4491 inst->opcode = OP_BR;
4492 inst->inst_target_bb = bb->last_ins->inst_false_bb;
4493 mono_bblock_add_inst (bb, inst);
4498 * The INDIRECT flag added by OP_LDADDR inhibits optimizations, even if the LDADDR
4499 * was later optimized away, so clear these flags, and add them back for the still
4500 * present OP_LDADDR instructions.
4502 for (i = 0; i < cfg->next_vreg; ++i) {
4505 ins = get_vreg_to_inst (cfg, i);
4506 if (ins && ins != cfg->rgctx_var)
4507 ins->flags &= ~MONO_INST_INDIRECT;
4511 * Make a first pass over the code to precreate PHI nodes/set INDIRECT flags.
4513 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
4515 LLVMBuilderRef builder;
4517 char dname_buf[128];
4519 builder = create_builder (ctx);
4521 for (ins = bb->code; ins; ins = ins->next) {
4522 switch (ins->opcode) {
4527 LLVMTypeRef phi_type = llvm_type_to_stack_type (type_to_llvm_type (ctx, &ins->klass->byval_arg));
4529 CHECK_FAILURE (ctx);
4531 if (ins->opcode == OP_VPHI) {
4532 /* Treat valuetype PHI nodes as operating on the address itself */
4533 g_assert (ins->klass);
4534 phi_type = LLVMPointerType (type_to_llvm_type (ctx, &ins->klass->byval_arg), 0);
4538 * Have to precreate these, as they can be referenced by
4539 * earlier instructions.
4541 sprintf (dname_buf, "t%d", ins->dreg);
4543 values [ins->dreg] = LLVMBuildPhi (builder, phi_type, dname);
4545 if (ins->opcode == OP_VPHI)
4546 ctx->addresses [ins->dreg] = values [ins->dreg];
4548 g_ptr_array_add (phi_values, values [ins->dreg]);
4551 * Set the expected type of the incoming arguments since these have
4552 * to have the same type.
4554 for (i = 0; i < ins->inst_phi_args [0]; i++) {
4555 int sreg1 = ins->inst_phi_args [i + 1];
4558 ctx->vreg_types [sreg1] = phi_type;
4563 ((MonoInst*)ins->inst_p0)->flags |= MONO_INST_INDIRECT;
4572 * Create an ordering for bblocks, use the depth first order first, then
4573 * put the exception handling bblocks last.
4575 for (bb_index = 0; bb_index < cfg->num_bblocks; ++bb_index) {
4576 bb = cfg->bblocks [bb_index];
4577 if (!(bb->region != -1 && !MONO_BBLOCK_IS_IN_REGION (bb, MONO_REGION_TRY))) {
4578 g_ptr_array_add (bblock_list, bb);
4579 bblocks [bb->block_num].added = TRUE;
4583 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
4584 if (!bblocks [bb->block_num].added)
4585 g_ptr_array_add (bblock_list, bb);
4589 * Second pass: generate code.
4591 for (bb_index = 0; bb_index < bblock_list->len; ++bb_index) {
4592 bb = g_ptr_array_index (bblock_list, bb_index);
4594 if (!(bb == cfg->bb_entry || bb->in_count > 0))
4597 process_bb (ctx, bb);
4598 CHECK_FAILURE (ctx);
4601 /* Add incoming phi values */
4602 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
4603 GSList *l, *ins_list;
4605 ins_list = bblocks [bb->block_num].phi_nodes;
4607 for (l = ins_list; l; l = l->next) {
4608 PhiNode *node = l->data;
4609 MonoInst *phi = node->phi;
4610 int sreg1 = node->sreg;
4611 LLVMBasicBlockRef in_bb;
4616 in_bb = get_end_bb (ctx, node->in_bb);
4618 if (ctx->unreachable [node->in_bb->block_num])
4621 if (!values [sreg1])
4622 /* Can happen with values in EH clauses */
4623 LLVM_FAILURE (ctx, "incoming phi sreg1");
4625 if (phi->opcode == OP_VPHI) {
4626 g_assert (LLVMTypeOf (ctx->addresses [sreg1]) == LLVMTypeOf (values [phi->dreg]));
4627 LLVMAddIncoming (values [phi->dreg], &ctx->addresses [sreg1], &in_bb, 1);
4629 if (LLVMTypeOf (values [sreg1]) != LLVMTypeOf (values [phi->dreg]))
4631 LLVM_FAILURE (ctx, "incoming phi arg type mismatch");
4632 g_assert (LLVMTypeOf (values [sreg1]) == LLVMTypeOf (values [phi->dreg]));
4633 LLVMAddIncoming (values [phi->dreg], &values [sreg1], &in_bb, 1);
4638 /* Create the SWITCH statements for ENDFINALLY instructions */
4639 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
4640 BBInfo *info = &bblocks [bb->block_num];
4642 for (l = info->endfinally_switch_ins_list; l; l = l->next) {
4643 LLVMValueRef switch_ins = l->data;
4644 GSList *bb_list = info->call_handler_return_bbs;
4646 for (i = 0; i < g_slist_length (bb_list); ++i)
4647 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), i + 1, FALSE), g_slist_nth (bb_list, i)->data);
4651 if (cfg->verbose_level > 1)
4652 mono_llvm_dump_value (method);
4654 if (cfg->compile_aot)
4655 mark_as_used (ctx->lmodule, method);
4657 if (cfg->compile_aot) {
4658 LLVMValueRef md_args [16];
4659 LLVMValueRef md_node;
4662 method_index = mono_aot_get_method_index (cfg->orig_method);
4663 md_args [0] = LLVMMDString (method_name, strlen (method_name));
4664 md_args [1] = LLVMConstInt (LLVMInt32Type (), method_index, FALSE);
4665 md_node = LLVMMDNode (md_args, 2);
4666 LLVMAddNamedMetadataOperand (module, "mono.function_indexes", md_node);
4667 //LLVMSetMetadata (method, md_kind, LLVMMDNode (&md_arg, 1));
4670 if (cfg->compile_aot) {
4671 /* Don't generate native code, keep the LLVM IR */
4672 if (cfg->compile_aot && cfg->verbose_level)
4673 printf ("%s emitted as %s\n", mono_method_full_name (cfg->method, TRUE), method_name);
4675 //LLVMVerifyFunction(method, 0);
4677 mono_llvm_optimize_method (ctx->lmodule->mono_ee, method);
4679 if (cfg->verbose_level > 1)
4680 mono_llvm_dump_value (method);
4682 cfg->native_code = LLVMGetPointerToGlobal (ctx->lmodule->ee, method);
4684 /* Set by emit_cb */
4685 g_assert (cfg->code_len);
4687 /* FIXME: Free the LLVM IL for the function */
4690 if (ctx->lmodule->method_to_lmethod)
4691 g_hash_table_insert (ctx->lmodule->method_to_lmethod, cfg->method, method);
4698 /* Need to add unused phi nodes as they can be referenced by other values */
4699 LLVMBasicBlockRef phi_bb = LLVMAppendBasicBlock (method, "PHI_BB");
4700 LLVMBuilderRef builder;
4702 builder = create_builder (ctx);
4703 LLVMPositionBuilderAtEnd (builder, phi_bb);
4705 for (i = 0; i < phi_values->len; ++i) {
4706 LLVMValueRef v = g_ptr_array_index (phi_values, i);
4707 if (LLVMGetInstructionParent (v) == NULL)
4708 LLVMInsertIntoBuilder (builder, v);
4711 LLVMDeleteFunction (method);
4716 g_free (ctx->addresses);
4717 g_free (ctx->vreg_types);
4718 g_free (ctx->vreg_cli_types);
4719 g_free (ctx->pindexes);
4720 g_free (ctx->is_dead);
4721 g_free (ctx->unreachable);
4722 g_ptr_array_free (phi_values, TRUE);
4723 g_free (ctx->bblocks);
4724 g_hash_table_destroy (ctx->region_to_handler);
4725 g_free (method_name);
4726 g_ptr_array_free (bblock_list, TRUE);
4728 for (l = ctx->builders; l; l = l->next) {
4729 LLVMBuilderRef builder = l->data;
4730 LLVMDisposeBuilder (builder);
4735 mono_native_tls_set_value (current_cfg_tls_id, NULL);
4737 mono_loader_unlock ();
4741 * mono_llvm_emit_call:
4743 * Same as mono_arch_emit_call () for LLVM.
4746 mono_llvm_emit_call (MonoCompile *cfg, MonoCallInst *call)
4749 MonoMethodSignature *sig;
4750 int i, n, stack_size;
4755 sig = call->signature;
4756 n = sig->param_count + sig->hasthis;
4758 call->cinfo = mono_arch_get_llvm_call_info (cfg, sig);
4760 if (cfg->disable_llvm)
4763 if (sig->call_convention == MONO_CALL_VARARG) {
4764 cfg->exception_message = g_strdup ("varargs");
4765 cfg->disable_llvm = TRUE;
4768 for (i = 0; i < n; ++i) {
4771 ainfo = call->cinfo->args + i;
4773 in = call->args [i];
4775 /* Simply remember the arguments */
4776 switch (ainfo->storage) {
4778 case LLVMArgInFPReg: {
4779 MonoType *t = (sig->hasthis && i == 0) ? &mono_get_intptr_class ()->byval_arg : sig->params [i - sig->hasthis];
4782 opcode = mono_type_to_regmove (cfg, t);
4783 if (opcode == OP_FMOVE) {
4784 MONO_INST_NEW (cfg, ins, OP_FMOVE);
4785 ins->dreg = mono_alloc_freg (cfg);
4786 } else if (opcode == OP_LMOVE) {
4787 MONO_INST_NEW (cfg, ins, OP_LMOVE);
4788 ins->dreg = mono_alloc_lreg (cfg);
4790 MONO_INST_NEW (cfg, ins, OP_MOVE);
4791 ins->dreg = mono_alloc_ireg (cfg);
4793 ins->sreg1 = in->dreg;
4796 case LLVMArgVtypeByVal:
4797 case LLVMArgVtypeInReg:
4798 MONO_INST_NEW (cfg, ins, OP_LLVM_OUTARG_VT);
4799 ins->dreg = mono_alloc_ireg (cfg);
4800 ins->sreg1 = in->dreg;
4801 ins->klass = mono_class_from_mono_type (sig->params [i - sig->hasthis]);
4804 call->cinfo = mono_arch_get_llvm_call_info (cfg, sig);
4805 cfg->exception_message = g_strdup ("ainfo->storage");
4806 cfg->disable_llvm = TRUE;
4810 if (!cfg->disable_llvm) {
4811 MONO_ADD_INS (cfg->cbb, ins);
4812 mono_call_inst_add_outarg_reg (cfg, call, ins->dreg, 0, FALSE);
4817 static unsigned char*
4818 alloc_cb (LLVMValueRef function, int size)
4822 cfg = mono_native_tls_get_value (current_cfg_tls_id);
4826 return mono_domain_code_reserve (cfg->domain, size);
4828 return mono_domain_code_reserve (mono_domain_get (), size);
4833 emitted_cb (LLVMValueRef function, void *start, void *end)
4837 cfg = mono_native_tls_get_value (current_cfg_tls_id);
4839 cfg->code_len = (guint8*)end - (guint8*)start;
4843 exception_cb (void *data)
4846 MonoJitExceptionInfo *ei;
4847 guint32 ei_len, i, j, nested_len, nindex;
4848 gpointer *type_info;
4849 int this_reg, this_offset;
4851 cfg = mono_native_tls_get_value (current_cfg_tls_id);
4855 * data points to a DWARF FDE structure, convert it to our unwind format and
4857 * An alternative would be to save it directly, and modify our unwinder to work
4860 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);
4861 if (cfg->verbose_level > 1)
4862 mono_print_unwind_info (cfg->encoded_unwind_ops, cfg->encoded_unwind_ops_len);
4864 /* Count nested clauses */
4866 for (i = 0; i < ei_len; ++i) {
4867 for (j = 0; j < ei_len; ++j) {
4868 gint32 cindex1 = *(gint32*)type_info [i];
4869 MonoExceptionClause *clause1 = &cfg->header->clauses [cindex1];
4870 gint32 cindex2 = *(gint32*)type_info [j];
4871 MonoExceptionClause *clause2 = &cfg->header->clauses [cindex2];
4873 if (cindex1 != cindex2 && clause1->try_offset >= clause2->try_offset && clause1->handler_offset <= clause2->handler_offset) {
4879 cfg->llvm_ex_info = mono_mempool_alloc0 (cfg->mempool, (ei_len + nested_len) * sizeof (MonoJitExceptionInfo));
4880 cfg->llvm_ex_info_len = ei_len + nested_len;
4881 memcpy (cfg->llvm_ex_info, ei, ei_len * sizeof (MonoJitExceptionInfo));
4882 /* Fill the rest of the information from the type info */
4883 for (i = 0; i < ei_len; ++i) {
4884 gint32 clause_index = *(gint32*)type_info [i];
4885 MonoExceptionClause *clause = &cfg->header->clauses [clause_index];
4887 cfg->llvm_ex_info [i].flags = clause->flags;
4888 cfg->llvm_ex_info [i].data.catch_class = clause->data.catch_class;
4892 * For nested clauses, the LLVM produced exception info associates the try interval with
4893 * the innermost handler, while mono expects it to be associated with all nesting clauses.
4895 /* FIXME: These should be order with the normal clauses */
4897 for (i = 0; i < ei_len; ++i) {
4898 for (j = 0; j < ei_len; ++j) {
4899 gint32 cindex1 = *(gint32*)type_info [i];
4900 MonoExceptionClause *clause1 = &cfg->header->clauses [cindex1];
4901 gint32 cindex2 = *(gint32*)type_info [j];
4902 MonoExceptionClause *clause2 = &cfg->header->clauses [cindex2];
4904 if (cindex1 != cindex2 && clause1->try_offset >= clause2->try_offset && clause1->handler_offset <= clause2->handler_offset) {
4906 * The try interval comes from the nested clause, everything else from the
4909 memcpy (&cfg->llvm_ex_info [nindex], &cfg->llvm_ex_info [j], sizeof (MonoJitExceptionInfo));
4910 cfg->llvm_ex_info [nindex].try_start = cfg->llvm_ex_info [i].try_start;
4911 cfg->llvm_ex_info [nindex].try_end = cfg->llvm_ex_info [i].try_end;
4916 g_assert (nindex == ei_len + nested_len);
4917 cfg->llvm_this_reg = this_reg;
4918 cfg->llvm_this_offset = this_offset;
4920 /* type_info [i] is cfg mempool allocated, no need to free it */
4927 dlsym_cb (const char *name, void **symbol)
4933 if (!strcmp (name, "__bzero")) {
4934 *symbol = (void*)bzero;
4936 current = mono_dl_open (NULL, 0, NULL);
4939 err = mono_dl_symbol (current, name, symbol);
4941 mono_dl_close (current);
4943 #ifdef MONO_ARCH_HAVE_CREATE_LLVM_NATIVE_THUNK
4944 *symbol = (char*)mono_arch_create_llvm_native_thunk (mono_domain_get (), (guint8*)(*symbol));
4950 AddFunc (LLVMModuleRef module, const char *name, LLVMTypeRef ret_type, LLVMTypeRef *param_types, int nparams)
4952 LLVMAddFunction (module, name, LLVMFunctionType (ret_type, param_types, nparams, FALSE));
4956 AddFunc2 (LLVMModuleRef module, const char *name, LLVMTypeRef ret_type, LLVMTypeRef param_type1, LLVMTypeRef param_type2)
4958 LLVMTypeRef param_types [4];
4960 param_types [0] = param_type1;
4961 param_types [1] = param_type2;
4963 AddFunc (module, name, ret_type, param_types, 2);
4967 add_intrinsics (LLVMModuleRef module)
4969 /* Emit declarations of instrinsics */
4971 * It would be nicer to emit only the intrinsics actually used, but LLVM's Module
4972 * type doesn't seem to do any locking.
4975 LLVMTypeRef memset_params [] = { LLVMPointerType (LLVMInt8Type (), 0), LLVMInt8Type (), LLVMInt32Type (), LLVMInt32Type (), LLVMInt1Type () };
4977 memset_param_count = 5;
4978 memset_func_name = "llvm.memset.p0i8.i32";
4980 LLVMAddFunction (module, memset_func_name, LLVMFunctionType (LLVMVoidType (), memset_params, memset_param_count, FALSE));
4984 LLVMTypeRef memcpy_params [] = { LLVMPointerType (LLVMInt8Type (), 0), LLVMPointerType (LLVMInt8Type (), 0), LLVMInt32Type (), LLVMInt32Type (), LLVMInt1Type () };
4986 memcpy_param_count = 5;
4987 memcpy_func_name = "llvm.memcpy.p0i8.p0i8.i32";
4989 LLVMAddFunction (module, memcpy_func_name, LLVMFunctionType (LLVMVoidType (), memcpy_params, memcpy_param_count, FALSE));
4993 LLVMTypeRef params [] = { LLVMDoubleType () };
4995 LLVMAddFunction (module, "llvm.sin.f64", LLVMFunctionType (LLVMDoubleType (), params, 1, FALSE));
4996 LLVMAddFunction (module, "llvm.cos.f64", LLVMFunctionType (LLVMDoubleType (), params, 1, FALSE));
4997 LLVMAddFunction (module, "llvm.sqrt.f64", LLVMFunctionType (LLVMDoubleType (), params, 1, FALSE));
4999 /* This isn't an intrinsic, instead llvm seems to special case it by name */
5000 LLVMAddFunction (module, "fabs", LLVMFunctionType (LLVMDoubleType (), params, 1, FALSE));
5004 LLVMTypeRef ovf_res_i32 [] = { LLVMInt32Type (), LLVMInt1Type () };
5005 LLVMTypeRef ovf_params_i32 [] = { LLVMInt32Type (), LLVMInt32Type () };
5007 LLVMAddFunction (module, "llvm.sadd.with.overflow.i32", LLVMFunctionType (LLVMStructType (ovf_res_i32, 2, FALSE), ovf_params_i32, 2, FALSE));
5008 LLVMAddFunction (module, "llvm.uadd.with.overflow.i32", LLVMFunctionType (LLVMStructType (ovf_res_i32, 2, FALSE), ovf_params_i32, 2, FALSE));
5009 LLVMAddFunction (module, "llvm.ssub.with.overflow.i32", LLVMFunctionType (LLVMStructType (ovf_res_i32, 2, FALSE), ovf_params_i32, 2, FALSE));
5010 LLVMAddFunction (module, "llvm.usub.with.overflow.i32", LLVMFunctionType (LLVMStructType (ovf_res_i32, 2, FALSE), ovf_params_i32, 2, FALSE));
5011 LLVMAddFunction (module, "llvm.smul.with.overflow.i32", LLVMFunctionType (LLVMStructType (ovf_res_i32, 2, FALSE), ovf_params_i32, 2, FALSE));
5012 LLVMAddFunction (module, "llvm.umul.with.overflow.i32", LLVMFunctionType (LLVMStructType (ovf_res_i32, 2, FALSE), ovf_params_i32, 2, FALSE));
5016 LLVMTypeRef ovf_res_i64 [] = { LLVMInt64Type (), LLVMInt1Type () };
5017 LLVMTypeRef ovf_params_i64 [] = { LLVMInt64Type (), LLVMInt64Type () };
5019 LLVMAddFunction (module, "llvm.sadd.with.overflow.i64", LLVMFunctionType (LLVMStructType (ovf_res_i64, 2, FALSE), ovf_params_i64, 2, FALSE));
5020 LLVMAddFunction (module, "llvm.uadd.with.overflow.i64", LLVMFunctionType (LLVMStructType (ovf_res_i64, 2, FALSE), ovf_params_i64, 2, FALSE));
5021 LLVMAddFunction (module, "llvm.ssub.with.overflow.i64", LLVMFunctionType (LLVMStructType (ovf_res_i64, 2, FALSE), ovf_params_i64, 2, FALSE));
5022 LLVMAddFunction (module, "llvm.usub.with.overflow.i64", LLVMFunctionType (LLVMStructType (ovf_res_i64, 2, FALSE), ovf_params_i64, 2, FALSE));
5023 LLVMAddFunction (module, "llvm.smul.with.overflow.i64", LLVMFunctionType (LLVMStructType (ovf_res_i64, 2, FALSE), ovf_params_i64, 2, FALSE));
5024 LLVMAddFunction (module, "llvm.umul.with.overflow.i64", LLVMFunctionType (LLVMStructType (ovf_res_i64, 2, FALSE), ovf_params_i64, 2, FALSE));
5029 LLVMTypeRef arg_types [2];
5030 LLVMTypeRef ret_type;
5032 arg_types [0] = LLVMPointerType (LLVMInt8Type (), 0);
5033 arg_types [1] = LLVMPointerType (LLVMInt8Type (), 0);
5034 ret_type = LLVMInt32Type ();
5036 LLVMAddFunction (module, "mono_personality", LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE));
5038 LLVMAddFunction (module, "llvm_resume_unwind_trampoline", LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE));
5041 /* SSE intrinsics */
5042 #if defined(TARGET_X86) || defined(TARGET_AMD64)
5044 LLVMTypeRef ret_type, arg_types [16];
5047 ret_type = type_to_simd_type (MONO_TYPE_I4);
5048 arg_types [0] = ret_type;
5049 arg_types [1] = ret_type;
5050 AddFunc (module, "llvm.x86.sse41.pminud", ret_type, arg_types, 2);
5051 AddFunc (module, "llvm.x86.sse41.pmaxud", ret_type, arg_types, 2);
5053 ret_type = type_to_simd_type (MONO_TYPE_I2);
5054 arg_types [0] = ret_type;
5055 arg_types [1] = ret_type;
5056 AddFunc (module, "llvm.x86.sse41.pminuw", ret_type, arg_types, 2);
5057 AddFunc (module, "llvm.x86.sse2.pmins.w", ret_type, arg_types, 2);
5058 AddFunc (module, "llvm.x86.sse41.pmaxuw", ret_type, arg_types, 2);
5059 AddFunc (module, "llvm.x86.sse2.padds.w", ret_type, arg_types, 2);
5060 AddFunc (module, "llvm.x86.sse2.psubs.w", ret_type, arg_types, 2);
5061 AddFunc (module, "llvm.x86.sse2.paddus.w", ret_type, arg_types, 2);
5062 AddFunc (module, "llvm.x86.sse2.psubus.w", ret_type, arg_types, 2);
5063 AddFunc (module, "llvm.x86.sse2.pavg.w", ret_type, arg_types, 2);
5064 AddFunc (module, "llvm.x86.sse2.pmulh.w", ret_type, arg_types, 2);
5065 AddFunc (module, "llvm.x86.sse2.pmulhu.w", ret_type, arg_types, 2);
5067 ret_type = type_to_simd_type (MONO_TYPE_I1);
5068 arg_types [0] = ret_type;
5069 arg_types [1] = ret_type;
5070 AddFunc (module, "llvm.x86.sse2.pminu.b", ret_type, arg_types, 2);
5071 AddFunc (module, "llvm.x86.sse2.pmaxu.b", ret_type, arg_types, 2);
5072 AddFunc (module, "llvm.x86.sse2.padds.b", ret_type, arg_types, 2);
5073 AddFunc (module, "llvm.x86.sse2.psubs.b", ret_type, arg_types, 2);
5074 AddFunc (module, "llvm.x86.sse2.paddus.b", ret_type, arg_types, 2);
5075 AddFunc (module, "llvm.x86.sse2.psubus.b", ret_type, arg_types, 2);
5076 AddFunc (module, "llvm.x86.sse2.pavg.b", ret_type, arg_types, 2);
5078 ret_type = type_to_simd_type (MONO_TYPE_R8);
5079 arg_types [0] = ret_type;
5080 arg_types [1] = ret_type;
5081 AddFunc (module, "llvm.x86.sse2.min.pd", ret_type, arg_types, 2);
5082 AddFunc (module, "llvm.x86.sse2.max.pd", ret_type, arg_types, 2);
5083 AddFunc (module, "llvm.x86.sse3.hadd.pd", ret_type, arg_types, 2);
5084 AddFunc (module, "llvm.x86.sse3.hsub.pd", ret_type, arg_types, 2);
5085 AddFunc (module, "llvm.x86.sse3.addsub.pd", ret_type, arg_types, 2);
5087 ret_type = type_to_simd_type (MONO_TYPE_R4);
5088 arg_types [0] = ret_type;
5089 arg_types [1] = ret_type;
5090 AddFunc (module, "llvm.x86.sse.min.ps", ret_type, arg_types, 2);
5091 AddFunc (module, "llvm.x86.sse.max.ps", ret_type, arg_types, 2);
5092 AddFunc (module, "llvm.x86.sse3.hadd.ps", ret_type, arg_types, 2);
5093 AddFunc (module, "llvm.x86.sse3.hsub.ps", ret_type, arg_types, 2);
5094 AddFunc (module, "llvm.x86.sse3.addsub.ps", ret_type, arg_types, 2);
5097 ret_type = type_to_simd_type (MONO_TYPE_I1);
5098 arg_types [0] = type_to_simd_type (MONO_TYPE_I2);
5099 arg_types [1] = type_to_simd_type (MONO_TYPE_I2);
5100 AddFunc (module, "llvm.x86.sse2.packsswb.128", ret_type, arg_types, 2);
5101 AddFunc (module, "llvm.x86.sse2.packuswb.128", ret_type, arg_types, 2);
5102 ret_type = type_to_simd_type (MONO_TYPE_I2);
5103 arg_types [0] = type_to_simd_type (MONO_TYPE_I4);
5104 arg_types [1] = type_to_simd_type (MONO_TYPE_I4);
5105 AddFunc (module, "llvm.x86.sse2.packssdw.128", ret_type, arg_types, 2);
5106 AddFunc (module, "llvm.x86.sse41.packusdw", ret_type, arg_types, 2);
5109 ret_type = type_to_simd_type (MONO_TYPE_R8);
5110 arg_types [0] = ret_type;
5111 arg_types [1] = ret_type;
5112 arg_types [2] = LLVMInt8Type ();
5113 AddFunc (module, "llvm.x86.sse2.cmp.pd", ret_type, arg_types, 3);
5114 ret_type = type_to_simd_type (MONO_TYPE_R4);
5115 arg_types [0] = ret_type;
5116 arg_types [1] = ret_type;
5117 arg_types [2] = LLVMInt8Type ();
5118 AddFunc (module, "llvm.x86.sse.cmp.ps", ret_type, arg_types, 3);
5120 /* Conversion ops */
5121 ret_type = type_to_simd_type (MONO_TYPE_R8);
5122 arg_types [0] = type_to_simd_type (MONO_TYPE_I4);
5123 AddFunc (module, "llvm.x86.sse2.cvtdq2pd", ret_type, arg_types, 1);
5124 ret_type = type_to_simd_type (MONO_TYPE_R4);
5125 arg_types [0] = type_to_simd_type (MONO_TYPE_I4);
5126 AddFunc (module, "llvm.x86.sse2.cvtdq2ps", ret_type, arg_types, 1);
5127 ret_type = type_to_simd_type (MONO_TYPE_I4);
5128 arg_types [0] = type_to_simd_type (MONO_TYPE_R8);
5129 AddFunc (module, "llvm.x86.sse2.cvtpd2dq", ret_type, arg_types, 1);
5130 ret_type = type_to_simd_type (MONO_TYPE_I4);
5131 arg_types [0] = type_to_simd_type (MONO_TYPE_R4);
5132 AddFunc (module, "llvm.x86.sse2.cvtps2dq", ret_type, arg_types, 1);
5133 ret_type = type_to_simd_type (MONO_TYPE_R4);
5134 arg_types [0] = type_to_simd_type (MONO_TYPE_R8);
5135 AddFunc (module, "llvm.x86.sse2.cvtpd2ps", ret_type, arg_types, 1);
5136 ret_type = type_to_simd_type (MONO_TYPE_R8);
5137 arg_types [0] = type_to_simd_type (MONO_TYPE_R4);
5138 AddFunc (module, "llvm.x86.sse2.cvtps2pd", ret_type, arg_types, 1);
5140 ret_type = type_to_simd_type (MONO_TYPE_I4);
5141 arg_types [0] = type_to_simd_type (MONO_TYPE_R8);
5142 AddFunc (module, "llvm.x86.sse2.cvttpd2dq", ret_type, arg_types, 1);
5143 ret_type = type_to_simd_type (MONO_TYPE_I4);
5144 arg_types [0] = type_to_simd_type (MONO_TYPE_R4);
5145 AddFunc (module, "llvm.x86.sse2.cvttps2dq", ret_type, arg_types, 1);
5148 ret_type = type_to_simd_type (MONO_TYPE_R8);
5149 arg_types [0] = ret_type;
5150 AddFunc (module, "llvm.x86.sse2.sqrt.pd", ret_type, arg_types, 1);
5151 ret_type = type_to_simd_type (MONO_TYPE_R4);
5152 arg_types [0] = ret_type;
5153 AddFunc (module, "llvm.x86.sse.sqrt.ps", ret_type, arg_types, 1);
5154 ret_type = type_to_simd_type (MONO_TYPE_R4);
5155 arg_types [0] = ret_type;
5156 AddFunc (module, "llvm.x86.sse.rsqrt.ps", ret_type, arg_types, 1);
5157 ret_type = type_to_simd_type (MONO_TYPE_R4);
5158 arg_types [0] = ret_type;
5159 AddFunc (module, "llvm.x86.sse.rcp.ps", ret_type, arg_types, 1);
5162 ret_type = type_to_simd_type (MONO_TYPE_I2);
5163 arg_types [0] = ret_type;
5164 arg_types [1] = LLVMInt32Type ();
5165 AddFunc (module, "llvm.x86.sse2.psrli.w", ret_type, arg_types, 2);
5166 AddFunc (module, "llvm.x86.sse2.psrai.w", ret_type, arg_types, 2);
5167 AddFunc (module, "llvm.x86.sse2.pslli.w", ret_type, arg_types, 2);
5168 ret_type = type_to_simd_type (MONO_TYPE_I4);
5169 arg_types [0] = ret_type;
5170 arg_types [1] = LLVMInt32Type ();
5171 AddFunc (module, "llvm.x86.sse2.psrli.d", ret_type, arg_types, 2);
5172 AddFunc (module, "llvm.x86.sse2.psrai.d", ret_type, arg_types, 2);
5173 AddFunc (module, "llvm.x86.sse2.pslli.d", ret_type, arg_types, 2);
5174 ret_type = type_to_simd_type (MONO_TYPE_I8);
5175 arg_types [0] = ret_type;
5176 arg_types [1] = LLVMInt32Type ();
5177 AddFunc (module, "llvm.x86.sse2.psrli.q", ret_type, arg_types, 2);
5178 AddFunc (module, "llvm.x86.sse2.pslli.q", ret_type, arg_types, 2);
5181 ret_type = LLVMInt32Type ();
5182 arg_types [0] = type_to_simd_type (MONO_TYPE_I1);
5183 AddFunc (module, "llvm.x86.sse2.pmovmskb.128", ret_type, arg_types, 1);
5186 AddFunc (module, "llvm.x86.sse2.pause", LLVMVoidType (), NULL, 0);
5189 /* Load/Store intrinsics */
5191 LLVMTypeRef arg_types [5];
5195 for (i = 1; i <= 8; i *= 2) {
5196 arg_types [0] = LLVMPointerType (LLVMIntType (i * 8), 0);
5197 arg_types [1] = LLVMInt32Type ();
5198 arg_types [2] = LLVMInt1Type ();
5199 sprintf (name, "llvm.mono.load.i%d.p0i%d", i * 8, i * 8);
5200 LLVMAddFunction (module, name, LLVMFunctionType (LLVMIntType (i * 8), arg_types, 3, FALSE));
5202 arg_types [0] = LLVMIntType (i * 8);
5203 arg_types [1] = LLVMPointerType (LLVMIntType (i * 8), 0);
5204 arg_types [2] = LLVMInt32Type ();
5205 arg_types [3] = LLVMInt1Type ();
5206 sprintf (name, "llvm.mono.store.i%d.p0i%d", i * 8, i * 8);
5207 LLVMAddFunction (module, name, LLVMFunctionType (LLVMVoidType (), arg_types, 4, FALSE));
5213 add_types (MonoLLVMModule *lmodule)
5215 lmodule->ptr_type = LLVMPointerType (sizeof (gpointer) == 8 ? LLVMInt64Type () : LLVMInt32Type (), 0);
5219 mono_llvm_init (void)
5221 mono_native_tls_alloc (¤t_cfg_tls_id, NULL);
5225 init_jit_module (MonoDomain *domain)
5227 MonoJitICallInfo *info;
5228 MonoJitDomainInfo *dinfo;
5229 MonoLLVMModule *module;
5232 dinfo = domain_jit_info (domain);
5233 if (dinfo->llvm_module)
5236 mono_loader_lock ();
5238 if (dinfo->llvm_module) {
5239 mono_loader_unlock ();
5243 module = g_new0 (MonoLLVMModule, 1);
5245 name = g_strdup_printf ("mono-%s", domain->friendly_name);
5246 module->module = LLVMModuleCreateWithName (name);
5248 module->mono_ee = mono_llvm_create_ee (LLVMCreateModuleProviderForExistingModule (module->module), alloc_cb, emitted_cb, exception_cb, dlsym_cb, &module->ee);
5250 add_intrinsics (module->module);
5253 module->llvm_types = g_hash_table_new (NULL, NULL);
5255 info = mono_find_jit_icall_by_name ("llvm_resume_unwind_trampoline");
5257 LLVMAddGlobalMapping (module->ee, LLVMGetNamedFunction (module->module, "llvm_resume_unwind_trampoline"), (void*)info->func);
5259 mono_memory_barrier ();
5261 dinfo->llvm_module = module;
5263 mono_loader_unlock ();
5267 mono_llvm_cleanup (void)
5269 if (aot_module.module)
5270 LLVMDisposeModule (aot_module.module);
5272 LLVMContextDispose (LLVMGetGlobalContext ());
5276 mono_llvm_free_domain_info (MonoDomain *domain)
5278 MonoJitDomainInfo *info = domain_jit_info (domain);
5279 MonoLLVMModule *module = info->llvm_module;
5285 if (module->llvm_types)
5286 g_hash_table_destroy (module->llvm_types);
5288 mono_llvm_dispose_ee (module->mono_ee);
5290 if (module->bb_names) {
5291 for (i = 0; i < module->bb_names_len; ++i)
5292 g_free (module->bb_names [i]);
5293 g_free (module->bb_names);
5295 //LLVMDisposeModule (module->module);
5299 info->llvm_module = NULL;
5303 mono_llvm_create_aot_module (const char *got_symbol)
5305 /* Delete previous module */
5306 if (aot_module.plt_entries)
5307 g_hash_table_destroy (aot_module.plt_entries);
5308 if (aot_module.module)
5309 LLVMDisposeModule (aot_module.module);
5311 memset (&aot_module, 0, sizeof (aot_module));
5313 aot_module.module = LLVMModuleCreateWithName ("aot");
5314 aot_module.got_symbol = got_symbol;
5316 add_intrinsics (aot_module.module);
5317 add_types (&aot_module);
5321 * We couldn't compute the type of the LLVM global representing the got because
5322 * its size is only known after all the methods have been emitted. So create
5323 * a dummy variable, and replace all uses it with the real got variable when
5324 * its size is known in mono_llvm_emit_aot_module ().
5327 LLVMTypeRef got_type = LLVMArrayType (aot_module.ptr_type, 0);
5329 aot_module.got_var = LLVMAddGlobal (aot_module.module, got_type, "mono_dummy_got");
5330 LLVMSetInitializer (aot_module.got_var, LLVMConstNull (got_type));
5333 /* Add a dummy personality function */
5335 LLVMBasicBlockRef lbb;
5336 LLVMBuilderRef lbuilder;
5337 LLVMValueRef personality;
5339 personality = LLVMAddFunction (aot_module.module, "mono_aot_personality", LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE));
5340 LLVMSetLinkage (personality, LLVMInternalLinkage);
5341 lbb = LLVMAppendBasicBlock (personality, "BB0");
5342 lbuilder = LLVMCreateBuilder ();
5343 LLVMPositionBuilderAtEnd (lbuilder, lbb);
5344 LLVMBuildRetVoid (lbuilder);
5347 aot_module.llvm_types = g_hash_table_new (NULL, NULL);
5348 aot_module.plt_entries = g_hash_table_new (g_str_hash, g_str_equal);
5349 aot_module.plt_entries_ji = g_hash_table_new (NULL, NULL);
5350 aot_module.method_to_lmethod = g_hash_table_new (NULL, NULL);
5354 * Emit the aot module into the LLVM bitcode file FILENAME.
5357 mono_llvm_emit_aot_module (const char *filename, int got_size)
5359 LLVMTypeRef got_type;
5360 LLVMValueRef real_got;
5361 MonoLLVMModule *module = &aot_module;
5364 * Create the real got variable and replace all uses of the dummy variable with
5367 got_type = LLVMArrayType (aot_module.ptr_type, got_size);
5368 real_got = LLVMAddGlobal (aot_module.module, got_type, aot_module.got_symbol);
5369 LLVMSetInitializer (real_got, LLVMConstNull (got_type));
5370 LLVMSetLinkage (real_got, LLVMInternalLinkage);
5372 mono_llvm_replace_uses_of (aot_module.got_var, real_got);
5374 mark_as_used (&aot_module, real_got);
5376 /* Delete the dummy got so it doesn't become a global */
5377 LLVMDeleteGlobal (aot_module.got_var);
5379 emit_llvm_used (&aot_module);
5381 /* Replace PLT entries for directly callable methods with the methods themselves */
5383 GHashTableIter iter;
5385 LLVMValueRef callee;
5387 g_hash_table_iter_init (&iter, aot_module.plt_entries_ji);
5388 while (g_hash_table_iter_next (&iter, (void**)&ji, (void**)&callee)) {
5389 if (mono_aot_is_direct_callable (ji)) {
5390 LLVMValueRef lmethod;
5392 lmethod = g_hash_table_lookup (module->method_to_lmethod, ji->data.method);
5394 mono_llvm_replace_uses_of (callee, lmethod);
5395 mono_aot_mark_unused_llvm_plt_entry (ji);
5405 if (LLVMVerifyModule (aot_module.module, LLVMReturnStatusAction, &verifier_err)) {
5406 g_assert_not_reached ();
5411 LLVMWriteBitcodeToFile (aot_module.module, filename);
5416 - Emit LLVM IR from the mono IR using the LLVM C API.
5417 - The original arch specific code remains, so we can fall back to it if we run
5418 into something we can't handle.
5422 A partial list of issues:
5423 - Handling of opcodes which can throw exceptions.
5425 In the mono JIT, these are implemented using code like this:
5432 push throw_pos - method
5433 call <exception trampoline>
5435 The problematic part is push throw_pos - method, which cannot be represented
5436 in the LLVM IR, since it does not support label values.
5437 -> this can be implemented in AOT mode using inline asm + labels, but cannot
5438 be implemented in JIT mode ?
5439 -> a possible but slower implementation would use the normal exception
5440 throwing code but it would need to control the placement of the throw code
5441 (it needs to be exactly after the compare+branch).
5442 -> perhaps add a PC offset intrinsics ?
5444 - efficient implementation of .ovf opcodes.
5446 These are currently implemented as:
5447 <ins which sets the condition codes>
5450 Some overflow opcodes are now supported by LLVM SVN.
5452 - exception handling, unwinding.
5453 - SSA is disabled for methods with exception handlers
5454 - How to obtain unwind info for LLVM compiled methods ?
5455 -> this is now solved by converting the unwind info generated by LLVM
5457 - LLVM uses the c++ exception handling framework, while we use our home grown
5458 code, and couldn't use the c++ one:
5459 - its not supported under VC++, other exotic platforms.
5460 - it might be impossible to support filter clauses with it.
5464 The trampolines need a predictable call sequence, since they need to disasm
5465 the calling code to obtain register numbers / offsets.
5467 LLVM currently generates this code in non-JIT mode:
5468 mov -0x98(%rax),%eax
5470 Here, the vtable pointer is lost.
5471 -> solution: use one vtable trampoline per class.
5473 - passing/receiving the IMT pointer/RGCTX.
5474 -> solution: pass them as normal arguments ?
5478 LLVM does not allow the specification of argument registers etc. This means
5479 that all calls are made according to the platform ABI.
5481 - passing/receiving vtypes.
5483 Vtypes passed/received in registers are handled by the front end by using
5484 a signature with scalar arguments, and loading the parts of the vtype into those
5487 Vtypes passed on the stack are handled using the 'byval' attribute.
5491 Supported though alloca, we need to emit the load/store code.
5495 The mono JIT uses pointer sized iregs/double fregs, while LLVM uses precisely
5496 typed registers, so we have to keep track of the precise LLVM type of each vreg.
5497 This is made easier because the IR is already in SSA form.
5498 An additional problem is that our IR is not consistent with types, i.e. i32/ia64
5499 types are frequently used incorrectly.
5504 Emit LLVM bytecode into a .bc file, compile it using llc into a .s file, then
5505 append the AOT data structures to that file. For methods which cannot be
5506 handled by LLVM, the normal JIT compiled versions are used.
5509 /* FIXME: Normalize some aspects of the mono IR to allow easier translation, like:
5510 * - each bblock should end with a branch
5511 * - setting the return value, making cfg->ret non-volatile
5512 * - avoid some transformations in the JIT which make it harder for us to generate
5514 * - use pointer types to help optimizations.