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/debug-mono-symfile.h>
11 #include <mono/metadata/mempool-internals.h>
12 #include <mono/utils/mono-tls.h>
13 #include <mono/utils/mono-dl.h>
14 #include <mono/utils/mono-time.h>
15 #include <mono/utils/freebsd-dwarf.h>
17 #ifndef __STDC_LIMIT_MACROS
18 #define __STDC_LIMIT_MACROS
20 #ifndef __STDC_CONSTANT_MACROS
21 #define __STDC_CONSTANT_MACROS
24 #include "llvm-c/Core.h"
25 #include "llvm-c/ExecutionEngine.h"
26 #include "llvm-c/BitWriter.h"
27 #include "llvm-c/Analysis.h"
29 #include "mini-llvm-cpp.h"
34 extern void *memset(void *, int, size_t);
35 void bzero (void *to, size_t count) { memset (to, 0, count); }
39 #if LLVM_API_VERSION < 4
40 #error "The version of the mono llvm repository is too old."
44 * Information associated by mono with LLVM modules.
48 LLVMValueRef throw, rethrow, throw_corlib_exception;
49 GHashTable *llvm_types;
51 const char *got_symbol;
52 GHashTable *plt_entries;
53 GHashTable *plt_entries_ji;
54 GHashTable *method_to_lmethod;
59 GPtrArray *subprogram_mds;
61 LLVMExecutionEngineRef ee;
62 gboolean external_symbols;
68 * Information associated by the backend with mono basic blocks.
71 LLVMBasicBlockRef bblock, end_bblock;
72 LLVMValueRef finally_ind;
73 gboolean added, invoke_target;
75 * If this bblock is the start of a finally clause, this is a list of bblocks it
76 * needs to branch to in ENDFINALLY.
78 GSList *call_handler_return_bbs;
80 * If this bblock is the start of a finally clause, this is the bblock that
81 * CALL_HANDLER needs to branch to.
83 LLVMBasicBlockRef call_handler_target_bb;
84 /* The list of switch statements generated by ENDFINALLY instructions */
85 GSList *endfinally_switch_ins_list;
90 * Structure containing emit state
95 /* Maps method names to the corresponding LLVMValueRef */
96 GHashTable *emitted_method_decls;
100 MonoLLVMModule *lmodule;
101 LLVMModuleRef module;
103 int sindex, default_index, ex_index;
104 LLVMBuilderRef builder;
105 LLVMValueRef *values, *addresses;
106 MonoType **vreg_cli_types;
108 MonoMethodSignature *sig;
110 GHashTable *region_to_handler;
111 GHashTable *clause_to_handler;
112 LLVMBuilderRef alloca_builder;
113 LLVMValueRef last_alloca;
114 LLVMValueRef rgctx_arg;
115 LLVMTypeRef *vreg_types;
117 gboolean *unreachable;
119 LLVMValueRef imt_rgctx_loc;
120 GHashTable *llvm_types;
122 MonoDebugMethodInfo *minfo;
124 /* For every clause, the clauses it is nested in */
132 MonoBasicBlock *in_bb;
137 * Instruction metadata
138 * This is the same as ins_info, but LREG != IREG.
146 #define MINI_OP(a,b,dest,src1,src2) dest, src1, src2, ' ',
147 #define MINI_OP3(a,b,dest,src1,src2,src3) dest, src1, src2, src3,
154 /* keep in sync with the enum in mini.h */
157 #include "mini-ops.h"
162 #if SIZEOF_VOID_P == 4
163 #define GET_LONG_IMM(ins) (((guint64)(ins)->inst_ms_word << 32) | (guint64)(guint32)(ins)->inst_ls_word)
165 #define GET_LONG_IMM(ins) ((ins)->inst_imm)
168 #define LLVM_INS_INFO(opcode) (&llvm_ins_info [((opcode) - OP_START - 1) * 4])
171 #define TRACE_FAILURE(msg) do { printf ("%s\n", msg); } while (0)
173 #define TRACE_FAILURE(msg)
177 #define IS_TARGET_X86 1
179 #define IS_TARGET_X86 0
183 #define IS_TARGET_AMD64 1
185 #define IS_TARGET_AMD64 0
188 #define LLVM_FAILURE(ctx, reason) do { \
189 TRACE_FAILURE (reason); \
190 (ctx)->cfg->exception_message = g_strdup (reason); \
191 (ctx)->cfg->disable_llvm = TRUE; \
195 #define CHECK_FAILURE(ctx) do { \
196 if ((ctx)->cfg->disable_llvm) \
200 static LLVMIntPredicate cond_to_llvm_cond [] = {
213 static LLVMRealPredicate fpcond_to_llvm_cond [] = {
226 static MonoNativeTlsKey current_cfg_tls_id;
228 static MonoLLVMModule aot_module;
229 static int memset_param_count, memcpy_param_count;
230 static const char *memset_func_name;
231 static const char *memcpy_func_name;
233 static void init_jit_module (MonoDomain *domain);
235 static void emit_dbg_loc (EmitContext *ctx, LLVMBuilderRef builder, const unsigned char *cil_code);
236 static LLVMValueRef emit_dbg_subprogram (EmitContext *ctx, MonoCompile *cfg, LLVMValueRef method, const char *name);
237 static void emit_dbg_info (MonoLLVMModule *lmodule, const char *filename, const char *cu_name);
242 * The LLVM type with width == sizeof (gpointer)
247 return sizeof (gpointer) == 8 ? LLVMInt64Type () : LLVMInt32Type ();
253 return sizeof (gpointer) == 8 ? LLVMPointerType (LLVMInt64Type (), 0) : LLVMPointerType (LLVMInt32Type (), 0);
259 return sizeof (gpointer) == 8 ? LLVMPointerType (LLVMInt64Type (), 0) : LLVMPointerType (LLVMInt32Type (), 0);
265 * Return the size of the LLVM representation of the vtype T.
268 get_vtype_size (MonoType *t)
272 size = mono_class_value_size (mono_class_from_mono_type (t), NULL);
274 while (size < 2 * sizeof (gpointer) && mono_is_power_of_two (size) == -1)
281 * simd_class_to_llvm_type:
283 * Return the LLVM type corresponding to the Mono.SIMD class KLASS
286 simd_class_to_llvm_type (EmitContext *ctx, MonoClass *klass)
288 if (!strcmp (klass->name, "Vector2d")) {
289 return LLVMVectorType (LLVMDoubleType (), 2);
290 } else if (!strcmp (klass->name, "Vector2l")) {
291 return LLVMVectorType (LLVMInt64Type (), 2);
292 } else if (!strcmp (klass->name, "Vector2ul")) {
293 return LLVMVectorType (LLVMInt64Type (), 2);
294 } else if (!strcmp (klass->name, "Vector4i")) {
295 return LLVMVectorType (LLVMInt32Type (), 4);
296 } else if (!strcmp (klass->name, "Vector4ui")) {
297 return LLVMVectorType (LLVMInt32Type (), 4);
298 } else if (!strcmp (klass->name, "Vector4f")) {
299 return LLVMVectorType (LLVMFloatType (), 4);
300 } else if (!strcmp (klass->name, "Vector8s")) {
301 return LLVMVectorType (LLVMInt16Type (), 8);
302 } else if (!strcmp (klass->name, "Vector8us")) {
303 return LLVMVectorType (LLVMInt16Type (), 8);
304 } else if (!strcmp (klass->name, "Vector16sb")) {
305 return LLVMVectorType (LLVMInt8Type (), 16);
306 } else if (!strcmp (klass->name, "Vector16b")) {
307 return LLVMVectorType (LLVMInt8Type (), 16);
309 printf ("%s\n", klass->name);
315 /* Return the 128 bit SIMD type corresponding to the mono type TYPE */
316 static inline G_GNUC_UNUSED LLVMTypeRef
317 type_to_simd_type (int type)
321 return LLVMVectorType (LLVMInt8Type (), 16);
323 return LLVMVectorType (LLVMInt16Type (), 8);
325 return LLVMVectorType (LLVMInt32Type (), 4);
327 return LLVMVectorType (LLVMInt64Type (), 2);
329 return LLVMVectorType (LLVMDoubleType (), 2);
331 return LLVMVectorType (LLVMFloatType (), 4);
333 g_assert_not_reached ();
339 create_llvm_type_for_type (MonoClass *klass)
341 int i, size, nfields, esize;
342 LLVMTypeRef *eltypes;
347 t = &klass->byval_arg;
349 if (mini_type_is_hfa (t, &nfields, &esize)) {
351 * This is needed on arm64 where HFAs are returned in
355 eltypes = g_new (LLVMTypeRef, size);
356 for (i = 0; i < size; ++i)
357 eltypes [i] = esize == 4 ? LLVMFloatType () : LLVMDoubleType ();
359 size = get_vtype_size (t);
361 eltypes = g_new (LLVMTypeRef, size);
362 for (i = 0; i < size; ++i)
363 eltypes [i] = LLVMInt8Type ();
366 name = mono_type_full_name (&klass->byval_arg);
367 ltype = LLVMStructCreateNamed (LLVMGetGlobalContext (), name);
368 LLVMStructSetBody (ltype, eltypes, size, FALSE);
378 * Return the LLVM type corresponding to T.
381 type_to_llvm_type (EmitContext *ctx, MonoType *t)
384 return LLVMPointerType (LLVMInt8Type (), 0);
386 t = mini_get_underlying_type (ctx->cfg, t);
389 return LLVMVoidType ();
391 return LLVMInt8Type ();
393 return LLVMInt16Type ();
395 return LLVMInt32Type ();
397 return LLVMInt8Type ();
399 return LLVMInt16Type ();
401 return LLVMInt32Type ();
402 case MONO_TYPE_BOOLEAN:
403 return LLVMInt8Type ();
406 return LLVMInt64Type ();
408 return LLVMInt16Type ();
410 return LLVMFloatType ();
412 return LLVMDoubleType ();
415 return IntPtrType ();
416 case MONO_TYPE_OBJECT:
417 case MONO_TYPE_CLASS:
418 case MONO_TYPE_ARRAY:
419 case MONO_TYPE_SZARRAY:
420 case MONO_TYPE_STRING:
422 return ObjRefType ();
425 /* Because of generic sharing */
426 return ObjRefType ();
427 case MONO_TYPE_GENERICINST:
428 if (!mono_type_generic_inst_is_valuetype (t))
429 return ObjRefType ();
431 case MONO_TYPE_VALUETYPE:
432 case MONO_TYPE_TYPEDBYREF: {
436 klass = mono_class_from_mono_type (t);
438 if (MONO_CLASS_IS_SIMD (ctx->cfg, klass))
439 return simd_class_to_llvm_type (ctx, klass);
442 return type_to_llvm_type (ctx, mono_class_enum_basetype (klass));
444 ltype = g_hash_table_lookup (ctx->lmodule->llvm_types, klass);
446 ltype = create_llvm_type_for_type (klass);
447 g_hash_table_insert (ctx->lmodule->llvm_types, klass, ltype);
453 printf ("X: %d\n", t->type);
454 ctx->cfg->exception_message = g_strdup_printf ("type %s", mono_type_full_name (t));
455 ctx->cfg->disable_llvm = TRUE;
463 * Return whenever T is an unsigned int type.
466 type_is_unsigned (EmitContext *ctx, MonoType *t)
483 * type_to_llvm_arg_type:
485 * Same as type_to_llvm_type, but treat i8/i16 as i32.
488 type_to_llvm_arg_type (EmitContext *ctx, MonoType *t)
490 LLVMTypeRef ptype = type_to_llvm_type (ctx, t);
493 * This works on all abis except arm64/ios which passes multiple
494 * arguments in one stack slot.
497 if (ptype == LLVMInt8Type () || ptype == LLVMInt16Type ()) {
499 * LLVM generates code which only sets the lower bits, while JITted
500 * code expects all the bits to be set.
502 ptype = LLVMInt32Type ();
510 * llvm_type_to_stack_type:
512 * Return the LLVM type which needs to be used when a value of type TYPE is pushed
515 static G_GNUC_UNUSED LLVMTypeRef
516 llvm_type_to_stack_type (MonoCompile *cfg, LLVMTypeRef type)
520 if (type == LLVMInt8Type ())
521 return LLVMInt32Type ();
522 else if (type == LLVMInt16Type ())
523 return LLVMInt32Type ();
524 else if (!cfg->r4fp && type == LLVMFloatType ())
525 return LLVMDoubleType ();
531 * regtype_to_llvm_type:
533 * Return the LLVM type corresponding to the regtype C used in instruction
537 regtype_to_llvm_type (char c)
541 return LLVMInt32Type ();
543 return LLVMInt64Type ();
545 return LLVMDoubleType ();
554 * Return the LLVM type corresponding to the unary/binary opcode OPCODE.
557 op_to_llvm_type (int opcode)
562 return LLVMInt8Type ();
565 return LLVMInt8Type ();
568 return LLVMInt16Type ();
571 return LLVMInt16Type ();
574 return LLVMInt32Type ();
577 return LLVMInt32Type ();
579 return LLVMInt64Type ();
581 return LLVMFloatType ();
583 return LLVMDoubleType ();
585 return LLVMInt64Type ();
587 return LLVMInt32Type ();
589 return LLVMInt64Type ();
594 return LLVMInt8Type ();
599 return LLVMInt16Type ();
602 return sizeof (gpointer) == 8 ? LLVMInt64Type () : LLVMInt32Type ();
609 return LLVMInt32Type ();
616 return LLVMInt64Type ();
618 printf ("%s\n", mono_inst_name (opcode));
619 g_assert_not_reached ();
625 * load_store_to_llvm_type:
627 * Return the size/sign/zero extension corresponding to the load/store opcode
631 load_store_to_llvm_type (int opcode, int *size, gboolean *sext, gboolean *zext)
637 case OP_LOADI1_MEMBASE:
638 case OP_STOREI1_MEMBASE_REG:
639 case OP_STOREI1_MEMBASE_IMM:
640 case OP_ATOMIC_LOAD_I1:
641 case OP_ATOMIC_STORE_I1:
644 return LLVMInt8Type ();
645 case OP_LOADU1_MEMBASE:
647 case OP_ATOMIC_LOAD_U1:
648 case OP_ATOMIC_STORE_U1:
651 return LLVMInt8Type ();
652 case OP_LOADI2_MEMBASE:
653 case OP_STOREI2_MEMBASE_REG:
654 case OP_STOREI2_MEMBASE_IMM:
655 case OP_ATOMIC_LOAD_I2:
656 case OP_ATOMIC_STORE_I2:
659 return LLVMInt16Type ();
660 case OP_LOADU2_MEMBASE:
662 case OP_ATOMIC_LOAD_U2:
663 case OP_ATOMIC_STORE_U2:
666 return LLVMInt16Type ();
667 case OP_LOADI4_MEMBASE:
668 case OP_LOADU4_MEMBASE:
671 case OP_STOREI4_MEMBASE_REG:
672 case OP_STOREI4_MEMBASE_IMM:
673 case OP_ATOMIC_LOAD_I4:
674 case OP_ATOMIC_STORE_I4:
675 case OP_ATOMIC_LOAD_U4:
676 case OP_ATOMIC_STORE_U4:
678 return LLVMInt32Type ();
679 case OP_LOADI8_MEMBASE:
681 case OP_STOREI8_MEMBASE_REG:
682 case OP_STOREI8_MEMBASE_IMM:
683 case OP_ATOMIC_LOAD_I8:
684 case OP_ATOMIC_STORE_I8:
685 case OP_ATOMIC_LOAD_U8:
686 case OP_ATOMIC_STORE_U8:
688 return LLVMInt64Type ();
689 case OP_LOADR4_MEMBASE:
690 case OP_STORER4_MEMBASE_REG:
691 case OP_ATOMIC_LOAD_R4:
692 case OP_ATOMIC_STORE_R4:
694 return LLVMFloatType ();
695 case OP_LOADR8_MEMBASE:
696 case OP_STORER8_MEMBASE_REG:
697 case OP_ATOMIC_LOAD_R8:
698 case OP_ATOMIC_STORE_R8:
700 return LLVMDoubleType ();
701 case OP_LOAD_MEMBASE:
703 case OP_STORE_MEMBASE_REG:
704 case OP_STORE_MEMBASE_IMM:
705 *size = sizeof (gpointer);
706 return IntPtrType ();
708 g_assert_not_reached ();
716 * Return the LLVM intrinsics corresponding to the overflow opcode OPCODE.
719 ovf_op_to_intrins (int opcode)
723 return "llvm.sadd.with.overflow.i32";
725 return "llvm.uadd.with.overflow.i32";
727 return "llvm.ssub.with.overflow.i32";
729 return "llvm.usub.with.overflow.i32";
731 return "llvm.smul.with.overflow.i32";
733 return "llvm.umul.with.overflow.i32";
735 return "llvm.sadd.with.overflow.i64";
737 return "llvm.uadd.with.overflow.i64";
739 return "llvm.ssub.with.overflow.i64";
741 return "llvm.usub.with.overflow.i64";
743 return "llvm.smul.with.overflow.i64";
745 return "llvm.umul.with.overflow.i64";
747 g_assert_not_reached ();
753 simd_op_to_intrins (int opcode)
756 #if defined(TARGET_X86) || defined(TARGET_AMD64)
758 return "llvm.x86.sse2.min.pd";
760 return "llvm.x86.sse.min.ps";
762 return "llvm.x86.sse41.pminud";
764 return "llvm.x86.sse41.pminuw";
766 return "llvm.x86.sse2.pminu.b";
768 return "llvm.x86.sse2.pmins.w";
770 return "llvm.x86.sse2.max.pd";
772 return "llvm.x86.sse.max.ps";
774 return "llvm.x86.sse3.hadd.pd";
776 return "llvm.x86.sse3.hadd.ps";
778 return "llvm.x86.sse3.hsub.pd";
780 return "llvm.x86.sse3.hsub.ps";
782 return "llvm.x86.sse41.pmaxud";
784 return "llvm.x86.sse41.pmaxuw";
786 return "llvm.x86.sse2.pmaxu.b";
788 return "llvm.x86.sse3.addsub.ps";
790 return "llvm.x86.sse3.addsub.pd";
791 case OP_EXTRACT_MASK:
792 return "llvm.x86.sse2.pmovmskb.128";
795 return "llvm.x86.sse2.psrli.w";
798 return "llvm.x86.sse2.psrli.d";
801 return "llvm.x86.sse2.psrli.q";
804 return "llvm.x86.sse2.pslli.w";
807 return "llvm.x86.sse2.pslli.d";
810 return "llvm.x86.sse2.pslli.q";
813 return "llvm.x86.sse2.psrai.w";
816 return "llvm.x86.sse2.psrai.d";
818 return "llvm.x86.sse2.padds.b";
820 return "llvm.x86.sse2.padds.w";
822 return "llvm.x86.sse2.psubs.b";
824 return "llvm.x86.sse2.psubs.w";
825 case OP_PADDB_SAT_UN:
826 return "llvm.x86.sse2.paddus.b";
827 case OP_PADDW_SAT_UN:
828 return "llvm.x86.sse2.paddus.w";
829 case OP_PSUBB_SAT_UN:
830 return "llvm.x86.sse2.psubus.b";
831 case OP_PSUBW_SAT_UN:
832 return "llvm.x86.sse2.psubus.w";
834 return "llvm.x86.sse2.pavg.b";
836 return "llvm.x86.sse2.pavg.w";
838 return "llvm.x86.sse.sqrt.ps";
840 return "llvm.x86.sse2.sqrt.pd";
842 return "llvm.x86.sse.rsqrt.ps";
844 return "llvm.x86.sse.rcp.ps";
846 return "llvm.x86.sse2.cvtdq2pd";
848 return "llvm.x86.sse2.cvtdq2ps";
850 return "llvm.x86.sse2.cvtpd2dq";
852 return "llvm.x86.sse2.cvtps2dq";
854 return "llvm.x86.sse2.cvtpd2ps";
856 return "llvm.x86.sse2.cvtps2pd";
858 return "llvm.x86.sse2.cvttpd2dq";
860 return "llvm.x86.sse2.cvttps2dq";
862 return "llvm.x86.sse.cmp.ps";
864 return "llvm.x86.sse2.cmp.pd";
866 return "llvm.x86.sse2.packsswb.128";
868 return "llvm.x86.sse2.packssdw.128";
870 return "llvm.x86.sse2.packuswb.128";
872 return "llvm.x86.sse41.packusdw";
874 return "llvm.x86.sse2.pmulh.w";
875 case OP_PMULW_HIGH_UN:
876 return "llvm.x86.sse2.pmulhu.w";
879 g_assert_not_reached ();
885 simd_op_to_llvm_type (int opcode)
887 #if defined(TARGET_X86) || defined(TARGET_AMD64)
891 return type_to_simd_type (MONO_TYPE_R8);
894 return type_to_simd_type (MONO_TYPE_I8);
897 return type_to_simd_type (MONO_TYPE_I4);
902 return type_to_simd_type (MONO_TYPE_I2);
906 return type_to_simd_type (MONO_TYPE_I1);
908 return type_to_simd_type (MONO_TYPE_R4);
911 return type_to_simd_type (MONO_TYPE_I4);
915 return type_to_simd_type (MONO_TYPE_R8);
919 return type_to_simd_type (MONO_TYPE_R4);
920 case OP_EXTRACT_MASK:
921 return type_to_simd_type (MONO_TYPE_I1);
927 return type_to_simd_type (MONO_TYPE_R4);
930 return type_to_simd_type (MONO_TYPE_R8);
932 g_assert_not_reached ();
943 * Return the LLVM basic block corresponding to BB.
945 static LLVMBasicBlockRef
946 get_bb (EmitContext *ctx, MonoBasicBlock *bb)
948 char bb_name_buf [128];
951 if (ctx->bblocks [bb->block_num].bblock == NULL) {
952 if (bb->flags & BB_EXCEPTION_HANDLER) {
953 int clause_index = (mono_get_block_region_notry (ctx->cfg, bb->region) >> 8) - 1;
954 sprintf (bb_name_buf, "EH_CLAUSE%d_BB%d", clause_index, bb->block_num);
955 bb_name = bb_name_buf;
956 } else if (bb->block_num < 256) {
957 if (!ctx->lmodule->bb_names) {
958 ctx->lmodule->bb_names_len = 256;
959 ctx->lmodule->bb_names = g_new0 (char*, ctx->lmodule->bb_names_len);
961 if (!ctx->lmodule->bb_names [bb->block_num]) {
964 n = g_strdup_printf ("BB%d", bb->block_num);
965 mono_memory_barrier ();
966 ctx->lmodule->bb_names [bb->block_num] = n;
968 bb_name = ctx->lmodule->bb_names [bb->block_num];
970 sprintf (bb_name_buf, "BB%d", bb->block_num);
971 bb_name = bb_name_buf;
974 ctx->bblocks [bb->block_num].bblock = LLVMAppendBasicBlock (ctx->lmethod, bb_name);
975 ctx->bblocks [bb->block_num].end_bblock = ctx->bblocks [bb->block_num].bblock;
978 return ctx->bblocks [bb->block_num].bblock;
984 * Return the last LLVM bblock corresponding to BB.
985 * This might not be equal to the bb returned by get_bb () since we need to generate
986 * multiple LLVM bblocks for a mono bblock to handle throwing exceptions.
988 static LLVMBasicBlockRef
989 get_end_bb (EmitContext *ctx, MonoBasicBlock *bb)
992 return ctx->bblocks [bb->block_num].end_bblock;
995 static LLVMBasicBlockRef
996 gen_bb (EmitContext *ctx, const char *prefix)
1000 sprintf (bb_name, "%s%d", prefix, ++ ctx->ex_index);
1001 return LLVMAppendBasicBlock (ctx->lmethod, bb_name);
1007 * Return the target of the patch identified by TYPE and TARGET.
1010 resolve_patch (MonoCompile *cfg, MonoJumpInfoType type, gconstpointer target)
1014 memset (&ji, 0, sizeof (ji));
1016 ji.data.target = target;
1018 return mono_resolve_patch_target (cfg->method, cfg->domain, NULL, &ji, FALSE);
1024 * Emit code to convert the LLVM value V to DTYPE.
1027 convert_full (EmitContext *ctx, LLVMValueRef v, LLVMTypeRef dtype, gboolean is_unsigned)
1029 LLVMTypeRef stype = LLVMTypeOf (v);
1031 if (stype != dtype) {
1032 gboolean ext = FALSE;
1035 if (dtype == LLVMInt64Type () && (stype == LLVMInt32Type () || stype == LLVMInt16Type () || stype == LLVMInt8Type ()))
1037 else if (dtype == LLVMInt32Type () && (stype == LLVMInt16Type () || stype == LLVMInt8Type ()))
1039 else if (dtype == LLVMInt16Type () && (stype == LLVMInt8Type ()))
1043 return is_unsigned ? LLVMBuildZExt (ctx->builder, v, dtype, "") : LLVMBuildSExt (ctx->builder, v, dtype, "");
1045 if (dtype == LLVMDoubleType () && stype == LLVMFloatType ())
1046 return LLVMBuildFPExt (ctx->builder, v, dtype, "");
1049 if (stype == LLVMInt64Type () && (dtype == LLVMInt32Type () || dtype == LLVMInt16Type () || dtype == LLVMInt8Type ()))
1050 return LLVMBuildTrunc (ctx->builder, v, dtype, "");
1051 if (stype == LLVMInt32Type () && (dtype == LLVMInt16Type () || dtype == LLVMInt8Type ()))
1052 return LLVMBuildTrunc (ctx->builder, v, dtype, "");
1053 if (stype == LLVMInt16Type () && dtype == LLVMInt8Type ())
1054 return LLVMBuildTrunc (ctx->builder, v, dtype, "");
1055 if (stype == LLVMDoubleType () && dtype == LLVMFloatType ())
1056 return LLVMBuildFPTrunc (ctx->builder, v, dtype, "");
1058 if (LLVMGetTypeKind (stype) == LLVMPointerTypeKind && LLVMGetTypeKind (dtype) == LLVMPointerTypeKind)
1059 return LLVMBuildBitCast (ctx->builder, v, dtype, "");
1060 if (LLVMGetTypeKind (dtype) == LLVMPointerTypeKind)
1061 return LLVMBuildIntToPtr (ctx->builder, v, dtype, "");
1062 if (LLVMGetTypeKind (stype) == LLVMPointerTypeKind)
1063 return LLVMBuildPtrToInt (ctx->builder, v, dtype, "");
1065 if (mono_arch_is_soft_float ()) {
1066 if (stype == LLVMInt32Type () && dtype == LLVMFloatType ())
1067 return LLVMBuildBitCast (ctx->builder, v, dtype, "");
1068 if (stype == LLVMInt32Type () && dtype == LLVMDoubleType ())
1069 return LLVMBuildBitCast (ctx->builder, LLVMBuildZExt (ctx->builder, v, LLVMInt64Type (), ""), dtype, "");
1072 if (LLVMGetTypeKind (stype) == LLVMVectorTypeKind && LLVMGetTypeKind (dtype) == LLVMVectorTypeKind)
1073 return LLVMBuildBitCast (ctx->builder, v, dtype, "");
1076 LLVMDumpValue (LLVMConstNull (dtype));
1077 g_assert_not_reached ();
1085 convert (EmitContext *ctx, LLVMValueRef v, LLVMTypeRef dtype)
1087 return convert_full (ctx, v, dtype, FALSE);
1091 * emit_volatile_load:
1093 * If vreg is volatile, emit a load from its address.
1096 emit_volatile_load (EmitContext *ctx, int vreg)
1100 LLVMValueRef v = LLVMBuildLoad (ctx->builder, ctx->addresses [vreg], "");
1101 t = ctx->vreg_cli_types [vreg];
1102 if (t && !t->byref) {
1104 * Might have to zero extend since llvm doesn't have
1107 if (t->type == MONO_TYPE_U1 || t->type == MONO_TYPE_U2 || t->type == MONO_TYPE_CHAR || t->type == MONO_TYPE_BOOLEAN)
1108 v = LLVMBuildZExt (ctx->builder, v, LLVMInt32Type (), "");
1109 else if (t->type == MONO_TYPE_U8)
1110 v = LLVMBuildZExt (ctx->builder, v, LLVMInt64Type (), "");
1117 * emit_volatile_store:
1119 * If VREG is volatile, emit a store from its value to its address.
1122 emit_volatile_store (EmitContext *ctx, int vreg)
1124 MonoInst *var = get_vreg_to_inst (ctx->cfg, vreg);
1126 if (var && var->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT)) {
1127 g_assert (ctx->addresses [vreg]);
1128 LLVMBuildStore (ctx->builder, convert (ctx, ctx->values [vreg], type_to_llvm_type (ctx, var->inst_vtype)), ctx->addresses [vreg]);
1134 * Maps parameter indexes in the original signature to parameter indexes
1135 * in the LLVM signature.
1138 /* The indexes of various special arguments in the LLVM signature */
1139 int vret_arg_pindex, this_arg_pindex, rgctx_arg_pindex, imt_arg_pindex;
1143 * sig_to_llvm_sig_full:
1145 * Return the LLVM signature corresponding to the mono signature SIG using the
1146 * calling convention information in CINFO. Return parameter mapping information in SINFO.
1149 sig_to_llvm_sig_full (EmitContext *ctx, MonoMethodSignature *sig, LLVMCallInfo *cinfo,
1152 LLVMTypeRef ret_type;
1153 LLVMTypeRef *param_types = NULL;
1155 int i, j, pindex, vret_arg_pindex = 0;
1157 gboolean vretaddr = FALSE;
1161 memset (sinfo, 0, sizeof (LLVMSigInfo));
1163 rtype = mini_get_underlying_type (ctx->cfg, sig->ret);
1164 ret_type = type_to_llvm_type (ctx, rtype);
1165 CHECK_FAILURE (ctx);
1168 if (cinfo->ret.storage == LLVMArgVtypeInReg) {
1169 /* LLVM models this by returning an aggregate value */
1170 if (cinfo->ret.pair_storage [0] == LLVMArgInIReg && cinfo->ret.pair_storage [1] == LLVMArgNone) {
1171 LLVMTypeRef members [2];
1173 members [0] = IntPtrType ();
1174 ret_type = LLVMStructType (members, 1, FALSE);
1176 g_assert_not_reached ();
1178 } else if (cinfo->ret.storage == LLVMArgVtypeByVal) {
1179 /* Vtype returned normally by val */
1180 } else if (cinfo->ret.storage == LLVMArgFpStruct) {
1181 /* Vtype returned as a fp struct */
1182 LLVMTypeRef members [16];
1184 /* Have to create our own structure since we don't map fp structures to LLVM fp structures yet */
1185 for (i = 0; i < cinfo->ret.nslots; ++i)
1186 members [i] = cinfo->ret.esize == 8 ? LLVMDoubleType () : LLVMFloatType ();
1187 ret_type = LLVMStructType (members, cinfo->ret.nslots, FALSE);
1188 } else if (mini_type_is_vtype (ctx->cfg, rtype)) {
1189 g_assert (cinfo->ret.storage == LLVMArgVtypeRetAddr);
1191 ret_type = LLVMVoidType ();
1195 pindexes = g_new0 (int, sig->param_count);
1196 param_types = g_new0 (LLVMTypeRef, (sig->param_count * 8) + 3);
1198 if (cinfo && cinfo->rgctx_arg) {
1200 sinfo->rgctx_arg_pindex = pindex;
1201 param_types [pindex] = ctx->lmodule->ptr_type;
1204 if (cinfo && cinfo->imt_arg) {
1206 sinfo->imt_arg_pindex = pindex;
1207 param_types [pindex] = ctx->lmodule->ptr_type;
1211 /* Compute the index in the LLVM signature where the vret arg needs to be passed */
1212 vret_arg_pindex = pindex;
1213 if (cinfo->vret_arg_index == 1) {
1214 /* Add the slots consumed by the first argument */
1215 LLVMArgInfo *ainfo = &cinfo->args [0];
1216 switch (ainfo->storage) {
1217 case LLVMArgVtypeInReg:
1218 for (j = 0; j < 2; ++j) {
1219 if (ainfo->pair_storage [j] == LLVMArgInIReg)
1229 sinfo->vret_arg_pindex = vret_arg_pindex;
1232 if (vretaddr && vret_arg_pindex == pindex)
1233 param_types [pindex ++] = IntPtrType ();
1236 sinfo->this_arg_pindex = pindex;
1237 param_types [pindex ++] = ThisType ();
1239 if (vretaddr && vret_arg_pindex == pindex)
1240 param_types [pindex ++] = IntPtrType ();
1241 for (i = 0; i < sig->param_count; ++i) {
1242 LLVMArgInfo *ainfo = cinfo ? &cinfo->args [i + sig->hasthis] : NULL;
1244 if (vretaddr && vret_arg_pindex == pindex)
1245 param_types [pindex ++] = IntPtrType ();
1246 pindexes [i] = pindex;
1249 param_types [pindex ++] = type_to_llvm_arg_type (ctx, sig->params [i]);
1253 switch (ainfo->storage) {
1254 case LLVMArgVtypeInReg:
1255 for (j = 0; j < 2; ++j) {
1256 switch (ainfo->pair_storage [j]) {
1258 param_types [pindex ++] = LLVMIntType (sizeof (gpointer) * 8);
1263 g_assert_not_reached ();
1267 case LLVMArgVtypeByVal:
1268 param_types [pindex] = type_to_llvm_arg_type (ctx, sig->params [i]);
1269 CHECK_FAILURE (ctx);
1270 param_types [pindex] = LLVMPointerType (param_types [pindex], 0);
1273 case LLVMArgAsIArgs:
1274 param_types [pindex] = LLVMArrayType (IntPtrType (), ainfo->nslots);
1277 case LLVMArgAsFpArgs: {
1280 for (j = 0; j < ainfo->nslots; ++j)
1281 param_types [pindex + j] = ainfo->esize == 8 ? LLVMDoubleType () : LLVMFloatType ();
1282 pindex += ainfo->nslots;
1286 param_types [pindex ++] = type_to_llvm_arg_type (ctx, sig->params [i]);
1290 if (vretaddr && vret_arg_pindex == pindex)
1291 param_types [pindex ++] = IntPtrType ();
1293 CHECK_FAILURE (ctx);
1295 res = LLVMFunctionType (ret_type, param_types, pindex, FALSE);
1296 g_free (param_types);
1299 sinfo->pindexes = pindexes;
1307 g_free (param_types);
1313 sig_to_llvm_sig (EmitContext *ctx, MonoMethodSignature *sig)
1315 return sig_to_llvm_sig_full (ctx, sig, NULL, NULL);
1319 * LLVMFunctionType1:
1321 * Create an LLVM function type from the arguments.
1323 static G_GNUC_UNUSED LLVMTypeRef
1324 LLVMFunctionType1(LLVMTypeRef ReturnType,
1325 LLVMTypeRef ParamType1,
1328 LLVMTypeRef param_types [1];
1330 param_types [0] = ParamType1;
1332 return LLVMFunctionType (ReturnType, param_types, 1, IsVarArg);
1336 * LLVMFunctionType2:
1338 * Create an LLVM function type from the arguments.
1340 static G_GNUC_UNUSED LLVMTypeRef
1341 LLVMFunctionType2(LLVMTypeRef ReturnType,
1342 LLVMTypeRef ParamType1,
1343 LLVMTypeRef ParamType2,
1346 LLVMTypeRef param_types [2];
1348 param_types [0] = ParamType1;
1349 param_types [1] = ParamType2;
1351 return LLVMFunctionType (ReturnType, param_types, 2, IsVarArg);
1355 * LLVMFunctionType3:
1357 * Create an LLVM function type from the arguments.
1359 static G_GNUC_UNUSED LLVMTypeRef
1360 LLVMFunctionType3(LLVMTypeRef ReturnType,
1361 LLVMTypeRef ParamType1,
1362 LLVMTypeRef ParamType2,
1363 LLVMTypeRef ParamType3,
1366 LLVMTypeRef param_types [3];
1368 param_types [0] = ParamType1;
1369 param_types [1] = ParamType2;
1370 param_types [2] = ParamType3;
1372 return LLVMFunctionType (ReturnType, param_types, 3, IsVarArg);
1378 * Create an LLVM builder and remember it so it can be freed later.
1380 static LLVMBuilderRef
1381 create_builder (EmitContext *ctx)
1383 LLVMBuilderRef builder = LLVMCreateBuilder ();
1385 ctx->builders = g_slist_prepend_mempool (ctx->cfg->mempool, ctx->builders, builder);
1391 get_plt_entry (EmitContext *ctx, LLVMTypeRef llvm_sig, MonoJumpInfoType type, gconstpointer data)
1393 char *callee_name = mono_aot_get_plt_symbol (type, data);
1394 LLVMValueRef callee;
1395 MonoJumpInfo *ji = NULL;
1400 if (ctx->cfg->compile_aot)
1401 /* Add a patch so referenced wrappers can be compiled in full aot mode */
1402 mono_add_patch_info (ctx->cfg, 0, type, data);
1405 callee = g_hash_table_lookup (ctx->lmodule->plt_entries, callee_name);
1407 callee = LLVMAddFunction (ctx->module, callee_name, llvm_sig);
1409 LLVMSetVisibility (callee, LLVMHiddenVisibility);
1411 g_hash_table_insert (ctx->lmodule->plt_entries, (char*)callee_name, callee);
1414 if (ctx->cfg->compile_aot) {
1415 ji = g_new0 (MonoJumpInfo, 1);
1417 ji->data.target = data;
1419 g_hash_table_insert (ctx->lmodule->plt_entries_ji, ji, callee);
1426 get_handler_clause (MonoCompile *cfg, MonoBasicBlock *bb)
1428 MonoMethodHeader *header = cfg->header;
1429 MonoExceptionClause *clause;
1433 if (bb->region != -1 && MONO_BBLOCK_IS_IN_REGION (bb, MONO_REGION_TRY))
1434 return (bb->region >> 8) - 1;
1437 for (i = 0; i < header->num_clauses; ++i) {
1438 clause = &header->clauses [i];
1440 if (MONO_OFFSET_IN_CLAUSE (clause, bb->real_offset) && clause->flags == MONO_EXCEPTION_CLAUSE_NONE)
1448 set_metadata_flag (LLVMValueRef v, const char *flag_name)
1450 LLVMValueRef md_arg;
1453 md_kind = LLVMGetMDKindID (flag_name, strlen (flag_name));
1454 md_arg = LLVMMDString ("mono", 4);
1455 LLVMSetMetadata (v, md_kind, LLVMMDNode (&md_arg, 1));
1459 set_invariant_load_flag (LLVMValueRef v)
1461 LLVMValueRef md_arg;
1463 const char *flag_name;
1465 // FIXME: Cache this
1466 flag_name = "invariant.load";
1467 md_kind = LLVMGetMDKindID (flag_name, strlen (flag_name));
1468 md_arg = LLVMMDString ("<index>", strlen ("<index>"));
1469 LLVMSetMetadata (v, md_kind, LLVMMDNode (&md_arg, 1));
1475 * Emit an LLVM call or invoke instruction depending on whenever the call is inside
1479 emit_call (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, LLVMValueRef callee, LLVMValueRef *args, int pindex)
1481 MonoCompile *cfg = ctx->cfg;
1483 LLVMBuilderRef builder = *builder_ref;
1486 clause_index = get_handler_clause (cfg, bb);
1488 if (clause_index != -1) {
1489 MonoMethodHeader *header = cfg->header;
1490 MonoExceptionClause *ec = &header->clauses [clause_index];
1491 MonoBasicBlock *tblock;
1492 LLVMBasicBlockRef ex_bb, noex_bb;
1495 * Have to use an invoke instead of a call, branching to the
1496 * handler bblock of the clause containing this bblock.
1499 g_assert (ec->flags == MONO_EXCEPTION_CLAUSE_NONE || ec->flags == MONO_EXCEPTION_CLAUSE_FINALLY);
1501 tblock = cfg->cil_offset_to_bb [ec->handler_offset];
1504 ctx->bblocks [tblock->block_num].invoke_target = TRUE;
1506 ex_bb = get_bb (ctx, tblock);
1508 noex_bb = gen_bb (ctx, "NOEX_BB");
1511 lcall = LLVMBuildInvoke (builder, callee, args, pindex, noex_bb, ex_bb, "");
1513 builder = ctx->builder = create_builder (ctx);
1514 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
1516 ctx->bblocks [bb->block_num].end_bblock = noex_bb;
1518 lcall = LLVMBuildCall (builder, callee, args, pindex, "");
1519 ctx->builder = builder;
1522 *builder_ref = ctx->builder;
1528 emit_load_general (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, int size, LLVMValueRef addr, const char *name, gboolean is_faulting, BarrierKind barrier)
1530 const char *intrins_name;
1531 LLVMValueRef args [16], res;
1532 LLVMTypeRef addr_type;
1534 if (is_faulting && bb->region != -1) {
1535 LLVMAtomicOrdering ordering;
1538 case LLVM_BARRIER_NONE:
1539 ordering = LLVMAtomicOrderingNotAtomic;
1541 case LLVM_BARRIER_ACQ:
1542 ordering = LLVMAtomicOrderingAcquire;
1544 case LLVM_BARRIER_SEQ:
1545 ordering = LLVMAtomicOrderingSequentiallyConsistent;
1548 g_assert_not_reached ();
1553 * We handle loads which can fault by calling a mono specific intrinsic
1554 * using an invoke, so they are handled properly inside try blocks.
1555 * We can't use this outside clauses, since LLVM optimizes intrinsics which
1556 * are marked with IntrReadArgMem.
1560 intrins_name = "llvm.mono.load.i8.p0i8";
1563 intrins_name = "llvm.mono.load.i16.p0i16";
1566 intrins_name = "llvm.mono.load.i32.p0i32";
1569 intrins_name = "llvm.mono.load.i64.p0i64";
1572 g_assert_not_reached ();
1575 addr_type = LLVMTypeOf (addr);
1576 if (addr_type == LLVMPointerType (LLVMDoubleType (), 0) || addr_type == LLVMPointerType (LLVMFloatType (), 0))
1577 addr = LLVMBuildBitCast (*builder_ref, addr, LLVMPointerType (LLVMIntType (size * 8), 0), "");
1580 args [1] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
1581 args [2] = LLVMConstInt (LLVMInt1Type (), TRUE, FALSE);
1582 args [3] = LLVMConstInt (LLVMInt32Type (), ordering, FALSE);
1583 res = emit_call (ctx, bb, builder_ref, LLVMGetNamedFunction (ctx->module, intrins_name), args, 4);
1585 if (addr_type == LLVMPointerType (LLVMDoubleType (), 0))
1586 res = LLVMBuildBitCast (*builder_ref, res, LLVMDoubleType (), "");
1587 else if (addr_type == LLVMPointerType (LLVMFloatType (), 0))
1588 res = LLVMBuildBitCast (*builder_ref, res, LLVMFloatType (), "");
1595 * We emit volatile loads for loads which can fault, because otherwise
1596 * LLVM will generate invalid code when encountering a load from a
1599 res = mono_llvm_build_load (*builder_ref, addr, name, is_faulting, barrier);
1601 /* Mark it with a custom metadata */
1604 set_metadata_flag (res, "mono.faulting.load");
1612 emit_load (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, int size, LLVMValueRef addr, const char *name, gboolean is_faulting)
1614 return emit_load_general (ctx, bb, builder_ref, size, addr, name, is_faulting, LLVM_BARRIER_NONE);
1618 emit_store_general (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, int size, LLVMValueRef value, LLVMValueRef addr, gboolean is_faulting, BarrierKind barrier)
1620 const char *intrins_name;
1621 LLVMValueRef args [16];
1623 if (is_faulting && bb->region != -1) {
1624 LLVMAtomicOrdering ordering;
1627 case LLVM_BARRIER_NONE:
1628 ordering = LLVMAtomicOrderingNotAtomic;
1630 case LLVM_BARRIER_REL:
1631 ordering = LLVMAtomicOrderingRelease;
1633 case LLVM_BARRIER_SEQ:
1634 ordering = LLVMAtomicOrderingSequentiallyConsistent;
1637 g_assert_not_reached ();
1643 intrins_name = "llvm.mono.store.i8.p0i8";
1646 intrins_name = "llvm.mono.store.i16.p0i16";
1649 intrins_name = "llvm.mono.store.i32.p0i32";
1652 intrins_name = "llvm.mono.store.i64.p0i64";
1655 g_assert_not_reached ();
1658 if (LLVMTypeOf (value) == LLVMDoubleType () || LLVMTypeOf (value) == LLVMFloatType ()) {
1659 value = LLVMBuildBitCast (*builder_ref, value, LLVMIntType (size * 8), "");
1660 addr = LLVMBuildBitCast (*builder_ref, addr, LLVMPointerType (LLVMIntType (size * 8), 0), "");
1665 args [2] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
1666 args [3] = LLVMConstInt (LLVMInt1Type (), TRUE, FALSE);
1667 args [4] = LLVMConstInt (LLVMInt32Type (), ordering, FALSE);
1668 emit_call (ctx, bb, builder_ref, LLVMGetNamedFunction (ctx->module, intrins_name), args, 5);
1670 mono_llvm_build_store (*builder_ref, value, addr, is_faulting, barrier);
1675 emit_store (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, int size, LLVMValueRef value, LLVMValueRef addr, gboolean is_faulting)
1677 emit_store_general (ctx, bb, builder_ref, size, value, addr, is_faulting, LLVM_BARRIER_NONE);
1681 * emit_cond_system_exception:
1683 * Emit code to throw the exception EXC_TYPE if the condition CMP is false.
1684 * Might set the ctx exception.
1687 emit_cond_system_exception (EmitContext *ctx, MonoBasicBlock *bb, const char *exc_type, LLVMValueRef cmp)
1689 LLVMBasicBlockRef ex_bb, noex_bb;
1690 LLVMBuilderRef builder;
1691 MonoClass *exc_class;
1692 LLVMValueRef args [2];
1694 ex_bb = gen_bb (ctx, "EX_BB");
1695 noex_bb = gen_bb (ctx, "NOEX_BB");
1697 LLVMBuildCondBr (ctx->builder, cmp, ex_bb, noex_bb);
1699 exc_class = mono_class_from_name (mono_get_corlib (), "System", exc_type);
1700 g_assert (exc_class);
1702 /* Emit exception throwing code */
1703 builder = create_builder (ctx);
1704 LLVMPositionBuilderAtEnd (builder, ex_bb);
1706 if (!ctx->lmodule->throw_corlib_exception) {
1707 LLVMValueRef callee;
1709 const char *icall_name;
1711 MonoMethodSignature *throw_sig = mono_metadata_signature_alloc (mono_get_corlib (), 2);
1712 throw_sig->ret = &mono_get_void_class ()->byval_arg;
1713 throw_sig->params [0] = &mono_get_int32_class ()->byval_arg;
1714 icall_name = "llvm_throw_corlib_exception_abs_trampoline";
1715 /* This will become i8* */
1716 throw_sig->params [1] = &mono_get_byte_class ()->this_arg;
1717 sig = sig_to_llvm_sig (ctx, throw_sig);
1719 if (ctx->cfg->compile_aot) {
1720 callee = get_plt_entry (ctx, sig, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
1722 callee = LLVMAddFunction (ctx->module, "llvm_throw_corlib_exception_trampoline", sig_to_llvm_sig (ctx, throw_sig));
1725 * Differences between the LLVM/non-LLVM throw corlib exception trampoline:
1726 * - On x86, LLVM generated code doesn't push the arguments
1727 * - The trampoline takes the throw address as an arguments, not a pc offset.
1729 LLVMAddGlobalMapping (ctx->lmodule->ee, callee, resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name));
1732 mono_memory_barrier ();
1733 ctx->lmodule->throw_corlib_exception = callee;
1736 if (IS_TARGET_X86 || IS_TARGET_AMD64)
1737 args [0] = LLVMConstInt (LLVMInt32Type (), exc_class->type_token - MONO_TOKEN_TYPE_DEF, FALSE);
1739 args [0] = LLVMConstInt (LLVMInt32Type (), exc_class->type_token, FALSE);
1742 * The LLVM mono branch contains changes so a block address can be passed as an
1743 * argument to a call.
1745 args [1] = LLVMBlockAddress (ctx->lmethod, ex_bb);
1746 emit_call (ctx, bb, &builder, ctx->lmodule->throw_corlib_exception, args, 2);
1748 LLVMBuildUnreachable (builder);
1750 ctx->builder = create_builder (ctx);
1751 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
1753 ctx->bblocks [bb->block_num].end_bblock = noex_bb;
1760 * emit_args_to_vtype:
1762 * Emit code to store the vtype in the arguments args to the address ADDRESS.
1765 emit_args_to_vtype (EmitContext *ctx, LLVMBuilderRef builder, MonoType *t, LLVMValueRef address, LLVMArgInfo *ainfo, LLVMValueRef *args)
1767 int j, size, nslots;
1769 size = get_vtype_size (t);
1771 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (t))) {
1772 address = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (LLVMInt8Type (), 0), "");
1775 if (ainfo->storage == LLVMArgAsFpArgs)
1776 nslots = ainfo->nslots;
1780 for (j = 0; j < nslots; ++j) {
1781 LLVMValueRef index [2], addr, daddr;
1782 int part_size = size > sizeof (gpointer) ? sizeof (gpointer) : size;
1783 LLVMTypeRef part_type;
1785 if (ainfo->pair_storage [j] == LLVMArgNone)
1788 switch (ainfo->pair_storage [j]) {
1789 case LLVMArgInIReg: {
1790 part_type = LLVMIntType (part_size * 8);
1791 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (t))) {
1792 index [0] = LLVMConstInt (LLVMInt32Type (), j * sizeof (gpointer), FALSE);
1793 addr = LLVMBuildGEP (builder, address, index, 1, "");
1795 daddr = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (IntPtrType (), 0), "");
1796 index [0] = LLVMConstInt (LLVMInt32Type (), j, FALSE);
1797 addr = LLVMBuildGEP (builder, daddr, index, 1, "");
1799 LLVMBuildStore (builder, convert (ctx, args [j], part_type), LLVMBuildBitCast (ctx->builder, addr, LLVMPointerType (part_type, 0), ""));
1802 case LLVMArgInFPReg: {
1803 LLVMTypeRef arg_type;
1805 if (ainfo->esize == 8)
1806 arg_type = LLVMDoubleType ();
1808 arg_type = LLVMFloatType ();
1810 index [0] = LLVMConstInt (LLVMInt32Type (), j, FALSE);
1811 daddr = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (arg_type, 0), "");
1812 addr = LLVMBuildGEP (builder, daddr, index, 1, "");
1813 LLVMBuildStore (builder, args [j], addr);
1819 g_assert_not_reached ();
1822 size -= sizeof (gpointer);
1827 * emit_vtype_to_args:
1829 * Emit code to load a vtype at address ADDRESS into scalar arguments. Store the arguments
1830 * into ARGS, and the number of arguments into NARGS.
1833 emit_vtype_to_args (EmitContext *ctx, LLVMBuilderRef builder, MonoType *t, LLVMValueRef address, LLVMArgInfo *ainfo, LLVMValueRef *args, guint32 *nargs)
1836 int j, size, nslots;
1837 LLVMTypeRef arg_type;
1839 size = get_vtype_size (t);
1841 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (t)))
1842 address = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (LLVMInt8Type (), 0), "");
1844 if (ainfo->storage == LLVMArgAsFpArgs)
1845 nslots = ainfo->nslots;
1848 for (j = 0; j < nslots; ++j) {
1849 LLVMValueRef index [2], addr, daddr;
1850 int partsize = size > sizeof (gpointer) ? sizeof (gpointer) : size;
1852 if (ainfo->pair_storage [j] == LLVMArgNone)
1855 switch (ainfo->pair_storage [j]) {
1857 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (t))) {
1858 index [0] = LLVMConstInt (LLVMInt32Type (), j * sizeof (gpointer), FALSE);
1859 addr = LLVMBuildGEP (builder, address, index, 1, "");
1861 daddr = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (IntPtrType (), 0), "");
1862 index [0] = LLVMConstInt (LLVMInt32Type (), j, FALSE);
1863 addr = LLVMBuildGEP (builder, daddr, index, 1, "");
1865 args [pindex ++] = convert (ctx, LLVMBuildLoad (builder, LLVMBuildBitCast (ctx->builder, addr, LLVMPointerType (LLVMIntType (partsize * 8), 0), ""), ""), IntPtrType ());
1867 case LLVMArgInFPReg:
1868 if (ainfo->esize == 8)
1869 arg_type = LLVMDoubleType ();
1871 arg_type = LLVMFloatType ();
1872 daddr = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (arg_type, 0), "");
1873 index [0] = LLVMConstInt (LLVMInt32Type (), j, FALSE);
1874 addr = LLVMBuildGEP (builder, daddr, index, 1, "");
1875 args [pindex ++] = LLVMBuildLoad (builder, addr, "");
1880 g_assert_not_reached ();
1882 size -= sizeof (gpointer);
1889 build_alloca_llvm_type (EmitContext *ctx, LLVMTypeRef t, int align)
1892 * Have to place all alloca's at the end of the entry bb, since otherwise they would
1893 * get executed every time control reaches them.
1895 LLVMPositionBuilder (ctx->alloca_builder, get_bb (ctx, ctx->cfg->bb_entry), ctx->last_alloca);
1897 ctx->last_alloca = mono_llvm_build_alloca (ctx->alloca_builder, t, NULL, align, "");
1898 return ctx->last_alloca;
1902 build_alloca (EmitContext *ctx, MonoType *t)
1904 MonoClass *k = mono_class_from_mono_type (t);
1907 if (MONO_CLASS_IS_SIMD (ctx->cfg, k))
1910 align = mono_class_min_align (k);
1912 /* Sometimes align is not a power of 2 */
1913 while (mono_is_power_of_two (align) == -1)
1916 return build_alloca_llvm_type (ctx, type_to_llvm_type (ctx, t), align);
1920 * Put the global into the 'llvm.used' array to prevent it from being optimized away.
1923 mark_as_used (MonoLLVMModule *lmodule, LLVMValueRef global)
1926 lmodule->used = g_ptr_array_sized_new (16);
1927 g_ptr_array_add (lmodule->used, global);
1931 emit_llvm_used (MonoLLVMModule *lmodule)
1933 LLVMModuleRef module = lmodule->module;
1934 LLVMTypeRef used_type;
1935 LLVMValueRef used, *used_elem;
1941 used_type = LLVMArrayType (LLVMPointerType (LLVMInt8Type (), 0), lmodule->used->len);
1942 used = LLVMAddGlobal (module, used_type, "llvm.used");
1943 used_elem = g_new0 (LLVMValueRef, lmodule->used->len);
1944 for (i = 0; i < lmodule->used->len; ++i)
1945 used_elem [i] = LLVMConstBitCast (g_ptr_array_index (lmodule->used, i), LLVMPointerType (LLVMInt8Type (), 0));
1946 LLVMSetInitializer (used, LLVMConstArray (LLVMPointerType (LLVMInt8Type (), 0), used_elem, lmodule->used->len));
1947 LLVMSetLinkage (used, LLVMAppendingLinkage);
1948 LLVMSetSection (used, "llvm.metadata");
1952 emit_div_check (EmitContext *ctx, LLVMBuilderRef builder, MonoBasicBlock *bb, MonoInst *ins, LLVMValueRef lhs, LLVMValueRef rhs)
1954 gboolean need_div_check = FALSE;
1956 #ifdef MONO_ARCH_NEED_DIV_CHECK
1957 need_div_check = TRUE;
1960 /* LLVM doesn't know that these can throw an exception since they are not called through an intrinsic */
1961 need_div_check = TRUE;
1963 if (!need_div_check)
1966 switch (ins->opcode) {
1979 case OP_IDIV_UN_IMM:
1980 case OP_LDIV_UN_IMM:
1981 case OP_IREM_UN_IMM:
1982 case OP_LREM_UN_IMM: {
1984 gboolean is_signed = (ins->opcode == OP_IDIV || ins->opcode == OP_LDIV || ins->opcode == OP_IREM || ins->opcode == OP_LREM ||
1985 ins->opcode == OP_IDIV_IMM || ins->opcode == OP_LDIV_IMM || ins->opcode == OP_IREM_IMM || ins->opcode == OP_LREM_IMM);
1987 cmp = LLVMBuildICmp (builder, LLVMIntEQ, rhs, LLVMConstInt (LLVMTypeOf (rhs), 0, FALSE), "");
1988 emit_cond_system_exception (ctx, bb, "DivideByZeroException", cmp);
1989 CHECK_FAILURE (ctx);
1990 builder = ctx->builder;
1992 /* b == -1 && a == 0x80000000 */
1994 LLVMValueRef c = (LLVMTypeOf (lhs) == LLVMInt32Type ()) ? LLVMConstInt (LLVMTypeOf (lhs), 0x80000000, FALSE) : LLVMConstInt (LLVMTypeOf (lhs), 0x8000000000000000LL, FALSE);
1995 LLVMValueRef cond1 = LLVMBuildICmp (builder, LLVMIntEQ, rhs, LLVMConstInt (LLVMTypeOf (rhs), -1, FALSE), "");
1996 LLVMValueRef cond2 = LLVMBuildICmp (builder, LLVMIntEQ, lhs, c, "");
1998 cmp = LLVMBuildICmp (builder, LLVMIntEQ, LLVMBuildAnd (builder, cond1, cond2, ""), LLVMConstInt (LLVMInt1Type (), 1, FALSE), "");
1999 emit_cond_system_exception (ctx, bb, "OverflowException", cmp);
2000 CHECK_FAILURE (ctx);
2001 builder = ctx->builder;
2016 * Emit code to load/convert arguments.
2019 emit_entry_bb (EmitContext *ctx, LLVMBuilderRef builder)
2022 MonoCompile *cfg = ctx->cfg;
2023 MonoMethodSignature *sig = ctx->sig;
2024 LLVMCallInfo *linfo = ctx->linfo;
2027 ctx->alloca_builder = create_builder (ctx);
2030 * Handle indirect/volatile variables by allocating memory for them
2031 * using 'alloca', and storing their address in a temporary.
2033 for (i = 0; i < cfg->num_varinfo; ++i) {
2034 MonoInst *var = cfg->varinfo [i];
2037 if (var->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT) || mini_type_is_vtype (cfg, var->inst_vtype)) {
2038 vtype = type_to_llvm_type (ctx, var->inst_vtype);
2039 CHECK_FAILURE (ctx);
2040 /* Could be already created by an OP_VPHI */
2041 if (!ctx->addresses [var->dreg])
2042 ctx->addresses [var->dreg] = build_alloca (ctx, var->inst_vtype);
2043 ctx->vreg_cli_types [var->dreg] = var->inst_vtype;
2047 for (i = 0; i < sig->param_count; ++i) {
2048 LLVMArgInfo *ainfo = &linfo->args [i + sig->hasthis];
2049 int reg = cfg->args [i + sig->hasthis]->dreg;
2051 switch (ainfo->storage) {
2052 case LLVMArgVtypeInReg:
2053 case LLVMArgAsFpArgs: {
2054 LLVMValueRef args [8];
2057 /* The argument is received as a set of int/fp arguments, store them into the real argument */
2058 memset (args, 0, sizeof (args));
2059 pindex = ctx->pindexes [i];
2060 if (ainfo->storage == LLVMArgVtypeInReg) {
2061 args [0] = LLVMGetParam (ctx->lmethod, pindex);
2062 if (ainfo->pair_storage [1] != LLVMArgNone)
2063 args [1] = LLVMGetParam (ctx->lmethod, pindex + 1);
2065 g_assert (ainfo->nslots <= 8);
2066 for (j = 0; j < ainfo->nslots; ++j)
2067 args [j] = LLVMGetParam (ctx->lmethod, ctx->pindexes [i] + j);
2069 ctx->addresses [reg] = build_alloca (ctx, sig->params [i]);
2071 emit_args_to_vtype (ctx, builder, sig->params [i], ctx->addresses [reg], ainfo, args);
2073 if (ainfo->storage == LLVMArgVtypeInReg && MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (sig->params [i]))) {
2074 /* Treat these as normal values */
2075 ctx->values [reg] = LLVMBuildLoad (builder, ctx->addresses [reg], "");
2079 case LLVMArgVtypeByVal: {
2080 ctx->addresses [reg] = LLVMGetParam (ctx->lmethod, ctx->pindexes [i]);
2082 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (sig->params [i]))) {
2083 /* Treat these as normal values */
2084 ctx->values [reg] = LLVMBuildLoad (builder, ctx->addresses [reg], "");
2088 case LLVMArgAsIArgs: {
2089 LLVMValueRef arg = LLVMGetParam (ctx->lmethod, ctx->pindexes [i]);
2091 ctx->addresses [reg] = build_alloca (ctx, sig->params [i]);
2093 /* The argument is received as an array of ints, store it into the real argument */
2094 LLVMBuildStore (ctx->builder, arg, convert (ctx, ctx->addresses [reg], LLVMPointerType (LLVMTypeOf (arg), 0)));
2098 ctx->values [reg] = convert_full (ctx, ctx->values [reg], llvm_type_to_stack_type (cfg, type_to_llvm_type (ctx, sig->params [i])), type_is_unsigned (ctx, sig->params [i]));
2104 emit_volatile_store (ctx, cfg->vret_addr->dreg);
2106 emit_volatile_store (ctx, cfg->args [0]->dreg);
2107 for (i = 0; i < sig->param_count; ++i)
2108 if (!mini_type_is_vtype (cfg, sig->params [i]))
2109 emit_volatile_store (ctx, cfg->args [i + sig->hasthis]->dreg);
2111 if (sig->hasthis && !cfg->rgctx_var && cfg->generic_sharing_context) {
2112 LLVMValueRef this_alloc;
2115 * The exception handling code needs the location where the this argument was
2116 * stored for gshared methods. We create a separate alloca to hold it, and mark it
2117 * with the "mono.this" custom metadata to tell llvm that it needs to save its
2118 * location into the LSDA.
2120 this_alloc = mono_llvm_build_alloca (builder, ThisType (), LLVMConstInt (LLVMInt32Type (), 1, FALSE), 0, "");
2121 /* This volatile store will keep the alloca alive */
2122 mono_llvm_build_store (builder, ctx->values [cfg->args [0]->dreg], this_alloc, TRUE, LLVM_BARRIER_NONE);
2124 set_metadata_flag (this_alloc, "mono.this");
2127 if (cfg->rgctx_var) {
2128 LLVMValueRef rgctx_alloc, store;
2131 * We handle the rgctx arg similarly to the this pointer.
2133 g_assert (ctx->addresses [cfg->rgctx_var->dreg]);
2134 rgctx_alloc = ctx->addresses [cfg->rgctx_var->dreg];
2135 /* This volatile store will keep the alloca alive */
2136 store = mono_llvm_build_store (builder, convert (ctx, ctx->rgctx_arg, IntPtrType ()), rgctx_alloc, TRUE, LLVM_BARRIER_NONE);
2138 set_metadata_flag (rgctx_alloc, "mono.this");
2141 /* Compute nesting between clauses */
2142 ctx->nested_in = mono_mempool_alloc0 (cfg->mempool, sizeof (GSList*) * cfg->header->num_clauses);
2143 for (i = 0; i < cfg->header->num_clauses; ++i) {
2144 for (j = 0; j < cfg->header->num_clauses; ++j) {
2145 MonoExceptionClause *clause1 = &cfg->header->clauses [i];
2146 MonoExceptionClause *clause2 = &cfg->header->clauses [j];
2148 if (i != j && clause1->try_offset >= clause2->try_offset && clause1->handler_offset <= clause2->handler_offset)
2149 ctx->nested_in [i] = g_slist_prepend_mempool (cfg->mempool, ctx->nested_in [i], GINT_TO_POINTER (j));
2154 * For finally clauses, create an indicator variable telling OP_ENDFINALLY whenever
2155 * it needs to continue normally, or return back to the exception handling system.
2157 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
2161 if (!(bb->region != -1 && (bb->flags & BB_EXCEPTION_HANDLER)))
2164 clause_index = MONO_REGION_CLAUSE_INDEX (bb->region);
2165 g_hash_table_insert (ctx->region_to_handler, GUINT_TO_POINTER (mono_get_block_region_notry (cfg, bb->region)), bb);
2166 g_hash_table_insert (ctx->clause_to_handler, GINT_TO_POINTER (clause_index), bb);
2168 if (bb->in_scount == 0) {
2171 sprintf (name, "finally_ind_bb%d", bb->block_num);
2172 val = LLVMBuildAlloca (builder, LLVMInt32Type (), name);
2173 LLVMBuildStore (builder, LLVMConstInt (LLVMInt32Type (), 0, FALSE), val);
2175 ctx->bblocks [bb->block_num].finally_ind = val;
2177 /* Create a variable to hold the exception var */
2179 ctx->ex_var = LLVMBuildAlloca (builder, ObjRefType (), "exvar");
2183 * Create a new bblock which CALL_HANDLER/landing pads can branch to, because branching to the
2184 * LLVM bblock containing a landing pad causes problems for the
2185 * LLVM optimizer passes.
2187 sprintf (name, "BB_%d_CALL_HANDLER_TARGET", bb->block_num);
2188 ctx->bblocks [bb->block_num].call_handler_target_bb = LLVMAppendBasicBlock (ctx->lmethod, name);
2195 /* Have to export this for AOT */
2197 mono_personality (void)
2200 g_assert_not_reached ();
2204 process_call (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, MonoInst *ins)
2206 MonoCompile *cfg = ctx->cfg;
2207 LLVMModuleRef module = ctx->module;
2208 LLVMValueRef *values = ctx->values;
2209 LLVMValueRef *addresses = ctx->addresses;
2210 MonoCallInst *call = (MonoCallInst*)ins;
2211 MonoMethodSignature *sig = call->signature;
2212 LLVMValueRef callee = NULL, lcall;
2214 LLVMCallInfo *cinfo;
2218 LLVMTypeRef llvm_sig;
2220 gboolean virtual, calli;
2221 LLVMBuilderRef builder = *builder_ref;
2224 if (call->signature->call_convention != MONO_CALL_DEFAULT)
2225 LLVM_FAILURE (ctx, "non-default callconv");
2227 cinfo = call->cinfo;
2228 if (call->rgctx_arg_reg)
2229 cinfo->rgctx_arg = TRUE;
2230 if (call->imt_arg_reg)
2231 cinfo->imt_arg = TRUE;
2233 vretaddr = cinfo && cinfo->ret.storage == LLVMArgVtypeRetAddr;
2235 llvm_sig = sig_to_llvm_sig_full (ctx, sig, cinfo, &sinfo);
2236 CHECK_FAILURE (ctx);
2238 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 || ins->opcode == OP_RCALL_MEMBASE);
2239 calli = !call->fptr_is_patch && (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 || ins->opcode == OP_RCALL_REG);
2241 /* FIXME: Avoid creating duplicate methods */
2243 if (ins->flags & MONO_INST_HAS_METHOD) {
2247 if (cfg->compile_aot) {
2248 callee = get_plt_entry (ctx, llvm_sig, MONO_PATCH_INFO_METHOD, call->method);
2250 LLVM_FAILURE (ctx, "can't encode patch");
2252 callee = LLVMAddFunction (module, "", llvm_sig);
2255 mono_create_jit_trampoline_in_domain (mono_domain_get (),
2257 LLVMAddGlobalMapping (ctx->lmodule->ee, callee, target);
2261 if (call->method && strstr (call->method->klass->name, "AsyncVoidMethodBuilder"))
2262 /* LLVM miscompiles async methods */
2263 LLVM_FAILURE (ctx, "#13734");
2266 MonoJitICallInfo *info = mono_find_jit_icall_by_addr (call->fptr);
2272 memset (&ji, 0, sizeof (ji));
2273 ji.type = MONO_PATCH_INFO_JIT_ICALL_ADDR;
2274 ji.data.target = info->name;
2276 target = mono_resolve_patch_target (cfg->method, cfg->domain, NULL, &ji, FALSE);
2278 if (cfg->compile_aot) {
2279 callee = get_plt_entry (ctx, llvm_sig, MONO_PATCH_INFO_INTERNAL_METHOD, (char*)info->name);
2281 LLVM_FAILURE (ctx, "can't encode patch");
2283 callee = LLVMAddFunction (module, "", llvm_sig);
2284 target = (gpointer)mono_icall_get_wrapper (info);
2285 LLVMAddGlobalMapping (ctx->lmodule->ee, callee, target);
2288 if (cfg->compile_aot) {
2290 if (cfg->abs_patches) {
2291 MonoJumpInfo *abs_ji = g_hash_table_lookup (cfg->abs_patches, call->fptr);
2293 callee = get_plt_entry (ctx, llvm_sig, abs_ji->type, abs_ji->data.target);
2295 LLVM_FAILURE (ctx, "can't encode patch");
2299 LLVM_FAILURE (ctx, "aot");
2301 callee = LLVMAddFunction (module, "", llvm_sig);
2303 if (cfg->abs_patches) {
2304 MonoJumpInfo *abs_ji = g_hash_table_lookup (cfg->abs_patches, call->fptr);
2307 * FIXME: Some trampolines might have
2308 * their own calling convention on some platforms.
2310 #ifndef TARGET_AMD64
2311 if (abs_ji->type == MONO_PATCH_INFO_MONITOR_ENTER || abs_ji->type == MONO_PATCH_INFO_MONITOR_ENTER_V4 ||
2312 abs_ji->type == MONO_PATCH_INFO_MONITOR_EXIT || abs_ji->type == MONO_PATCH_INFO_GENERIC_CLASS_INIT)
2313 LLVM_FAILURE (ctx, "trampoline with own cconv");
2315 target = mono_resolve_patch_target (cfg->method, cfg->domain, NULL, abs_ji, FALSE);
2316 LLVMAddGlobalMapping (ctx->lmodule->ee, callee, target);
2320 LLVMAddGlobalMapping (ctx->lmodule->ee, callee, (gpointer)call->fptr);
2326 int size = sizeof (gpointer);
2329 g_assert (ins->inst_offset % size == 0);
2330 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
2332 callee = convert (ctx, LLVMBuildLoad (builder, LLVMBuildGEP (builder, convert (ctx, values [ins->inst_basereg], LLVMPointerType (LLVMPointerType (IntPtrType (), 0), 0)), &index, 1, ""), ""), LLVMPointerType (llvm_sig, 0));
2334 callee = convert (ctx, values [ins->sreg1], LLVMPointerType (llvm_sig, 0));
2336 if (ins->flags & MONO_INST_HAS_METHOD) {
2341 * Collect and convert arguments
2343 nargs = (sig->param_count * 16) + sig->hasthis + vretaddr + call->rgctx_reg + call->imt_arg_reg;
2344 len = sizeof (LLVMValueRef) * nargs;
2345 args = alloca (len);
2346 memset (args, 0, len);
2347 l = call->out_ireg_args;
2349 if (call->rgctx_arg_reg) {
2350 g_assert (values [call->rgctx_arg_reg]);
2351 g_assert (sinfo.rgctx_arg_pindex < nargs);
2353 * On ARM, the imt/rgctx argument is passed in a caller save register, but some of our trampolines etc. clobber it, leading to
2354 * problems is LLVM moves the arg assignment earlier. To work around this, save the argument into a stack slot and load
2355 * it using a volatile load.
2358 if (!ctx->imt_rgctx_loc)
2359 ctx->imt_rgctx_loc = build_alloca_llvm_type (ctx, ctx->lmodule->ptr_type, sizeof (gpointer));
2360 LLVMBuildStore (builder, convert (ctx, ctx->values [call->rgctx_arg_reg], ctx->lmodule->ptr_type), ctx->imt_rgctx_loc);
2361 args [sinfo.rgctx_arg_pindex] = mono_llvm_build_load (builder, ctx->imt_rgctx_loc, "", TRUE, LLVM_BARRIER_NONE);
2363 args [sinfo.rgctx_arg_pindex] = convert (ctx, values [call->rgctx_arg_reg], ctx->lmodule->ptr_type);
2366 if (call->imt_arg_reg) {
2367 g_assert (values [call->imt_arg_reg]);
2368 g_assert (sinfo.imt_arg_pindex < nargs);
2370 if (!ctx->imt_rgctx_loc)
2371 ctx->imt_rgctx_loc = build_alloca_llvm_type (ctx, ctx->lmodule->ptr_type, sizeof (gpointer));
2372 LLVMBuildStore (builder, convert (ctx, ctx->values [call->imt_arg_reg], ctx->lmodule->ptr_type), ctx->imt_rgctx_loc);
2373 args [sinfo.imt_arg_pindex] = mono_llvm_build_load (builder, ctx->imt_rgctx_loc, "", TRUE, LLVM_BARRIER_NONE);
2375 args [sinfo.imt_arg_pindex] = convert (ctx, values [call->imt_arg_reg], ctx->lmodule->ptr_type);
2380 if (!addresses [call->inst.dreg])
2381 addresses [call->inst.dreg] = build_alloca (ctx, sig->ret);
2382 g_assert (sinfo.vret_arg_pindex < nargs);
2383 args [sinfo.vret_arg_pindex] = LLVMBuildPtrToInt (builder, addresses [call->inst.dreg], IntPtrType (), "");
2386 for (i = 0; i < sig->param_count + sig->hasthis; ++i) {
2389 LLVMArgInfo *ainfo = call->cinfo ? &call->cinfo->args [i] : NULL;
2393 pindex = sinfo.this_arg_pindex;
2395 pindex = sinfo.pindexes [i - 1];
2397 pindex = sinfo.pindexes [i];
2400 regpair = (guint32)(gssize)(l->data);
2401 reg = regpair & 0xffffff;
2402 args [pindex] = values [reg];
2403 switch (ainfo->storage) {
2404 case LLVMArgVtypeInReg:
2405 case LLVMArgAsFpArgs: {
2408 g_assert (addresses [reg]);
2409 emit_vtype_to_args (ctx, builder, sig->params [i - sig->hasthis], addresses [reg], ainfo, args + pindex, &nargs);
2413 // FIXME: Get rid of the VMOVE
2416 case LLVMArgVtypeByVal:
2417 g_assert (addresses [reg]);
2418 args [pindex] = addresses [reg];
2420 case LLVMArgAsIArgs:
2421 g_assert (addresses [reg]);
2422 args [pindex] = LLVMBuildLoad (ctx->builder, convert (ctx, addresses [reg], LLVMPointerType (LLVMArrayType (IntPtrType (), ainfo->nslots), 0)), "");
2425 g_assert (args [pindex]);
2426 if (i == 0 && sig->hasthis)
2427 args [pindex] = convert (ctx, args [pindex], ThisType ());
2429 args [pindex] = convert (ctx, args [pindex], type_to_llvm_arg_type (ctx, sig->params [i - sig->hasthis]));
2432 g_assert (pindex <= nargs);
2437 // FIXME: Align call sites
2443 lcall = emit_call (ctx, bb, &builder, callee, args, LLVMCountParamTypes (llvm_sig));
2446 * Modify cconv and parameter attributes to pass rgctx/imt correctly.
2448 #if defined(MONO_ARCH_IMT_REG) && defined(MONO_ARCH_RGCTX_REG)
2449 g_assert (MONO_ARCH_IMT_REG == MONO_ARCH_RGCTX_REG);
2451 /* The two can't be used together, so use only one LLVM calling conv to pass them */
2452 g_assert (!(call->rgctx_arg_reg && call->imt_arg_reg));
2454 LLVMSetInstructionCallConv (lcall, LLVMMono1CallConv);
2456 if (call->rgctx_arg_reg)
2457 LLVMAddInstrAttribute (lcall, 1 + sinfo.rgctx_arg_pindex, LLVMInRegAttribute);
2458 if (call->imt_arg_reg)
2459 LLVMAddInstrAttribute (lcall, 1 + sinfo.imt_arg_pindex, LLVMInRegAttribute);
2461 /* Add byval attributes if needed */
2462 for (i = 0; i < sig->param_count; ++i) {
2463 LLVMArgInfo *ainfo = call->cinfo ? &call->cinfo->args [i + sig->hasthis] : NULL;
2465 if (ainfo && ainfo->storage == LLVMArgVtypeByVal) {
2466 LLVMAddInstrAttribute (lcall, 1 + sinfo.pindexes [i], LLVMByValAttribute);
2471 * Convert the result
2474 switch (cinfo->ret.storage) {
2475 case LLVMArgVtypeInReg: {
2476 LLVMValueRef regs [2];
2478 if (!addresses [ins->dreg])
2479 addresses [ins->dreg] = build_alloca (ctx, sig->ret);
2481 regs [0] = LLVMBuildExtractValue (builder, lcall, 0, "");
2482 if (cinfo->ret.pair_storage [1] != LLVMArgNone)
2483 regs [1] = LLVMBuildExtractValue (builder, lcall, 1, "");
2484 emit_args_to_vtype (ctx, builder, sig->ret, addresses [ins->dreg], &cinfo->ret, regs);
2487 case LLVMArgVtypeByVal:
2488 if (!addresses [call->inst.dreg])
2489 addresses [call->inst.dreg] = build_alloca (ctx, sig->ret);
2490 LLVMBuildStore (builder, lcall, addresses [call->inst.dreg]);
2492 case LLVMArgFpStruct:
2493 if (!addresses [call->inst.dreg])
2494 addresses [call->inst.dreg] = build_alloca (ctx, sig->ret);
2495 LLVMBuildStore (builder, lcall, convert_full (ctx, addresses [call->inst.dreg], LLVMPointerType (LLVMTypeOf (lcall), 0), FALSE));
2498 if (sig->ret->type != MONO_TYPE_VOID && !vretaddr)
2499 /* If the method returns an unsigned value, need to zext it */
2500 values [ins->dreg] = convert_full (ctx, lcall, llvm_type_to_stack_type (cfg, type_to_llvm_type (ctx, sig->ret)), type_is_unsigned (ctx, sig->ret));
2504 if (sig->ret->type != MONO_TYPE_VOID && !vretaddr)
2505 /* If the method returns an unsigned value, need to zext it */
2506 values [ins->dreg] = convert_full (ctx, lcall, llvm_type_to_stack_type (cfg, type_to_llvm_type (ctx, sig->ret)), type_is_unsigned (ctx, sig->ret));
2510 if (!addresses [call->inst.dreg])
2511 addresses [call->inst.dreg] = build_alloca (ctx, sig->ret);
2512 g_assert (sinfo.vret_arg_pindex < nargs);
2513 args [sinfo.vret_arg_pindex] = LLVMBuildPtrToInt (builder, addresses [call->inst.dreg], IntPtrType (), "");
2516 *builder_ref = ctx->builder;
2518 g_free (sinfo.pindexes);
2526 emit_handler_start (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef builder)
2528 MonoCompile *cfg = ctx->cfg;
2529 LLVMValueRef *values = ctx->values;
2530 LLVMModuleRef module = ctx->module;
2531 BBInfo *bblocks = ctx->bblocks;
2533 LLVMValueRef personality;
2534 LLVMValueRef landing_pad;
2535 LLVMBasicBlockRef target_bb;
2537 static gint32 mapping_inited;
2538 static int ti_generator;
2541 LLVMValueRef type_info;
2545 // <resultval> = landingpad <somety> personality <type> <pers_fn> <clause>+
2547 if (cfg->compile_aot) {
2548 /* Use a dummy personality function */
2549 personality = LLVMGetNamedFunction (module, "mono_aot_personality");
2550 g_assert (personality);
2552 personality = LLVMGetNamedFunction (module, "mono_personality");
2553 if (InterlockedCompareExchange (&mapping_inited, 1, 0) == 0)
2554 LLVMAddGlobalMapping (ctx->lmodule->ee, personality, mono_personality);
2557 i8ptr = LLVMPointerType (LLVMInt8Type (), 0);
2559 clause_index = (mono_get_block_region_notry (cfg, bb->region) >> 8) - 1;
2562 * Create the type info
2564 sprintf (ti_name, "type_info_%d", ti_generator);
2567 if (cfg->compile_aot) {
2568 /* decode_eh_frame () in aot-runtime.c will decode this */
2569 type_info = LLVMAddGlobal (module, LLVMInt32Type (), ti_name);
2570 LLVMSetInitializer (type_info, LLVMConstInt (LLVMInt32Type (), clause_index, FALSE));
2573 * These symbols are not really used, the clause_index is embedded into the EH tables generated by DwarfMonoException in LLVM.
2575 LLVMSetLinkage (type_info, LLVMInternalLinkage);
2578 // test_0_invalid_unbox_arrays () fails
2579 LLVM_FAILURE (ctx, "aot+clauses");
2583 * After the cfg mempool is freed, the type info will point to stale memory,
2584 * but this is not a problem, since we decode it once in exception_cb during
2587 ti = mono_mempool_alloc (cfg->mempool, sizeof (gint32));
2588 *(gint32*)ti = clause_index;
2590 type_info = LLVMAddGlobal (module, i8ptr, ti_name);
2592 LLVMAddGlobalMapping (ctx->lmodule->ee, type_info, ti);
2596 LLVMTypeRef members [2], ret_type;
2598 members [0] = i8ptr;
2599 members [1] = LLVMInt32Type ();
2600 ret_type = LLVMStructType (members, 2, FALSE);
2602 landing_pad = LLVMBuildLandingPad (builder, ret_type, personality, 1, "");
2603 LLVMAddClause (landing_pad, type_info);
2605 /* Store the exception into the exvar */
2607 LLVMBuildStore (builder, convert (ctx, LLVMBuildExtractValue (builder, landing_pad, 0, "ex_obj"), ObjRefType ()), ctx->ex_var);
2611 * LLVM throw sites are associated with a one landing pad, and LLVM generated
2612 * code expects control to be transferred to this landing pad even in the
2613 * presence of nested clauses. The landing pad needs to branch to the landing
2614 * pads belonging to nested clauses based on the selector value returned by
2615 * the landing pad instruction, which is passed to the landing pad in a
2616 * register by the EH code.
2618 target_bb = bblocks [bb->block_num].call_handler_target_bb;
2619 g_assert (target_bb);
2622 * Branch to the correct landing pad
2624 LLVMValueRef ex_selector = LLVMBuildExtractValue (builder, landing_pad, 1, "ex_selector");
2625 LLVMValueRef switch_ins = LLVMBuildSwitch (builder, ex_selector, target_bb, 0);
2627 for (l = ctx->nested_in [clause_index]; l; l = l->next) {
2628 int nesting_clause_index = GPOINTER_TO_INT (l->data);
2629 MonoBasicBlock *handler_bb;
2631 handler_bb = g_hash_table_lookup (ctx->clause_to_handler, GINT_TO_POINTER (nesting_clause_index));
2632 g_assert (handler_bb);
2634 g_assert (ctx->bblocks [handler_bb->block_num].call_handler_target_bb);
2635 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), nesting_clause_index, FALSE), ctx->bblocks [handler_bb->block_num].call_handler_target_bb);
2638 /* Start a new bblock which CALL_HANDLER can branch to */
2639 target_bb = bblocks [bb->block_num].call_handler_target_bb;
2641 ctx->builder = builder = create_builder (ctx);
2642 LLVMPositionBuilderAtEnd (ctx->builder, target_bb);
2644 ctx->bblocks [bb->block_num].end_bblock = target_bb;
2646 /* Store the exception into the IL level exvar */
2647 if (bb->in_scount == 1) {
2648 g_assert (bb->in_scount == 1);
2649 exvar = bb->in_stack [0];
2651 // FIXME: This is shared with filter clauses ?
2652 g_assert (!values [exvar->dreg]);
2654 g_assert (ctx->ex_var);
2655 values [exvar->dreg] = LLVMBuildLoad (builder, ctx->ex_var, "");
2656 emit_volatile_store (ctx, exvar->dreg);
2667 process_bb (EmitContext *ctx, MonoBasicBlock *bb)
2669 MonoCompile *cfg = ctx->cfg;
2670 MonoMethodSignature *sig = ctx->sig;
2671 LLVMValueRef method = ctx->lmethod;
2672 LLVMValueRef *values = ctx->values;
2673 LLVMValueRef *addresses = ctx->addresses;
2674 LLVMCallInfo *linfo = ctx->linfo;
2675 LLVMModuleRef module = ctx->module;
2676 BBInfo *bblocks = ctx->bblocks;
2678 LLVMBasicBlockRef cbb;
2679 LLVMBuilderRef builder, starting_builder;
2680 gboolean has_terminator;
2682 LLVMValueRef lhs, rhs;
2685 cbb = get_bb (ctx, bb);
2686 builder = create_builder (ctx);
2687 ctx->builder = builder;
2688 LLVMPositionBuilderAtEnd (builder, cbb);
2690 if (bb == cfg->bb_entry)
2691 emit_entry_bb (ctx, builder);
2692 CHECK_FAILURE (ctx);
2694 if (bb->flags & BB_EXCEPTION_HANDLER) {
2695 if (!bblocks [bb->block_num].invoke_target) {
2697 * LLVM asserts if llvm.eh.selector is called from a bblock which
2698 * doesn't have an invoke pointing at it.
2699 * Update: LLVM no longer asserts, but some tests in exceptions.exe now fail.
2701 LLVM_FAILURE (ctx, "handler without invokes");
2704 emit_handler_start (ctx, bb, builder);
2705 CHECK_FAILURE (ctx);
2706 builder = ctx->builder;
2709 has_terminator = FALSE;
2710 starting_builder = builder;
2711 for (ins = bb->code; ins; ins = ins->next) {
2712 const char *spec = LLVM_INS_INFO (ins->opcode);
2714 char dname_buf [128];
2716 emit_dbg_loc (ctx, builder, ins->cil_code);
2719 if (nins > 5000 && builder == starting_builder) {
2720 /* some steps in llc are non-linear in the size of basic blocks, see #5714 */
2721 LLVM_FAILURE (ctx, "basic block too long");
2725 /* There could be instructions after a terminator, skip them */
2728 if (spec [MONO_INST_DEST] != ' ' && !MONO_IS_STORE_MEMBASE (ins)) {
2729 sprintf (dname_buf, "t%d", ins->dreg);
2733 if (spec [MONO_INST_SRC1] != ' ' && spec [MONO_INST_SRC1] != 'v') {
2734 MonoInst *var = get_vreg_to_inst (cfg, ins->sreg1);
2736 if (var && var->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT)) {
2737 lhs = emit_volatile_load (ctx, ins->sreg1);
2739 /* It is ok for SETRET to have an uninitialized argument */
2740 if (!values [ins->sreg1] && ins->opcode != OP_SETRET)
2741 LLVM_FAILURE (ctx, "sreg1");
2742 lhs = values [ins->sreg1];
2748 if (spec [MONO_INST_SRC2] != ' ' && spec [MONO_INST_SRC2] != ' ') {
2749 MonoInst *var = get_vreg_to_inst (cfg, ins->sreg2);
2750 if (var && var->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT)) {
2751 rhs = emit_volatile_load (ctx, ins->sreg2);
2753 if (!values [ins->sreg2])
2754 LLVM_FAILURE (ctx, "sreg2");
2755 rhs = values [ins->sreg2];
2761 //mono_print_ins (ins);
2762 switch (ins->opcode) {
2765 case OP_LIVERANGE_START:
2766 case OP_LIVERANGE_END:
2769 values [ins->dreg] = LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE);
2772 #if SIZEOF_VOID_P == 4
2773 values [ins->dreg] = LLVMConstInt (LLVMInt64Type (), GET_LONG_IMM (ins), FALSE);
2775 values [ins->dreg] = LLVMConstInt (LLVMInt64Type (), (gint64)ins->inst_c0, FALSE);
2779 values [ins->dreg] = LLVMConstReal (LLVMDoubleType (), *(double*)ins->inst_p0);
2783 values [ins->dreg] = LLVMConstReal (LLVMFloatType (), *(float*)ins->inst_p0);
2785 values [ins->dreg] = LLVMConstFPExt (LLVMConstReal (LLVMFloatType (), *(float*)ins->inst_p0), LLVMDoubleType ());
2787 case OP_DUMMY_ICONST:
2788 values [ins->dreg] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
2790 case OP_DUMMY_I8CONST:
2791 values [ins->dreg] = LLVMConstInt (LLVMInt64Type (), 0, FALSE);
2793 case OP_DUMMY_R8CONST:
2794 values [ins->dreg] = LLVMConstReal (LLVMDoubleType (), 0.0f);
2797 LLVMBuildBr (builder, get_bb (ctx, ins->inst_target_bb));
2798 has_terminator = TRUE;
2804 LLVMBasicBlockRef new_bb;
2805 LLVMBuilderRef new_builder;
2807 // The default branch is already handled
2808 // FIXME: Handle it here
2810 /* Start new bblock */
2811 sprintf (bb_name, "SWITCH_DEFAULT_BB%d", ctx->default_index ++);
2812 new_bb = LLVMAppendBasicBlock (ctx->lmethod, bb_name);
2814 lhs = convert (ctx, lhs, LLVMInt32Type ());
2815 v = LLVMBuildSwitch (builder, lhs, new_bb, GPOINTER_TO_UINT (ins->klass));
2816 for (i = 0; i < GPOINTER_TO_UINT (ins->klass); ++i) {
2817 MonoBasicBlock *target_bb = ins->inst_many_bb [i];
2819 LLVMAddCase (v, LLVMConstInt (LLVMInt32Type (), i, FALSE), get_bb (ctx, target_bb));
2822 new_builder = create_builder (ctx);
2823 LLVMPositionBuilderAtEnd (new_builder, new_bb);
2824 LLVMBuildUnreachable (new_builder);
2826 has_terminator = TRUE;
2827 g_assert (!ins->next);
2833 if (linfo->ret.storage == LLVMArgVtypeInReg) {
2834 LLVMTypeRef ret_type = LLVMGetReturnType (LLVMGetElementType (LLVMTypeOf (method)));
2835 LLVMValueRef part1, retval;
2838 size = get_vtype_size (sig->ret);
2840 g_assert (addresses [ins->sreg1]);
2842 g_assert (linfo->ret.pair_storage [0] == LLVMArgInIReg);
2843 g_assert (linfo->ret.pair_storage [1] == LLVMArgNone);
2845 part1 = convert (ctx, LLVMBuildLoad (builder, LLVMBuildBitCast (builder, addresses [ins->sreg1], LLVMPointerType (LLVMIntType (size * 8), 0), ""), ""), IntPtrType ());
2847 retval = LLVMBuildInsertValue (builder, LLVMGetUndef (ret_type), part1, 0, "");
2849 LLVMBuildRet (builder, retval);
2853 if (linfo->ret.storage == LLVMArgVtypeByVal) {
2854 LLVMValueRef retval;
2856 g_assert (addresses [ins->sreg1]);
2857 retval = LLVMBuildLoad (builder, addresses [ins->sreg1], "");
2858 LLVMBuildRet (builder, retval);
2862 if (linfo->ret.storage == LLVMArgVtypeRetAddr) {
2863 LLVMBuildRetVoid (builder);
2867 if (linfo->ret.storage == LLVMArgFpStruct) {
2868 LLVMTypeRef ret_type = LLVMGetReturnType (LLVMGetElementType (LLVMTypeOf (method)));
2869 LLVMValueRef retval;
2871 g_assert (addresses [ins->sreg1]);
2872 retval = LLVMBuildLoad (builder, convert (ctx, addresses [ins->sreg1], LLVMPointerType (ret_type, 0)), "");
2873 LLVMBuildRet (builder, retval);
2877 if (!lhs || ctx->is_dead [ins->sreg1]) {
2879 * The method did not set its return value, probably because it
2880 * ends with a throw.
2883 LLVMBuildRetVoid (builder);
2885 LLVMBuildRet (builder, LLVMConstNull (type_to_llvm_type (ctx, sig->ret)));
2887 LLVMBuildRet (builder, convert (ctx, lhs, type_to_llvm_type (ctx, sig->ret)));
2889 has_terminator = TRUE;
2896 case OP_ICOMPARE_IMM:
2897 case OP_LCOMPARE_IMM:
2898 case OP_COMPARE_IMM: {
2902 if (ins->next->opcode == OP_NOP)
2905 if (ins->next->opcode == OP_BR)
2906 /* The comparison result is not needed */
2909 rel = mono_opcode_to_cond (ins->next->opcode);
2911 if (ins->opcode == OP_ICOMPARE_IMM) {
2912 lhs = convert (ctx, lhs, LLVMInt32Type ());
2913 rhs = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
2915 if (ins->opcode == OP_LCOMPARE_IMM) {
2916 lhs = convert (ctx, lhs, LLVMInt64Type ());
2917 rhs = LLVMConstInt (LLVMInt64Type (), GET_LONG_IMM (ins), FALSE);
2919 if (ins->opcode == OP_LCOMPARE) {
2920 lhs = convert (ctx, lhs, LLVMInt64Type ());
2921 rhs = convert (ctx, rhs, LLVMInt64Type ());
2923 if (ins->opcode == OP_ICOMPARE) {
2924 lhs = convert (ctx, lhs, LLVMInt32Type ());
2925 rhs = convert (ctx, rhs, LLVMInt32Type ());
2929 if (LLVMGetTypeKind (LLVMTypeOf (lhs)) == LLVMPointerTypeKind)
2930 rhs = convert (ctx, rhs, LLVMTypeOf (lhs));
2931 else if (LLVMGetTypeKind (LLVMTypeOf (rhs)) == LLVMPointerTypeKind)
2932 lhs = convert (ctx, lhs, LLVMTypeOf (rhs));
2935 /* We use COMPARE+SETcc/Bcc, llvm uses SETcc+br cond */
2936 if (ins->opcode == OP_FCOMPARE) {
2937 cmp = LLVMBuildFCmp (builder, fpcond_to_llvm_cond [rel], convert (ctx, lhs, LLVMDoubleType ()), convert (ctx, rhs, LLVMDoubleType ()), "");
2938 } else if (ins->opcode == OP_RCOMPARE) {
2939 cmp = LLVMBuildFCmp (builder, fpcond_to_llvm_cond [rel], convert (ctx, lhs, LLVMFloatType ()), convert (ctx, rhs, LLVMFloatType ()), "");
2940 } else if (ins->opcode == OP_COMPARE_IMM) {
2941 if (LLVMGetTypeKind (LLVMTypeOf (lhs)) == LLVMPointerTypeKind && ins->inst_imm == 0)
2942 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], lhs, LLVMConstNull (LLVMTypeOf (lhs)), "");
2944 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE), "");
2945 } else if (ins->opcode == OP_LCOMPARE_IMM) {
2946 if (SIZEOF_REGISTER == 4 && COMPILE_LLVM (cfg)) {
2947 /* The immediate is encoded in two fields */
2948 guint64 l = ((guint64)(guint32)ins->inst_offset << 32) | ((guint32)ins->inst_imm);
2949 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, LLVMInt64Type ()), LLVMConstInt (LLVMInt64Type (), l, FALSE), "");
2951 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, LLVMInt64Type ()), LLVMConstInt (LLVMInt64Type (), ins->inst_imm, FALSE), "");
2954 else if (ins->opcode == OP_COMPARE) {
2955 if (LLVMGetTypeKind (LLVMTypeOf (lhs)) == LLVMPointerTypeKind && LLVMTypeOf (lhs) == LLVMTypeOf (rhs))
2956 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], lhs, rhs, "");
2958 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, IntPtrType ()), convert (ctx, rhs, IntPtrType ()), "");
2960 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], lhs, rhs, "");
2962 if (MONO_IS_COND_BRANCH_OP (ins->next)) {
2963 if (ins->next->inst_true_bb == ins->next->inst_false_bb) {
2965 * If the target bb contains PHI instructions, LLVM requires
2966 * two PHI entries for this bblock, while we only generate one.
2967 * So convert this to an unconditional bblock. (bxc #171).
2969 LLVMBuildBr (builder, get_bb (ctx, ins->next->inst_true_bb));
2971 LLVMBuildCondBr (builder, cmp, get_bb (ctx, ins->next->inst_true_bb), get_bb (ctx, ins->next->inst_false_bb));
2973 has_terminator = TRUE;
2974 } else if (MONO_IS_SETCC (ins->next)) {
2975 sprintf (dname_buf, "t%d", ins->next->dreg);
2977 values [ins->next->dreg] = LLVMBuildZExt (builder, cmp, LLVMInt32Type (), dname);
2979 /* Add stores for volatile variables */
2980 emit_volatile_store (ctx, ins->next->dreg);
2981 } else if (MONO_IS_COND_EXC (ins->next)) {
2982 emit_cond_system_exception (ctx, bb, ins->next->inst_p1, cmp);
2983 CHECK_FAILURE (ctx);
2984 builder = ctx->builder;
2986 LLVM_FAILURE (ctx, "next");
3000 rel = mono_opcode_to_cond (ins->opcode);
3002 cmp = LLVMBuildFCmp (builder, fpcond_to_llvm_cond [rel], convert (ctx, lhs, LLVMDoubleType ()), convert (ctx, rhs, LLVMDoubleType ()), "");
3003 values [ins->dreg] = LLVMBuildZExt (builder, cmp, LLVMInt32Type (), dname);
3014 rel = mono_opcode_to_cond (ins->opcode);
3016 cmp = LLVMBuildFCmp (builder, fpcond_to_llvm_cond [rel], convert (ctx, lhs, LLVMFloatType ()), convert (ctx, rhs, LLVMFloatType ()), "");
3017 values [ins->dreg] = LLVMBuildZExt (builder, cmp, LLVMInt32Type (), dname);
3025 gboolean empty = TRUE;
3027 /* Check that all input bblocks really branch to us */
3028 for (i = 0; i < bb->in_count; ++i) {
3029 if (bb->in_bb [i]->last_ins && bb->in_bb [i]->last_ins->opcode == OP_NOT_REACHED)
3030 ins->inst_phi_args [i + 1] = -1;
3036 /* LLVM doesn't like phi instructions with zero operands */
3037 ctx->is_dead [ins->dreg] = TRUE;
3041 /* Created earlier, insert it now */
3042 LLVMInsertIntoBuilder (builder, values [ins->dreg]);
3044 for (i = 0; i < ins->inst_phi_args [0]; i++) {
3045 int sreg1 = ins->inst_phi_args [i + 1];
3049 * Count the number of times the incoming bblock branches to us,
3050 * since llvm requires a separate entry for each.
3052 if (bb->in_bb [i]->last_ins && bb->in_bb [i]->last_ins->opcode == OP_SWITCH) {
3053 MonoInst *switch_ins = bb->in_bb [i]->last_ins;
3056 for (j = 0; j < GPOINTER_TO_UINT (switch_ins->klass); ++j) {
3057 if (switch_ins->inst_many_bb [j] == bb)
3064 /* Remember for later */
3065 for (j = 0; j < count; ++j) {
3066 PhiNode *node = mono_mempool_alloc0 (ctx->mempool, sizeof (PhiNode));
3069 node->in_bb = bb->in_bb [i];
3071 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);
3081 values [ins->dreg] = lhs;
3085 MonoInst *var = get_vreg_to_inst (cfg, ins->dreg);
3088 values [ins->dreg] = lhs;
3090 if (var && var->klass->byval_arg.type == MONO_TYPE_R4) {
3092 * This is added by the spilling pass in case of the JIT,
3093 * but we have to do it ourselves.
3095 values [ins->dreg] = convert (ctx, values [ins->dreg], LLVMFloatType ());
3099 case OP_MOVE_F_TO_I4: {
3100 values [ins->dreg] = LLVMBuildBitCast (builder, LLVMBuildFPTrunc (builder, lhs, LLVMFloatType (), ""), LLVMInt32Type (), "");
3103 case OP_MOVE_I4_TO_F: {
3104 values [ins->dreg] = LLVMBuildFPExt (builder, LLVMBuildBitCast (builder, lhs, LLVMFloatType (), ""), LLVMDoubleType (), "");
3107 case OP_MOVE_F_TO_I8: {
3108 values [ins->dreg] = LLVMBuildBitCast (builder, lhs, LLVMInt64Type (), "");
3111 case OP_MOVE_I8_TO_F: {
3112 values [ins->dreg] = LLVMBuildBitCast (builder, lhs, LLVMDoubleType (), "");
3145 lhs = convert (ctx, lhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
3146 rhs = convert (ctx, rhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
3148 emit_div_check (ctx, builder, bb, ins, lhs, rhs);
3149 CHECK_FAILURE (ctx);
3150 builder = ctx->builder;
3152 switch (ins->opcode) {
3155 values [ins->dreg] = LLVMBuildAdd (builder, lhs, rhs, dname);
3159 values [ins->dreg] = LLVMBuildSub (builder, lhs, rhs, dname);
3163 values [ins->dreg] = LLVMBuildMul (builder, lhs, rhs, dname);
3167 values [ins->dreg] = LLVMBuildSRem (builder, lhs, rhs, dname);
3171 values [ins->dreg] = LLVMBuildURem (builder, lhs, rhs, dname);
3175 values [ins->dreg] = LLVMBuildSDiv (builder, lhs, rhs, dname);
3179 values [ins->dreg] = LLVMBuildUDiv (builder, lhs, rhs, dname);
3183 values [ins->dreg] = LLVMBuildFDiv (builder, lhs, rhs, dname);
3187 values [ins->dreg] = LLVMBuildAnd (builder, lhs, rhs, dname);
3191 values [ins->dreg] = LLVMBuildOr (builder, lhs, rhs, dname);
3195 values [ins->dreg] = LLVMBuildXor (builder, lhs, rhs, dname);
3199 values [ins->dreg] = LLVMBuildShl (builder, lhs, rhs, dname);
3203 values [ins->dreg] = LLVMBuildAShr (builder, lhs, rhs, dname);
3207 values [ins->dreg] = LLVMBuildLShr (builder, lhs, rhs, dname);
3211 values [ins->dreg] = LLVMBuildFAdd (builder, lhs, rhs, dname);
3214 values [ins->dreg] = LLVMBuildFSub (builder, lhs, rhs, dname);
3217 values [ins->dreg] = LLVMBuildFMul (builder, lhs, rhs, dname);
3221 g_assert_not_reached ();
3228 lhs = convert (ctx, lhs, LLVMFloatType ());
3229 rhs = convert (ctx, rhs, LLVMFloatType ());
3230 switch (ins->opcode) {
3232 values [ins->dreg] = LLVMBuildFAdd (builder, lhs, rhs, dname);
3235 values [ins->dreg] = LLVMBuildFSub (builder, lhs, rhs, dname);
3238 values [ins->dreg] = LLVMBuildFMul (builder, lhs, rhs, dname);
3241 values [ins->dreg] = LLVMBuildFDiv (builder, lhs, rhs, dname);
3244 g_assert_not_reached ();
3253 case OP_IREM_UN_IMM:
3255 case OP_IDIV_UN_IMM:
3261 case OP_ISHR_UN_IMM:
3270 case OP_LSHR_UN_IMM:
3276 case OP_SHR_UN_IMM: {
3279 if (spec [MONO_INST_SRC1] == 'l') {
3280 imm = LLVMConstInt (LLVMInt64Type (), GET_LONG_IMM (ins), FALSE);
3282 imm = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
3285 emit_div_check (ctx, builder, bb, ins, lhs, imm);
3286 CHECK_FAILURE (ctx);
3287 builder = ctx->builder;
3289 #if SIZEOF_VOID_P == 4
3290 if (ins->opcode == OP_LSHL_IMM || ins->opcode == OP_LSHR_IMM || ins->opcode == OP_LSHR_UN_IMM)
3291 imm = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
3294 if (LLVMGetTypeKind (LLVMTypeOf (lhs)) == LLVMPointerTypeKind)
3295 lhs = convert (ctx, lhs, IntPtrType ());
3296 imm = convert (ctx, imm, LLVMTypeOf (lhs));
3297 switch (ins->opcode) {
3301 values [ins->dreg] = LLVMBuildAdd (builder, lhs, imm, dname);
3305 values [ins->dreg] = LLVMBuildSub (builder, lhs, imm, dname);
3309 values [ins->dreg] = LLVMBuildMul (builder, lhs, imm, dname);
3313 values [ins->dreg] = LLVMBuildSDiv (builder, lhs, imm, dname);
3315 case OP_IDIV_UN_IMM:
3316 case OP_LDIV_UN_IMM:
3317 values [ins->dreg] = LLVMBuildUDiv (builder, lhs, imm, dname);
3321 values [ins->dreg] = LLVMBuildSRem (builder, lhs, imm, dname);
3323 case OP_IREM_UN_IMM:
3324 values [ins->dreg] = LLVMBuildURem (builder, lhs, imm, dname);
3329 values [ins->dreg] = LLVMBuildAnd (builder, lhs, imm, dname);
3333 values [ins->dreg] = LLVMBuildOr (builder, lhs, imm, dname);
3337 values [ins->dreg] = LLVMBuildXor (builder, lhs, imm, dname);
3342 values [ins->dreg] = LLVMBuildShl (builder, lhs, imm, dname);
3347 values [ins->dreg] = LLVMBuildAShr (builder, lhs, imm, dname);
3349 case OP_ISHR_UN_IMM:
3350 /* This is used to implement conv.u4, so the lhs could be an i8 */
3351 lhs = convert (ctx, lhs, LLVMInt32Type ());
3352 imm = convert (ctx, imm, LLVMInt32Type ());
3353 values [ins->dreg] = LLVMBuildLShr (builder, lhs, imm, dname);
3355 case OP_LSHR_UN_IMM:
3357 values [ins->dreg] = LLVMBuildLShr (builder, lhs, imm, dname);
3360 g_assert_not_reached ();
3365 values [ins->dreg] = LLVMBuildSub (builder, LLVMConstInt (LLVMInt32Type (), 0, FALSE), convert (ctx, lhs, LLVMInt32Type ()), dname);
3368 values [ins->dreg] = LLVMBuildSub (builder, LLVMConstInt (LLVMInt64Type (), 0, FALSE), lhs, dname);
3371 lhs = convert (ctx, lhs, LLVMDoubleType ());
3372 values [ins->dreg] = LLVMBuildFSub (builder, LLVMConstReal (LLVMDoubleType (), 0.0), lhs, dname);
3375 lhs = convert (ctx, lhs, LLVMFloatType ());
3376 values [ins->dreg] = LLVMBuildFSub (builder, LLVMConstReal (LLVMFloatType (), 0.0), lhs, dname);
3379 guint32 v = 0xffffffff;
3380 values [ins->dreg] = LLVMBuildXor (builder, LLVMConstInt (LLVMInt32Type (), v, FALSE), convert (ctx, lhs, LLVMInt32Type ()), dname);
3384 guint64 v = 0xffffffffffffffffLL;
3385 values [ins->dreg] = LLVMBuildXor (builder, LLVMConstInt (LLVMInt64Type (), v, FALSE), lhs, dname);
3388 #if defined(TARGET_X86) || defined(TARGET_AMD64)
3390 LLVMValueRef v1, v2;
3392 v1 = LLVMBuildMul (builder, convert (ctx, rhs, IntPtrType ()), LLVMConstInt (IntPtrType (), (1 << ins->backend.shift_amount), FALSE), "");
3393 v2 = LLVMBuildAdd (builder, convert (ctx, lhs, IntPtrType ()), v1, "");
3394 values [ins->dreg] = LLVMBuildAdd (builder, v2, LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE), dname);
3399 case OP_ICONV_TO_I1:
3400 case OP_ICONV_TO_I2:
3401 case OP_ICONV_TO_I4:
3402 case OP_ICONV_TO_U1:
3403 case OP_ICONV_TO_U2:
3404 case OP_ICONV_TO_U4:
3405 case OP_LCONV_TO_I1:
3406 case OP_LCONV_TO_I2:
3407 case OP_LCONV_TO_U1:
3408 case OP_LCONV_TO_U2:
3409 case OP_LCONV_TO_U4: {
3412 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);
3414 /* Have to do two casts since our vregs have type int */
3415 v = LLVMBuildTrunc (builder, lhs, op_to_llvm_type (ins->opcode), "");
3417 values [ins->dreg] = LLVMBuildSExt (builder, v, LLVMInt32Type (), dname);
3419 values [ins->dreg] = LLVMBuildZExt (builder, v, LLVMInt32Type (), dname);
3422 case OP_ICONV_TO_I8:
3423 values [ins->dreg] = LLVMBuildSExt (builder, lhs, LLVMInt64Type (), dname);
3425 case OP_ICONV_TO_U8:
3426 values [ins->dreg] = LLVMBuildZExt (builder, lhs, LLVMInt64Type (), dname);
3428 case OP_FCONV_TO_I4:
3429 case OP_RCONV_TO_I4:
3430 values [ins->dreg] = LLVMBuildFPToSI (builder, lhs, LLVMInt32Type (), dname);
3432 case OP_FCONV_TO_I1:
3433 case OP_RCONV_TO_I1:
3434 values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildFPToSI (builder, lhs, LLVMInt8Type (), dname), LLVMInt32Type (), "");
3436 case OP_FCONV_TO_U1:
3437 case OP_RCONV_TO_U1:
3438 values [ins->dreg] = LLVMBuildZExt (builder, LLVMBuildFPToUI (builder, lhs, LLVMInt8Type (), dname), LLVMInt32Type (), "");
3440 case OP_FCONV_TO_I2:
3441 case OP_RCONV_TO_I2:
3442 values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildFPToSI (builder, lhs, LLVMInt16Type (), dname), LLVMInt32Type (), "");
3444 case OP_FCONV_TO_U2:
3445 case OP_RCONV_TO_U2:
3446 values [ins->dreg] = LLVMBuildZExt (builder, LLVMBuildFPToUI (builder, lhs, LLVMInt16Type (), dname), LLVMInt32Type (), "");
3448 case OP_FCONV_TO_I8:
3449 case OP_RCONV_TO_I8:
3450 values [ins->dreg] = LLVMBuildFPToSI (builder, lhs, LLVMInt64Type (), dname);
3453 values [ins->dreg] = LLVMBuildFPToSI (builder, lhs, IntPtrType (), dname);
3455 case OP_ICONV_TO_R8:
3456 case OP_LCONV_TO_R8:
3457 values [ins->dreg] = LLVMBuildSIToFP (builder, lhs, LLVMDoubleType (), dname);
3459 case OP_LCONV_TO_R_UN:
3460 values [ins->dreg] = LLVMBuildUIToFP (builder, lhs, LLVMDoubleType (), dname);
3462 #if SIZEOF_VOID_P == 4
3465 case OP_LCONV_TO_I4:
3466 values [ins->dreg] = LLVMBuildTrunc (builder, lhs, LLVMInt32Type (), dname);
3468 case OP_ICONV_TO_R4:
3469 case OP_LCONV_TO_R4:
3470 v = LLVMBuildSIToFP (builder, lhs, LLVMFloatType (), "");
3472 values [ins->dreg] = v;
3474 values [ins->dreg] = LLVMBuildFPExt (builder, v, LLVMDoubleType (), dname);
3476 case OP_FCONV_TO_R4:
3477 v = LLVMBuildFPTrunc (builder, lhs, LLVMFloatType (), "");
3479 values [ins->dreg] = v;
3481 values [ins->dreg] = LLVMBuildFPExt (builder, v, LLVMDoubleType (), dname);
3483 case OP_RCONV_TO_R8:
3484 values [ins->dreg] = LLVMBuildFPExt (builder, lhs, LLVMDoubleType (), dname);
3486 case OP_RCONV_TO_R4:
3487 values [ins->dreg] = lhs;
3490 values [ins->dreg] = LLVMBuildSExt (builder, convert (ctx, lhs, LLVMInt32Type ()), LLVMInt64Type (), dname);
3493 values [ins->dreg] = LLVMBuildZExt (builder, convert (ctx, lhs, LLVMInt32Type ()), LLVMInt64Type (), dname);
3496 values [ins->dreg] = LLVMBuildTrunc (builder, lhs, LLVMInt32Type (), dname);
3498 case OP_LOCALLOC_IMM: {
3501 guint32 size = ins->inst_imm;
3502 size = (size + (MONO_ARCH_FRAME_ALIGNMENT - 1)) & ~ (MONO_ARCH_FRAME_ALIGNMENT - 1);
3504 v = mono_llvm_build_alloca (builder, LLVMInt8Type (), LLVMConstInt (LLVMInt32Type (), size, FALSE), MONO_ARCH_FRAME_ALIGNMENT, "");
3506 if (ins->flags & MONO_INST_INIT) {
3507 LLVMValueRef args [5];
3510 args [1] = LLVMConstInt (LLVMInt8Type (), 0, FALSE);
3511 args [2] = LLVMConstInt (LLVMInt32Type (), size, FALSE);
3512 args [3] = LLVMConstInt (LLVMInt32Type (), MONO_ARCH_FRAME_ALIGNMENT, FALSE);
3513 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
3514 LLVMBuildCall (builder, LLVMGetNamedFunction (module, memset_func_name), args, memset_param_count, "");
3517 values [ins->dreg] = v;
3521 LLVMValueRef v, size;
3523 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), "");
3525 v = mono_llvm_build_alloca (builder, LLVMInt8Type (), size, MONO_ARCH_FRAME_ALIGNMENT, "");
3527 if (ins->flags & MONO_INST_INIT) {
3528 LLVMValueRef args [5];
3531 args [1] = LLVMConstInt (LLVMInt8Type (), 0, FALSE);
3533 args [3] = LLVMConstInt (LLVMInt32Type (), MONO_ARCH_FRAME_ALIGNMENT, FALSE);
3534 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
3535 LLVMBuildCall (builder, LLVMGetNamedFunction (module, memset_func_name), args, memset_param_count, "");
3537 values [ins->dreg] = v;
3541 case OP_LOADI1_MEMBASE:
3542 case OP_LOADU1_MEMBASE:
3543 case OP_LOADI2_MEMBASE:
3544 case OP_LOADU2_MEMBASE:
3545 case OP_LOADI4_MEMBASE:
3546 case OP_LOADU4_MEMBASE:
3547 case OP_LOADI8_MEMBASE:
3548 case OP_LOADR4_MEMBASE:
3549 case OP_LOADR8_MEMBASE:
3550 case OP_LOAD_MEMBASE:
3558 LLVMValueRef base, index, addr;
3560 gboolean sext = FALSE, zext = FALSE;
3561 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
3563 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
3568 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)) {
3569 addr = LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE);
3574 if (ins->inst_offset == 0) {
3576 } else if (ins->inst_offset % size != 0) {
3577 /* Unaligned load */
3578 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset, FALSE);
3579 addr = LLVMBuildGEP (builder, convert (ctx, base, LLVMPointerType (LLVMInt8Type (), 0)), &index, 1, "");
3581 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
3582 addr = LLVMBuildGEP (builder, convert (ctx, base, LLVMPointerType (t, 0)), &index, 1, "");
3586 addr = convert (ctx, addr, LLVMPointerType (t, 0));
3588 values [ins->dreg] = emit_load (ctx, bb, &builder, size, addr, dname, is_volatile);
3590 if (!is_volatile && (ins->flags & MONO_INST_INVARIANT_LOAD)) {
3592 * These will signal LLVM that these loads do not alias any stores, and
3593 * they can't fail, allowing them to be hoisted out of loops.
3595 set_invariant_load_flag (values [ins->dreg]);
3596 set_metadata_flag (values [ins->dreg], "mono.nofail.load");
3600 values [ins->dreg] = LLVMBuildSExt (builder, values [ins->dreg], LLVMInt32Type (), dname);
3602 values [ins->dreg] = LLVMBuildZExt (builder, values [ins->dreg], LLVMInt32Type (), dname);
3603 else if (!cfg->r4fp && ins->opcode == OP_LOADR4_MEMBASE)
3604 values [ins->dreg] = LLVMBuildFPExt (builder, values [ins->dreg], LLVMDoubleType (), dname);
3608 case OP_STOREI1_MEMBASE_REG:
3609 case OP_STOREI2_MEMBASE_REG:
3610 case OP_STOREI4_MEMBASE_REG:
3611 case OP_STOREI8_MEMBASE_REG:
3612 case OP_STORER4_MEMBASE_REG:
3613 case OP_STORER8_MEMBASE_REG:
3614 case OP_STORE_MEMBASE_REG: {
3616 LLVMValueRef index, addr;
3618 gboolean sext = FALSE, zext = FALSE;
3619 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
3621 if (!values [ins->inst_destbasereg])
3622 LLVM_FAILURE (ctx, "inst_destbasereg");
3624 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
3626 if (ins->inst_offset % size != 0) {
3627 /* Unaligned store */
3628 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset, FALSE);
3629 addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (LLVMInt8Type (), 0)), &index, 1, "");
3631 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
3632 addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (t, 0)), &index, 1, "");
3634 emit_store (ctx, bb, &builder, size, convert (ctx, values [ins->sreg1], t), convert (ctx, addr, LLVMPointerType (t, 0)), is_volatile);
3638 case OP_STOREI1_MEMBASE_IMM:
3639 case OP_STOREI2_MEMBASE_IMM:
3640 case OP_STOREI4_MEMBASE_IMM:
3641 case OP_STOREI8_MEMBASE_IMM:
3642 case OP_STORE_MEMBASE_IMM: {
3644 LLVMValueRef index, addr;
3646 gboolean sext = FALSE, zext = FALSE;
3647 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
3649 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
3651 if (ins->inst_offset % size != 0) {
3652 /* Unaligned store */
3653 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset, FALSE);
3654 addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (LLVMInt8Type (), 0)), &index, 1, "");
3656 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
3657 addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (t, 0)), &index, 1, "");
3659 emit_store (ctx, bb, &builder, size, convert (ctx, LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE), t), convert (ctx, addr, LLVMPointerType (t, 0)), is_volatile);
3664 emit_load (ctx, bb, &builder, sizeof (gpointer), convert (ctx, lhs, LLVMPointerType (IntPtrType (), 0)), "", TRUE);
3666 case OP_OUTARG_VTRETADDR:
3674 case OP_VOIDCALL_MEMBASE:
3675 case OP_CALL_MEMBASE:
3676 case OP_LCALL_MEMBASE:
3677 case OP_FCALL_MEMBASE:
3678 case OP_RCALL_MEMBASE:
3679 case OP_VCALL_MEMBASE:
3680 case OP_VOIDCALL_REG:
3685 case OP_VCALL_REG: {
3686 process_call (ctx, bb, &builder, ins);
3687 CHECK_FAILURE (ctx);
3692 LLVMValueRef indexes [2];
3694 LLVMValueRef got_entry_addr;
3697 * FIXME: Can't allocate from the cfg mempool since that is freed if
3698 * the LLVM compile fails.
3700 ji = g_new0 (MonoJumpInfo, 1);
3701 ji->type = (MonoJumpInfoType)ins->inst_i1;
3702 ji->data.target = ins->inst_p0;
3704 ji = mono_aot_patch_info_dup (ji);
3706 ji->next = cfg->patch_info;
3707 cfg->patch_info = ji;
3709 //mono_add_patch_info (cfg, 0, (MonoJumpInfoType)ins->inst_i1, ins->inst_p0);
3710 got_offset = mono_aot_get_got_offset (cfg->patch_info);
3711 ctx->lmodule->max_got_offset = MAX (ctx->lmodule->max_got_offset, got_offset);
3713 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
3714 indexes [1] = LLVMConstInt (LLVMInt32Type (), (gssize)got_offset, FALSE);
3715 got_entry_addr = LLVMBuildGEP (builder, ctx->lmodule->got_var, indexes, 2, "");
3717 values [ins->dreg] = LLVMBuildLoad (builder, got_entry_addr, dname);
3718 set_invariant_load_flag (values [ins->dreg]);
3721 case OP_NOT_REACHED:
3722 LLVMBuildUnreachable (builder);
3723 has_terminator = TRUE;
3724 g_assert (bb->block_num < cfg->max_block_num);
3725 ctx->unreachable [bb->block_num] = TRUE;
3726 /* Might have instructions after this */
3728 MonoInst *next = ins->next;
3730 * FIXME: If later code uses the regs defined by these instructions,
3731 * compilation will fail.
3733 MONO_DELETE_INS (bb, next);
3737 MonoInst *var = ins->inst_p0;
3739 values [ins->dreg] = addresses [var->dreg];
3743 LLVMValueRef args [1];
3745 args [0] = convert (ctx, lhs, LLVMDoubleType ());
3746 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, "llvm.sin.f64"), args, 1, dname);
3750 LLVMValueRef args [1];
3752 args [0] = convert (ctx, lhs, LLVMDoubleType ());
3753 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, "llvm.cos.f64"), args, 1, dname);
3757 LLVMValueRef args [1];
3760 /* This no longer seems to happen */
3762 * LLVM optimizes sqrt(nan) into undefined in
3763 * lib/Analysis/ConstantFolding.cpp
3764 * Also, sqrt(NegativeInfinity) is optimized into 0.
3766 LLVM_FAILURE (ctx, "sqrt");
3768 args [0] = convert (ctx, lhs, LLVMDoubleType ());
3769 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, "llvm.sqrt.f64"), args, 1, dname);
3773 LLVMValueRef args [1];
3775 args [0] = convert (ctx, lhs, LLVMDoubleType ());
3776 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, "fabs"), args, 1, dname);
3790 lhs = convert (ctx, lhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
3791 rhs = convert (ctx, rhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
3793 switch (ins->opcode) {
3796 v = LLVMBuildICmp (builder, LLVMIntSLE, lhs, rhs, "");
3800 v = LLVMBuildICmp (builder, LLVMIntSGE, lhs, rhs, "");
3804 v = LLVMBuildICmp (builder, LLVMIntULE, lhs, rhs, "");
3808 v = LLVMBuildICmp (builder, LLVMIntUGE, lhs, rhs, "");
3811 g_assert_not_reached ();
3814 values [ins->dreg] = LLVMBuildSelect (builder, v, lhs, rhs, dname);
3817 case OP_ATOMIC_EXCHANGE_I4:
3818 case OP_ATOMIC_EXCHANGE_I8: {
3819 LLVMValueRef args [2];
3822 if (ins->opcode == OP_ATOMIC_EXCHANGE_I4)
3823 t = LLVMInt32Type ();
3825 t = LLVMInt64Type ();
3827 g_assert (ins->inst_offset == 0);
3829 args [0] = convert (ctx, lhs, LLVMPointerType (t, 0));
3830 args [1] = convert (ctx, rhs, t);
3832 values [ins->dreg] = mono_llvm_build_atomic_rmw (builder, LLVM_ATOMICRMW_OP_XCHG, args [0], args [1]);
3835 case OP_ATOMIC_ADD_I4:
3836 case OP_ATOMIC_ADD_I8: {
3837 LLVMValueRef args [2];
3840 if (ins->opcode == OP_ATOMIC_ADD_I4)
3841 t = LLVMInt32Type ();
3843 t = LLVMInt64Type ();
3845 g_assert (ins->inst_offset == 0);
3847 args [0] = convert (ctx, lhs, LLVMPointerType (t, 0));
3848 args [1] = convert (ctx, rhs, t);
3849 values [ins->dreg] = LLVMBuildAdd (builder, mono_llvm_build_atomic_rmw (builder, LLVM_ATOMICRMW_OP_ADD, args [0], args [1]), args [1], dname);
3852 case OP_ATOMIC_CAS_I4:
3853 case OP_ATOMIC_CAS_I8: {
3854 LLVMValueRef args [3], val;
3857 if (ins->opcode == OP_ATOMIC_CAS_I4)
3858 t = LLVMInt32Type ();
3860 t = LLVMInt64Type ();
3862 args [0] = convert (ctx, lhs, LLVMPointerType (t, 0));
3864 args [1] = convert (ctx, values [ins->sreg3], t);
3866 args [2] = convert (ctx, values [ins->sreg2], t);
3867 val = mono_llvm_build_cmpxchg (builder, args [0], args [1], args [2]);
3868 /* cmpxchg returns a pair */
3869 values [ins->dreg] = LLVMBuildExtractValue (builder, val, 0, "");
3872 case OP_MEMORY_BARRIER: {
3873 mono_llvm_build_fence (builder, (BarrierKind) ins->backend.memory_barrier_kind);
3876 case OP_ATOMIC_LOAD_I1:
3877 case OP_ATOMIC_LOAD_I2:
3878 case OP_ATOMIC_LOAD_I4:
3879 case OP_ATOMIC_LOAD_I8:
3880 case OP_ATOMIC_LOAD_U1:
3881 case OP_ATOMIC_LOAD_U2:
3882 case OP_ATOMIC_LOAD_U4:
3883 case OP_ATOMIC_LOAD_U8:
3884 case OP_ATOMIC_LOAD_R4:
3885 case OP_ATOMIC_LOAD_R8: {
3886 LLVM_FAILURE (ctx, "atomic mono.load intrinsic");
3889 gboolean sext, zext;
3891 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
3892 BarrierKind barrier = (BarrierKind) ins->backend.memory_barrier_kind;
3893 LLVMValueRef index, addr;
3895 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
3900 if (ins->inst_offset != 0) {
3901 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
3902 addr = LLVMBuildGEP (builder, convert (ctx, lhs, LLVMPointerType (t, 0)), &index, 1, "");
3907 addr = convert (ctx, addr, LLVMPointerType (t, 0));
3909 values [ins->dreg] = emit_load_general (ctx, bb, &builder, size, addr, dname, is_volatile, barrier);
3912 values [ins->dreg] = LLVMBuildSExt (builder, values [ins->dreg], LLVMInt32Type (), dname);
3914 values [ins->dreg] = LLVMBuildZExt (builder, values [ins->dreg], LLVMInt32Type (), dname);
3917 case OP_ATOMIC_STORE_I1:
3918 case OP_ATOMIC_STORE_I2:
3919 case OP_ATOMIC_STORE_I4:
3920 case OP_ATOMIC_STORE_I8:
3921 case OP_ATOMIC_STORE_U1:
3922 case OP_ATOMIC_STORE_U2:
3923 case OP_ATOMIC_STORE_U4:
3924 case OP_ATOMIC_STORE_U8:
3925 case OP_ATOMIC_STORE_R4:
3926 case OP_ATOMIC_STORE_R8: {
3927 LLVM_FAILURE (ctx, "atomic mono.load intrinsic");
3930 gboolean sext, zext;
3932 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
3933 BarrierKind barrier = (BarrierKind) ins->backend.memory_barrier_kind;
3934 LLVMValueRef index, addr, value;
3936 if (!values [ins->inst_destbasereg])
3937 LLVM_FAILURE (ctx, "inst_destbasereg");
3939 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
3941 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
3942 addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (t, 0)), &index, 1, "");
3943 value = convert (ctx, values [ins->sreg1], t);
3945 emit_store_general (ctx, bb, &builder, size, value, addr, is_volatile, barrier);
3948 case OP_RELAXED_NOP: {
3949 #if defined(TARGET_AMD64) || defined(TARGET_X86)
3950 emit_call (ctx, bb, &builder, LLVMGetNamedFunction (ctx->module, "llvm.x86.sse2.pause"), NULL, 0);
3957 #if (defined(TARGET_AMD64) || defined(TARGET_X86)) && defined(__linux__)
3959 // 257 == FS segment register
3960 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 257);
3962 // 256 == GS segment register
3963 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 256);
3966 values [ins->dreg] = LLVMBuildLoad (builder, LLVMBuildIntToPtr (builder, LLVMConstInt (IntPtrType (), ins->inst_offset, TRUE), ptrtype, ""), "");
3967 #elif defined(TARGET_AMD64) && defined(TARGET_OSX)
3968 /* See mono_amd64_emit_tls_get () */
3969 int offset = mono_amd64_get_tls_gs_offset () + (ins->inst_offset * 8);
3971 // 256 == GS segment register
3972 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 256);
3973 values [ins->dreg] = LLVMBuildLoad (builder, LLVMBuildIntToPtr (builder, LLVMConstInt (IntPtrType (), offset, TRUE), ptrtype, ""), "");
3975 LLVM_FAILURE (ctx, "opcode tls-get");
3980 case OP_TLS_GET_REG: {
3981 #if defined(TARGET_AMD64) && defined(TARGET_OSX)
3982 /* See emit_tls_get_reg () */
3983 // 256 == GS segment register
3984 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 256);
3985 values [ins->dreg] = LLVMBuildLoad (builder, LLVMBuildIntToPtr (builder, convert (ctx, lhs, LLVMInt32Type ()), ptrtype, ""), "");
3987 LLVM_FAILURE (ctx, "opcode tls-get");
3996 case OP_IADD_OVF_UN:
3998 case OP_ISUB_OVF_UN:
4000 case OP_IMUL_OVF_UN:
4001 #if SIZEOF_VOID_P == 8
4003 case OP_LADD_OVF_UN:
4005 case OP_LSUB_OVF_UN:
4007 case OP_LMUL_OVF_UN:
4010 LLVMValueRef args [2], val, ovf, func;
4012 args [0] = convert (ctx, lhs, op_to_llvm_type (ins->opcode));
4013 args [1] = convert (ctx, rhs, op_to_llvm_type (ins->opcode));
4014 func = LLVMGetNamedFunction (module, ovf_op_to_intrins (ins->opcode));
4016 val = LLVMBuildCall (builder, func, args, 2, "");
4017 values [ins->dreg] = LLVMBuildExtractValue (builder, val, 0, dname);
4018 ovf = LLVMBuildExtractValue (builder, val, 1, "");
4019 emit_cond_system_exception (ctx, bb, "OverflowException", ovf);
4020 CHECK_FAILURE (ctx);
4021 builder = ctx->builder;
4027 * We currently model them using arrays. Promotion to local vregs is
4028 * disabled for them in mono_handle_global_vregs () in the LLVM case,
4029 * so we always have an entry in cfg->varinfo for them.
4030 * FIXME: Is this needed ?
4033 MonoClass *klass = ins->klass;
4034 LLVMValueRef args [5];
4038 LLVM_FAILURE (ctx, "!klass");
4042 if (!addresses [ins->dreg])
4043 addresses [ins->dreg] = build_alloca (ctx, &klass->byval_arg);
4044 args [0] = LLVMBuildBitCast (builder, addresses [ins->dreg], LLVMPointerType (LLVMInt8Type (), 0), "");
4045 args [1] = LLVMConstInt (LLVMInt8Type (), 0, FALSE);
4046 args [2] = LLVMConstInt (LLVMInt32Type (), mono_class_value_size (klass, NULL), FALSE);
4048 args [3] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
4049 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
4050 LLVMBuildCall (builder, LLVMGetNamedFunction (module, memset_func_name), args, memset_param_count, "");
4053 case OP_DUMMY_VZERO:
4056 case OP_STOREV_MEMBASE:
4057 case OP_LOADV_MEMBASE:
4059 MonoClass *klass = ins->klass;
4060 LLVMValueRef src = NULL, dst, args [5];
4061 gboolean done = FALSE;
4065 LLVM_FAILURE (ctx, "!klass");
4069 if (mini_is_gsharedvt_klass (cfg, klass)) {
4071 LLVM_FAILURE (ctx, "gsharedvt");
4075 switch (ins->opcode) {
4076 case OP_STOREV_MEMBASE:
4077 if (cfg->gen_write_barriers && klass->has_references && ins->inst_destbasereg != cfg->frame_reg &&
4078 LLVMGetInstructionOpcode (values [ins->inst_destbasereg]) != LLVMAlloca) {
4079 /* Decomposed earlier */
4080 g_assert_not_reached ();
4083 if (!addresses [ins->sreg1]) {
4085 g_assert (values [ins->sreg1]);
4086 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));
4087 LLVMBuildStore (builder, values [ins->sreg1], dst);
4090 src = LLVMBuildBitCast (builder, addresses [ins->sreg1], LLVMPointerType (LLVMInt8Type (), 0), "");
4091 dst = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_destbasereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (LLVMInt8Type (), 0));
4094 case OP_LOADV_MEMBASE:
4095 if (!addresses [ins->dreg])
4096 addresses [ins->dreg] = build_alloca (ctx, &klass->byval_arg);
4097 src = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_basereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (LLVMInt8Type (), 0));
4098 dst = LLVMBuildBitCast (builder, addresses [ins->dreg], LLVMPointerType (LLVMInt8Type (), 0), "");
4101 if (!addresses [ins->sreg1])
4102 addresses [ins->sreg1] = build_alloca (ctx, &klass->byval_arg);
4103 if (!addresses [ins->dreg])
4104 addresses [ins->dreg] = build_alloca (ctx, &klass->byval_arg);
4105 src = LLVMBuildBitCast (builder, addresses [ins->sreg1], LLVMPointerType (LLVMInt8Type (), 0), "");
4106 dst = LLVMBuildBitCast (builder, addresses [ins->dreg], LLVMPointerType (LLVMInt8Type (), 0), "");
4109 g_assert_not_reached ();
4111 CHECK_FAILURE (ctx);
4118 args [2] = LLVMConstInt (LLVMInt32Type (), mono_class_value_size (klass, NULL), FALSE);
4119 args [3] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
4121 args [3] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
4122 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
4123 LLVMBuildCall (builder, LLVMGetNamedFunction (module, memcpy_func_name), args, memcpy_param_count, "");
4126 case OP_LLVM_OUTARG_VT:
4127 if (!addresses [ins->sreg1]) {
4128 addresses [ins->sreg1] = build_alloca (ctx, &ins->klass->byval_arg);
4129 g_assert (values [ins->sreg1]);
4130 LLVMBuildStore (builder, values [ins->sreg1], addresses [ins->sreg1]);
4132 addresses [ins->dreg] = addresses [ins->sreg1];
4138 #if defined(TARGET_X86) || defined(TARGET_AMD64)
4140 values [ins->dreg] = LLVMConstNull (type_to_llvm_type (ctx, &ins->klass->byval_arg));
4143 case OP_LOADX_MEMBASE: {
4144 LLVMTypeRef t = type_to_llvm_type (ctx, &ins->klass->byval_arg);
4147 src = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_basereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (t, 0));
4148 values [ins->dreg] = mono_llvm_build_aligned_load (builder, src, "", FALSE, 1);
4151 case OP_STOREX_MEMBASE: {
4152 LLVMTypeRef t = LLVMTypeOf (values [ins->sreg1]);
4155 dest = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_destbasereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (t, 0));
4156 mono_llvm_build_aligned_store (builder, values [ins->sreg1], dest, FALSE, 1);
4163 values [ins->dreg] = LLVMBuildAdd (builder, lhs, rhs, "");
4167 values [ins->dreg] = LLVMBuildFAdd (builder, lhs, rhs, "");
4173 values [ins->dreg] = LLVMBuildSub (builder, lhs, rhs, "");
4177 values [ins->dreg] = LLVMBuildFSub (builder, lhs, rhs, "");
4181 values [ins->dreg] = LLVMBuildFMul (builder, lhs, rhs, "");
4185 values [ins->dreg] = LLVMBuildFDiv (builder, lhs, rhs, "");
4188 values [ins->dreg] = LLVMBuildAnd (builder, lhs, rhs, "");
4191 values [ins->dreg] = LLVMBuildOr (builder, lhs, rhs, "");
4194 values [ins->dreg] = LLVMBuildXor (builder, lhs, rhs, "");
4198 values [ins->dreg] = LLVMBuildMul (builder, lhs, rhs, "");
4209 LLVMValueRef v = NULL;
4211 switch (ins->opcode) {
4216 t = LLVMVectorType (LLVMInt32Type (), 4);
4217 rt = LLVMVectorType (LLVMFloatType (), 4);
4223 t = LLVMVectorType (LLVMInt64Type (), 2);
4224 rt = LLVMVectorType (LLVMDoubleType (), 2);
4227 t = LLVMInt32Type ();
4228 rt = LLVMInt32Type ();
4229 g_assert_not_reached ();
4232 lhs = LLVMBuildBitCast (builder, lhs, t, "");
4233 rhs = LLVMBuildBitCast (builder, rhs, t, "");
4234 switch (ins->opcode) {
4237 v = LLVMBuildAnd (builder, lhs, rhs, "");
4241 v = LLVMBuildOr (builder, lhs, rhs, "");
4245 v = LLVMBuildXor (builder, lhs, rhs, "");
4249 v = LLVMBuildAnd (builder, rhs, LLVMBuildNot (builder, lhs, ""), "");
4252 values [ins->dreg] = LLVMBuildBitCast (builder, v, rt, "");
4276 case OP_PADDB_SAT_UN:
4277 case OP_PADDW_SAT_UN:
4278 case OP_PSUBB_SAT_UN:
4279 case OP_PSUBW_SAT_UN:
4287 case OP_PMULW_HIGH_UN: {
4288 LLVMValueRef args [2];
4293 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, simd_op_to_intrins (ins->opcode)), args, 2, dname);
4300 values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildICmp (builder, LLVMIntEQ, lhs, rhs, ""), LLVMTypeOf (lhs), "");
4304 values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildICmp (builder, LLVMIntSGT, lhs, rhs, ""), LLVMTypeOf (lhs), "");
4312 case OP_EXTRACTX_U2:
4314 case OP_EXTRACT_U1: {
4316 gboolean zext = FALSE;
4318 t = simd_op_to_llvm_type (ins->opcode);
4320 switch (ins->opcode) {
4328 case OP_EXTRACTX_U2:
4333 t = LLVMInt32Type ();
4334 g_assert_not_reached ();
4337 lhs = LLVMBuildBitCast (builder, lhs, t, "");
4338 values [ins->dreg] = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), "");
4340 values [ins->dreg] = LLVMBuildZExt (builder, values [ins->dreg], LLVMInt32Type (), "");
4349 case OP_EXPAND_R8: {
4350 LLVMTypeRef t = simd_op_to_llvm_type (ins->opcode);
4351 LLVMValueRef mask [16], v;
4354 for (i = 0; i < 16; ++i)
4355 mask [i] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
4357 v = convert (ctx, values [ins->sreg1], LLVMGetElementType (t));
4359 values [ins->dreg] = LLVMBuildInsertElement (builder, LLVMConstNull (t), v, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
4360 values [ins->dreg] = LLVMBuildShuffleVector (builder, values [ins->dreg], LLVMGetUndef (t), LLVMConstVector (mask, LLVMGetVectorSize (t)), "");
4365 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt8Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
4368 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt16Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
4371 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt32Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
4374 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt64Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
4377 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMFloatType ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
4380 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMDoubleType ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
4391 case OP_EXTRACT_MASK:
4398 v = convert (ctx, values [ins->sreg1], simd_op_to_llvm_type (ins->opcode));
4400 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, simd_op_to_intrins (ins->opcode)), &v, 1, dname);
4406 LLVMValueRef args [3];
4410 args [2] = LLVMConstInt (LLVMInt8Type (), ins->inst_c0, FALSE);
4412 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, simd_op_to_intrins (ins->opcode)), args, 3, dname);
4417 /* This is only used for implementing shifts by non-immediate */
4418 values [ins->dreg] = lhs;
4429 LLVMValueRef args [3];
4432 args [1] = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
4434 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, simd_op_to_intrins (ins->opcode)), args, 2, dname);
4445 case OP_PSHLQ_REG: {
4446 LLVMValueRef args [3];
4449 args [1] = values [ins->sreg2];
4451 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, simd_op_to_intrins (ins->opcode)), args, 2, dname);
4458 case OP_PSHUFLEW_LOW:
4459 case OP_PSHUFLEW_HIGH: {
4461 LLVMValueRef v1 = NULL, v2 = NULL, mask_values [16];
4462 int i, mask_size = 0;
4463 int imask = ins->inst_c0;
4465 /* Convert the x86 shuffle mask to LLVM's */
4466 switch (ins->opcode) {
4469 mask [0] = ((imask >> 0) & 3);
4470 mask [1] = ((imask >> 2) & 3);
4471 mask [2] = ((imask >> 4) & 3) + 4;
4472 mask [3] = ((imask >> 6) & 3) + 4;
4473 v1 = values [ins->sreg1];
4474 v2 = values [ins->sreg2];
4478 mask [0] = ((imask >> 0) & 1);
4479 mask [1] = ((imask >> 1) & 1) + 2;
4480 v1 = values [ins->sreg1];
4481 v2 = values [ins->sreg2];
4483 case OP_PSHUFLEW_LOW:
4485 mask [0] = ((imask >> 0) & 3);
4486 mask [1] = ((imask >> 2) & 3);
4487 mask [2] = ((imask >> 4) & 3);
4488 mask [3] = ((imask >> 6) & 3);
4493 v1 = values [ins->sreg1];
4494 v2 = LLVMGetUndef (LLVMTypeOf (v1));
4496 case OP_PSHUFLEW_HIGH:
4502 mask [4] = 4 + ((imask >> 0) & 3);
4503 mask [5] = 4 + ((imask >> 2) & 3);
4504 mask [6] = 4 + ((imask >> 4) & 3);
4505 mask [7] = 4 + ((imask >> 6) & 3);
4506 v1 = values [ins->sreg1];
4507 v2 = LLVMGetUndef (LLVMTypeOf (v1));
4511 mask [0] = ((imask >> 0) & 3);
4512 mask [1] = ((imask >> 2) & 3);
4513 mask [2] = ((imask >> 4) & 3);
4514 mask [3] = ((imask >> 6) & 3);
4515 v1 = values [ins->sreg1];
4516 v2 = LLVMGetUndef (LLVMTypeOf (v1));
4519 g_assert_not_reached ();
4521 for (i = 0; i < mask_size; ++i)
4522 mask_values [i] = LLVMConstInt (LLVMInt32Type (), mask [i], FALSE);
4524 values [ins->dreg] =
4525 LLVMBuildShuffleVector (builder, v1, v2,
4526 LLVMConstVector (mask_values, mask_size), dname);
4530 case OP_UNPACK_LOWB:
4531 case OP_UNPACK_LOWW:
4532 case OP_UNPACK_LOWD:
4533 case OP_UNPACK_LOWQ:
4534 case OP_UNPACK_LOWPS:
4535 case OP_UNPACK_LOWPD:
4536 case OP_UNPACK_HIGHB:
4537 case OP_UNPACK_HIGHW:
4538 case OP_UNPACK_HIGHD:
4539 case OP_UNPACK_HIGHQ:
4540 case OP_UNPACK_HIGHPS:
4541 case OP_UNPACK_HIGHPD: {
4543 LLVMValueRef mask_values [16];
4544 int i, mask_size = 0;
4545 gboolean low = FALSE;
4547 switch (ins->opcode) {
4548 case OP_UNPACK_LOWB:
4552 case OP_UNPACK_LOWW:
4556 case OP_UNPACK_LOWD:
4557 case OP_UNPACK_LOWPS:
4561 case OP_UNPACK_LOWQ:
4562 case OP_UNPACK_LOWPD:
4566 case OP_UNPACK_HIGHB:
4569 case OP_UNPACK_HIGHW:
4572 case OP_UNPACK_HIGHD:
4573 case OP_UNPACK_HIGHPS:
4576 case OP_UNPACK_HIGHQ:
4577 case OP_UNPACK_HIGHPD:
4581 g_assert_not_reached ();
4585 for (i = 0; i < (mask_size / 2); ++i) {
4587 mask [(i * 2) + 1] = mask_size + i;
4590 for (i = 0; i < (mask_size / 2); ++i) {
4591 mask [(i * 2)] = (mask_size / 2) + i;
4592 mask [(i * 2) + 1] = mask_size + (mask_size / 2) + i;
4596 for (i = 0; i < mask_size; ++i)
4597 mask_values [i] = LLVMConstInt (LLVMInt32Type (), mask [i], FALSE);
4599 values [ins->dreg] =
4600 LLVMBuildShuffleVector (builder, values [ins->sreg1], values [ins->sreg2],
4601 LLVMConstVector (mask_values, mask_size), dname);
4606 LLVMTypeRef t = simd_op_to_llvm_type (ins->opcode);
4607 LLVMValueRef v, val;
4609 v = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
4610 val = LLVMConstNull (t);
4611 val = LLVMBuildInsertElement (builder, val, v, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
4612 val = LLVMBuildInsertElement (builder, val, v, LLVMConstInt (LLVMInt32Type (), 1, FALSE), dname);
4614 values [ins->dreg] = val;
4618 case OP_DUPPS_HIGH: {
4619 LLVMTypeRef t = simd_op_to_llvm_type (ins->opcode);
4620 LLVMValueRef v1, v2, val;
4623 if (ins->opcode == OP_DUPPS_LOW) {
4624 v1 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
4625 v2 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 2, FALSE), "");
4627 v1 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 1, FALSE), "");
4628 v2 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 3, FALSE), "");
4630 val = LLVMConstNull (t);
4631 val = LLVMBuildInsertElement (builder, val, v1, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
4632 val = LLVMBuildInsertElement (builder, val, v1, LLVMConstInt (LLVMInt32Type (), 1, FALSE), "");
4633 val = LLVMBuildInsertElement (builder, val, v2, LLVMConstInt (LLVMInt32Type (), 2, FALSE), "");
4634 val = LLVMBuildInsertElement (builder, val, v2, LLVMConstInt (LLVMInt32Type (), 3, FALSE), "");
4636 values [ins->dreg] = val;
4646 * EXCEPTION HANDLING
4648 case OP_IMPLICIT_EXCEPTION:
4649 /* This marks a place where an implicit exception can happen */
4650 if (bb->region != -1)
4651 LLVM_FAILURE (ctx, "implicit-exception");
4655 MonoMethodSignature *throw_sig;
4656 LLVMValueRef callee, arg;
4657 gboolean rethrow = (ins->opcode == OP_RETHROW);
4658 const char *icall_name;
4660 callee = rethrow ? ctx->lmodule->rethrow : ctx->lmodule->throw;
4661 icall_name = rethrow ? "mono_arch_rethrow_exception" : "mono_arch_throw_exception";
4664 throw_sig = mono_metadata_signature_alloc (mono_get_corlib (), 1);
4665 throw_sig->ret = &mono_get_void_class ()->byval_arg;
4666 throw_sig->params [0] = &mono_get_object_class ()->byval_arg;
4667 if (cfg->compile_aot) {
4668 callee = get_plt_entry (ctx, sig_to_llvm_sig (ctx, throw_sig), MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
4670 callee = LLVMAddFunction (module, icall_name, sig_to_llvm_sig (ctx, throw_sig));
4674 * LLVM doesn't push the exception argument, so we need a different
4677 LLVMAddGlobalMapping (ctx->lmodule->ee, callee, resolve_patch (cfg, MONO_PATCH_INFO_INTERNAL_METHOD, rethrow ? "llvm_rethrow_exception_trampoline" : "llvm_throw_exception_trampoline"));
4679 LLVMAddGlobalMapping (ctx->lmodule->ee, callee, resolve_patch (cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name));
4683 mono_memory_barrier ();
4685 ctx->lmodule->rethrow = callee;
4687 ctx->lmodule->throw = callee;
4689 arg = convert (ctx, lhs, type_to_llvm_type (ctx, &mono_get_object_class ()->byval_arg));
4690 emit_call (ctx, bb, &builder, callee, &arg, 1);
4693 case OP_CALL_HANDLER: {
4695 * We don't 'call' handlers, but instead simply branch to them.
4696 * The code generated by ENDFINALLY will branch back to us.
4698 LLVMBasicBlockRef noex_bb;
4700 BBInfo *info = &bblocks [ins->inst_target_bb->block_num];
4702 bb_list = info->call_handler_return_bbs;
4705 * Set the indicator variable for the finally clause.
4707 lhs = info->finally_ind;
4709 LLVMBuildStore (builder, LLVMConstInt (LLVMInt32Type (), g_slist_length (bb_list) + 1, FALSE), lhs);
4711 /* Branch to the finally clause */
4712 LLVMBuildBr (builder, info->call_handler_target_bb);
4714 noex_bb = gen_bb (ctx, "CALL_HANDLER_CONT_BB");
4715 info->call_handler_return_bbs = g_slist_append_mempool (cfg->mempool, info->call_handler_return_bbs, noex_bb);
4717 builder = ctx->builder = create_builder (ctx);
4718 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
4720 bblocks [bb->block_num].end_bblock = noex_bb;
4723 case OP_START_HANDLER: {
4726 case OP_ENDFINALLY: {
4727 LLVMBasicBlockRef resume_bb;
4728 MonoBasicBlock *handler_bb;
4729 LLVMValueRef val, switch_ins, callee;
4733 handler_bb = g_hash_table_lookup (ctx->region_to_handler, GUINT_TO_POINTER (mono_get_block_region_notry (cfg, bb->region)));
4734 g_assert (handler_bb);
4735 info = &bblocks [handler_bb->block_num];
4736 lhs = info->finally_ind;
4739 bb_list = info->call_handler_return_bbs;
4741 resume_bb = gen_bb (ctx, "ENDFINALLY_RESUME_BB");
4743 /* Load the finally variable */
4744 val = LLVMBuildLoad (builder, lhs, "");
4746 /* Reset the variable */
4747 LLVMBuildStore (builder, LLVMConstInt (LLVMInt32Type (), 0, FALSE), lhs);
4749 /* Branch to either resume_bb, or to the bblocks in bb_list */
4750 switch_ins = LLVMBuildSwitch (builder, val, resume_bb, g_slist_length (bb_list));
4752 * The other targets are added at the end to handle OP_CALL_HANDLER
4753 * opcodes processed later.
4755 info->endfinally_switch_ins_list = g_slist_append_mempool (cfg->mempool, info->endfinally_switch_ins_list, switch_ins);
4757 builder = ctx->builder = create_builder (ctx);
4758 LLVMPositionBuilderAtEnd (ctx->builder, resume_bb);
4760 if (ctx->cfg->compile_aot) {
4761 callee = get_plt_entry (ctx, LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE), MONO_PATCH_INFO_INTERNAL_METHOD, "llvm_resume_unwind_trampoline");
4763 callee = LLVMGetNamedFunction (module, "llvm_resume_unwind_trampoline");
4765 LLVMBuildCall (builder, callee, NULL, 0, "");
4767 LLVMBuildUnreachable (builder);
4768 has_terminator = TRUE;
4774 sprintf (reason, "opcode %s", mono_inst_name (ins->opcode));
4775 LLVM_FAILURE (ctx, reason);
4780 /* Convert the value to the type required by phi nodes */
4781 if (spec [MONO_INST_DEST] != ' ' && !MONO_IS_STORE_MEMBASE (ins) && ctx->vreg_types [ins->dreg]) {
4782 if (!values [ins->dreg])
4784 values [ins->dreg] = addresses [ins->dreg];
4786 values [ins->dreg] = convert (ctx, values [ins->dreg], ctx->vreg_types [ins->dreg]);
4789 /* Add stores for volatile variables */
4790 if (spec [MONO_INST_DEST] != ' ' && spec [MONO_INST_DEST] != 'v' && !MONO_IS_STORE_MEMBASE (ins))
4791 emit_volatile_store (ctx, ins->dreg);
4794 if (!has_terminator && bb->next_bb && (bb == cfg->bb_entry || bb->in_count > 0))
4795 LLVMBuildBr (builder, get_bb (ctx, bb->next_bb));
4797 if (bb == cfg->bb_exit && sig->ret->type == MONO_TYPE_VOID) {
4798 emit_dbg_loc (ctx, builder, cfg->header->code + cfg->header->code_size - 1);
4799 LLVMBuildRetVoid (builder);
4802 if (bb == cfg->bb_entry)
4803 ctx->last_alloca = LLVMGetLastInstruction (get_bb (ctx, cfg->bb_entry));
4812 * mono_llvm_check_method_supported:
4814 * Do some quick checks to decide whenever cfg->method can be compiled by LLVM, to avoid
4815 * compiling a method twice.
4818 mono_llvm_check_method_supported (MonoCompile *cfg)
4822 if (cfg->method->save_lmf) {
4823 cfg->exception_message = g_strdup ("lmf");
4824 cfg->disable_llvm = TRUE;
4826 if (cfg->disable_llvm)
4830 * Nested clauses where one of the clauses is a finally clause is
4831 * not supported, because LLVM can't figure out the control flow,
4832 * probably because we resume exception handling by calling our
4833 * own function instead of using the 'resume' llvm instruction.
4835 for (i = 0; i < cfg->header->num_clauses; ++i) {
4836 for (j = 0; j < cfg->header->num_clauses; ++j) {
4837 MonoExceptionClause *clause1 = &cfg->header->clauses [i];
4838 MonoExceptionClause *clause2 = &cfg->header->clauses [j];
4840 if (i != j && clause1->try_offset >= clause2->try_offset && clause1->handler_offset <= clause2->handler_offset &&
4841 (clause1->flags == MONO_EXCEPTION_CLAUSE_FINALLY || clause2->flags == MONO_EXCEPTION_CLAUSE_FINALLY)) {
4842 cfg->exception_message = g_strdup ("nested clauses");
4843 cfg->disable_llvm = TRUE;
4848 if (cfg->disable_llvm)
4852 if (cfg->method->dynamic) {
4853 cfg->exception_message = g_strdup ("dynamic.");
4854 cfg->disable_llvm = TRUE;
4856 if (cfg->disable_llvm)
4861 * mono_llvm_emit_method:
4863 * Emit LLVM IL from the mono IL, and compile it to native code using LLVM.
4866 mono_llvm_emit_method (MonoCompile *cfg)
4869 MonoMethodSignature *sig;
4871 LLVMTypeRef method_type;
4872 LLVMValueRef method = NULL;
4874 LLVMValueRef *values;
4875 int i, max_block_num, bb_index;
4876 gboolean last = FALSE;
4877 GPtrArray *phi_values;
4878 LLVMCallInfo *linfo;
4880 LLVMModuleRef module;
4882 GPtrArray *bblock_list;
4883 MonoMethodHeader *header;
4884 MonoExceptionClause *clause;
4888 /* The code below might acquire the loader lock, so use it for global locking */
4889 mono_loader_lock ();
4891 /* Used to communicate with the callbacks */
4892 mono_native_tls_set_value (current_cfg_tls_id, cfg);
4894 ctx = g_new0 (EmitContext, 1);
4896 ctx->mempool = cfg->mempool;
4899 * This maps vregs to the LLVM instruction defining them
4901 values = g_new0 (LLVMValueRef, cfg->next_vreg);
4903 * This maps vregs for volatile variables to the LLVM instruction defining their
4906 ctx->addresses = g_new0 (LLVMValueRef, cfg->next_vreg);
4907 ctx->vreg_types = g_new0 (LLVMTypeRef, cfg->next_vreg);
4908 ctx->vreg_cli_types = g_new0 (MonoType*, cfg->next_vreg);
4909 phi_values = g_ptr_array_sized_new (256);
4911 * This signals whenever the vreg was defined by a phi node with no input vars
4912 * (i.e. all its input bblocks end with NOT_REACHABLE).
4914 ctx->is_dead = g_new0 (gboolean, cfg->next_vreg);
4915 /* Whenever the bblock is unreachable */
4916 ctx->unreachable = g_new0 (gboolean, cfg->max_block_num);
4918 bblock_list = g_ptr_array_sized_new (256);
4920 ctx->values = values;
4921 ctx->region_to_handler = g_hash_table_new (NULL, NULL);
4922 ctx->clause_to_handler = g_hash_table_new (NULL, NULL);
4924 if (cfg->compile_aot) {
4925 ctx->lmodule = &aot_module;
4926 method_name = mono_aot_get_method_name (cfg);
4927 cfg->llvm_method_name = g_strdup (method_name);
4929 init_jit_module (cfg->domain);
4930 ctx->lmodule = domain_jit_info (cfg->domain)->llvm_module;
4931 method_name = mono_method_full_name (cfg->method, TRUE);
4934 module = ctx->module = ctx->lmodule->module;
4937 LLVM_FAILURE (ctx, "gsharedvt");
4941 static int count = 0;
4944 if (g_getenv ("LLVM_COUNT")) {
4945 if (count == atoi (g_getenv ("LLVM_COUNT"))) {
4946 printf ("LAST: %s\n", mono_method_full_name (cfg->method, TRUE));
4950 if (count > atoi (g_getenv ("LLVM_COUNT")))
4951 LLVM_FAILURE (ctx, "");
4956 sig = mono_method_signature (cfg->method);
4959 linfo = mono_arch_get_llvm_call_info (cfg, sig);
4961 CHECK_FAILURE (ctx);
4964 linfo->rgctx_arg = TRUE;
4965 method_type = sig_to_llvm_sig_full (ctx, sig, linfo, &sinfo);
4966 CHECK_FAILURE (ctx);
4969 * This maps parameter indexes in the original signature to the indexes in
4970 * the LLVM signature.
4972 ctx->pindexes = sinfo.pindexes;
4974 method = LLVMAddFunction (module, method_name, method_type);
4975 ctx->lmethod = method;
4977 LLVMSetFunctionCallConv (method, LLVMMono1CallConv);
4978 LLVMSetLinkage (method, LLVMPrivateLinkage);
4980 LLVMAddFunctionAttr (method, LLVMUWTable);
4982 if (cfg->compile_aot) {
4983 LLVMSetLinkage (method, LLVMInternalLinkage);
4984 if (ctx->lmodule->external_symbols) {
4985 LLVMSetLinkage (method, LLVMExternalLinkage);
4986 LLVMSetVisibility (method, LLVMHiddenVisibility);
4989 LLVMSetLinkage (method, LLVMPrivateLinkage);
4992 if (cfg->method->save_lmf)
4993 LLVM_FAILURE (ctx, "lmf");
4995 if (sig->pinvoke && cfg->method->wrapper_type != MONO_WRAPPER_RUNTIME_INVOKE)
4996 LLVM_FAILURE (ctx, "pinvoke signature");
4998 header = cfg->header;
4999 for (i = 0; i < header->num_clauses; ++i) {
5000 clause = &header->clauses [i];
5001 if (clause->flags != MONO_EXCEPTION_CLAUSE_FINALLY && clause->flags != MONO_EXCEPTION_CLAUSE_NONE)
5002 LLVM_FAILURE (ctx, "non-finally/catch clause.");
5004 if (header->num_clauses || (cfg->method->iflags & METHOD_IMPL_ATTRIBUTE_NOINLINING))
5005 /* We can't handle inlined methods with clauses */
5006 LLVMAddFunctionAttr (method, LLVMNoInlineAttribute);
5008 if (linfo->rgctx_arg) {
5009 ctx->rgctx_arg = LLVMGetParam (method, sinfo.rgctx_arg_pindex);
5011 * We mark the rgctx parameter with the inreg attribute, which is mapped to
5012 * MONO_ARCH_RGCTX_REG in the Mono calling convention in llvm, i.e.
5013 * CC_X86_64_Mono in X86CallingConv.td.
5015 LLVMAddAttribute (ctx->rgctx_arg, LLVMInRegAttribute);
5016 LLVMSetValueName (ctx->rgctx_arg, "rgctx");
5018 if (cfg->vret_addr) {
5019 values [cfg->vret_addr->dreg] = LLVMGetParam (method, sinfo.vret_arg_pindex);
5020 LLVMSetValueName (values [cfg->vret_addr->dreg], "vret");
5023 values [cfg->args [0]->dreg] = LLVMGetParam (method, sinfo.this_arg_pindex);
5024 LLVMSetValueName (values [cfg->args [0]->dreg], "this");
5027 names = g_new (char *, sig->param_count);
5028 mono_method_get_param_names (cfg->method, (const char **) names);
5030 for (i = 0; i < sig->param_count; ++i) {
5033 values [cfg->args [i + sig->hasthis]->dreg] = LLVMGetParam (method, sinfo.pindexes [i]);
5034 if (names [i] && names [i][0] != '\0')
5035 name = g_strdup_printf ("arg_%s", names [i]);
5037 name = g_strdup_printf ("arg_%d", i);
5038 LLVMSetValueName (values [cfg->args [i + sig->hasthis]->dreg], name);
5040 if (linfo->args [i + sig->hasthis].storage == LLVMArgVtypeByVal)
5041 LLVMAddAttribute (LLVMGetParam (method, sinfo.pindexes [i]), LLVMByValAttribute);
5045 if (ctx->lmodule->emit_dwarf && cfg->compile_aot && mono_debug_enabled ()) {
5046 ctx->minfo = mono_debug_lookup_method (cfg->method);
5047 ctx->dbg_md = emit_dbg_subprogram (ctx, cfg, method, method_name);
5051 for (bb = cfg->bb_entry; bb; bb = bb->next_bb)
5052 max_block_num = MAX (max_block_num, bb->block_num);
5053 ctx->bblocks = bblocks = g_new0 (BBInfo, max_block_num + 1);
5055 /* Add branches between non-consecutive bblocks */
5056 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
5057 if (bb->last_ins && MONO_IS_COND_BRANCH_OP (bb->last_ins) &&
5058 bb->next_bb != bb->last_ins->inst_false_bb) {
5060 MonoInst *inst = mono_mempool_alloc0 (cfg->mempool, sizeof (MonoInst));
5061 inst->opcode = OP_BR;
5062 inst->inst_target_bb = bb->last_ins->inst_false_bb;
5063 mono_bblock_add_inst (bb, inst);
5068 * The INDIRECT flag added by OP_LDADDR inhibits optimizations, even if the LDADDR
5069 * was later optimized away, so clear these flags, and add them back for the still
5070 * present OP_LDADDR instructions.
5072 for (i = 0; i < cfg->next_vreg; ++i) {
5075 ins = get_vreg_to_inst (cfg, i);
5076 if (ins && ins != cfg->rgctx_var)
5077 ins->flags &= ~MONO_INST_INDIRECT;
5081 * Make a first pass over the code to precreate PHI nodes/set INDIRECT flags.
5083 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
5085 LLVMBuilderRef builder;
5087 char dname_buf[128];
5089 builder = create_builder (ctx);
5091 for (ins = bb->code; ins; ins = ins->next) {
5092 switch (ins->opcode) {
5097 LLVMTypeRef phi_type = llvm_type_to_stack_type (cfg, type_to_llvm_type (ctx, &ins->klass->byval_arg));
5099 CHECK_FAILURE (ctx);
5101 if (ins->opcode == OP_VPHI) {
5102 /* Treat valuetype PHI nodes as operating on the address itself */
5103 g_assert (ins->klass);
5104 phi_type = LLVMPointerType (type_to_llvm_type (ctx, &ins->klass->byval_arg), 0);
5108 * Have to precreate these, as they can be referenced by
5109 * earlier instructions.
5111 sprintf (dname_buf, "t%d", ins->dreg);
5113 values [ins->dreg] = LLVMBuildPhi (builder, phi_type, dname);
5115 if (ins->opcode == OP_VPHI)
5116 ctx->addresses [ins->dreg] = values [ins->dreg];
5118 g_ptr_array_add (phi_values, values [ins->dreg]);
5121 * Set the expected type of the incoming arguments since these have
5122 * to have the same type.
5124 for (i = 0; i < ins->inst_phi_args [0]; i++) {
5125 int sreg1 = ins->inst_phi_args [i + 1];
5128 ctx->vreg_types [sreg1] = phi_type;
5133 ((MonoInst*)ins->inst_p0)->flags |= MONO_INST_INDIRECT;
5142 * Create an ordering for bblocks, use the depth first order first, then
5143 * put the exception handling bblocks last.
5145 for (bb_index = 0; bb_index < cfg->num_bblocks; ++bb_index) {
5146 bb = cfg->bblocks [bb_index];
5147 if (!(bb->region != -1 && !MONO_BBLOCK_IS_IN_REGION (bb, MONO_REGION_TRY))) {
5148 g_ptr_array_add (bblock_list, bb);
5149 bblocks [bb->block_num].added = TRUE;
5153 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
5154 if (!bblocks [bb->block_num].added)
5155 g_ptr_array_add (bblock_list, bb);
5159 * Second pass: generate code.
5161 for (bb_index = 0; bb_index < bblock_list->len; ++bb_index) {
5162 bb = g_ptr_array_index (bblock_list, bb_index);
5164 if (!(bb == cfg->bb_entry || bb->in_count > 0))
5167 process_bb (ctx, bb);
5168 CHECK_FAILURE (ctx);
5171 /* Add incoming phi values */
5172 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
5173 GSList *l, *ins_list;
5175 ins_list = bblocks [bb->block_num].phi_nodes;
5177 for (l = ins_list; l; l = l->next) {
5178 PhiNode *node = l->data;
5179 MonoInst *phi = node->phi;
5180 int sreg1 = node->sreg;
5181 LLVMBasicBlockRef in_bb;
5186 in_bb = get_end_bb (ctx, node->in_bb);
5188 if (ctx->unreachable [node->in_bb->block_num])
5191 if (!values [sreg1])
5192 /* Can happen with values in EH clauses */
5193 LLVM_FAILURE (ctx, "incoming phi sreg1");
5195 if (phi->opcode == OP_VPHI) {
5196 g_assert (LLVMTypeOf (ctx->addresses [sreg1]) == LLVMTypeOf (values [phi->dreg]));
5197 LLVMAddIncoming (values [phi->dreg], &ctx->addresses [sreg1], &in_bb, 1);
5199 if (LLVMTypeOf (values [sreg1]) != LLVMTypeOf (values [phi->dreg]))
5201 LLVM_FAILURE (ctx, "incoming phi arg type mismatch");
5202 g_assert (LLVMTypeOf (values [sreg1]) == LLVMTypeOf (values [phi->dreg]));
5203 LLVMAddIncoming (values [phi->dreg], &values [sreg1], &in_bb, 1);
5208 /* Create the SWITCH statements for ENDFINALLY instructions */
5209 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
5210 BBInfo *info = &bblocks [bb->block_num];
5212 for (l = info->endfinally_switch_ins_list; l; l = l->next) {
5213 LLVMValueRef switch_ins = l->data;
5214 GSList *bb_list = info->call_handler_return_bbs;
5216 for (i = 0; i < g_slist_length (bb_list); ++i)
5217 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), i + 1, FALSE), g_slist_nth (bb_list, i)->data);
5221 if (cfg->verbose_level > 1)
5222 mono_llvm_dump_value (method);
5224 if (cfg->compile_aot)
5225 mark_as_used (ctx->lmodule, method);
5227 if (cfg->compile_aot) {
5228 LLVMValueRef md_args [16];
5229 LLVMValueRef md_node;
5232 method_index = mono_aot_get_method_index (cfg->orig_method);
5233 md_args [0] = LLVMMDString (method_name, strlen (method_name));
5234 md_args [1] = LLVMConstInt (LLVMInt32Type (), method_index, FALSE);
5235 md_node = LLVMMDNode (md_args, 2);
5236 LLVMAddNamedMetadataOperand (module, "mono.function_indexes", md_node);
5237 //LLVMSetMetadata (method, md_kind, LLVMMDNode (&md_arg, 1));
5240 if (cfg->compile_aot) {
5241 /* Don't generate native code, keep the LLVM IR */
5242 if (cfg->compile_aot && cfg->verbose_level)
5243 printf ("%s emitted as %s\n", mono_method_full_name (cfg->method, TRUE), method_name);
5245 //LLVMVerifyFunction(method, 0);
5247 mono_llvm_optimize_method (ctx->lmodule->mono_ee, method);
5249 if (cfg->verbose_level > 1)
5250 mono_llvm_dump_value (method);
5252 cfg->native_code = LLVMGetPointerToGlobal (ctx->lmodule->ee, method);
5254 /* Set by emit_cb */
5255 g_assert (cfg->code_len);
5257 /* FIXME: Free the LLVM IL for the function */
5260 if (ctx->lmodule->method_to_lmethod)
5261 g_hash_table_insert (ctx->lmodule->method_to_lmethod, cfg->method, method);
5268 /* Need to add unused phi nodes as they can be referenced by other values */
5269 LLVMBasicBlockRef phi_bb = LLVMAppendBasicBlock (method, "PHI_BB");
5270 LLVMBuilderRef builder;
5272 builder = create_builder (ctx);
5273 LLVMPositionBuilderAtEnd (builder, phi_bb);
5275 for (i = 0; i < phi_values->len; ++i) {
5276 LLVMValueRef v = g_ptr_array_index (phi_values, i);
5277 if (LLVMGetInstructionParent (v) == NULL)
5278 LLVMInsertIntoBuilder (builder, v);
5281 LLVMDeleteFunction (method);
5286 g_free (ctx->addresses);
5287 g_free (ctx->vreg_types);
5288 g_free (ctx->vreg_cli_types);
5289 g_free (ctx->pindexes);
5290 g_free (ctx->is_dead);
5291 g_free (ctx->unreachable);
5292 g_ptr_array_free (phi_values, TRUE);
5293 g_free (ctx->bblocks);
5294 g_hash_table_destroy (ctx->region_to_handler);
5295 g_hash_table_destroy (ctx->clause_to_handler);
5296 g_free (method_name);
5297 g_ptr_array_free (bblock_list, TRUE);
5299 for (l = ctx->builders; l; l = l->next) {
5300 LLVMBuilderRef builder = l->data;
5301 LLVMDisposeBuilder (builder);
5306 mono_native_tls_set_value (current_cfg_tls_id, NULL);
5308 mono_loader_unlock ();
5312 * mono_llvm_emit_call:
5314 * Same as mono_arch_emit_call () for LLVM.
5317 mono_llvm_emit_call (MonoCompile *cfg, MonoCallInst *call)
5320 MonoMethodSignature *sig;
5321 int i, n, stack_size;
5326 sig = call->signature;
5327 n = sig->param_count + sig->hasthis;
5329 call->cinfo = mono_arch_get_llvm_call_info (cfg, sig);
5331 if (cfg->disable_llvm)
5334 if (sig->call_convention == MONO_CALL_VARARG) {
5335 cfg->exception_message = g_strdup ("varargs");
5336 cfg->disable_llvm = TRUE;
5339 for (i = 0; i < n; ++i) {
5342 ainfo = call->cinfo->args + i;
5344 in = call->args [i];
5346 /* Simply remember the arguments */
5347 switch (ainfo->storage) {
5349 case LLVMArgInFPReg: {
5350 MonoType *t = (sig->hasthis && i == 0) ? &mono_get_intptr_class ()->byval_arg : sig->params [i - sig->hasthis];
5353 opcode = mono_type_to_regmove (cfg, t);
5354 if (opcode == OP_FMOVE) {
5355 MONO_INST_NEW (cfg, ins, OP_FMOVE);
5356 ins->dreg = mono_alloc_freg (cfg);
5357 } else if (opcode == OP_LMOVE) {
5358 MONO_INST_NEW (cfg, ins, OP_LMOVE);
5359 ins->dreg = mono_alloc_lreg (cfg);
5361 MONO_INST_NEW (cfg, ins, OP_MOVE);
5362 ins->dreg = mono_alloc_ireg (cfg);
5364 ins->sreg1 = in->dreg;
5367 case LLVMArgVtypeByVal:
5368 case LLVMArgVtypeInReg:
5369 case LLVMArgAsIArgs:
5370 case LLVMArgAsFpArgs:
5371 MONO_INST_NEW (cfg, ins, OP_LLVM_OUTARG_VT);
5372 ins->dreg = mono_alloc_ireg (cfg);
5373 ins->sreg1 = in->dreg;
5374 ins->klass = mono_class_from_mono_type (sig->params [i - sig->hasthis]);
5377 call->cinfo = mono_arch_get_llvm_call_info (cfg, sig);
5378 cfg->exception_message = g_strdup ("ainfo->storage");
5379 cfg->disable_llvm = TRUE;
5383 if (!cfg->disable_llvm) {
5384 MONO_ADD_INS (cfg->cbb, ins);
5385 mono_call_inst_add_outarg_reg (cfg, call, ins->dreg, 0, FALSE);
5390 static unsigned char*
5391 alloc_cb (LLVMValueRef function, int size)
5395 cfg = mono_native_tls_get_value (current_cfg_tls_id);
5399 return mono_domain_code_reserve (cfg->domain, size);
5401 return mono_domain_code_reserve (mono_domain_get (), size);
5406 emitted_cb (LLVMValueRef function, void *start, void *end)
5410 cfg = mono_native_tls_get_value (current_cfg_tls_id);
5412 cfg->code_len = (guint8*)end - (guint8*)start;
5416 exception_cb (void *data)
5419 MonoJitExceptionInfo *ei;
5420 guint32 ei_len, i, j, nested_len, nindex;
5421 gpointer *type_info;
5422 int this_reg, this_offset;
5424 cfg = mono_native_tls_get_value (current_cfg_tls_id);
5428 * data points to a DWARF FDE structure, convert it to our unwind format and
5430 * An alternative would be to save it directly, and modify our unwinder to work
5433 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);
5434 if (cfg->verbose_level > 1)
5435 mono_print_unwind_info (cfg->encoded_unwind_ops, cfg->encoded_unwind_ops_len);
5437 /* Count nested clauses */
5439 for (i = 0; i < ei_len; ++i) {
5440 for (j = 0; j < ei_len; ++j) {
5441 gint32 cindex1 = *(gint32*)type_info [i];
5442 MonoExceptionClause *clause1 = &cfg->header->clauses [cindex1];
5443 gint32 cindex2 = *(gint32*)type_info [j];
5444 MonoExceptionClause *clause2 = &cfg->header->clauses [cindex2];
5446 if (cindex1 != cindex2 && clause1->try_offset >= clause2->try_offset && clause1->handler_offset <= clause2->handler_offset) {
5452 cfg->llvm_ex_info = mono_mempool_alloc0 (cfg->mempool, (ei_len + nested_len) * sizeof (MonoJitExceptionInfo));
5453 cfg->llvm_ex_info_len = ei_len + nested_len;
5454 memcpy (cfg->llvm_ex_info, ei, ei_len * sizeof (MonoJitExceptionInfo));
5455 /* Fill the rest of the information from the type info */
5456 for (i = 0; i < ei_len; ++i) {
5457 gint32 clause_index = *(gint32*)type_info [i];
5458 MonoExceptionClause *clause = &cfg->header->clauses [clause_index];
5460 cfg->llvm_ex_info [i].flags = clause->flags;
5461 cfg->llvm_ex_info [i].data.catch_class = clause->data.catch_class;
5462 cfg->llvm_ex_info [i].clause_index = clause_index;
5466 * For nested clauses, the LLVM produced exception info associates the try interval with
5467 * the innermost handler, while mono expects it to be associated with all nesting clauses.
5468 * So add new clauses which use the IL info (catch class etc.) from the nesting clause,
5469 * and everything else from the nested clause.
5472 for (i = 0; i < ei_len; ++i) {
5473 for (j = 0; j < ei_len; ++j) {
5474 gint32 cindex1 = *(gint32*)type_info [i];
5475 MonoExceptionClause *clause1 = &cfg->header->clauses [cindex1];
5476 gint32 cindex2 = *(gint32*)type_info [j];
5477 MonoExceptionClause *clause2 = &cfg->header->clauses [cindex2];
5479 if (cindex1 != cindex2 && clause1->try_offset >= clause2->try_offset && clause1->handler_offset <= clause2->handler_offset) {
5480 memcpy (&cfg->llvm_ex_info [nindex], &cfg->llvm_ex_info [j], sizeof (MonoJitExceptionInfo));
5481 cfg->llvm_ex_info [nindex].try_start = cfg->llvm_ex_info [i].try_start;
5482 cfg->llvm_ex_info [nindex].try_end = cfg->llvm_ex_info [i].try_end;
5483 cfg->llvm_ex_info [nindex].handler_start = cfg->llvm_ex_info [i].handler_start;
5484 cfg->llvm_ex_info [nindex].exvar_offset = cfg->llvm_ex_info [i].exvar_offset;
5489 g_assert (nindex == ei_len + nested_len);
5490 cfg->llvm_this_reg = this_reg;
5491 cfg->llvm_this_offset = this_offset;
5493 /* type_info [i] is cfg mempool allocated, no need to free it */
5500 dlsym_cb (const char *name, void **symbol)
5506 if (!strcmp (name, "__bzero")) {
5507 *symbol = (void*)bzero;
5509 current = mono_dl_open (NULL, 0, NULL);
5512 err = mono_dl_symbol (current, name, symbol);
5514 mono_dl_close (current);
5516 #ifdef MONO_ARCH_HAVE_CREATE_LLVM_NATIVE_THUNK
5517 *symbol = (char*)mono_arch_create_llvm_native_thunk (mono_domain_get (), (guint8*)(*symbol));
5523 AddFunc (LLVMModuleRef module, const char *name, LLVMTypeRef ret_type, LLVMTypeRef *param_types, int nparams)
5525 LLVMAddFunction (module, name, LLVMFunctionType (ret_type, param_types, nparams, FALSE));
5529 AddFunc2 (LLVMModuleRef module, const char *name, LLVMTypeRef ret_type, LLVMTypeRef param_type1, LLVMTypeRef param_type2)
5531 LLVMTypeRef param_types [4];
5533 param_types [0] = param_type1;
5534 param_types [1] = param_type2;
5536 AddFunc (module, name, ret_type, param_types, 2);
5540 add_intrinsics (LLVMModuleRef module)
5542 /* Emit declarations of instrinsics */
5544 * It would be nicer to emit only the intrinsics actually used, but LLVM's Module
5545 * type doesn't seem to do any locking.
5548 LLVMTypeRef memset_params [] = { LLVMPointerType (LLVMInt8Type (), 0), LLVMInt8Type (), LLVMInt32Type (), LLVMInt32Type (), LLVMInt1Type () };
5550 memset_param_count = 5;
5551 memset_func_name = "llvm.memset.p0i8.i32";
5553 LLVMAddFunction (module, memset_func_name, LLVMFunctionType (LLVMVoidType (), memset_params, memset_param_count, FALSE));
5557 LLVMTypeRef memcpy_params [] = { LLVMPointerType (LLVMInt8Type (), 0), LLVMPointerType (LLVMInt8Type (), 0), LLVMInt32Type (), LLVMInt32Type (), LLVMInt1Type () };
5559 memcpy_param_count = 5;
5560 memcpy_func_name = "llvm.memcpy.p0i8.p0i8.i32";
5562 LLVMAddFunction (module, memcpy_func_name, LLVMFunctionType (LLVMVoidType (), memcpy_params, memcpy_param_count, FALSE));
5566 LLVMTypeRef params [] = { LLVMDoubleType () };
5568 LLVMAddFunction (module, "llvm.sin.f64", LLVMFunctionType (LLVMDoubleType (), params, 1, FALSE));
5569 LLVMAddFunction (module, "llvm.cos.f64", LLVMFunctionType (LLVMDoubleType (), params, 1, FALSE));
5570 LLVMAddFunction (module, "llvm.sqrt.f64", LLVMFunctionType (LLVMDoubleType (), params, 1, FALSE));
5572 /* This isn't an intrinsic, instead llvm seems to special case it by name */
5573 LLVMAddFunction (module, "fabs", LLVMFunctionType (LLVMDoubleType (), params, 1, FALSE));
5577 LLVMTypeRef ovf_res_i32 [] = { LLVMInt32Type (), LLVMInt1Type () };
5578 LLVMTypeRef ovf_params_i32 [] = { LLVMInt32Type (), LLVMInt32Type () };
5580 LLVMAddFunction (module, "llvm.sadd.with.overflow.i32", LLVMFunctionType (LLVMStructType (ovf_res_i32, 2, FALSE), ovf_params_i32, 2, FALSE));
5581 LLVMAddFunction (module, "llvm.uadd.with.overflow.i32", LLVMFunctionType (LLVMStructType (ovf_res_i32, 2, FALSE), ovf_params_i32, 2, FALSE));
5582 LLVMAddFunction (module, "llvm.ssub.with.overflow.i32", LLVMFunctionType (LLVMStructType (ovf_res_i32, 2, FALSE), ovf_params_i32, 2, FALSE));
5583 LLVMAddFunction (module, "llvm.usub.with.overflow.i32", LLVMFunctionType (LLVMStructType (ovf_res_i32, 2, FALSE), ovf_params_i32, 2, FALSE));
5584 LLVMAddFunction (module, "llvm.smul.with.overflow.i32", LLVMFunctionType (LLVMStructType (ovf_res_i32, 2, FALSE), ovf_params_i32, 2, FALSE));
5585 LLVMAddFunction (module, "llvm.umul.with.overflow.i32", LLVMFunctionType (LLVMStructType (ovf_res_i32, 2, FALSE), ovf_params_i32, 2, FALSE));
5589 LLVMTypeRef ovf_res_i64 [] = { LLVMInt64Type (), LLVMInt1Type () };
5590 LLVMTypeRef ovf_params_i64 [] = { LLVMInt64Type (), LLVMInt64Type () };
5592 LLVMAddFunction (module, "llvm.sadd.with.overflow.i64", LLVMFunctionType (LLVMStructType (ovf_res_i64, 2, FALSE), ovf_params_i64, 2, FALSE));
5593 LLVMAddFunction (module, "llvm.uadd.with.overflow.i64", LLVMFunctionType (LLVMStructType (ovf_res_i64, 2, FALSE), ovf_params_i64, 2, FALSE));
5594 LLVMAddFunction (module, "llvm.ssub.with.overflow.i64", LLVMFunctionType (LLVMStructType (ovf_res_i64, 2, FALSE), ovf_params_i64, 2, FALSE));
5595 LLVMAddFunction (module, "llvm.usub.with.overflow.i64", LLVMFunctionType (LLVMStructType (ovf_res_i64, 2, FALSE), ovf_params_i64, 2, FALSE));
5596 LLVMAddFunction (module, "llvm.smul.with.overflow.i64", LLVMFunctionType (LLVMStructType (ovf_res_i64, 2, FALSE), ovf_params_i64, 2, FALSE));
5597 LLVMAddFunction (module, "llvm.umul.with.overflow.i64", LLVMFunctionType (LLVMStructType (ovf_res_i64, 2, FALSE), ovf_params_i64, 2, FALSE));
5602 LLVMTypeRef arg_types [2];
5603 LLVMTypeRef ret_type;
5605 arg_types [0] = LLVMPointerType (LLVMInt8Type (), 0);
5606 arg_types [1] = LLVMPointerType (LLVMInt8Type (), 0);
5607 ret_type = LLVMInt32Type ();
5609 LLVMAddFunction (module, "mono_personality", LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE));
5611 LLVMAddFunction (module, "llvm_resume_unwind_trampoline", LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE));
5614 /* SSE intrinsics */
5615 #if defined(TARGET_X86) || defined(TARGET_AMD64)
5617 LLVMTypeRef ret_type, arg_types [16];
5620 ret_type = type_to_simd_type (MONO_TYPE_I4);
5621 arg_types [0] = ret_type;
5622 arg_types [1] = ret_type;
5623 AddFunc (module, "llvm.x86.sse41.pminud", ret_type, arg_types, 2);
5624 AddFunc (module, "llvm.x86.sse41.pmaxud", ret_type, arg_types, 2);
5626 ret_type = type_to_simd_type (MONO_TYPE_I2);
5627 arg_types [0] = ret_type;
5628 arg_types [1] = ret_type;
5629 AddFunc (module, "llvm.x86.sse41.pminuw", ret_type, arg_types, 2);
5630 AddFunc (module, "llvm.x86.sse2.pmins.w", ret_type, arg_types, 2);
5631 AddFunc (module, "llvm.x86.sse41.pmaxuw", ret_type, arg_types, 2);
5632 AddFunc (module, "llvm.x86.sse2.padds.w", ret_type, arg_types, 2);
5633 AddFunc (module, "llvm.x86.sse2.psubs.w", ret_type, arg_types, 2);
5634 AddFunc (module, "llvm.x86.sse2.paddus.w", ret_type, arg_types, 2);
5635 AddFunc (module, "llvm.x86.sse2.psubus.w", ret_type, arg_types, 2);
5636 AddFunc (module, "llvm.x86.sse2.pavg.w", ret_type, arg_types, 2);
5637 AddFunc (module, "llvm.x86.sse2.pmulh.w", ret_type, arg_types, 2);
5638 AddFunc (module, "llvm.x86.sse2.pmulhu.w", ret_type, arg_types, 2);
5640 ret_type = type_to_simd_type (MONO_TYPE_I1);
5641 arg_types [0] = ret_type;
5642 arg_types [1] = ret_type;
5643 AddFunc (module, "llvm.x86.sse2.pminu.b", ret_type, arg_types, 2);
5644 AddFunc (module, "llvm.x86.sse2.pmaxu.b", ret_type, arg_types, 2);
5645 AddFunc (module, "llvm.x86.sse2.padds.b", ret_type, arg_types, 2);
5646 AddFunc (module, "llvm.x86.sse2.psubs.b", ret_type, arg_types, 2);
5647 AddFunc (module, "llvm.x86.sse2.paddus.b", ret_type, arg_types, 2);
5648 AddFunc (module, "llvm.x86.sse2.psubus.b", ret_type, arg_types, 2);
5649 AddFunc (module, "llvm.x86.sse2.pavg.b", ret_type, arg_types, 2);
5651 ret_type = type_to_simd_type (MONO_TYPE_R8);
5652 arg_types [0] = ret_type;
5653 arg_types [1] = ret_type;
5654 AddFunc (module, "llvm.x86.sse2.min.pd", ret_type, arg_types, 2);
5655 AddFunc (module, "llvm.x86.sse2.max.pd", ret_type, arg_types, 2);
5656 AddFunc (module, "llvm.x86.sse3.hadd.pd", ret_type, arg_types, 2);
5657 AddFunc (module, "llvm.x86.sse3.hsub.pd", ret_type, arg_types, 2);
5658 AddFunc (module, "llvm.x86.sse3.addsub.pd", ret_type, arg_types, 2);
5660 ret_type = type_to_simd_type (MONO_TYPE_R4);
5661 arg_types [0] = ret_type;
5662 arg_types [1] = ret_type;
5663 AddFunc (module, "llvm.x86.sse.min.ps", ret_type, arg_types, 2);
5664 AddFunc (module, "llvm.x86.sse.max.ps", ret_type, arg_types, 2);
5665 AddFunc (module, "llvm.x86.sse3.hadd.ps", ret_type, arg_types, 2);
5666 AddFunc (module, "llvm.x86.sse3.hsub.ps", ret_type, arg_types, 2);
5667 AddFunc (module, "llvm.x86.sse3.addsub.ps", ret_type, arg_types, 2);
5670 ret_type = type_to_simd_type (MONO_TYPE_I1);
5671 arg_types [0] = type_to_simd_type (MONO_TYPE_I2);
5672 arg_types [1] = type_to_simd_type (MONO_TYPE_I2);
5673 AddFunc (module, "llvm.x86.sse2.packsswb.128", ret_type, arg_types, 2);
5674 AddFunc (module, "llvm.x86.sse2.packuswb.128", ret_type, arg_types, 2);
5675 ret_type = type_to_simd_type (MONO_TYPE_I2);
5676 arg_types [0] = type_to_simd_type (MONO_TYPE_I4);
5677 arg_types [1] = type_to_simd_type (MONO_TYPE_I4);
5678 AddFunc (module, "llvm.x86.sse2.packssdw.128", ret_type, arg_types, 2);
5679 AddFunc (module, "llvm.x86.sse41.packusdw", ret_type, arg_types, 2);
5682 ret_type = type_to_simd_type (MONO_TYPE_R8);
5683 arg_types [0] = ret_type;
5684 arg_types [1] = ret_type;
5685 arg_types [2] = LLVMInt8Type ();
5686 AddFunc (module, "llvm.x86.sse2.cmp.pd", ret_type, arg_types, 3);
5687 ret_type = type_to_simd_type (MONO_TYPE_R4);
5688 arg_types [0] = ret_type;
5689 arg_types [1] = ret_type;
5690 arg_types [2] = LLVMInt8Type ();
5691 AddFunc (module, "llvm.x86.sse.cmp.ps", ret_type, arg_types, 3);
5693 /* Conversion ops */
5694 ret_type = type_to_simd_type (MONO_TYPE_R8);
5695 arg_types [0] = type_to_simd_type (MONO_TYPE_I4);
5696 AddFunc (module, "llvm.x86.sse2.cvtdq2pd", ret_type, arg_types, 1);
5697 ret_type = type_to_simd_type (MONO_TYPE_R4);
5698 arg_types [0] = type_to_simd_type (MONO_TYPE_I4);
5699 AddFunc (module, "llvm.x86.sse2.cvtdq2ps", ret_type, arg_types, 1);
5700 ret_type = type_to_simd_type (MONO_TYPE_I4);
5701 arg_types [0] = type_to_simd_type (MONO_TYPE_R8);
5702 AddFunc (module, "llvm.x86.sse2.cvtpd2dq", ret_type, arg_types, 1);
5703 ret_type = type_to_simd_type (MONO_TYPE_I4);
5704 arg_types [0] = type_to_simd_type (MONO_TYPE_R4);
5705 AddFunc (module, "llvm.x86.sse2.cvtps2dq", ret_type, arg_types, 1);
5706 ret_type = type_to_simd_type (MONO_TYPE_R4);
5707 arg_types [0] = type_to_simd_type (MONO_TYPE_R8);
5708 AddFunc (module, "llvm.x86.sse2.cvtpd2ps", ret_type, arg_types, 1);
5709 ret_type = type_to_simd_type (MONO_TYPE_R8);
5710 arg_types [0] = type_to_simd_type (MONO_TYPE_R4);
5711 AddFunc (module, "llvm.x86.sse2.cvtps2pd", ret_type, arg_types, 1);
5713 ret_type = type_to_simd_type (MONO_TYPE_I4);
5714 arg_types [0] = type_to_simd_type (MONO_TYPE_R8);
5715 AddFunc (module, "llvm.x86.sse2.cvttpd2dq", ret_type, arg_types, 1);
5716 ret_type = type_to_simd_type (MONO_TYPE_I4);
5717 arg_types [0] = type_to_simd_type (MONO_TYPE_R4);
5718 AddFunc (module, "llvm.x86.sse2.cvttps2dq", ret_type, arg_types, 1);
5721 ret_type = type_to_simd_type (MONO_TYPE_R8);
5722 arg_types [0] = ret_type;
5723 AddFunc (module, "llvm.x86.sse2.sqrt.pd", ret_type, arg_types, 1);
5724 ret_type = type_to_simd_type (MONO_TYPE_R4);
5725 arg_types [0] = ret_type;
5726 AddFunc (module, "llvm.x86.sse.sqrt.ps", ret_type, arg_types, 1);
5727 ret_type = type_to_simd_type (MONO_TYPE_R4);
5728 arg_types [0] = ret_type;
5729 AddFunc (module, "llvm.x86.sse.rsqrt.ps", ret_type, arg_types, 1);
5730 ret_type = type_to_simd_type (MONO_TYPE_R4);
5731 arg_types [0] = ret_type;
5732 AddFunc (module, "llvm.x86.sse.rcp.ps", ret_type, arg_types, 1);
5735 ret_type = type_to_simd_type (MONO_TYPE_I2);
5736 arg_types [0] = ret_type;
5737 arg_types [1] = LLVMInt32Type ();
5738 AddFunc (module, "llvm.x86.sse2.psrli.w", ret_type, arg_types, 2);
5739 AddFunc (module, "llvm.x86.sse2.psrai.w", ret_type, arg_types, 2);
5740 AddFunc (module, "llvm.x86.sse2.pslli.w", ret_type, arg_types, 2);
5741 ret_type = type_to_simd_type (MONO_TYPE_I4);
5742 arg_types [0] = ret_type;
5743 arg_types [1] = LLVMInt32Type ();
5744 AddFunc (module, "llvm.x86.sse2.psrli.d", ret_type, arg_types, 2);
5745 AddFunc (module, "llvm.x86.sse2.psrai.d", ret_type, arg_types, 2);
5746 AddFunc (module, "llvm.x86.sse2.pslli.d", ret_type, arg_types, 2);
5747 ret_type = type_to_simd_type (MONO_TYPE_I8);
5748 arg_types [0] = ret_type;
5749 arg_types [1] = LLVMInt32Type ();
5750 AddFunc (module, "llvm.x86.sse2.psrli.q", ret_type, arg_types, 2);
5751 AddFunc (module, "llvm.x86.sse2.pslli.q", ret_type, arg_types, 2);
5754 ret_type = LLVMInt32Type ();
5755 arg_types [0] = type_to_simd_type (MONO_TYPE_I1);
5756 AddFunc (module, "llvm.x86.sse2.pmovmskb.128", ret_type, arg_types, 1);
5759 AddFunc (module, "llvm.x86.sse2.pause", LLVMVoidType (), NULL, 0);
5762 /* Load/Store intrinsics */
5764 LLVMTypeRef arg_types [5];
5768 for (i = 1; i <= 8; i *= 2) {
5769 arg_types [0] = LLVMPointerType (LLVMIntType (i * 8), 0);
5770 arg_types [1] = LLVMInt32Type ();
5771 arg_types [2] = LLVMInt1Type ();
5772 arg_types [3] = LLVMInt32Type ();
5773 sprintf (name, "llvm.mono.load.i%d.p0i%d", i * 8, i * 8);
5774 LLVMAddFunction (module, name, LLVMFunctionType (LLVMIntType (i * 8), arg_types, 4, FALSE));
5776 arg_types [0] = LLVMIntType (i * 8);
5777 arg_types [1] = LLVMPointerType (LLVMIntType (i * 8), 0);
5778 arg_types [2] = LLVMInt32Type ();
5779 arg_types [3] = LLVMInt1Type ();
5780 arg_types [4] = LLVMInt32Type ();
5781 sprintf (name, "llvm.mono.store.i%d.p0i%d", i * 8, i * 8);
5782 LLVMAddFunction (module, name, LLVMFunctionType (LLVMVoidType (), arg_types, 5, FALSE));
5788 add_types (MonoLLVMModule *lmodule)
5790 lmodule->ptr_type = LLVMPointerType (sizeof (gpointer) == 8 ? LLVMInt64Type () : LLVMInt32Type (), 0);
5794 mono_llvm_init (void)
5796 mono_native_tls_alloc (¤t_cfg_tls_id, NULL);
5800 init_jit_module (MonoDomain *domain)
5802 MonoJitICallInfo *info;
5803 MonoJitDomainInfo *dinfo;
5804 MonoLLVMModule *module;
5807 dinfo = domain_jit_info (domain);
5808 if (dinfo->llvm_module)
5811 mono_loader_lock ();
5813 if (dinfo->llvm_module) {
5814 mono_loader_unlock ();
5818 module = g_new0 (MonoLLVMModule, 1);
5820 name = g_strdup_printf ("mono-%s", domain->friendly_name);
5821 module->module = LLVMModuleCreateWithName (name);
5823 module->mono_ee = mono_llvm_create_ee (LLVMCreateModuleProviderForExistingModule (module->module), alloc_cb, emitted_cb, exception_cb, dlsym_cb, &module->ee);
5825 add_intrinsics (module->module);
5828 module->llvm_types = g_hash_table_new (NULL, NULL);
5830 info = mono_find_jit_icall_by_name ("llvm_resume_unwind_trampoline");
5832 LLVMAddGlobalMapping (module->ee, LLVMGetNamedFunction (module->module, "llvm_resume_unwind_trampoline"), (void*)info->func);
5834 mono_memory_barrier ();
5836 dinfo->llvm_module = module;
5838 mono_loader_unlock ();
5842 mono_llvm_cleanup (void)
5844 if (aot_module.module)
5845 LLVMDisposeModule (aot_module.module);
5847 LLVMContextDispose (LLVMGetGlobalContext ());
5851 mono_llvm_free_domain_info (MonoDomain *domain)
5853 MonoJitDomainInfo *info = domain_jit_info (domain);
5854 MonoLLVMModule *module = info->llvm_module;
5860 if (module->llvm_types)
5861 g_hash_table_destroy (module->llvm_types);
5863 mono_llvm_dispose_ee (module->mono_ee);
5865 if (module->bb_names) {
5866 for (i = 0; i < module->bb_names_len; ++i)
5867 g_free (module->bb_names [i]);
5868 g_free (module->bb_names);
5870 //LLVMDisposeModule (module->module);
5874 info->llvm_module = NULL;
5878 mono_llvm_create_aot_module (const char *got_symbol, gboolean external_symbols, gboolean emit_dwarf)
5880 /* Delete previous module */
5881 if (aot_module.plt_entries)
5882 g_hash_table_destroy (aot_module.plt_entries);
5883 if (aot_module.module)
5884 LLVMDisposeModule (aot_module.module);
5886 memset (&aot_module, 0, sizeof (aot_module));
5888 aot_module.module = LLVMModuleCreateWithName ("aot");
5889 aot_module.got_symbol = got_symbol;
5890 aot_module.external_symbols = external_symbols;
5891 aot_module.emit_dwarf = emit_dwarf;
5892 /* The first few entries are reserved */
5893 aot_module.max_got_offset = 16;
5895 add_intrinsics (aot_module.module);
5896 add_types (&aot_module);
5900 * We couldn't compute the type of the LLVM global representing the got because
5901 * its size is only known after all the methods have been emitted. So create
5902 * a dummy variable, and replace all uses it with the real got variable when
5903 * its size is known in mono_llvm_emit_aot_module ().
5906 LLVMTypeRef got_type = LLVMArrayType (aot_module.ptr_type, 0);
5908 aot_module.got_var = LLVMAddGlobal (aot_module.module, got_type, "mono_dummy_got");
5909 LLVMSetInitializer (aot_module.got_var, LLVMConstNull (got_type));
5912 /* Add a dummy personality function */
5914 LLVMBasicBlockRef lbb;
5915 LLVMBuilderRef lbuilder;
5916 LLVMValueRef personality;
5918 personality = LLVMAddFunction (aot_module.module, "mono_aot_personality", LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE));
5919 LLVMSetLinkage (personality, LLVMInternalLinkage);
5920 lbb = LLVMAppendBasicBlock (personality, "BB0");
5921 lbuilder = LLVMCreateBuilder ();
5922 LLVMPositionBuilderAtEnd (lbuilder, lbb);
5923 LLVMBuildRetVoid (lbuilder);
5924 mark_as_used (&aot_module, personality);
5927 aot_module.llvm_types = g_hash_table_new (NULL, NULL);
5928 aot_module.plt_entries = g_hash_table_new (g_str_hash, g_str_equal);
5929 aot_module.plt_entries_ji = g_hash_table_new (NULL, NULL);
5930 aot_module.method_to_lmethod = g_hash_table_new (NULL, NULL);
5934 * Emit the aot module into the LLVM bitcode file FILENAME.
5937 mono_llvm_emit_aot_module (const char *filename, const char *cu_name)
5939 LLVMTypeRef got_type;
5940 LLVMValueRef real_got;
5941 MonoLLVMModule *module = &aot_module;
5944 * Create the real got variable and replace all uses of the dummy variable with
5947 got_type = LLVMArrayType (aot_module.ptr_type, module->max_got_offset + 1);
5948 real_got = LLVMAddGlobal (aot_module.module, got_type, aot_module.got_symbol);
5949 LLVMSetInitializer (real_got, LLVMConstNull (got_type));
5950 if (module->external_symbols) {
5951 LLVMSetLinkage (real_got, LLVMExternalLinkage);
5952 LLVMSetVisibility (real_got, LLVMHiddenVisibility);
5954 LLVMSetLinkage (real_got, LLVMInternalLinkage);
5956 mono_llvm_replace_uses_of (aot_module.got_var, real_got);
5958 mark_as_used (&aot_module, real_got);
5960 /* Delete the dummy got so it doesn't become a global */
5961 LLVMDeleteGlobal (aot_module.got_var);
5963 emit_llvm_used (&aot_module);
5964 emit_dbg_info (&aot_module, filename, cu_name);
5966 /* Replace PLT entries for directly callable methods with the methods themselves */
5968 GHashTableIter iter;
5970 LLVMValueRef callee;
5972 g_hash_table_iter_init (&iter, aot_module.plt_entries_ji);
5973 while (g_hash_table_iter_next (&iter, (void**)&ji, (void**)&callee)) {
5974 if (mono_aot_is_direct_callable (ji)) {
5975 LLVMValueRef lmethod;
5977 lmethod = g_hash_table_lookup (module->method_to_lmethod, ji->data.method);
5978 /* The types might not match because the caller might pass an rgctx */
5979 if (lmethod && LLVMTypeOf (callee) == LLVMTypeOf (lmethod)) {
5980 mono_llvm_replace_uses_of (callee, lmethod);
5981 mono_aot_mark_unused_llvm_plt_entry (ji);
5991 if (LLVMVerifyModule (aot_module.module, LLVMReturnStatusAction, &verifier_err)) {
5992 g_assert_not_reached ();
5997 LLVMWriteBitcodeToFile (aot_module.module, filename);
6002 md_string (const char *s)
6004 return LLVMMDString (s, strlen (s));
6007 /* Debugging support */
6010 emit_dbg_info (MonoLLVMModule *lmodule, const char *filename, const char *cu_name)
6012 LLVMModuleRef module = lmodule->module;
6013 LLVMValueRef args [16], cu_args [16], cu, ver;
6015 char *build_info, *s, *dir;
6018 * This can only be enabled when LLVM code is emitted into a separate object
6019 * file, since the AOT compiler also emits dwarf info,
6020 * and the abbrev indexes will not be correct since llvm has added its own
6023 if (!lmodule->emit_dwarf)
6027 * Emit dwarf info in the form of LLVM metadata. There is some
6028 * out-of-date documentation at:
6029 * http://llvm.org/docs/SourceLevelDebugging.html
6030 * but most of this was gathered from the llvm and
6035 cu_args [n_cuargs ++] = LLVMConstInt (LLVMInt32Type (), DW_TAG_compile_unit, FALSE);
6036 /* CU name/compilation dir */
6037 dir = g_path_get_dirname (filename);
6038 args [0] = LLVMMDString (cu_name, strlen (cu_name));
6039 args [1] = LLVMMDString (dir, strlen (dir));
6040 cu_args [n_cuargs ++] = LLVMMDNode (args, 2);
6043 cu_args [n_cuargs ++] = LLVMConstInt (LLVMInt32Type (), DW_LANG_C99, FALSE);
6045 build_info = mono_get_runtime_build_info ();
6046 s = g_strdup_printf ("Mono AOT Compiler %s (LLVM)", build_info);
6047 cu_args [n_cuargs ++] = LLVMMDString (s, strlen (s));
6048 g_free (build_info);
6050 cu_args [n_cuargs ++] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
6052 cu_args [n_cuargs ++] = LLVMMDString ("", strlen (""));
6053 /* Runtime version */
6054 cu_args [n_cuargs ++] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
6056 cu_args [n_cuargs ++] = LLVMMDNode (args, 0);
6057 cu_args [n_cuargs ++] = LLVMMDNode (args, 0);
6059 if (lmodule->subprogram_mds) {
6063 mds = g_new0 (LLVMValueRef, lmodule->subprogram_mds->len);
6064 for (i = 0; i < lmodule->subprogram_mds->len; ++i)
6065 mds [i] = g_ptr_array_index (lmodule->subprogram_mds, i);
6066 cu_args [n_cuargs ++] = LLVMMDNode (mds, lmodule->subprogram_mds->len);
6068 cu_args [n_cuargs ++] = LLVMMDNode (args, 0);
6071 cu_args [n_cuargs ++] = LLVMMDNode (args, 0);
6072 /* Imported modules */
6073 cu_args [n_cuargs ++] = LLVMMDNode (args, 0);
6075 cu_args [n_cuargs ++] = LLVMMDString ("", strlen (""));
6076 /* DebugEmissionKind = FullDebug */
6077 cu_args [n_cuargs ++] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
6078 cu = LLVMMDNode (cu_args, n_cuargs);
6079 LLVMAddNamedMetadataOperand (module, "llvm.dbg.cu", cu);
6081 args [0] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
6082 args [1] = LLVMMDString ("Dwarf Version", strlen ("Dwarf Version"));
6083 args [2] = LLVMConstInt (LLVMInt32Type (), 2, FALSE);
6084 ver = LLVMMDNode (args, 3);
6085 LLVMAddNamedMetadataOperand (module, "llvm.module.flags", ver);
6087 args [0] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
6088 args [1] = LLVMMDString ("Debug Info Version", strlen ("Debug Info Version"));
6089 args [2] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
6090 ver = LLVMMDNode (args, 3);
6091 LLVMAddNamedMetadataOperand (module, "llvm.module.flags", ver);
6095 emit_dbg_subprogram (EmitContext *ctx, MonoCompile *cfg, LLVMValueRef method, const char *name)
6097 MonoLLVMModule *module = ctx->lmodule;
6098 MonoDebugMethodInfo *minfo = ctx->minfo;
6099 char *source_file, *dir, *filename;
6100 LLVMValueRef md, args [16], ctx_args [16], md_args [64], type_args [16], ctx_md, type_md;
6108 mono_debug_symfile_get_line_numbers_full (minfo, &source_file, NULL, &n_il_offsets, &il_offsets, &line_numbers, NULL, NULL, NULL, NULL);
6110 source_file = g_strdup ("<unknown>");
6111 dir = g_path_get_dirname (source_file);
6112 filename = g_path_get_basename (source_file);
6114 ctx_args [0] = LLVMConstInt (LLVMInt32Type (), 0x29, FALSE);
6115 args [0] = md_string (filename);
6116 args [1] = md_string (dir);
6117 ctx_args [1] = LLVMMDNode (args, 2);
6118 ctx_md = LLVMMDNode (ctx_args, 2);
6120 type_args [0] = LLVMConstInt (LLVMInt32Type (), DW_TAG_subroutine_type, FALSE);
6121 type_args [1] = NULL;
6122 type_args [2] = NULL;
6123 type_args [3] = LLVMMDString ("", 0);
6124 type_args [4] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
6125 type_args [5] = LLVMConstInt (LLVMInt64Type (), 0, FALSE);
6126 type_args [6] = LLVMConstInt (LLVMInt64Type (), 0, FALSE);
6127 type_args [7] = LLVMConstInt (LLVMInt64Type (), 0, FALSE);
6128 type_args [8] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
6129 type_args [9] = NULL;
6130 type_args [10] = NULL;
6131 type_args [11] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
6132 type_args [12] = NULL;
6133 type_args [13] = NULL;
6134 type_args [14] = NULL;
6135 type_md = LLVMMDNode (type_args, 14);
6137 /* http://llvm.org/docs/SourceLevelDebugging.html#subprogram-descriptors */
6138 md_args [0] = LLVMConstInt (LLVMInt32Type (), DW_TAG_subprogram, FALSE);
6139 /* Source directory + file pair */
6140 args [0] = md_string (filename);
6141 args [1] = md_string (dir);
6142 md_args [1] = LLVMMDNode (args ,2);
6143 md_args [2] = ctx_md;
6144 md_args [3] = md_string (cfg->method->name);
6145 md_args [4] = md_string (name);
6146 md_args [5] = md_string (name);
6149 md_args [6] = LLVMConstInt (LLVMInt32Type (), line_numbers [0], FALSE);
6151 md_args [6] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
6153 md_args [7] = type_md;
6155 md_args [8] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
6157 md_args [9] = LLVMConstInt (LLVMInt1Type (), 1, FALSE);
6159 md_args [10] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
6160 /* Index into a virtual function */
6161 md_args [11] = NULL;
6162 md_args [12] = NULL;
6164 md_args [13] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
6166 md_args [14] = LLVMConstInt (LLVMInt1Type (), 1, FALSE);
6167 /* Pointer to LLVM function */
6168 md_args [15] = method;
6169 /* Function template parameter */
6170 md_args [16] = NULL;
6171 /* Function declaration descriptor */
6172 md_args [17] = NULL;
6173 /* List of function variables */
6174 md_args [18] = LLVMMDNode (args, 0);
6176 md_args [19] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
6177 md = LLVMMDNode (md_args, 20);
6179 if (!module->subprogram_mds)
6180 module->subprogram_mds = g_ptr_array_new ();
6181 g_ptr_array_add (module->subprogram_mds, md);
6185 g_free (source_file);
6186 g_free (il_offsets);
6187 g_free (line_numbers);
6193 emit_dbg_loc (EmitContext *ctx, LLVMBuilderRef builder, const unsigned char *cil_code)
6195 MonoCompile *cfg = ctx->cfg;
6197 if (ctx->minfo && cil_code && cil_code >= cfg->header->code && cil_code < cfg->header->code + cfg->header->code_size) {
6198 MonoDebugSourceLocation *loc;
6199 LLVMValueRef loc_md, md_args [16];
6202 loc = mono_debug_symfile_lookup_location (ctx->minfo, cil_code - cfg->header->code);
6206 md_args [nmd_args ++] = LLVMConstInt (LLVMInt32Type (), loc->row, FALSE);
6207 md_args [nmd_args ++] = LLVMConstInt (LLVMInt32Type (), loc->column, FALSE);
6208 md_args [nmd_args ++] = ctx->dbg_md;
6209 md_args [nmd_args ++] = NULL;
6210 loc_md = LLVMMDNode (md_args, nmd_args);
6211 LLVMSetCurrentDebugLocation (builder, loc_md);
6212 mono_debug_symfile_free_location (loc);
6219 - Emit LLVM IR from the mono IR using the LLVM C API.
6220 - The original arch specific code remains, so we can fall back to it if we run
6221 into something we can't handle.
6225 A partial list of issues:
6226 - Handling of opcodes which can throw exceptions.
6228 In the mono JIT, these are implemented using code like this:
6235 push throw_pos - method
6236 call <exception trampoline>
6238 The problematic part is push throw_pos - method, which cannot be represented
6239 in the LLVM IR, since it does not support label values.
6240 -> this can be implemented in AOT mode using inline asm + labels, but cannot
6241 be implemented in JIT mode ?
6242 -> a possible but slower implementation would use the normal exception
6243 throwing code but it would need to control the placement of the throw code
6244 (it needs to be exactly after the compare+branch).
6245 -> perhaps add a PC offset intrinsics ?
6247 - efficient implementation of .ovf opcodes.
6249 These are currently implemented as:
6250 <ins which sets the condition codes>
6253 Some overflow opcodes are now supported by LLVM SVN.
6255 - exception handling, unwinding.
6256 - SSA is disabled for methods with exception handlers
6257 - How to obtain unwind info for LLVM compiled methods ?
6258 -> this is now solved by converting the unwind info generated by LLVM
6260 - LLVM uses the c++ exception handling framework, while we use our home grown
6261 code, and couldn't use the c++ one:
6262 - its not supported under VC++, other exotic platforms.
6263 - it might be impossible to support filter clauses with it.
6267 The trampolines need a predictable call sequence, since they need to disasm
6268 the calling code to obtain register numbers / offsets.
6270 LLVM currently generates this code in non-JIT mode:
6271 mov -0x98(%rax),%eax
6273 Here, the vtable pointer is lost.
6274 -> solution: use one vtable trampoline per class.
6276 - passing/receiving the IMT pointer/RGCTX.
6277 -> solution: pass them as normal arguments ?
6281 LLVM does not allow the specification of argument registers etc. This means
6282 that all calls are made according to the platform ABI.
6284 - passing/receiving vtypes.
6286 Vtypes passed/received in registers are handled by the front end by using
6287 a signature with scalar arguments, and loading the parts of the vtype into those
6290 Vtypes passed on the stack are handled using the 'byval' attribute.
6294 Supported though alloca, we need to emit the load/store code.
6298 The mono JIT uses pointer sized iregs/double fregs, while LLVM uses precisely
6299 typed registers, so we have to keep track of the precise LLVM type of each vreg.
6300 This is made easier because the IR is already in SSA form.
6301 An additional problem is that our IR is not consistent with types, i.e. i32/ia64
6302 types are frequently used incorrectly.
6307 Emit LLVM bytecode into a .bc file, compile it using llc into a .s file, then link
6308 it with the file containing the methods emitted by the JIT and the AOT data
6312 /* FIXME: Normalize some aspects of the mono IR to allow easier translation, like:
6313 * - each bblock should end with a branch
6314 * - setting the return value, making cfg->ret non-volatile
6315 * - avoid some transformations in the JIT which make it harder for us to generate
6317 * - use pointer types to help optimizations.