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/metadata/environment.h>
13 #include <mono/metadata/object-internals.h>
14 #include <mono/utils/mono-tls.h>
15 #include <mono/utils/mono-dl.h>
16 #include <mono/utils/mono-time.h>
17 #include <mono/utils/freebsd-dwarf.h>
19 #ifndef __STDC_LIMIT_MACROS
20 #define __STDC_LIMIT_MACROS
22 #ifndef __STDC_CONSTANT_MACROS
23 #define __STDC_CONSTANT_MACROS
26 #include "llvm-c/Core.h"
27 #include "llvm-c/ExecutionEngine.h"
28 #include "llvm-c/BitWriter.h"
29 #include "llvm-c/Analysis.h"
31 #include "mini-llvm-cpp.h"
32 #include "aot-compiler.h"
33 #include "mini-llvm.h"
38 extern void *memset(void *, int, size_t);
39 void bzero (void *to, size_t count) { memset (to, 0, count); }
43 #if LLVM_API_VERSION < 4
44 #error "The version of the mono llvm repository is too old."
48 * Information associated by mono with LLVM modules.
51 LLVMModuleRef lmodule;
52 LLVMValueRef throw_icall, rethrow, match_exc, throw_corlib_exception, resume_eh;
53 GHashTable *llvm_types;
55 const char *got_symbol;
56 const char *get_method_symbol;
57 const char *get_unbox_tramp_symbol;
58 GHashTable *plt_entries;
59 GHashTable *plt_entries_ji;
60 GHashTable *method_to_lmethod;
61 GHashTable *direct_callables;
66 GPtrArray *subprogram_mds;
68 LLVMExecutionEngineRef ee;
69 gboolean external_symbols;
74 MonoAssembly *assembly;
76 MonoAotFileInfo aot_info;
77 const char *jit_got_symbol;
78 const char *eh_frame_symbol;
79 LLVMValueRef get_method, get_unbox_tramp;
80 LLVMValueRef init_method, init_method_gshared_rgctx, init_method_gshared_this;
81 LLVMValueRef code_start, code_end;
82 LLVMValueRef inited_var;
83 int max_inited_idx, max_method_idx;
84 gboolean has_jitted_code;
87 GHashTable *idx_to_lmethod;
88 GHashTable *idx_to_unbox_tramp;
89 /* Maps a MonoMethod to LLVM instructions representing it */
90 GHashTable *method_to_callers;
91 LLVMContextRef context;
92 LLVMValueRef sentinel_exception;
96 * Information associated by the backend with mono basic blocks.
99 LLVMBasicBlockRef bblock, end_bblock;
100 LLVMValueRef finally_ind;
101 gboolean added, invoke_target;
103 * If this bblock is the start of a finally clause, this is a list of bblocks it
104 * needs to branch to in ENDFINALLY.
106 GSList *call_handler_return_bbs;
108 * If this bblock is the start of a finally clause, this is the bblock that
109 * CALL_HANDLER needs to branch to.
111 LLVMBasicBlockRef call_handler_target_bb;
112 /* The list of switch statements generated by ENDFINALLY instructions */
113 GSList *endfinally_switch_ins_list;
118 * Structure containing emit state
121 MonoMemPool *mempool;
123 /* Maps method names to the corresponding LLVMValueRef */
124 GHashTable *emitted_method_decls;
127 LLVMValueRef lmethod;
128 MonoLLVMModule *module;
129 LLVMModuleRef lmodule;
131 int sindex, default_index, ex_index;
132 LLVMBuilderRef builder;
133 LLVMValueRef *values, *addresses;
134 MonoType **vreg_cli_types;
136 MonoMethodSignature *sig;
138 GHashTable *region_to_handler;
139 GHashTable *clause_to_handler;
140 LLVMBuilderRef alloca_builder;
141 LLVMValueRef last_alloca;
142 LLVMValueRef rgctx_arg;
143 LLVMValueRef this_arg;
144 LLVMTypeRef *vreg_types;
145 LLVMBasicBlockRef init_bb, inited_bb;
147 gboolean *unreachable;
149 gboolean has_got_access;
150 int this_arg_pindex, rgctx_arg_pindex;
151 LLVMValueRef imt_rgctx_loc;
152 GHashTable *llvm_types;
154 MonoDebugMethodInfo *minfo;
156 /* For every clause, the clauses it is nested in */
159 GHashTable *exc_meta;
160 GHashTable *method_to_callers;
166 MonoBasicBlock *in_bb;
171 * Instruction metadata
172 * This is the same as ins_info, but LREG != IREG.
180 #define MINI_OP(a,b,dest,src1,src2) dest, src1, src2, ' ',
181 #define MINI_OP3(a,b,dest,src1,src2,src3) dest, src1, src2, src3,
188 /* keep in sync with the enum in mini.h */
191 #include "mini-ops.h"
196 #if SIZEOF_VOID_P == 4
197 #define GET_LONG_IMM(ins) (((guint64)(ins)->inst_ms_word << 32) | (guint64)(guint32)(ins)->inst_ls_word)
199 #define GET_LONG_IMM(ins) ((ins)->inst_imm)
202 #define LLVM_INS_INFO(opcode) (&llvm_ins_info [((opcode) - OP_START - 1) * 4])
205 #define TRACE_FAILURE(msg) do { printf ("%s\n", msg); } while (0)
207 #define TRACE_FAILURE(msg)
211 #define IS_TARGET_X86 1
213 #define IS_TARGET_X86 0
217 #define IS_TARGET_AMD64 1
219 #define IS_TARGET_AMD64 0
222 #define LLVM_FAILURE(ctx, reason) do { \
223 TRACE_FAILURE (reason); \
224 (ctx)->cfg->exception_message = g_strdup (reason); \
225 (ctx)->cfg->disable_llvm = TRUE; \
229 #define CHECK_FAILURE(ctx) do { \
230 if ((ctx)->cfg->disable_llvm) \
234 static LLVMIntPredicate cond_to_llvm_cond [] = {
247 static LLVMRealPredicate fpcond_to_llvm_cond [] = {
260 static MonoNativeTlsKey current_cfg_tls_id;
262 static MonoLLVMModule aot_module;
263 static int memset_param_count, memcpy_param_count;
264 static const char *memset_func_name;
265 static const char *memcpy_func_name;
267 static void init_jit_module (MonoDomain *domain);
269 static void emit_dbg_loc (EmitContext *ctx, LLVMBuilderRef builder, const unsigned char *cil_code);
270 static LLVMValueRef emit_dbg_subprogram (EmitContext *ctx, MonoCompile *cfg, LLVMValueRef method, const char *name);
271 static void emit_dbg_info (MonoLLVMModule *module, const char *filename, const char *cu_name);
276 * The LLVM type with width == sizeof (gpointer)
281 return sizeof (gpointer) == 8 ? LLVMInt64Type () : LLVMInt32Type ();
287 return sizeof (gpointer) == 8 ? LLVMPointerType (LLVMInt64Type (), 0) : LLVMPointerType (LLVMInt32Type (), 0);
293 return sizeof (gpointer) == 8 ? LLVMPointerType (LLVMInt64Type (), 0) : LLVMPointerType (LLVMInt32Type (), 0);
299 * Return the size of the LLVM representation of the vtype T.
302 get_vtype_size (MonoType *t)
306 size = mono_class_value_size (mono_class_from_mono_type (t), NULL);
308 /* LLVMArgAsIArgs depends on this since it stores whole words */
309 while (size < 2 * sizeof (gpointer) && mono_is_power_of_two (size) == -1)
316 * simd_class_to_llvm_type:
318 * Return the LLVM type corresponding to the Mono.SIMD class KLASS
321 simd_class_to_llvm_type (EmitContext *ctx, MonoClass *klass)
323 if (!strcmp (klass->name, "Vector2d")) {
324 return LLVMVectorType (LLVMDoubleType (), 2);
325 } else if (!strcmp (klass->name, "Vector2l")) {
326 return LLVMVectorType (LLVMInt64Type (), 2);
327 } else if (!strcmp (klass->name, "Vector2ul")) {
328 return LLVMVectorType (LLVMInt64Type (), 2);
329 } else if (!strcmp (klass->name, "Vector4i")) {
330 return LLVMVectorType (LLVMInt32Type (), 4);
331 } else if (!strcmp (klass->name, "Vector4ui")) {
332 return LLVMVectorType (LLVMInt32Type (), 4);
333 } else if (!strcmp (klass->name, "Vector4f")) {
334 return LLVMVectorType (LLVMFloatType (), 4);
335 } else if (!strcmp (klass->name, "Vector8s")) {
336 return LLVMVectorType (LLVMInt16Type (), 8);
337 } else if (!strcmp (klass->name, "Vector8us")) {
338 return LLVMVectorType (LLVMInt16Type (), 8);
339 } else if (!strcmp (klass->name, "Vector16sb")) {
340 return LLVMVectorType (LLVMInt8Type (), 16);
341 } else if (!strcmp (klass->name, "Vector16b")) {
342 return LLVMVectorType (LLVMInt8Type (), 16);
344 printf ("%s\n", klass->name);
350 /* Return the 128 bit SIMD type corresponding to the mono type TYPE */
351 static inline G_GNUC_UNUSED LLVMTypeRef
352 type_to_simd_type (int type)
356 return LLVMVectorType (LLVMInt8Type (), 16);
358 return LLVMVectorType (LLVMInt16Type (), 8);
360 return LLVMVectorType (LLVMInt32Type (), 4);
362 return LLVMVectorType (LLVMInt64Type (), 2);
364 return LLVMVectorType (LLVMDoubleType (), 2);
366 return LLVMVectorType (LLVMFloatType (), 4);
368 g_assert_not_reached ();
374 create_llvm_type_for_type (MonoLLVMModule *module, MonoClass *klass)
376 int i, size, nfields, esize;
377 LLVMTypeRef *eltypes;
382 t = &klass->byval_arg;
384 if (mini_type_is_hfa (t, &nfields, &esize)) {
386 * This is needed on arm64 where HFAs are returned in
390 eltypes = g_new (LLVMTypeRef, size);
391 for (i = 0; i < size; ++i)
392 eltypes [i] = esize == 4 ? LLVMFloatType () : LLVMDoubleType ();
394 size = get_vtype_size (t);
396 eltypes = g_new (LLVMTypeRef, size);
397 for (i = 0; i < size; ++i)
398 eltypes [i] = LLVMInt8Type ();
401 name = mono_type_full_name (&klass->byval_arg);
402 ltype = LLVMStructCreateNamed (module->context, name);
403 LLVMStructSetBody (ltype, eltypes, size, FALSE);
413 * Return the LLVM type corresponding to T.
416 type_to_llvm_type (EmitContext *ctx, MonoType *t)
418 t = mini_get_underlying_type (t);
422 return LLVMVoidType ();
424 return LLVMInt8Type ();
426 return LLVMInt16Type ();
428 return LLVMInt32Type ();
430 return LLVMInt8Type ();
432 return LLVMInt16Type ();
434 return LLVMInt32Type ();
435 case MONO_TYPE_BOOLEAN:
436 return LLVMInt8Type ();
439 return LLVMInt64Type ();
441 return LLVMInt16Type ();
443 return LLVMFloatType ();
445 return LLVMDoubleType ();
448 return IntPtrType ();
449 case MONO_TYPE_OBJECT:
450 case MONO_TYPE_CLASS:
451 case MONO_TYPE_ARRAY:
452 case MONO_TYPE_SZARRAY:
453 case MONO_TYPE_STRING:
455 return ObjRefType ();
458 /* Because of generic sharing */
459 return ObjRefType ();
460 case MONO_TYPE_GENERICINST:
461 if (!mono_type_generic_inst_is_valuetype (t))
462 return ObjRefType ();
464 case MONO_TYPE_VALUETYPE:
465 case MONO_TYPE_TYPEDBYREF: {
469 klass = mono_class_from_mono_type (t);
471 if (MONO_CLASS_IS_SIMD (ctx->cfg, klass))
472 return simd_class_to_llvm_type (ctx, klass);
475 return type_to_llvm_type (ctx, mono_class_enum_basetype (klass));
477 ltype = (LLVMTypeRef)g_hash_table_lookup (ctx->module->llvm_types, klass);
479 ltype = create_llvm_type_for_type (ctx->module, klass);
480 g_hash_table_insert (ctx->module->llvm_types, klass, ltype);
486 printf ("X: %d\n", t->type);
487 ctx->cfg->exception_message = g_strdup_printf ("type %s", mono_type_full_name (t));
488 ctx->cfg->disable_llvm = TRUE;
496 * Return whenever T is an unsigned int type.
499 type_is_unsigned (EmitContext *ctx, MonoType *t)
516 * type_to_llvm_arg_type:
518 * Same as type_to_llvm_type, but treat i8/i16 as i32.
521 type_to_llvm_arg_type (EmitContext *ctx, MonoType *t)
523 LLVMTypeRef ptype = type_to_llvm_type (ctx, t);
526 * This works on all abis except arm64/ios which passes multiple
527 * arguments in one stack slot.
530 if (ptype == LLVMInt8Type () || ptype == LLVMInt16Type ()) {
532 * LLVM generates code which only sets the lower bits, while JITted
533 * code expects all the bits to be set.
535 ptype = LLVMInt32Type ();
543 * llvm_type_to_stack_type:
545 * Return the LLVM type which needs to be used when a value of type TYPE is pushed
548 static G_GNUC_UNUSED LLVMTypeRef
549 llvm_type_to_stack_type (MonoCompile *cfg, LLVMTypeRef type)
553 if (type == LLVMInt8Type ())
554 return LLVMInt32Type ();
555 else if (type == LLVMInt16Type ())
556 return LLVMInt32Type ();
557 else if (!cfg->r4fp && type == LLVMFloatType ())
558 return LLVMDoubleType ();
564 * regtype_to_llvm_type:
566 * Return the LLVM type corresponding to the regtype C used in instruction
570 regtype_to_llvm_type (char c)
574 return LLVMInt32Type ();
576 return LLVMInt64Type ();
578 return LLVMDoubleType ();
587 * Return the LLVM type corresponding to the unary/binary opcode OPCODE.
590 op_to_llvm_type (int opcode)
595 return LLVMInt8Type ();
598 return LLVMInt8Type ();
601 return LLVMInt16Type ();
604 return LLVMInt16Type ();
607 return LLVMInt32Type ();
610 return LLVMInt32Type ();
612 return LLVMInt64Type ();
614 return LLVMFloatType ();
616 return LLVMDoubleType ();
618 return LLVMInt64Type ();
620 return LLVMInt32Type ();
622 return LLVMInt64Type ();
627 return LLVMInt8Type ();
632 return LLVMInt16Type ();
635 return sizeof (gpointer) == 8 ? LLVMInt64Type () : LLVMInt32Type ();
642 return LLVMInt32Type ();
649 return LLVMInt64Type ();
651 printf ("%s\n", mono_inst_name (opcode));
652 g_assert_not_reached ();
657 #define CLAUSE_START(clause) ((clause)->try_offset)
658 #define CLAUSE_END(clause) (((clause))->try_offset + ((clause))->try_len)
661 * load_store_to_llvm_type:
663 * Return the size/sign/zero extension corresponding to the load/store opcode
667 load_store_to_llvm_type (int opcode, int *size, gboolean *sext, gboolean *zext)
673 case OP_LOADI1_MEMBASE:
674 case OP_STOREI1_MEMBASE_REG:
675 case OP_STOREI1_MEMBASE_IMM:
676 case OP_ATOMIC_LOAD_I1:
677 case OP_ATOMIC_STORE_I1:
680 return LLVMInt8Type ();
681 case OP_LOADU1_MEMBASE:
683 case OP_ATOMIC_LOAD_U1:
684 case OP_ATOMIC_STORE_U1:
687 return LLVMInt8Type ();
688 case OP_LOADI2_MEMBASE:
689 case OP_STOREI2_MEMBASE_REG:
690 case OP_STOREI2_MEMBASE_IMM:
691 case OP_ATOMIC_LOAD_I2:
692 case OP_ATOMIC_STORE_I2:
695 return LLVMInt16Type ();
696 case OP_LOADU2_MEMBASE:
698 case OP_ATOMIC_LOAD_U2:
699 case OP_ATOMIC_STORE_U2:
702 return LLVMInt16Type ();
703 case OP_LOADI4_MEMBASE:
704 case OP_LOADU4_MEMBASE:
707 case OP_STOREI4_MEMBASE_REG:
708 case OP_STOREI4_MEMBASE_IMM:
709 case OP_ATOMIC_LOAD_I4:
710 case OP_ATOMIC_STORE_I4:
711 case OP_ATOMIC_LOAD_U4:
712 case OP_ATOMIC_STORE_U4:
714 return LLVMInt32Type ();
715 case OP_LOADI8_MEMBASE:
717 case OP_STOREI8_MEMBASE_REG:
718 case OP_STOREI8_MEMBASE_IMM:
719 case OP_ATOMIC_LOAD_I8:
720 case OP_ATOMIC_STORE_I8:
721 case OP_ATOMIC_LOAD_U8:
722 case OP_ATOMIC_STORE_U8:
724 return LLVMInt64Type ();
725 case OP_LOADR4_MEMBASE:
726 case OP_STORER4_MEMBASE_REG:
727 case OP_ATOMIC_LOAD_R4:
728 case OP_ATOMIC_STORE_R4:
730 return LLVMFloatType ();
731 case OP_LOADR8_MEMBASE:
732 case OP_STORER8_MEMBASE_REG:
733 case OP_ATOMIC_LOAD_R8:
734 case OP_ATOMIC_STORE_R8:
736 return LLVMDoubleType ();
737 case OP_LOAD_MEMBASE:
739 case OP_STORE_MEMBASE_REG:
740 case OP_STORE_MEMBASE_IMM:
741 *size = sizeof (gpointer);
742 return IntPtrType ();
744 g_assert_not_reached ();
752 * Return the LLVM intrinsics corresponding to the overflow opcode OPCODE.
755 ovf_op_to_intrins (int opcode)
759 return "llvm.sadd.with.overflow.i32";
761 return "llvm.uadd.with.overflow.i32";
763 return "llvm.ssub.with.overflow.i32";
765 return "llvm.usub.with.overflow.i32";
767 return "llvm.smul.with.overflow.i32";
769 return "llvm.umul.with.overflow.i32";
771 return "llvm.sadd.with.overflow.i64";
773 return "llvm.uadd.with.overflow.i64";
775 return "llvm.ssub.with.overflow.i64";
777 return "llvm.usub.with.overflow.i64";
779 return "llvm.smul.with.overflow.i64";
781 return "llvm.umul.with.overflow.i64";
783 g_assert_not_reached ();
789 simd_op_to_intrins (int opcode)
792 #if defined(TARGET_X86) || defined(TARGET_AMD64)
794 return "llvm.x86.sse2.min.pd";
796 return "llvm.x86.sse.min.ps";
798 return "llvm.x86.sse41.pminud";
800 return "llvm.x86.sse41.pminuw";
802 return "llvm.x86.sse2.pminu.b";
804 return "llvm.x86.sse2.pmins.w";
806 return "llvm.x86.sse2.max.pd";
808 return "llvm.x86.sse.max.ps";
810 return "llvm.x86.sse3.hadd.pd";
812 return "llvm.x86.sse3.hadd.ps";
814 return "llvm.x86.sse3.hsub.pd";
816 return "llvm.x86.sse3.hsub.ps";
818 return "llvm.x86.sse41.pmaxud";
820 return "llvm.x86.sse41.pmaxuw";
822 return "llvm.x86.sse2.pmaxu.b";
824 return "llvm.x86.sse3.addsub.ps";
826 return "llvm.x86.sse3.addsub.pd";
827 case OP_EXTRACT_MASK:
828 return "llvm.x86.sse2.pmovmskb.128";
831 return "llvm.x86.sse2.psrli.w";
834 return "llvm.x86.sse2.psrli.d";
837 return "llvm.x86.sse2.psrli.q";
840 return "llvm.x86.sse2.pslli.w";
843 return "llvm.x86.sse2.pslli.d";
846 return "llvm.x86.sse2.pslli.q";
849 return "llvm.x86.sse2.psrai.w";
852 return "llvm.x86.sse2.psrai.d";
854 return "llvm.x86.sse2.padds.b";
856 return "llvm.x86.sse2.padds.w";
858 return "llvm.x86.sse2.psubs.b";
860 return "llvm.x86.sse2.psubs.w";
861 case OP_PADDB_SAT_UN:
862 return "llvm.x86.sse2.paddus.b";
863 case OP_PADDW_SAT_UN:
864 return "llvm.x86.sse2.paddus.w";
865 case OP_PSUBB_SAT_UN:
866 return "llvm.x86.sse2.psubus.b";
867 case OP_PSUBW_SAT_UN:
868 return "llvm.x86.sse2.psubus.w";
870 return "llvm.x86.sse2.pavg.b";
872 return "llvm.x86.sse2.pavg.w";
874 return "llvm.x86.sse.sqrt.ps";
876 return "llvm.x86.sse2.sqrt.pd";
878 return "llvm.x86.sse.rsqrt.ps";
880 return "llvm.x86.sse.rcp.ps";
882 return "llvm.x86.sse2.cvtdq2pd";
884 return "llvm.x86.sse2.cvtdq2ps";
886 return "llvm.x86.sse2.cvtpd2dq";
888 return "llvm.x86.sse2.cvtps2dq";
890 return "llvm.x86.sse2.cvtpd2ps";
892 return "llvm.x86.sse2.cvtps2pd";
894 return "llvm.x86.sse2.cvttpd2dq";
896 return "llvm.x86.sse2.cvttps2dq";
898 return "llvm.x86.sse.cmp.ps";
900 return "llvm.x86.sse2.cmp.pd";
902 return "llvm.x86.sse2.packsswb.128";
904 return "llvm.x86.sse2.packssdw.128";
906 return "llvm.x86.sse2.packuswb.128";
908 return "llvm.x86.sse41.packusdw";
910 return "llvm.x86.sse2.pmulh.w";
911 case OP_PMULW_HIGH_UN:
912 return "llvm.x86.sse2.pmulhu.w";
915 g_assert_not_reached ();
921 simd_op_to_llvm_type (int opcode)
923 #if defined(TARGET_X86) || defined(TARGET_AMD64)
927 return type_to_simd_type (MONO_TYPE_R8);
930 return type_to_simd_type (MONO_TYPE_I8);
933 return type_to_simd_type (MONO_TYPE_I4);
938 return type_to_simd_type (MONO_TYPE_I2);
942 return type_to_simd_type (MONO_TYPE_I1);
944 return type_to_simd_type (MONO_TYPE_R4);
947 return type_to_simd_type (MONO_TYPE_I4);
951 return type_to_simd_type (MONO_TYPE_R8);
955 return type_to_simd_type (MONO_TYPE_R4);
956 case OP_EXTRACT_MASK:
957 return type_to_simd_type (MONO_TYPE_I1);
963 return type_to_simd_type (MONO_TYPE_R4);
966 return type_to_simd_type (MONO_TYPE_R8);
968 g_assert_not_reached ();
979 * Return the LLVM basic block corresponding to BB.
981 static LLVMBasicBlockRef
982 get_bb (EmitContext *ctx, MonoBasicBlock *bb)
984 char bb_name_buf [128];
987 if (ctx->bblocks [bb->block_num].bblock == NULL) {
988 if (bb->flags & BB_EXCEPTION_HANDLER) {
989 int clause_index = (mono_get_block_region_notry (ctx->cfg, bb->region) >> 8) - 1;
990 sprintf (bb_name_buf, "EH_CLAUSE%d_BB%d", clause_index, bb->block_num);
991 bb_name = bb_name_buf;
992 } else if (bb->block_num < 256) {
993 if (!ctx->module->bb_names) {
994 ctx->module->bb_names_len = 256;
995 ctx->module->bb_names = g_new0 (char*, ctx->module->bb_names_len);
997 if (!ctx->module->bb_names [bb->block_num]) {
1000 n = g_strdup_printf ("BB%d", bb->block_num);
1001 mono_memory_barrier ();
1002 ctx->module->bb_names [bb->block_num] = n;
1004 bb_name = ctx->module->bb_names [bb->block_num];
1006 sprintf (bb_name_buf, "BB%d", bb->block_num);
1007 bb_name = bb_name_buf;
1010 ctx->bblocks [bb->block_num].bblock = LLVMAppendBasicBlock (ctx->lmethod, bb_name);
1011 ctx->bblocks [bb->block_num].end_bblock = ctx->bblocks [bb->block_num].bblock;
1014 return ctx->bblocks [bb->block_num].bblock;
1020 * Return the last LLVM bblock corresponding to BB.
1021 * This might not be equal to the bb returned by get_bb () since we need to generate
1022 * multiple LLVM bblocks for a mono bblock to handle throwing exceptions.
1024 static LLVMBasicBlockRef
1025 get_end_bb (EmitContext *ctx, MonoBasicBlock *bb)
1028 return ctx->bblocks [bb->block_num].end_bblock;
1031 static LLVMBasicBlockRef
1032 gen_bb (EmitContext *ctx, const char *prefix)
1036 sprintf (bb_name, "%s%d", prefix, ++ ctx->ex_index);
1037 return LLVMAppendBasicBlock (ctx->lmethod, bb_name);
1043 * Return the target of the patch identified by TYPE and TARGET.
1046 resolve_patch (MonoCompile *cfg, MonoJumpInfoType type, gconstpointer target)
1050 memset (&ji, 0, sizeof (ji));
1052 ji.data.target = target;
1054 return mono_resolve_patch_target (cfg->method, cfg->domain, NULL, &ji, FALSE);
1060 * Emit code to convert the LLVM value V to DTYPE.
1063 convert_full (EmitContext *ctx, LLVMValueRef v, LLVMTypeRef dtype, gboolean is_unsigned)
1065 LLVMTypeRef stype = LLVMTypeOf (v);
1067 if (stype != dtype) {
1068 gboolean ext = FALSE;
1071 if (dtype == LLVMInt64Type () && (stype == LLVMInt32Type () || stype == LLVMInt16Type () || stype == LLVMInt8Type ()))
1073 else if (dtype == LLVMInt32Type () && (stype == LLVMInt16Type () || stype == LLVMInt8Type ()))
1075 else if (dtype == LLVMInt16Type () && (stype == LLVMInt8Type ()))
1079 return is_unsigned ? LLVMBuildZExt (ctx->builder, v, dtype, "") : LLVMBuildSExt (ctx->builder, v, dtype, "");
1081 if (dtype == LLVMDoubleType () && stype == LLVMFloatType ())
1082 return LLVMBuildFPExt (ctx->builder, v, dtype, "");
1085 if (stype == LLVMInt64Type () && (dtype == LLVMInt32Type () || dtype == LLVMInt16Type () || dtype == LLVMInt8Type ()))
1086 return LLVMBuildTrunc (ctx->builder, v, dtype, "");
1087 if (stype == LLVMInt32Type () && (dtype == LLVMInt16Type () || dtype == LLVMInt8Type ()))
1088 return LLVMBuildTrunc (ctx->builder, v, dtype, "");
1089 if (stype == LLVMInt16Type () && dtype == LLVMInt8Type ())
1090 return LLVMBuildTrunc (ctx->builder, v, dtype, "");
1091 if (stype == LLVMDoubleType () && dtype == LLVMFloatType ())
1092 return LLVMBuildFPTrunc (ctx->builder, v, dtype, "");
1094 if (LLVMGetTypeKind (stype) == LLVMPointerTypeKind && LLVMGetTypeKind (dtype) == LLVMPointerTypeKind)
1095 return LLVMBuildBitCast (ctx->builder, v, dtype, "");
1096 if (LLVMGetTypeKind (dtype) == LLVMPointerTypeKind)
1097 return LLVMBuildIntToPtr (ctx->builder, v, dtype, "");
1098 if (LLVMGetTypeKind (stype) == LLVMPointerTypeKind)
1099 return LLVMBuildPtrToInt (ctx->builder, v, dtype, "");
1101 if (mono_arch_is_soft_float ()) {
1102 if (stype == LLVMInt32Type () && dtype == LLVMFloatType ())
1103 return LLVMBuildBitCast (ctx->builder, v, dtype, "");
1104 if (stype == LLVMInt32Type () && dtype == LLVMDoubleType ())
1105 return LLVMBuildBitCast (ctx->builder, LLVMBuildZExt (ctx->builder, v, LLVMInt64Type (), ""), dtype, "");
1108 if (LLVMGetTypeKind (stype) == LLVMVectorTypeKind && LLVMGetTypeKind (dtype) == LLVMVectorTypeKind)
1109 return LLVMBuildBitCast (ctx->builder, v, dtype, "");
1112 LLVMDumpValue (LLVMConstNull (dtype));
1113 g_assert_not_reached ();
1121 convert (EmitContext *ctx, LLVMValueRef v, LLVMTypeRef dtype)
1123 return convert_full (ctx, v, dtype, FALSE);
1127 * emit_volatile_load:
1129 * If vreg is volatile, emit a load from its address.
1132 emit_volatile_load (EmitContext *ctx, int vreg)
1136 LLVMValueRef v = LLVMBuildLoad (ctx->builder, ctx->addresses [vreg], "");
1137 t = ctx->vreg_cli_types [vreg];
1138 if (t && !t->byref) {
1140 * Might have to zero extend since llvm doesn't have
1143 if (t->type == MONO_TYPE_U1 || t->type == MONO_TYPE_U2 || t->type == MONO_TYPE_CHAR || t->type == MONO_TYPE_BOOLEAN)
1144 v = LLVMBuildZExt (ctx->builder, v, LLVMInt32Type (), "");
1145 else if (t->type == MONO_TYPE_I1 || t->type == MONO_TYPE_I2)
1146 v = LLVMBuildSExt (ctx->builder, v, LLVMInt32Type (), "");
1147 else if (t->type == MONO_TYPE_U8)
1148 v = LLVMBuildZExt (ctx->builder, v, LLVMInt64Type (), "");
1155 * emit_volatile_store:
1157 * If VREG is volatile, emit a store from its value to its address.
1160 emit_volatile_store (EmitContext *ctx, int vreg)
1162 MonoInst *var = get_vreg_to_inst (ctx->cfg, vreg);
1164 if (var && var->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT)) {
1165 g_assert (ctx->addresses [vreg]);
1166 LLVMBuildStore (ctx->builder, convert (ctx, ctx->values [vreg], type_to_llvm_type (ctx, var->inst_vtype)), ctx->addresses [vreg]);
1171 sig_to_llvm_sig_no_cinfo (EmitContext *ctx, MonoMethodSignature *sig)
1173 LLVMTypeRef ret_type;
1174 LLVMTypeRef *param_types = NULL;
1179 rtype = mini_get_underlying_type (sig->ret);
1180 ret_type = type_to_llvm_type (ctx, rtype);
1181 CHECK_FAILURE (ctx);
1183 param_types = g_new0 (LLVMTypeRef, (sig->param_count * 8) + 3);
1187 param_types [pindex ++] = ThisType ();
1188 for (i = 0; i < sig->param_count; ++i)
1189 param_types [pindex ++] = type_to_llvm_arg_type (ctx, sig->params [i]);
1191 CHECK_FAILURE (ctx);
1193 res = LLVMFunctionType (ret_type, param_types, pindex, FALSE);
1194 g_free (param_types);
1199 g_free (param_types);
1205 * sig_to_llvm_sig_full:
1207 * Return the LLVM signature corresponding to the mono signature SIG using the
1208 * calling convention information in CINFO. Fill out the parameter mapping information in CINFO.
1211 sig_to_llvm_sig_full (EmitContext *ctx, MonoMethodSignature *sig, LLVMCallInfo *cinfo)
1213 LLVMTypeRef ret_type;
1214 LLVMTypeRef *param_types = NULL;
1216 int i, j, pindex, vret_arg_pindex = 0;
1217 gboolean vretaddr = FALSE;
1221 return sig_to_llvm_sig_no_cinfo (ctx, sig);
1223 rtype = mini_get_underlying_type (sig->ret);
1224 ret_type = type_to_llvm_type (ctx, rtype);
1225 CHECK_FAILURE (ctx);
1227 switch (cinfo->ret.storage) {
1228 case LLVMArgVtypeInReg:
1229 /* LLVM models this by returning an aggregate value */
1230 if (cinfo->ret.pair_storage [0] == LLVMArgInIReg && cinfo->ret.pair_storage [1] == LLVMArgNone) {
1231 LLVMTypeRef members [2];
1233 members [0] = IntPtrType ();
1234 ret_type = LLVMStructType (members, 1, FALSE);
1235 } else if (cinfo->ret.pair_storage [0] == LLVMArgNone && cinfo->ret.pair_storage [1] == LLVMArgNone) {
1237 ret_type = LLVMVoidType ();
1238 } else if (cinfo->ret.pair_storage [0] == LLVMArgInIReg && cinfo->ret.pair_storage [1] == LLVMArgInIReg) {
1239 LLVMTypeRef members [2];
1241 members [0] = IntPtrType ();
1242 members [1] = IntPtrType ();
1243 ret_type = LLVMStructType (members, 2, FALSE);
1245 g_assert_not_reached ();
1248 case LLVMArgVtypeByVal:
1249 /* Vtype returned normally by val */
1251 case LLVMArgVtypeAsScalar:
1252 /* LLVM models this by returning an int */
1253 g_assert (cinfo->ret.nslots == 1 || cinfo->ret.nslots == 2);
1254 ret_type = LLVMIntType (cinfo->ret.nslots * sizeof (mgreg_t) * 8);
1256 case LLVMArgFpStruct: {
1257 /* Vtype returned as a fp struct */
1258 LLVMTypeRef members [16];
1260 /* Have to create our own structure since we don't map fp structures to LLVM fp structures yet */
1261 for (i = 0; i < cinfo->ret.nslots; ++i)
1262 members [i] = cinfo->ret.esize == 8 ? LLVMDoubleType () : LLVMFloatType ();
1263 ret_type = LLVMStructType (members, cinfo->ret.nslots, FALSE);
1266 case LLVMArgVtypeByRef:
1267 /* Vtype returned using a hidden argument */
1268 ret_type = LLVMVoidType ();
1270 case LLVMArgVtypeRetAddr:
1271 case LLVMArgScalarRetAddr:
1273 ret_type = LLVMVoidType ();
1279 param_types = g_new0 (LLVMTypeRef, (sig->param_count * 8) + 3);
1281 if (cinfo->ret.storage == LLVMArgVtypeByRef) {
1283 * Has to be the first argument because of the sret argument attribute
1284 * FIXME: This might conflict with passing 'this' as the first argument, but
1285 * this is only used on arm64 which has a dedicated struct return register.
1287 cinfo->vret_arg_pindex = pindex;
1288 param_types [pindex] = type_to_llvm_arg_type (ctx, sig->ret);
1289 CHECK_FAILURE (ctx);
1290 param_types [pindex] = LLVMPointerType (param_types [pindex], 0);
1293 if (!ctx->llvm_only && cinfo->rgctx_arg) {
1294 cinfo->rgctx_arg_pindex = pindex;
1295 param_types [pindex] = ctx->module->ptr_type;
1298 if (cinfo->imt_arg) {
1299 cinfo->imt_arg_pindex = pindex;
1300 param_types [pindex] = ctx->module->ptr_type;
1304 /* Compute the index in the LLVM signature where the vret arg needs to be passed */
1305 vret_arg_pindex = pindex;
1306 if (cinfo->vret_arg_index == 1) {
1307 /* Add the slots consumed by the first argument */
1308 LLVMArgInfo *ainfo = &cinfo->args [0];
1309 switch (ainfo->storage) {
1310 case LLVMArgVtypeInReg:
1311 for (j = 0; j < 2; ++j) {
1312 if (ainfo->pair_storage [j] == LLVMArgInIReg)
1321 cinfo->vret_arg_pindex = vret_arg_pindex;
1324 if (vretaddr && vret_arg_pindex == pindex)
1325 param_types [pindex ++] = IntPtrType ();
1327 cinfo->this_arg_pindex = pindex;
1328 param_types [pindex ++] = ThisType ();
1329 cinfo->args [0].pindex = cinfo->this_arg_pindex;
1331 if (vretaddr && vret_arg_pindex == pindex)
1332 param_types [pindex ++] = IntPtrType ();
1333 for (i = 0; i < sig->param_count; ++i) {
1334 LLVMArgInfo *ainfo = &cinfo->args [i + sig->hasthis];
1336 if (vretaddr && vret_arg_pindex == pindex)
1337 param_types [pindex ++] = IntPtrType ();
1338 ainfo->pindex = pindex;
1340 switch (ainfo->storage) {
1341 case LLVMArgVtypeInReg:
1342 for (j = 0; j < 2; ++j) {
1343 switch (ainfo->pair_storage [j]) {
1345 param_types [pindex ++] = LLVMIntType (sizeof (gpointer) * 8);
1350 g_assert_not_reached ();
1354 case LLVMArgVtypeByVal:
1355 param_types [pindex] = type_to_llvm_arg_type (ctx, ainfo->type);
1356 CHECK_FAILURE (ctx);
1357 param_types [pindex] = LLVMPointerType (param_types [pindex], 0);
1360 case LLVMArgAsIArgs:
1361 param_types [pindex] = LLVMArrayType (IntPtrType (), ainfo->nslots);
1364 case LLVMArgVtypeByRef:
1365 case LLVMArgScalarByRef:
1366 param_types [pindex] = type_to_llvm_arg_type (ctx, ainfo->type);
1367 CHECK_FAILURE (ctx);
1368 param_types [pindex] = LLVMPointerType (param_types [pindex], 0);
1371 case LLVMArgAsFpArgs: {
1374 for (j = 0; j < ainfo->nslots; ++j)
1375 param_types [pindex + j] = ainfo->esize == 8 ? LLVMDoubleType () : LLVMFloatType ();
1376 pindex += ainfo->nslots;
1379 case LLVMArgVtypeAsScalar:
1380 g_assert_not_reached ();
1383 param_types [pindex ++] = type_to_llvm_arg_type (ctx, ainfo->type);
1387 if (vretaddr && vret_arg_pindex == pindex)
1388 param_types [pindex ++] = IntPtrType ();
1389 if (ctx->llvm_only && cinfo->rgctx_arg) {
1390 /* Pass the rgctx as the last argument */
1391 cinfo->rgctx_arg_pindex = pindex;
1392 param_types [pindex] = ctx->module->ptr_type;
1396 CHECK_FAILURE (ctx);
1398 res = LLVMFunctionType (ret_type, param_types, pindex, FALSE);
1399 g_free (param_types);
1404 g_free (param_types);
1410 sig_to_llvm_sig (EmitContext *ctx, MonoMethodSignature *sig)
1412 return sig_to_llvm_sig_full (ctx, sig, NULL);
1416 * LLVMFunctionType1:
1418 * Create an LLVM function type from the arguments.
1420 static G_GNUC_UNUSED LLVMTypeRef
1421 LLVMFunctionType0 (LLVMTypeRef ReturnType,
1424 return LLVMFunctionType (ReturnType, NULL, 0, IsVarArg);
1428 * LLVMFunctionType1:
1430 * Create an LLVM function type from the arguments.
1432 static G_GNUC_UNUSED LLVMTypeRef
1433 LLVMFunctionType1 (LLVMTypeRef ReturnType,
1434 LLVMTypeRef ParamType1,
1437 LLVMTypeRef param_types [1];
1439 param_types [0] = ParamType1;
1441 return LLVMFunctionType (ReturnType, param_types, 1, IsVarArg);
1445 * LLVMFunctionType2:
1447 * Create an LLVM function type from the arguments.
1449 static G_GNUC_UNUSED LLVMTypeRef
1450 LLVMFunctionType2 (LLVMTypeRef ReturnType,
1451 LLVMTypeRef ParamType1,
1452 LLVMTypeRef ParamType2,
1455 LLVMTypeRef param_types [2];
1457 param_types [0] = ParamType1;
1458 param_types [1] = ParamType2;
1460 return LLVMFunctionType (ReturnType, param_types, 2, IsVarArg);
1464 * LLVMFunctionType3:
1466 * Create an LLVM function type from the arguments.
1468 static G_GNUC_UNUSED LLVMTypeRef
1469 LLVMFunctionType3 (LLVMTypeRef ReturnType,
1470 LLVMTypeRef ParamType1,
1471 LLVMTypeRef ParamType2,
1472 LLVMTypeRef ParamType3,
1475 LLVMTypeRef param_types [3];
1477 param_types [0] = ParamType1;
1478 param_types [1] = ParamType2;
1479 param_types [2] = ParamType3;
1481 return LLVMFunctionType (ReturnType, param_types, 3, IsVarArg);
1487 * Create an LLVM builder and remember it so it can be freed later.
1489 static LLVMBuilderRef
1490 create_builder (EmitContext *ctx)
1492 LLVMBuilderRef builder = LLVMCreateBuilder ();
1494 ctx->builders = g_slist_prepend_mempool (ctx->cfg->mempool, ctx->builders, builder);
1500 get_aotconst_name (MonoJumpInfoType type, gconstpointer data, int got_offset)
1505 case MONO_PATCH_INFO_INTERNAL_METHOD:
1506 name = g_strdup_printf ("jit_icall_%s", data);
1509 name = g_strdup_printf ("%s_%d", mono_ji_type_to_string (type), got_offset);
1517 get_aotconst (EmitContext *ctx, MonoJumpInfoType type, gconstpointer data)
1521 LLVMValueRef indexes [2];
1523 LLVMValueRef got_entry_addr, load;
1524 LLVMBuilderRef builder = ctx->builder;
1529 ji = g_new0 (MonoJumpInfo, 1);
1531 ji->data.target = data;
1533 ji = mono_aot_patch_info_dup (ji);
1535 ji->next = cfg->patch_info;
1536 cfg->patch_info = ji;
1538 got_offset = mono_aot_get_got_offset (cfg->patch_info);
1539 ctx->module->max_got_offset = MAX (ctx->module->max_got_offset, got_offset);
1541 * If the got slot is shared, it means its initialized when the aot image is loaded, so we don't need to
1542 * explicitly initialize it.
1544 if (!mono_aot_is_shared_got_offset (got_offset)) {
1545 //mono_print_ji (ji);
1547 ctx->has_got_access = TRUE;
1550 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
1551 indexes [1] = LLVMConstInt (LLVMInt32Type (), (gssize)got_offset, FALSE);
1552 got_entry_addr = LLVMBuildGEP (builder, ctx->module->got_var, indexes, 2, "");
1554 name = get_aotconst_name (type, data, got_offset);
1555 load = LLVMBuildLoad (builder, got_entry_addr, name ? name : "");
1557 //set_invariant_load_flag (load);
1563 get_callee (EmitContext *ctx, LLVMTypeRef llvm_sig, MonoJumpInfoType type, gconstpointer data)
1565 LLVMValueRef callee;
1567 if (ctx->llvm_only) {
1570 callee_name = mono_aot_get_direct_call_symbol (type, data);
1572 /* Directly callable */
1574 callee = (LLVMValueRef)g_hash_table_lookup (ctx->module->direct_callables, callee_name);
1576 callee = LLVMAddFunction (ctx->lmodule, callee_name, llvm_sig);
1578 LLVMSetVisibility (callee, LLVMHiddenVisibility);
1580 g_hash_table_insert (ctx->module->direct_callables, (char*)callee_name, callee);
1582 g_free (callee_name);
1588 * Calls are made through the GOT.
1590 load = get_aotconst (ctx, type, data);
1592 return convert (ctx, load, LLVMPointerType (llvm_sig, 0));
1594 MonoJumpInfo *ji = NULL;
1596 callee_name = mono_aot_get_plt_symbol (type, data);
1600 if (ctx->cfg->compile_aot)
1601 /* Add a patch so referenced wrappers can be compiled in full aot mode */
1602 mono_add_patch_info (ctx->cfg, 0, type, data);
1605 callee = (LLVMValueRef)g_hash_table_lookup (ctx->module->plt_entries, callee_name);
1607 callee = LLVMAddFunction (ctx->lmodule, callee_name, llvm_sig);
1609 LLVMSetVisibility (callee, LLVMHiddenVisibility);
1611 g_hash_table_insert (ctx->module->plt_entries, (char*)callee_name, callee);
1614 if (ctx->cfg->compile_aot) {
1615 ji = g_new0 (MonoJumpInfo, 1);
1617 ji->data.target = data;
1619 g_hash_table_insert (ctx->module->plt_entries_ji, ji, callee);
1627 get_handler_clause (MonoCompile *cfg, MonoBasicBlock *bb)
1629 MonoMethodHeader *header = cfg->header;
1630 MonoExceptionClause *clause;
1634 if (bb->region != -1 && MONO_BBLOCK_IS_IN_REGION (bb, MONO_REGION_TRY))
1635 return (bb->region >> 8) - 1;
1638 for (i = 0; i < header->num_clauses; ++i) {
1639 clause = &header->clauses [i];
1641 if (MONO_OFFSET_IN_CLAUSE (clause, bb->real_offset) && clause->flags == MONO_EXCEPTION_CLAUSE_NONE)
1648 static MonoExceptionClause *
1649 get_most_deep_clause (MonoCompile *cfg, EmitContext *ctx, MonoBasicBlock *bb)
1651 // Since they're sorted by nesting we just need
1652 // the first one that the bb is a member of
1653 MonoExceptionClause *last = NULL;
1655 for (int i = 0; i < cfg->header->num_clauses; i++) {
1656 MonoExceptionClause *curr = &cfg->header->clauses [i];
1658 if (MONO_OFFSET_IN_CLAUSE (curr, bb->real_offset))
1661 if (MONO_OFFSET_IN_CLAUSE (curr, bb->real_offset)) {
1662 if (last && CLAUSE_END(last) > CLAUSE_END(curr))
1676 set_metadata_flag (LLVMValueRef v, const char *flag_name)
1678 LLVMValueRef md_arg;
1681 md_kind = LLVMGetMDKindID (flag_name, strlen (flag_name));
1682 md_arg = LLVMMDString ("mono", 4);
1683 LLVMSetMetadata (v, md_kind, LLVMMDNode (&md_arg, 1));
1687 set_invariant_load_flag (LLVMValueRef v)
1689 LLVMValueRef md_arg;
1691 const char *flag_name;
1693 // FIXME: Cache this
1694 flag_name = "invariant.load";
1695 md_kind = LLVMGetMDKindID (flag_name, strlen (flag_name));
1696 md_arg = LLVMMDString ("<index>", strlen ("<index>"));
1697 LLVMSetMetadata (v, md_kind, LLVMMDNode (&md_arg, 1));
1703 * Emit an LLVM call or invoke instruction depending on whenever the call is inside
1707 emit_call (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, LLVMValueRef callee, LLVMValueRef *args, int pindex)
1709 MonoCompile *cfg = ctx->cfg;
1710 LLVMValueRef lcall = NULL;
1711 LLVMBuilderRef builder = *builder_ref;
1712 MonoExceptionClause *clause;
1714 if (ctx->llvm_only) {
1715 clause = get_most_deep_clause (cfg, ctx, bb);
1718 g_assert (clause->flags == MONO_EXCEPTION_CLAUSE_NONE || clause->flags == MONO_EXCEPTION_CLAUSE_FINALLY);
1721 * Have to use an invoke instead of a call, branching to the
1722 * handler bblock of the clause containing this bblock.
1724 intptr_t key = CLAUSE_END(clause);
1726 LLVMBasicBlockRef lpad_bb = (LLVMBasicBlockRef)g_hash_table_lookup (ctx->exc_meta, (gconstpointer)key);
1728 // FIXME: Find the one that has the lowest end bound for the right start address
1729 // FIXME: Finally + nesting
1732 LLVMBasicBlockRef noex_bb = gen_bb (ctx, "CALL_NOEX_BB");
1735 lcall = LLVMBuildInvoke (builder, callee, args, pindex, noex_bb, lpad_bb, "");
1737 builder = ctx->builder = create_builder (ctx);
1738 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
1740 ctx->bblocks [bb->block_num].end_bblock = noex_bb;
1744 int clause_index = get_handler_clause (cfg, bb);
1746 if (clause_index != -1) {
1747 MonoMethodHeader *header = cfg->header;
1748 MonoExceptionClause *ec = &header->clauses [clause_index];
1749 MonoBasicBlock *tblock;
1750 LLVMBasicBlockRef ex_bb, noex_bb;
1753 * Have to use an invoke instead of a call, branching to the
1754 * handler bblock of the clause containing this bblock.
1757 g_assert (ec->flags == MONO_EXCEPTION_CLAUSE_NONE || ec->flags == MONO_EXCEPTION_CLAUSE_FINALLY);
1759 tblock = cfg->cil_offset_to_bb [ec->handler_offset];
1762 ctx->bblocks [tblock->block_num].invoke_target = TRUE;
1764 ex_bb = get_bb (ctx, tblock);
1766 noex_bb = gen_bb (ctx, "NOEX_BB");
1769 lcall = LLVMBuildInvoke (builder, callee, args, pindex, noex_bb, ex_bb, "");
1771 builder = ctx->builder = create_builder (ctx);
1772 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
1774 ctx->bblocks [bb->block_num].end_bblock = noex_bb;
1779 lcall = LLVMBuildCall (builder, callee, args, pindex, "");
1780 ctx->builder = builder;
1784 *builder_ref = ctx->builder;
1790 emit_load_general (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, int size, LLVMValueRef addr, const char *name, gboolean is_faulting, BarrierKind barrier)
1792 const char *intrins_name;
1793 LLVMValueRef args [16], res;
1794 LLVMTypeRef addr_type;
1796 if (is_faulting && bb->region != -1 && !ctx->cfg->llvm_only) {
1797 LLVMAtomicOrdering ordering;
1800 case LLVM_BARRIER_NONE:
1801 ordering = LLVMAtomicOrderingNotAtomic;
1803 case LLVM_BARRIER_ACQ:
1804 ordering = LLVMAtomicOrderingAcquire;
1806 case LLVM_BARRIER_SEQ:
1807 ordering = LLVMAtomicOrderingSequentiallyConsistent;
1810 g_assert_not_reached ();
1815 * We handle loads which can fault by calling a mono specific intrinsic
1816 * using an invoke, so they are handled properly inside try blocks.
1817 * We can't use this outside clauses, since LLVM optimizes intrinsics which
1818 * are marked with IntrReadArgMem.
1822 intrins_name = "llvm.mono.load.i8.p0i8";
1825 intrins_name = "llvm.mono.load.i16.p0i16";
1828 intrins_name = "llvm.mono.load.i32.p0i32";
1831 intrins_name = "llvm.mono.load.i64.p0i64";
1834 g_assert_not_reached ();
1837 addr_type = LLVMTypeOf (addr);
1838 if (addr_type == LLVMPointerType (LLVMDoubleType (), 0) || addr_type == LLVMPointerType (LLVMFloatType (), 0))
1839 addr = LLVMBuildBitCast (*builder_ref, addr, LLVMPointerType (LLVMIntType (size * 8), 0), "");
1842 args [1] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
1843 args [2] = LLVMConstInt (LLVMInt1Type (), TRUE, FALSE);
1844 args [3] = LLVMConstInt (LLVMInt32Type (), ordering, FALSE);
1845 res = emit_call (ctx, bb, builder_ref, LLVMGetNamedFunction (ctx->lmodule, intrins_name), args, 4);
1847 if (addr_type == LLVMPointerType (LLVMDoubleType (), 0))
1848 res = LLVMBuildBitCast (*builder_ref, res, LLVMDoubleType (), "");
1849 else if (addr_type == LLVMPointerType (LLVMFloatType (), 0))
1850 res = LLVMBuildBitCast (*builder_ref, res, LLVMFloatType (), "");
1857 * We emit volatile loads for loads which can fault, because otherwise
1858 * LLVM will generate invalid code when encountering a load from a
1861 res = mono_llvm_build_load (*builder_ref, addr, name, is_faulting, barrier);
1863 /* Mark it with a custom metadata */
1866 set_metadata_flag (res, "mono.faulting.load");
1874 emit_load (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, int size, LLVMValueRef addr, const char *name, gboolean is_faulting)
1876 return emit_load_general (ctx, bb, builder_ref, size, addr, name, is_faulting, LLVM_BARRIER_NONE);
1880 emit_store_general (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, int size, LLVMValueRef value, LLVMValueRef addr, gboolean is_faulting, BarrierKind barrier)
1882 const char *intrins_name;
1883 LLVMValueRef args [16];
1885 if (is_faulting && bb->region != -1 && !ctx->cfg->llvm_only) {
1886 LLVMAtomicOrdering ordering;
1889 case LLVM_BARRIER_NONE:
1890 ordering = LLVMAtomicOrderingNotAtomic;
1892 case LLVM_BARRIER_REL:
1893 ordering = LLVMAtomicOrderingRelease;
1895 case LLVM_BARRIER_SEQ:
1896 ordering = LLVMAtomicOrderingSequentiallyConsistent;
1899 g_assert_not_reached ();
1905 intrins_name = "llvm.mono.store.i8.p0i8";
1908 intrins_name = "llvm.mono.store.i16.p0i16";
1911 intrins_name = "llvm.mono.store.i32.p0i32";
1914 intrins_name = "llvm.mono.store.i64.p0i64";
1917 g_assert_not_reached ();
1920 if (LLVMTypeOf (value) == LLVMDoubleType () || LLVMTypeOf (value) == LLVMFloatType ()) {
1921 value = LLVMBuildBitCast (*builder_ref, value, LLVMIntType (size * 8), "");
1922 addr = LLVMBuildBitCast (*builder_ref, addr, LLVMPointerType (LLVMIntType (size * 8), 0), "");
1927 args [2] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
1928 args [3] = LLVMConstInt (LLVMInt1Type (), TRUE, FALSE);
1929 args [4] = LLVMConstInt (LLVMInt32Type (), ordering, FALSE);
1930 emit_call (ctx, bb, builder_ref, LLVMGetNamedFunction (ctx->lmodule, intrins_name), args, 5);
1932 mono_llvm_build_store (*builder_ref, value, addr, is_faulting, barrier);
1937 emit_store (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, int size, LLVMValueRef value, LLVMValueRef addr, gboolean is_faulting)
1939 emit_store_general (ctx, bb, builder_ref, size, value, addr, is_faulting, LLVM_BARRIER_NONE);
1943 * emit_cond_system_exception:
1945 * Emit code to throw the exception EXC_TYPE if the condition CMP is false.
1946 * Might set the ctx exception.
1949 emit_cond_system_exception (EmitContext *ctx, MonoBasicBlock *bb, const char *exc_type, LLVMValueRef cmp)
1951 LLVMBasicBlockRef ex_bb, ex2_bb = NULL, noex_bb;
1952 LLVMBuilderRef builder;
1953 MonoClass *exc_class;
1954 LLVMValueRef args [2];
1955 LLVMValueRef callee;
1957 ex_bb = gen_bb (ctx, "EX_BB");
1959 ex2_bb = gen_bb (ctx, "EX2_BB");
1960 noex_bb = gen_bb (ctx, "NOEX_BB");
1962 LLVMBuildCondBr (ctx->builder, cmp, ex_bb, noex_bb);
1964 exc_class = mono_class_from_name (mono_get_corlib (), "System", exc_type);
1965 g_assert (exc_class);
1967 /* Emit exception throwing code */
1968 ctx->builder = builder = create_builder (ctx);
1969 LLVMPositionBuilderAtEnd (builder, ex_bb);
1971 if (ctx->cfg->llvm_only) {
1972 static LLVMTypeRef sig;
1975 sig = LLVMFunctionType1 (LLVMVoidType (), LLVMInt32Type (), FALSE);
1976 callee = get_callee (ctx, sig, MONO_PATCH_INFO_INTERNAL_METHOD, "mono_llvm_throw_corlib_exception");
1978 LLVMBuildBr (builder, ex2_bb);
1980 ctx->builder = builder = create_builder (ctx);
1981 LLVMPositionBuilderAtEnd (ctx->builder, ex2_bb);
1983 args [0] = LLVMConstInt (LLVMInt32Type (), exc_class->type_token - MONO_TOKEN_TYPE_DEF, FALSE);
1984 emit_call (ctx, bb, &builder, callee, args, 1);
1985 LLVMBuildUnreachable (builder);
1987 ctx->builder = builder = create_builder (ctx);
1988 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
1990 ctx->bblocks [bb->block_num].end_bblock = noex_bb;
1996 callee = ctx->module->throw_corlib_exception;
1999 const char *icall_name;
2001 sig = LLVMFunctionType2 (LLVMVoidType (), LLVMInt32Type (), LLVMPointerType (LLVMInt8Type (), 0), FALSE);
2002 icall_name = "llvm_throw_corlib_exception_abs_trampoline";
2004 if (ctx->cfg->compile_aot) {
2005 callee = get_callee (ctx, sig, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
2007 callee = LLVMAddFunction (ctx->lmodule, "llvm_throw_corlib_exception_trampoline", sig);
2010 * Differences between the LLVM/non-LLVM throw corlib exception trampoline:
2011 * - On x86, LLVM generated code doesn't push the arguments
2012 * - The trampoline takes the throw address as an arguments, not a pc offset.
2014 LLVMAddGlobalMapping (ctx->module->ee, callee, resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name));
2016 mono_memory_barrier ();
2017 ctx->module->throw_corlib_exception = callee;
2021 if (IS_TARGET_X86 || IS_TARGET_AMD64)
2022 args [0] = LLVMConstInt (LLVMInt32Type (), exc_class->type_token - MONO_TOKEN_TYPE_DEF, FALSE);
2024 args [0] = LLVMConstInt (LLVMInt32Type (), exc_class->type_token, FALSE);
2027 * The LLVM mono branch contains changes so a block address can be passed as an
2028 * argument to a call.
2030 args [1] = LLVMBlockAddress (ctx->lmethod, ex_bb);
2031 emit_call (ctx, bb, &builder, callee, args, 2);
2033 LLVMBuildUnreachable (builder);
2035 ctx->builder = builder = create_builder (ctx);
2036 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
2038 ctx->bblocks [bb->block_num].end_bblock = noex_bb;
2045 * emit_args_to_vtype:
2047 * Emit code to store the vtype in the arguments args to the address ADDRESS.
2050 emit_args_to_vtype (EmitContext *ctx, LLVMBuilderRef builder, MonoType *t, LLVMValueRef address, LLVMArgInfo *ainfo, LLVMValueRef *args)
2052 int j, size, nslots;
2054 size = get_vtype_size (t);
2056 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (t))) {
2057 address = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (LLVMInt8Type (), 0), "");
2060 if (ainfo->storage == LLVMArgAsFpArgs)
2061 nslots = ainfo->nslots;
2065 for (j = 0; j < nslots; ++j) {
2066 LLVMValueRef index [2], addr, daddr;
2067 int part_size = size > sizeof (gpointer) ? sizeof (gpointer) : size;
2068 LLVMTypeRef part_type;
2070 if (ainfo->pair_storage [j] == LLVMArgNone)
2073 switch (ainfo->pair_storage [j]) {
2074 case LLVMArgInIReg: {
2075 part_type = LLVMIntType (part_size * 8);
2076 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (t))) {
2077 index [0] = LLVMConstInt (LLVMInt32Type (), j * sizeof (gpointer), FALSE);
2078 addr = LLVMBuildGEP (builder, address, index, 1, "");
2080 daddr = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (IntPtrType (), 0), "");
2081 index [0] = LLVMConstInt (LLVMInt32Type (), j, FALSE);
2082 addr = LLVMBuildGEP (builder, daddr, index, 1, "");
2084 LLVMBuildStore (builder, convert (ctx, args [j], part_type), LLVMBuildBitCast (ctx->builder, addr, LLVMPointerType (part_type, 0), ""));
2087 case LLVMArgInFPReg: {
2088 LLVMTypeRef arg_type;
2090 if (ainfo->esize == 8)
2091 arg_type = LLVMDoubleType ();
2093 arg_type = LLVMFloatType ();
2095 index [0] = LLVMConstInt (LLVMInt32Type (), j, FALSE);
2096 daddr = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (arg_type, 0), "");
2097 addr = LLVMBuildGEP (builder, daddr, index, 1, "");
2098 LLVMBuildStore (builder, args [j], addr);
2104 g_assert_not_reached ();
2107 size -= sizeof (gpointer);
2112 * emit_vtype_to_args:
2114 * Emit code to load a vtype at address ADDRESS into scalar arguments. Store the arguments
2115 * into ARGS, and the number of arguments into NARGS.
2118 emit_vtype_to_args (EmitContext *ctx, LLVMBuilderRef builder, MonoType *t, LLVMValueRef address, LLVMArgInfo *ainfo, LLVMValueRef *args, guint32 *nargs)
2121 int j, size, nslots;
2122 LLVMTypeRef arg_type;
2124 size = get_vtype_size (t);
2126 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (t)))
2127 address = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (LLVMInt8Type (), 0), "");
2129 if (ainfo->storage == LLVMArgAsFpArgs)
2130 nslots = ainfo->nslots;
2133 for (j = 0; j < nslots; ++j) {
2134 LLVMValueRef index [2], addr, daddr;
2135 int partsize = size > sizeof (gpointer) ? sizeof (gpointer) : size;
2137 if (ainfo->pair_storage [j] == LLVMArgNone)
2140 switch (ainfo->pair_storage [j]) {
2142 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (t))) {
2143 index [0] = LLVMConstInt (LLVMInt32Type (), j * sizeof (gpointer), FALSE);
2144 addr = LLVMBuildGEP (builder, address, index, 1, "");
2146 daddr = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (IntPtrType (), 0), "");
2147 index [0] = LLVMConstInt (LLVMInt32Type (), j, FALSE);
2148 addr = LLVMBuildGEP (builder, daddr, index, 1, "");
2150 args [pindex ++] = convert (ctx, LLVMBuildLoad (builder, LLVMBuildBitCast (ctx->builder, addr, LLVMPointerType (LLVMIntType (partsize * 8), 0), ""), ""), IntPtrType ());
2152 case LLVMArgInFPReg:
2153 if (ainfo->esize == 8)
2154 arg_type = LLVMDoubleType ();
2156 arg_type = LLVMFloatType ();
2157 daddr = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (arg_type, 0), "");
2158 index [0] = LLVMConstInt (LLVMInt32Type (), j, FALSE);
2159 addr = LLVMBuildGEP (builder, daddr, index, 1, "");
2160 args [pindex ++] = LLVMBuildLoad (builder, addr, "");
2165 g_assert_not_reached ();
2167 size -= sizeof (gpointer);
2174 build_alloca_llvm_type_name (EmitContext *ctx, LLVMTypeRef t, int align, const char *name)
2177 * Have to place all alloca's at the end of the entry bb, since otherwise they would
2178 * get executed every time control reaches them.
2180 LLVMPositionBuilder (ctx->alloca_builder, get_bb (ctx, ctx->cfg->bb_entry), ctx->last_alloca);
2182 ctx->last_alloca = mono_llvm_build_alloca (ctx->alloca_builder, t, NULL, align, name);
2183 return ctx->last_alloca;
2187 build_alloca_llvm_type (EmitContext *ctx, LLVMTypeRef t, int align)
2189 return build_alloca_llvm_type_name (ctx, t, align, "");
2193 build_alloca (EmitContext *ctx, MonoType *t)
2195 MonoClass *k = mono_class_from_mono_type (t);
2198 if (MONO_CLASS_IS_SIMD (ctx->cfg, k))
2201 align = mono_class_min_align (k);
2203 /* Sometimes align is not a power of 2 */
2204 while (mono_is_power_of_two (align) == -1)
2207 return build_alloca_llvm_type (ctx, type_to_llvm_type (ctx, t), align);
2211 * Put the global into the 'llvm.used' array to prevent it from being optimized away.
2214 mark_as_used (MonoLLVMModule *module, LLVMValueRef global)
2217 module->used = g_ptr_array_sized_new (16);
2218 g_ptr_array_add (module->used, global);
2222 emit_llvm_used (MonoLLVMModule *module)
2224 LLVMModuleRef lmodule = module->lmodule;
2225 LLVMTypeRef used_type;
2226 LLVMValueRef used, *used_elem;
2232 used_type = LLVMArrayType (LLVMPointerType (LLVMInt8Type (), 0), module->used->len);
2233 used = LLVMAddGlobal (lmodule, used_type, "llvm.used");
2234 used_elem = g_new0 (LLVMValueRef, module->used->len);
2235 for (i = 0; i < module->used->len; ++i)
2236 used_elem [i] = LLVMConstBitCast ((LLVMValueRef)g_ptr_array_index (module->used, i), LLVMPointerType (LLVMInt8Type (), 0));
2237 LLVMSetInitializer (used, LLVMConstArray (LLVMPointerType (LLVMInt8Type (), 0), used_elem, module->used->len));
2238 LLVMSetLinkage (used, LLVMAppendingLinkage);
2239 LLVMSetSection (used, "llvm.metadata");
2245 * Emit a function mapping method indexes to their code
2248 emit_get_method (MonoLLVMModule *module)
2250 LLVMModuleRef lmodule = module->lmodule;
2251 LLVMValueRef func, switch_ins, m;
2252 LLVMBasicBlockRef entry_bb, fail_bb, bb, code_start_bb, code_end_bb;
2253 LLVMBasicBlockRef *bbs;
2255 LLVMBuilderRef builder;
2260 * Emit a switch statement. Emitting a table of function addresses is smaller/faster,
2261 * but generating code seems safer.
2263 rtype = LLVMPointerType (LLVMInt8Type (), 0);
2264 func = LLVMAddFunction (lmodule, module->get_method_symbol, LLVMFunctionType1 (rtype, LLVMInt32Type (), FALSE));
2265 LLVMSetLinkage (func, LLVMExternalLinkage);
2266 LLVMSetVisibility (func, LLVMHiddenVisibility);
2267 LLVMAddFunctionAttr (func, LLVMNoUnwindAttribute);
2268 module->get_method = func;
2270 entry_bb = LLVMAppendBasicBlock (func, "ENTRY");
2273 * Return llvm_code_start/llvm_code_end when called with -1/-2.
2274 * Hopefully, the toolchain doesn't reorder these functions. If it does,
2275 * then we will have to find another solution.
2278 name = g_strdup_printf ("BB_CODE_START");
2279 code_start_bb = LLVMAppendBasicBlock (func, name);
2281 builder = LLVMCreateBuilder ();
2282 LLVMPositionBuilderAtEnd (builder, code_start_bb);
2283 LLVMBuildRet (builder, LLVMBuildBitCast (builder, module->code_start, rtype, ""));
2285 name = g_strdup_printf ("BB_CODE_END");
2286 code_end_bb = LLVMAppendBasicBlock (func, name);
2288 builder = LLVMCreateBuilder ();
2289 LLVMPositionBuilderAtEnd (builder, code_end_bb);
2290 LLVMBuildRet (builder, LLVMBuildBitCast (builder, module->code_end, rtype, ""));
2292 bbs = g_new0 (LLVMBasicBlockRef, module->max_method_idx + 1);
2293 for (i = 0; i < module->max_method_idx + 1; ++i) {
2294 name = g_strdup_printf ("BB_%d", i);
2295 bb = LLVMAppendBasicBlock (func, name);
2299 builder = LLVMCreateBuilder ();
2300 LLVMPositionBuilderAtEnd (builder, bb);
2302 m = (LLVMValueRef)g_hash_table_lookup (module->idx_to_lmethod, GINT_TO_POINTER (i));
2304 LLVMBuildRet (builder, LLVMBuildBitCast (builder, m, rtype, ""));
2306 LLVMBuildRet (builder, LLVMConstNull (rtype));
2309 fail_bb = LLVMAppendBasicBlock (func, "FAIL");
2310 builder = LLVMCreateBuilder ();
2311 LLVMPositionBuilderAtEnd (builder, fail_bb);
2312 LLVMBuildRet (builder, LLVMConstNull (rtype));
2314 builder = LLVMCreateBuilder ();
2315 LLVMPositionBuilderAtEnd (builder, entry_bb);
2317 switch_ins = LLVMBuildSwitch (builder, LLVMGetParam (func, 0), fail_bb, 0);
2318 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), -1, FALSE), code_start_bb);
2319 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), -2, FALSE), code_end_bb);
2320 for (i = 0; i < module->max_method_idx + 1; ++i) {
2321 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), i, FALSE), bbs [i]);
2324 mark_as_used (module, func);
2328 * emit_get_unbox_tramp:
2330 * Emit a function mapping method indexes to their unbox trampoline
2333 emit_get_unbox_tramp (MonoLLVMModule *module)
2335 LLVMModuleRef lmodule = module->lmodule;
2336 LLVMValueRef func, switch_ins, m;
2337 LLVMBasicBlockRef entry_bb, fail_bb, bb;
2338 LLVMBasicBlockRef *bbs;
2340 LLVMBuilderRef builder;
2344 /* Similar to emit_get_method () */
2346 rtype = LLVMPointerType (LLVMInt8Type (), 0);
2347 func = LLVMAddFunction (lmodule, module->get_unbox_tramp_symbol, LLVMFunctionType1 (rtype, LLVMInt32Type (), FALSE));
2348 LLVMSetLinkage (func, LLVMExternalLinkage);
2349 LLVMSetVisibility (func, LLVMHiddenVisibility);
2350 LLVMAddFunctionAttr (func, LLVMNoUnwindAttribute);
2351 module->get_unbox_tramp = func;
2353 entry_bb = LLVMAppendBasicBlock (func, "ENTRY");
2355 bbs = g_new0 (LLVMBasicBlockRef, module->max_method_idx + 1);
2356 for (i = 0; i < module->max_method_idx + 1; ++i) {
2357 m = (LLVMValueRef)g_hash_table_lookup (module->idx_to_unbox_tramp, GINT_TO_POINTER (i));
2361 name = g_strdup_printf ("BB_%d", i);
2362 bb = LLVMAppendBasicBlock (func, name);
2366 builder = LLVMCreateBuilder ();
2367 LLVMPositionBuilderAtEnd (builder, bb);
2369 LLVMBuildRet (builder, LLVMBuildBitCast (builder, m, rtype, ""));
2372 fail_bb = LLVMAppendBasicBlock (func, "FAIL");
2373 builder = LLVMCreateBuilder ();
2374 LLVMPositionBuilderAtEnd (builder, fail_bb);
2375 LLVMBuildRet (builder, LLVMConstNull (rtype));
2377 builder = LLVMCreateBuilder ();
2378 LLVMPositionBuilderAtEnd (builder, entry_bb);
2380 switch_ins = LLVMBuildSwitch (builder, LLVMGetParam (func, 0), fail_bb, 0);
2381 for (i = 0; i < module->max_method_idx + 1; ++i) {
2382 m = (LLVMValueRef)g_hash_table_lookup (module->idx_to_unbox_tramp, GINT_TO_POINTER (i));
2386 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), i, FALSE), bbs [i]);
2389 mark_as_used (module, func);
2392 /* Add a function to mark the beginning of LLVM code */
2394 emit_llvm_code_start (MonoLLVMModule *module)
2396 LLVMModuleRef lmodule = module->lmodule;
2398 LLVMBasicBlockRef entry_bb;
2399 LLVMBuilderRef builder;
2401 func = LLVMAddFunction (lmodule, "llvm_code_start", LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE));
2402 LLVMSetLinkage (func, LLVMInternalLinkage);
2403 LLVMAddFunctionAttr (func, LLVMNoUnwindAttribute);
2404 module->code_start = func;
2405 entry_bb = LLVMAppendBasicBlock (func, "ENTRY");
2406 builder = LLVMCreateBuilder ();
2407 LLVMPositionBuilderAtEnd (builder, entry_bb);
2408 LLVMBuildRetVoid (builder);
2412 emit_init_icall_wrapper (MonoLLVMModule *module, const char *name, const char *icall_name, int subtype)
2414 LLVMModuleRef lmodule = module->lmodule;
2415 LLVMValueRef func, indexes [2], got_entry_addr, args [16], callee;
2416 LLVMBasicBlockRef entry_bb;
2417 LLVMBuilderRef builder;
2424 func = LLVMAddFunction (lmodule, name, LLVMFunctionType1 (LLVMVoidType (), LLVMInt32Type (), FALSE));
2425 sig = LLVMFunctionType2 (LLVMVoidType (), IntPtrType (), LLVMInt32Type (), FALSE);
2428 func = LLVMAddFunction (lmodule, name, LLVMFunctionType2 (LLVMVoidType (), LLVMInt32Type (), IntPtrType (), FALSE));
2429 sig = LLVMFunctionType3 (LLVMVoidType (), IntPtrType (), LLVMInt32Type (), IntPtrType (), FALSE);
2432 func = LLVMAddFunction (lmodule, name, LLVMFunctionType2 (LLVMVoidType (), LLVMInt32Type (), ObjRefType (), FALSE));
2433 sig = LLVMFunctionType3 (LLVMVoidType (), IntPtrType (), LLVMInt32Type (), ObjRefType (), FALSE);
2436 g_assert_not_reached ();
2438 LLVMSetLinkage (func, LLVMInternalLinkage);
2439 LLVMAddFunctionAttr (func, LLVMNoInlineAttribute);
2440 mono_llvm_set_preserveall_cc (func);
2441 entry_bb = LLVMAppendBasicBlock (func, "ENTRY");
2442 builder = LLVMCreateBuilder ();
2443 LLVMPositionBuilderAtEnd (builder, entry_bb);
2446 ji = g_new0 (MonoJumpInfo, 1);
2447 ji->type = MONO_PATCH_INFO_AOT_MODULE;
2448 ji = mono_aot_patch_info_dup (ji);
2449 got_offset = mono_aot_get_got_offset (ji);
2450 module->max_got_offset = MAX (module->max_got_offset, got_offset);
2451 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
2452 indexes [1] = LLVMConstInt (LLVMInt32Type (), got_offset, FALSE);
2453 got_entry_addr = LLVMBuildGEP (builder, module->got_var, indexes, 2, "");
2454 args [0] = LLVMBuildPtrToInt (builder, LLVMBuildLoad (builder, got_entry_addr, ""), IntPtrType (), "");
2455 args [1] = LLVMGetParam (func, 0);
2457 args [2] = LLVMGetParam (func, 1);
2459 ji = g_new0 (MonoJumpInfo, 1);
2460 ji->type = MONO_PATCH_INFO_INTERNAL_METHOD;
2461 ji->data.name = icall_name;
2462 ji = mono_aot_patch_info_dup (ji);
2463 got_offset = mono_aot_get_got_offset (ji);
2464 module->max_got_offset = MAX (module->max_got_offset, got_offset);
2465 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
2466 indexes [1] = LLVMConstInt (LLVMInt32Type (), got_offset, FALSE);
2467 got_entry_addr = LLVMBuildGEP (builder, module->got_var, indexes, 2, "");
2468 callee = LLVMBuildLoad (builder, got_entry_addr, "");
2469 callee = LLVMBuildBitCast (builder, callee, LLVMPointerType (sig, 0), "");
2470 LLVMBuildCall (builder, callee, args, LLVMCountParamTypes (sig), "");
2472 // Set the inited flag
2473 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
2474 indexes [1] = LLVMGetParam (func, 0);
2475 LLVMBuildStore (builder, LLVMConstInt (LLVMInt8Type (), 1, FALSE), LLVMBuildGEP (builder, module->inited_var, indexes, 2, ""));
2477 LLVMBuildRetVoid (builder);
2479 LLVMVerifyFunction(func, 0);
2484 * Emit wrappers around the C icalls used to initialize llvm methods, to
2485 * make the calling code smaller and to enable usage of the llvm
2486 * PreserveAll calling convention.
2489 emit_init_icall_wrappers (MonoLLVMModule *module)
2491 module->init_method = emit_init_icall_wrapper (module, "init_method", "mono_aot_init_llvm_method", 0);
2492 module->init_method_gshared_rgctx = emit_init_icall_wrapper (module, "init_method_gshared_rgctx", "mono_aot_init_gshared_method_rgctx", 1);
2493 module->init_method_gshared_this = emit_init_icall_wrapper (module, "init_method_gshared_this", "mono_aot_init_gshared_method_this", 2);
2497 emit_llvm_code_end (MonoLLVMModule *module)
2499 LLVMModuleRef lmodule = module->lmodule;
2501 LLVMBasicBlockRef entry_bb;
2502 LLVMBuilderRef builder;
2504 func = LLVMAddFunction (lmodule, "llvm_code_end", LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE));
2505 LLVMSetLinkage (func, LLVMInternalLinkage);
2506 LLVMAddFunctionAttr (func, LLVMNoUnwindAttribute);
2507 module->code_end = func;
2508 entry_bb = LLVMAppendBasicBlock (func, "ENTRY");
2509 builder = LLVMCreateBuilder ();
2510 LLVMPositionBuilderAtEnd (builder, entry_bb);
2511 LLVMBuildRetVoid (builder);
2515 emit_div_check (EmitContext *ctx, LLVMBuilderRef builder, MonoBasicBlock *bb, MonoInst *ins, LLVMValueRef lhs, LLVMValueRef rhs)
2517 gboolean need_div_check = ctx->cfg->backend->need_div_check;
2520 /* LLVM doesn't know that these can throw an exception since they are not called through an intrinsic */
2521 need_div_check = TRUE;
2523 if (!need_div_check)
2526 switch (ins->opcode) {
2539 case OP_IDIV_UN_IMM:
2540 case OP_LDIV_UN_IMM:
2541 case OP_IREM_UN_IMM:
2542 case OP_LREM_UN_IMM: {
2544 gboolean is_signed = (ins->opcode == OP_IDIV || ins->opcode == OP_LDIV || ins->opcode == OP_IREM || ins->opcode == OP_LREM ||
2545 ins->opcode == OP_IDIV_IMM || ins->opcode == OP_LDIV_IMM || ins->opcode == OP_IREM_IMM || ins->opcode == OP_LREM_IMM);
2547 cmp = LLVMBuildICmp (builder, LLVMIntEQ, rhs, LLVMConstInt (LLVMTypeOf (rhs), 0, FALSE), "");
2548 emit_cond_system_exception (ctx, bb, "DivideByZeroException", cmp);
2549 CHECK_FAILURE (ctx);
2550 builder = ctx->builder;
2552 /* b == -1 && a == 0x80000000 */
2554 LLVMValueRef c = (LLVMTypeOf (lhs) == LLVMInt32Type ()) ? LLVMConstInt (LLVMTypeOf (lhs), 0x80000000, FALSE) : LLVMConstInt (LLVMTypeOf (lhs), 0x8000000000000000LL, FALSE);
2555 LLVMValueRef cond1 = LLVMBuildICmp (builder, LLVMIntEQ, rhs, LLVMConstInt (LLVMTypeOf (rhs), -1, FALSE), "");
2556 LLVMValueRef cond2 = LLVMBuildICmp (builder, LLVMIntEQ, lhs, c, "");
2558 cmp = LLVMBuildICmp (builder, LLVMIntEQ, LLVMBuildAnd (builder, cond1, cond2, ""), LLVMConstInt (LLVMInt1Type (), 1, FALSE), "");
2559 emit_cond_system_exception (ctx, bb, "OverflowException", cmp);
2560 CHECK_FAILURE (ctx);
2561 builder = ctx->builder;
2576 * Emit code to initialize the GOT slots used by the method.
2579 emit_init_method (EmitContext *ctx)
2581 LLVMValueRef indexes [16], args [16], callee;
2582 LLVMValueRef inited_var, cmp, call;
2583 LLVMBasicBlockRef inited_bb, notinited_bb;
2584 LLVMBuilderRef builder = ctx->builder;
2585 MonoCompile *cfg = ctx->cfg;
2587 ctx->module->max_inited_idx = MAX (ctx->module->max_inited_idx, cfg->method_index);
2588 ctx->module->max_method_idx = MAX (ctx->module->max_method_idx, cfg->method_index);
2590 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
2591 indexes [1] = LLVMConstInt (LLVMInt32Type (), cfg->method_index, FALSE);
2592 inited_var = LLVMBuildLoad (builder, LLVMBuildGEP (builder, ctx->module->inited_var, indexes, 2, ""), "is_inited");
2594 args [0] = inited_var;
2595 args [1] = LLVMConstInt (LLVMInt8Type (), 1, FALSE);
2596 inited_var = LLVMBuildCall (ctx->builder, LLVMGetNamedFunction (ctx->lmodule, "llvm.expect.i8"), args, 2, "");
2598 cmp = LLVMBuildICmp (builder, LLVMIntEQ, inited_var, LLVMConstInt (LLVMTypeOf (inited_var), 0, FALSE), "");
2600 inited_bb = ctx->inited_bb;
2601 notinited_bb = gen_bb (ctx, "NOTINITED_BB");
2603 LLVMBuildCondBr (ctx->builder, cmp, notinited_bb, inited_bb);
2605 builder = ctx->builder = create_builder (ctx);
2606 LLVMPositionBuilderAtEnd (ctx->builder, notinited_bb);
2609 if (ctx->rgctx_arg) {
2610 args [0] = LLVMConstInt (LLVMInt32Type (), cfg->method_index, 0);
2611 args [1] = convert (ctx, ctx->rgctx_arg, IntPtrType ());
2612 callee = ctx->module->init_method_gshared_rgctx;
2613 call = LLVMBuildCall (builder, callee, args, 2, "");
2614 } else if (cfg->gshared) {
2615 args [0] = LLVMConstInt (LLVMInt32Type (), cfg->method_index, 0);
2616 args [1] = convert (ctx, ctx->this_arg, ObjRefType ());
2617 callee = ctx->module->init_method_gshared_this;
2618 call = LLVMBuildCall (builder, callee, args, 2, "");
2620 args [0] = LLVMConstInt (LLVMInt32Type (), cfg->method_index, 0);
2621 callee = ctx->module->init_method;
2622 call = LLVMBuildCall (builder, callee, args, 1, "");
2626 * This enables llvm to keep arguments in their original registers/
2627 * scratch registers, since the call will not clobber them.
2629 mono_llvm_set_call_preserveall_cc (call);
2631 LLVMBuildBr (builder, inited_bb);
2632 ctx->bblocks [cfg->bb_entry->block_num].end_bblock = inited_bb;
2634 builder = ctx->builder = create_builder (ctx);
2635 LLVMPositionBuilderAtEnd (ctx->builder, inited_bb);
2639 emit_unbox_tramp (EmitContext *ctx, const char *method_name, LLVMTypeRef method_type, LLVMValueRef method, int method_index)
2642 * Emit unbox trampoline using a tail call
2644 LLVMValueRef tramp, call, *args;
2645 LLVMBuilderRef builder;
2646 LLVMBasicBlockRef lbb;
2650 tramp_name = g_strdup_printf ("ut_%s", method_name);
2651 tramp = LLVMAddFunction (ctx->module->lmodule, tramp_name, method_type);
2652 LLVMSetLinkage (tramp, LLVMInternalLinkage);
2653 LLVMAddFunctionAttr (tramp, LLVMNoUnwindAttribute);
2654 if (!ctx->llvm_only && ctx->rgctx_arg_pindex != -1)
2655 LLVMAddAttribute (LLVMGetParam (tramp, ctx->rgctx_arg_pindex), LLVMInRegAttribute);
2657 lbb = LLVMAppendBasicBlock (tramp, "");
2658 builder = LLVMCreateBuilder ();
2659 LLVMPositionBuilderAtEnd (builder, lbb);
2661 nargs = LLVMCountParamTypes (method_type);
2662 args = g_new0 (LLVMValueRef, nargs);
2663 for (i = 0; i < nargs; ++i) {
2664 args [i] = LLVMGetParam (tramp, i);
2665 if (i == ctx->this_arg_pindex) {
2666 LLVMTypeRef arg_type = LLVMTypeOf (args [i]);
2668 args [i] = LLVMBuildPtrToInt (builder, args [i], IntPtrType (), "");
2669 args [i] = LLVMBuildAdd (builder, args [i], LLVMConstInt (IntPtrType (), sizeof (MonoObject), FALSE), "");
2670 args [i] = LLVMBuildIntToPtr (builder, args [i], arg_type, "");
2673 call = LLVMBuildCall (builder, method, args, nargs, "");
2674 if (!ctx->llvm_only && ctx->rgctx_arg_pindex != -1)
2675 LLVMAddInstrAttribute (call, 1 + ctx->rgctx_arg_pindex, LLVMInRegAttribute);
2676 mono_llvm_set_must_tail (call);
2677 if (LLVMGetReturnType (method_type) == LLVMVoidType ())
2678 LLVMBuildRetVoid (builder);
2680 LLVMBuildRet (builder, call);
2682 g_hash_table_insert (ctx->module->idx_to_unbox_tramp, GINT_TO_POINTER (method_index), tramp);
2688 * Emit code to load/convert arguments.
2691 emit_entry_bb (EmitContext *ctx, LLVMBuilderRef builder)
2694 MonoCompile *cfg = ctx->cfg;
2695 MonoMethodSignature *sig = ctx->sig;
2696 LLVMCallInfo *linfo = ctx->linfo;
2700 LLVMBuilderRef old_builder = ctx->builder;
2701 ctx->builder = builder;
2703 ctx->alloca_builder = create_builder (ctx);
2706 * Handle indirect/volatile variables by allocating memory for them
2707 * using 'alloca', and storing their address in a temporary.
2709 for (i = 0; i < cfg->num_varinfo; ++i) {
2710 MonoInst *var = cfg->varinfo [i];
2713 if (var->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT) || (mini_type_is_vtype (var->inst_vtype) && !MONO_CLASS_IS_SIMD (ctx->cfg, var->klass))) {
2714 vtype = type_to_llvm_type (ctx, var->inst_vtype);
2715 CHECK_FAILURE (ctx);
2716 /* Could be already created by an OP_VPHI */
2717 if (!ctx->addresses [var->dreg])
2718 ctx->addresses [var->dreg] = build_alloca (ctx, var->inst_vtype);
2719 ctx->vreg_cli_types [var->dreg] = var->inst_vtype;
2723 names = g_new (char *, sig->param_count);
2724 mono_method_get_param_names (cfg->method, (const char **) names);
2726 for (i = 0; i < sig->param_count; ++i) {
2727 LLVMArgInfo *ainfo = &linfo->args [i + sig->hasthis];
2728 int reg = cfg->args [i + sig->hasthis]->dreg;
2731 pindex = ainfo->pindex;
2733 switch (ainfo->storage) {
2734 case LLVMArgVtypeInReg:
2735 case LLVMArgAsFpArgs: {
2736 LLVMValueRef args [8];
2739 /* The argument is received as a set of int/fp arguments, store them into the real argument */
2740 memset (args, 0, sizeof (args));
2741 if (ainfo->storage == LLVMArgVtypeInReg) {
2742 args [0] = LLVMGetParam (ctx->lmethod, pindex);
2743 if (ainfo->pair_storage [1] != LLVMArgNone)
2744 args [1] = LLVMGetParam (ctx->lmethod, pindex + 1);
2746 g_assert (ainfo->nslots <= 8);
2747 for (j = 0; j < ainfo->nslots; ++j)
2748 args [j] = LLVMGetParam (ctx->lmethod, pindex + j);
2750 ctx->addresses [reg] = build_alloca (ctx, ainfo->type);
2752 emit_args_to_vtype (ctx, builder, ainfo->type, ctx->addresses [reg], ainfo, args);
2754 if (ainfo->storage == LLVMArgVtypeInReg && MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (ainfo->type))) {
2755 /* Treat these as normal values */
2756 ctx->values [reg] = LLVMBuildLoad (builder, ctx->addresses [reg], "");
2760 case LLVMArgVtypeByVal: {
2761 ctx->addresses [reg] = LLVMGetParam (ctx->lmethod, pindex);
2763 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (ainfo->type))) {
2764 /* Treat these as normal values */
2765 ctx->values [reg] = LLVMBuildLoad (builder, ctx->addresses [reg], "");
2769 case LLVMArgVtypeByRef: {
2770 /* The argument is passed by ref */
2771 ctx->addresses [reg] = LLVMGetParam (ctx->lmethod, pindex);
2774 case LLVMArgScalarByRef: {
2776 name = g_strdup_printf ("arg_%s", names [i]);
2778 name = g_strdup_printf ("arg_%d", i);
2779 ctx->values [reg] = LLVMBuildLoad (builder, LLVMGetParam (ctx->lmethod, pindex), name);
2783 case LLVMArgAsIArgs: {
2784 LLVMValueRef arg = LLVMGetParam (ctx->lmethod, pindex);
2786 ctx->addresses [reg] = build_alloca (ctx, ainfo->type);
2788 /* The argument is received as an array of ints, store it into the real argument */
2789 LLVMBuildStore (ctx->builder, arg, convert (ctx, ctx->addresses [reg], LLVMPointerType (LLVMTypeOf (arg), 0)));
2792 case LLVMArgVtypeAsScalar:
2793 g_assert_not_reached ();
2796 ctx->values [reg] = convert_full (ctx, ctx->values [reg], llvm_type_to_stack_type (cfg, type_to_llvm_type (ctx, ainfo->type)), type_is_unsigned (ctx, ainfo->type));
2803 emit_volatile_store (ctx, cfg->vret_addr->dreg);
2805 emit_volatile_store (ctx, cfg->args [0]->dreg);
2806 for (i = 0; i < sig->param_count; ++i)
2807 if (!mini_type_is_vtype (sig->params [i]))
2808 emit_volatile_store (ctx, cfg->args [i + sig->hasthis]->dreg);
2810 if (sig->hasthis && !cfg->rgctx_var && cfg->gshared) {
2811 LLVMValueRef this_alloc;
2814 * The exception handling code needs the location where the this argument was
2815 * stored for gshared methods. We create a separate alloca to hold it, and mark it
2816 * with the "mono.this" custom metadata to tell llvm that it needs to save its
2817 * location into the LSDA.
2819 this_alloc = mono_llvm_build_alloca (builder, ThisType (), LLVMConstInt (LLVMInt32Type (), 1, FALSE), 0, "");
2820 /* This volatile store will keep the alloca alive */
2821 mono_llvm_build_store (builder, ctx->values [cfg->args [0]->dreg], this_alloc, TRUE, LLVM_BARRIER_NONE);
2823 set_metadata_flag (this_alloc, "mono.this");
2826 if (cfg->rgctx_var) {
2827 LLVMValueRef rgctx_alloc, store;
2830 * We handle the rgctx arg similarly to the this pointer.
2832 g_assert (ctx->addresses [cfg->rgctx_var->dreg]);
2833 rgctx_alloc = ctx->addresses [cfg->rgctx_var->dreg];
2834 /* This volatile store will keep the alloca alive */
2835 store = mono_llvm_build_store (builder, convert (ctx, ctx->rgctx_arg, IntPtrType ()), rgctx_alloc, TRUE, LLVM_BARRIER_NONE);
2837 set_metadata_flag (rgctx_alloc, "mono.this");
2840 /* Initialize the method if needed */
2841 if (cfg->compile_aot && ctx->llvm_only) {
2842 /* Emit a location for the initialization code */
2843 ctx->init_bb = gen_bb (ctx, "INIT_BB");
2844 ctx->inited_bb = gen_bb (ctx, "INITED_BB");
2846 LLVMBuildBr (ctx->builder, ctx->init_bb);
2847 builder = ctx->builder = create_builder (ctx);
2848 LLVMPositionBuilderAtEnd (ctx->builder, ctx->inited_bb);
2849 ctx->bblocks [cfg->bb_entry->block_num].end_bblock = ctx->inited_bb;
2852 /* Compute nesting between clauses */
2853 ctx->nested_in = mono_mempool_alloc0 (cfg->mempool, sizeof (GSList*) * cfg->header->num_clauses);
2854 for (i = 0; i < cfg->header->num_clauses; ++i) {
2855 for (j = 0; j < cfg->header->num_clauses; ++j) {
2856 MonoExceptionClause *clause1 = &cfg->header->clauses [i];
2857 MonoExceptionClause *clause2 = &cfg->header->clauses [j];
2859 if (i != j && clause1->try_offset >= clause2->try_offset && clause1->handler_offset <= clause2->handler_offset)
2860 ctx->nested_in [i] = g_slist_prepend_mempool (cfg->mempool, ctx->nested_in [i], GINT_TO_POINTER (j));
2865 * For finally clauses, create an indicator variable telling OP_ENDFINALLY whenever
2866 * it needs to continue normally, or return back to the exception handling system.
2868 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
2872 if (!(bb->region != -1 && (bb->flags & BB_EXCEPTION_HANDLER)))
2875 clause_index = MONO_REGION_CLAUSE_INDEX (bb->region);
2876 g_hash_table_insert (ctx->region_to_handler, GUINT_TO_POINTER (mono_get_block_region_notry (cfg, bb->region)), bb);
2877 g_hash_table_insert (ctx->clause_to_handler, GINT_TO_POINTER (clause_index), bb);
2879 if (bb->in_scount == 0) {
2882 sprintf (name, "finally_ind_bb%d", bb->block_num);
2883 val = LLVMBuildAlloca (builder, LLVMInt32Type (), name);
2884 LLVMBuildStore (builder, LLVMConstInt (LLVMInt32Type (), 0, FALSE), val);
2886 ctx->bblocks [bb->block_num].finally_ind = val;
2888 /* Create a variable to hold the exception var */
2890 ctx->ex_var = LLVMBuildAlloca (builder, ObjRefType (), "exvar");
2894 * Create a new bblock which CALL_HANDLER/landing pads can branch to, because branching to the
2895 * LLVM bblock containing a landing pad causes problems for the
2896 * LLVM optimizer passes.
2898 sprintf (name, "BB%d_CALL_HANDLER_TARGET", bb->block_num);
2899 ctx->bblocks [bb->block_num].call_handler_target_bb = LLVMAppendBasicBlock (ctx->lmethod, name);
2906 ctx->builder = old_builder;
2910 process_call (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, MonoInst *ins)
2912 MonoCompile *cfg = ctx->cfg;
2913 LLVMModuleRef lmodule = ctx->lmodule;
2914 LLVMValueRef *values = ctx->values;
2915 LLVMValueRef *addresses = ctx->addresses;
2916 MonoCallInst *call = (MonoCallInst*)ins;
2917 MonoMethodSignature *sig = call->signature;
2918 LLVMValueRef callee = NULL, lcall;
2920 LLVMCallInfo *cinfo;
2924 LLVMTypeRef llvm_sig;
2926 gboolean is_virtual, calli;
2927 LLVMBuilderRef builder = *builder_ref;
2929 if (call->signature->call_convention != MONO_CALL_DEFAULT)
2930 LLVM_FAILURE (ctx, "non-default callconv");
2932 cinfo = call->cinfo;
2934 if (call->rgctx_arg_reg)
2935 cinfo->rgctx_arg = TRUE;
2936 if (call->imt_arg_reg)
2937 cinfo->imt_arg = TRUE;
2939 vretaddr = (cinfo->ret.storage == LLVMArgVtypeRetAddr || cinfo->ret.storage == LLVMArgVtypeByRef || cinfo->ret.storage == LLVMArgScalarRetAddr);
2941 llvm_sig = sig_to_llvm_sig_full (ctx, sig, cinfo);
2942 CHECK_FAILURE (ctx);
2944 is_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);
2945 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);
2947 /* FIXME: Avoid creating duplicate methods */
2949 if (ins->flags & MONO_INST_HAS_METHOD) {
2953 if (cfg->compile_aot) {
2954 callee = get_callee (ctx, llvm_sig, MONO_PATCH_INFO_METHOD, call->method);
2956 LLVM_FAILURE (ctx, "can't encode patch");
2958 if (cfg->llvm_only && call->method->klass->image->assembly == ctx->module->assembly) {
2960 * Collect instructions representing the callee into a hash so they can be replaced
2961 * by the llvm method for the callee if the callee turns out to be direct
2962 * callable. Currently this only requires it to not fail llvm compilation.
2964 GSList *l = g_hash_table_lookup (ctx->method_to_callers, call->method);
2965 l = g_slist_prepend (l, callee);
2966 g_hash_table_insert (ctx->method_to_callers, call->method, l);
2969 callee = LLVMAddFunction (lmodule, "", llvm_sig);
2972 mono_create_jit_trampoline_in_domain (mono_domain_get (),
2974 LLVMAddGlobalMapping (ctx->module->ee, callee, target);
2978 if (call->method && strstr (call->method->klass->name, "AsyncVoidMethodBuilder"))
2979 /* LLVM miscompiles async methods */
2980 LLVM_FAILURE (ctx, "#13734");
2983 MonoJitICallInfo *info = mono_find_jit_icall_by_addr (call->fptr);
2989 memset (&ji, 0, sizeof (ji));
2990 ji.type = MONO_PATCH_INFO_JIT_ICALL_ADDR;
2991 ji.data.target = info->name;
2993 target = mono_resolve_patch_target (cfg->method, cfg->domain, NULL, &ji, FALSE);
2995 if (cfg->compile_aot) {
2996 callee = get_callee (ctx, llvm_sig, MONO_PATCH_INFO_INTERNAL_METHOD, (char*)info->name);
2998 LLVM_FAILURE (ctx, "can't encode patch");
3000 callee = LLVMAddFunction (lmodule, "", llvm_sig);
3001 target = (gpointer)mono_icall_get_wrapper (info);
3002 LLVMAddGlobalMapping (ctx->module->ee, callee, target);
3005 if (cfg->compile_aot) {
3007 if (cfg->abs_patches) {
3008 MonoJumpInfo *abs_ji = (MonoJumpInfo*)g_hash_table_lookup (cfg->abs_patches, call->fptr);
3010 callee = get_callee (ctx, llvm_sig, abs_ji->type, abs_ji->data.target);
3012 LLVM_FAILURE (ctx, "can't encode patch");
3016 LLVM_FAILURE (ctx, "aot");
3018 callee = LLVMAddFunction (lmodule, "", llvm_sig);
3020 if (cfg->abs_patches) {
3021 MonoJumpInfo *abs_ji = (MonoJumpInfo*)g_hash_table_lookup (cfg->abs_patches, call->fptr);
3024 * FIXME: Some trampolines might have
3025 * their own calling convention on some platforms.
3027 #ifndef TARGET_AMD64
3028 if (abs_ji->type == MONO_PATCH_INFO_MONITOR_ENTER || abs_ji->type == MONO_PATCH_INFO_MONITOR_ENTER_V4 ||
3029 abs_ji->type == MONO_PATCH_INFO_MONITOR_EXIT)
3030 LLVM_FAILURE (ctx, "trampoline with own cconv");
3032 target = mono_resolve_patch_target (cfg->method, cfg->domain, NULL, abs_ji, FALSE);
3033 LLVMAddGlobalMapping (ctx->module->ee, callee, target);
3037 LLVMAddGlobalMapping (ctx->module->ee, callee, (gpointer)call->fptr);
3043 int size = sizeof (gpointer);
3046 g_assert (ins->inst_offset % size == 0);
3047 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
3049 callee = convert (ctx, LLVMBuildLoad (builder, LLVMBuildGEP (builder, convert (ctx, values [ins->inst_basereg], LLVMPointerType (LLVMPointerType (IntPtrType (), 0), 0)), &index, 1, ""), ""), LLVMPointerType (llvm_sig, 0));
3051 callee = convert (ctx, values [ins->sreg1], LLVMPointerType (llvm_sig, 0));
3053 if (ins->flags & MONO_INST_HAS_METHOD) {
3058 * Collect and convert arguments
3060 nargs = (sig->param_count * 16) + sig->hasthis + vretaddr + call->rgctx_reg + call->imt_arg_reg;
3061 len = sizeof (LLVMValueRef) * nargs;
3062 args = (LLVMValueRef*)alloca (len);
3063 memset (args, 0, len);
3064 l = call->out_ireg_args;
3066 if (call->rgctx_arg_reg) {
3067 g_assert (values [call->rgctx_arg_reg]);
3068 g_assert (cinfo->rgctx_arg_pindex < nargs);
3070 * On ARM, the imt/rgctx argument is passed in a caller save register, but some of our trampolines etc. clobber it, leading to
3071 * problems is LLVM moves the arg assignment earlier. To work around this, save the argument into a stack slot and load
3072 * it using a volatile load.
3075 if (!ctx->imt_rgctx_loc)
3076 ctx->imt_rgctx_loc = build_alloca_llvm_type (ctx, ctx->module->ptr_type, sizeof (gpointer));
3077 LLVMBuildStore (builder, convert (ctx, ctx->values [call->rgctx_arg_reg], ctx->module->ptr_type), ctx->imt_rgctx_loc);
3078 args [cinfo->rgctx_arg_pindex] = mono_llvm_build_load (builder, ctx->imt_rgctx_loc, "", TRUE, LLVM_BARRIER_NONE);
3080 args [cinfo->rgctx_arg_pindex] = convert (ctx, values [call->rgctx_arg_reg], ctx->module->ptr_type);
3083 if (call->imt_arg_reg) {
3084 g_assert (!ctx->llvm_only);
3085 g_assert (values [call->imt_arg_reg]);
3086 g_assert (cinfo->imt_arg_pindex < nargs);
3088 if (!ctx->imt_rgctx_loc)
3089 ctx->imt_rgctx_loc = build_alloca_llvm_type (ctx, ctx->module->ptr_type, sizeof (gpointer));
3090 LLVMBuildStore (builder, convert (ctx, ctx->values [call->imt_arg_reg], ctx->module->ptr_type), ctx->imt_rgctx_loc);
3091 args [cinfo->imt_arg_pindex] = mono_llvm_build_load (builder, ctx->imt_rgctx_loc, "", TRUE, LLVM_BARRIER_NONE);
3093 args [cinfo->imt_arg_pindex] = convert (ctx, values [call->imt_arg_reg], ctx->module->ptr_type);
3097 if (!addresses [call->inst.dreg])
3098 addresses [call->inst.dreg] = build_alloca (ctx, sig->ret);
3099 g_assert (cinfo->vret_arg_pindex < nargs);
3100 if (cinfo->ret.storage == LLVMArgVtypeByRef)
3101 args [cinfo->vret_arg_pindex] = addresses [call->inst.dreg];
3103 args [cinfo->vret_arg_pindex] = LLVMBuildPtrToInt (builder, addresses [call->inst.dreg], IntPtrType (), "");
3106 for (i = 0; i < sig->param_count + sig->hasthis; ++i) {
3109 LLVMArgInfo *ainfo = &call->cinfo->args [i];
3111 pindex = ainfo->pindex;
3113 regpair = (guint32)(gssize)(l->data);
3114 reg = regpair & 0xffffff;
3115 args [pindex] = values [reg];
3116 switch (ainfo->storage) {
3117 case LLVMArgVtypeInReg:
3118 case LLVMArgAsFpArgs: {
3121 g_assert (addresses [reg]);
3122 emit_vtype_to_args (ctx, builder, ainfo->type, addresses [reg], ainfo, args + pindex, &nargs);
3126 // FIXME: Get rid of the VMOVE
3129 case LLVMArgVtypeByVal:
3130 g_assert (addresses [reg]);
3131 args [pindex] = addresses [reg];
3133 case LLVMArgVtypeByRef:
3134 case LLVMArgScalarByRef: {
3135 g_assert (addresses [reg]);
3136 args [pindex] = convert (ctx, addresses [reg], LLVMPointerType (type_to_llvm_arg_type (ctx, ainfo->type), 0));
3139 case LLVMArgAsIArgs:
3140 g_assert (addresses [reg]);
3141 args [pindex] = LLVMBuildLoad (ctx->builder, convert (ctx, addresses [reg], LLVMPointerType (LLVMArrayType (IntPtrType (), ainfo->nslots), 0)), "");
3143 case LLVMArgVtypeAsScalar:
3144 g_assert_not_reached ();
3147 g_assert (args [pindex]);
3148 if (i == 0 && sig->hasthis)
3149 args [pindex] = convert (ctx, args [pindex], ThisType ());
3151 args [pindex] = convert (ctx, args [pindex], type_to_llvm_arg_type (ctx, ainfo->type));
3154 g_assert (pindex <= nargs);
3159 // FIXME: Align call sites
3165 lcall = emit_call (ctx, bb, &builder, callee, args, LLVMCountParamTypes (llvm_sig));
3168 * Modify cconv and parameter attributes to pass rgctx/imt correctly.
3170 #if defined(MONO_ARCH_IMT_REG) && defined(MONO_ARCH_RGCTX_REG)
3171 g_assert (MONO_ARCH_IMT_REG == MONO_ARCH_RGCTX_REG);
3173 /* The two can't be used together, so use only one LLVM calling conv to pass them */
3174 g_assert (!(call->rgctx_arg_reg && call->imt_arg_reg));
3175 if (!sig->pinvoke && !cfg->llvm_only)
3176 LLVMSetInstructionCallConv (lcall, LLVMMono1CallConv);
3178 if (cinfo->ret.storage == LLVMArgVtypeByRef)
3179 LLVMAddInstrAttribute (lcall, 1 + cinfo->vret_arg_pindex, LLVMStructRetAttribute);
3180 if (!ctx->llvm_only && call->rgctx_arg_reg)
3181 LLVMAddInstrAttribute (lcall, 1 + cinfo->rgctx_arg_pindex, LLVMInRegAttribute);
3182 if (call->imt_arg_reg)
3183 LLVMAddInstrAttribute (lcall, 1 + cinfo->imt_arg_pindex, LLVMInRegAttribute);
3185 /* Add byval attributes if needed */
3186 for (i = 0; i < sig->param_count; ++i) {
3187 LLVMArgInfo *ainfo = &call->cinfo->args [i + sig->hasthis];
3189 if (ainfo && ainfo->storage == LLVMArgVtypeByVal)
3190 LLVMAddInstrAttribute (lcall, 1 + ainfo->pindex, LLVMByValAttribute);
3194 * Convert the result
3196 switch (cinfo->ret.storage) {
3197 case LLVMArgVtypeInReg: {
3198 LLVMValueRef regs [2];
3200 if (LLVMTypeOf (lcall) == LLVMVoidType ())
3204 if (!addresses [ins->dreg])
3205 addresses [ins->dreg] = build_alloca (ctx, sig->ret);
3207 regs [0] = LLVMBuildExtractValue (builder, lcall, 0, "");
3208 if (cinfo->ret.pair_storage [1] != LLVMArgNone)
3209 regs [1] = LLVMBuildExtractValue (builder, lcall, 1, "");
3210 emit_args_to_vtype (ctx, builder, sig->ret, addresses [ins->dreg], &cinfo->ret, regs);
3213 case LLVMArgVtypeByVal:
3214 if (!addresses [call->inst.dreg])
3215 addresses [call->inst.dreg] = build_alloca (ctx, sig->ret);
3216 LLVMBuildStore (builder, lcall, addresses [call->inst.dreg]);
3218 case LLVMArgFpStruct:
3219 if (!addresses [call->inst.dreg])
3220 addresses [call->inst.dreg] = build_alloca (ctx, sig->ret);
3221 LLVMBuildStore (builder, lcall, convert_full (ctx, addresses [call->inst.dreg], LLVMPointerType (LLVMTypeOf (lcall), 0), FALSE));
3223 case LLVMArgVtypeAsScalar:
3224 if (!addresses [call->inst.dreg])
3225 addresses [call->inst.dreg] = build_alloca (ctx, sig->ret);
3226 LLVMBuildStore (builder, lcall, convert_full (ctx, addresses [call->inst.dreg], LLVMPointerType (LLVMTypeOf (lcall), 0), FALSE));
3228 case LLVMArgVtypeRetAddr:
3229 case LLVMArgVtypeByRef:
3231 case LLVMArgScalarRetAddr:
3232 /* Normal scalar returned using a vtype return argument */
3233 values [ins->dreg] = LLVMBuildLoad (builder, convert_full (ctx, addresses [call->inst.dreg], LLVMPointerType (type_to_llvm_type (ctx, sig->ret), 0), FALSE), "");
3236 if (sig->ret->type != MONO_TYPE_VOID)
3237 /* If the method returns an unsigned value, need to zext it */
3238 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));
3242 *builder_ref = ctx->builder;
3250 emit_llvmonly_throw (EmitContext *ctx, MonoBasicBlock *bb, gboolean rethrow, LLVMValueRef exc)
3252 const char *icall_name = rethrow ? "mono_llvm_rethrow_exception" : "mono_llvm_throw_exception";
3253 LLVMValueRef callee = rethrow ? ctx->module->rethrow : ctx->module->throw_icall;
3255 LLVMTypeRef exc_type = type_to_llvm_type (ctx, &mono_get_exception_class ()->byval_arg);
3258 LLVMTypeRef fun_sig = LLVMFunctionType1 (LLVMVoidType (), exc_type, FALSE);
3260 if (ctx->cfg->compile_aot) {
3261 callee = get_callee (ctx, fun_sig, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
3263 callee = LLVMAddFunction (ctx->lmodule, icall_name, fun_sig);
3264 LLVMAddGlobalMapping (ctx->module->ee, callee, resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name));
3265 mono_memory_barrier ();
3268 ctx->module->rethrow = callee;
3270 ctx->module->throw_icall = callee;
3274 LLVMValueRef args [2];
3276 args [0] = convert (ctx, exc, exc_type);
3277 emit_call (ctx, bb, &ctx->builder, callee, args, 1);
3279 LLVMBuildUnreachable (ctx->builder);
3281 ctx->builder = create_builder (ctx);
3285 emit_throw (EmitContext *ctx, MonoBasicBlock *bb, gboolean rethrow, LLVMValueRef exc)
3287 MonoMethodSignature *throw_sig;
3288 LLVMValueRef callee, arg;
3289 const char *icall_name;
3291 callee = rethrow ? ctx->module->rethrow : ctx->module->throw_icall;
3292 icall_name = rethrow ? "mono_arch_rethrow_exception" : "mono_arch_throw_exception";
3295 throw_sig = mono_metadata_signature_alloc (mono_get_corlib (), 1);
3296 throw_sig->ret = &mono_get_void_class ()->byval_arg;
3297 throw_sig->params [0] = &mono_get_object_class ()->byval_arg;
3298 if (ctx->cfg->compile_aot) {
3299 callee = get_callee (ctx, sig_to_llvm_sig (ctx, throw_sig), MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
3301 callee = LLVMAddFunction (ctx->lmodule, icall_name, sig_to_llvm_sig (ctx, throw_sig));
3305 * LLVM doesn't push the exception argument, so we need a different
3308 LLVMAddGlobalMapping (ctx->module->ee, callee, resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, rethrow ? "llvm_rethrow_exception_trampoline" : "llvm_throw_exception_trampoline"));
3310 LLVMAddGlobalMapping (ctx->module->ee, callee, resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name));
3314 mono_memory_barrier ();
3316 ctx->module->rethrow = callee;
3318 ctx->module->throw_icall = callee;
3320 arg = convert (ctx, exc, type_to_llvm_type (ctx, &mono_get_object_class ()->byval_arg));
3321 emit_call (ctx, bb, &ctx->builder, callee, &arg, 1);
3325 emit_resume_eh (EmitContext *ctx, MonoBasicBlock *bb)
3327 const char *icall_name = "mono_llvm_resume_exception";
3328 LLVMValueRef callee = ctx->module->resume_eh;
3330 LLVMTypeRef fun_sig = LLVMFunctionType0 (LLVMVoidType (), FALSE);
3333 if (ctx->cfg->compile_aot) {
3334 callee = get_callee (ctx, fun_sig, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
3336 callee = LLVMAddFunction (ctx->lmodule, icall_name, fun_sig);
3337 LLVMAddGlobalMapping (ctx->module->ee, callee, resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name));
3338 mono_memory_barrier ();
3340 ctx->module->resume_eh = callee;
3344 emit_call (ctx, bb, &ctx->builder, callee, NULL, 0);
3346 LLVMBuildUnreachable (ctx->builder);
3348 ctx->builder = create_builder (ctx);
3352 mono_llvm_emit_clear_exception_call (EmitContext *ctx, LLVMBuilderRef builder)
3354 const char *icall_name = "mono_llvm_clear_exception";
3356 LLVMTypeRef call_sig = LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE);
3357 LLVMValueRef callee = NULL;
3360 if (ctx->cfg->compile_aot) {
3361 callee = get_callee (ctx, call_sig, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
3363 // FIXME: This is broken.
3364 callee = LLVMAddFunction (ctx->lmodule, icall_name, call_sig);
3368 g_assert (builder && callee);
3370 return LLVMBuildCall (builder, callee, NULL, 0, "");
3374 mono_llvm_emit_load_exception_call (EmitContext *ctx, LLVMBuilderRef builder)
3376 const char *icall_name = "mono_llvm_load_exception";
3378 LLVMTypeRef call_sig = LLVMFunctionType (ObjRefType (), NULL, 0, FALSE);
3379 LLVMValueRef callee = NULL;
3382 if (ctx->cfg->compile_aot) {
3383 callee = get_callee (ctx, call_sig, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
3385 // FIXME: This is broken.
3386 callee = LLVMAddFunction (ctx->lmodule, icall_name, call_sig);
3390 g_assert (builder && callee);
3392 return LLVMBuildCall (builder, callee, NULL, 0, icall_name);
3397 mono_llvm_emit_match_exception_call (EmitContext *ctx, LLVMBuilderRef builder, gint32 region_start, gint32 region_end)
3399 const char *icall_name = "mono_llvm_match_exception";
3401 ctx->builder = builder;
3403 const int num_args = 3;
3404 LLVMValueRef args [num_args];
3405 args [0] = convert (ctx, get_aotconst (ctx, MONO_PATCH_INFO_AOT_JIT_INFO, GINT_TO_POINTER (ctx->cfg->method_index)), IntPtrType ());
3406 args [1] = LLVMConstInt (LLVMInt32Type (), region_start, 0);
3407 args [2] = LLVMConstInt (LLVMInt32Type (), region_end, 0);
3409 LLVMTypeRef match_sig = LLVMFunctionType3 (LLVMInt32Type (), IntPtrType (), LLVMInt32Type (), LLVMInt32Type (), FALSE);
3410 LLVMValueRef callee = ctx->module->match_exc;
3413 if (ctx->cfg->compile_aot) {
3414 ctx->builder = builder;
3415 // get_callee expects ctx->builder to be the emitting builder
3416 callee = get_callee (ctx, match_sig, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
3418 callee = ctx->module->match_exc = LLVMAddFunction (ctx->lmodule, icall_name, match_sig);
3419 LLVMAddGlobalMapping (ctx->module->ee, ctx->module->match_exc, resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name));
3420 ctx->module->match_exc = callee;
3421 mono_memory_barrier ();
3425 g_assert (builder && callee);
3427 g_assert (ctx->ex_var);
3429 return LLVMBuildCall (builder, callee, args, num_args, icall_name);
3432 // FIXME: This won't work because the code-finding makes this
3434 /*#define MONO_PERSONALITY_DEBUG*/
3436 #ifdef MONO_PERSONALITY_DEBUG
3437 static const gboolean use_debug_personality = TRUE;
3438 static const char *default_personality_name = "mono_debug_personality";
3440 static const gboolean use_debug_personality = FALSE;
3441 static const char *default_personality_name = "__gxx_personality_v0";
3445 default_cpp_lpad_exc_signature (void)
3447 static gboolean inited = FALSE;
3448 static LLVMTypeRef sig;
3451 LLVMTypeRef signature [2];
3452 signature [0] = LLVMPointerType (LLVMInt8Type (), 0);
3453 signature [1] = LLVMInt32Type ();
3454 sig = LLVMStructType (signature, 2, FALSE);
3462 get_mono_personality (EmitContext *ctx)
3464 LLVMValueRef personality = NULL;
3465 static gint32 mapping_inited = FALSE;
3466 LLVMTypeRef personality_type = LLVMFunctionType (LLVMInt32Type (), NULL, 0, TRUE);
3468 if (!use_debug_personality) {
3469 if (ctx->cfg->compile_aot) {
3470 personality = LLVMGetNamedFunction (ctx->lmodule, default_personality_name);
3471 } else if (InterlockedCompareExchange (&mapping_inited, 1, 0) == 0) {
3472 personality = LLVMAddFunction (ctx->lmodule, default_personality_name, personality_type);
3473 LLVMAddGlobalMapping (ctx->module->ee, personality, personality);
3476 if (ctx->cfg->compile_aot) {
3477 personality = get_callee (ctx, personality_type, MONO_PATCH_INFO_INTERNAL_METHOD, default_personality_name);
3479 personality = LLVMAddFunction (ctx->lmodule, default_personality_name, personality_type);
3480 LLVMAddGlobalMapping (ctx->module->ee, personality, resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, default_personality_name));
3481 mono_memory_barrier ();
3485 g_assert (personality);
3489 static LLVMBasicBlockRef
3490 emit_landing_pad (EmitContext *ctx, int group_index, int group_size)
3492 MonoCompile *cfg = ctx->cfg;
3493 LLVMBuilderRef old_builder = ctx->builder;
3494 MonoExceptionClause *group_start = cfg->header->clauses + group_index;
3496 LLVMBuilderRef lpadBuilder = create_builder (ctx);
3497 ctx->builder = lpadBuilder;
3499 MonoBasicBlock *handler_bb = cfg->cil_offset_to_bb [CLAUSE_START (group_start)];
3500 g_assert (handler_bb);
3502 // <resultval> = landingpad <somety> personality <type> <pers_fn> <clause>+
3503 LLVMValueRef personality = get_mono_personality (ctx);
3504 g_assert (personality);
3506 char *bb_name = g_strdup_printf ("LPAD%d_BB", group_index);
3507 LLVMBasicBlockRef lpad_bb = gen_bb (ctx, bb_name);
3509 LLVMPositionBuilderAtEnd (lpadBuilder, lpad_bb);
3510 LLVMValueRef landing_pad = LLVMBuildLandingPad (lpadBuilder, default_cpp_lpad_exc_signature (), personality, 0, "");
3511 g_assert (landing_pad);
3513 LLVMValueRef cast = LLVMBuildBitCast (lpadBuilder, ctx->module->sentinel_exception, LLVMPointerType (LLVMInt8Type (), 0), "int8TypeInfo");
3514 LLVMAddClause (landing_pad, cast);
3516 LLVMBasicBlockRef resume_bb = gen_bb (ctx, "RESUME_BB");
3517 LLVMBuilderRef resume_builder = create_builder (ctx);
3518 ctx->builder = resume_builder;
3519 LLVMPositionBuilderAtEnd (resume_builder, resume_bb);
3521 emit_resume_eh (ctx, handler_bb);
3524 ctx->builder = lpadBuilder;
3525 LLVMPositionBuilderAtEnd (lpadBuilder, lpad_bb);
3527 gboolean finally_only = TRUE;
3529 MonoExceptionClause *group_cursor = group_start;
3531 for (int i = 0; i < group_size; i ++) {
3532 if (!(group_cursor->flags & MONO_EXCEPTION_CLAUSE_FINALLY))
3533 finally_only = FALSE;
3539 // Handle landing pad inlining
3541 if (!finally_only) {
3542 // So at each level of the exception stack we will match the exception again.
3543 // During that match, we need to compare against the handler types for the current
3544 // protected region. We send the try start and end so that we can only check against
3545 // handlers for this lexical protected region.
3546 LLVMValueRef match = mono_llvm_emit_match_exception_call (ctx, lpadBuilder, group_start->try_offset, group_start->try_offset + group_start->try_len);
3548 // if returns -1, resume
3549 LLVMValueRef switch_ins = LLVMBuildSwitch (lpadBuilder, match, resume_bb, group_size);
3551 // else move to that target bb
3552 for (int i=0; i < group_size; i++) {
3553 MonoExceptionClause *clause = group_start + i;
3554 int clause_index = clause - cfg->header->clauses;
3555 MonoBasicBlock *handler_bb = (MonoBasicBlock*)g_hash_table_lookup (ctx->clause_to_handler, GINT_TO_POINTER (clause_index));
3556 g_assert (handler_bb);
3557 g_assert (ctx->bblocks [handler_bb->block_num].call_handler_target_bb);
3558 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), clause_index, FALSE), ctx->bblocks [handler_bb->block_num].call_handler_target_bb);
3561 int clause_index = group_start - cfg->header->clauses;
3562 MonoBasicBlock *finally_bb = (MonoBasicBlock*)g_hash_table_lookup (ctx->clause_to_handler, GINT_TO_POINTER (clause_index));
3563 g_assert (finally_bb);
3565 LLVMBuildBr (ctx->builder, ctx->bblocks [finally_bb->block_num].call_handler_target_bb);
3568 ctx->builder = old_builder;
3575 emit_llvmonly_handler_start (EmitContext *ctx, MonoBasicBlock *bb, LLVMBasicBlockRef cbb)
3577 int clause_index = MONO_REGION_CLAUSE_INDEX (bb->region);
3578 MonoExceptionClause *clause = &ctx->cfg->header->clauses [clause_index];
3580 // Make exception available to catch blocks
3581 if (!(clause->flags & MONO_EXCEPTION_CLAUSE_FINALLY)) {
3582 LLVMValueRef mono_exc = mono_llvm_emit_load_exception_call (ctx, ctx->builder);
3584 g_assert (ctx->ex_var);
3585 LLVMBuildStore (ctx->builder, LLVMBuildBitCast (ctx->builder, mono_exc, ObjRefType (), ""), ctx->ex_var);
3587 if (bb->in_scount == 1) {
3588 MonoInst *exvar = bb->in_stack [0];
3589 g_assert (!ctx->values [exvar->dreg]);
3590 g_assert (ctx->ex_var);
3591 ctx->values [exvar->dreg] = LLVMBuildLoad (ctx->builder, ctx->ex_var, "save_exception");
3592 emit_volatile_store (ctx, exvar->dreg);
3595 mono_llvm_emit_clear_exception_call (ctx, ctx->builder);
3598 LLVMBuilderRef handler_builder = create_builder (ctx);
3599 LLVMBasicBlockRef target_bb = ctx->bblocks [bb->block_num].call_handler_target_bb;
3600 LLVMPositionBuilderAtEnd (handler_builder, target_bb);
3602 // Make the handler code end with a jump to cbb
3603 LLVMBuildBr (handler_builder, cbb);
3607 emit_handler_start (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef builder)
3609 MonoCompile *cfg = ctx->cfg;
3610 LLVMValueRef *values = ctx->values;
3611 LLVMModuleRef lmodule = ctx->lmodule;
3612 BBInfo *bblocks = ctx->bblocks;
3614 LLVMValueRef personality;
3615 LLVMValueRef landing_pad;
3616 LLVMBasicBlockRef target_bb;
3618 static gint32 mapping_inited;
3619 static int ti_generator;
3622 LLVMValueRef type_info;
3626 // <resultval> = landingpad <somety> personality <type> <pers_fn> <clause>+
3628 if (cfg->compile_aot) {
3629 /* Use a dummy personality function */
3630 personality = LLVMGetNamedFunction (lmodule, "mono_personality");
3631 g_assert (personality);
3633 personality = LLVMGetNamedFunction (lmodule, "mono_personality");
3634 if (InterlockedCompareExchange (&mapping_inited, 1, 0) == 0)
3635 LLVMAddGlobalMapping (ctx->module->ee, personality, mono_personality);
3638 i8ptr = LLVMPointerType (LLVMInt8Type (), 0);
3640 clause_index = (mono_get_block_region_notry (cfg, bb->region) >> 8) - 1;
3643 * Create the type info
3645 sprintf (ti_name, "type_info_%d", ti_generator);
3648 if (cfg->compile_aot) {
3649 /* decode_eh_frame () in aot-runtime.c will decode this */
3650 type_info = LLVMAddGlobal (lmodule, LLVMInt32Type (), ti_name);
3651 LLVMSetInitializer (type_info, LLVMConstInt (LLVMInt32Type (), clause_index, FALSE));
3654 * These symbols are not really used, the clause_index is embedded into the EH tables generated by DwarfMonoException in LLVM.
3656 LLVMSetLinkage (type_info, LLVMInternalLinkage);
3659 * After the cfg mempool is freed, the type info will point to stale memory,
3660 * but this is not a problem, since we decode it once in exception_cb during
3663 ti = mono_mempool_alloc (cfg->mempool, sizeof (gint32));
3664 *(gint32*)ti = clause_index;
3666 type_info = LLVMAddGlobal (lmodule, i8ptr, ti_name);
3668 LLVMAddGlobalMapping (ctx->module->ee, type_info, ti);
3672 LLVMTypeRef members [2], ret_type;
3674 members [0] = i8ptr;
3675 members [1] = LLVMInt32Type ();
3676 ret_type = LLVMStructType (members, 2, FALSE);
3678 landing_pad = LLVMBuildLandingPad (builder, ret_type, personality, 1, "");
3679 LLVMAddClause (landing_pad, type_info);
3681 /* Store the exception into the exvar */
3683 LLVMBuildStore (builder, convert (ctx, LLVMBuildExtractValue (builder, landing_pad, 0, "ex_obj"), ObjRefType ()), ctx->ex_var);
3687 * LLVM throw sites are associated with a one landing pad, and LLVM generated
3688 * code expects control to be transferred to this landing pad even in the
3689 * presence of nested clauses. The landing pad needs to branch to the landing
3690 * pads belonging to nested clauses based on the selector value returned by
3691 * the landing pad instruction, which is passed to the landing pad in a
3692 * register by the EH code.
3694 target_bb = bblocks [bb->block_num].call_handler_target_bb;
3695 g_assert (target_bb);
3698 * Branch to the correct landing pad
3700 LLVMValueRef ex_selector = LLVMBuildExtractValue (builder, landing_pad, 1, "ex_selector");
3701 LLVMValueRef switch_ins = LLVMBuildSwitch (builder, ex_selector, target_bb, 0);
3703 for (l = ctx->nested_in [clause_index]; l; l = l->next) {
3704 int nesting_clause_index = GPOINTER_TO_INT (l->data);
3705 MonoBasicBlock *handler_bb;
3707 handler_bb = g_hash_table_lookup (ctx->clause_to_handler, GINT_TO_POINTER (nesting_clause_index));
3708 g_assert (handler_bb);
3710 g_assert (ctx->bblocks [handler_bb->block_num].call_handler_target_bb);
3711 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), nesting_clause_index, FALSE), ctx->bblocks [handler_bb->block_num].call_handler_target_bb);
3714 /* Start a new bblock which CALL_HANDLER can branch to */
3715 target_bb = bblocks [bb->block_num].call_handler_target_bb;
3717 ctx->builder = builder = create_builder (ctx);
3718 LLVMPositionBuilderAtEnd (ctx->builder, target_bb);
3720 ctx->bblocks [bb->block_num].end_bblock = target_bb;
3722 /* Store the exception into the IL level exvar */
3723 if (bb->in_scount == 1) {
3724 g_assert (bb->in_scount == 1);
3725 exvar = bb->in_stack [0];
3727 // FIXME: This is shared with filter clauses ?
3728 g_assert (!values [exvar->dreg]);
3730 g_assert (ctx->ex_var);
3731 values [exvar->dreg] = LLVMBuildLoad (builder, ctx->ex_var, "");
3732 emit_volatile_store (ctx, exvar->dreg);
3738 process_bb (EmitContext *ctx, MonoBasicBlock *bb)
3740 MonoCompile *cfg = ctx->cfg;
3741 MonoMethodSignature *sig = ctx->sig;
3742 LLVMValueRef method = ctx->lmethod;
3743 LLVMValueRef *values = ctx->values;
3744 LLVMValueRef *addresses = ctx->addresses;
3745 LLVMCallInfo *linfo = ctx->linfo;
3746 LLVMModuleRef lmodule = ctx->lmodule;
3747 BBInfo *bblocks = ctx->bblocks;
3749 LLVMBasicBlockRef cbb;
3750 LLVMBuilderRef builder, starting_builder;
3751 gboolean has_terminator;
3753 LLVMValueRef lhs, rhs;
3756 cbb = get_end_bb (ctx, bb);
3758 builder = create_builder (ctx);
3759 ctx->builder = builder;
3760 LLVMPositionBuilderAtEnd (builder, cbb);
3762 CHECK_FAILURE (ctx);
3764 if (bb->flags & BB_EXCEPTION_HANDLER) {
3765 if (!ctx->llvm_only && !bblocks [bb->block_num].invoke_target) {
3766 LLVM_FAILURE (ctx, "handler without invokes");
3770 emit_llvmonly_handler_start (ctx, bb, cbb);
3772 emit_handler_start (ctx, bb, builder);
3773 CHECK_FAILURE (ctx);
3774 builder = ctx->builder;
3777 has_terminator = FALSE;
3778 starting_builder = builder;
3779 for (ins = bb->code; ins; ins = ins->next) {
3780 const char *spec = LLVM_INS_INFO (ins->opcode);
3782 char dname_buf [128];
3784 emit_dbg_loc (ctx, builder, ins->cil_code);
3787 if (nins > 3000 && builder == starting_builder) {
3788 /* some steps in llc are non-linear in the size of basic blocks, see #5714 */
3789 LLVM_FAILURE (ctx, "basic block too long");
3793 /* There could be instructions after a terminator, skip them */
3796 if (spec [MONO_INST_DEST] != ' ' && !MONO_IS_STORE_MEMBASE (ins)) {
3797 sprintf (dname_buf, "t%d", ins->dreg);
3801 if (spec [MONO_INST_SRC1] != ' ' && spec [MONO_INST_SRC1] != 'v') {
3802 MonoInst *var = get_vreg_to_inst (cfg, ins->sreg1);
3804 if (var && var->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT)) {
3805 lhs = emit_volatile_load (ctx, ins->sreg1);
3807 /* It is ok for SETRET to have an uninitialized argument */
3808 if (!values [ins->sreg1] && ins->opcode != OP_SETRET)
3809 LLVM_FAILURE (ctx, "sreg1");
3810 lhs = values [ins->sreg1];
3816 if (spec [MONO_INST_SRC2] != ' ' && spec [MONO_INST_SRC2] != ' ') {
3817 MonoInst *var = get_vreg_to_inst (cfg, ins->sreg2);
3818 if (var && var->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT)) {
3819 rhs = emit_volatile_load (ctx, ins->sreg2);
3821 if (!values [ins->sreg2])
3822 LLVM_FAILURE (ctx, "sreg2");
3823 rhs = values [ins->sreg2];
3829 //mono_print_ins (ins);
3830 switch (ins->opcode) {
3833 case OP_LIVERANGE_START:
3834 case OP_LIVERANGE_END:
3837 values [ins->dreg] = LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE);
3840 #if SIZEOF_VOID_P == 4
3841 values [ins->dreg] = LLVMConstInt (LLVMInt64Type (), GET_LONG_IMM (ins), FALSE);
3843 values [ins->dreg] = LLVMConstInt (LLVMInt64Type (), (gint64)ins->inst_c0, FALSE);
3847 values [ins->dreg] = LLVMConstReal (LLVMDoubleType (), *(double*)ins->inst_p0);
3851 values [ins->dreg] = LLVMConstReal (LLVMFloatType (), *(float*)ins->inst_p0);
3853 values [ins->dreg] = LLVMConstFPExt (LLVMConstReal (LLVMFloatType (), *(float*)ins->inst_p0), LLVMDoubleType ());
3855 case OP_DUMMY_ICONST:
3856 values [ins->dreg] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
3858 case OP_DUMMY_I8CONST:
3859 values [ins->dreg] = LLVMConstInt (LLVMInt64Type (), 0, FALSE);
3861 case OP_DUMMY_R8CONST:
3862 values [ins->dreg] = LLVMConstReal (LLVMDoubleType (), 0.0f);
3865 LLVMBasicBlockRef target_bb = get_bb (ctx, ins->inst_target_bb);
3866 LLVMBuildBr (builder, target_bb);
3867 has_terminator = TRUE;
3874 LLVMBasicBlockRef new_bb;
3875 LLVMBuilderRef new_builder;
3877 // The default branch is already handled
3878 // FIXME: Handle it here
3880 /* Start new bblock */
3881 sprintf (bb_name, "SWITCH_DEFAULT_BB%d", ctx->default_index ++);
3882 new_bb = LLVMAppendBasicBlock (ctx->lmethod, bb_name);
3884 lhs = convert (ctx, lhs, LLVMInt32Type ());
3885 v = LLVMBuildSwitch (builder, lhs, new_bb, GPOINTER_TO_UINT (ins->klass));
3886 for (i = 0; i < GPOINTER_TO_UINT (ins->klass); ++i) {
3887 MonoBasicBlock *target_bb = ins->inst_many_bb [i];
3889 LLVMAddCase (v, LLVMConstInt (LLVMInt32Type (), i, FALSE), get_bb (ctx, target_bb));
3892 new_builder = create_builder (ctx);
3893 LLVMPositionBuilderAtEnd (new_builder, new_bb);
3894 LLVMBuildUnreachable (new_builder);
3896 has_terminator = TRUE;
3897 g_assert (!ins->next);
3903 switch (linfo->ret.storage) {
3904 case LLVMArgVtypeInReg: {
3905 LLVMTypeRef ret_type = LLVMGetReturnType (LLVMGetElementType (LLVMTypeOf (method)));
3906 LLVMValueRef val, addr, retval;
3909 retval = LLVMGetUndef (ret_type);
3911 if (!addresses [ins->sreg1]) {
3913 * The return type is an LLVM vector type, have to convert between it and the
3914 * real return type which is a struct type.
3916 g_assert (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (sig->ret)));
3917 /* Convert to 2xi64 first */
3918 val = LLVMBuildBitCast (builder, values [ins->sreg1], LLVMVectorType (IntPtrType (), 2), "");
3920 for (i = 0; i < 2; ++i) {
3921 if (linfo->ret.pair_storage [i] == LLVMArgInIReg) {
3922 retval = LLVMBuildInsertValue (builder, retval, LLVMBuildExtractElement (builder, val, LLVMConstInt (LLVMInt32Type (), i, FALSE), ""), i, "");
3924 g_assert (linfo->ret.pair_storage [i] == LLVMArgNone);
3928 addr = LLVMBuildBitCast (builder, addresses [ins->sreg1], LLVMPointerType (ret_type, 0), "");
3929 for (i = 0; i < 2; ++i) {
3930 if (linfo->ret.pair_storage [i] == LLVMArgInIReg) {
3931 LLVMValueRef indexes [2], part_addr;
3933 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
3934 indexes [1] = LLVMConstInt (LLVMInt32Type (), i, FALSE);
3935 part_addr = LLVMBuildGEP (builder, addr, indexes, 2, "");
3937 retval = LLVMBuildInsertValue (builder, retval, LLVMBuildLoad (builder, part_addr, ""), i, "");
3939 g_assert (linfo->ret.pair_storage [i] == LLVMArgNone);
3943 LLVMBuildRet (builder, retval);
3946 case LLVMArgVtypeAsScalar: {
3947 LLVMTypeRef ret_type = LLVMGetReturnType (LLVMGetElementType (LLVMTypeOf (method)));
3948 LLVMValueRef retval;
3951 size = get_vtype_size (sig->ret);
3953 g_assert (addresses [ins->sreg1]);
3955 retval = LLVMBuildLoad (builder, LLVMBuildBitCast (builder, addresses [ins->sreg1], LLVMPointerType (ret_type, 0), ""), "");
3956 LLVMBuildRet (builder, retval);
3959 case LLVMArgVtypeByVal: {
3960 LLVMValueRef retval;
3962 g_assert (addresses [ins->sreg1]);
3963 retval = LLVMBuildLoad (builder, addresses [ins->sreg1], "");
3964 LLVMBuildRet (builder, retval);
3967 case LLVMArgVtypeByRef: {
3968 LLVMBuildRetVoid (builder);
3971 case LLVMArgVtypeRetAddr: {
3972 LLVMBuildRetVoid (builder);
3975 case LLVMArgScalarRetAddr: {
3976 LLVMTypeRef ret_type = type_to_llvm_type (ctx, sig->ret);
3977 LLVMValueRef param = LLVMGetParam (method, linfo->vret_arg_pindex);
3979 /* sreg1 might not be set */
3981 LLVMBuildStore (builder, convert (ctx, lhs, ret_type), convert (ctx, param, LLVMPointerType (ret_type, 0)));
3982 LLVMBuildRetVoid (builder);
3985 case LLVMArgFpStruct: {
3986 LLVMTypeRef ret_type = LLVMGetReturnType (LLVMGetElementType (LLVMTypeOf (method)));
3987 LLVMValueRef retval;
3989 g_assert (addresses [ins->sreg1]);
3990 retval = LLVMBuildLoad (builder, convert (ctx, addresses [ins->sreg1], LLVMPointerType (ret_type, 0)), "");
3991 LLVMBuildRet (builder, retval);
3995 case LLVMArgNormal: {
3996 if (!lhs || ctx->is_dead [ins->sreg1]) {
3998 * The method did not set its return value, probably because it
3999 * ends with a throw.
4002 LLVMBuildRetVoid (builder);
4004 LLVMBuildRet (builder, LLVMConstNull (type_to_llvm_type (ctx, sig->ret)));
4006 LLVMBuildRet (builder, convert (ctx, lhs, type_to_llvm_type (ctx, sig->ret)));
4008 has_terminator = TRUE;
4012 g_assert_not_reached ();
4021 case OP_ICOMPARE_IMM:
4022 case OP_LCOMPARE_IMM:
4023 case OP_COMPARE_IMM: {
4027 if (ins->next->opcode == OP_NOP)
4030 if (ins->next->opcode == OP_BR)
4031 /* The comparison result is not needed */
4034 rel = mono_opcode_to_cond (ins->next->opcode);
4036 if (ins->opcode == OP_ICOMPARE_IMM) {
4037 lhs = convert (ctx, lhs, LLVMInt32Type ());
4038 rhs = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
4040 if (ins->opcode == OP_LCOMPARE_IMM) {
4041 lhs = convert (ctx, lhs, LLVMInt64Type ());
4042 rhs = LLVMConstInt (LLVMInt64Type (), GET_LONG_IMM (ins), FALSE);
4044 if (ins->opcode == OP_LCOMPARE) {
4045 lhs = convert (ctx, lhs, LLVMInt64Type ());
4046 rhs = convert (ctx, rhs, LLVMInt64Type ());
4048 if (ins->opcode == OP_ICOMPARE) {
4049 lhs = convert (ctx, lhs, LLVMInt32Type ());
4050 rhs = convert (ctx, rhs, LLVMInt32Type ());
4054 if (LLVMGetTypeKind (LLVMTypeOf (lhs)) == LLVMPointerTypeKind)
4055 rhs = convert (ctx, rhs, LLVMTypeOf (lhs));
4056 else if (LLVMGetTypeKind (LLVMTypeOf (rhs)) == LLVMPointerTypeKind)
4057 lhs = convert (ctx, lhs, LLVMTypeOf (rhs));
4060 /* We use COMPARE+SETcc/Bcc, llvm uses SETcc+br cond */
4061 if (ins->opcode == OP_FCOMPARE) {
4062 cmp = LLVMBuildFCmp (builder, fpcond_to_llvm_cond [rel], convert (ctx, lhs, LLVMDoubleType ()), convert (ctx, rhs, LLVMDoubleType ()), "");
4063 } else if (ins->opcode == OP_RCOMPARE) {
4064 cmp = LLVMBuildFCmp (builder, fpcond_to_llvm_cond [rel], convert (ctx, lhs, LLVMFloatType ()), convert (ctx, rhs, LLVMFloatType ()), "");
4065 } else if (ins->opcode == OP_COMPARE_IMM) {
4066 if (LLVMGetTypeKind (LLVMTypeOf (lhs)) == LLVMPointerTypeKind && ins->inst_imm == 0)
4067 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], lhs, LLVMConstNull (LLVMTypeOf (lhs)), "");
4069 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE), "");
4070 } else if (ins->opcode == OP_LCOMPARE_IMM) {
4071 if (SIZEOF_REGISTER == 4 && COMPILE_LLVM (cfg)) {
4072 /* The immediate is encoded in two fields */
4073 guint64 l = ((guint64)(guint32)ins->inst_offset << 32) | ((guint32)ins->inst_imm);
4074 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, LLVMInt64Type ()), LLVMConstInt (LLVMInt64Type (), l, FALSE), "");
4076 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, LLVMInt64Type ()), LLVMConstInt (LLVMInt64Type (), ins->inst_imm, FALSE), "");
4079 else if (ins->opcode == OP_COMPARE) {
4080 if (LLVMGetTypeKind (LLVMTypeOf (lhs)) == LLVMPointerTypeKind && LLVMTypeOf (lhs) == LLVMTypeOf (rhs))
4081 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], lhs, rhs, "");
4083 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, IntPtrType ()), convert (ctx, rhs, IntPtrType ()), "");
4085 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], lhs, rhs, "");
4087 if (MONO_IS_COND_BRANCH_OP (ins->next)) {
4088 if (ins->next->inst_true_bb == ins->next->inst_false_bb) {
4090 * If the target bb contains PHI instructions, LLVM requires
4091 * two PHI entries for this bblock, while we only generate one.
4092 * So convert this to an unconditional bblock. (bxc #171).
4094 LLVMBuildBr (builder, get_bb (ctx, ins->next->inst_true_bb));
4096 LLVMBuildCondBr (builder, cmp, get_bb (ctx, ins->next->inst_true_bb), get_bb (ctx, ins->next->inst_false_bb));
4098 has_terminator = TRUE;
4099 } else if (MONO_IS_SETCC (ins->next)) {
4100 sprintf (dname_buf, "t%d", ins->next->dreg);
4102 values [ins->next->dreg] = LLVMBuildZExt (builder, cmp, LLVMInt32Type (), dname);
4104 /* Add stores for volatile variables */
4105 emit_volatile_store (ctx, ins->next->dreg);
4106 } else if (MONO_IS_COND_EXC (ins->next)) {
4107 emit_cond_system_exception (ctx, bb, (const char*)ins->next->inst_p1, cmp);
4108 CHECK_FAILURE (ctx);
4109 builder = ctx->builder;
4111 LLVM_FAILURE (ctx, "next");
4125 rel = mono_opcode_to_cond (ins->opcode);
4127 cmp = LLVMBuildFCmp (builder, fpcond_to_llvm_cond [rel], convert (ctx, lhs, LLVMDoubleType ()), convert (ctx, rhs, LLVMDoubleType ()), "");
4128 values [ins->dreg] = LLVMBuildZExt (builder, cmp, LLVMInt32Type (), dname);
4139 rel = mono_opcode_to_cond (ins->opcode);
4141 cmp = LLVMBuildFCmp (builder, fpcond_to_llvm_cond [rel], convert (ctx, lhs, LLVMFloatType ()), convert (ctx, rhs, LLVMFloatType ()), "");
4142 values [ins->dreg] = LLVMBuildZExt (builder, cmp, LLVMInt32Type (), dname);
4150 gboolean empty = TRUE;
4152 /* Check that all input bblocks really branch to us */
4153 for (i = 0; i < bb->in_count; ++i) {
4154 if (bb->in_bb [i]->last_ins && bb->in_bb [i]->last_ins->opcode == OP_NOT_REACHED)
4155 ins->inst_phi_args [i + 1] = -1;
4161 /* LLVM doesn't like phi instructions with zero operands */
4162 ctx->is_dead [ins->dreg] = TRUE;
4166 /* Created earlier, insert it now */
4167 LLVMInsertIntoBuilder (builder, values [ins->dreg]);
4169 for (i = 0; i < ins->inst_phi_args [0]; i++) {
4170 int sreg1 = ins->inst_phi_args [i + 1];
4174 * Count the number of times the incoming bblock branches to us,
4175 * since llvm requires a separate entry for each.
4177 if (bb->in_bb [i]->last_ins && bb->in_bb [i]->last_ins->opcode == OP_SWITCH) {
4178 MonoInst *switch_ins = bb->in_bb [i]->last_ins;
4181 for (j = 0; j < GPOINTER_TO_UINT (switch_ins->klass); ++j) {
4182 if (switch_ins->inst_many_bb [j] == bb)
4189 /* Remember for later */
4190 for (j = 0; j < count; ++j) {
4191 PhiNode *node = (PhiNode*)mono_mempool_alloc0 (ctx->mempool, sizeof (PhiNode));
4194 node->in_bb = bb->in_bb [i];
4196 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);
4206 values [ins->dreg] = lhs;
4210 MonoInst *var = get_vreg_to_inst (cfg, ins->dreg);
4213 values [ins->dreg] = lhs;
4215 if (var && var->klass->byval_arg.type == MONO_TYPE_R4) {
4217 * This is added by the spilling pass in case of the JIT,
4218 * but we have to do it ourselves.
4220 values [ins->dreg] = convert (ctx, values [ins->dreg], LLVMFloatType ());
4224 case OP_MOVE_F_TO_I4: {
4225 values [ins->dreg] = LLVMBuildBitCast (builder, LLVMBuildFPTrunc (builder, lhs, LLVMFloatType (), ""), LLVMInt32Type (), "");
4228 case OP_MOVE_I4_TO_F: {
4229 values [ins->dreg] = LLVMBuildFPExt (builder, LLVMBuildBitCast (builder, lhs, LLVMFloatType (), ""), LLVMDoubleType (), "");
4232 case OP_MOVE_F_TO_I8: {
4233 values [ins->dreg] = LLVMBuildBitCast (builder, lhs, LLVMInt64Type (), "");
4236 case OP_MOVE_I8_TO_F: {
4237 values [ins->dreg] = LLVMBuildBitCast (builder, lhs, LLVMDoubleType (), "");
4270 lhs = convert (ctx, lhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
4271 rhs = convert (ctx, rhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
4273 emit_div_check (ctx, builder, bb, ins, lhs, rhs);
4274 CHECK_FAILURE (ctx);
4275 builder = ctx->builder;
4277 switch (ins->opcode) {
4280 values [ins->dreg] = LLVMBuildAdd (builder, lhs, rhs, dname);
4284 values [ins->dreg] = LLVMBuildSub (builder, lhs, rhs, dname);
4288 values [ins->dreg] = LLVMBuildMul (builder, lhs, rhs, dname);
4292 values [ins->dreg] = LLVMBuildSRem (builder, lhs, rhs, dname);
4296 values [ins->dreg] = LLVMBuildURem (builder, lhs, rhs, dname);
4300 values [ins->dreg] = LLVMBuildSDiv (builder, lhs, rhs, dname);
4304 values [ins->dreg] = LLVMBuildUDiv (builder, lhs, rhs, dname);
4308 values [ins->dreg] = LLVMBuildFDiv (builder, lhs, rhs, dname);
4312 values [ins->dreg] = LLVMBuildAnd (builder, lhs, rhs, dname);
4316 values [ins->dreg] = LLVMBuildOr (builder, lhs, rhs, dname);
4320 values [ins->dreg] = LLVMBuildXor (builder, lhs, rhs, dname);
4324 values [ins->dreg] = LLVMBuildShl (builder, lhs, rhs, dname);
4328 values [ins->dreg] = LLVMBuildAShr (builder, lhs, rhs, dname);
4332 values [ins->dreg] = LLVMBuildLShr (builder, lhs, rhs, dname);
4336 values [ins->dreg] = LLVMBuildFAdd (builder, lhs, rhs, dname);
4339 values [ins->dreg] = LLVMBuildFSub (builder, lhs, rhs, dname);
4342 values [ins->dreg] = LLVMBuildFMul (builder, lhs, rhs, dname);
4346 g_assert_not_reached ();
4353 lhs = convert (ctx, lhs, LLVMFloatType ());
4354 rhs = convert (ctx, rhs, LLVMFloatType ());
4355 switch (ins->opcode) {
4357 values [ins->dreg] = LLVMBuildFAdd (builder, lhs, rhs, dname);
4360 values [ins->dreg] = LLVMBuildFSub (builder, lhs, rhs, dname);
4363 values [ins->dreg] = LLVMBuildFMul (builder, lhs, rhs, dname);
4366 values [ins->dreg] = LLVMBuildFDiv (builder, lhs, rhs, dname);
4369 g_assert_not_reached ();
4378 case OP_IREM_UN_IMM:
4380 case OP_IDIV_UN_IMM:
4386 case OP_ISHR_UN_IMM:
4395 case OP_LSHR_UN_IMM:
4401 case OP_SHR_UN_IMM: {
4404 if (spec [MONO_INST_SRC1] == 'l') {
4405 imm = LLVMConstInt (LLVMInt64Type (), GET_LONG_IMM (ins), FALSE);
4407 imm = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
4410 emit_div_check (ctx, builder, bb, ins, lhs, imm);
4411 CHECK_FAILURE (ctx);
4412 builder = ctx->builder;
4414 #if SIZEOF_VOID_P == 4
4415 if (ins->opcode == OP_LSHL_IMM || ins->opcode == OP_LSHR_IMM || ins->opcode == OP_LSHR_UN_IMM)
4416 imm = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
4419 if (LLVMGetTypeKind (LLVMTypeOf (lhs)) == LLVMPointerTypeKind)
4420 lhs = convert (ctx, lhs, IntPtrType ());
4421 imm = convert (ctx, imm, LLVMTypeOf (lhs));
4422 switch (ins->opcode) {
4426 values [ins->dreg] = LLVMBuildAdd (builder, lhs, imm, dname);
4430 values [ins->dreg] = LLVMBuildSub (builder, lhs, imm, dname);
4434 values [ins->dreg] = LLVMBuildMul (builder, lhs, imm, dname);
4438 values [ins->dreg] = LLVMBuildSDiv (builder, lhs, imm, dname);
4440 case OP_IDIV_UN_IMM:
4441 case OP_LDIV_UN_IMM:
4442 values [ins->dreg] = LLVMBuildUDiv (builder, lhs, imm, dname);
4446 values [ins->dreg] = LLVMBuildSRem (builder, lhs, imm, dname);
4448 case OP_IREM_UN_IMM:
4449 values [ins->dreg] = LLVMBuildURem (builder, lhs, imm, dname);
4454 values [ins->dreg] = LLVMBuildAnd (builder, lhs, imm, dname);
4458 values [ins->dreg] = LLVMBuildOr (builder, lhs, imm, dname);
4462 values [ins->dreg] = LLVMBuildXor (builder, lhs, imm, dname);
4467 values [ins->dreg] = LLVMBuildShl (builder, lhs, imm, dname);
4472 values [ins->dreg] = LLVMBuildAShr (builder, lhs, imm, dname);
4474 case OP_ISHR_UN_IMM:
4475 /* This is used to implement conv.u4, so the lhs could be an i8 */
4476 lhs = convert (ctx, lhs, LLVMInt32Type ());
4477 imm = convert (ctx, imm, LLVMInt32Type ());
4478 values [ins->dreg] = LLVMBuildLShr (builder, lhs, imm, dname);
4480 case OP_LSHR_UN_IMM:
4482 values [ins->dreg] = LLVMBuildLShr (builder, lhs, imm, dname);
4485 g_assert_not_reached ();
4490 values [ins->dreg] = LLVMBuildSub (builder, LLVMConstInt (LLVMInt32Type (), 0, FALSE), convert (ctx, lhs, LLVMInt32Type ()), dname);
4493 values [ins->dreg] = LLVMBuildSub (builder, LLVMConstInt (LLVMInt64Type (), 0, FALSE), lhs, dname);
4496 lhs = convert (ctx, lhs, LLVMDoubleType ());
4497 values [ins->dreg] = LLVMBuildFSub (builder, LLVMConstReal (LLVMDoubleType (), 0.0), lhs, dname);
4500 lhs = convert (ctx, lhs, LLVMFloatType ());
4501 values [ins->dreg] = LLVMBuildFSub (builder, LLVMConstReal (LLVMFloatType (), 0.0), lhs, dname);
4504 guint32 v = 0xffffffff;
4505 values [ins->dreg] = LLVMBuildXor (builder, LLVMConstInt (LLVMInt32Type (), v, FALSE), convert (ctx, lhs, LLVMInt32Type ()), dname);
4509 guint64 v = 0xffffffffffffffffLL;
4510 values [ins->dreg] = LLVMBuildXor (builder, LLVMConstInt (LLVMInt64Type (), v, FALSE), lhs, dname);
4513 #if defined(TARGET_X86) || defined(TARGET_AMD64)
4515 LLVMValueRef v1, v2;
4517 v1 = LLVMBuildMul (builder, convert (ctx, rhs, IntPtrType ()), LLVMConstInt (IntPtrType (), (1 << ins->backend.shift_amount), FALSE), "");
4518 v2 = LLVMBuildAdd (builder, convert (ctx, lhs, IntPtrType ()), v1, "");
4519 values [ins->dreg] = LLVMBuildAdd (builder, v2, LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE), dname);
4524 case OP_ICONV_TO_I1:
4525 case OP_ICONV_TO_I2:
4526 case OP_ICONV_TO_I4:
4527 case OP_ICONV_TO_U1:
4528 case OP_ICONV_TO_U2:
4529 case OP_ICONV_TO_U4:
4530 case OP_LCONV_TO_I1:
4531 case OP_LCONV_TO_I2:
4532 case OP_LCONV_TO_U1:
4533 case OP_LCONV_TO_U2:
4534 case OP_LCONV_TO_U4: {
4537 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);
4539 /* Have to do two casts since our vregs have type int */
4540 v = LLVMBuildTrunc (builder, lhs, op_to_llvm_type (ins->opcode), "");
4542 values [ins->dreg] = LLVMBuildSExt (builder, v, LLVMInt32Type (), dname);
4544 values [ins->dreg] = LLVMBuildZExt (builder, v, LLVMInt32Type (), dname);
4547 case OP_ICONV_TO_I8:
4548 values [ins->dreg] = LLVMBuildSExt (builder, lhs, LLVMInt64Type (), dname);
4550 case OP_ICONV_TO_U8:
4551 values [ins->dreg] = LLVMBuildZExt (builder, lhs, LLVMInt64Type (), dname);
4553 case OP_FCONV_TO_I4:
4554 case OP_RCONV_TO_I4:
4555 values [ins->dreg] = LLVMBuildFPToSI (builder, lhs, LLVMInt32Type (), dname);
4557 case OP_FCONV_TO_I1:
4558 case OP_RCONV_TO_I1:
4559 values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildFPToSI (builder, lhs, LLVMInt8Type (), dname), LLVMInt32Type (), "");
4561 case OP_FCONV_TO_U1:
4562 case OP_RCONV_TO_U1:
4563 values [ins->dreg] = LLVMBuildZExt (builder, LLVMBuildFPToUI (builder, lhs, LLVMInt8Type (), dname), LLVMInt32Type (), "");
4565 case OP_FCONV_TO_I2:
4566 case OP_RCONV_TO_I2:
4567 values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildFPToSI (builder, lhs, LLVMInt16Type (), dname), LLVMInt32Type (), "");
4569 case OP_FCONV_TO_U2:
4570 case OP_RCONV_TO_U2:
4571 values [ins->dreg] = LLVMBuildZExt (builder, LLVMBuildFPToUI (builder, lhs, LLVMInt16Type (), dname), LLVMInt32Type (), "");
4573 case OP_FCONV_TO_I8:
4574 case OP_RCONV_TO_I8:
4575 values [ins->dreg] = LLVMBuildFPToSI (builder, lhs, LLVMInt64Type (), dname);
4578 values [ins->dreg] = LLVMBuildFPToSI (builder, lhs, IntPtrType (), dname);
4580 case OP_ICONV_TO_R8:
4581 case OP_LCONV_TO_R8:
4582 values [ins->dreg] = LLVMBuildSIToFP (builder, lhs, LLVMDoubleType (), dname);
4584 case OP_ICONV_TO_R_UN:
4585 case OP_LCONV_TO_R_UN:
4586 values [ins->dreg] = LLVMBuildUIToFP (builder, lhs, LLVMDoubleType (), dname);
4588 #if SIZEOF_VOID_P == 4
4591 case OP_LCONV_TO_I4:
4592 values [ins->dreg] = LLVMBuildTrunc (builder, lhs, LLVMInt32Type (), dname);
4594 case OP_ICONV_TO_R4:
4595 case OP_LCONV_TO_R4:
4596 v = LLVMBuildSIToFP (builder, lhs, LLVMFloatType (), "");
4598 values [ins->dreg] = v;
4600 values [ins->dreg] = LLVMBuildFPExt (builder, v, LLVMDoubleType (), dname);
4602 case OP_FCONV_TO_R4:
4603 v = LLVMBuildFPTrunc (builder, lhs, LLVMFloatType (), "");
4605 values [ins->dreg] = v;
4607 values [ins->dreg] = LLVMBuildFPExt (builder, v, LLVMDoubleType (), dname);
4609 case OP_RCONV_TO_R8:
4610 values [ins->dreg] = LLVMBuildFPExt (builder, lhs, LLVMDoubleType (), dname);
4612 case OP_RCONV_TO_R4:
4613 values [ins->dreg] = lhs;
4616 values [ins->dreg] = LLVMBuildSExt (builder, convert (ctx, lhs, LLVMInt32Type ()), LLVMInt64Type (), dname);
4619 values [ins->dreg] = LLVMBuildZExt (builder, convert (ctx, lhs, LLVMInt32Type ()), LLVMInt64Type (), dname);
4622 values [ins->dreg] = LLVMBuildTrunc (builder, lhs, LLVMInt32Type (), dname);
4624 case OP_LOCALLOC_IMM: {
4627 guint32 size = ins->inst_imm;
4628 size = (size + (MONO_ARCH_FRAME_ALIGNMENT - 1)) & ~ (MONO_ARCH_FRAME_ALIGNMENT - 1);
4630 v = mono_llvm_build_alloca (builder, LLVMInt8Type (), LLVMConstInt (LLVMInt32Type (), size, FALSE), MONO_ARCH_FRAME_ALIGNMENT, "");
4632 if (ins->flags & MONO_INST_INIT) {
4633 LLVMValueRef args [5];
4636 args [1] = LLVMConstInt (LLVMInt8Type (), 0, FALSE);
4637 args [2] = LLVMConstInt (LLVMInt32Type (), size, FALSE);
4638 args [3] = LLVMConstInt (LLVMInt32Type (), MONO_ARCH_FRAME_ALIGNMENT, FALSE);
4639 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
4640 LLVMBuildCall (builder, LLVMGetNamedFunction (lmodule, memset_func_name), args, memset_param_count, "");
4643 values [ins->dreg] = v;
4647 LLVMValueRef v, size;
4649 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), "");
4651 v = mono_llvm_build_alloca (builder, LLVMInt8Type (), size, MONO_ARCH_FRAME_ALIGNMENT, "");
4653 if (ins->flags & MONO_INST_INIT) {
4654 LLVMValueRef args [5];
4657 args [1] = LLVMConstInt (LLVMInt8Type (), 0, FALSE);
4659 args [3] = LLVMConstInt (LLVMInt32Type (), MONO_ARCH_FRAME_ALIGNMENT, FALSE);
4660 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
4661 LLVMBuildCall (builder, LLVMGetNamedFunction (lmodule, memset_func_name), args, memset_param_count, "");
4663 values [ins->dreg] = v;
4667 case OP_LOADI1_MEMBASE:
4668 case OP_LOADU1_MEMBASE:
4669 case OP_LOADI2_MEMBASE:
4670 case OP_LOADU2_MEMBASE:
4671 case OP_LOADI4_MEMBASE:
4672 case OP_LOADU4_MEMBASE:
4673 case OP_LOADI8_MEMBASE:
4674 case OP_LOADR4_MEMBASE:
4675 case OP_LOADR8_MEMBASE:
4676 case OP_LOAD_MEMBASE:
4684 LLVMValueRef base, index, addr;
4686 gboolean sext = FALSE, zext = FALSE;
4687 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
4689 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
4694 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)) {
4695 addr = LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE);
4700 if (ins->inst_offset == 0) {
4702 } else if (ins->inst_offset % size != 0) {
4703 /* Unaligned load */
4704 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset, FALSE);
4705 addr = LLVMBuildGEP (builder, convert (ctx, base, LLVMPointerType (LLVMInt8Type (), 0)), &index, 1, "");
4707 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
4708 addr = LLVMBuildGEP (builder, convert (ctx, base, LLVMPointerType (t, 0)), &index, 1, "");
4712 addr = convert (ctx, addr, LLVMPointerType (t, 0));
4714 values [ins->dreg] = emit_load (ctx, bb, &builder, size, addr, dname, is_volatile);
4716 if (!is_volatile && (ins->flags & MONO_INST_INVARIANT_LOAD)) {
4718 * These will signal LLVM that these loads do not alias any stores, and
4719 * they can't fail, allowing them to be hoisted out of loops.
4721 set_invariant_load_flag (values [ins->dreg]);
4722 set_metadata_flag (values [ins->dreg], "mono.nofail.load");
4726 values [ins->dreg] = LLVMBuildSExt (builder, values [ins->dreg], LLVMInt32Type (), dname);
4728 values [ins->dreg] = LLVMBuildZExt (builder, values [ins->dreg], LLVMInt32Type (), dname);
4729 else if (!cfg->r4fp && ins->opcode == OP_LOADR4_MEMBASE)
4730 values [ins->dreg] = LLVMBuildFPExt (builder, values [ins->dreg], LLVMDoubleType (), dname);
4734 case OP_STOREI1_MEMBASE_REG:
4735 case OP_STOREI2_MEMBASE_REG:
4736 case OP_STOREI4_MEMBASE_REG:
4737 case OP_STOREI8_MEMBASE_REG:
4738 case OP_STORER4_MEMBASE_REG:
4739 case OP_STORER8_MEMBASE_REG:
4740 case OP_STORE_MEMBASE_REG: {
4742 LLVMValueRef index, addr;
4744 gboolean sext = FALSE, zext = FALSE;
4745 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
4747 if (!values [ins->inst_destbasereg])
4748 LLVM_FAILURE (ctx, "inst_destbasereg");
4750 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
4752 if (ins->inst_offset % size != 0) {
4753 /* Unaligned store */
4754 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset, FALSE);
4755 addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (LLVMInt8Type (), 0)), &index, 1, "");
4757 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
4758 addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (t, 0)), &index, 1, "");
4760 emit_store (ctx, bb, &builder, size, convert (ctx, values [ins->sreg1], t), convert (ctx, addr, LLVMPointerType (t, 0)), is_volatile);
4764 case OP_STOREI1_MEMBASE_IMM:
4765 case OP_STOREI2_MEMBASE_IMM:
4766 case OP_STOREI4_MEMBASE_IMM:
4767 case OP_STOREI8_MEMBASE_IMM:
4768 case OP_STORE_MEMBASE_IMM: {
4770 LLVMValueRef index, addr;
4772 gboolean sext = FALSE, zext = FALSE;
4773 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
4775 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
4777 if (ins->inst_offset % size != 0) {
4778 /* Unaligned store */
4779 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset, FALSE);
4780 addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (LLVMInt8Type (), 0)), &index, 1, "");
4782 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
4783 addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (t, 0)), &index, 1, "");
4785 emit_store (ctx, bb, &builder, size, convert (ctx, LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE), t), convert (ctx, addr, LLVMPointerType (t, 0)), is_volatile);
4790 emit_load (ctx, bb, &builder, sizeof (gpointer), convert (ctx, lhs, LLVMPointerType (IntPtrType (), 0)), "", TRUE);
4792 case OP_OUTARG_VTRETADDR:
4800 case OP_VOIDCALL_MEMBASE:
4801 case OP_CALL_MEMBASE:
4802 case OP_LCALL_MEMBASE:
4803 case OP_FCALL_MEMBASE:
4804 case OP_RCALL_MEMBASE:
4805 case OP_VCALL_MEMBASE:
4806 case OP_VOIDCALL_REG:
4811 case OP_VCALL_REG: {
4812 process_call (ctx, bb, &builder, ins);
4813 CHECK_FAILURE (ctx);
4818 LLVMValueRef indexes [2];
4819 MonoJumpInfo *tmp_ji, *ji;
4820 LLVMValueRef got_entry_addr;
4824 * FIXME: Can't allocate from the cfg mempool since that is freed if
4825 * the LLVM compile fails.
4827 tmp_ji = g_new0 (MonoJumpInfo, 1);
4828 tmp_ji->type = (MonoJumpInfoType)ins->inst_c1;
4829 tmp_ji->data.target = ins->inst_p0;
4831 ji = mono_aot_patch_info_dup (tmp_ji);
4834 ji->next = cfg->patch_info;
4835 cfg->patch_info = ji;
4837 //mono_add_patch_info (cfg, 0, (MonoJumpInfoType)ins->inst_i1, ins->inst_p0);
4838 got_offset = mono_aot_get_got_offset (cfg->patch_info);
4839 ctx->module->max_got_offset = MAX (ctx->module->max_got_offset, got_offset);
4840 if (!mono_aot_is_shared_got_offset (got_offset)) {
4841 //mono_print_ji (ji);
4843 ctx->has_got_access = TRUE;
4846 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
4847 indexes [1] = LLVMConstInt (LLVMInt32Type (), (gssize)got_offset, FALSE);
4848 got_entry_addr = LLVMBuildGEP (builder, ctx->module->got_var, indexes, 2, "");
4850 name = get_aotconst_name (ji->type, ji->data.target, got_offset);
4851 values [ins->dreg] = LLVMBuildLoad (builder, got_entry_addr, name);
4853 set_invariant_load_flag (values [ins->dreg]);
4856 case OP_NOT_REACHED:
4857 LLVMBuildUnreachable (builder);
4858 has_terminator = TRUE;
4859 g_assert (bb->block_num < cfg->max_block_num);
4860 ctx->unreachable [bb->block_num] = TRUE;
4861 /* Might have instructions after this */
4863 MonoInst *next = ins->next;
4865 * FIXME: If later code uses the regs defined by these instructions,
4866 * compilation will fail.
4868 MONO_DELETE_INS (bb, next);
4872 MonoInst *var = ins->inst_i0;
4874 if (var->opcode == OP_VTARG_ADDR) {
4875 /* The variable contains the vtype address */
4876 values [ins->dreg] = values [var->dreg];
4878 values [ins->dreg] = addresses [var->dreg];
4883 LLVMValueRef args [1];
4885 args [0] = convert (ctx, lhs, LLVMDoubleType ());
4886 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (lmodule, "llvm.sin.f64"), args, 1, dname);
4890 LLVMValueRef args [1];
4892 args [0] = convert (ctx, lhs, LLVMDoubleType ());
4893 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (lmodule, "llvm.cos.f64"), args, 1, dname);
4897 LLVMValueRef args [1];
4900 /* This no longer seems to happen */
4902 * LLVM optimizes sqrt(nan) into undefined in
4903 * lib/Analysis/ConstantFolding.cpp
4904 * Also, sqrt(NegativeInfinity) is optimized into 0.
4906 LLVM_FAILURE (ctx, "sqrt");
4908 args [0] = convert (ctx, lhs, LLVMDoubleType ());
4909 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (lmodule, "llvm.sqrt.f64"), args, 1, dname);
4913 LLVMValueRef args [1];
4915 args [0] = convert (ctx, lhs, LLVMDoubleType ());
4916 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (lmodule, "fabs"), args, 1, dname);
4930 lhs = convert (ctx, lhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
4931 rhs = convert (ctx, rhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
4933 switch (ins->opcode) {
4936 v = LLVMBuildICmp (builder, LLVMIntSLE, lhs, rhs, "");
4940 v = LLVMBuildICmp (builder, LLVMIntSGE, lhs, rhs, "");
4944 v = LLVMBuildICmp (builder, LLVMIntULE, lhs, rhs, "");
4948 v = LLVMBuildICmp (builder, LLVMIntUGE, lhs, rhs, "");
4951 g_assert_not_reached ();
4954 values [ins->dreg] = LLVMBuildSelect (builder, v, lhs, rhs, dname);
4957 case OP_ATOMIC_EXCHANGE_I4:
4958 case OP_ATOMIC_EXCHANGE_I8: {
4959 LLVMValueRef args [2];
4962 if (ins->opcode == OP_ATOMIC_EXCHANGE_I4)
4963 t = LLVMInt32Type ();
4965 t = LLVMInt64Type ();
4967 g_assert (ins->inst_offset == 0);
4969 args [0] = convert (ctx, lhs, LLVMPointerType (t, 0));
4970 args [1] = convert (ctx, rhs, t);
4972 values [ins->dreg] = mono_llvm_build_atomic_rmw (builder, LLVM_ATOMICRMW_OP_XCHG, args [0], args [1]);
4975 case OP_ATOMIC_ADD_I4:
4976 case OP_ATOMIC_ADD_I8: {
4977 LLVMValueRef args [2];
4980 if (ins->opcode == OP_ATOMIC_ADD_I4)
4981 t = LLVMInt32Type ();
4983 t = LLVMInt64Type ();
4985 g_assert (ins->inst_offset == 0);
4987 args [0] = convert (ctx, lhs, LLVMPointerType (t, 0));
4988 args [1] = convert (ctx, rhs, t);
4989 values [ins->dreg] = LLVMBuildAdd (builder, mono_llvm_build_atomic_rmw (builder, LLVM_ATOMICRMW_OP_ADD, args [0], args [1]), args [1], dname);
4992 case OP_ATOMIC_CAS_I4:
4993 case OP_ATOMIC_CAS_I8: {
4994 LLVMValueRef args [3], val;
4997 if (ins->opcode == OP_ATOMIC_CAS_I4)
4998 t = LLVMInt32Type ();
5000 t = LLVMInt64Type ();
5002 args [0] = convert (ctx, lhs, LLVMPointerType (t, 0));
5004 args [1] = convert (ctx, values [ins->sreg3], t);
5006 args [2] = convert (ctx, values [ins->sreg2], t);
5007 val = mono_llvm_build_cmpxchg (builder, args [0], args [1], args [2]);
5008 /* cmpxchg returns a pair */
5009 values [ins->dreg] = LLVMBuildExtractValue (builder, val, 0, "");
5012 case OP_MEMORY_BARRIER: {
5013 mono_llvm_build_fence (builder, (BarrierKind) ins->backend.memory_barrier_kind);
5016 case OP_ATOMIC_LOAD_I1:
5017 case OP_ATOMIC_LOAD_I2:
5018 case OP_ATOMIC_LOAD_I4:
5019 case OP_ATOMIC_LOAD_I8:
5020 case OP_ATOMIC_LOAD_U1:
5021 case OP_ATOMIC_LOAD_U2:
5022 case OP_ATOMIC_LOAD_U4:
5023 case OP_ATOMIC_LOAD_U8:
5024 case OP_ATOMIC_LOAD_R4:
5025 case OP_ATOMIC_LOAD_R8: {
5026 LLVM_FAILURE (ctx, "atomic mono.load intrinsic");
5029 gboolean sext, zext;
5031 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
5032 BarrierKind barrier = (BarrierKind) ins->backend.memory_barrier_kind;
5033 LLVMValueRef index, addr;
5035 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
5040 if (ins->inst_offset != 0) {
5041 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
5042 addr = LLVMBuildGEP (builder, convert (ctx, lhs, LLVMPointerType (t, 0)), &index, 1, "");
5047 addr = convert (ctx, addr, LLVMPointerType (t, 0));
5049 values [ins->dreg] = emit_load_general (ctx, bb, &builder, size, addr, dname, is_volatile, barrier);
5052 values [ins->dreg] = LLVMBuildSExt (builder, values [ins->dreg], LLVMInt32Type (), dname);
5054 values [ins->dreg] = LLVMBuildZExt (builder, values [ins->dreg], LLVMInt32Type (), dname);
5057 case OP_ATOMIC_STORE_I1:
5058 case OP_ATOMIC_STORE_I2:
5059 case OP_ATOMIC_STORE_I4:
5060 case OP_ATOMIC_STORE_I8:
5061 case OP_ATOMIC_STORE_U1:
5062 case OP_ATOMIC_STORE_U2:
5063 case OP_ATOMIC_STORE_U4:
5064 case OP_ATOMIC_STORE_U8:
5065 case OP_ATOMIC_STORE_R4:
5066 case OP_ATOMIC_STORE_R8: {
5067 LLVM_FAILURE (ctx, "atomic mono.store intrinsic");
5070 gboolean sext, zext;
5072 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
5073 BarrierKind barrier = (BarrierKind) ins->backend.memory_barrier_kind;
5074 LLVMValueRef index, addr, value;
5076 if (!values [ins->inst_destbasereg])
5077 LLVM_FAILURE (ctx, "inst_destbasereg");
5079 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
5081 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
5082 addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (t, 0)), &index, 1, "");
5083 value = convert (ctx, values [ins->sreg1], t);
5085 emit_store_general (ctx, bb, &builder, size, value, addr, is_volatile, barrier);
5088 case OP_RELAXED_NOP: {
5089 #if defined(TARGET_AMD64) || defined(TARGET_X86)
5090 emit_call (ctx, bb, &builder, LLVMGetNamedFunction (ctx->lmodule, "llvm.x86.sse2.pause"), NULL, 0);
5097 #if (defined(TARGET_AMD64) || defined(TARGET_X86)) && defined(__linux__)
5099 // 257 == FS segment register
5100 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 257);
5102 // 256 == GS segment register
5103 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 256);
5106 values [ins->dreg] = LLVMBuildLoad (builder, LLVMBuildIntToPtr (builder, LLVMConstInt (IntPtrType (), ins->inst_offset, TRUE), ptrtype, ""), "");
5107 #elif defined(TARGET_AMD64) && defined(TARGET_OSX)
5108 /* See mono_amd64_emit_tls_get () */
5109 int offset = mono_amd64_get_tls_gs_offset () + (ins->inst_offset * 8);
5111 // 256 == GS segment register
5112 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 256);
5113 values [ins->dreg] = LLVMBuildLoad (builder, LLVMBuildIntToPtr (builder, LLVMConstInt (IntPtrType (), offset, TRUE), ptrtype, ""), "");
5115 LLVM_FAILURE (ctx, "opcode tls-get");
5120 case OP_TLS_GET_REG: {
5121 #if defined(TARGET_AMD64) && defined(TARGET_OSX)
5122 /* See emit_tls_get_reg () */
5123 // 256 == GS segment register
5124 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 256);
5125 values [ins->dreg] = LLVMBuildLoad (builder, LLVMBuildIntToPtr (builder, convert (ctx, lhs, LLVMInt32Type ()), ptrtype, ""), "");
5127 LLVM_FAILURE (ctx, "opcode tls-get");
5132 case OP_TLS_SET_REG: {
5133 #if defined(TARGET_AMD64) && defined(TARGET_OSX)
5134 /* See emit_tls_get_reg () */
5135 // 256 == GS segment register
5136 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 256);
5137 LLVMBuildStore (builder, convert (ctx, lhs, IntPtrType ()), LLVMBuildIntToPtr (builder, convert (ctx, rhs, LLVMInt32Type ()), ptrtype, ""));
5139 LLVM_FAILURE (ctx, "opcode tls-set-reg");
5148 case OP_IADD_OVF_UN:
5150 case OP_ISUB_OVF_UN:
5152 case OP_IMUL_OVF_UN:
5153 #if SIZEOF_VOID_P == 8
5155 case OP_LADD_OVF_UN:
5157 case OP_LSUB_OVF_UN:
5159 case OP_LMUL_OVF_UN:
5162 LLVMValueRef args [2], val, ovf, func;
5164 args [0] = convert (ctx, lhs, op_to_llvm_type (ins->opcode));
5165 args [1] = convert (ctx, rhs, op_to_llvm_type (ins->opcode));
5166 func = LLVMGetNamedFunction (lmodule, ovf_op_to_intrins (ins->opcode));
5168 val = LLVMBuildCall (builder, func, args, 2, "");
5169 values [ins->dreg] = LLVMBuildExtractValue (builder, val, 0, dname);
5170 ovf = LLVMBuildExtractValue (builder, val, 1, "");
5171 emit_cond_system_exception (ctx, bb, "OverflowException", ovf);
5172 CHECK_FAILURE (ctx);
5173 builder = ctx->builder;
5179 * We currently model them using arrays. Promotion to local vregs is
5180 * disabled for them in mono_handle_global_vregs () in the LLVM case,
5181 * so we always have an entry in cfg->varinfo for them.
5182 * FIXME: Is this needed ?
5185 MonoClass *klass = ins->klass;
5186 LLVMValueRef args [5];
5190 LLVM_FAILURE (ctx, "!klass");
5194 if (!addresses [ins->dreg])
5195 addresses [ins->dreg] = build_alloca (ctx, &klass->byval_arg);
5196 args [0] = LLVMBuildBitCast (builder, addresses [ins->dreg], LLVMPointerType (LLVMInt8Type (), 0), "");
5197 args [1] = LLVMConstInt (LLVMInt8Type (), 0, FALSE);
5198 args [2] = LLVMConstInt (LLVMInt32Type (), mono_class_value_size (klass, NULL), FALSE);
5200 args [3] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
5201 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
5202 LLVMBuildCall (builder, LLVMGetNamedFunction (lmodule, memset_func_name), args, memset_param_count, "");
5205 case OP_DUMMY_VZERO:
5208 case OP_STOREV_MEMBASE:
5209 case OP_LOADV_MEMBASE:
5211 MonoClass *klass = ins->klass;
5212 LLVMValueRef src = NULL, dst, args [5];
5213 gboolean done = FALSE;
5217 LLVM_FAILURE (ctx, "!klass");
5221 if (mini_is_gsharedvt_klass (klass)) {
5223 LLVM_FAILURE (ctx, "gsharedvt");
5227 switch (ins->opcode) {
5228 case OP_STOREV_MEMBASE:
5229 if (cfg->gen_write_barriers && klass->has_references && ins->inst_destbasereg != cfg->frame_reg &&
5230 LLVMGetInstructionOpcode (values [ins->inst_destbasereg]) != LLVMAlloca) {
5231 /* Decomposed earlier */
5232 g_assert_not_reached ();
5235 if (!addresses [ins->sreg1]) {
5237 g_assert (values [ins->sreg1]);
5238 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));
5239 LLVMBuildStore (builder, values [ins->sreg1], dst);
5242 src = LLVMBuildBitCast (builder, addresses [ins->sreg1], LLVMPointerType (LLVMInt8Type (), 0), "");
5243 dst = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_destbasereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (LLVMInt8Type (), 0));
5246 case OP_LOADV_MEMBASE:
5247 if (!addresses [ins->dreg])
5248 addresses [ins->dreg] = build_alloca (ctx, &klass->byval_arg);
5249 src = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_basereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (LLVMInt8Type (), 0));
5250 dst = LLVMBuildBitCast (builder, addresses [ins->dreg], LLVMPointerType (LLVMInt8Type (), 0), "");
5253 if (!addresses [ins->sreg1])
5254 addresses [ins->sreg1] = build_alloca (ctx, &klass->byval_arg);
5255 if (!addresses [ins->dreg])
5256 addresses [ins->dreg] = build_alloca (ctx, &klass->byval_arg);
5257 src = LLVMBuildBitCast (builder, addresses [ins->sreg1], LLVMPointerType (LLVMInt8Type (), 0), "");
5258 dst = LLVMBuildBitCast (builder, addresses [ins->dreg], LLVMPointerType (LLVMInt8Type (), 0), "");
5261 g_assert_not_reached ();
5263 CHECK_FAILURE (ctx);
5270 args [2] = LLVMConstInt (LLVMInt32Type (), mono_class_value_size (klass, NULL), FALSE);
5271 args [3] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
5273 args [3] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
5274 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
5275 LLVMBuildCall (builder, LLVMGetNamedFunction (lmodule, memcpy_func_name), args, memcpy_param_count, "");
5278 case OP_LLVM_OUTARG_VT: {
5279 LLVMArgInfo *ainfo = (LLVMArgInfo*)ins->inst_p0;
5280 MonoType *t = mini_get_underlying_type (ins->inst_vtype);
5282 if (ainfo->storage == LLVMArgScalarByRef) {
5283 LLVMTypeRef argtype;
5284 LLVMValueRef loc, v;
5286 argtype = type_to_llvm_arg_type (ctx, t);
5287 loc = build_alloca_llvm_type (ctx, argtype, 0);
5288 v = convert (ctx, values [ins->sreg1], argtype);
5289 LLVMBuildStore (ctx->builder, v, loc);
5290 addresses [ins->dreg] = loc;
5292 if (!addresses [ins->sreg1]) {
5293 addresses [ins->sreg1] = build_alloca (ctx, t);
5294 g_assert (values [ins->sreg1]);
5295 LLVMBuildStore (builder, values [ins->sreg1], addresses [ins->sreg1]);
5297 addresses [ins->dreg] = addresses [ins->sreg1];
5305 #if defined(TARGET_X86) || defined(TARGET_AMD64)
5307 values [ins->dreg] = LLVMConstNull (type_to_llvm_type (ctx, &ins->klass->byval_arg));
5310 case OP_LOADX_MEMBASE: {
5311 LLVMTypeRef t = type_to_llvm_type (ctx, &ins->klass->byval_arg);
5314 src = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_basereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (t, 0));
5315 values [ins->dreg] = mono_llvm_build_aligned_load (builder, src, "", FALSE, 1);
5318 case OP_STOREX_MEMBASE: {
5319 LLVMTypeRef t = LLVMTypeOf (values [ins->sreg1]);
5322 dest = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_destbasereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (t, 0));
5323 mono_llvm_build_aligned_store (builder, values [ins->sreg1], dest, FALSE, 1);
5330 values [ins->dreg] = LLVMBuildAdd (builder, lhs, rhs, "");
5334 values [ins->dreg] = LLVMBuildFAdd (builder, lhs, rhs, "");
5340 values [ins->dreg] = LLVMBuildSub (builder, lhs, rhs, "");
5344 values [ins->dreg] = LLVMBuildFSub (builder, lhs, rhs, "");
5348 values [ins->dreg] = LLVMBuildFMul (builder, lhs, rhs, "");
5352 values [ins->dreg] = LLVMBuildFDiv (builder, lhs, rhs, "");
5355 values [ins->dreg] = LLVMBuildAnd (builder, lhs, rhs, "");
5358 values [ins->dreg] = LLVMBuildOr (builder, lhs, rhs, "");
5361 values [ins->dreg] = LLVMBuildXor (builder, lhs, rhs, "");
5365 values [ins->dreg] = LLVMBuildMul (builder, lhs, rhs, "");
5376 LLVMValueRef v = NULL;
5378 switch (ins->opcode) {
5383 t = LLVMVectorType (LLVMInt32Type (), 4);
5384 rt = LLVMVectorType (LLVMFloatType (), 4);
5390 t = LLVMVectorType (LLVMInt64Type (), 2);
5391 rt = LLVMVectorType (LLVMDoubleType (), 2);
5394 t = LLVMInt32Type ();
5395 rt = LLVMInt32Type ();
5396 g_assert_not_reached ();
5399 lhs = LLVMBuildBitCast (builder, lhs, t, "");
5400 rhs = LLVMBuildBitCast (builder, rhs, t, "");
5401 switch (ins->opcode) {
5404 v = LLVMBuildAnd (builder, lhs, rhs, "");
5408 v = LLVMBuildOr (builder, lhs, rhs, "");
5412 v = LLVMBuildXor (builder, lhs, rhs, "");
5416 v = LLVMBuildAnd (builder, rhs, LLVMBuildNot (builder, lhs, ""), "");
5419 values [ins->dreg] = LLVMBuildBitCast (builder, v, rt, "");
5443 case OP_PADDB_SAT_UN:
5444 case OP_PADDW_SAT_UN:
5445 case OP_PSUBB_SAT_UN:
5446 case OP_PSUBW_SAT_UN:
5454 case OP_PMULW_HIGH_UN: {
5455 LLVMValueRef args [2];
5460 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (lmodule, simd_op_to_intrins (ins->opcode)), args, 2, dname);
5467 values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildICmp (builder, LLVMIntEQ, lhs, rhs, ""), LLVMTypeOf (lhs), "");
5471 values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildICmp (builder, LLVMIntSGT, lhs, rhs, ""), LLVMTypeOf (lhs), "");
5479 case OP_EXTRACTX_U2:
5481 case OP_EXTRACT_U1: {
5483 gboolean zext = FALSE;
5485 t = simd_op_to_llvm_type (ins->opcode);
5487 switch (ins->opcode) {
5495 case OP_EXTRACTX_U2:
5500 t = LLVMInt32Type ();
5501 g_assert_not_reached ();
5504 lhs = LLVMBuildBitCast (builder, lhs, t, "");
5505 values [ins->dreg] = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), "");
5507 values [ins->dreg] = LLVMBuildZExt (builder, values [ins->dreg], LLVMInt32Type (), "");
5516 case OP_EXPAND_R8: {
5517 LLVMTypeRef t = simd_op_to_llvm_type (ins->opcode);
5518 LLVMValueRef mask [16], v;
5521 for (i = 0; i < 16; ++i)
5522 mask [i] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
5524 v = convert (ctx, values [ins->sreg1], LLVMGetElementType (t));
5526 values [ins->dreg] = LLVMBuildInsertElement (builder, LLVMConstNull (t), v, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
5527 values [ins->dreg] = LLVMBuildShuffleVector (builder, values [ins->dreg], LLVMGetUndef (t), LLVMConstVector (mask, LLVMGetVectorSize (t)), "");
5532 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt8Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
5535 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt16Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
5538 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt32Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
5541 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt64Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
5544 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMFloatType ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
5547 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMDoubleType ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
5558 case OP_EXTRACT_MASK:
5565 v = convert (ctx, values [ins->sreg1], simd_op_to_llvm_type (ins->opcode));
5567 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (lmodule, simd_op_to_intrins (ins->opcode)), &v, 1, dname);
5573 LLVMValueRef args [3];
5577 args [2] = LLVMConstInt (LLVMInt8Type (), ins->inst_c0, FALSE);
5579 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (lmodule, simd_op_to_intrins (ins->opcode)), args, 3, dname);
5584 /* This is only used for implementing shifts by non-immediate */
5585 values [ins->dreg] = lhs;
5596 LLVMValueRef args [3];
5599 args [1] = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
5601 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (lmodule, simd_op_to_intrins (ins->opcode)), args, 2, dname);
5612 case OP_PSHLQ_REG: {
5613 LLVMValueRef args [3];
5616 args [1] = values [ins->sreg2];
5618 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (lmodule, simd_op_to_intrins (ins->opcode)), args, 2, dname);
5625 case OP_PSHUFLEW_LOW:
5626 case OP_PSHUFLEW_HIGH: {
5628 LLVMValueRef v1 = NULL, v2 = NULL, mask_values [16];
5629 int i, mask_size = 0;
5630 int imask = ins->inst_c0;
5632 /* Convert the x86 shuffle mask to LLVM's */
5633 switch (ins->opcode) {
5636 mask [0] = ((imask >> 0) & 3);
5637 mask [1] = ((imask >> 2) & 3);
5638 mask [2] = ((imask >> 4) & 3) + 4;
5639 mask [3] = ((imask >> 6) & 3) + 4;
5640 v1 = values [ins->sreg1];
5641 v2 = values [ins->sreg2];
5645 mask [0] = ((imask >> 0) & 1);
5646 mask [1] = ((imask >> 1) & 1) + 2;
5647 v1 = values [ins->sreg1];
5648 v2 = values [ins->sreg2];
5650 case OP_PSHUFLEW_LOW:
5652 mask [0] = ((imask >> 0) & 3);
5653 mask [1] = ((imask >> 2) & 3);
5654 mask [2] = ((imask >> 4) & 3);
5655 mask [3] = ((imask >> 6) & 3);
5660 v1 = values [ins->sreg1];
5661 v2 = LLVMGetUndef (LLVMTypeOf (v1));
5663 case OP_PSHUFLEW_HIGH:
5669 mask [4] = 4 + ((imask >> 0) & 3);
5670 mask [5] = 4 + ((imask >> 2) & 3);
5671 mask [6] = 4 + ((imask >> 4) & 3);
5672 mask [7] = 4 + ((imask >> 6) & 3);
5673 v1 = values [ins->sreg1];
5674 v2 = LLVMGetUndef (LLVMTypeOf (v1));
5678 mask [0] = ((imask >> 0) & 3);
5679 mask [1] = ((imask >> 2) & 3);
5680 mask [2] = ((imask >> 4) & 3);
5681 mask [3] = ((imask >> 6) & 3);
5682 v1 = values [ins->sreg1];
5683 v2 = LLVMGetUndef (LLVMTypeOf (v1));
5686 g_assert_not_reached ();
5688 for (i = 0; i < mask_size; ++i)
5689 mask_values [i] = LLVMConstInt (LLVMInt32Type (), mask [i], FALSE);
5691 values [ins->dreg] =
5692 LLVMBuildShuffleVector (builder, v1, v2,
5693 LLVMConstVector (mask_values, mask_size), dname);
5697 case OP_UNPACK_LOWB:
5698 case OP_UNPACK_LOWW:
5699 case OP_UNPACK_LOWD:
5700 case OP_UNPACK_LOWQ:
5701 case OP_UNPACK_LOWPS:
5702 case OP_UNPACK_LOWPD:
5703 case OP_UNPACK_HIGHB:
5704 case OP_UNPACK_HIGHW:
5705 case OP_UNPACK_HIGHD:
5706 case OP_UNPACK_HIGHQ:
5707 case OP_UNPACK_HIGHPS:
5708 case OP_UNPACK_HIGHPD: {
5710 LLVMValueRef mask_values [16];
5711 int i, mask_size = 0;
5712 gboolean low = FALSE;
5714 switch (ins->opcode) {
5715 case OP_UNPACK_LOWB:
5719 case OP_UNPACK_LOWW:
5723 case OP_UNPACK_LOWD:
5724 case OP_UNPACK_LOWPS:
5728 case OP_UNPACK_LOWQ:
5729 case OP_UNPACK_LOWPD:
5733 case OP_UNPACK_HIGHB:
5736 case OP_UNPACK_HIGHW:
5739 case OP_UNPACK_HIGHD:
5740 case OP_UNPACK_HIGHPS:
5743 case OP_UNPACK_HIGHQ:
5744 case OP_UNPACK_HIGHPD:
5748 g_assert_not_reached ();
5752 for (i = 0; i < (mask_size / 2); ++i) {
5754 mask [(i * 2) + 1] = mask_size + i;
5757 for (i = 0; i < (mask_size / 2); ++i) {
5758 mask [(i * 2)] = (mask_size / 2) + i;
5759 mask [(i * 2) + 1] = mask_size + (mask_size / 2) + i;
5763 for (i = 0; i < mask_size; ++i)
5764 mask_values [i] = LLVMConstInt (LLVMInt32Type (), mask [i], FALSE);
5766 values [ins->dreg] =
5767 LLVMBuildShuffleVector (builder, values [ins->sreg1], values [ins->sreg2],
5768 LLVMConstVector (mask_values, mask_size), dname);
5773 LLVMTypeRef t = simd_op_to_llvm_type (ins->opcode);
5774 LLVMValueRef v, val;
5776 v = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
5777 val = LLVMConstNull (t);
5778 val = LLVMBuildInsertElement (builder, val, v, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
5779 val = LLVMBuildInsertElement (builder, val, v, LLVMConstInt (LLVMInt32Type (), 1, FALSE), dname);
5781 values [ins->dreg] = val;
5785 case OP_DUPPS_HIGH: {
5786 LLVMTypeRef t = simd_op_to_llvm_type (ins->opcode);
5787 LLVMValueRef v1, v2, val;
5790 if (ins->opcode == OP_DUPPS_LOW) {
5791 v1 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
5792 v2 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 2, FALSE), "");
5794 v1 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 1, FALSE), "");
5795 v2 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 3, FALSE), "");
5797 val = LLVMConstNull (t);
5798 val = LLVMBuildInsertElement (builder, val, v1, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
5799 val = LLVMBuildInsertElement (builder, val, v1, LLVMConstInt (LLVMInt32Type (), 1, FALSE), "");
5800 val = LLVMBuildInsertElement (builder, val, v2, LLVMConstInt (LLVMInt32Type (), 2, FALSE), "");
5801 val = LLVMBuildInsertElement (builder, val, v2, LLVMConstInt (LLVMInt32Type (), 3, FALSE), "");
5803 values [ins->dreg] = val;
5813 * EXCEPTION HANDLING
5815 case OP_IMPLICIT_EXCEPTION:
5816 /* This marks a place where an implicit exception can happen */
5817 if (bb->region != -1)
5818 LLVM_FAILURE (ctx, "implicit-exception");
5822 gboolean rethrow = (ins->opcode == OP_RETHROW);
5823 if (ctx->llvm_only) {
5824 emit_llvmonly_throw (ctx, bb, rethrow, lhs);
5825 has_terminator = TRUE;
5826 ctx->unreachable [bb->block_num] = TRUE;
5828 emit_throw (ctx, bb, rethrow, lhs);
5829 builder = ctx->builder;
5833 case OP_CALL_HANDLER: {
5835 * We don't 'call' handlers, but instead simply branch to them.
5836 * The code generated by ENDFINALLY will branch back to us.
5838 LLVMBasicBlockRef noex_bb;
5840 BBInfo *info = &bblocks [ins->inst_target_bb->block_num];
5842 bb_list = info->call_handler_return_bbs;
5845 * Set the indicator variable for the finally clause.
5847 lhs = info->finally_ind;
5849 LLVMBuildStore (builder, LLVMConstInt (LLVMInt32Type (), g_slist_length (bb_list) + 1, FALSE), lhs);
5851 /* Branch to the finally clause */
5852 LLVMBuildBr (builder, info->call_handler_target_bb);
5854 noex_bb = gen_bb (ctx, "CALL_HANDLER_CONT_BB");
5855 info->call_handler_return_bbs = g_slist_append_mempool (cfg->mempool, info->call_handler_return_bbs, noex_bb);
5857 builder = ctx->builder = create_builder (ctx);
5858 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
5860 bblocks [bb->block_num].end_bblock = noex_bb;
5863 case OP_START_HANDLER: {
5866 case OP_ENDFINALLY: {
5867 LLVMBasicBlockRef resume_bb;
5868 MonoBasicBlock *handler_bb;
5869 LLVMValueRef val, switch_ins, callee;
5873 handler_bb = (MonoBasicBlock*)g_hash_table_lookup (ctx->region_to_handler, GUINT_TO_POINTER (mono_get_block_region_notry (cfg, bb->region)));
5874 g_assert (handler_bb);
5875 info = &bblocks [handler_bb->block_num];
5876 lhs = info->finally_ind;
5879 bb_list = info->call_handler_return_bbs;
5881 resume_bb = gen_bb (ctx, "ENDFINALLY_RESUME_BB");
5883 /* Load the finally variable */
5884 val = LLVMBuildLoad (builder, lhs, "");
5886 /* Reset the variable */
5887 LLVMBuildStore (builder, LLVMConstInt (LLVMInt32Type (), 0, FALSE), lhs);
5889 /* Branch to either resume_bb, or to the bblocks in bb_list */
5890 switch_ins = LLVMBuildSwitch (builder, val, resume_bb, g_slist_length (bb_list));
5892 * The other targets are added at the end to handle OP_CALL_HANDLER
5893 * opcodes processed later.
5895 info->endfinally_switch_ins_list = g_slist_append_mempool (cfg->mempool, info->endfinally_switch_ins_list, switch_ins);
5897 builder = ctx->builder = create_builder (ctx);
5898 LLVMPositionBuilderAtEnd (ctx->builder, resume_bb);
5900 if (ctx->llvm_only) {
5901 emit_resume_eh (ctx, bb);
5903 if (ctx->cfg->compile_aot) {
5904 callee = get_callee (ctx, LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE), MONO_PATCH_INFO_INTERNAL_METHOD, "llvm_resume_unwind_trampoline");
5906 callee = LLVMGetNamedFunction (lmodule, "llvm_resume_unwind_trampoline");
5908 LLVMBuildCall (builder, callee, NULL, 0, "");
5909 LLVMBuildUnreachable (builder);
5912 has_terminator = TRUE;
5918 sprintf (reason, "opcode %s", mono_inst_name (ins->opcode));
5919 LLVM_FAILURE (ctx, reason);
5924 /* Convert the value to the type required by phi nodes */
5925 if (spec [MONO_INST_DEST] != ' ' && !MONO_IS_STORE_MEMBASE (ins) && ctx->vreg_types [ins->dreg]) {
5926 if (!values [ins->dreg])
5928 values [ins->dreg] = addresses [ins->dreg];
5930 values [ins->dreg] = convert (ctx, values [ins->dreg], ctx->vreg_types [ins->dreg]);
5933 /* Add stores for volatile variables */
5934 if (spec [MONO_INST_DEST] != ' ' && spec [MONO_INST_DEST] != 'v' && !MONO_IS_STORE_MEMBASE (ins))
5935 emit_volatile_store (ctx, ins->dreg);
5938 if (!has_terminator && bb->next_bb && (bb == cfg->bb_entry || bb->in_count > 0)) {
5939 LLVMBuildBr (builder, get_bb (ctx, bb->next_bb));
5942 if (bb == cfg->bb_exit && sig->ret->type == MONO_TYPE_VOID) {
5943 emit_dbg_loc (ctx, builder, cfg->header->code + cfg->header->code_size - 1);
5944 LLVMBuildRetVoid (builder);
5947 if (bb == cfg->bb_entry)
5948 ctx->last_alloca = LLVMGetLastInstruction (get_bb (ctx, cfg->bb_entry));
5957 * mono_llvm_check_method_supported:
5959 * Do some quick checks to decide whenever cfg->method can be compiled by LLVM, to avoid
5960 * compiling a method twice.
5963 mono_llvm_check_method_supported (MonoCompile *cfg)
5970 if (cfg->method->save_lmf) {
5971 cfg->exception_message = g_strdup ("lmf");
5972 cfg->disable_llvm = TRUE;
5974 if (cfg->disable_llvm)
5978 * Nested clauses where one of the clauses is a finally clause is
5979 * not supported, because LLVM can't figure out the control flow,
5980 * probably because we resume exception handling by calling our
5981 * own function instead of using the 'resume' llvm instruction.
5983 for (i = 0; i < cfg->header->num_clauses; ++i) {
5984 for (j = 0; j < cfg->header->num_clauses; ++j) {
5985 MonoExceptionClause *clause1 = &cfg->header->clauses [i];
5986 MonoExceptionClause *clause2 = &cfg->header->clauses [j];
5988 if (i != j && clause1->try_offset >= clause2->try_offset && clause1->handler_offset <= clause2->handler_offset &&
5989 (clause1->flags == MONO_EXCEPTION_CLAUSE_FINALLY || clause2->flags == MONO_EXCEPTION_CLAUSE_FINALLY)) {
5990 cfg->exception_message = g_strdup ("nested clauses");
5991 cfg->disable_llvm = TRUE;
5996 if (cfg->disable_llvm)
6000 if (cfg->method->dynamic) {
6001 cfg->exception_message = g_strdup ("dynamic.");
6002 cfg->disable_llvm = TRUE;
6004 if (cfg->disable_llvm)
6008 static LLVMCallInfo*
6009 get_llvm_call_info (MonoCompile *cfg, MonoMethodSignature *sig)
6011 LLVMCallInfo *linfo;
6014 linfo = mono_arch_get_llvm_call_info (cfg, sig);
6015 for (i = 0; i < sig->param_count; ++i)
6016 linfo->args [i + sig->hasthis].type = sig->params [i];
6022 * mono_llvm_emit_method:
6024 * Emit LLVM IL from the mono IL, and compile it to native code using LLVM.
6027 mono_llvm_emit_method (MonoCompile *cfg)
6030 MonoMethodSignature *sig;
6032 LLVMTypeRef method_type;
6033 LLVMValueRef method = NULL;
6035 LLVMValueRef *values;
6036 int i, max_block_num, bb_index;
6037 gboolean last = FALSE;
6038 GPtrArray *phi_values;
6039 LLVMCallInfo *linfo;
6041 LLVMModuleRef lmodule;
6043 GPtrArray *bblock_list;
6044 MonoMethodHeader *header;
6045 MonoExceptionClause *clause;
6048 /* The code below might acquire the loader lock, so use it for global locking */
6049 mono_loader_lock ();
6051 /* Used to communicate with the callbacks */
6052 mono_native_tls_set_value (current_cfg_tls_id, cfg);
6054 ctx = g_new0 (EmitContext, 1);
6056 ctx->mempool = cfg->mempool;
6059 * This maps vregs to the LLVM instruction defining them
6061 values = g_new0 (LLVMValueRef, cfg->next_vreg);
6063 * This maps vregs for volatile variables to the LLVM instruction defining their
6066 ctx->addresses = g_new0 (LLVMValueRef, cfg->next_vreg);
6067 ctx->vreg_types = g_new0 (LLVMTypeRef, cfg->next_vreg);
6068 ctx->vreg_cli_types = g_new0 (MonoType*, cfg->next_vreg);
6069 phi_values = g_ptr_array_sized_new (256);
6071 * This signals whenever the vreg was defined by a phi node with no input vars
6072 * (i.e. all its input bblocks end with NOT_REACHABLE).
6074 ctx->is_dead = g_new0 (gboolean, cfg->next_vreg);
6075 /* Whenever the bblock is unreachable */
6076 ctx->unreachable = g_new0 (gboolean, cfg->max_block_num);
6077 bblock_list = g_ptr_array_sized_new (256);
6079 ctx->values = values;
6080 ctx->region_to_handler = g_hash_table_new (NULL, NULL);
6081 ctx->clause_to_handler = g_hash_table_new (NULL, NULL);
6082 ctx->method_to_callers = g_hash_table_new (NULL, NULL);
6084 if (cfg->compile_aot) {
6085 ctx->module = &aot_module;
6086 method_name = mono_aot_get_method_name (cfg);
6087 cfg->llvm_method_name = g_strdup (method_name);
6089 init_jit_module (cfg->domain);
6090 ctx->module = (MonoLLVMModule*)domain_jit_info (cfg->domain)->llvm_module;
6091 method_name = mono_method_full_name (cfg->method, TRUE);
6094 lmodule = ctx->lmodule = ctx->module->lmodule;
6095 ctx->llvm_only = ctx->module->llvm_only;
6097 if (cfg->gsharedvt && !cfg->llvm_only)
6098 LLVM_FAILURE (ctx, "gsharedvt");
6102 static int count = 0;
6105 if (g_getenv ("LLVM_COUNT")) {
6106 if (count == atoi (g_getenv ("LLVM_COUNT"))) {
6107 printf ("LAST: %s\n", mono_method_full_name (cfg->method, TRUE));
6111 if (count > atoi (g_getenv ("LLVM_COUNT")))
6112 LLVM_FAILURE (ctx, "");
6117 sig = mono_method_signature (cfg->method);
6120 linfo = get_llvm_call_info (cfg, sig);
6122 CHECK_FAILURE (ctx);
6125 linfo->rgctx_arg = TRUE;
6126 method_type = sig_to_llvm_sig_full (ctx, sig, linfo);
6127 CHECK_FAILURE (ctx);
6129 method = LLVMAddFunction (lmodule, method_name, method_type);
6130 ctx->lmethod = method;
6132 if (!cfg->llvm_only)
6133 LLVMSetFunctionCallConv (method, LLVMMono1CallConv);
6134 LLVMSetLinkage (method, LLVMPrivateLinkage);
6136 LLVMAddFunctionAttr (method, LLVMUWTable);
6138 if (cfg->compile_aot) {
6139 LLVMSetLinkage (method, LLVMInternalLinkage);
6140 if (ctx->module->external_symbols) {
6141 LLVMSetLinkage (method, LLVMExternalLinkage);
6142 LLVMSetVisibility (method, LLVMHiddenVisibility);
6145 LLVMSetLinkage (method, LLVMPrivateLinkage);
6148 if (cfg->method->save_lmf && !cfg->llvm_only)
6149 LLVM_FAILURE (ctx, "lmf");
6151 if (sig->pinvoke && cfg->method->wrapper_type != MONO_WRAPPER_RUNTIME_INVOKE && !cfg->llvm_only)
6152 LLVM_FAILURE (ctx, "pinvoke signature");
6154 header = cfg->header;
6155 for (i = 0; i < header->num_clauses; ++i) {
6156 clause = &header->clauses [i];
6157 if (clause->flags != MONO_EXCEPTION_CLAUSE_FINALLY && clause->flags != MONO_EXCEPTION_CLAUSE_NONE)
6158 LLVM_FAILURE (ctx, "non-finally/catch clause.");
6160 if (header->num_clauses || (cfg->method->iflags & METHOD_IMPL_ATTRIBUTE_NOINLINING))
6161 /* We can't handle inlined methods with clauses */
6162 LLVMAddFunctionAttr (method, LLVMNoInlineAttribute);
6164 if (linfo->rgctx_arg) {
6165 ctx->rgctx_arg = LLVMGetParam (method, linfo->rgctx_arg_pindex);
6166 ctx->rgctx_arg_pindex = linfo->rgctx_arg_pindex;
6168 * We mark the rgctx parameter with the inreg attribute, which is mapped to
6169 * MONO_ARCH_RGCTX_REG in the Mono calling convention in llvm, i.e.
6170 * CC_X86_64_Mono in X86CallingConv.td.
6172 if (!ctx->llvm_only)
6173 LLVMAddAttribute (ctx->rgctx_arg, LLVMInRegAttribute);
6174 LLVMSetValueName (ctx->rgctx_arg, "rgctx");
6176 ctx->rgctx_arg_pindex = -1;
6178 if (cfg->vret_addr) {
6179 values [cfg->vret_addr->dreg] = LLVMGetParam (method, linfo->vret_arg_pindex);
6180 LLVMSetValueName (values [cfg->vret_addr->dreg], "vret");
6181 if (linfo->ret.storage == LLVMArgVtypeByRef) {
6182 LLVMAddAttribute (LLVMGetParam (method, linfo->vret_arg_pindex), LLVMStructRetAttribute);
6183 LLVMAddAttribute (LLVMGetParam (method, linfo->vret_arg_pindex), LLVMNoAliasAttribute);
6185 } else if (linfo->ret.storage == LLVMArgScalarRetAddr) {
6186 LLVMValueRef param = LLVMGetParam (method, linfo->vret_arg_pindex);
6187 LLVMSetValueName (param, "vret");
6191 ctx->this_arg_pindex = linfo->this_arg_pindex;
6192 ctx->this_arg = LLVMGetParam (method, linfo->this_arg_pindex);
6193 values [cfg->args [0]->dreg] = ctx->this_arg;
6194 LLVMSetValueName (values [cfg->args [0]->dreg], "this");
6197 names = g_new (char *, sig->param_count);
6198 mono_method_get_param_names (cfg->method, (const char **) names);
6200 for (i = 0; i < sig->param_count; ++i) {
6201 LLVMArgInfo *ainfo = &linfo->args [i + sig->hasthis];
6204 values [cfg->args [i + sig->hasthis]->dreg] = LLVMGetParam (method, ainfo->pindex);
6205 if (ainfo->storage == LLVMArgScalarByRef) {
6206 if (names [i] && names [i][0] != '\0')
6207 name = g_strdup_printf ("p_arg_%s", names [i]);
6209 name = g_strdup_printf ("p_arg_%d", i);
6211 if (names [i] && names [i][0] != '\0')
6212 name = g_strdup_printf ("arg_%s", names [i]);
6214 name = g_strdup_printf ("arg_%d", i);
6216 LLVMSetValueName (values [cfg->args [i + sig->hasthis]->dreg], name);
6218 if (ainfo->storage == LLVMArgVtypeByVal)
6219 LLVMAddAttribute (LLVMGetParam (method, ainfo->pindex), LLVMByValAttribute);
6221 if (ainfo->storage == LLVMArgVtypeByRef) {
6223 cfg->args [i + sig->hasthis]->opcode = OP_VTARG_ADDR;
6228 if (ctx->module->emit_dwarf && cfg->compile_aot && mono_debug_enabled ()) {
6229 ctx->minfo = mono_debug_lookup_method (cfg->method);
6230 ctx->dbg_md = emit_dbg_subprogram (ctx, cfg, method, method_name);
6234 for (bb = cfg->bb_entry; bb; bb = bb->next_bb)
6235 max_block_num = MAX (max_block_num, bb->block_num);
6236 ctx->bblocks = bblocks = g_new0 (BBInfo, max_block_num + 1);
6238 /* Add branches between non-consecutive bblocks */
6239 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
6240 if (bb->last_ins && MONO_IS_COND_BRANCH_OP (bb->last_ins) &&
6241 bb->next_bb != bb->last_ins->inst_false_bb) {
6243 MonoInst *inst = (MonoInst*)mono_mempool_alloc0 (cfg->mempool, sizeof (MonoInst));
6244 inst->opcode = OP_BR;
6245 inst->inst_target_bb = bb->last_ins->inst_false_bb;
6246 mono_bblock_add_inst (bb, inst);
6251 * The INDIRECT flag added by OP_LDADDR inhibits optimizations, even if the LDADDR
6252 * was later optimized away, so clear these flags, and add them back for the still
6253 * present OP_LDADDR instructions.
6255 for (i = 0; i < cfg->next_vreg; ++i) {
6258 ins = get_vreg_to_inst (cfg, i);
6259 if (ins && ins != cfg->rgctx_var)
6260 ins->flags &= ~MONO_INST_INDIRECT;
6264 * Make a first pass over the code to precreate PHI nodes/set INDIRECT flags.
6266 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
6268 LLVMBuilderRef builder;
6270 char dname_buf[128];
6272 builder = create_builder (ctx);
6274 for (ins = bb->code; ins; ins = ins->next) {
6275 switch (ins->opcode) {
6280 LLVMTypeRef phi_type = llvm_type_to_stack_type (cfg, type_to_llvm_type (ctx, &ins->klass->byval_arg));
6282 CHECK_FAILURE (ctx);
6284 if (ins->opcode == OP_VPHI) {
6285 /* Treat valuetype PHI nodes as operating on the address itself */
6286 g_assert (ins->klass);
6287 phi_type = LLVMPointerType (type_to_llvm_type (ctx, &ins->klass->byval_arg), 0);
6291 * Have to precreate these, as they can be referenced by
6292 * earlier instructions.
6294 sprintf (dname_buf, "t%d", ins->dreg);
6296 values [ins->dreg] = LLVMBuildPhi (builder, phi_type, dname);
6298 if (ins->opcode == OP_VPHI)
6299 ctx->addresses [ins->dreg] = values [ins->dreg];
6301 g_ptr_array_add (phi_values, values [ins->dreg]);
6304 * Set the expected type of the incoming arguments since these have
6305 * to have the same type.
6307 for (i = 0; i < ins->inst_phi_args [0]; i++) {
6308 int sreg1 = ins->inst_phi_args [i + 1];
6311 ctx->vreg_types [sreg1] = phi_type;
6316 ((MonoInst*)ins->inst_p0)->flags |= MONO_INST_INDIRECT;
6325 * Create an ordering for bblocks, use the depth first order first, then
6326 * put the exception handling bblocks last.
6328 for (bb_index = 0; bb_index < cfg->num_bblocks; ++bb_index) {
6329 bb = cfg->bblocks [bb_index];
6330 if (!(bb->region != -1 && !MONO_BBLOCK_IS_IN_REGION (bb, MONO_REGION_TRY))) {
6331 g_ptr_array_add (bblock_list, bb);
6332 bblocks [bb->block_num].added = TRUE;
6336 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
6337 if (!bblocks [bb->block_num].added)
6338 g_ptr_array_add (bblock_list, bb);
6342 * Second pass: generate code.
6345 LLVMBuilderRef entry_builder = create_builder (ctx);
6346 LLVMBasicBlockRef entry_bb = get_bb (ctx, cfg->bb_entry);
6347 LLVMPositionBuilderAtEnd (entry_builder, entry_bb);
6348 emit_entry_bb (ctx, entry_builder);
6350 // Make landing pads first
6351 ctx->exc_meta = g_hash_table_new_full (NULL, NULL, NULL, NULL);
6353 if (ctx->llvm_only) {
6354 size_t group_index = 0;
6355 while (group_index < cfg->header->num_clauses) {
6357 size_t cursor = group_index;
6358 while (cursor < cfg->header->num_clauses &&
6359 CLAUSE_START (&cfg->header->clauses [cursor]) == CLAUSE_START (&cfg->header->clauses [group_index]) &&
6360 CLAUSE_END (&cfg->header->clauses [cursor]) == CLAUSE_END (&cfg->header->clauses [group_index])) {
6365 LLVMBasicBlockRef lpad_bb = emit_landing_pad (ctx, group_index, count);
6366 intptr_t key = CLAUSE_END (&cfg->header->clauses [group_index]);
6367 g_hash_table_insert (ctx->exc_meta, (gpointer)key, lpad_bb);
6369 group_index = cursor;
6373 for (bb_index = 0; bb_index < bblock_list->len; ++bb_index) {
6374 bb = (MonoBasicBlock*)g_ptr_array_index (bblock_list, bb_index);
6376 // Prune unreachable mono BBs.
6377 if (!(bb == cfg->bb_entry || bb->in_count > 0))
6380 process_bb (ctx, bb);
6381 CHECK_FAILURE (ctx);
6383 g_hash_table_destroy (ctx->exc_meta);
6385 mono_memory_barrier ();
6387 /* Add incoming phi values */
6388 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
6389 GSList *l, *ins_list;
6391 ins_list = bblocks [bb->block_num].phi_nodes;
6393 for (l = ins_list; l; l = l->next) {
6394 PhiNode *node = (PhiNode*)l->data;
6395 MonoInst *phi = node->phi;
6396 int sreg1 = node->sreg;
6397 LLVMBasicBlockRef in_bb;
6402 in_bb = get_end_bb (ctx, node->in_bb);
6404 if (ctx->unreachable [node->in_bb->block_num])
6407 if (!values [sreg1])
6408 /* Can happen with values in EH clauses */
6409 LLVM_FAILURE (ctx, "incoming phi sreg1");
6411 if (phi->opcode == OP_VPHI) {
6412 g_assert (LLVMTypeOf (ctx->addresses [sreg1]) == LLVMTypeOf (values [phi->dreg]));
6413 LLVMAddIncoming (values [phi->dreg], &ctx->addresses [sreg1], &in_bb, 1);
6415 if (LLVMTypeOf (values [sreg1]) != LLVMTypeOf (values [phi->dreg]))
6417 LLVM_FAILURE (ctx, "incoming phi arg type mismatch");
6418 g_assert (LLVMTypeOf (values [sreg1]) == LLVMTypeOf (values [phi->dreg]));
6419 LLVMAddIncoming (values [phi->dreg], &values [sreg1], &in_bb, 1);
6424 /* Nullify empty phi instructions */
6425 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
6426 GSList *l, *ins_list;
6428 ins_list = bblocks [bb->block_num].phi_nodes;
6430 for (l = ins_list; l; l = l->next) {
6431 PhiNode *node = (PhiNode*)l->data;
6432 MonoInst *phi = node->phi;
6433 LLVMValueRef phi_ins = values [phi->dreg];
6436 /* Already removed */
6439 if (LLVMCountIncoming (phi_ins) == 0) {
6440 mono_llvm_replace_uses_of (phi_ins, LLVMConstNull (LLVMTypeOf (phi_ins)));
6441 LLVMInstructionEraseFromParent (phi_ins);
6442 values [phi->dreg] = NULL;
6447 /* Create the SWITCH statements for ENDFINALLY instructions */
6448 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
6449 BBInfo *info = &bblocks [bb->block_num];
6451 for (l = info->endfinally_switch_ins_list; l; l = l->next) {
6452 LLVMValueRef switch_ins = (LLVMValueRef)l->data;
6453 GSList *bb_list = info->call_handler_return_bbs;
6455 for (i = 0; i < g_slist_length (bb_list); ++i)
6456 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), i + 1, FALSE), g_slist_nth (bb_list, i)->data);
6460 /* Initialize the method if needed */
6461 if (cfg->compile_aot && ctx->llvm_only) {
6462 // FIXME: Add more shared got entries
6463 ctx->builder = create_builder (ctx);
6464 LLVMPositionBuilderAtEnd (ctx->builder, ctx->init_bb);
6466 // FIXME: beforefieldinit
6467 if (ctx->has_got_access || mono_class_get_cctor (cfg->method->klass)) {
6468 emit_init_method (ctx);
6470 LLVMBuildBr (ctx->builder, ctx->inited_bb);
6474 if (cfg->llvm_only) {
6475 GHashTableIter iter;
6477 GSList *callers, *l, *l2;
6480 * Add the contents of ctx->method_to_callers to module->method_to_callers.
6481 * We can't do this earlier, as it contains llvm instructions which can be
6482 * freed if compilation fails.
6483 * FIXME: Get rid of this when all methods can be llvm compiled.
6485 g_hash_table_iter_init (&iter, ctx->method_to_callers);
6486 while (g_hash_table_iter_next (&iter, (void**)&method, (void**)&callers)) {
6487 for (l = callers; l; l = l->next) {
6488 l2 = g_hash_table_lookup (ctx->module->method_to_callers, method);
6489 l2 = g_slist_prepend (l2, l->data);
6490 g_hash_table_insert (ctx->module->method_to_callers, method, l2);
6495 if (cfg->verbose_level > 1)
6496 mono_llvm_dump_value (method);
6498 if (cfg->compile_aot && !cfg->llvm_only)
6499 mark_as_used (ctx->module, method);
6501 if (cfg->compile_aot) {
6502 LLVMValueRef md_args [16];
6503 LLVMValueRef md_node;
6506 method_index = mono_aot_get_method_index (cfg->orig_method);
6507 md_args [0] = LLVMMDString (method_name, strlen (method_name));
6508 md_args [1] = LLVMConstInt (LLVMInt32Type (), method_index, FALSE);
6509 md_node = LLVMMDNode (md_args, 2);
6510 LLVMAddNamedMetadataOperand (lmodule, "mono.function_indexes", md_node);
6511 //LLVMSetMetadata (method, md_kind, LLVMMDNode (&md_arg, 1));
6514 if (cfg->compile_aot) {
6515 /* Don't generate native code, keep the LLVM IR */
6516 if (cfg->verbose_level)
6517 printf ("%s emitted as %s\n", mono_method_full_name (cfg->method, TRUE), method_name);
6519 int err = LLVMVerifyFunction(method, LLVMPrintMessageAction);
6520 g_assert (err == 0);
6522 //LLVMVerifyFunction(method, 0);
6523 mono_llvm_optimize_method (ctx->module->mono_ee, method);
6525 if (cfg->verbose_level > 1)
6526 mono_llvm_dump_value (method);
6528 cfg->native_code = LLVMGetPointerToGlobal (ctx->module->ee, method);
6530 /* Set by emit_cb */
6531 g_assert (cfg->code_len);
6533 /* FIXME: Free the LLVM IL for the function */
6536 if (ctx->module->method_to_lmethod)
6537 g_hash_table_insert (ctx->module->method_to_lmethod, cfg->method, method);
6538 if (ctx->module->idx_to_lmethod)
6539 g_hash_table_insert (ctx->module->idx_to_lmethod, GINT_TO_POINTER (cfg->method_index), method);
6541 if (ctx->llvm_only && cfg->orig_method->klass->valuetype && !(cfg->orig_method->flags & METHOD_ATTRIBUTE_STATIC))
6542 emit_unbox_tramp (ctx, method_name, method_type, method, cfg->method_index);
6549 /* Need to add unused phi nodes as they can be referenced by other values */
6550 LLVMBasicBlockRef phi_bb = LLVMAppendBasicBlock (method, "PHI_BB");
6551 LLVMBuilderRef builder;
6553 builder = create_builder (ctx);
6554 LLVMPositionBuilderAtEnd (builder, phi_bb);
6556 for (i = 0; i < phi_values->len; ++i) {
6557 LLVMValueRef v = g_ptr_array_index (phi_values, i);
6558 if (LLVMGetInstructionParent (v) == NULL)
6559 LLVMInsertIntoBuilder (builder, v);
6562 LLVMDeleteFunction (method);
6567 g_free (ctx->addresses);
6568 g_free (ctx->vreg_types);
6569 g_free (ctx->vreg_cli_types);
6570 g_free (ctx->is_dead);
6571 g_free (ctx->unreachable);
6572 g_ptr_array_free (phi_values, TRUE);
6573 g_free (ctx->bblocks);
6574 g_hash_table_destroy (ctx->region_to_handler);
6575 g_hash_table_destroy (ctx->clause_to_handler);
6576 g_free (method_name);
6577 g_ptr_array_free (bblock_list, TRUE);
6579 for (l = ctx->builders; l; l = l->next) {
6580 LLVMBuilderRef builder = l->data;
6581 LLVMDisposeBuilder (builder);
6586 mono_native_tls_set_value (current_cfg_tls_id, NULL);
6588 mono_loader_unlock ();
6592 * mono_llvm_emit_call:
6594 * Same as mono_arch_emit_call () for LLVM.
6597 mono_llvm_emit_call (MonoCompile *cfg, MonoCallInst *call)
6600 MonoMethodSignature *sig;
6601 int i, n, stack_size;
6606 sig = call->signature;
6607 n = sig->param_count + sig->hasthis;
6609 call->cinfo = get_llvm_call_info (cfg, sig);
6611 if (cfg->disable_llvm)
6614 if (sig->call_convention == MONO_CALL_VARARG) {
6615 cfg->exception_message = g_strdup ("varargs");
6616 cfg->disable_llvm = TRUE;
6619 for (i = 0; i < n; ++i) {
6622 ainfo = call->cinfo->args + i;
6624 in = call->args [i];
6626 /* Simply remember the arguments */
6627 switch (ainfo->storage) {
6628 case LLVMArgNormal: {
6629 MonoType *t = (sig->hasthis && i == 0) ? &mono_get_intptr_class ()->byval_arg : ainfo->type;
6632 opcode = mono_type_to_regmove (cfg, t);
6633 if (opcode == OP_FMOVE) {
6634 MONO_INST_NEW (cfg, ins, OP_FMOVE);
6635 ins->dreg = mono_alloc_freg (cfg);
6636 } else if (opcode == OP_LMOVE) {
6637 MONO_INST_NEW (cfg, ins, OP_LMOVE);
6638 ins->dreg = mono_alloc_lreg (cfg);
6639 } else if (opcode == OP_RMOVE) {
6640 MONO_INST_NEW (cfg, ins, OP_RMOVE);
6641 ins->dreg = mono_alloc_freg (cfg);
6643 MONO_INST_NEW (cfg, ins, OP_MOVE);
6644 ins->dreg = mono_alloc_ireg (cfg);
6646 ins->sreg1 = in->dreg;
6649 case LLVMArgVtypeByVal:
6650 case LLVMArgVtypeByRef:
6651 case LLVMArgVtypeInReg:
6652 case LLVMArgVtypeAsScalar:
6653 case LLVMArgScalarByRef:
6654 case LLVMArgAsIArgs:
6655 case LLVMArgAsFpArgs:
6656 MONO_INST_NEW (cfg, ins, OP_LLVM_OUTARG_VT);
6657 ins->dreg = mono_alloc_ireg (cfg);
6658 ins->sreg1 = in->dreg;
6659 ins->inst_p0 = mono_mempool_alloc0 (cfg->mempool, sizeof (LLVMArgInfo));
6660 memcpy (ins->inst_p0, ainfo, sizeof (LLVMArgInfo));
6661 ins->inst_vtype = ainfo->type;
6662 ins->klass = mono_class_from_mono_type (ainfo->type);
6665 cfg->exception_message = g_strdup ("ainfo->storage");
6666 cfg->disable_llvm = TRUE;
6670 if (!cfg->disable_llvm) {
6671 MONO_ADD_INS (cfg->cbb, ins);
6672 mono_call_inst_add_outarg_reg (cfg, call, ins->dreg, 0, FALSE);
6677 static unsigned char*
6678 alloc_cb (LLVMValueRef function, int size)
6682 cfg = mono_native_tls_get_value (current_cfg_tls_id);
6686 return mono_domain_code_reserve (cfg->domain, size);
6688 return mono_domain_code_reserve (mono_domain_get (), size);
6693 emitted_cb (LLVMValueRef function, void *start, void *end)
6697 cfg = mono_native_tls_get_value (current_cfg_tls_id);
6699 cfg->code_len = (guint8*)end - (guint8*)start;
6703 exception_cb (void *data)
6706 MonoJitExceptionInfo *ei;
6707 guint32 ei_len, i, j, nested_len, nindex;
6708 gpointer *type_info;
6709 int this_reg, this_offset;
6711 cfg = mono_native_tls_get_value (current_cfg_tls_id);
6715 * data points to a DWARF FDE structure, convert it to our unwind format and
6717 * An alternative would be to save it directly, and modify our unwinder to work
6720 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);
6721 if (cfg->verbose_level > 1)
6722 mono_print_unwind_info (cfg->encoded_unwind_ops, cfg->encoded_unwind_ops_len);
6724 /* Count nested clauses */
6726 for (i = 0; i < ei_len; ++i) {
6727 gint32 cindex1 = *(gint32*)type_info [i];
6728 MonoExceptionClause *clause1 = &cfg->header->clauses [cindex1];
6730 for (j = 0; j < cfg->header->num_clauses; ++j) {
6732 MonoExceptionClause *clause2 = &cfg->header->clauses [cindex2];
6734 if (cindex1 != cindex2 && clause1->try_offset >= clause2->try_offset && clause1->handler_offset <= clause2->handler_offset) {
6740 cfg->llvm_ex_info = mono_mempool_alloc0 (cfg->mempool, (ei_len + nested_len) * sizeof (MonoJitExceptionInfo));
6741 cfg->llvm_ex_info_len = ei_len + nested_len;
6742 memcpy (cfg->llvm_ex_info, ei, ei_len * sizeof (MonoJitExceptionInfo));
6743 /* Fill the rest of the information from the type info */
6744 for (i = 0; i < ei_len; ++i) {
6745 gint32 clause_index = *(gint32*)type_info [i];
6746 MonoExceptionClause *clause = &cfg->header->clauses [clause_index];
6748 cfg->llvm_ex_info [i].flags = clause->flags;
6749 cfg->llvm_ex_info [i].data.catch_class = clause->data.catch_class;
6750 cfg->llvm_ex_info [i].clause_index = clause_index;
6754 * For nested clauses, the LLVM produced exception info associates the try interval with
6755 * the innermost handler, while mono expects it to be associated with all nesting clauses.
6756 * So add new clauses which use the IL info (catch class etc.) from the nesting clause,
6757 * and everything else from the nested clause.
6760 for (i = 0; i < ei_len; ++i) {
6761 gint32 cindex1 = *(gint32*)type_info [i];
6762 MonoExceptionClause *clause1 = &cfg->header->clauses [cindex1];
6764 for (j = 0; j < cfg->header->num_clauses; ++j) {
6766 MonoExceptionClause *clause2 = &cfg->header->clauses [cindex2];
6767 MonoJitExceptionInfo *nesting_ei, *nested_ei;
6769 if (cindex1 != cindex2 && clause1->try_offset >= clause2->try_offset && clause1->handler_offset <= clause2->handler_offset) {
6770 /* clause1 is the nested clause */
6771 nested_ei = &cfg->llvm_ex_info [i];
6772 nesting_ei = &cfg->llvm_ex_info [nindex];
6775 memcpy (nesting_ei, nested_ei, sizeof (MonoJitExceptionInfo));
6777 nesting_ei->flags = clause2->flags;
6778 nesting_ei->data.catch_class = clause2->data.catch_class;
6779 nesting_ei->clause_index = cindex2;
6783 g_assert (nindex == ei_len + nested_len);
6784 cfg->llvm_this_reg = this_reg;
6785 cfg->llvm_this_offset = this_offset;
6787 /* type_info [i] is cfg mempool allocated, no need to free it */
6794 dlsym_cb (const char *name, void **symbol)
6800 if (!strcmp (name, "__bzero")) {
6801 *symbol = (void*)bzero;
6803 current = mono_dl_open (NULL, 0, NULL);
6806 err = mono_dl_symbol (current, name, symbol);
6808 mono_dl_close (current);
6810 #ifdef MONO_ARCH_HAVE_CREATE_LLVM_NATIVE_THUNK
6811 *symbol = (char*)mono_arch_create_llvm_native_thunk (mono_domain_get (), (guint8*)(*symbol));
6817 AddFunc (LLVMModuleRef module, const char *name, LLVMTypeRef ret_type, LLVMTypeRef *param_types, int nparams)
6819 LLVMAddFunction (module, name, LLVMFunctionType (ret_type, param_types, nparams, FALSE));
6823 AddFunc2 (LLVMModuleRef module, const char *name, LLVMTypeRef ret_type, LLVMTypeRef param_type1, LLVMTypeRef param_type2)
6825 LLVMTypeRef param_types [4];
6827 param_types [0] = param_type1;
6828 param_types [1] = param_type2;
6830 AddFunc (module, name, ret_type, param_types, 2);
6834 add_intrinsics (LLVMModuleRef module)
6836 /* Emit declarations of instrinsics */
6838 * It would be nicer to emit only the intrinsics actually used, but LLVM's Module
6839 * type doesn't seem to do any locking.
6842 LLVMTypeRef params [] = { LLVMPointerType (LLVMInt8Type (), 0), LLVMInt8Type (), LLVMInt32Type (), LLVMInt32Type (), LLVMInt1Type () };
6844 memset_param_count = 5;
6845 memset_func_name = "llvm.memset.p0i8.i32";
6847 AddFunc (module, memset_func_name, LLVMVoidType (), params, memset_param_count);
6851 LLVMTypeRef params [] = { LLVMPointerType (LLVMInt8Type (), 0), LLVMPointerType (LLVMInt8Type (), 0), LLVMInt32Type (), LLVMInt32Type (), LLVMInt1Type () };
6853 memcpy_param_count = 5;
6854 memcpy_func_name = "llvm.memcpy.p0i8.p0i8.i32";
6856 AddFunc (module, memcpy_func_name, LLVMVoidType (), params, memcpy_param_count);
6860 LLVMTypeRef params [] = { LLVMDoubleType () };
6862 AddFunc (module, "llvm.sin.f64", LLVMDoubleType (), params, 1);
6863 AddFunc (module, "llvm.cos.f64", LLVMDoubleType (), params, 1);
6864 AddFunc (module, "llvm.sqrt.f64", LLVMDoubleType (), params, 1);
6866 /* This isn't an intrinsic, instead llvm seems to special case it by name */
6867 AddFunc (module, "fabs", LLVMDoubleType (), params, 1);
6871 LLVMTypeRef ovf_res_i32 [] = { LLVMInt32Type (), LLVMInt1Type () };
6872 LLVMTypeRef params [] = { LLVMInt32Type (), LLVMInt32Type () };
6873 LLVMTypeRef ret_type = LLVMStructType (ovf_res_i32, 2, FALSE);
6875 AddFunc (module, "llvm.sadd.with.overflow.i32", ret_type, params, 2);
6876 AddFunc (module, "llvm.sadd.with.overflow.i32", ret_type, params, 2);
6877 AddFunc (module, "llvm.uadd.with.overflow.i32", ret_type, params, 2);
6878 AddFunc (module, "llvm.ssub.with.overflow.i32", ret_type, params, 2);
6879 AddFunc (module, "llvm.usub.with.overflow.i32", ret_type, params, 2);
6880 AddFunc (module, "llvm.smul.with.overflow.i32", ret_type, params, 2);
6881 AddFunc (module, "llvm.umul.with.overflow.i32", ret_type, params, 2);
6885 LLVMTypeRef ovf_res_i64 [] = { LLVMInt64Type (), LLVMInt1Type () };
6886 LLVMTypeRef params [] = { LLVMInt64Type (), LLVMInt64Type () };
6887 LLVMTypeRef ret_type = LLVMStructType (ovf_res_i64, 2, FALSE);
6889 AddFunc (module, "llvm.sadd.with.overflow.i64", ret_type, params, 2);
6890 AddFunc (module, "llvm.uadd.with.overflow.i64", ret_type, params, 2);
6891 AddFunc (module, "llvm.ssub.with.overflow.i64", ret_type, params, 2);
6892 AddFunc (module, "llvm.usub.with.overflow.i64", ret_type, params, 2);
6893 AddFunc (module, "llvm.smul.with.overflow.i64", ret_type, params, 2);
6894 AddFunc (module, "llvm.umul.with.overflow.i64", ret_type, params, 2);
6897 AddFunc2 (module, "llvm.expect.i8", LLVMInt8Type (), LLVMInt8Type (), LLVMInt8Type ());
6901 AddFunc (module, "mono_personality", LLVMVoidType (), NULL, 0);
6903 AddFunc (module, "llvm_resume_unwind_trampoline", LLVMVoidType (), NULL, 0);
6906 /* SSE intrinsics */
6907 #if defined(TARGET_X86) || defined(TARGET_AMD64)
6909 LLVMTypeRef ret_type, arg_types [16];
6912 ret_type = type_to_simd_type (MONO_TYPE_I4);
6913 arg_types [0] = ret_type;
6914 arg_types [1] = ret_type;
6915 AddFunc (module, "llvm.x86.sse41.pminud", ret_type, arg_types, 2);
6916 AddFunc (module, "llvm.x86.sse41.pmaxud", ret_type, arg_types, 2);
6918 ret_type = type_to_simd_type (MONO_TYPE_I2);
6919 arg_types [0] = ret_type;
6920 arg_types [1] = ret_type;
6921 AddFunc (module, "llvm.x86.sse41.pminuw", ret_type, arg_types, 2);
6922 AddFunc (module, "llvm.x86.sse2.pmins.w", ret_type, arg_types, 2);
6923 AddFunc (module, "llvm.x86.sse41.pmaxuw", ret_type, arg_types, 2);
6924 AddFunc (module, "llvm.x86.sse2.padds.w", ret_type, arg_types, 2);
6925 AddFunc (module, "llvm.x86.sse2.psubs.w", ret_type, arg_types, 2);
6926 AddFunc (module, "llvm.x86.sse2.paddus.w", ret_type, arg_types, 2);
6927 AddFunc (module, "llvm.x86.sse2.psubus.w", ret_type, arg_types, 2);
6928 AddFunc (module, "llvm.x86.sse2.pavg.w", ret_type, arg_types, 2);
6929 AddFunc (module, "llvm.x86.sse2.pmulh.w", ret_type, arg_types, 2);
6930 AddFunc (module, "llvm.x86.sse2.pmulhu.w", ret_type, arg_types, 2);
6932 ret_type = type_to_simd_type (MONO_TYPE_I1);
6933 arg_types [0] = ret_type;
6934 arg_types [1] = ret_type;
6935 AddFunc (module, "llvm.x86.sse2.pminu.b", ret_type, arg_types, 2);
6936 AddFunc (module, "llvm.x86.sse2.pmaxu.b", ret_type, arg_types, 2);
6937 AddFunc (module, "llvm.x86.sse2.padds.b", ret_type, arg_types, 2);
6938 AddFunc (module, "llvm.x86.sse2.psubs.b", ret_type, arg_types, 2);
6939 AddFunc (module, "llvm.x86.sse2.paddus.b", ret_type, arg_types, 2);
6940 AddFunc (module, "llvm.x86.sse2.psubus.b", ret_type, arg_types, 2);
6941 AddFunc (module, "llvm.x86.sse2.pavg.b", ret_type, arg_types, 2);
6943 ret_type = type_to_simd_type (MONO_TYPE_R8);
6944 arg_types [0] = ret_type;
6945 arg_types [1] = ret_type;
6946 AddFunc (module, "llvm.x86.sse2.min.pd", ret_type, arg_types, 2);
6947 AddFunc (module, "llvm.x86.sse2.max.pd", ret_type, arg_types, 2);
6948 AddFunc (module, "llvm.x86.sse3.hadd.pd", ret_type, arg_types, 2);
6949 AddFunc (module, "llvm.x86.sse3.hsub.pd", ret_type, arg_types, 2);
6950 AddFunc (module, "llvm.x86.sse3.addsub.pd", ret_type, arg_types, 2);
6952 ret_type = type_to_simd_type (MONO_TYPE_R4);
6953 arg_types [0] = ret_type;
6954 arg_types [1] = ret_type;
6955 AddFunc (module, "llvm.x86.sse.min.ps", ret_type, arg_types, 2);
6956 AddFunc (module, "llvm.x86.sse.max.ps", ret_type, arg_types, 2);
6957 AddFunc (module, "llvm.x86.sse3.hadd.ps", ret_type, arg_types, 2);
6958 AddFunc (module, "llvm.x86.sse3.hsub.ps", ret_type, arg_types, 2);
6959 AddFunc (module, "llvm.x86.sse3.addsub.ps", ret_type, arg_types, 2);
6962 ret_type = type_to_simd_type (MONO_TYPE_I1);
6963 arg_types [0] = type_to_simd_type (MONO_TYPE_I2);
6964 arg_types [1] = type_to_simd_type (MONO_TYPE_I2);
6965 AddFunc (module, "llvm.x86.sse2.packsswb.128", ret_type, arg_types, 2);
6966 AddFunc (module, "llvm.x86.sse2.packuswb.128", ret_type, arg_types, 2);
6967 ret_type = type_to_simd_type (MONO_TYPE_I2);
6968 arg_types [0] = type_to_simd_type (MONO_TYPE_I4);
6969 arg_types [1] = type_to_simd_type (MONO_TYPE_I4);
6970 AddFunc (module, "llvm.x86.sse2.packssdw.128", ret_type, arg_types, 2);
6971 AddFunc (module, "llvm.x86.sse41.packusdw", ret_type, arg_types, 2);
6974 ret_type = type_to_simd_type (MONO_TYPE_R8);
6975 arg_types [0] = ret_type;
6976 arg_types [1] = ret_type;
6977 arg_types [2] = LLVMInt8Type ();
6978 AddFunc (module, "llvm.x86.sse2.cmp.pd", ret_type, arg_types, 3);
6979 ret_type = type_to_simd_type (MONO_TYPE_R4);
6980 arg_types [0] = ret_type;
6981 arg_types [1] = ret_type;
6982 arg_types [2] = LLVMInt8Type ();
6983 AddFunc (module, "llvm.x86.sse.cmp.ps", ret_type, arg_types, 3);
6985 /* Conversion ops */
6986 ret_type = type_to_simd_type (MONO_TYPE_R8);
6987 arg_types [0] = type_to_simd_type (MONO_TYPE_I4);
6988 AddFunc (module, "llvm.x86.sse2.cvtdq2pd", ret_type, arg_types, 1);
6989 ret_type = type_to_simd_type (MONO_TYPE_R4);
6990 arg_types [0] = type_to_simd_type (MONO_TYPE_I4);
6991 AddFunc (module, "llvm.x86.sse2.cvtdq2ps", ret_type, arg_types, 1);
6992 ret_type = type_to_simd_type (MONO_TYPE_I4);
6993 arg_types [0] = type_to_simd_type (MONO_TYPE_R8);
6994 AddFunc (module, "llvm.x86.sse2.cvtpd2dq", ret_type, arg_types, 1);
6995 ret_type = type_to_simd_type (MONO_TYPE_I4);
6996 arg_types [0] = type_to_simd_type (MONO_TYPE_R4);
6997 AddFunc (module, "llvm.x86.sse2.cvtps2dq", ret_type, arg_types, 1);
6998 ret_type = type_to_simd_type (MONO_TYPE_R4);
6999 arg_types [0] = type_to_simd_type (MONO_TYPE_R8);
7000 AddFunc (module, "llvm.x86.sse2.cvtpd2ps", ret_type, arg_types, 1);
7001 ret_type = type_to_simd_type (MONO_TYPE_R8);
7002 arg_types [0] = type_to_simd_type (MONO_TYPE_R4);
7003 AddFunc (module, "llvm.x86.sse2.cvtps2pd", ret_type, arg_types, 1);
7005 ret_type = type_to_simd_type (MONO_TYPE_I4);
7006 arg_types [0] = type_to_simd_type (MONO_TYPE_R8);
7007 AddFunc (module, "llvm.x86.sse2.cvttpd2dq", ret_type, arg_types, 1);
7008 ret_type = type_to_simd_type (MONO_TYPE_I4);
7009 arg_types [0] = type_to_simd_type (MONO_TYPE_R4);
7010 AddFunc (module, "llvm.x86.sse2.cvttps2dq", ret_type, arg_types, 1);
7013 ret_type = type_to_simd_type (MONO_TYPE_R8);
7014 arg_types [0] = ret_type;
7015 AddFunc (module, "llvm.x86.sse2.sqrt.pd", ret_type, arg_types, 1);
7016 ret_type = type_to_simd_type (MONO_TYPE_R4);
7017 arg_types [0] = ret_type;
7018 AddFunc (module, "llvm.x86.sse.sqrt.ps", ret_type, arg_types, 1);
7019 ret_type = type_to_simd_type (MONO_TYPE_R4);
7020 arg_types [0] = ret_type;
7021 AddFunc (module, "llvm.x86.sse.rsqrt.ps", ret_type, arg_types, 1);
7022 ret_type = type_to_simd_type (MONO_TYPE_R4);
7023 arg_types [0] = ret_type;
7024 AddFunc (module, "llvm.x86.sse.rcp.ps", ret_type, arg_types, 1);
7027 ret_type = type_to_simd_type (MONO_TYPE_I2);
7028 arg_types [0] = ret_type;
7029 arg_types [1] = LLVMInt32Type ();
7030 AddFunc (module, "llvm.x86.sse2.psrli.w", ret_type, arg_types, 2);
7031 AddFunc (module, "llvm.x86.sse2.psrai.w", ret_type, arg_types, 2);
7032 AddFunc (module, "llvm.x86.sse2.pslli.w", ret_type, arg_types, 2);
7033 ret_type = type_to_simd_type (MONO_TYPE_I4);
7034 arg_types [0] = ret_type;
7035 arg_types [1] = LLVMInt32Type ();
7036 AddFunc (module, "llvm.x86.sse2.psrli.d", ret_type, arg_types, 2);
7037 AddFunc (module, "llvm.x86.sse2.psrai.d", ret_type, arg_types, 2);
7038 AddFunc (module, "llvm.x86.sse2.pslli.d", ret_type, arg_types, 2);
7039 ret_type = type_to_simd_type (MONO_TYPE_I8);
7040 arg_types [0] = ret_type;
7041 arg_types [1] = LLVMInt32Type ();
7042 AddFunc (module, "llvm.x86.sse2.psrli.q", ret_type, arg_types, 2);
7043 AddFunc (module, "llvm.x86.sse2.pslli.q", ret_type, arg_types, 2);
7046 ret_type = LLVMInt32Type ();
7047 arg_types [0] = type_to_simd_type (MONO_TYPE_I1);
7048 AddFunc (module, "llvm.x86.sse2.pmovmskb.128", ret_type, arg_types, 1);
7051 AddFunc (module, "llvm.x86.sse2.pause", LLVMVoidType (), NULL, 0);
7054 /* Load/Store intrinsics */
7056 LLVMTypeRef arg_types [5];
7060 for (i = 1; i <= 8; i *= 2) {
7061 arg_types [0] = LLVMPointerType (LLVMIntType (i * 8), 0);
7062 arg_types [1] = LLVMInt32Type ();
7063 arg_types [2] = LLVMInt1Type ();
7064 arg_types [3] = LLVMInt32Type ();
7065 sprintf (name, "llvm.mono.load.i%d.p0i%d", i * 8, i * 8);
7066 AddFunc (module, name, LLVMIntType (i * 8), arg_types, 4);
7068 arg_types [0] = LLVMIntType (i * 8);
7069 arg_types [1] = LLVMPointerType (LLVMIntType (i * 8), 0);
7070 arg_types [2] = LLVMInt32Type ();
7071 arg_types [3] = LLVMInt1Type ();
7072 arg_types [4] = LLVMInt32Type ();
7073 sprintf (name, "llvm.mono.store.i%d.p0i%d", i * 8, i * 8);
7074 AddFunc (module, name, LLVMVoidType (), arg_types, 5);
7080 add_types (MonoLLVMModule *module)
7082 module->ptr_type = LLVMPointerType (sizeof (gpointer) == 8 ? LLVMInt64Type () : LLVMInt32Type (), 0);
7086 mono_llvm_init (void)
7088 mono_native_tls_alloc (¤t_cfg_tls_id, NULL);
7092 init_jit_module (MonoDomain *domain)
7094 MonoJitICallInfo *info;
7095 MonoJitDomainInfo *dinfo;
7096 MonoLLVMModule *module;
7099 dinfo = domain_jit_info (domain);
7100 if (dinfo->llvm_module)
7103 mono_loader_lock ();
7105 if (dinfo->llvm_module) {
7106 mono_loader_unlock ();
7110 module = g_new0 (MonoLLVMModule, 1);
7112 name = g_strdup_printf ("mono-%s", domain->friendly_name);
7113 module->lmodule = LLVMModuleCreateWithName (name);
7114 module->context = LLVMGetGlobalContext ();
7116 module->mono_ee = mono_llvm_create_ee (LLVMCreateModuleProviderForExistingModule (module->lmodule), alloc_cb, emitted_cb, exception_cb, dlsym_cb, &module->ee);
7118 add_intrinsics (module->lmodule);
7121 module->llvm_types = g_hash_table_new (NULL, NULL);
7123 info = mono_find_jit_icall_by_name ("llvm_resume_unwind_trampoline");
7125 LLVMAddGlobalMapping (module->ee, LLVMGetNamedFunction (module->lmodule, "llvm_resume_unwind_trampoline"), (void*)info->func);
7127 mono_memory_barrier ();
7129 dinfo->llvm_module = module;
7131 mono_loader_unlock ();
7135 mono_llvm_cleanup (void)
7137 MonoLLVMModule *module = &aot_module;
7139 if (module->lmodule)
7140 LLVMDisposeModule (module->lmodule);
7142 if (module->context)
7143 LLVMContextDispose (module->context);
7147 mono_llvm_free_domain_info (MonoDomain *domain)
7149 MonoJitDomainInfo *info = domain_jit_info (domain);
7150 MonoLLVMModule *module = info->llvm_module;
7156 if (module->llvm_types)
7157 g_hash_table_destroy (module->llvm_types);
7159 mono_llvm_dispose_ee (module->mono_ee);
7161 if (module->bb_names) {
7162 for (i = 0; i < module->bb_names_len; ++i)
7163 g_free (module->bb_names [i]);
7164 g_free (module->bb_names);
7166 //LLVMDisposeModule (module->module);
7170 info->llvm_module = NULL;
7174 mono_llvm_create_aot_module (MonoAssembly *assembly, const char *global_prefix, gboolean emit_dwarf, gboolean static_link, gboolean llvm_only)
7176 MonoLLVMModule *module = &aot_module;
7178 /* Delete previous module */
7179 if (module->plt_entries)
7180 g_hash_table_destroy (module->plt_entries);
7181 if (module->lmodule)
7182 LLVMDisposeModule (module->lmodule);
7184 memset (module, 0, sizeof (aot_module));
7186 module->lmodule = LLVMModuleCreateWithName ("aot");
7187 module->assembly = assembly;
7188 module->global_prefix = g_strdup (global_prefix);
7189 module->got_symbol = g_strdup_printf ("%s_llvm_got", global_prefix);
7190 module->eh_frame_symbol = g_strdup_printf ("%s_eh_frame", global_prefix);
7191 module->get_method_symbol = g_strdup_printf ("%s_get_method", global_prefix);
7192 module->get_unbox_tramp_symbol = g_strdup_printf ("%s_get_unbox_tramp", global_prefix);
7193 module->external_symbols = TRUE;
7194 module->emit_dwarf = emit_dwarf;
7195 module->static_link = static_link;
7196 module->llvm_only = llvm_only;
7197 /* The first few entries are reserved */
7198 module->max_got_offset = 16;
7199 module->context = LLVMContextCreate ();
7201 add_intrinsics (module->lmodule);
7206 * We couldn't compute the type of the LLVM global representing the got because
7207 * its size is only known after all the methods have been emitted. So create
7208 * a dummy variable, and replace all uses it with the real got variable when
7209 * its size is known in mono_llvm_emit_aot_module ().
7212 LLVMTypeRef got_type = LLVMArrayType (module->ptr_type, 0);
7214 module->got_var = LLVMAddGlobal (module->lmodule, got_type, "mono_dummy_got");
7215 LLVMSetInitializer (module->got_var, LLVMConstNull (got_type));
7218 /* Add initialization array */
7220 LLVMTypeRef inited_type = LLVMArrayType (LLVMInt8Type (), 0);
7222 module->inited_var = LLVMAddGlobal (aot_module.lmodule, inited_type, "mono_inited_tmp");
7223 LLVMSetInitializer (module->inited_var, LLVMConstNull (inited_type));
7227 emit_init_icall_wrappers (module);
7229 emit_llvm_code_start (module);
7231 /* Add a dummy personality function */
7232 if (!use_debug_personality) {
7233 LLVMValueRef personality = LLVMAddFunction (module->lmodule, default_personality_name, LLVMFunctionType (LLVMInt32Type (), NULL, 0, TRUE));
7234 LLVMSetLinkage (personality, LLVMExternalLinkage);
7235 mark_as_used (module, personality);
7238 /* Add a reference to the c++ exception we throw/catch */
7240 LLVMTypeRef exc = LLVMPointerType (LLVMInt8Type (), 0);
7241 module->sentinel_exception = LLVMAddGlobal (module->lmodule, exc, "_ZTIPi");
7242 LLVMSetLinkage (module->sentinel_exception, LLVMExternalLinkage);
7243 mono_llvm_set_is_constant (module->sentinel_exception);
7246 module->llvm_types = g_hash_table_new (NULL, NULL);
7247 module->plt_entries = g_hash_table_new (g_str_hash, g_str_equal);
7248 module->plt_entries_ji = g_hash_table_new (NULL, NULL);
7249 module->direct_callables = g_hash_table_new (g_str_hash, g_str_equal);
7250 module->method_to_lmethod = g_hash_table_new (NULL, NULL);
7251 module->idx_to_lmethod = g_hash_table_new (NULL, NULL);
7252 module->idx_to_unbox_tramp = g_hash_table_new (NULL, NULL);
7253 module->method_to_callers = g_hash_table_new (NULL, NULL);
7257 llvm_array_from_uints (LLVMTypeRef el_type, guint32 *values, int nvalues)
7260 LLVMValueRef res, *vals;
7262 vals = g_new0 (LLVMValueRef, nvalues);
7263 for (i = 0; i < nvalues; ++i)
7264 vals [i] = LLVMConstInt (LLVMInt32Type (), values [i], FALSE);
7265 res = LLVMConstArray (LLVMInt32Type (), vals, nvalues);
7271 * mono_llvm_emit_aot_file_info:
7273 * Emit the MonoAotFileInfo structure.
7274 * Same as emit_aot_file_info () in aot-compiler.c.
7277 mono_llvm_emit_aot_file_info (MonoAotFileInfo *info, gboolean has_jitted_code)
7279 MonoLLVMModule *module = &aot_module;
7281 /* Save these for later */
7282 memcpy (&module->aot_info, info, sizeof (MonoAotFileInfo));
7283 module->has_jitted_code = has_jitted_code;
7287 * mono_llvm_emit_aot_data:
7289 * Emit the binary data DATA pointed to by symbol SYMBOL.
7292 mono_llvm_emit_aot_data (const char *symbol, guint8 *data, int data_len)
7294 MonoLLVMModule *module = &aot_module;
7298 type = LLVMArrayType (LLVMInt8Type (), data_len);
7299 d = LLVMAddGlobal (module->lmodule, type, symbol);
7300 LLVMSetVisibility (d, LLVMHiddenVisibility);
7301 LLVMSetLinkage (d, LLVMInternalLinkage);
7302 LLVMSetInitializer (d, mono_llvm_create_constant_data_array (data, data_len));
7303 mono_llvm_set_is_constant (d);
7306 /* Add a reference to a global defined in JITted code */
7308 AddJitGlobal (MonoLLVMModule *module, LLVMTypeRef type, const char *name)
7313 s = g_strdup_printf ("%s%s", module->global_prefix, name);
7314 v = LLVMAddGlobal (module->lmodule, LLVMInt8Type (), s);
7320 emit_aot_file_info (MonoLLVMModule *module)
7322 LLVMTypeRef file_info_type;
7323 LLVMTypeRef *eltypes, eltype;
7324 LLVMValueRef info_var;
7325 LLVMValueRef *fields;
7326 int i, nfields, tindex;
7327 MonoAotFileInfo *info;
7328 LLVMModuleRef lmodule = module->lmodule;
7330 info = &module->aot_info;
7332 /* Create an LLVM type to represent MonoAotFileInfo */
7333 nfields = 2 + MONO_AOT_FILE_INFO_NUM_SYMBOLS + 14 + 4;
7334 eltypes = g_new (LLVMTypeRef, nfields);
7336 eltypes [tindex ++] = LLVMInt32Type ();
7337 eltypes [tindex ++] = LLVMInt32Type ();
7339 for (i = 0; i < MONO_AOT_FILE_INFO_NUM_SYMBOLS; ++i)
7340 eltypes [tindex ++] = LLVMPointerType (LLVMInt8Type (), 0);
7342 for (i = 0; i < 14; ++i)
7343 eltypes [tindex ++] = LLVMInt32Type ();
7345 for (i = 0; i < 4; ++i)
7346 eltypes [tindex ++] = LLVMArrayType (LLVMInt32Type (), MONO_AOT_TRAMP_NUM);
7347 g_assert (tindex == nfields);
7348 file_info_type = LLVMStructCreateNamed (module->context, "MonoAotFileInfo");
7349 LLVMStructSetBody (file_info_type, eltypes, nfields, FALSE);
7351 info_var = LLVMAddGlobal (lmodule, file_info_type, "mono_aot_file_info");
7352 if (module->static_link) {
7353 LLVMSetVisibility (info_var, LLVMHiddenVisibility);
7354 LLVMSetLinkage (info_var, LLVMInternalLinkage);
7356 fields = g_new (LLVMValueRef, nfields);
7358 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->version, FALSE);
7359 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->dummy, FALSE);
7363 * We use LLVMGetNamedGlobal () for symbol which are defined in LLVM code, and LLVMAddGlobal ()
7364 * for symbols defined in the .s file emitted by the aot compiler.
7366 eltype = eltypes [tindex];
7367 if (module->llvm_only)
7368 fields [tindex ++] = LLVMConstNull (eltype);
7370 fields [tindex ++] = AddJitGlobal (module, eltype, "jit_got");
7371 fields [tindex ++] = module->got_var;
7372 /* llc defines this directly */
7373 if (!module->llvm_only) {
7374 fields [tindex ++] = LLVMAddGlobal (lmodule, eltype, module->eh_frame_symbol);
7375 fields [tindex ++] = LLVMConstNull (eltype);
7376 fields [tindex ++] = LLVMConstNull (eltype);
7378 fields [tindex ++] = LLVMConstNull (eltype);
7379 fields [tindex ++] = module->get_method;
7380 fields [tindex ++] = module->get_unbox_tramp;
7382 if (module->has_jitted_code) {
7383 fields [tindex ++] = AddJitGlobal (module, eltype, "jit_code_start");
7384 fields [tindex ++] = AddJitGlobal (module, eltype, "jit_code_end");
7386 fields [tindex ++] = LLVMConstNull (eltype);
7387 fields [tindex ++] = LLVMConstNull (eltype);
7389 if (!module->llvm_only)
7390 fields [tindex ++] = AddJitGlobal (module, eltype, "method_addresses");
7392 fields [tindex ++] = LLVMConstNull (eltype);
7393 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "blob");
7394 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "class_name_table");
7395 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "class_info_offsets");
7396 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "method_info_offsets");
7397 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "ex_info_offsets");
7398 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "extra_method_info_offsets");
7399 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "extra_method_table");
7400 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "got_info_offsets");
7401 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "llvm_got_info_offsets");
7402 /* Not needed (mem_end) */
7403 fields [tindex ++] = LLVMConstNull (eltype);
7404 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "image_table");
7405 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "assembly_guid");
7406 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "runtime_version");
7407 if (info->trampoline_size [0]) {
7408 fields [tindex ++] = AddJitGlobal (module, eltype, "specific_trampolines");
7409 fields [tindex ++] = AddJitGlobal (module, eltype, "static_rgctx_trampolines");
7410 fields [tindex ++] = AddJitGlobal (module, eltype, "imt_thunks");
7411 fields [tindex ++] = AddJitGlobal (module, eltype, "gsharedvt_arg_trampolines");
7413 fields [tindex ++] = LLVMConstNull (eltype);
7414 fields [tindex ++] = LLVMConstNull (eltype);
7415 fields [tindex ++] = LLVMConstNull (eltype);
7416 fields [tindex ++] = LLVMConstNull (eltype);
7418 if (module->static_link)
7419 fields [tindex ++] = AddJitGlobal (module, eltype, "globals");
7421 fields [tindex ++] = LLVMConstNull (eltype);
7422 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "assembly_name");
7423 if (!module->llvm_only) {
7424 fields [tindex ++] = AddJitGlobal (module, eltype, "plt");
7425 fields [tindex ++] = AddJitGlobal (module, eltype, "plt_end");
7426 fields [tindex ++] = AddJitGlobal (module, eltype, "unwind_info");
7427 fields [tindex ++] = AddJitGlobal (module, eltype, "unbox_trampolines");
7428 fields [tindex ++] = AddJitGlobal (module, eltype, "unbox_trampolines_end");
7429 fields [tindex ++] = AddJitGlobal (module, eltype, "unbox_trampoline_addresses");
7431 fields [tindex ++] = LLVMConstNull (eltype);
7432 fields [tindex ++] = LLVMConstNull (eltype);
7433 fields [tindex ++] = LLVMConstNull (eltype);
7434 fields [tindex ++] = LLVMConstNull (eltype);
7435 fields [tindex ++] = LLVMConstNull (eltype);
7436 fields [tindex ++] = LLVMConstNull (eltype);
7439 for (i = 0; i < MONO_AOT_FILE_INFO_NUM_SYMBOLS; ++i)
7440 fields [2 + i] = LLVMConstBitCast (fields [2 + i], eltype);
7443 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->plt_got_offset_base, FALSE);
7444 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->got_size, FALSE);
7445 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->plt_size, FALSE);
7446 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->nmethods, FALSE);
7447 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->flags, FALSE);
7448 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->opts, FALSE);
7449 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->simd_opts, FALSE);
7450 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->gc_name_index, FALSE);
7451 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->num_rgctx_fetch_trampolines, FALSE);
7452 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->double_align, FALSE);
7453 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->long_align, FALSE);
7454 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->generic_tramp_num, FALSE);
7455 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->tramp_page_size, FALSE);
7456 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->nshared_got_entries, FALSE);
7458 fields [tindex ++] = llvm_array_from_uints (LLVMInt32Type (), info->num_trampolines, MONO_AOT_TRAMP_NUM);
7459 fields [tindex ++] = llvm_array_from_uints (LLVMInt32Type (), info->trampoline_got_offset_base, MONO_AOT_TRAMP_NUM);
7460 fields [tindex ++] = llvm_array_from_uints (LLVMInt32Type (), info->trampoline_size, MONO_AOT_TRAMP_NUM);
7461 fields [tindex ++] = llvm_array_from_uints (LLVMInt32Type (), info->tramp_page_code_offsets, MONO_AOT_TRAMP_NUM);
7462 g_assert (tindex == nfields);
7464 LLVMSetInitializer (info_var, LLVMConstNamedStruct (file_info_type, fields, nfields));
7466 if (module->static_link) {
7470 s = g_strdup_printf ("mono_aot_module_%s_info", module->assembly->aname.name);
7471 /* Get rid of characters which cannot occur in symbols */
7473 for (p = s; *p; ++p) {
7474 if (!(isalnum (*p) || *p == '_'))
7477 var = LLVMAddGlobal (module->lmodule, LLVMPointerType (LLVMInt8Type (), 0), s);
7479 LLVMSetInitializer (var, LLVMConstBitCast (LLVMGetNamedGlobal (module->lmodule, "mono_aot_file_info"), LLVMPointerType (LLVMInt8Type (), 0)));
7480 LLVMSetLinkage (var, LLVMExternalLinkage);
7485 * Emit the aot module into the LLVM bitcode file FILENAME.
7488 mono_llvm_emit_aot_module (const char *filename, const char *cu_name)
7490 LLVMTypeRef got_type, inited_type;
7491 LLVMValueRef real_got, real_inited;
7492 MonoLLVMModule *module = &aot_module;
7494 emit_llvm_code_end (module);
7497 * Create the real got variable and replace all uses of the dummy variable with
7500 got_type = LLVMArrayType (module->ptr_type, module->max_got_offset + 1);
7501 real_got = LLVMAddGlobal (module->lmodule, got_type, module->got_symbol);
7502 LLVMSetInitializer (real_got, LLVMConstNull (got_type));
7503 if (module->external_symbols) {
7504 LLVMSetLinkage (real_got, LLVMExternalLinkage);
7505 LLVMSetVisibility (real_got, LLVMHiddenVisibility);
7507 LLVMSetLinkage (real_got, LLVMInternalLinkage);
7509 mono_llvm_replace_uses_of (module->got_var, real_got);
7511 mark_as_used (&aot_module, real_got);
7513 /* Delete the dummy got so it doesn't become a global */
7514 LLVMDeleteGlobal (module->got_var);
7515 module->got_var = real_got;
7518 * Same for the init_var
7520 if (module->llvm_only) {
7521 inited_type = LLVMArrayType (LLVMInt8Type (), module->max_inited_idx + 1);
7522 real_inited = LLVMAddGlobal (module->lmodule, inited_type, "mono_inited");
7523 LLVMSetInitializer (real_inited, LLVMConstNull (inited_type));
7524 LLVMSetLinkage (real_inited, LLVMInternalLinkage);
7525 mono_llvm_replace_uses_of (module->inited_var, real_inited);
7526 LLVMDeleteGlobal (module->inited_var);
7529 if (module->llvm_only) {
7530 emit_get_method (&aot_module);
7531 emit_get_unbox_tramp (&aot_module);
7534 emit_llvm_used (&aot_module);
7535 emit_dbg_info (&aot_module, filename, cu_name);
7536 emit_aot_file_info (&aot_module);
7539 * Replace GOT entries for directly callable methods with the methods themselves.
7540 * It would be easier to implement this by predefining all methods before compiling
7541 * their bodies, but that couldn't handle the case when a method fails to compile
7544 if (module->llvm_only) {
7545 GHashTableIter iter;
7547 GSList *callers, *l;
7549 g_hash_table_iter_init (&iter, module->method_to_callers);
7550 while (g_hash_table_iter_next (&iter, (void**)&method, (void**)&callers)) {
7551 LLVMValueRef lmethod;
7553 lmethod = g_hash_table_lookup (module->method_to_lmethod, method);
7555 for (l = callers; l; l = l->next) {
7556 LLVMValueRef caller = l->data;
7558 mono_llvm_replace_uses_of (caller, lmethod);
7564 /* Replace PLT entries for directly callable methods with the methods themselves */
7566 GHashTableIter iter;
7568 LLVMValueRef callee;
7570 g_hash_table_iter_init (&iter, module->plt_entries_ji);
7571 while (g_hash_table_iter_next (&iter, (void**)&ji, (void**)&callee)) {
7572 if (mono_aot_is_direct_callable (ji)) {
7573 LLVMValueRef lmethod;
7575 lmethod = g_hash_table_lookup (module->method_to_lmethod, ji->data.method);
7576 /* The types might not match because the caller might pass an rgctx */
7577 if (lmethod && LLVMTypeOf (callee) == LLVMTypeOf (lmethod)) {
7578 mono_llvm_replace_uses_of (callee, lmethod);
7579 mono_aot_mark_unused_llvm_plt_entry (ji);
7589 if (LLVMVerifyModule (module->module, LLVMReturnStatusAction, &verifier_err)) {
7590 g_assert_not_reached ();
7595 LLVMWriteBitcodeToFile (module->lmodule, filename);
7600 md_string (const char *s)
7602 return LLVMMDString (s, strlen (s));
7605 /* Debugging support */
7608 emit_dbg_info (MonoLLVMModule *module, const char *filename, const char *cu_name)
7610 LLVMModuleRef lmodule = module->lmodule;
7611 LLVMValueRef args [16], cu_args [16], cu, ver;
7613 char *build_info, *s, *dir;
7616 * This can only be enabled when LLVM code is emitted into a separate object
7617 * file, since the AOT compiler also emits dwarf info,
7618 * and the abbrev indexes will not be correct since llvm has added its own
7621 if (!module->emit_dwarf)
7625 * Emit dwarf info in the form of LLVM metadata. There is some
7626 * out-of-date documentation at:
7627 * http://llvm.org/docs/SourceLevelDebugging.html
7628 * but most of this was gathered from the llvm and
7633 cu_args [n_cuargs ++] = LLVMConstInt (LLVMInt32Type (), DW_TAG_compile_unit, FALSE);
7634 /* CU name/compilation dir */
7635 dir = g_path_get_dirname (filename);
7636 args [0] = LLVMMDString (cu_name, strlen (cu_name));
7637 args [1] = LLVMMDString (dir, strlen (dir));
7638 cu_args [n_cuargs ++] = LLVMMDNode (args, 2);
7641 cu_args [n_cuargs ++] = LLVMConstInt (LLVMInt32Type (), DW_LANG_C99, FALSE);
7643 build_info = mono_get_runtime_build_info ();
7644 s = g_strdup_printf ("Mono AOT Compiler %s (LLVM)", build_info);
7645 cu_args [n_cuargs ++] = LLVMMDString (s, strlen (s));
7646 g_free (build_info);
7648 cu_args [n_cuargs ++] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
7650 cu_args [n_cuargs ++] = LLVMMDString ("", strlen (""));
7651 /* Runtime version */
7652 cu_args [n_cuargs ++] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
7654 cu_args [n_cuargs ++] = LLVMMDNode (args, 0);
7655 cu_args [n_cuargs ++] = LLVMMDNode (args, 0);
7657 if (module->subprogram_mds) {
7661 mds = g_new0 (LLVMValueRef, module->subprogram_mds->len);
7662 for (i = 0; i < module->subprogram_mds->len; ++i)
7663 mds [i] = g_ptr_array_index (module->subprogram_mds, i);
7664 cu_args [n_cuargs ++] = LLVMMDNode (mds, module->subprogram_mds->len);
7666 cu_args [n_cuargs ++] = LLVMMDNode (args, 0);
7669 cu_args [n_cuargs ++] = LLVMMDNode (args, 0);
7670 /* Imported modules */
7671 cu_args [n_cuargs ++] = LLVMMDNode (args, 0);
7673 cu_args [n_cuargs ++] = LLVMMDString ("", strlen (""));
7674 /* DebugEmissionKind = FullDebug */
7675 cu_args [n_cuargs ++] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
7676 cu = LLVMMDNode (cu_args, n_cuargs);
7677 LLVMAddNamedMetadataOperand (lmodule, "llvm.dbg.cu", cu);
7679 args [0] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
7680 args [1] = LLVMMDString ("Dwarf Version", strlen ("Dwarf Version"));
7681 args [2] = LLVMConstInt (LLVMInt32Type (), 2, FALSE);
7682 ver = LLVMMDNode (args, 3);
7683 LLVMAddNamedMetadataOperand (lmodule, "llvm.module.flags", ver);
7685 args [0] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
7686 args [1] = LLVMMDString ("Debug Info Version", strlen ("Debug Info Version"));
7687 args [2] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
7688 ver = LLVMMDNode (args, 3);
7689 LLVMAddNamedMetadataOperand (lmodule, "llvm.module.flags", ver);
7693 emit_dbg_subprogram (EmitContext *ctx, MonoCompile *cfg, LLVMValueRef method, const char *name)
7695 MonoLLVMModule *module = ctx->module;
7696 MonoDebugMethodInfo *minfo = ctx->minfo;
7697 char *source_file, *dir, *filename;
7698 LLVMValueRef md, args [16], ctx_args [16], md_args [64], type_args [16], ctx_md, type_md;
7699 MonoSymSeqPoint *sym_seq_points;
7705 mono_debug_symfile_get_seq_points (minfo, &source_file, NULL, NULL, &sym_seq_points, &n_seq_points);
7707 source_file = g_strdup ("<unknown>");
7708 dir = g_path_get_dirname (source_file);
7709 filename = g_path_get_basename (source_file);
7711 ctx_args [0] = LLVMConstInt (LLVMInt32Type (), 0x29, FALSE);
7712 args [0] = md_string (filename);
7713 args [1] = md_string (dir);
7714 ctx_args [1] = LLVMMDNode (args, 2);
7715 ctx_md = LLVMMDNode (ctx_args, 2);
7717 type_args [0] = LLVMConstInt (LLVMInt32Type (), DW_TAG_subroutine_type, FALSE);
7718 type_args [1] = NULL;
7719 type_args [2] = NULL;
7720 type_args [3] = LLVMMDString ("", 0);
7721 type_args [4] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
7722 type_args [5] = LLVMConstInt (LLVMInt64Type (), 0, FALSE);
7723 type_args [6] = LLVMConstInt (LLVMInt64Type (), 0, FALSE);
7724 type_args [7] = LLVMConstInt (LLVMInt64Type (), 0, FALSE);
7725 type_args [8] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
7726 type_args [9] = NULL;
7727 type_args [10] = NULL;
7728 type_args [11] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
7729 type_args [12] = NULL;
7730 type_args [13] = NULL;
7731 type_args [14] = NULL;
7732 type_md = LLVMMDNode (type_args, 14);
7734 /* http://llvm.org/docs/SourceLevelDebugging.html#subprogram-descriptors */
7735 md_args [0] = LLVMConstInt (LLVMInt32Type (), DW_TAG_subprogram, FALSE);
7736 /* Source directory + file pair */
7737 args [0] = md_string (filename);
7738 args [1] = md_string (dir);
7739 md_args [1] = LLVMMDNode (args ,2);
7740 md_args [2] = ctx_md;
7741 md_args [3] = md_string (cfg->method->name);
7742 md_args [4] = md_string (name);
7743 md_args [5] = md_string (name);
7746 md_args [6] = LLVMConstInt (LLVMInt32Type (), sym_seq_points [0].line, FALSE);
7748 md_args [6] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
7750 md_args [7] = type_md;
7752 md_args [8] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
7754 md_args [9] = LLVMConstInt (LLVMInt1Type (), 1, FALSE);
7756 md_args [10] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
7757 /* Index into a virtual function */
7758 md_args [11] = NULL;
7759 md_args [12] = NULL;
7761 md_args [13] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
7763 md_args [14] = LLVMConstInt (LLVMInt1Type (), 1, FALSE);
7764 /* Pointer to LLVM function */
7765 md_args [15] = method;
7766 /* Function template parameter */
7767 md_args [16] = NULL;
7768 /* Function declaration descriptor */
7769 md_args [17] = NULL;
7770 /* List of function variables */
7771 md_args [18] = LLVMMDNode (args, 0);
7773 md_args [19] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
7774 md = LLVMMDNode (md_args, 20);
7776 if (!module->subprogram_mds)
7777 module->subprogram_mds = g_ptr_array_new ();
7778 g_ptr_array_add (module->subprogram_mds, md);
7782 g_free (source_file);
7783 g_free (sym_seq_points);
7789 emit_dbg_loc (EmitContext *ctx, LLVMBuilderRef builder, const unsigned char *cil_code)
7791 MonoCompile *cfg = ctx->cfg;
7793 if (ctx->minfo && cil_code && cil_code >= cfg->header->code && cil_code < cfg->header->code + cfg->header->code_size) {
7794 MonoDebugSourceLocation *loc;
7795 LLVMValueRef loc_md, md_args [16];
7798 loc = mono_debug_symfile_lookup_location (ctx->minfo, cil_code - cfg->header->code);
7802 md_args [nmd_args ++] = LLVMConstInt (LLVMInt32Type (), loc->row, FALSE);
7803 md_args [nmd_args ++] = LLVMConstInt (LLVMInt32Type (), loc->column, FALSE);
7804 md_args [nmd_args ++] = ctx->dbg_md;
7805 md_args [nmd_args ++] = NULL;
7806 loc_md = LLVMMDNode (md_args, nmd_args);
7807 LLVMSetCurrentDebugLocation (builder, loc_md);
7808 mono_debug_symfile_free_location (loc);
7814 default_mono_llvm_unhandled_exception (void)
7816 MonoJitTlsData *jit_tls = mono_get_jit_tls ();
7817 MonoObject *target = mono_gchandle_get_target (jit_tls->thrown_exc);
7819 mono_unhandled_exception (target);
7820 exit (mono_environment_exitcode_get ());
7825 - Emit LLVM IR from the mono IR using the LLVM C API.
7826 - The original arch specific code remains, so we can fall back to it if we run
7827 into something we can't handle.
7831 A partial list of issues:
7832 - Handling of opcodes which can throw exceptions.
7834 In the mono JIT, these are implemented using code like this:
7841 push throw_pos - method
7842 call <exception trampoline>
7844 The problematic part is push throw_pos - method, which cannot be represented
7845 in the LLVM IR, since it does not support label values.
7846 -> this can be implemented in AOT mode using inline asm + labels, but cannot
7847 be implemented in JIT mode ?
7848 -> a possible but slower implementation would use the normal exception
7849 throwing code but it would need to control the placement of the throw code
7850 (it needs to be exactly after the compare+branch).
7851 -> perhaps add a PC offset intrinsics ?
7853 - efficient implementation of .ovf opcodes.
7855 These are currently implemented as:
7856 <ins which sets the condition codes>
7859 Some overflow opcodes are now supported by LLVM SVN.
7861 - exception handling, unwinding.
7862 - SSA is disabled for methods with exception handlers
7863 - How to obtain unwind info for LLVM compiled methods ?
7864 -> this is now solved by converting the unwind info generated by LLVM
7866 - LLVM uses the c++ exception handling framework, while we use our home grown
7867 code, and couldn't use the c++ one:
7868 - its not supported under VC++, other exotic platforms.
7869 - it might be impossible to support filter clauses with it.
7873 The trampolines need a predictable call sequence, since they need to disasm
7874 the calling code to obtain register numbers / offsets.
7876 LLVM currently generates this code in non-JIT mode:
7877 mov -0x98(%rax),%eax
7879 Here, the vtable pointer is lost.
7880 -> solution: use one vtable trampoline per class.
7882 - passing/receiving the IMT pointer/RGCTX.
7883 -> solution: pass them as normal arguments ?
7887 LLVM does not allow the specification of argument registers etc. This means
7888 that all calls are made according to the platform ABI.
7890 - passing/receiving vtypes.
7892 Vtypes passed/received in registers are handled by the front end by using
7893 a signature with scalar arguments, and loading the parts of the vtype into those
7896 Vtypes passed on the stack are handled using the 'byval' attribute.
7900 Supported though alloca, we need to emit the load/store code.
7904 The mono JIT uses pointer sized iregs/double fregs, while LLVM uses precisely
7905 typed registers, so we have to keep track of the precise LLVM type of each vreg.
7906 This is made easier because the IR is already in SSA form.
7907 An additional problem is that our IR is not consistent with types, i.e. i32/ia64
7908 types are frequently used incorrectly.
7913 Emit LLVM bytecode into a .bc file, compile it using llc into a .s file, then link
7914 it with the file containing the methods emitted by the JIT and the AOT data
7918 /* FIXME: Normalize some aspects of the mono IR to allow easier translation, like:
7919 * - each bblock should end with a branch
7920 * - setting the return value, making cfg->ret non-volatile
7921 * - avoid some transformations in the JIT which make it harder for us to generate
7923 * - use pointer types to help optimizations.