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);
2662 process_bb (EmitContext *ctx, MonoBasicBlock *bb)
2664 MonoCompile *cfg = ctx->cfg;
2665 MonoMethodSignature *sig = ctx->sig;
2666 LLVMValueRef method = ctx->lmethod;
2667 LLVMValueRef *values = ctx->values;
2668 LLVMValueRef *addresses = ctx->addresses;
2669 LLVMCallInfo *linfo = ctx->linfo;
2670 LLVMModuleRef module = ctx->module;
2671 BBInfo *bblocks = ctx->bblocks;
2673 LLVMBasicBlockRef cbb;
2674 LLVMBuilderRef builder, starting_builder;
2675 gboolean has_terminator;
2677 LLVMValueRef lhs, rhs;
2680 cbb = get_bb (ctx, bb);
2681 builder = create_builder (ctx);
2682 ctx->builder = builder;
2683 LLVMPositionBuilderAtEnd (builder, cbb);
2685 if (bb == cfg->bb_entry)
2686 emit_entry_bb (ctx, builder);
2687 CHECK_FAILURE (ctx);
2689 if (bb->flags & BB_EXCEPTION_HANDLER) {
2690 if (!bblocks [bb->block_num].invoke_target) {
2692 * LLVM asserts if llvm.eh.selector is called from a bblock which
2693 * doesn't have an invoke pointing at it.
2694 * Update: LLVM no longer asserts, but some tests in exceptions.exe now fail.
2696 LLVM_FAILURE (ctx, "handler without invokes");
2699 emit_handler_start (ctx, bb, builder);
2700 builder = ctx->builder;
2703 has_terminator = FALSE;
2704 starting_builder = builder;
2705 for (ins = bb->code; ins; ins = ins->next) {
2706 const char *spec = LLVM_INS_INFO (ins->opcode);
2708 char dname_buf [128];
2710 emit_dbg_loc (ctx, builder, ins->cil_code);
2713 if (nins > 5000 && builder == starting_builder) {
2714 /* some steps in llc are non-linear in the size of basic blocks, see #5714 */
2715 LLVM_FAILURE (ctx, "basic block too long");
2719 /* There could be instructions after a terminator, skip them */
2722 if (spec [MONO_INST_DEST] != ' ' && !MONO_IS_STORE_MEMBASE (ins)) {
2723 sprintf (dname_buf, "t%d", ins->dreg);
2727 if (spec [MONO_INST_SRC1] != ' ' && spec [MONO_INST_SRC1] != 'v') {
2728 MonoInst *var = get_vreg_to_inst (cfg, ins->sreg1);
2730 if (var && var->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT)) {
2731 lhs = emit_volatile_load (ctx, ins->sreg1);
2733 /* It is ok for SETRET to have an uninitialized argument */
2734 if (!values [ins->sreg1] && ins->opcode != OP_SETRET)
2735 LLVM_FAILURE (ctx, "sreg1");
2736 lhs = values [ins->sreg1];
2742 if (spec [MONO_INST_SRC2] != ' ' && spec [MONO_INST_SRC2] != ' ') {
2743 MonoInst *var = get_vreg_to_inst (cfg, ins->sreg2);
2744 if (var && var->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT)) {
2745 rhs = emit_volatile_load (ctx, ins->sreg2);
2747 if (!values [ins->sreg2])
2748 LLVM_FAILURE (ctx, "sreg2");
2749 rhs = values [ins->sreg2];
2755 //mono_print_ins (ins);
2756 switch (ins->opcode) {
2759 case OP_LIVERANGE_START:
2760 case OP_LIVERANGE_END:
2763 values [ins->dreg] = LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE);
2766 #if SIZEOF_VOID_P == 4
2767 values [ins->dreg] = LLVMConstInt (LLVMInt64Type (), GET_LONG_IMM (ins), FALSE);
2769 values [ins->dreg] = LLVMConstInt (LLVMInt64Type (), (gint64)ins->inst_c0, FALSE);
2773 values [ins->dreg] = LLVMConstReal (LLVMDoubleType (), *(double*)ins->inst_p0);
2777 values [ins->dreg] = LLVMConstReal (LLVMFloatType (), *(float*)ins->inst_p0);
2779 values [ins->dreg] = LLVMConstFPExt (LLVMConstReal (LLVMFloatType (), *(float*)ins->inst_p0), LLVMDoubleType ());
2781 case OP_DUMMY_ICONST:
2782 values [ins->dreg] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
2784 case OP_DUMMY_I8CONST:
2785 values [ins->dreg] = LLVMConstInt (LLVMInt64Type (), 0, FALSE);
2787 case OP_DUMMY_R8CONST:
2788 values [ins->dreg] = LLVMConstReal (LLVMDoubleType (), 0.0f);
2791 LLVMBuildBr (builder, get_bb (ctx, ins->inst_target_bb));
2792 has_terminator = TRUE;
2798 LLVMBasicBlockRef new_bb;
2799 LLVMBuilderRef new_builder;
2801 // The default branch is already handled
2802 // FIXME: Handle it here
2804 /* Start new bblock */
2805 sprintf (bb_name, "SWITCH_DEFAULT_BB%d", ctx->default_index ++);
2806 new_bb = LLVMAppendBasicBlock (ctx->lmethod, bb_name);
2808 lhs = convert (ctx, lhs, LLVMInt32Type ());
2809 v = LLVMBuildSwitch (builder, lhs, new_bb, GPOINTER_TO_UINT (ins->klass));
2810 for (i = 0; i < GPOINTER_TO_UINT (ins->klass); ++i) {
2811 MonoBasicBlock *target_bb = ins->inst_many_bb [i];
2813 LLVMAddCase (v, LLVMConstInt (LLVMInt32Type (), i, FALSE), get_bb (ctx, target_bb));
2816 new_builder = create_builder (ctx);
2817 LLVMPositionBuilderAtEnd (new_builder, new_bb);
2818 LLVMBuildUnreachable (new_builder);
2820 has_terminator = TRUE;
2821 g_assert (!ins->next);
2827 if (linfo->ret.storage == LLVMArgVtypeInReg) {
2828 LLVMTypeRef ret_type = LLVMGetReturnType (LLVMGetElementType (LLVMTypeOf (method)));
2829 LLVMValueRef part1, retval;
2832 size = get_vtype_size (sig->ret);
2834 g_assert (addresses [ins->sreg1]);
2836 g_assert (linfo->ret.pair_storage [0] == LLVMArgInIReg);
2837 g_assert (linfo->ret.pair_storage [1] == LLVMArgNone);
2839 part1 = convert (ctx, LLVMBuildLoad (builder, LLVMBuildBitCast (builder, addresses [ins->sreg1], LLVMPointerType (LLVMIntType (size * 8), 0), ""), ""), IntPtrType ());
2841 retval = LLVMBuildInsertValue (builder, LLVMGetUndef (ret_type), part1, 0, "");
2843 LLVMBuildRet (builder, retval);
2847 if (linfo->ret.storage == LLVMArgVtypeByVal) {
2848 LLVMValueRef retval;
2850 g_assert (addresses [ins->sreg1]);
2851 retval = LLVMBuildLoad (builder, addresses [ins->sreg1], "");
2852 LLVMBuildRet (builder, retval);
2856 if (linfo->ret.storage == LLVMArgVtypeRetAddr) {
2857 LLVMBuildRetVoid (builder);
2861 if (linfo->ret.storage == LLVMArgFpStruct) {
2862 LLVMTypeRef ret_type = LLVMGetReturnType (LLVMGetElementType (LLVMTypeOf (method)));
2863 LLVMValueRef retval;
2865 g_assert (addresses [ins->sreg1]);
2866 retval = LLVMBuildLoad (builder, convert (ctx, addresses [ins->sreg1], LLVMPointerType (ret_type, 0)), "");
2867 LLVMBuildRet (builder, retval);
2871 if (!lhs || ctx->is_dead [ins->sreg1]) {
2873 * The method did not set its return value, probably because it
2874 * ends with a throw.
2877 LLVMBuildRetVoid (builder);
2879 LLVMBuildRet (builder, LLVMConstNull (type_to_llvm_type (ctx, sig->ret)));
2881 LLVMBuildRet (builder, convert (ctx, lhs, type_to_llvm_type (ctx, sig->ret)));
2883 has_terminator = TRUE;
2890 case OP_ICOMPARE_IMM:
2891 case OP_LCOMPARE_IMM:
2892 case OP_COMPARE_IMM: {
2896 if (ins->next->opcode == OP_NOP)
2899 if (ins->next->opcode == OP_BR)
2900 /* The comparison result is not needed */
2903 rel = mono_opcode_to_cond (ins->next->opcode);
2905 if (ins->opcode == OP_ICOMPARE_IMM) {
2906 lhs = convert (ctx, lhs, LLVMInt32Type ());
2907 rhs = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
2909 if (ins->opcode == OP_LCOMPARE_IMM) {
2910 lhs = convert (ctx, lhs, LLVMInt64Type ());
2911 rhs = LLVMConstInt (LLVMInt64Type (), GET_LONG_IMM (ins), FALSE);
2913 if (ins->opcode == OP_LCOMPARE) {
2914 lhs = convert (ctx, lhs, LLVMInt64Type ());
2915 rhs = convert (ctx, rhs, LLVMInt64Type ());
2917 if (ins->opcode == OP_ICOMPARE) {
2918 lhs = convert (ctx, lhs, LLVMInt32Type ());
2919 rhs = convert (ctx, rhs, LLVMInt32Type ());
2923 if (LLVMGetTypeKind (LLVMTypeOf (lhs)) == LLVMPointerTypeKind)
2924 rhs = convert (ctx, rhs, LLVMTypeOf (lhs));
2925 else if (LLVMGetTypeKind (LLVMTypeOf (rhs)) == LLVMPointerTypeKind)
2926 lhs = convert (ctx, lhs, LLVMTypeOf (rhs));
2929 /* We use COMPARE+SETcc/Bcc, llvm uses SETcc+br cond */
2930 if (ins->opcode == OP_FCOMPARE) {
2931 cmp = LLVMBuildFCmp (builder, fpcond_to_llvm_cond [rel], convert (ctx, lhs, LLVMDoubleType ()), convert (ctx, rhs, LLVMDoubleType ()), "");
2932 } else if (ins->opcode == OP_RCOMPARE) {
2933 cmp = LLVMBuildFCmp (builder, fpcond_to_llvm_cond [rel], convert (ctx, lhs, LLVMFloatType ()), convert (ctx, rhs, LLVMFloatType ()), "");
2934 } else if (ins->opcode == OP_COMPARE_IMM) {
2935 if (LLVMGetTypeKind (LLVMTypeOf (lhs)) == LLVMPointerTypeKind && ins->inst_imm == 0)
2936 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], lhs, LLVMConstNull (LLVMTypeOf (lhs)), "");
2938 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE), "");
2939 } else if (ins->opcode == OP_LCOMPARE_IMM) {
2940 if (SIZEOF_REGISTER == 4 && COMPILE_LLVM (cfg)) {
2941 /* The immediate is encoded in two fields */
2942 guint64 l = ((guint64)(guint32)ins->inst_offset << 32) | ((guint32)ins->inst_imm);
2943 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, LLVMInt64Type ()), LLVMConstInt (LLVMInt64Type (), l, FALSE), "");
2945 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, LLVMInt64Type ()), LLVMConstInt (LLVMInt64Type (), ins->inst_imm, FALSE), "");
2948 else if (ins->opcode == OP_COMPARE) {
2949 if (LLVMGetTypeKind (LLVMTypeOf (lhs)) == LLVMPointerTypeKind && LLVMTypeOf (lhs) == LLVMTypeOf (rhs))
2950 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], lhs, rhs, "");
2952 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, IntPtrType ()), convert (ctx, rhs, IntPtrType ()), "");
2954 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], lhs, rhs, "");
2956 if (MONO_IS_COND_BRANCH_OP (ins->next)) {
2957 if (ins->next->inst_true_bb == ins->next->inst_false_bb) {
2959 * If the target bb contains PHI instructions, LLVM requires
2960 * two PHI entries for this bblock, while we only generate one.
2961 * So convert this to an unconditional bblock. (bxc #171).
2963 LLVMBuildBr (builder, get_bb (ctx, ins->next->inst_true_bb));
2965 LLVMBuildCondBr (builder, cmp, get_bb (ctx, ins->next->inst_true_bb), get_bb (ctx, ins->next->inst_false_bb));
2967 has_terminator = TRUE;
2968 } else if (MONO_IS_SETCC (ins->next)) {
2969 sprintf (dname_buf, "t%d", ins->next->dreg);
2971 values [ins->next->dreg] = LLVMBuildZExt (builder, cmp, LLVMInt32Type (), dname);
2973 /* Add stores for volatile variables */
2974 emit_volatile_store (ctx, ins->next->dreg);
2975 } else if (MONO_IS_COND_EXC (ins->next)) {
2976 emit_cond_system_exception (ctx, bb, ins->next->inst_p1, cmp);
2977 CHECK_FAILURE (ctx);
2978 builder = ctx->builder;
2980 LLVM_FAILURE (ctx, "next");
2994 rel = mono_opcode_to_cond (ins->opcode);
2996 cmp = LLVMBuildFCmp (builder, fpcond_to_llvm_cond [rel], convert (ctx, lhs, LLVMDoubleType ()), convert (ctx, rhs, LLVMDoubleType ()), "");
2997 values [ins->dreg] = LLVMBuildZExt (builder, cmp, LLVMInt32Type (), dname);
3008 rel = mono_opcode_to_cond (ins->opcode);
3010 cmp = LLVMBuildFCmp (builder, fpcond_to_llvm_cond [rel], convert (ctx, lhs, LLVMFloatType ()), convert (ctx, rhs, LLVMFloatType ()), "");
3011 values [ins->dreg] = LLVMBuildZExt (builder, cmp, LLVMInt32Type (), dname);
3019 gboolean empty = TRUE;
3021 /* Check that all input bblocks really branch to us */
3022 for (i = 0; i < bb->in_count; ++i) {
3023 if (bb->in_bb [i]->last_ins && bb->in_bb [i]->last_ins->opcode == OP_NOT_REACHED)
3024 ins->inst_phi_args [i + 1] = -1;
3030 /* LLVM doesn't like phi instructions with zero operands */
3031 ctx->is_dead [ins->dreg] = TRUE;
3035 /* Created earlier, insert it now */
3036 LLVMInsertIntoBuilder (builder, values [ins->dreg]);
3038 for (i = 0; i < ins->inst_phi_args [0]; i++) {
3039 int sreg1 = ins->inst_phi_args [i + 1];
3043 * Count the number of times the incoming bblock branches to us,
3044 * since llvm requires a separate entry for each.
3046 if (bb->in_bb [i]->last_ins && bb->in_bb [i]->last_ins->opcode == OP_SWITCH) {
3047 MonoInst *switch_ins = bb->in_bb [i]->last_ins;
3050 for (j = 0; j < GPOINTER_TO_UINT (switch_ins->klass); ++j) {
3051 if (switch_ins->inst_many_bb [j] == bb)
3058 /* Remember for later */
3059 for (j = 0; j < count; ++j) {
3060 PhiNode *node = mono_mempool_alloc0 (ctx->mempool, sizeof (PhiNode));
3063 node->in_bb = bb->in_bb [i];
3065 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);
3075 values [ins->dreg] = lhs;
3079 MonoInst *var = get_vreg_to_inst (cfg, ins->dreg);
3082 values [ins->dreg] = lhs;
3084 if (var && var->klass->byval_arg.type == MONO_TYPE_R4) {
3086 * This is added by the spilling pass in case of the JIT,
3087 * but we have to do it ourselves.
3089 values [ins->dreg] = convert (ctx, values [ins->dreg], LLVMFloatType ());
3093 case OP_MOVE_F_TO_I4: {
3094 values [ins->dreg] = LLVMBuildBitCast (builder, LLVMBuildFPTrunc (builder, lhs, LLVMFloatType (), ""), LLVMInt32Type (), "");
3097 case OP_MOVE_I4_TO_F: {
3098 values [ins->dreg] = LLVMBuildFPExt (builder, LLVMBuildBitCast (builder, lhs, LLVMFloatType (), ""), LLVMDoubleType (), "");
3101 case OP_MOVE_F_TO_I8: {
3102 values [ins->dreg] = LLVMBuildBitCast (builder, lhs, LLVMInt64Type (), "");
3105 case OP_MOVE_I8_TO_F: {
3106 values [ins->dreg] = LLVMBuildBitCast (builder, lhs, LLVMDoubleType (), "");
3139 lhs = convert (ctx, lhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
3140 rhs = convert (ctx, rhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
3142 emit_div_check (ctx, builder, bb, ins, lhs, rhs);
3143 CHECK_FAILURE (ctx);
3144 builder = ctx->builder;
3146 switch (ins->opcode) {
3149 values [ins->dreg] = LLVMBuildAdd (builder, lhs, rhs, dname);
3153 values [ins->dreg] = LLVMBuildSub (builder, lhs, rhs, dname);
3157 values [ins->dreg] = LLVMBuildMul (builder, lhs, rhs, dname);
3161 values [ins->dreg] = LLVMBuildSRem (builder, lhs, rhs, dname);
3165 values [ins->dreg] = LLVMBuildURem (builder, lhs, rhs, dname);
3169 values [ins->dreg] = LLVMBuildSDiv (builder, lhs, rhs, dname);
3173 values [ins->dreg] = LLVMBuildUDiv (builder, lhs, rhs, dname);
3177 values [ins->dreg] = LLVMBuildFDiv (builder, lhs, rhs, dname);
3181 values [ins->dreg] = LLVMBuildAnd (builder, lhs, rhs, dname);
3185 values [ins->dreg] = LLVMBuildOr (builder, lhs, rhs, dname);
3189 values [ins->dreg] = LLVMBuildXor (builder, lhs, rhs, dname);
3193 values [ins->dreg] = LLVMBuildShl (builder, lhs, rhs, dname);
3197 values [ins->dreg] = LLVMBuildAShr (builder, lhs, rhs, dname);
3201 values [ins->dreg] = LLVMBuildLShr (builder, lhs, rhs, dname);
3205 values [ins->dreg] = LLVMBuildFAdd (builder, lhs, rhs, dname);
3208 values [ins->dreg] = LLVMBuildFSub (builder, lhs, rhs, dname);
3211 values [ins->dreg] = LLVMBuildFMul (builder, lhs, rhs, dname);
3215 g_assert_not_reached ();
3222 lhs = convert (ctx, lhs, LLVMFloatType ());
3223 rhs = convert (ctx, rhs, LLVMFloatType ());
3224 switch (ins->opcode) {
3226 values [ins->dreg] = LLVMBuildFAdd (builder, lhs, rhs, dname);
3229 values [ins->dreg] = LLVMBuildFSub (builder, lhs, rhs, dname);
3232 values [ins->dreg] = LLVMBuildFMul (builder, lhs, rhs, dname);
3235 values [ins->dreg] = LLVMBuildFDiv (builder, lhs, rhs, dname);
3238 g_assert_not_reached ();
3247 case OP_IREM_UN_IMM:
3249 case OP_IDIV_UN_IMM:
3255 case OP_ISHR_UN_IMM:
3264 case OP_LSHR_UN_IMM:
3270 case OP_SHR_UN_IMM: {
3273 if (spec [MONO_INST_SRC1] == 'l') {
3274 imm = LLVMConstInt (LLVMInt64Type (), GET_LONG_IMM (ins), FALSE);
3276 imm = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
3279 emit_div_check (ctx, builder, bb, ins, lhs, imm);
3280 CHECK_FAILURE (ctx);
3281 builder = ctx->builder;
3283 #if SIZEOF_VOID_P == 4
3284 if (ins->opcode == OP_LSHL_IMM || ins->opcode == OP_LSHR_IMM || ins->opcode == OP_LSHR_UN_IMM)
3285 imm = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
3288 if (LLVMGetTypeKind (LLVMTypeOf (lhs)) == LLVMPointerTypeKind)
3289 lhs = convert (ctx, lhs, IntPtrType ());
3290 imm = convert (ctx, imm, LLVMTypeOf (lhs));
3291 switch (ins->opcode) {
3295 values [ins->dreg] = LLVMBuildAdd (builder, lhs, imm, dname);
3299 values [ins->dreg] = LLVMBuildSub (builder, lhs, imm, dname);
3303 values [ins->dreg] = LLVMBuildMul (builder, lhs, imm, dname);
3307 values [ins->dreg] = LLVMBuildSDiv (builder, lhs, imm, dname);
3309 case OP_IDIV_UN_IMM:
3310 case OP_LDIV_UN_IMM:
3311 values [ins->dreg] = LLVMBuildUDiv (builder, lhs, imm, dname);
3315 values [ins->dreg] = LLVMBuildSRem (builder, lhs, imm, dname);
3317 case OP_IREM_UN_IMM:
3318 values [ins->dreg] = LLVMBuildURem (builder, lhs, imm, dname);
3323 values [ins->dreg] = LLVMBuildAnd (builder, lhs, imm, dname);
3327 values [ins->dreg] = LLVMBuildOr (builder, lhs, imm, dname);
3331 values [ins->dreg] = LLVMBuildXor (builder, lhs, imm, dname);
3336 values [ins->dreg] = LLVMBuildShl (builder, lhs, imm, dname);
3341 values [ins->dreg] = LLVMBuildAShr (builder, lhs, imm, dname);
3343 case OP_ISHR_UN_IMM:
3344 /* This is used to implement conv.u4, so the lhs could be an i8 */
3345 lhs = convert (ctx, lhs, LLVMInt32Type ());
3346 imm = convert (ctx, imm, LLVMInt32Type ());
3347 values [ins->dreg] = LLVMBuildLShr (builder, lhs, imm, dname);
3349 case OP_LSHR_UN_IMM:
3351 values [ins->dreg] = LLVMBuildLShr (builder, lhs, imm, dname);
3354 g_assert_not_reached ();
3359 values [ins->dreg] = LLVMBuildSub (builder, LLVMConstInt (LLVMInt32Type (), 0, FALSE), convert (ctx, lhs, LLVMInt32Type ()), dname);
3362 values [ins->dreg] = LLVMBuildSub (builder, LLVMConstInt (LLVMInt64Type (), 0, FALSE), lhs, dname);
3365 lhs = convert (ctx, lhs, LLVMDoubleType ());
3366 values [ins->dreg] = LLVMBuildFSub (builder, LLVMConstReal (LLVMDoubleType (), 0.0), lhs, dname);
3369 lhs = convert (ctx, lhs, LLVMFloatType ());
3370 values [ins->dreg] = LLVMBuildFSub (builder, LLVMConstReal (LLVMFloatType (), 0.0), lhs, dname);
3373 guint32 v = 0xffffffff;
3374 values [ins->dreg] = LLVMBuildXor (builder, LLVMConstInt (LLVMInt32Type (), v, FALSE), convert (ctx, lhs, LLVMInt32Type ()), dname);
3378 guint64 v = 0xffffffffffffffffLL;
3379 values [ins->dreg] = LLVMBuildXor (builder, LLVMConstInt (LLVMInt64Type (), v, FALSE), lhs, dname);
3382 #if defined(TARGET_X86) || defined(TARGET_AMD64)
3384 LLVMValueRef v1, v2;
3386 v1 = LLVMBuildMul (builder, convert (ctx, rhs, IntPtrType ()), LLVMConstInt (IntPtrType (), (1 << ins->backend.shift_amount), FALSE), "");
3387 v2 = LLVMBuildAdd (builder, convert (ctx, lhs, IntPtrType ()), v1, "");
3388 values [ins->dreg] = LLVMBuildAdd (builder, v2, LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE), dname);
3393 case OP_ICONV_TO_I1:
3394 case OP_ICONV_TO_I2:
3395 case OP_ICONV_TO_I4:
3396 case OP_ICONV_TO_U1:
3397 case OP_ICONV_TO_U2:
3398 case OP_ICONV_TO_U4:
3399 case OP_LCONV_TO_I1:
3400 case OP_LCONV_TO_I2:
3401 case OP_LCONV_TO_U1:
3402 case OP_LCONV_TO_U2:
3403 case OP_LCONV_TO_U4: {
3406 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);
3408 /* Have to do two casts since our vregs have type int */
3409 v = LLVMBuildTrunc (builder, lhs, op_to_llvm_type (ins->opcode), "");
3411 values [ins->dreg] = LLVMBuildSExt (builder, v, LLVMInt32Type (), dname);
3413 values [ins->dreg] = LLVMBuildZExt (builder, v, LLVMInt32Type (), dname);
3416 case OP_ICONV_TO_I8:
3417 values [ins->dreg] = LLVMBuildSExt (builder, lhs, LLVMInt64Type (), dname);
3419 case OP_ICONV_TO_U8:
3420 values [ins->dreg] = LLVMBuildZExt (builder, lhs, LLVMInt64Type (), dname);
3422 case OP_FCONV_TO_I4:
3423 case OP_RCONV_TO_I4:
3424 values [ins->dreg] = LLVMBuildFPToSI (builder, lhs, LLVMInt32Type (), dname);
3426 case OP_FCONV_TO_I1:
3427 case OP_RCONV_TO_I1:
3428 values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildFPToSI (builder, lhs, LLVMInt8Type (), dname), LLVMInt32Type (), "");
3430 case OP_FCONV_TO_U1:
3431 case OP_RCONV_TO_U1:
3432 values [ins->dreg] = LLVMBuildZExt (builder, LLVMBuildFPToUI (builder, lhs, LLVMInt8Type (), dname), LLVMInt32Type (), "");
3434 case OP_FCONV_TO_I2:
3435 case OP_RCONV_TO_I2:
3436 values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildFPToSI (builder, lhs, LLVMInt16Type (), dname), LLVMInt32Type (), "");
3438 case OP_FCONV_TO_U2:
3439 case OP_RCONV_TO_U2:
3440 values [ins->dreg] = LLVMBuildZExt (builder, LLVMBuildFPToUI (builder, lhs, LLVMInt16Type (), dname), LLVMInt32Type (), "");
3442 case OP_FCONV_TO_I8:
3443 case OP_RCONV_TO_I8:
3444 values [ins->dreg] = LLVMBuildFPToSI (builder, lhs, LLVMInt64Type (), dname);
3447 values [ins->dreg] = LLVMBuildFPToSI (builder, lhs, IntPtrType (), dname);
3449 case OP_ICONV_TO_R8:
3450 case OP_LCONV_TO_R8:
3451 values [ins->dreg] = LLVMBuildSIToFP (builder, lhs, LLVMDoubleType (), dname);
3453 case OP_LCONV_TO_R_UN:
3454 values [ins->dreg] = LLVMBuildUIToFP (builder, lhs, LLVMDoubleType (), dname);
3456 #if SIZEOF_VOID_P == 4
3459 case OP_LCONV_TO_I4:
3460 values [ins->dreg] = LLVMBuildTrunc (builder, lhs, LLVMInt32Type (), dname);
3462 case OP_ICONV_TO_R4:
3463 case OP_LCONV_TO_R4:
3464 v = LLVMBuildSIToFP (builder, lhs, LLVMFloatType (), "");
3466 values [ins->dreg] = v;
3468 values [ins->dreg] = LLVMBuildFPExt (builder, v, LLVMDoubleType (), dname);
3470 case OP_FCONV_TO_R4:
3471 v = LLVMBuildFPTrunc (builder, lhs, LLVMFloatType (), "");
3473 values [ins->dreg] = v;
3475 values [ins->dreg] = LLVMBuildFPExt (builder, v, LLVMDoubleType (), dname);
3477 case OP_RCONV_TO_R8:
3478 values [ins->dreg] = LLVMBuildFPExt (builder, lhs, LLVMDoubleType (), dname);
3480 case OP_RCONV_TO_R4:
3481 values [ins->dreg] = lhs;
3484 values [ins->dreg] = LLVMBuildSExt (builder, convert (ctx, lhs, LLVMInt32Type ()), LLVMInt64Type (), dname);
3487 values [ins->dreg] = LLVMBuildZExt (builder, convert (ctx, lhs, LLVMInt32Type ()), LLVMInt64Type (), dname);
3490 values [ins->dreg] = LLVMBuildTrunc (builder, lhs, LLVMInt32Type (), dname);
3492 case OP_LOCALLOC_IMM: {
3495 guint32 size = ins->inst_imm;
3496 size = (size + (MONO_ARCH_FRAME_ALIGNMENT - 1)) & ~ (MONO_ARCH_FRAME_ALIGNMENT - 1);
3498 v = mono_llvm_build_alloca (builder, LLVMInt8Type (), LLVMConstInt (LLVMInt32Type (), size, FALSE), MONO_ARCH_FRAME_ALIGNMENT, "");
3500 if (ins->flags & MONO_INST_INIT) {
3501 LLVMValueRef args [5];
3504 args [1] = LLVMConstInt (LLVMInt8Type (), 0, FALSE);
3505 args [2] = LLVMConstInt (LLVMInt32Type (), size, FALSE);
3506 args [3] = LLVMConstInt (LLVMInt32Type (), MONO_ARCH_FRAME_ALIGNMENT, FALSE);
3507 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
3508 LLVMBuildCall (builder, LLVMGetNamedFunction (module, memset_func_name), args, memset_param_count, "");
3511 values [ins->dreg] = v;
3515 LLVMValueRef v, size;
3517 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), "");
3519 v = mono_llvm_build_alloca (builder, LLVMInt8Type (), size, MONO_ARCH_FRAME_ALIGNMENT, "");
3521 if (ins->flags & MONO_INST_INIT) {
3522 LLVMValueRef args [5];
3525 args [1] = LLVMConstInt (LLVMInt8Type (), 0, FALSE);
3527 args [3] = LLVMConstInt (LLVMInt32Type (), MONO_ARCH_FRAME_ALIGNMENT, FALSE);
3528 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
3529 LLVMBuildCall (builder, LLVMGetNamedFunction (module, memset_func_name), args, memset_param_count, "");
3531 values [ins->dreg] = v;
3535 case OP_LOADI1_MEMBASE:
3536 case OP_LOADU1_MEMBASE:
3537 case OP_LOADI2_MEMBASE:
3538 case OP_LOADU2_MEMBASE:
3539 case OP_LOADI4_MEMBASE:
3540 case OP_LOADU4_MEMBASE:
3541 case OP_LOADI8_MEMBASE:
3542 case OP_LOADR4_MEMBASE:
3543 case OP_LOADR8_MEMBASE:
3544 case OP_LOAD_MEMBASE:
3552 LLVMValueRef base, index, addr;
3554 gboolean sext = FALSE, zext = FALSE;
3555 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
3557 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
3562 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)) {
3563 addr = LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE);
3568 if (ins->inst_offset == 0) {
3570 } else if (ins->inst_offset % size != 0) {
3571 /* Unaligned load */
3572 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset, FALSE);
3573 addr = LLVMBuildGEP (builder, convert (ctx, base, LLVMPointerType (LLVMInt8Type (), 0)), &index, 1, "");
3575 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
3576 addr = LLVMBuildGEP (builder, convert (ctx, base, LLVMPointerType (t, 0)), &index, 1, "");
3580 addr = convert (ctx, addr, LLVMPointerType (t, 0));
3582 values [ins->dreg] = emit_load (ctx, bb, &builder, size, addr, dname, is_volatile);
3584 if (!is_volatile && (ins->flags & MONO_INST_INVARIANT_LOAD)) {
3586 * These will signal LLVM that these loads do not alias any stores, and
3587 * they can't fail, allowing them to be hoisted out of loops.
3589 set_invariant_load_flag (values [ins->dreg]);
3590 set_metadata_flag (values [ins->dreg], "mono.nofail.load");
3594 values [ins->dreg] = LLVMBuildSExt (builder, values [ins->dreg], LLVMInt32Type (), dname);
3596 values [ins->dreg] = LLVMBuildZExt (builder, values [ins->dreg], LLVMInt32Type (), dname);
3597 else if (!cfg->r4fp && ins->opcode == OP_LOADR4_MEMBASE)
3598 values [ins->dreg] = LLVMBuildFPExt (builder, values [ins->dreg], LLVMDoubleType (), dname);
3602 case OP_STOREI1_MEMBASE_REG:
3603 case OP_STOREI2_MEMBASE_REG:
3604 case OP_STOREI4_MEMBASE_REG:
3605 case OP_STOREI8_MEMBASE_REG:
3606 case OP_STORER4_MEMBASE_REG:
3607 case OP_STORER8_MEMBASE_REG:
3608 case OP_STORE_MEMBASE_REG: {
3610 LLVMValueRef index, addr;
3612 gboolean sext = FALSE, zext = FALSE;
3613 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
3615 if (!values [ins->inst_destbasereg])
3616 LLVM_FAILURE (ctx, "inst_destbasereg");
3618 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
3620 if (ins->inst_offset % size != 0) {
3621 /* Unaligned store */
3622 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset, FALSE);
3623 addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (LLVMInt8Type (), 0)), &index, 1, "");
3625 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
3626 addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (t, 0)), &index, 1, "");
3628 emit_store (ctx, bb, &builder, size, convert (ctx, values [ins->sreg1], t), convert (ctx, addr, LLVMPointerType (t, 0)), is_volatile);
3632 case OP_STOREI1_MEMBASE_IMM:
3633 case OP_STOREI2_MEMBASE_IMM:
3634 case OP_STOREI4_MEMBASE_IMM:
3635 case OP_STOREI8_MEMBASE_IMM:
3636 case OP_STORE_MEMBASE_IMM: {
3638 LLVMValueRef index, addr;
3640 gboolean sext = FALSE, zext = FALSE;
3641 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
3643 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
3645 if (ins->inst_offset % size != 0) {
3646 /* Unaligned store */
3647 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset, FALSE);
3648 addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (LLVMInt8Type (), 0)), &index, 1, "");
3650 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
3651 addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (t, 0)), &index, 1, "");
3653 emit_store (ctx, bb, &builder, size, convert (ctx, LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE), t), convert (ctx, addr, LLVMPointerType (t, 0)), is_volatile);
3658 emit_load (ctx, bb, &builder, sizeof (gpointer), convert (ctx, lhs, LLVMPointerType (IntPtrType (), 0)), "", TRUE);
3660 case OP_OUTARG_VTRETADDR:
3668 case OP_VOIDCALL_MEMBASE:
3669 case OP_CALL_MEMBASE:
3670 case OP_LCALL_MEMBASE:
3671 case OP_FCALL_MEMBASE:
3672 case OP_RCALL_MEMBASE:
3673 case OP_VCALL_MEMBASE:
3674 case OP_VOIDCALL_REG:
3679 case OP_VCALL_REG: {
3680 process_call (ctx, bb, &builder, ins);
3681 CHECK_FAILURE (ctx);
3686 LLVMValueRef indexes [2];
3688 LLVMValueRef got_entry_addr;
3691 * FIXME: Can't allocate from the cfg mempool since that is freed if
3692 * the LLVM compile fails.
3694 ji = g_new0 (MonoJumpInfo, 1);
3695 ji->type = (MonoJumpInfoType)ins->inst_i1;
3696 ji->data.target = ins->inst_p0;
3698 ji = mono_aot_patch_info_dup (ji);
3700 ji->next = cfg->patch_info;
3701 cfg->patch_info = ji;
3703 //mono_add_patch_info (cfg, 0, (MonoJumpInfoType)ins->inst_i1, ins->inst_p0);
3704 got_offset = mono_aot_get_got_offset (cfg->patch_info);
3705 ctx->lmodule->max_got_offset = MAX (ctx->lmodule->max_got_offset, got_offset);
3707 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
3708 indexes [1] = LLVMConstInt (LLVMInt32Type (), (gssize)got_offset, FALSE);
3709 got_entry_addr = LLVMBuildGEP (builder, ctx->lmodule->got_var, indexes, 2, "");
3711 values [ins->dreg] = LLVMBuildLoad (builder, got_entry_addr, dname);
3712 set_invariant_load_flag (values [ins->dreg]);
3715 case OP_NOT_REACHED:
3716 LLVMBuildUnreachable (builder);
3717 has_terminator = TRUE;
3718 g_assert (bb->block_num < cfg->max_block_num);
3719 ctx->unreachable [bb->block_num] = TRUE;
3720 /* Might have instructions after this */
3722 MonoInst *next = ins->next;
3724 * FIXME: If later code uses the regs defined by these instructions,
3725 * compilation will fail.
3727 MONO_DELETE_INS (bb, next);
3731 MonoInst *var = ins->inst_p0;
3733 values [ins->dreg] = addresses [var->dreg];
3737 LLVMValueRef args [1];
3739 args [0] = convert (ctx, lhs, LLVMDoubleType ());
3740 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, "llvm.sin.f64"), args, 1, dname);
3744 LLVMValueRef args [1];
3746 args [0] = convert (ctx, lhs, LLVMDoubleType ());
3747 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, "llvm.cos.f64"), args, 1, dname);
3751 LLVMValueRef args [1];
3754 /* This no longer seems to happen */
3756 * LLVM optimizes sqrt(nan) into undefined in
3757 * lib/Analysis/ConstantFolding.cpp
3758 * Also, sqrt(NegativeInfinity) is optimized into 0.
3760 LLVM_FAILURE (ctx, "sqrt");
3762 args [0] = convert (ctx, lhs, LLVMDoubleType ());
3763 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, "llvm.sqrt.f64"), args, 1, dname);
3767 LLVMValueRef args [1];
3769 args [0] = convert (ctx, lhs, LLVMDoubleType ());
3770 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, "fabs"), args, 1, dname);
3784 lhs = convert (ctx, lhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
3785 rhs = convert (ctx, rhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
3787 switch (ins->opcode) {
3790 v = LLVMBuildICmp (builder, LLVMIntSLE, lhs, rhs, "");
3794 v = LLVMBuildICmp (builder, LLVMIntSGE, lhs, rhs, "");
3798 v = LLVMBuildICmp (builder, LLVMIntULE, lhs, rhs, "");
3802 v = LLVMBuildICmp (builder, LLVMIntUGE, lhs, rhs, "");
3805 g_assert_not_reached ();
3808 values [ins->dreg] = LLVMBuildSelect (builder, v, lhs, rhs, dname);
3811 case OP_ATOMIC_EXCHANGE_I4:
3812 case OP_ATOMIC_EXCHANGE_I8: {
3813 LLVMValueRef args [2];
3816 if (ins->opcode == OP_ATOMIC_EXCHANGE_I4)
3817 t = LLVMInt32Type ();
3819 t = LLVMInt64Type ();
3821 g_assert (ins->inst_offset == 0);
3823 args [0] = convert (ctx, lhs, LLVMPointerType (t, 0));
3824 args [1] = convert (ctx, rhs, t);
3826 values [ins->dreg] = mono_llvm_build_atomic_rmw (builder, LLVM_ATOMICRMW_OP_XCHG, args [0], args [1]);
3829 case OP_ATOMIC_ADD_I4:
3830 case OP_ATOMIC_ADD_I8: {
3831 LLVMValueRef args [2];
3834 if (ins->opcode == OP_ATOMIC_ADD_I4)
3835 t = LLVMInt32Type ();
3837 t = LLVMInt64Type ();
3839 g_assert (ins->inst_offset == 0);
3841 args [0] = convert (ctx, lhs, LLVMPointerType (t, 0));
3842 args [1] = convert (ctx, rhs, t);
3843 values [ins->dreg] = LLVMBuildAdd (builder, mono_llvm_build_atomic_rmw (builder, LLVM_ATOMICRMW_OP_ADD, args [0], args [1]), args [1], dname);
3846 case OP_ATOMIC_CAS_I4:
3847 case OP_ATOMIC_CAS_I8: {
3848 LLVMValueRef args [3], val;
3851 if (ins->opcode == OP_ATOMIC_CAS_I4)
3852 t = LLVMInt32Type ();
3854 t = LLVMInt64Type ();
3856 args [0] = convert (ctx, lhs, LLVMPointerType (t, 0));
3858 args [1] = convert (ctx, values [ins->sreg3], t);
3860 args [2] = convert (ctx, values [ins->sreg2], t);
3861 val = mono_llvm_build_cmpxchg (builder, args [0], args [1], args [2]);
3862 /* cmpxchg returns a pair */
3863 values [ins->dreg] = LLVMBuildExtractValue (builder, val, 0, "");
3866 case OP_MEMORY_BARRIER: {
3867 mono_llvm_build_fence (builder, (BarrierKind) ins->backend.memory_barrier_kind);
3870 case OP_ATOMIC_LOAD_I1:
3871 case OP_ATOMIC_LOAD_I2:
3872 case OP_ATOMIC_LOAD_I4:
3873 case OP_ATOMIC_LOAD_I8:
3874 case OP_ATOMIC_LOAD_U1:
3875 case OP_ATOMIC_LOAD_U2:
3876 case OP_ATOMIC_LOAD_U4:
3877 case OP_ATOMIC_LOAD_U8:
3878 case OP_ATOMIC_LOAD_R4:
3879 case OP_ATOMIC_LOAD_R8: {
3880 LLVM_FAILURE (ctx, "atomic mono.load intrinsic");
3883 gboolean sext, zext;
3885 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
3886 BarrierKind barrier = (BarrierKind) ins->backend.memory_barrier_kind;
3887 LLVMValueRef index, addr;
3889 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
3894 if (ins->inst_offset != 0) {
3895 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
3896 addr = LLVMBuildGEP (builder, convert (ctx, lhs, LLVMPointerType (t, 0)), &index, 1, "");
3901 addr = convert (ctx, addr, LLVMPointerType (t, 0));
3903 values [ins->dreg] = emit_load_general (ctx, bb, &builder, size, addr, dname, is_volatile, barrier);
3906 values [ins->dreg] = LLVMBuildSExt (builder, values [ins->dreg], LLVMInt32Type (), dname);
3908 values [ins->dreg] = LLVMBuildZExt (builder, values [ins->dreg], LLVMInt32Type (), dname);
3911 case OP_ATOMIC_STORE_I1:
3912 case OP_ATOMIC_STORE_I2:
3913 case OP_ATOMIC_STORE_I4:
3914 case OP_ATOMIC_STORE_I8:
3915 case OP_ATOMIC_STORE_U1:
3916 case OP_ATOMIC_STORE_U2:
3917 case OP_ATOMIC_STORE_U4:
3918 case OP_ATOMIC_STORE_U8:
3919 case OP_ATOMIC_STORE_R4:
3920 case OP_ATOMIC_STORE_R8: {
3921 LLVM_FAILURE (ctx, "atomic mono.load intrinsic");
3924 gboolean sext, zext;
3926 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
3927 BarrierKind barrier = (BarrierKind) ins->backend.memory_barrier_kind;
3928 LLVMValueRef index, addr, value;
3930 if (!values [ins->inst_destbasereg])
3931 LLVM_FAILURE (ctx, "inst_destbasereg");
3933 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
3935 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
3936 addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (t, 0)), &index, 1, "");
3937 value = convert (ctx, values [ins->sreg1], t);
3939 emit_store_general (ctx, bb, &builder, size, value, addr, is_volatile, barrier);
3942 case OP_RELAXED_NOP: {
3943 #if defined(TARGET_AMD64) || defined(TARGET_X86)
3944 emit_call (ctx, bb, &builder, LLVMGetNamedFunction (ctx->module, "llvm.x86.sse2.pause"), NULL, 0);
3951 #if (defined(TARGET_AMD64) || defined(TARGET_X86)) && defined(__linux__)
3953 // 257 == FS segment register
3954 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 257);
3956 // 256 == GS segment register
3957 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 256);
3960 values [ins->dreg] = LLVMBuildLoad (builder, LLVMBuildIntToPtr (builder, LLVMConstInt (IntPtrType (), ins->inst_offset, TRUE), ptrtype, ""), "");
3961 #elif defined(TARGET_AMD64) && defined(TARGET_OSX)
3962 /* See mono_amd64_emit_tls_get () */
3963 int offset = mono_amd64_get_tls_gs_offset () + (ins->inst_offset * 8);
3965 // 256 == GS segment register
3966 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 256);
3967 values [ins->dreg] = LLVMBuildLoad (builder, LLVMBuildIntToPtr (builder, LLVMConstInt (IntPtrType (), offset, TRUE), ptrtype, ""), "");
3969 LLVM_FAILURE (ctx, "opcode tls-get");
3974 case OP_TLS_GET_REG: {
3975 #if defined(TARGET_AMD64) && defined(TARGET_OSX)
3976 /* See emit_tls_get_reg () */
3977 // 256 == GS segment register
3978 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 256);
3979 values [ins->dreg] = LLVMBuildLoad (builder, LLVMBuildIntToPtr (builder, convert (ctx, lhs, LLVMInt32Type ()), ptrtype, ""), "");
3981 LLVM_FAILURE (ctx, "opcode tls-get");
3990 case OP_IADD_OVF_UN:
3992 case OP_ISUB_OVF_UN:
3994 case OP_IMUL_OVF_UN:
3995 #if SIZEOF_VOID_P == 8
3997 case OP_LADD_OVF_UN:
3999 case OP_LSUB_OVF_UN:
4001 case OP_LMUL_OVF_UN:
4004 LLVMValueRef args [2], val, ovf, func;
4006 args [0] = convert (ctx, lhs, op_to_llvm_type (ins->opcode));
4007 args [1] = convert (ctx, rhs, op_to_llvm_type (ins->opcode));
4008 func = LLVMGetNamedFunction (module, ovf_op_to_intrins (ins->opcode));
4010 val = LLVMBuildCall (builder, func, args, 2, "");
4011 values [ins->dreg] = LLVMBuildExtractValue (builder, val, 0, dname);
4012 ovf = LLVMBuildExtractValue (builder, val, 1, "");
4013 emit_cond_system_exception (ctx, bb, "OverflowException", ovf);
4014 CHECK_FAILURE (ctx);
4015 builder = ctx->builder;
4021 * We currently model them using arrays. Promotion to local vregs is
4022 * disabled for them in mono_handle_global_vregs () in the LLVM case,
4023 * so we always have an entry in cfg->varinfo for them.
4024 * FIXME: Is this needed ?
4027 MonoClass *klass = ins->klass;
4028 LLVMValueRef args [5];
4032 LLVM_FAILURE (ctx, "!klass");
4036 if (!addresses [ins->dreg])
4037 addresses [ins->dreg] = build_alloca (ctx, &klass->byval_arg);
4038 args [0] = LLVMBuildBitCast (builder, addresses [ins->dreg], LLVMPointerType (LLVMInt8Type (), 0), "");
4039 args [1] = LLVMConstInt (LLVMInt8Type (), 0, FALSE);
4040 args [2] = LLVMConstInt (LLVMInt32Type (), mono_class_value_size (klass, NULL), FALSE);
4042 args [3] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
4043 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
4044 LLVMBuildCall (builder, LLVMGetNamedFunction (module, memset_func_name), args, memset_param_count, "");
4047 case OP_DUMMY_VZERO:
4050 case OP_STOREV_MEMBASE:
4051 case OP_LOADV_MEMBASE:
4053 MonoClass *klass = ins->klass;
4054 LLVMValueRef src = NULL, dst, args [5];
4055 gboolean done = FALSE;
4059 LLVM_FAILURE (ctx, "!klass");
4063 if (mini_is_gsharedvt_klass (cfg, klass)) {
4065 LLVM_FAILURE (ctx, "gsharedvt");
4069 switch (ins->opcode) {
4070 case OP_STOREV_MEMBASE:
4071 if (cfg->gen_write_barriers && klass->has_references && ins->inst_destbasereg != cfg->frame_reg &&
4072 LLVMGetInstructionOpcode (values [ins->inst_destbasereg]) != LLVMAlloca) {
4073 /* Decomposed earlier */
4074 g_assert_not_reached ();
4077 if (!addresses [ins->sreg1]) {
4079 g_assert (values [ins->sreg1]);
4080 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));
4081 LLVMBuildStore (builder, values [ins->sreg1], dst);
4084 src = LLVMBuildBitCast (builder, addresses [ins->sreg1], LLVMPointerType (LLVMInt8Type (), 0), "");
4085 dst = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_destbasereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (LLVMInt8Type (), 0));
4088 case OP_LOADV_MEMBASE:
4089 if (!addresses [ins->dreg])
4090 addresses [ins->dreg] = build_alloca (ctx, &klass->byval_arg);
4091 src = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_basereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (LLVMInt8Type (), 0));
4092 dst = LLVMBuildBitCast (builder, addresses [ins->dreg], LLVMPointerType (LLVMInt8Type (), 0), "");
4095 if (!addresses [ins->sreg1])
4096 addresses [ins->sreg1] = build_alloca (ctx, &klass->byval_arg);
4097 if (!addresses [ins->dreg])
4098 addresses [ins->dreg] = build_alloca (ctx, &klass->byval_arg);
4099 src = LLVMBuildBitCast (builder, addresses [ins->sreg1], LLVMPointerType (LLVMInt8Type (), 0), "");
4100 dst = LLVMBuildBitCast (builder, addresses [ins->dreg], LLVMPointerType (LLVMInt8Type (), 0), "");
4103 g_assert_not_reached ();
4105 CHECK_FAILURE (ctx);
4112 args [2] = LLVMConstInt (LLVMInt32Type (), mono_class_value_size (klass, NULL), FALSE);
4113 args [3] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
4115 args [3] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
4116 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
4117 LLVMBuildCall (builder, LLVMGetNamedFunction (module, memcpy_func_name), args, memcpy_param_count, "");
4120 case OP_LLVM_OUTARG_VT:
4121 if (!addresses [ins->sreg1]) {
4122 addresses [ins->sreg1] = build_alloca (ctx, &ins->klass->byval_arg);
4123 g_assert (values [ins->sreg1]);
4124 LLVMBuildStore (builder, values [ins->sreg1], addresses [ins->sreg1]);
4126 addresses [ins->dreg] = addresses [ins->sreg1];
4132 #if defined(TARGET_X86) || defined(TARGET_AMD64)
4134 values [ins->dreg] = LLVMConstNull (type_to_llvm_type (ctx, &ins->klass->byval_arg));
4137 case OP_LOADX_MEMBASE: {
4138 LLVMTypeRef t = type_to_llvm_type (ctx, &ins->klass->byval_arg);
4141 src = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_basereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (t, 0));
4142 values [ins->dreg] = mono_llvm_build_aligned_load (builder, src, "", FALSE, 1);
4145 case OP_STOREX_MEMBASE: {
4146 LLVMTypeRef t = LLVMTypeOf (values [ins->sreg1]);
4149 dest = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_destbasereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (t, 0));
4150 mono_llvm_build_aligned_store (builder, values [ins->sreg1], dest, FALSE, 1);
4157 values [ins->dreg] = LLVMBuildAdd (builder, lhs, rhs, "");
4161 values [ins->dreg] = LLVMBuildFAdd (builder, lhs, rhs, "");
4167 values [ins->dreg] = LLVMBuildSub (builder, lhs, rhs, "");
4171 values [ins->dreg] = LLVMBuildFSub (builder, lhs, rhs, "");
4175 values [ins->dreg] = LLVMBuildFMul (builder, lhs, rhs, "");
4179 values [ins->dreg] = LLVMBuildFDiv (builder, lhs, rhs, "");
4182 values [ins->dreg] = LLVMBuildAnd (builder, lhs, rhs, "");
4185 values [ins->dreg] = LLVMBuildOr (builder, lhs, rhs, "");
4188 values [ins->dreg] = LLVMBuildXor (builder, lhs, rhs, "");
4192 values [ins->dreg] = LLVMBuildMul (builder, lhs, rhs, "");
4203 LLVMValueRef v = NULL;
4205 switch (ins->opcode) {
4210 t = LLVMVectorType (LLVMInt32Type (), 4);
4211 rt = LLVMVectorType (LLVMFloatType (), 4);
4217 t = LLVMVectorType (LLVMInt64Type (), 2);
4218 rt = LLVMVectorType (LLVMDoubleType (), 2);
4221 t = LLVMInt32Type ();
4222 rt = LLVMInt32Type ();
4223 g_assert_not_reached ();
4226 lhs = LLVMBuildBitCast (builder, lhs, t, "");
4227 rhs = LLVMBuildBitCast (builder, rhs, t, "");
4228 switch (ins->opcode) {
4231 v = LLVMBuildAnd (builder, lhs, rhs, "");
4235 v = LLVMBuildOr (builder, lhs, rhs, "");
4239 v = LLVMBuildXor (builder, lhs, rhs, "");
4243 v = LLVMBuildAnd (builder, rhs, LLVMBuildNot (builder, lhs, ""), "");
4246 values [ins->dreg] = LLVMBuildBitCast (builder, v, rt, "");
4270 case OP_PADDB_SAT_UN:
4271 case OP_PADDW_SAT_UN:
4272 case OP_PSUBB_SAT_UN:
4273 case OP_PSUBW_SAT_UN:
4281 case OP_PMULW_HIGH_UN: {
4282 LLVMValueRef args [2];
4287 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, simd_op_to_intrins (ins->opcode)), args, 2, dname);
4294 values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildICmp (builder, LLVMIntEQ, lhs, rhs, ""), LLVMTypeOf (lhs), "");
4298 values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildICmp (builder, LLVMIntSGT, lhs, rhs, ""), LLVMTypeOf (lhs), "");
4306 case OP_EXTRACTX_U2:
4308 case OP_EXTRACT_U1: {
4310 gboolean zext = FALSE;
4312 t = simd_op_to_llvm_type (ins->opcode);
4314 switch (ins->opcode) {
4322 case OP_EXTRACTX_U2:
4327 t = LLVMInt32Type ();
4328 g_assert_not_reached ();
4331 lhs = LLVMBuildBitCast (builder, lhs, t, "");
4332 values [ins->dreg] = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), "");
4334 values [ins->dreg] = LLVMBuildZExt (builder, values [ins->dreg], LLVMInt32Type (), "");
4343 case OP_EXPAND_R8: {
4344 LLVMTypeRef t = simd_op_to_llvm_type (ins->opcode);
4345 LLVMValueRef mask [16], v;
4348 for (i = 0; i < 16; ++i)
4349 mask [i] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
4351 v = convert (ctx, values [ins->sreg1], LLVMGetElementType (t));
4353 values [ins->dreg] = LLVMBuildInsertElement (builder, LLVMConstNull (t), v, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
4354 values [ins->dreg] = LLVMBuildShuffleVector (builder, values [ins->dreg], LLVMGetUndef (t), LLVMConstVector (mask, LLVMGetVectorSize (t)), "");
4359 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt8Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
4362 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt16Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
4365 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt32Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
4368 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt64Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
4371 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMFloatType ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
4374 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMDoubleType ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
4385 case OP_EXTRACT_MASK:
4392 v = convert (ctx, values [ins->sreg1], simd_op_to_llvm_type (ins->opcode));
4394 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, simd_op_to_intrins (ins->opcode)), &v, 1, dname);
4400 LLVMValueRef args [3];
4404 args [2] = LLVMConstInt (LLVMInt8Type (), ins->inst_c0, FALSE);
4406 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, simd_op_to_intrins (ins->opcode)), args, 3, dname);
4411 /* This is only used for implementing shifts by non-immediate */
4412 values [ins->dreg] = lhs;
4423 LLVMValueRef args [3];
4426 args [1] = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
4428 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, simd_op_to_intrins (ins->opcode)), args, 2, dname);
4439 case OP_PSHLQ_REG: {
4440 LLVMValueRef args [3];
4443 args [1] = values [ins->sreg2];
4445 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (module, simd_op_to_intrins (ins->opcode)), args, 2, dname);
4452 case OP_PSHUFLEW_LOW:
4453 case OP_PSHUFLEW_HIGH: {
4455 LLVMValueRef v1 = NULL, v2 = NULL, mask_values [16];
4456 int i, mask_size = 0;
4457 int imask = ins->inst_c0;
4459 /* Convert the x86 shuffle mask to LLVM's */
4460 switch (ins->opcode) {
4463 mask [0] = ((imask >> 0) & 3);
4464 mask [1] = ((imask >> 2) & 3);
4465 mask [2] = ((imask >> 4) & 3) + 4;
4466 mask [3] = ((imask >> 6) & 3) + 4;
4467 v1 = values [ins->sreg1];
4468 v2 = values [ins->sreg2];
4472 mask [0] = ((imask >> 0) & 1);
4473 mask [1] = ((imask >> 1) & 1) + 2;
4474 v1 = values [ins->sreg1];
4475 v2 = values [ins->sreg2];
4477 case OP_PSHUFLEW_LOW:
4479 mask [0] = ((imask >> 0) & 3);
4480 mask [1] = ((imask >> 2) & 3);
4481 mask [2] = ((imask >> 4) & 3);
4482 mask [3] = ((imask >> 6) & 3);
4487 v1 = values [ins->sreg1];
4488 v2 = LLVMGetUndef (LLVMTypeOf (v1));
4490 case OP_PSHUFLEW_HIGH:
4496 mask [4] = 4 + ((imask >> 0) & 3);
4497 mask [5] = 4 + ((imask >> 2) & 3);
4498 mask [6] = 4 + ((imask >> 4) & 3);
4499 mask [7] = 4 + ((imask >> 6) & 3);
4500 v1 = values [ins->sreg1];
4501 v2 = LLVMGetUndef (LLVMTypeOf (v1));
4505 mask [0] = ((imask >> 0) & 3);
4506 mask [1] = ((imask >> 2) & 3);
4507 mask [2] = ((imask >> 4) & 3);
4508 mask [3] = ((imask >> 6) & 3);
4509 v1 = values [ins->sreg1];
4510 v2 = LLVMGetUndef (LLVMTypeOf (v1));
4513 g_assert_not_reached ();
4515 for (i = 0; i < mask_size; ++i)
4516 mask_values [i] = LLVMConstInt (LLVMInt32Type (), mask [i], FALSE);
4518 values [ins->dreg] =
4519 LLVMBuildShuffleVector (builder, v1, v2,
4520 LLVMConstVector (mask_values, mask_size), dname);
4524 case OP_UNPACK_LOWB:
4525 case OP_UNPACK_LOWW:
4526 case OP_UNPACK_LOWD:
4527 case OP_UNPACK_LOWQ:
4528 case OP_UNPACK_LOWPS:
4529 case OP_UNPACK_LOWPD:
4530 case OP_UNPACK_HIGHB:
4531 case OP_UNPACK_HIGHW:
4532 case OP_UNPACK_HIGHD:
4533 case OP_UNPACK_HIGHQ:
4534 case OP_UNPACK_HIGHPS:
4535 case OP_UNPACK_HIGHPD: {
4537 LLVMValueRef mask_values [16];
4538 int i, mask_size = 0;
4539 gboolean low = FALSE;
4541 switch (ins->opcode) {
4542 case OP_UNPACK_LOWB:
4546 case OP_UNPACK_LOWW:
4550 case OP_UNPACK_LOWD:
4551 case OP_UNPACK_LOWPS:
4555 case OP_UNPACK_LOWQ:
4556 case OP_UNPACK_LOWPD:
4560 case OP_UNPACK_HIGHB:
4563 case OP_UNPACK_HIGHW:
4566 case OP_UNPACK_HIGHD:
4567 case OP_UNPACK_HIGHPS:
4570 case OP_UNPACK_HIGHQ:
4571 case OP_UNPACK_HIGHPD:
4575 g_assert_not_reached ();
4579 for (i = 0; i < (mask_size / 2); ++i) {
4581 mask [(i * 2) + 1] = mask_size + i;
4584 for (i = 0; i < (mask_size / 2); ++i) {
4585 mask [(i * 2)] = (mask_size / 2) + i;
4586 mask [(i * 2) + 1] = mask_size + (mask_size / 2) + i;
4590 for (i = 0; i < mask_size; ++i)
4591 mask_values [i] = LLVMConstInt (LLVMInt32Type (), mask [i], FALSE);
4593 values [ins->dreg] =
4594 LLVMBuildShuffleVector (builder, values [ins->sreg1], values [ins->sreg2],
4595 LLVMConstVector (mask_values, mask_size), dname);
4600 LLVMTypeRef t = simd_op_to_llvm_type (ins->opcode);
4601 LLVMValueRef v, val;
4603 v = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
4604 val = LLVMConstNull (t);
4605 val = LLVMBuildInsertElement (builder, val, v, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
4606 val = LLVMBuildInsertElement (builder, val, v, LLVMConstInt (LLVMInt32Type (), 1, FALSE), dname);
4608 values [ins->dreg] = val;
4612 case OP_DUPPS_HIGH: {
4613 LLVMTypeRef t = simd_op_to_llvm_type (ins->opcode);
4614 LLVMValueRef v1, v2, val;
4617 if (ins->opcode == OP_DUPPS_LOW) {
4618 v1 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
4619 v2 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 2, FALSE), "");
4621 v1 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 1, FALSE), "");
4622 v2 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 3, FALSE), "");
4624 val = LLVMConstNull (t);
4625 val = LLVMBuildInsertElement (builder, val, v1, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
4626 val = LLVMBuildInsertElement (builder, val, v1, LLVMConstInt (LLVMInt32Type (), 1, FALSE), "");
4627 val = LLVMBuildInsertElement (builder, val, v2, LLVMConstInt (LLVMInt32Type (), 2, FALSE), "");
4628 val = LLVMBuildInsertElement (builder, val, v2, LLVMConstInt (LLVMInt32Type (), 3, FALSE), "");
4630 values [ins->dreg] = val;
4640 * EXCEPTION HANDLING
4642 case OP_IMPLICIT_EXCEPTION:
4643 /* This marks a place where an implicit exception can happen */
4644 if (bb->region != -1)
4645 LLVM_FAILURE (ctx, "implicit-exception");
4649 MonoMethodSignature *throw_sig;
4650 LLVMValueRef callee, arg;
4651 gboolean rethrow = (ins->opcode == OP_RETHROW);
4652 const char *icall_name;
4654 callee = rethrow ? ctx->lmodule->rethrow : ctx->lmodule->throw;
4655 icall_name = rethrow ? "mono_arch_rethrow_exception" : "mono_arch_throw_exception";
4658 throw_sig = mono_metadata_signature_alloc (mono_get_corlib (), 1);
4659 throw_sig->ret = &mono_get_void_class ()->byval_arg;
4660 throw_sig->params [0] = &mono_get_object_class ()->byval_arg;
4661 if (cfg->compile_aot) {
4662 callee = get_plt_entry (ctx, sig_to_llvm_sig (ctx, throw_sig), MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
4664 callee = LLVMAddFunction (module, icall_name, sig_to_llvm_sig (ctx, throw_sig));
4668 * LLVM doesn't push the exception argument, so we need a different
4671 LLVMAddGlobalMapping (ctx->lmodule->ee, callee, resolve_patch (cfg, MONO_PATCH_INFO_INTERNAL_METHOD, rethrow ? "llvm_rethrow_exception_trampoline" : "llvm_throw_exception_trampoline"));
4673 LLVMAddGlobalMapping (ctx->lmodule->ee, callee, resolve_patch (cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name));
4677 mono_memory_barrier ();
4679 ctx->lmodule->rethrow = callee;
4681 ctx->lmodule->throw = callee;
4683 arg = convert (ctx, lhs, type_to_llvm_type (ctx, &mono_get_object_class ()->byval_arg));
4684 emit_call (ctx, bb, &builder, callee, &arg, 1);
4687 case OP_CALL_HANDLER: {
4689 * We don't 'call' handlers, but instead simply branch to them.
4690 * The code generated by ENDFINALLY will branch back to us.
4692 LLVMBasicBlockRef noex_bb;
4694 BBInfo *info = &bblocks [ins->inst_target_bb->block_num];
4696 bb_list = info->call_handler_return_bbs;
4699 * Set the indicator variable for the finally clause.
4701 lhs = info->finally_ind;
4703 LLVMBuildStore (builder, LLVMConstInt (LLVMInt32Type (), g_slist_length (bb_list) + 1, FALSE), lhs);
4705 /* Branch to the finally clause */
4706 LLVMBuildBr (builder, info->call_handler_target_bb);
4708 noex_bb = gen_bb (ctx, "CALL_HANDLER_CONT_BB");
4709 info->call_handler_return_bbs = g_slist_append_mempool (cfg->mempool, info->call_handler_return_bbs, noex_bb);
4711 builder = ctx->builder = create_builder (ctx);
4712 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
4714 bblocks [bb->block_num].end_bblock = noex_bb;
4717 case OP_START_HANDLER: {
4720 case OP_ENDFINALLY: {
4721 LLVMBasicBlockRef resume_bb;
4722 MonoBasicBlock *handler_bb;
4723 LLVMValueRef val, switch_ins, callee;
4727 handler_bb = g_hash_table_lookup (ctx->region_to_handler, GUINT_TO_POINTER (mono_get_block_region_notry (cfg, bb->region)));
4728 g_assert (handler_bb);
4729 info = &bblocks [handler_bb->block_num];
4730 lhs = info->finally_ind;
4733 bb_list = info->call_handler_return_bbs;
4735 resume_bb = gen_bb (ctx, "ENDFINALLY_RESUME_BB");
4737 /* Load the finally variable */
4738 val = LLVMBuildLoad (builder, lhs, "");
4740 /* Reset the variable */
4741 LLVMBuildStore (builder, LLVMConstInt (LLVMInt32Type (), 0, FALSE), lhs);
4743 /* Branch to either resume_bb, or to the bblocks in bb_list */
4744 switch_ins = LLVMBuildSwitch (builder, val, resume_bb, g_slist_length (bb_list));
4746 * The other targets are added at the end to handle OP_CALL_HANDLER
4747 * opcodes processed later.
4749 info->endfinally_switch_ins_list = g_slist_append_mempool (cfg->mempool, info->endfinally_switch_ins_list, switch_ins);
4751 builder = ctx->builder = create_builder (ctx);
4752 LLVMPositionBuilderAtEnd (ctx->builder, resume_bb);
4754 if (ctx->cfg->compile_aot) {
4755 callee = get_plt_entry (ctx, LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE), MONO_PATCH_INFO_INTERNAL_METHOD, "llvm_resume_unwind_trampoline");
4757 callee = LLVMGetNamedFunction (module, "llvm_resume_unwind_trampoline");
4759 LLVMBuildCall (builder, callee, NULL, 0, "");
4761 LLVMBuildUnreachable (builder);
4762 has_terminator = TRUE;
4768 sprintf (reason, "opcode %s", mono_inst_name (ins->opcode));
4769 LLVM_FAILURE (ctx, reason);
4774 /* Convert the value to the type required by phi nodes */
4775 if (spec [MONO_INST_DEST] != ' ' && !MONO_IS_STORE_MEMBASE (ins) && ctx->vreg_types [ins->dreg]) {
4776 if (!values [ins->dreg])
4778 values [ins->dreg] = addresses [ins->dreg];
4780 values [ins->dreg] = convert (ctx, values [ins->dreg], ctx->vreg_types [ins->dreg]);
4783 /* Add stores for volatile variables */
4784 if (spec [MONO_INST_DEST] != ' ' && spec [MONO_INST_DEST] != 'v' && !MONO_IS_STORE_MEMBASE (ins))
4785 emit_volatile_store (ctx, ins->dreg);
4788 if (!has_terminator && bb->next_bb && (bb == cfg->bb_entry || bb->in_count > 0))
4789 LLVMBuildBr (builder, get_bb (ctx, bb->next_bb));
4791 if (bb == cfg->bb_exit && sig->ret->type == MONO_TYPE_VOID) {
4792 emit_dbg_loc (ctx, builder, cfg->header->code + cfg->header->code_size - 1);
4793 LLVMBuildRetVoid (builder);
4796 if (bb == cfg->bb_entry)
4797 ctx->last_alloca = LLVMGetLastInstruction (get_bb (ctx, cfg->bb_entry));
4806 * mono_llvm_check_method_supported:
4808 * Do some quick checks to decide whenever cfg->method can be compiled by LLVM, to avoid
4809 * compiling a method twice.
4812 mono_llvm_check_method_supported (MonoCompile *cfg)
4816 if (cfg->method->save_lmf) {
4817 cfg->exception_message = g_strdup ("lmf");
4818 cfg->disable_llvm = TRUE;
4820 if (cfg->disable_llvm)
4824 * Nested clauses where one of the clauses is a finally clause is
4825 * not supported, because LLVM can't figure out the control flow,
4826 * probably because we resume exception handling by calling our
4827 * own function instead of using the 'resume' llvm instruction.
4829 for (i = 0; i < cfg->header->num_clauses; ++i) {
4830 for (j = 0; j < cfg->header->num_clauses; ++j) {
4831 MonoExceptionClause *clause1 = &cfg->header->clauses [i];
4832 MonoExceptionClause *clause2 = &cfg->header->clauses [j];
4834 if (i != j && clause1->try_offset >= clause2->try_offset && clause1->handler_offset <= clause2->handler_offset &&
4835 (clause1->flags == MONO_EXCEPTION_CLAUSE_FINALLY || clause2->flags == MONO_EXCEPTION_CLAUSE_FINALLY)) {
4836 cfg->exception_message = g_strdup ("nested clauses");
4837 cfg->disable_llvm = TRUE;
4842 if (cfg->disable_llvm)
4846 if (cfg->method->dynamic) {
4847 cfg->exception_message = g_strdup ("dynamic.");
4848 cfg->disable_llvm = TRUE;
4850 if (cfg->disable_llvm)
4855 * mono_llvm_emit_method:
4857 * Emit LLVM IL from the mono IL, and compile it to native code using LLVM.
4860 mono_llvm_emit_method (MonoCompile *cfg)
4863 MonoMethodSignature *sig;
4865 LLVMTypeRef method_type;
4866 LLVMValueRef method = NULL;
4868 LLVMValueRef *values;
4869 int i, max_block_num, bb_index;
4870 gboolean last = FALSE;
4871 GPtrArray *phi_values;
4872 LLVMCallInfo *linfo;
4874 LLVMModuleRef module;
4876 GPtrArray *bblock_list;
4877 MonoMethodHeader *header;
4878 MonoExceptionClause *clause;
4882 /* The code below might acquire the loader lock, so use it for global locking */
4883 mono_loader_lock ();
4885 /* Used to communicate with the callbacks */
4886 mono_native_tls_set_value (current_cfg_tls_id, cfg);
4888 ctx = g_new0 (EmitContext, 1);
4890 ctx->mempool = cfg->mempool;
4893 * This maps vregs to the LLVM instruction defining them
4895 values = g_new0 (LLVMValueRef, cfg->next_vreg);
4897 * This maps vregs for volatile variables to the LLVM instruction defining their
4900 ctx->addresses = g_new0 (LLVMValueRef, cfg->next_vreg);
4901 ctx->vreg_types = g_new0 (LLVMTypeRef, cfg->next_vreg);
4902 ctx->vreg_cli_types = g_new0 (MonoType*, cfg->next_vreg);
4903 phi_values = g_ptr_array_sized_new (256);
4905 * This signals whenever the vreg was defined by a phi node with no input vars
4906 * (i.e. all its input bblocks end with NOT_REACHABLE).
4908 ctx->is_dead = g_new0 (gboolean, cfg->next_vreg);
4909 /* Whenever the bblock is unreachable */
4910 ctx->unreachable = g_new0 (gboolean, cfg->max_block_num);
4912 bblock_list = g_ptr_array_sized_new (256);
4914 ctx->values = values;
4915 ctx->region_to_handler = g_hash_table_new (NULL, NULL);
4916 ctx->clause_to_handler = g_hash_table_new (NULL, NULL);
4918 if (cfg->compile_aot) {
4919 ctx->lmodule = &aot_module;
4920 method_name = mono_aot_get_method_name (cfg);
4921 cfg->llvm_method_name = g_strdup (method_name);
4923 init_jit_module (cfg->domain);
4924 ctx->lmodule = domain_jit_info (cfg->domain)->llvm_module;
4925 method_name = mono_method_full_name (cfg->method, TRUE);
4928 module = ctx->module = ctx->lmodule->module;
4931 LLVM_FAILURE (ctx, "gsharedvt");
4935 static int count = 0;
4938 if (g_getenv ("LLVM_COUNT")) {
4939 if (count == atoi (g_getenv ("LLVM_COUNT"))) {
4940 printf ("LAST: %s\n", mono_method_full_name (cfg->method, TRUE));
4944 if (count > atoi (g_getenv ("LLVM_COUNT")))
4945 LLVM_FAILURE (ctx, "");
4950 sig = mono_method_signature (cfg->method);
4953 linfo = mono_arch_get_llvm_call_info (cfg, sig);
4955 CHECK_FAILURE (ctx);
4958 linfo->rgctx_arg = TRUE;
4959 method_type = sig_to_llvm_sig_full (ctx, sig, linfo, &sinfo);
4960 CHECK_FAILURE (ctx);
4963 * This maps parameter indexes in the original signature to the indexes in
4964 * the LLVM signature.
4966 ctx->pindexes = sinfo.pindexes;
4968 method = LLVMAddFunction (module, method_name, method_type);
4969 ctx->lmethod = method;
4971 LLVMSetFunctionCallConv (method, LLVMMono1CallConv);
4972 LLVMSetLinkage (method, LLVMPrivateLinkage);
4974 LLVMAddFunctionAttr (method, LLVMUWTable);
4976 if (cfg->compile_aot) {
4977 LLVMSetLinkage (method, LLVMInternalLinkage);
4978 if (ctx->lmodule->external_symbols) {
4979 LLVMSetLinkage (method, LLVMExternalLinkage);
4980 LLVMSetVisibility (method, LLVMHiddenVisibility);
4983 LLVMSetLinkage (method, LLVMPrivateLinkage);
4986 if (cfg->method->save_lmf)
4987 LLVM_FAILURE (ctx, "lmf");
4989 if (sig->pinvoke && cfg->method->wrapper_type != MONO_WRAPPER_RUNTIME_INVOKE)
4990 LLVM_FAILURE (ctx, "pinvoke signature");
4992 header = cfg->header;
4993 for (i = 0; i < header->num_clauses; ++i) {
4994 clause = &header->clauses [i];
4995 if (clause->flags != MONO_EXCEPTION_CLAUSE_FINALLY && clause->flags != MONO_EXCEPTION_CLAUSE_NONE)
4996 LLVM_FAILURE (ctx, "non-finally/catch clause.");
4998 if (header->num_clauses || (cfg->method->iflags & METHOD_IMPL_ATTRIBUTE_NOINLINING))
4999 /* We can't handle inlined methods with clauses */
5000 LLVMAddFunctionAttr (method, LLVMNoInlineAttribute);
5002 if (linfo->rgctx_arg) {
5003 ctx->rgctx_arg = LLVMGetParam (method, sinfo.rgctx_arg_pindex);
5005 * We mark the rgctx parameter with the inreg attribute, which is mapped to
5006 * MONO_ARCH_RGCTX_REG in the Mono calling convention in llvm, i.e.
5007 * CC_X86_64_Mono in X86CallingConv.td.
5009 LLVMAddAttribute (ctx->rgctx_arg, LLVMInRegAttribute);
5010 LLVMSetValueName (ctx->rgctx_arg, "rgctx");
5012 if (cfg->vret_addr) {
5013 values [cfg->vret_addr->dreg] = LLVMGetParam (method, sinfo.vret_arg_pindex);
5014 LLVMSetValueName (values [cfg->vret_addr->dreg], "vret");
5017 values [cfg->args [0]->dreg] = LLVMGetParam (method, sinfo.this_arg_pindex);
5018 LLVMSetValueName (values [cfg->args [0]->dreg], "this");
5021 names = g_new (char *, sig->param_count);
5022 mono_method_get_param_names (cfg->method, (const char **) names);
5024 for (i = 0; i < sig->param_count; ++i) {
5027 values [cfg->args [i + sig->hasthis]->dreg] = LLVMGetParam (method, sinfo.pindexes [i]);
5028 if (names [i] && names [i][0] != '\0')
5029 name = g_strdup_printf ("arg_%s", names [i]);
5031 name = g_strdup_printf ("arg_%d", i);
5032 LLVMSetValueName (values [cfg->args [i + sig->hasthis]->dreg], name);
5034 if (linfo->args [i + sig->hasthis].storage == LLVMArgVtypeByVal)
5035 LLVMAddAttribute (LLVMGetParam (method, sinfo.pindexes [i]), LLVMByValAttribute);
5039 if (ctx->lmodule->emit_dwarf && cfg->compile_aot && mono_debug_enabled ()) {
5040 ctx->minfo = mono_debug_lookup_method (cfg->method);
5041 ctx->dbg_md = emit_dbg_subprogram (ctx, cfg, method, method_name);
5045 for (bb = cfg->bb_entry; bb; bb = bb->next_bb)
5046 max_block_num = MAX (max_block_num, bb->block_num);
5047 ctx->bblocks = bblocks = g_new0 (BBInfo, max_block_num + 1);
5049 /* Add branches between non-consecutive bblocks */
5050 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
5051 if (bb->last_ins && MONO_IS_COND_BRANCH_OP (bb->last_ins) &&
5052 bb->next_bb != bb->last_ins->inst_false_bb) {
5054 MonoInst *inst = mono_mempool_alloc0 (cfg->mempool, sizeof (MonoInst));
5055 inst->opcode = OP_BR;
5056 inst->inst_target_bb = bb->last_ins->inst_false_bb;
5057 mono_bblock_add_inst (bb, inst);
5062 * The INDIRECT flag added by OP_LDADDR inhibits optimizations, even if the LDADDR
5063 * was later optimized away, so clear these flags, and add them back for the still
5064 * present OP_LDADDR instructions.
5066 for (i = 0; i < cfg->next_vreg; ++i) {
5069 ins = get_vreg_to_inst (cfg, i);
5070 if (ins && ins != cfg->rgctx_var)
5071 ins->flags &= ~MONO_INST_INDIRECT;
5075 * Make a first pass over the code to precreate PHI nodes/set INDIRECT flags.
5077 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
5079 LLVMBuilderRef builder;
5081 char dname_buf[128];
5083 builder = create_builder (ctx);
5085 for (ins = bb->code; ins; ins = ins->next) {
5086 switch (ins->opcode) {
5091 LLVMTypeRef phi_type = llvm_type_to_stack_type (cfg, type_to_llvm_type (ctx, &ins->klass->byval_arg));
5093 CHECK_FAILURE (ctx);
5095 if (ins->opcode == OP_VPHI) {
5096 /* Treat valuetype PHI nodes as operating on the address itself */
5097 g_assert (ins->klass);
5098 phi_type = LLVMPointerType (type_to_llvm_type (ctx, &ins->klass->byval_arg), 0);
5102 * Have to precreate these, as they can be referenced by
5103 * earlier instructions.
5105 sprintf (dname_buf, "t%d", ins->dreg);
5107 values [ins->dreg] = LLVMBuildPhi (builder, phi_type, dname);
5109 if (ins->opcode == OP_VPHI)
5110 ctx->addresses [ins->dreg] = values [ins->dreg];
5112 g_ptr_array_add (phi_values, values [ins->dreg]);
5115 * Set the expected type of the incoming arguments since these have
5116 * to have the same type.
5118 for (i = 0; i < ins->inst_phi_args [0]; i++) {
5119 int sreg1 = ins->inst_phi_args [i + 1];
5122 ctx->vreg_types [sreg1] = phi_type;
5127 ((MonoInst*)ins->inst_p0)->flags |= MONO_INST_INDIRECT;
5136 * Create an ordering for bblocks, use the depth first order first, then
5137 * put the exception handling bblocks last.
5139 for (bb_index = 0; bb_index < cfg->num_bblocks; ++bb_index) {
5140 bb = cfg->bblocks [bb_index];
5141 if (!(bb->region != -1 && !MONO_BBLOCK_IS_IN_REGION (bb, MONO_REGION_TRY))) {
5142 g_ptr_array_add (bblock_list, bb);
5143 bblocks [bb->block_num].added = TRUE;
5147 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
5148 if (!bblocks [bb->block_num].added)
5149 g_ptr_array_add (bblock_list, bb);
5153 * Second pass: generate code.
5155 for (bb_index = 0; bb_index < bblock_list->len; ++bb_index) {
5156 bb = g_ptr_array_index (bblock_list, bb_index);
5158 if (!(bb == cfg->bb_entry || bb->in_count > 0))
5161 process_bb (ctx, bb);
5162 CHECK_FAILURE (ctx);
5165 /* Add incoming phi values */
5166 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
5167 GSList *l, *ins_list;
5169 ins_list = bblocks [bb->block_num].phi_nodes;
5171 for (l = ins_list; l; l = l->next) {
5172 PhiNode *node = l->data;
5173 MonoInst *phi = node->phi;
5174 int sreg1 = node->sreg;
5175 LLVMBasicBlockRef in_bb;
5180 in_bb = get_end_bb (ctx, node->in_bb);
5182 if (ctx->unreachable [node->in_bb->block_num])
5185 if (!values [sreg1])
5186 /* Can happen with values in EH clauses */
5187 LLVM_FAILURE (ctx, "incoming phi sreg1");
5189 if (phi->opcode == OP_VPHI) {
5190 g_assert (LLVMTypeOf (ctx->addresses [sreg1]) == LLVMTypeOf (values [phi->dreg]));
5191 LLVMAddIncoming (values [phi->dreg], &ctx->addresses [sreg1], &in_bb, 1);
5193 if (LLVMTypeOf (values [sreg1]) != LLVMTypeOf (values [phi->dreg]))
5195 LLVM_FAILURE (ctx, "incoming phi arg type mismatch");
5196 g_assert (LLVMTypeOf (values [sreg1]) == LLVMTypeOf (values [phi->dreg]));
5197 LLVMAddIncoming (values [phi->dreg], &values [sreg1], &in_bb, 1);
5202 /* Create the SWITCH statements for ENDFINALLY instructions */
5203 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
5204 BBInfo *info = &bblocks [bb->block_num];
5206 for (l = info->endfinally_switch_ins_list; l; l = l->next) {
5207 LLVMValueRef switch_ins = l->data;
5208 GSList *bb_list = info->call_handler_return_bbs;
5210 for (i = 0; i < g_slist_length (bb_list); ++i)
5211 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), i + 1, FALSE), g_slist_nth (bb_list, i)->data);
5215 if (cfg->verbose_level > 1)
5216 mono_llvm_dump_value (method);
5218 if (cfg->compile_aot)
5219 mark_as_used (ctx->lmodule, method);
5221 if (cfg->compile_aot) {
5222 LLVMValueRef md_args [16];
5223 LLVMValueRef md_node;
5226 method_index = mono_aot_get_method_index (cfg->orig_method);
5227 md_args [0] = LLVMMDString (method_name, strlen (method_name));
5228 md_args [1] = LLVMConstInt (LLVMInt32Type (), method_index, FALSE);
5229 md_node = LLVMMDNode (md_args, 2);
5230 LLVMAddNamedMetadataOperand (module, "mono.function_indexes", md_node);
5231 //LLVMSetMetadata (method, md_kind, LLVMMDNode (&md_arg, 1));
5234 if (cfg->compile_aot) {
5235 /* Don't generate native code, keep the LLVM IR */
5236 if (cfg->compile_aot && cfg->verbose_level)
5237 printf ("%s emitted as %s\n", mono_method_full_name (cfg->method, TRUE), method_name);
5239 //LLVMVerifyFunction(method, 0);
5241 mono_llvm_optimize_method (ctx->lmodule->mono_ee, method);
5243 if (cfg->verbose_level > 1)
5244 mono_llvm_dump_value (method);
5246 cfg->native_code = LLVMGetPointerToGlobal (ctx->lmodule->ee, method);
5248 /* Set by emit_cb */
5249 g_assert (cfg->code_len);
5251 /* FIXME: Free the LLVM IL for the function */
5254 if (ctx->lmodule->method_to_lmethod)
5255 g_hash_table_insert (ctx->lmodule->method_to_lmethod, cfg->method, method);
5262 /* Need to add unused phi nodes as they can be referenced by other values */
5263 LLVMBasicBlockRef phi_bb = LLVMAppendBasicBlock (method, "PHI_BB");
5264 LLVMBuilderRef builder;
5266 builder = create_builder (ctx);
5267 LLVMPositionBuilderAtEnd (builder, phi_bb);
5269 for (i = 0; i < phi_values->len; ++i) {
5270 LLVMValueRef v = g_ptr_array_index (phi_values, i);
5271 if (LLVMGetInstructionParent (v) == NULL)
5272 LLVMInsertIntoBuilder (builder, v);
5275 LLVMDeleteFunction (method);
5280 g_free (ctx->addresses);
5281 g_free (ctx->vreg_types);
5282 g_free (ctx->vreg_cli_types);
5283 g_free (ctx->pindexes);
5284 g_free (ctx->is_dead);
5285 g_free (ctx->unreachable);
5286 g_ptr_array_free (phi_values, TRUE);
5287 g_free (ctx->bblocks);
5288 g_hash_table_destroy (ctx->region_to_handler);
5289 g_hash_table_destroy (ctx->clause_to_handler);
5290 g_free (method_name);
5291 g_ptr_array_free (bblock_list, TRUE);
5293 for (l = ctx->builders; l; l = l->next) {
5294 LLVMBuilderRef builder = l->data;
5295 LLVMDisposeBuilder (builder);
5300 mono_native_tls_set_value (current_cfg_tls_id, NULL);
5302 mono_loader_unlock ();
5306 * mono_llvm_emit_call:
5308 * Same as mono_arch_emit_call () for LLVM.
5311 mono_llvm_emit_call (MonoCompile *cfg, MonoCallInst *call)
5314 MonoMethodSignature *sig;
5315 int i, n, stack_size;
5320 sig = call->signature;
5321 n = sig->param_count + sig->hasthis;
5323 call->cinfo = mono_arch_get_llvm_call_info (cfg, sig);
5325 if (cfg->disable_llvm)
5328 if (sig->call_convention == MONO_CALL_VARARG) {
5329 cfg->exception_message = g_strdup ("varargs");
5330 cfg->disable_llvm = TRUE;
5333 for (i = 0; i < n; ++i) {
5336 ainfo = call->cinfo->args + i;
5338 in = call->args [i];
5340 /* Simply remember the arguments */
5341 switch (ainfo->storage) {
5343 case LLVMArgInFPReg: {
5344 MonoType *t = (sig->hasthis && i == 0) ? &mono_get_intptr_class ()->byval_arg : sig->params [i - sig->hasthis];
5347 opcode = mono_type_to_regmove (cfg, t);
5348 if (opcode == OP_FMOVE) {
5349 MONO_INST_NEW (cfg, ins, OP_FMOVE);
5350 ins->dreg = mono_alloc_freg (cfg);
5351 } else if (opcode == OP_LMOVE) {
5352 MONO_INST_NEW (cfg, ins, OP_LMOVE);
5353 ins->dreg = mono_alloc_lreg (cfg);
5355 MONO_INST_NEW (cfg, ins, OP_MOVE);
5356 ins->dreg = mono_alloc_ireg (cfg);
5358 ins->sreg1 = in->dreg;
5361 case LLVMArgVtypeByVal:
5362 case LLVMArgVtypeInReg:
5363 case LLVMArgAsIArgs:
5364 case LLVMArgAsFpArgs:
5365 MONO_INST_NEW (cfg, ins, OP_LLVM_OUTARG_VT);
5366 ins->dreg = mono_alloc_ireg (cfg);
5367 ins->sreg1 = in->dreg;
5368 ins->klass = mono_class_from_mono_type (sig->params [i - sig->hasthis]);
5371 call->cinfo = mono_arch_get_llvm_call_info (cfg, sig);
5372 cfg->exception_message = g_strdup ("ainfo->storage");
5373 cfg->disable_llvm = TRUE;
5377 if (!cfg->disable_llvm) {
5378 MONO_ADD_INS (cfg->cbb, ins);
5379 mono_call_inst_add_outarg_reg (cfg, call, ins->dreg, 0, FALSE);
5384 static unsigned char*
5385 alloc_cb (LLVMValueRef function, int size)
5389 cfg = mono_native_tls_get_value (current_cfg_tls_id);
5393 return mono_domain_code_reserve (cfg->domain, size);
5395 return mono_domain_code_reserve (mono_domain_get (), size);
5400 emitted_cb (LLVMValueRef function, void *start, void *end)
5404 cfg = mono_native_tls_get_value (current_cfg_tls_id);
5406 cfg->code_len = (guint8*)end - (guint8*)start;
5410 exception_cb (void *data)
5413 MonoJitExceptionInfo *ei;
5414 guint32 ei_len, i, j, nested_len, nindex;
5415 gpointer *type_info;
5416 int this_reg, this_offset;
5418 cfg = mono_native_tls_get_value (current_cfg_tls_id);
5422 * data points to a DWARF FDE structure, convert it to our unwind format and
5424 * An alternative would be to save it directly, and modify our unwinder to work
5427 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);
5428 if (cfg->verbose_level > 1)
5429 mono_print_unwind_info (cfg->encoded_unwind_ops, cfg->encoded_unwind_ops_len);
5431 /* Count nested clauses */
5433 for (i = 0; i < ei_len; ++i) {
5434 for (j = 0; j < ei_len; ++j) {
5435 gint32 cindex1 = *(gint32*)type_info [i];
5436 MonoExceptionClause *clause1 = &cfg->header->clauses [cindex1];
5437 gint32 cindex2 = *(gint32*)type_info [j];
5438 MonoExceptionClause *clause2 = &cfg->header->clauses [cindex2];
5440 if (cindex1 != cindex2 && clause1->try_offset >= clause2->try_offset && clause1->handler_offset <= clause2->handler_offset) {
5446 cfg->llvm_ex_info = mono_mempool_alloc0 (cfg->mempool, (ei_len + nested_len) * sizeof (MonoJitExceptionInfo));
5447 cfg->llvm_ex_info_len = ei_len + nested_len;
5448 memcpy (cfg->llvm_ex_info, ei, ei_len * sizeof (MonoJitExceptionInfo));
5449 /* Fill the rest of the information from the type info */
5450 for (i = 0; i < ei_len; ++i) {
5451 gint32 clause_index = *(gint32*)type_info [i];
5452 MonoExceptionClause *clause = &cfg->header->clauses [clause_index];
5454 cfg->llvm_ex_info [i].flags = clause->flags;
5455 cfg->llvm_ex_info [i].data.catch_class = clause->data.catch_class;
5456 cfg->llvm_ex_info [i].clause_index = clause_index;
5460 * For nested clauses, the LLVM produced exception info associates the try interval with
5461 * the innermost handler, while mono expects it to be associated with all nesting clauses.
5462 * So add new clauses which use the IL info (catch class etc.) from the nesting clause,
5463 * and everything else from the nested clause.
5466 for (i = 0; i < ei_len; ++i) {
5467 for (j = 0; j < ei_len; ++j) {
5468 gint32 cindex1 = *(gint32*)type_info [i];
5469 MonoExceptionClause *clause1 = &cfg->header->clauses [cindex1];
5470 gint32 cindex2 = *(gint32*)type_info [j];
5471 MonoExceptionClause *clause2 = &cfg->header->clauses [cindex2];
5473 if (cindex1 != cindex2 && clause1->try_offset >= clause2->try_offset && clause1->handler_offset <= clause2->handler_offset) {
5474 memcpy (&cfg->llvm_ex_info [nindex], &cfg->llvm_ex_info [j], sizeof (MonoJitExceptionInfo));
5475 cfg->llvm_ex_info [nindex].try_start = cfg->llvm_ex_info [i].try_start;
5476 cfg->llvm_ex_info [nindex].try_end = cfg->llvm_ex_info [i].try_end;
5477 cfg->llvm_ex_info [nindex].handler_start = cfg->llvm_ex_info [i].handler_start;
5478 cfg->llvm_ex_info [nindex].exvar_offset = cfg->llvm_ex_info [i].exvar_offset;
5483 g_assert (nindex == ei_len + nested_len);
5484 cfg->llvm_this_reg = this_reg;
5485 cfg->llvm_this_offset = this_offset;
5487 /* type_info [i] is cfg mempool allocated, no need to free it */
5494 dlsym_cb (const char *name, void **symbol)
5500 if (!strcmp (name, "__bzero")) {
5501 *symbol = (void*)bzero;
5503 current = mono_dl_open (NULL, 0, NULL);
5506 err = mono_dl_symbol (current, name, symbol);
5508 mono_dl_close (current);
5510 #ifdef MONO_ARCH_HAVE_CREATE_LLVM_NATIVE_THUNK
5511 *symbol = (char*)mono_arch_create_llvm_native_thunk (mono_domain_get (), (guint8*)(*symbol));
5517 AddFunc (LLVMModuleRef module, const char *name, LLVMTypeRef ret_type, LLVMTypeRef *param_types, int nparams)
5519 LLVMAddFunction (module, name, LLVMFunctionType (ret_type, param_types, nparams, FALSE));
5523 AddFunc2 (LLVMModuleRef module, const char *name, LLVMTypeRef ret_type, LLVMTypeRef param_type1, LLVMTypeRef param_type2)
5525 LLVMTypeRef param_types [4];
5527 param_types [0] = param_type1;
5528 param_types [1] = param_type2;
5530 AddFunc (module, name, ret_type, param_types, 2);
5534 add_intrinsics (LLVMModuleRef module)
5536 /* Emit declarations of instrinsics */
5538 * It would be nicer to emit only the intrinsics actually used, but LLVM's Module
5539 * type doesn't seem to do any locking.
5542 LLVMTypeRef memset_params [] = { LLVMPointerType (LLVMInt8Type (), 0), LLVMInt8Type (), LLVMInt32Type (), LLVMInt32Type (), LLVMInt1Type () };
5544 memset_param_count = 5;
5545 memset_func_name = "llvm.memset.p0i8.i32";
5547 LLVMAddFunction (module, memset_func_name, LLVMFunctionType (LLVMVoidType (), memset_params, memset_param_count, FALSE));
5551 LLVMTypeRef memcpy_params [] = { LLVMPointerType (LLVMInt8Type (), 0), LLVMPointerType (LLVMInt8Type (), 0), LLVMInt32Type (), LLVMInt32Type (), LLVMInt1Type () };
5553 memcpy_param_count = 5;
5554 memcpy_func_name = "llvm.memcpy.p0i8.p0i8.i32";
5556 LLVMAddFunction (module, memcpy_func_name, LLVMFunctionType (LLVMVoidType (), memcpy_params, memcpy_param_count, FALSE));
5560 LLVMTypeRef params [] = { LLVMDoubleType () };
5562 LLVMAddFunction (module, "llvm.sin.f64", LLVMFunctionType (LLVMDoubleType (), params, 1, FALSE));
5563 LLVMAddFunction (module, "llvm.cos.f64", LLVMFunctionType (LLVMDoubleType (), params, 1, FALSE));
5564 LLVMAddFunction (module, "llvm.sqrt.f64", LLVMFunctionType (LLVMDoubleType (), params, 1, FALSE));
5566 /* This isn't an intrinsic, instead llvm seems to special case it by name */
5567 LLVMAddFunction (module, "fabs", LLVMFunctionType (LLVMDoubleType (), params, 1, FALSE));
5571 LLVMTypeRef ovf_res_i32 [] = { LLVMInt32Type (), LLVMInt1Type () };
5572 LLVMTypeRef ovf_params_i32 [] = { LLVMInt32Type (), LLVMInt32Type () };
5574 LLVMAddFunction (module, "llvm.sadd.with.overflow.i32", LLVMFunctionType (LLVMStructType (ovf_res_i32, 2, FALSE), ovf_params_i32, 2, FALSE));
5575 LLVMAddFunction (module, "llvm.uadd.with.overflow.i32", LLVMFunctionType (LLVMStructType (ovf_res_i32, 2, FALSE), ovf_params_i32, 2, FALSE));
5576 LLVMAddFunction (module, "llvm.ssub.with.overflow.i32", LLVMFunctionType (LLVMStructType (ovf_res_i32, 2, FALSE), ovf_params_i32, 2, FALSE));
5577 LLVMAddFunction (module, "llvm.usub.with.overflow.i32", LLVMFunctionType (LLVMStructType (ovf_res_i32, 2, FALSE), ovf_params_i32, 2, FALSE));
5578 LLVMAddFunction (module, "llvm.smul.with.overflow.i32", LLVMFunctionType (LLVMStructType (ovf_res_i32, 2, FALSE), ovf_params_i32, 2, FALSE));
5579 LLVMAddFunction (module, "llvm.umul.with.overflow.i32", LLVMFunctionType (LLVMStructType (ovf_res_i32, 2, FALSE), ovf_params_i32, 2, FALSE));
5583 LLVMTypeRef ovf_res_i64 [] = { LLVMInt64Type (), LLVMInt1Type () };
5584 LLVMTypeRef ovf_params_i64 [] = { LLVMInt64Type (), LLVMInt64Type () };
5586 LLVMAddFunction (module, "llvm.sadd.with.overflow.i64", LLVMFunctionType (LLVMStructType (ovf_res_i64, 2, FALSE), ovf_params_i64, 2, FALSE));
5587 LLVMAddFunction (module, "llvm.uadd.with.overflow.i64", LLVMFunctionType (LLVMStructType (ovf_res_i64, 2, FALSE), ovf_params_i64, 2, FALSE));
5588 LLVMAddFunction (module, "llvm.ssub.with.overflow.i64", LLVMFunctionType (LLVMStructType (ovf_res_i64, 2, FALSE), ovf_params_i64, 2, FALSE));
5589 LLVMAddFunction (module, "llvm.usub.with.overflow.i64", LLVMFunctionType (LLVMStructType (ovf_res_i64, 2, FALSE), ovf_params_i64, 2, FALSE));
5590 LLVMAddFunction (module, "llvm.smul.with.overflow.i64", LLVMFunctionType (LLVMStructType (ovf_res_i64, 2, FALSE), ovf_params_i64, 2, FALSE));
5591 LLVMAddFunction (module, "llvm.umul.with.overflow.i64", LLVMFunctionType (LLVMStructType (ovf_res_i64, 2, FALSE), ovf_params_i64, 2, FALSE));
5596 LLVMTypeRef arg_types [2];
5597 LLVMTypeRef ret_type;
5599 arg_types [0] = LLVMPointerType (LLVMInt8Type (), 0);
5600 arg_types [1] = LLVMPointerType (LLVMInt8Type (), 0);
5601 ret_type = LLVMInt32Type ();
5603 LLVMAddFunction (module, "mono_personality", LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE));
5605 LLVMAddFunction (module, "llvm_resume_unwind_trampoline", LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE));
5608 /* SSE intrinsics */
5609 #if defined(TARGET_X86) || defined(TARGET_AMD64)
5611 LLVMTypeRef ret_type, arg_types [16];
5614 ret_type = type_to_simd_type (MONO_TYPE_I4);
5615 arg_types [0] = ret_type;
5616 arg_types [1] = ret_type;
5617 AddFunc (module, "llvm.x86.sse41.pminud", ret_type, arg_types, 2);
5618 AddFunc (module, "llvm.x86.sse41.pmaxud", ret_type, arg_types, 2);
5620 ret_type = type_to_simd_type (MONO_TYPE_I2);
5621 arg_types [0] = ret_type;
5622 arg_types [1] = ret_type;
5623 AddFunc (module, "llvm.x86.sse41.pminuw", ret_type, arg_types, 2);
5624 AddFunc (module, "llvm.x86.sse2.pmins.w", ret_type, arg_types, 2);
5625 AddFunc (module, "llvm.x86.sse41.pmaxuw", ret_type, arg_types, 2);
5626 AddFunc (module, "llvm.x86.sse2.padds.w", ret_type, arg_types, 2);
5627 AddFunc (module, "llvm.x86.sse2.psubs.w", ret_type, arg_types, 2);
5628 AddFunc (module, "llvm.x86.sse2.paddus.w", ret_type, arg_types, 2);
5629 AddFunc (module, "llvm.x86.sse2.psubus.w", ret_type, arg_types, 2);
5630 AddFunc (module, "llvm.x86.sse2.pavg.w", ret_type, arg_types, 2);
5631 AddFunc (module, "llvm.x86.sse2.pmulh.w", ret_type, arg_types, 2);
5632 AddFunc (module, "llvm.x86.sse2.pmulhu.w", ret_type, arg_types, 2);
5634 ret_type = type_to_simd_type (MONO_TYPE_I1);
5635 arg_types [0] = ret_type;
5636 arg_types [1] = ret_type;
5637 AddFunc (module, "llvm.x86.sse2.pminu.b", ret_type, arg_types, 2);
5638 AddFunc (module, "llvm.x86.sse2.pmaxu.b", ret_type, arg_types, 2);
5639 AddFunc (module, "llvm.x86.sse2.padds.b", ret_type, arg_types, 2);
5640 AddFunc (module, "llvm.x86.sse2.psubs.b", ret_type, arg_types, 2);
5641 AddFunc (module, "llvm.x86.sse2.paddus.b", ret_type, arg_types, 2);
5642 AddFunc (module, "llvm.x86.sse2.psubus.b", ret_type, arg_types, 2);
5643 AddFunc (module, "llvm.x86.sse2.pavg.b", ret_type, arg_types, 2);
5645 ret_type = type_to_simd_type (MONO_TYPE_R8);
5646 arg_types [0] = ret_type;
5647 arg_types [1] = ret_type;
5648 AddFunc (module, "llvm.x86.sse2.min.pd", ret_type, arg_types, 2);
5649 AddFunc (module, "llvm.x86.sse2.max.pd", ret_type, arg_types, 2);
5650 AddFunc (module, "llvm.x86.sse3.hadd.pd", ret_type, arg_types, 2);
5651 AddFunc (module, "llvm.x86.sse3.hsub.pd", ret_type, arg_types, 2);
5652 AddFunc (module, "llvm.x86.sse3.addsub.pd", ret_type, arg_types, 2);
5654 ret_type = type_to_simd_type (MONO_TYPE_R4);
5655 arg_types [0] = ret_type;
5656 arg_types [1] = ret_type;
5657 AddFunc (module, "llvm.x86.sse.min.ps", ret_type, arg_types, 2);
5658 AddFunc (module, "llvm.x86.sse.max.ps", ret_type, arg_types, 2);
5659 AddFunc (module, "llvm.x86.sse3.hadd.ps", ret_type, arg_types, 2);
5660 AddFunc (module, "llvm.x86.sse3.hsub.ps", ret_type, arg_types, 2);
5661 AddFunc (module, "llvm.x86.sse3.addsub.ps", ret_type, arg_types, 2);
5664 ret_type = type_to_simd_type (MONO_TYPE_I1);
5665 arg_types [0] = type_to_simd_type (MONO_TYPE_I2);
5666 arg_types [1] = type_to_simd_type (MONO_TYPE_I2);
5667 AddFunc (module, "llvm.x86.sse2.packsswb.128", ret_type, arg_types, 2);
5668 AddFunc (module, "llvm.x86.sse2.packuswb.128", ret_type, arg_types, 2);
5669 ret_type = type_to_simd_type (MONO_TYPE_I2);
5670 arg_types [0] = type_to_simd_type (MONO_TYPE_I4);
5671 arg_types [1] = type_to_simd_type (MONO_TYPE_I4);
5672 AddFunc (module, "llvm.x86.sse2.packssdw.128", ret_type, arg_types, 2);
5673 AddFunc (module, "llvm.x86.sse41.packusdw", ret_type, arg_types, 2);
5676 ret_type = type_to_simd_type (MONO_TYPE_R8);
5677 arg_types [0] = ret_type;
5678 arg_types [1] = ret_type;
5679 arg_types [2] = LLVMInt8Type ();
5680 AddFunc (module, "llvm.x86.sse2.cmp.pd", ret_type, arg_types, 3);
5681 ret_type = type_to_simd_type (MONO_TYPE_R4);
5682 arg_types [0] = ret_type;
5683 arg_types [1] = ret_type;
5684 arg_types [2] = LLVMInt8Type ();
5685 AddFunc (module, "llvm.x86.sse.cmp.ps", ret_type, arg_types, 3);
5687 /* Conversion ops */
5688 ret_type = type_to_simd_type (MONO_TYPE_R8);
5689 arg_types [0] = type_to_simd_type (MONO_TYPE_I4);
5690 AddFunc (module, "llvm.x86.sse2.cvtdq2pd", ret_type, arg_types, 1);
5691 ret_type = type_to_simd_type (MONO_TYPE_R4);
5692 arg_types [0] = type_to_simd_type (MONO_TYPE_I4);
5693 AddFunc (module, "llvm.x86.sse2.cvtdq2ps", ret_type, arg_types, 1);
5694 ret_type = type_to_simd_type (MONO_TYPE_I4);
5695 arg_types [0] = type_to_simd_type (MONO_TYPE_R8);
5696 AddFunc (module, "llvm.x86.sse2.cvtpd2dq", ret_type, arg_types, 1);
5697 ret_type = type_to_simd_type (MONO_TYPE_I4);
5698 arg_types [0] = type_to_simd_type (MONO_TYPE_R4);
5699 AddFunc (module, "llvm.x86.sse2.cvtps2dq", ret_type, arg_types, 1);
5700 ret_type = type_to_simd_type (MONO_TYPE_R4);
5701 arg_types [0] = type_to_simd_type (MONO_TYPE_R8);
5702 AddFunc (module, "llvm.x86.sse2.cvtpd2ps", ret_type, arg_types, 1);
5703 ret_type = type_to_simd_type (MONO_TYPE_R8);
5704 arg_types [0] = type_to_simd_type (MONO_TYPE_R4);
5705 AddFunc (module, "llvm.x86.sse2.cvtps2pd", ret_type, arg_types, 1);
5707 ret_type = type_to_simd_type (MONO_TYPE_I4);
5708 arg_types [0] = type_to_simd_type (MONO_TYPE_R8);
5709 AddFunc (module, "llvm.x86.sse2.cvttpd2dq", ret_type, arg_types, 1);
5710 ret_type = type_to_simd_type (MONO_TYPE_I4);
5711 arg_types [0] = type_to_simd_type (MONO_TYPE_R4);
5712 AddFunc (module, "llvm.x86.sse2.cvttps2dq", ret_type, arg_types, 1);
5715 ret_type = type_to_simd_type (MONO_TYPE_R8);
5716 arg_types [0] = ret_type;
5717 AddFunc (module, "llvm.x86.sse2.sqrt.pd", ret_type, arg_types, 1);
5718 ret_type = type_to_simd_type (MONO_TYPE_R4);
5719 arg_types [0] = ret_type;
5720 AddFunc (module, "llvm.x86.sse.sqrt.ps", ret_type, arg_types, 1);
5721 ret_type = type_to_simd_type (MONO_TYPE_R4);
5722 arg_types [0] = ret_type;
5723 AddFunc (module, "llvm.x86.sse.rsqrt.ps", 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.rcp.ps", ret_type, arg_types, 1);
5729 ret_type = type_to_simd_type (MONO_TYPE_I2);
5730 arg_types [0] = ret_type;
5731 arg_types [1] = LLVMInt32Type ();
5732 AddFunc (module, "llvm.x86.sse2.psrli.w", ret_type, arg_types, 2);
5733 AddFunc (module, "llvm.x86.sse2.psrai.w", ret_type, arg_types, 2);
5734 AddFunc (module, "llvm.x86.sse2.pslli.w", ret_type, arg_types, 2);
5735 ret_type = type_to_simd_type (MONO_TYPE_I4);
5736 arg_types [0] = ret_type;
5737 arg_types [1] = LLVMInt32Type ();
5738 AddFunc (module, "llvm.x86.sse2.psrli.d", ret_type, arg_types, 2);
5739 AddFunc (module, "llvm.x86.sse2.psrai.d", ret_type, arg_types, 2);
5740 AddFunc (module, "llvm.x86.sse2.pslli.d", ret_type, arg_types, 2);
5741 ret_type = type_to_simd_type (MONO_TYPE_I8);
5742 arg_types [0] = ret_type;
5743 arg_types [1] = LLVMInt32Type ();
5744 AddFunc (module, "llvm.x86.sse2.psrli.q", ret_type, arg_types, 2);
5745 AddFunc (module, "llvm.x86.sse2.pslli.q", ret_type, arg_types, 2);
5748 ret_type = LLVMInt32Type ();
5749 arg_types [0] = type_to_simd_type (MONO_TYPE_I1);
5750 AddFunc (module, "llvm.x86.sse2.pmovmskb.128", ret_type, arg_types, 1);
5753 AddFunc (module, "llvm.x86.sse2.pause", LLVMVoidType (), NULL, 0);
5756 /* Load/Store intrinsics */
5758 LLVMTypeRef arg_types [5];
5762 for (i = 1; i <= 8; i *= 2) {
5763 arg_types [0] = LLVMPointerType (LLVMIntType (i * 8), 0);
5764 arg_types [1] = LLVMInt32Type ();
5765 arg_types [2] = LLVMInt1Type ();
5766 arg_types [3] = LLVMInt32Type ();
5767 sprintf (name, "llvm.mono.load.i%d.p0i%d", i * 8, i * 8);
5768 LLVMAddFunction (module, name, LLVMFunctionType (LLVMIntType (i * 8), arg_types, 4, FALSE));
5770 arg_types [0] = LLVMIntType (i * 8);
5771 arg_types [1] = LLVMPointerType (LLVMIntType (i * 8), 0);
5772 arg_types [2] = LLVMInt32Type ();
5773 arg_types [3] = LLVMInt1Type ();
5774 arg_types [4] = LLVMInt32Type ();
5775 sprintf (name, "llvm.mono.store.i%d.p0i%d", i * 8, i * 8);
5776 LLVMAddFunction (module, name, LLVMFunctionType (LLVMVoidType (), arg_types, 5, FALSE));
5782 add_types (MonoLLVMModule *lmodule)
5784 lmodule->ptr_type = LLVMPointerType (sizeof (gpointer) == 8 ? LLVMInt64Type () : LLVMInt32Type (), 0);
5788 mono_llvm_init (void)
5790 mono_native_tls_alloc (¤t_cfg_tls_id, NULL);
5794 init_jit_module (MonoDomain *domain)
5796 MonoJitICallInfo *info;
5797 MonoJitDomainInfo *dinfo;
5798 MonoLLVMModule *module;
5801 dinfo = domain_jit_info (domain);
5802 if (dinfo->llvm_module)
5805 mono_loader_lock ();
5807 if (dinfo->llvm_module) {
5808 mono_loader_unlock ();
5812 module = g_new0 (MonoLLVMModule, 1);
5814 name = g_strdup_printf ("mono-%s", domain->friendly_name);
5815 module->module = LLVMModuleCreateWithName (name);
5817 module->mono_ee = mono_llvm_create_ee (LLVMCreateModuleProviderForExistingModule (module->module), alloc_cb, emitted_cb, exception_cb, dlsym_cb, &module->ee);
5819 add_intrinsics (module->module);
5822 module->llvm_types = g_hash_table_new (NULL, NULL);
5824 info = mono_find_jit_icall_by_name ("llvm_resume_unwind_trampoline");
5826 LLVMAddGlobalMapping (module->ee, LLVMGetNamedFunction (module->module, "llvm_resume_unwind_trampoline"), (void*)info->func);
5828 mono_memory_barrier ();
5830 dinfo->llvm_module = module;
5832 mono_loader_unlock ();
5836 mono_llvm_cleanup (void)
5838 if (aot_module.module)
5839 LLVMDisposeModule (aot_module.module);
5841 LLVMContextDispose (LLVMGetGlobalContext ());
5845 mono_llvm_free_domain_info (MonoDomain *domain)
5847 MonoJitDomainInfo *info = domain_jit_info (domain);
5848 MonoLLVMModule *module = info->llvm_module;
5854 if (module->llvm_types)
5855 g_hash_table_destroy (module->llvm_types);
5857 mono_llvm_dispose_ee (module->mono_ee);
5859 if (module->bb_names) {
5860 for (i = 0; i < module->bb_names_len; ++i)
5861 g_free (module->bb_names [i]);
5862 g_free (module->bb_names);
5864 //LLVMDisposeModule (module->module);
5868 info->llvm_module = NULL;
5872 mono_llvm_create_aot_module (const char *got_symbol, gboolean external_symbols, gboolean emit_dwarf)
5874 /* Delete previous module */
5875 if (aot_module.plt_entries)
5876 g_hash_table_destroy (aot_module.plt_entries);
5877 if (aot_module.module)
5878 LLVMDisposeModule (aot_module.module);
5880 memset (&aot_module, 0, sizeof (aot_module));
5882 aot_module.module = LLVMModuleCreateWithName ("aot");
5883 aot_module.got_symbol = got_symbol;
5884 aot_module.external_symbols = external_symbols;
5885 aot_module.emit_dwarf = emit_dwarf;
5886 /* The first few entries are reserved */
5887 aot_module.max_got_offset = 16;
5889 add_intrinsics (aot_module.module);
5890 add_types (&aot_module);
5894 * We couldn't compute the type of the LLVM global representing the got because
5895 * its size is only known after all the methods have been emitted. So create
5896 * a dummy variable, and replace all uses it with the real got variable when
5897 * its size is known in mono_llvm_emit_aot_module ().
5900 LLVMTypeRef got_type = LLVMArrayType (aot_module.ptr_type, 0);
5902 aot_module.got_var = LLVMAddGlobal (aot_module.module, got_type, "mono_dummy_got");
5903 LLVMSetInitializer (aot_module.got_var, LLVMConstNull (got_type));
5906 /* Add a dummy personality function */
5908 LLVMBasicBlockRef lbb;
5909 LLVMBuilderRef lbuilder;
5910 LLVMValueRef personality;
5912 personality = LLVMAddFunction (aot_module.module, "mono_aot_personality", LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE));
5913 LLVMSetLinkage (personality, LLVMInternalLinkage);
5914 lbb = LLVMAppendBasicBlock (personality, "BB0");
5915 lbuilder = LLVMCreateBuilder ();
5916 LLVMPositionBuilderAtEnd (lbuilder, lbb);
5917 LLVMBuildRetVoid (lbuilder);
5918 mark_as_used (&aot_module, personality);
5921 aot_module.llvm_types = g_hash_table_new (NULL, NULL);
5922 aot_module.plt_entries = g_hash_table_new (g_str_hash, g_str_equal);
5923 aot_module.plt_entries_ji = g_hash_table_new (NULL, NULL);
5924 aot_module.method_to_lmethod = g_hash_table_new (NULL, NULL);
5928 * Emit the aot module into the LLVM bitcode file FILENAME.
5931 mono_llvm_emit_aot_module (const char *filename, const char *cu_name)
5933 LLVMTypeRef got_type;
5934 LLVMValueRef real_got;
5935 MonoLLVMModule *module = &aot_module;
5938 * Create the real got variable and replace all uses of the dummy variable with
5941 got_type = LLVMArrayType (aot_module.ptr_type, module->max_got_offset + 1);
5942 real_got = LLVMAddGlobal (aot_module.module, got_type, aot_module.got_symbol);
5943 LLVMSetInitializer (real_got, LLVMConstNull (got_type));
5944 if (module->external_symbols) {
5945 LLVMSetLinkage (real_got, LLVMExternalLinkage);
5946 LLVMSetVisibility (real_got, LLVMHiddenVisibility);
5948 LLVMSetLinkage (real_got, LLVMInternalLinkage);
5950 mono_llvm_replace_uses_of (aot_module.got_var, real_got);
5952 mark_as_used (&aot_module, real_got);
5954 /* Delete the dummy got so it doesn't become a global */
5955 LLVMDeleteGlobal (aot_module.got_var);
5957 emit_llvm_used (&aot_module);
5958 emit_dbg_info (&aot_module, filename, cu_name);
5960 /* Replace PLT entries for directly callable methods with the methods themselves */
5962 GHashTableIter iter;
5964 LLVMValueRef callee;
5966 g_hash_table_iter_init (&iter, aot_module.plt_entries_ji);
5967 while (g_hash_table_iter_next (&iter, (void**)&ji, (void**)&callee)) {
5968 if (mono_aot_is_direct_callable (ji)) {
5969 LLVMValueRef lmethod;
5971 lmethod = g_hash_table_lookup (module->method_to_lmethod, ji->data.method);
5972 /* The types might not match because the caller might pass an rgctx */
5973 if (lmethod && LLVMTypeOf (callee) == LLVMTypeOf (lmethod)) {
5974 mono_llvm_replace_uses_of (callee, lmethod);
5975 mono_aot_mark_unused_llvm_plt_entry (ji);
5985 if (LLVMVerifyModule (aot_module.module, LLVMReturnStatusAction, &verifier_err)) {
5986 g_assert_not_reached ();
5991 LLVMWriteBitcodeToFile (aot_module.module, filename);
5996 md_string (const char *s)
5998 return LLVMMDString (s, strlen (s));
6001 /* Debugging support */
6004 emit_dbg_info (MonoLLVMModule *lmodule, const char *filename, const char *cu_name)
6006 LLVMModuleRef module = lmodule->module;
6007 LLVMValueRef args [16], cu_args [16], cu, ver;
6009 char *build_info, *s, *dir;
6012 * This can only be enabled when LLVM code is emitted into a separate object
6013 * file, since the AOT compiler also emits dwarf info,
6014 * and the abbrev indexes will not be correct since llvm has added its own
6017 if (!lmodule->emit_dwarf)
6021 * Emit dwarf info in the form of LLVM metadata. There is some
6022 * out-of-date documentation at:
6023 * http://llvm.org/docs/SourceLevelDebugging.html
6024 * but most of this was gathered from the llvm and
6029 cu_args [n_cuargs ++] = LLVMConstInt (LLVMInt32Type (), DW_TAG_compile_unit, FALSE);
6030 /* CU name/compilation dir */
6031 dir = g_path_get_dirname (filename);
6032 args [0] = LLVMMDString (cu_name, strlen (cu_name));
6033 args [1] = LLVMMDString (dir, strlen (dir));
6034 cu_args [n_cuargs ++] = LLVMMDNode (args, 2);
6037 cu_args [n_cuargs ++] = LLVMConstInt (LLVMInt32Type (), DW_LANG_C99, FALSE);
6039 build_info = mono_get_runtime_build_info ();
6040 s = g_strdup_printf ("Mono AOT Compiler %s (LLVM)", build_info);
6041 cu_args [n_cuargs ++] = LLVMMDString (s, strlen (s));
6042 g_free (build_info);
6044 cu_args [n_cuargs ++] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
6046 cu_args [n_cuargs ++] = LLVMMDString ("", strlen (""));
6047 /* Runtime version */
6048 cu_args [n_cuargs ++] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
6050 cu_args [n_cuargs ++] = LLVMMDNode (args, 0);
6051 cu_args [n_cuargs ++] = LLVMMDNode (args, 0);
6053 if (lmodule->subprogram_mds) {
6057 mds = g_new0 (LLVMValueRef, lmodule->subprogram_mds->len);
6058 for (i = 0; i < lmodule->subprogram_mds->len; ++i)
6059 mds [i] = g_ptr_array_index (lmodule->subprogram_mds, i);
6060 cu_args [n_cuargs ++] = LLVMMDNode (mds, lmodule->subprogram_mds->len);
6062 cu_args [n_cuargs ++] = LLVMMDNode (args, 0);
6065 cu_args [n_cuargs ++] = LLVMMDNode (args, 0);
6066 /* Imported modules */
6067 cu_args [n_cuargs ++] = LLVMMDNode (args, 0);
6069 cu_args [n_cuargs ++] = LLVMMDString ("", strlen (""));
6070 /* DebugEmissionKind = FullDebug */
6071 cu_args [n_cuargs ++] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
6072 cu = LLVMMDNode (cu_args, n_cuargs);
6073 LLVMAddNamedMetadataOperand (module, "llvm.dbg.cu", cu);
6075 args [0] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
6076 args [1] = LLVMMDString ("Dwarf Version", strlen ("Dwarf Version"));
6077 args [2] = LLVMConstInt (LLVMInt32Type (), 2, FALSE);
6078 ver = LLVMMDNode (args, 3);
6079 LLVMAddNamedMetadataOperand (module, "llvm.module.flags", ver);
6081 args [0] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
6082 args [1] = LLVMMDString ("Debug Info Version", strlen ("Debug Info Version"));
6083 args [2] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
6084 ver = LLVMMDNode (args, 3);
6085 LLVMAddNamedMetadataOperand (module, "llvm.module.flags", ver);
6089 emit_dbg_subprogram (EmitContext *ctx, MonoCompile *cfg, LLVMValueRef method, const char *name)
6091 MonoLLVMModule *module = ctx->lmodule;
6092 MonoDebugMethodInfo *minfo = ctx->minfo;
6093 char *source_file, *dir, *filename;
6094 LLVMValueRef md, args [16], ctx_args [16], md_args [64], type_args [16], ctx_md, type_md;
6102 mono_debug_symfile_get_line_numbers_full (minfo, &source_file, NULL, &n_il_offsets, &il_offsets, &line_numbers, NULL, NULL, NULL, NULL);
6104 source_file = g_strdup ("<unknown>");
6105 dir = g_path_get_dirname (source_file);
6106 filename = g_path_get_basename (source_file);
6108 ctx_args [0] = LLVMConstInt (LLVMInt32Type (), 0x29, FALSE);
6109 args [0] = md_string (filename);
6110 args [1] = md_string (dir);
6111 ctx_args [1] = LLVMMDNode (args, 2);
6112 ctx_md = LLVMMDNode (ctx_args, 2);
6114 type_args [0] = LLVMConstInt (LLVMInt32Type (), DW_TAG_subroutine_type, FALSE);
6115 type_args [1] = NULL;
6116 type_args [2] = NULL;
6117 type_args [3] = LLVMMDString ("", 0);
6118 type_args [4] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
6119 type_args [5] = LLVMConstInt (LLVMInt64Type (), 0, FALSE);
6120 type_args [6] = LLVMConstInt (LLVMInt64Type (), 0, FALSE);
6121 type_args [7] = LLVMConstInt (LLVMInt64Type (), 0, FALSE);
6122 type_args [8] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
6123 type_args [9] = NULL;
6124 type_args [10] = NULL;
6125 type_args [11] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
6126 type_args [12] = NULL;
6127 type_args [13] = NULL;
6128 type_args [14] = NULL;
6129 type_md = LLVMMDNode (type_args, 14);
6131 /* http://llvm.org/docs/SourceLevelDebugging.html#subprogram-descriptors */
6132 md_args [0] = LLVMConstInt (LLVMInt32Type (), DW_TAG_subprogram, FALSE);
6133 /* Source directory + file pair */
6134 args [0] = md_string (filename);
6135 args [1] = md_string (dir);
6136 md_args [1] = LLVMMDNode (args ,2);
6137 md_args [2] = ctx_md;
6138 md_args [3] = md_string (cfg->method->name);
6139 md_args [4] = md_string (name);
6140 md_args [5] = md_string (name);
6143 md_args [6] = LLVMConstInt (LLVMInt32Type (), line_numbers [0], FALSE);
6145 md_args [6] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
6147 md_args [7] = type_md;
6149 md_args [8] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
6151 md_args [9] = LLVMConstInt (LLVMInt1Type (), 1, FALSE);
6153 md_args [10] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
6154 /* Index into a virtual function */
6155 md_args [11] = NULL;
6156 md_args [12] = NULL;
6158 md_args [13] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
6160 md_args [14] = LLVMConstInt (LLVMInt1Type (), 1, FALSE);
6161 /* Pointer to LLVM function */
6162 md_args [15] = method;
6163 /* Function template parameter */
6164 md_args [16] = NULL;
6165 /* Function declaration descriptor */
6166 md_args [17] = NULL;
6167 /* List of function variables */
6168 md_args [18] = LLVMMDNode (args, 0);
6170 md_args [19] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
6171 md = LLVMMDNode (md_args, 20);
6173 if (!module->subprogram_mds)
6174 module->subprogram_mds = g_ptr_array_new ();
6175 g_ptr_array_add (module->subprogram_mds, md);
6179 g_free (source_file);
6180 g_free (il_offsets);
6181 g_free (line_numbers);
6187 emit_dbg_loc (EmitContext *ctx, LLVMBuilderRef builder, const unsigned char *cil_code)
6189 MonoCompile *cfg = ctx->cfg;
6191 if (ctx->minfo && cil_code && cil_code >= cfg->header->code && cil_code < cfg->header->code + cfg->header->code_size) {
6192 MonoDebugSourceLocation *loc;
6193 LLVMValueRef loc_md, md_args [16];
6196 loc = mono_debug_symfile_lookup_location (ctx->minfo, cil_code - cfg->header->code);
6200 md_args [nmd_args ++] = LLVMConstInt (LLVMInt32Type (), loc->row, FALSE);
6201 md_args [nmd_args ++] = LLVMConstInt (LLVMInt32Type (), loc->column, FALSE);
6202 md_args [nmd_args ++] = ctx->dbg_md;
6203 md_args [nmd_args ++] = NULL;
6204 loc_md = LLVMMDNode (md_args, nmd_args);
6205 LLVMSetCurrentDebugLocation (builder, loc_md);
6206 mono_debug_symfile_free_location (loc);
6213 - Emit LLVM IR from the mono IR using the LLVM C API.
6214 - The original arch specific code remains, so we can fall back to it if we run
6215 into something we can't handle.
6219 A partial list of issues:
6220 - Handling of opcodes which can throw exceptions.
6222 In the mono JIT, these are implemented using code like this:
6229 push throw_pos - method
6230 call <exception trampoline>
6232 The problematic part is push throw_pos - method, which cannot be represented
6233 in the LLVM IR, since it does not support label values.
6234 -> this can be implemented in AOT mode using inline asm + labels, but cannot
6235 be implemented in JIT mode ?
6236 -> a possible but slower implementation would use the normal exception
6237 throwing code but it would need to control the placement of the throw code
6238 (it needs to be exactly after the compare+branch).
6239 -> perhaps add a PC offset intrinsics ?
6241 - efficient implementation of .ovf opcodes.
6243 These are currently implemented as:
6244 <ins which sets the condition codes>
6247 Some overflow opcodes are now supported by LLVM SVN.
6249 - exception handling, unwinding.
6250 - SSA is disabled for methods with exception handlers
6251 - How to obtain unwind info for LLVM compiled methods ?
6252 -> this is now solved by converting the unwind info generated by LLVM
6254 - LLVM uses the c++ exception handling framework, while we use our home grown
6255 code, and couldn't use the c++ one:
6256 - its not supported under VC++, other exotic platforms.
6257 - it might be impossible to support filter clauses with it.
6261 The trampolines need a predictable call sequence, since they need to disasm
6262 the calling code to obtain register numbers / offsets.
6264 LLVM currently generates this code in non-JIT mode:
6265 mov -0x98(%rax),%eax
6267 Here, the vtable pointer is lost.
6268 -> solution: use one vtable trampoline per class.
6270 - passing/receiving the IMT pointer/RGCTX.
6271 -> solution: pass them as normal arguments ?
6275 LLVM does not allow the specification of argument registers etc. This means
6276 that all calls are made according to the platform ABI.
6278 - passing/receiving vtypes.
6280 Vtypes passed/received in registers are handled by the front end by using
6281 a signature with scalar arguments, and loading the parts of the vtype into those
6284 Vtypes passed on the stack are handled using the 'byval' attribute.
6288 Supported though alloca, we need to emit the load/store code.
6292 The mono JIT uses pointer sized iregs/double fregs, while LLVM uses precisely
6293 typed registers, so we have to keep track of the precise LLVM type of each vreg.
6294 This is made easier because the IR is already in SSA form.
6295 An additional problem is that our IR is not consistent with types, i.e. i32/ia64
6296 types are frequently used incorrectly.
6301 Emit LLVM bytecode into a .bc file, compile it using llc into a .s file, then link
6302 it with the file containing the methods emitted by the JIT and the AOT data
6306 /* FIXME: Normalize some aspects of the mono IR to allow easier translation, like:
6307 * - each bblock should end with a branch
6308 * - setting the return value, making cfg->ret non-volatile
6309 * - avoid some transformations in the JIT which make it harder for us to generate
6311 * - use pointer types to help optimizations.