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/metadata/abi-details.h>
15 #include <mono/utils/mono-tls.h>
16 #include <mono/utils/mono-dl.h>
17 #include <mono/utils/mono-time.h>
18 #include <mono/utils/freebsd-dwarf.h>
20 #ifndef __STDC_LIMIT_MACROS
21 #define __STDC_LIMIT_MACROS
23 #ifndef __STDC_CONSTANT_MACROS
24 #define __STDC_CONSTANT_MACROS
27 #include "llvm-c/BitWriter.h"
28 #include "llvm-c/Analysis.h"
30 #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."
47 #define ALIGN_PTR_TO(ptr,align) (gpointer)((((gssize)(ptr)) + (align - 1)) & (~(align - 1)))
50 * Information associated by mono with LLVM modules.
53 LLVMModuleRef lmodule;
54 LLVMValueRef throw_icall, rethrow, match_exc, throw_corlib_exception, resume_eh;
55 GHashTable *llvm_types;
57 const char *got_symbol;
58 const char *get_method_symbol;
59 const char *get_unbox_tramp_symbol;
60 GHashTable *plt_entries;
61 GHashTable *plt_entries_ji;
62 GHashTable *method_to_lmethod;
63 GHashTable *direct_callables;
68 GPtrArray *subprogram_mds;
70 LLVMExecutionEngineRef ee;
71 gboolean external_symbols;
76 MonoAssembly *assembly;
78 MonoAotFileInfo aot_info;
79 const char *jit_got_symbol;
80 const char *eh_frame_symbol;
81 LLVMValueRef get_method, get_unbox_tramp;
82 LLVMValueRef init_method, init_method_gshared_mrgctx, init_method_gshared_this, init_method_gshared_vtable;
83 LLVMValueRef code_start, code_end;
84 LLVMValueRef inited_var;
85 int max_inited_idx, max_method_idx;
86 gboolean has_jitted_code;
89 GHashTable *idx_to_lmethod;
90 GHashTable *idx_to_unbox_tramp;
91 /* Maps a MonoMethod to LLVM instructions representing it */
92 GHashTable *method_to_callers;
93 LLVMContextRef context;
94 LLVMValueRef sentinel_exception;
95 void *di_builder, *cu;
99 * Information associated by the backend with mono basic blocks.
102 LLVMBasicBlockRef bblock, end_bblock;
103 LLVMValueRef finally_ind;
104 gboolean added, invoke_target;
106 * If this bblock is the start of a finally clause, this is a list of bblocks it
107 * needs to branch to in ENDFINALLY.
109 GSList *call_handler_return_bbs;
111 * If this bblock is the start of a finally clause, this is the bblock that
112 * CALL_HANDLER needs to branch to.
114 LLVMBasicBlockRef call_handler_target_bb;
115 /* The list of switch statements generated by ENDFINALLY instructions */
116 GSList *endfinally_switch_ins_list;
121 * Structure containing emit state
124 MonoMemPool *mempool;
126 /* Maps method names to the corresponding LLVMValueRef */
127 GHashTable *emitted_method_decls;
130 LLVMValueRef lmethod;
131 MonoLLVMModule *module;
132 LLVMModuleRef lmodule;
134 int sindex, default_index, ex_index;
135 LLVMBuilderRef builder;
136 LLVMValueRef *values, *addresses;
137 MonoType **vreg_cli_types;
139 MonoMethodSignature *sig;
141 GHashTable *region_to_handler;
142 GHashTable *clause_to_handler;
143 LLVMBuilderRef alloca_builder;
144 LLVMValueRef last_alloca;
145 LLVMValueRef rgctx_arg;
146 LLVMValueRef this_arg;
147 LLVMTypeRef *vreg_types;
148 LLVMTypeRef method_type;
149 LLVMBasicBlockRef init_bb, inited_bb;
151 gboolean *unreachable;
153 gboolean has_got_access;
154 gboolean is_linkonce;
155 int this_arg_pindex, rgctx_arg_pindex;
156 LLVMValueRef imt_rgctx_loc;
157 GHashTable *llvm_types;
159 MonoDebugMethodInfo *minfo;
161 /* For every clause, the clauses it is nested in */
164 GHashTable *exc_meta;
165 GHashTable *method_to_callers;
166 GPtrArray *phi_values;
167 GPtrArray *bblock_list;
169 GHashTable *jit_callees;
175 MonoBasicBlock *in_bb;
180 * Instruction metadata
181 * This is the same as ins_info, but LREG != IREG.
189 #define MINI_OP(a,b,dest,src1,src2) dest, src1, src2, ' ',
190 #define MINI_OP3(a,b,dest,src1,src2,src3) dest, src1, src2, src3,
197 /* keep in sync with the enum in mini.h */
200 #include "mini-ops.h"
205 #if SIZEOF_VOID_P == 4
206 #define GET_LONG_IMM(ins) (((guint64)(ins)->inst_ms_word << 32) | (guint64)(guint32)(ins)->inst_ls_word)
208 #define GET_LONG_IMM(ins) ((ins)->inst_imm)
211 #define LLVM_INS_INFO(opcode) (&llvm_ins_info [((opcode) - OP_START - 1) * 4])
214 #define TRACE_FAILURE(msg) do { printf ("%s\n", msg); } while (0)
216 #define TRACE_FAILURE(msg)
220 #define IS_TARGET_X86 1
222 #define IS_TARGET_X86 0
226 #define IS_TARGET_AMD64 1
228 #define IS_TARGET_AMD64 0
231 #define ctx_ok(ctx) (!(ctx)->cfg->disable_llvm)
233 static LLVMIntPredicate cond_to_llvm_cond [] = {
246 static LLVMRealPredicate fpcond_to_llvm_cond [] = {
259 static MonoNativeTlsKey current_cfg_tls_id;
261 static MonoLLVMModule aot_module;
263 static GHashTable *intrins_id_to_name;
264 static GHashTable *intrins_name_to_id;
266 static void init_jit_module (MonoDomain *domain);
268 static void emit_dbg_loc (EmitContext *ctx, LLVMBuilderRef builder, const unsigned char *cil_code);
269 static LLVMValueRef emit_dbg_subprogram (EmitContext *ctx, MonoCompile *cfg, LLVMValueRef method, const char *name);
270 static void emit_dbg_info (MonoLLVMModule *module, const char *filename, const char *cu_name);
271 static void emit_cond_system_exception (EmitContext *ctx, MonoBasicBlock *bb, const char *exc_type, LLVMValueRef cmp);
272 static LLVMValueRef get_intrinsic (EmitContext *ctx, const char *name);
273 static void decode_llvm_eh_info (EmitContext *ctx, gpointer eh_frame);
276 set_failure (EmitContext *ctx, const char *message)
278 TRACE_FAILURE (reason);
279 ctx->cfg->exception_message = g_strdup (message);
280 ctx->cfg->disable_llvm = TRUE;
286 * The LLVM type with width == sizeof (gpointer)
291 return sizeof (gpointer) == 8 ? LLVMInt64Type () : LLVMInt32Type ();
297 return sizeof (gpointer) == 8 ? LLVMPointerType (LLVMInt64Type (), 0) : LLVMPointerType (LLVMInt32Type (), 0);
303 return sizeof (gpointer) == 8 ? LLVMPointerType (LLVMInt64Type (), 0) : LLVMPointerType (LLVMInt32Type (), 0);
309 * Return the size of the LLVM representation of the vtype T.
312 get_vtype_size (MonoType *t)
316 size = mono_class_value_size (mono_class_from_mono_type (t), NULL);
318 /* LLVMArgAsIArgs depends on this since it stores whole words */
319 while (size < 2 * sizeof (gpointer) && mono_is_power_of_two (size) == -1)
326 * simd_class_to_llvm_type:
328 * Return the LLVM type corresponding to the Mono.SIMD class KLASS
331 simd_class_to_llvm_type (EmitContext *ctx, MonoClass *klass)
333 if (!strcmp (klass->name, "Vector2d")) {
334 return LLVMVectorType (LLVMDoubleType (), 2);
335 } else if (!strcmp (klass->name, "Vector2l")) {
336 return LLVMVectorType (LLVMInt64Type (), 2);
337 } else if (!strcmp (klass->name, "Vector2ul")) {
338 return LLVMVectorType (LLVMInt64Type (), 2);
339 } else if (!strcmp (klass->name, "Vector4i")) {
340 return LLVMVectorType (LLVMInt32Type (), 4);
341 } else if (!strcmp (klass->name, "Vector4ui")) {
342 return LLVMVectorType (LLVMInt32Type (), 4);
343 } else if (!strcmp (klass->name, "Vector4f")) {
344 return LLVMVectorType (LLVMFloatType (), 4);
345 } else if (!strcmp (klass->name, "Vector8s")) {
346 return LLVMVectorType (LLVMInt16Type (), 8);
347 } else if (!strcmp (klass->name, "Vector8us")) {
348 return LLVMVectorType (LLVMInt16Type (), 8);
349 } else if (!strcmp (klass->name, "Vector16sb")) {
350 return LLVMVectorType (LLVMInt8Type (), 16);
351 } else if (!strcmp (klass->name, "Vector16b")) {
352 return LLVMVectorType (LLVMInt8Type (), 16);
354 printf ("%s\n", klass->name);
360 /* Return the 128 bit SIMD type corresponding to the mono type TYPE */
361 static inline G_GNUC_UNUSED LLVMTypeRef
362 type_to_simd_type (int type)
366 return LLVMVectorType (LLVMInt8Type (), 16);
368 return LLVMVectorType (LLVMInt16Type (), 8);
370 return LLVMVectorType (LLVMInt32Type (), 4);
372 return LLVMVectorType (LLVMInt64Type (), 2);
374 return LLVMVectorType (LLVMDoubleType (), 2);
376 return LLVMVectorType (LLVMFloatType (), 4);
378 g_assert_not_reached ();
384 create_llvm_type_for_type (MonoLLVMModule *module, MonoClass *klass)
386 int i, size, nfields, esize;
387 LLVMTypeRef *eltypes;
392 t = &klass->byval_arg;
394 if (mini_type_is_hfa (t, &nfields, &esize)) {
396 * This is needed on arm64 where HFAs are returned in
400 eltypes = g_new (LLVMTypeRef, size);
401 for (i = 0; i < size; ++i)
402 eltypes [i] = esize == 4 ? LLVMFloatType () : LLVMDoubleType ();
404 size = get_vtype_size (t);
406 eltypes = g_new (LLVMTypeRef, size);
407 for (i = 0; i < size; ++i)
408 eltypes [i] = LLVMInt8Type ();
411 name = mono_type_full_name (&klass->byval_arg);
412 ltype = LLVMStructCreateNamed (module->context, name);
413 LLVMStructSetBody (ltype, eltypes, size, FALSE);
423 * Return the LLVM type corresponding to T.
426 type_to_llvm_type (EmitContext *ctx, MonoType *t)
428 t = mini_get_underlying_type (t);
432 return LLVMVoidType ();
434 return LLVMInt8Type ();
436 return LLVMInt16Type ();
438 return LLVMInt32Type ();
440 return LLVMInt8Type ();
442 return LLVMInt16Type ();
444 return LLVMInt32Type ();
445 case MONO_TYPE_BOOLEAN:
446 return LLVMInt8Type ();
449 return LLVMInt64Type ();
451 return LLVMInt16Type ();
453 return LLVMFloatType ();
455 return LLVMDoubleType ();
458 return IntPtrType ();
459 case MONO_TYPE_OBJECT:
460 case MONO_TYPE_CLASS:
461 case MONO_TYPE_ARRAY:
462 case MONO_TYPE_SZARRAY:
463 case MONO_TYPE_STRING:
465 return ObjRefType ();
468 /* Because of generic sharing */
469 return ObjRefType ();
470 case MONO_TYPE_GENERICINST:
471 if (!mono_type_generic_inst_is_valuetype (t))
472 return ObjRefType ();
474 case MONO_TYPE_VALUETYPE:
475 case MONO_TYPE_TYPEDBYREF: {
479 klass = mono_class_from_mono_type (t);
481 if (MONO_CLASS_IS_SIMD (ctx->cfg, klass))
482 return simd_class_to_llvm_type (ctx, klass);
485 return type_to_llvm_type (ctx, mono_class_enum_basetype (klass));
487 ltype = (LLVMTypeRef)g_hash_table_lookup (ctx->module->llvm_types, klass);
489 ltype = create_llvm_type_for_type (ctx->module, klass);
490 g_hash_table_insert (ctx->module->llvm_types, klass, ltype);
496 printf ("X: %d\n", t->type);
497 ctx->cfg->exception_message = g_strdup_printf ("type %s", mono_type_full_name (t));
498 ctx->cfg->disable_llvm = TRUE;
506 * Return whenever T is an unsigned int type.
509 type_is_unsigned (EmitContext *ctx, MonoType *t)
511 t = mini_get_underlying_type (t);
527 * type_to_llvm_arg_type:
529 * Same as type_to_llvm_type, but treat i8/i16 as i32.
532 type_to_llvm_arg_type (EmitContext *ctx, MonoType *t)
534 LLVMTypeRef ptype = type_to_llvm_type (ctx, t);
536 if (ctx->cfg->llvm_only)
540 * This works on all abis except arm64/ios which passes multiple
541 * arguments in one stack slot.
544 if (ptype == LLVMInt8Type () || ptype == LLVMInt16Type ()) {
546 * LLVM generates code which only sets the lower bits, while JITted
547 * code expects all the bits to be set.
549 ptype = LLVMInt32Type ();
557 * llvm_type_to_stack_type:
559 * Return the LLVM type which needs to be used when a value of type TYPE is pushed
562 static G_GNUC_UNUSED LLVMTypeRef
563 llvm_type_to_stack_type (MonoCompile *cfg, LLVMTypeRef type)
567 if (type == LLVMInt8Type ())
568 return LLVMInt32Type ();
569 else if (type == LLVMInt16Type ())
570 return LLVMInt32Type ();
571 else if (!cfg->r4fp && type == LLVMFloatType ())
572 return LLVMDoubleType ();
578 * regtype_to_llvm_type:
580 * Return the LLVM type corresponding to the regtype C used in instruction
584 regtype_to_llvm_type (char c)
588 return LLVMInt32Type ();
590 return LLVMInt64Type ();
592 return LLVMDoubleType ();
601 * Return the LLVM type corresponding to the unary/binary opcode OPCODE.
604 op_to_llvm_type (int opcode)
609 return LLVMInt8Type ();
612 return LLVMInt8Type ();
615 return LLVMInt16Type ();
618 return LLVMInt16Type ();
621 return LLVMInt32Type ();
624 return LLVMInt32Type ();
626 return LLVMInt64Type ();
628 return LLVMFloatType ();
630 return LLVMDoubleType ();
632 return LLVMInt64Type ();
634 return LLVMInt32Type ();
636 return LLVMInt64Type ();
641 return LLVMInt8Type ();
646 return LLVMInt16Type ();
648 return LLVMInt32Type ();
651 return sizeof (gpointer) == 8 ? LLVMInt64Type () : LLVMInt32Type ();
658 return LLVMInt32Type ();
665 return LLVMInt64Type ();
667 printf ("%s\n", mono_inst_name (opcode));
668 g_assert_not_reached ();
673 #define CLAUSE_START(clause) ((clause)->try_offset)
674 #define CLAUSE_END(clause) (((clause))->try_offset + ((clause))->try_len)
677 * load_store_to_llvm_type:
679 * Return the size/sign/zero extension corresponding to the load/store opcode
683 load_store_to_llvm_type (int opcode, int *size, gboolean *sext, gboolean *zext)
689 case OP_LOADI1_MEMBASE:
690 case OP_STOREI1_MEMBASE_REG:
691 case OP_STOREI1_MEMBASE_IMM:
692 case OP_ATOMIC_LOAD_I1:
693 case OP_ATOMIC_STORE_I1:
696 return LLVMInt8Type ();
697 case OP_LOADU1_MEMBASE:
699 case OP_ATOMIC_LOAD_U1:
700 case OP_ATOMIC_STORE_U1:
703 return LLVMInt8Type ();
704 case OP_LOADI2_MEMBASE:
705 case OP_STOREI2_MEMBASE_REG:
706 case OP_STOREI2_MEMBASE_IMM:
707 case OP_ATOMIC_LOAD_I2:
708 case OP_ATOMIC_STORE_I2:
711 return LLVMInt16Type ();
712 case OP_LOADU2_MEMBASE:
714 case OP_ATOMIC_LOAD_U2:
715 case OP_ATOMIC_STORE_U2:
718 return LLVMInt16Type ();
719 case OP_LOADI4_MEMBASE:
720 case OP_LOADU4_MEMBASE:
723 case OP_STOREI4_MEMBASE_REG:
724 case OP_STOREI4_MEMBASE_IMM:
725 case OP_ATOMIC_LOAD_I4:
726 case OP_ATOMIC_STORE_I4:
727 case OP_ATOMIC_LOAD_U4:
728 case OP_ATOMIC_STORE_U4:
730 return LLVMInt32Type ();
731 case OP_LOADI8_MEMBASE:
733 case OP_STOREI8_MEMBASE_REG:
734 case OP_STOREI8_MEMBASE_IMM:
735 case OP_ATOMIC_LOAD_I8:
736 case OP_ATOMIC_STORE_I8:
737 case OP_ATOMIC_LOAD_U8:
738 case OP_ATOMIC_STORE_U8:
740 return LLVMInt64Type ();
741 case OP_LOADR4_MEMBASE:
742 case OP_STORER4_MEMBASE_REG:
743 case OP_ATOMIC_LOAD_R4:
744 case OP_ATOMIC_STORE_R4:
746 return LLVMFloatType ();
747 case OP_LOADR8_MEMBASE:
748 case OP_STORER8_MEMBASE_REG:
749 case OP_ATOMIC_LOAD_R8:
750 case OP_ATOMIC_STORE_R8:
752 return LLVMDoubleType ();
753 case OP_LOAD_MEMBASE:
755 case OP_STORE_MEMBASE_REG:
756 case OP_STORE_MEMBASE_IMM:
757 *size = sizeof (gpointer);
758 return IntPtrType ();
760 g_assert_not_reached ();
768 * Return the LLVM intrinsics corresponding to the overflow opcode OPCODE.
771 ovf_op_to_intrins (int opcode)
775 return "llvm.sadd.with.overflow.i32";
777 return "llvm.uadd.with.overflow.i32";
779 return "llvm.ssub.with.overflow.i32";
781 return "llvm.usub.with.overflow.i32";
783 return "llvm.smul.with.overflow.i32";
785 return "llvm.umul.with.overflow.i32";
787 return "llvm.sadd.with.overflow.i64";
789 return "llvm.uadd.with.overflow.i64";
791 return "llvm.ssub.with.overflow.i64";
793 return "llvm.usub.with.overflow.i64";
795 return "llvm.smul.with.overflow.i64";
797 return "llvm.umul.with.overflow.i64";
799 g_assert_not_reached ();
805 simd_op_to_intrins (int opcode)
808 #if defined(TARGET_X86) || defined(TARGET_AMD64)
810 return "llvm.x86.sse2.min.pd";
812 return "llvm.x86.sse.min.ps";
814 return "llvm.x86.sse41.pminud";
816 return "llvm.x86.sse41.pminuw";
818 return "llvm.x86.sse2.pminu.b";
820 return "llvm.x86.sse2.pmins.w";
822 return "llvm.x86.sse2.max.pd";
824 return "llvm.x86.sse.max.ps";
826 return "llvm.x86.sse3.hadd.pd";
828 return "llvm.x86.sse3.hadd.ps";
830 return "llvm.x86.sse3.hsub.pd";
832 return "llvm.x86.sse3.hsub.ps";
834 return "llvm.x86.sse41.pmaxud";
836 return "llvm.x86.sse41.pmaxuw";
838 return "llvm.x86.sse2.pmaxu.b";
840 return "llvm.x86.sse3.addsub.ps";
842 return "llvm.x86.sse3.addsub.pd";
843 case OP_EXTRACT_MASK:
844 return "llvm.x86.sse2.pmovmskb.128";
847 return "llvm.x86.sse2.psrli.w";
850 return "llvm.x86.sse2.psrli.d";
853 return "llvm.x86.sse2.psrli.q";
856 return "llvm.x86.sse2.pslli.w";
859 return "llvm.x86.sse2.pslli.d";
862 return "llvm.x86.sse2.pslli.q";
865 return "llvm.x86.sse2.psrai.w";
868 return "llvm.x86.sse2.psrai.d";
870 return "llvm.x86.sse2.padds.b";
872 return "llvm.x86.sse2.padds.w";
874 return "llvm.x86.sse2.psubs.b";
876 return "llvm.x86.sse2.psubs.w";
877 case OP_PADDB_SAT_UN:
878 return "llvm.x86.sse2.paddus.b";
879 case OP_PADDW_SAT_UN:
880 return "llvm.x86.sse2.paddus.w";
881 case OP_PSUBB_SAT_UN:
882 return "llvm.x86.sse2.psubus.b";
883 case OP_PSUBW_SAT_UN:
884 return "llvm.x86.sse2.psubus.w";
886 return "llvm.x86.sse2.pavg.b";
888 return "llvm.x86.sse2.pavg.w";
890 return "llvm.x86.sse.sqrt.ps";
892 return "llvm.x86.sse2.sqrt.pd";
894 return "llvm.x86.sse.rsqrt.ps";
896 return "llvm.x86.sse.rcp.ps";
898 return "llvm.x86.sse2.cvtdq2pd";
900 return "llvm.x86.sse2.cvtdq2ps";
902 return "llvm.x86.sse2.cvtpd2dq";
904 return "llvm.x86.sse2.cvtps2dq";
906 return "llvm.x86.sse2.cvtpd2ps";
908 return "llvm.x86.sse2.cvtps2pd";
910 return "llvm.x86.sse2.cvttpd2dq";
912 return "llvm.x86.sse2.cvttps2dq";
914 return "llvm.x86.sse.cmp.ps";
916 return "llvm.x86.sse2.cmp.pd";
918 return "llvm.x86.sse2.packsswb.128";
920 return "llvm.x86.sse2.packssdw.128";
922 return "llvm.x86.sse2.packuswb.128";
924 return "llvm.x86.sse41.packusdw";
926 return "llvm.x86.sse2.pmulh.w";
927 case OP_PMULW_HIGH_UN:
928 return "llvm.x86.sse2.pmulhu.w";
931 g_assert_not_reached ();
937 simd_op_to_llvm_type (int opcode)
939 #if defined(TARGET_X86) || defined(TARGET_AMD64)
943 return type_to_simd_type (MONO_TYPE_R8);
946 return type_to_simd_type (MONO_TYPE_I8);
949 return type_to_simd_type (MONO_TYPE_I4);
954 return type_to_simd_type (MONO_TYPE_I2);
958 return type_to_simd_type (MONO_TYPE_I1);
960 return type_to_simd_type (MONO_TYPE_R4);
963 return type_to_simd_type (MONO_TYPE_I4);
967 return type_to_simd_type (MONO_TYPE_R8);
971 return type_to_simd_type (MONO_TYPE_R4);
972 case OP_EXTRACT_MASK:
973 return type_to_simd_type (MONO_TYPE_I1);
979 return type_to_simd_type (MONO_TYPE_R4);
982 return type_to_simd_type (MONO_TYPE_R8);
984 g_assert_not_reached ();
995 * Return the LLVM basic block corresponding to BB.
997 static LLVMBasicBlockRef
998 get_bb (EmitContext *ctx, MonoBasicBlock *bb)
1000 char bb_name_buf [128];
1003 if (ctx->bblocks [bb->block_num].bblock == NULL) {
1004 if (bb->flags & BB_EXCEPTION_HANDLER) {
1005 int clause_index = (mono_get_block_region_notry (ctx->cfg, bb->region) >> 8) - 1;
1006 sprintf (bb_name_buf, "EH_CLAUSE%d_BB%d", clause_index, bb->block_num);
1007 bb_name = bb_name_buf;
1008 } else if (bb->block_num < 256) {
1009 if (!ctx->module->bb_names) {
1010 ctx->module->bb_names_len = 256;
1011 ctx->module->bb_names = g_new0 (char*, ctx->module->bb_names_len);
1013 if (!ctx->module->bb_names [bb->block_num]) {
1016 n = g_strdup_printf ("BB%d", bb->block_num);
1017 mono_memory_barrier ();
1018 ctx->module->bb_names [bb->block_num] = n;
1020 bb_name = ctx->module->bb_names [bb->block_num];
1022 sprintf (bb_name_buf, "BB%d", bb->block_num);
1023 bb_name = bb_name_buf;
1026 ctx->bblocks [bb->block_num].bblock = LLVMAppendBasicBlock (ctx->lmethod, bb_name);
1027 ctx->bblocks [bb->block_num].end_bblock = ctx->bblocks [bb->block_num].bblock;
1030 return ctx->bblocks [bb->block_num].bblock;
1036 * Return the last LLVM bblock corresponding to BB.
1037 * This might not be equal to the bb returned by get_bb () since we need to generate
1038 * multiple LLVM bblocks for a mono bblock to handle throwing exceptions.
1040 static LLVMBasicBlockRef
1041 get_end_bb (EmitContext *ctx, MonoBasicBlock *bb)
1044 return ctx->bblocks [bb->block_num].end_bblock;
1047 static LLVMBasicBlockRef
1048 gen_bb (EmitContext *ctx, const char *prefix)
1052 sprintf (bb_name, "%s%d", prefix, ++ ctx->ex_index);
1053 return LLVMAppendBasicBlock (ctx->lmethod, bb_name);
1059 * Return the target of the patch identified by TYPE and TARGET.
1062 resolve_patch (MonoCompile *cfg, MonoJumpInfoType type, gconstpointer target)
1068 memset (&ji, 0, sizeof (ji));
1070 ji.data.target = target;
1072 res = mono_resolve_patch_target (cfg->method, cfg->domain, NULL, &ji, FALSE, &error);
1073 mono_error_assert_ok (&error);
1081 * Emit code to convert the LLVM value V to DTYPE.
1084 convert_full (EmitContext *ctx, LLVMValueRef v, LLVMTypeRef dtype, gboolean is_unsigned)
1086 LLVMTypeRef stype = LLVMTypeOf (v);
1088 if (stype != dtype) {
1089 gboolean ext = FALSE;
1092 if (dtype == LLVMInt64Type () && (stype == LLVMInt32Type () || stype == LLVMInt16Type () || stype == LLVMInt8Type ()))
1094 else if (dtype == LLVMInt32Type () && (stype == LLVMInt16Type () || stype == LLVMInt8Type ()))
1096 else if (dtype == LLVMInt16Type () && (stype == LLVMInt8Type ()))
1100 return is_unsigned ? LLVMBuildZExt (ctx->builder, v, dtype, "") : LLVMBuildSExt (ctx->builder, v, dtype, "");
1102 if (dtype == LLVMDoubleType () && stype == LLVMFloatType ())
1103 return LLVMBuildFPExt (ctx->builder, v, dtype, "");
1106 if (stype == LLVMInt64Type () && (dtype == LLVMInt32Type () || dtype == LLVMInt16Type () || dtype == LLVMInt8Type ()))
1107 return LLVMBuildTrunc (ctx->builder, v, dtype, "");
1108 if (stype == LLVMInt32Type () && (dtype == LLVMInt16Type () || dtype == LLVMInt8Type ()))
1109 return LLVMBuildTrunc (ctx->builder, v, dtype, "");
1110 if (stype == LLVMInt16Type () && dtype == LLVMInt8Type ())
1111 return LLVMBuildTrunc (ctx->builder, v, dtype, "");
1112 if (stype == LLVMDoubleType () && dtype == LLVMFloatType ())
1113 return LLVMBuildFPTrunc (ctx->builder, v, dtype, "");
1115 if (LLVMGetTypeKind (stype) == LLVMPointerTypeKind && LLVMGetTypeKind (dtype) == LLVMPointerTypeKind)
1116 return LLVMBuildBitCast (ctx->builder, v, dtype, "");
1117 if (LLVMGetTypeKind (dtype) == LLVMPointerTypeKind)
1118 return LLVMBuildIntToPtr (ctx->builder, v, dtype, "");
1119 if (LLVMGetTypeKind (stype) == LLVMPointerTypeKind)
1120 return LLVMBuildPtrToInt (ctx->builder, v, dtype, "");
1122 if (mono_arch_is_soft_float ()) {
1123 if (stype == LLVMInt32Type () && dtype == LLVMFloatType ())
1124 return LLVMBuildBitCast (ctx->builder, v, dtype, "");
1125 if (stype == LLVMInt32Type () && dtype == LLVMDoubleType ())
1126 return LLVMBuildBitCast (ctx->builder, LLVMBuildZExt (ctx->builder, v, LLVMInt64Type (), ""), dtype, "");
1129 if (LLVMGetTypeKind (stype) == LLVMVectorTypeKind && LLVMGetTypeKind (dtype) == LLVMVectorTypeKind)
1130 return LLVMBuildBitCast (ctx->builder, v, dtype, "");
1133 LLVMDumpValue (LLVMConstNull (dtype));
1134 g_assert_not_reached ();
1142 convert (EmitContext *ctx, LLVMValueRef v, LLVMTypeRef dtype)
1144 return convert_full (ctx, v, dtype, FALSE);
1148 * emit_volatile_load:
1150 * If vreg is volatile, emit a load from its address.
1153 emit_volatile_load (EmitContext *ctx, int vreg)
1157 LLVMValueRef v = LLVMBuildLoad (ctx->builder, ctx->addresses [vreg], "");
1158 t = ctx->vreg_cli_types [vreg];
1159 if (t && !t->byref) {
1161 * Might have to zero extend since llvm doesn't have
1164 if (t->type == MONO_TYPE_U1 || t->type == MONO_TYPE_U2 || t->type == MONO_TYPE_CHAR || t->type == MONO_TYPE_BOOLEAN)
1165 v = LLVMBuildZExt (ctx->builder, v, LLVMInt32Type (), "");
1166 else if (t->type == MONO_TYPE_I1 || t->type == MONO_TYPE_I2)
1167 v = LLVMBuildSExt (ctx->builder, v, LLVMInt32Type (), "");
1168 else if (t->type == MONO_TYPE_U8)
1169 v = LLVMBuildZExt (ctx->builder, v, LLVMInt64Type (), "");
1176 * emit_volatile_store:
1178 * If VREG is volatile, emit a store from its value to its address.
1181 emit_volatile_store (EmitContext *ctx, int vreg)
1183 MonoInst *var = get_vreg_to_inst (ctx->cfg, vreg);
1185 if (var && var->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT)) {
1186 g_assert (ctx->addresses [vreg]);
1187 LLVMBuildStore (ctx->builder, convert (ctx, ctx->values [vreg], type_to_llvm_type (ctx, var->inst_vtype)), ctx->addresses [vreg]);
1192 sig_to_llvm_sig_no_cinfo (EmitContext *ctx, MonoMethodSignature *sig)
1194 LLVMTypeRef ret_type;
1195 LLVMTypeRef *param_types = NULL;
1200 rtype = mini_get_underlying_type (sig->ret);
1201 ret_type = type_to_llvm_type (ctx, rtype);
1205 param_types = g_new0 (LLVMTypeRef, (sig->param_count * 8) + 3);
1209 param_types [pindex ++] = ThisType ();
1210 for (i = 0; i < sig->param_count; ++i)
1211 param_types [pindex ++] = type_to_llvm_arg_type (ctx, sig->params [i]);
1213 if (!ctx_ok (ctx)) {
1214 g_free (param_types);
1218 res = LLVMFunctionType (ret_type, param_types, pindex, FALSE);
1219 g_free (param_types);
1225 * sig_to_llvm_sig_full:
1227 * Return the LLVM signature corresponding to the mono signature SIG using the
1228 * calling convention information in CINFO. Fill out the parameter mapping information in CINFO.
1231 sig_to_llvm_sig_full (EmitContext *ctx, MonoMethodSignature *sig, LLVMCallInfo *cinfo)
1233 LLVMTypeRef ret_type;
1234 LLVMTypeRef *param_types = NULL;
1236 int i, j, pindex, vret_arg_pindex = 0;
1237 gboolean vretaddr = FALSE;
1241 return sig_to_llvm_sig_no_cinfo (ctx, sig);
1243 rtype = mini_get_underlying_type (sig->ret);
1244 ret_type = type_to_llvm_type (ctx, rtype);
1248 switch (cinfo->ret.storage) {
1249 case LLVMArgVtypeInReg:
1250 /* LLVM models this by returning an aggregate value */
1251 if (cinfo->ret.pair_storage [0] == LLVMArgInIReg && cinfo->ret.pair_storage [1] == LLVMArgNone) {
1252 LLVMTypeRef members [2];
1254 members [0] = IntPtrType ();
1255 ret_type = LLVMStructType (members, 1, FALSE);
1256 } else if (cinfo->ret.pair_storage [0] == LLVMArgNone && cinfo->ret.pair_storage [1] == LLVMArgNone) {
1258 ret_type = LLVMVoidType ();
1259 } else if (cinfo->ret.pair_storage [0] == LLVMArgInIReg && cinfo->ret.pair_storage [1] == LLVMArgInIReg) {
1260 LLVMTypeRef members [2];
1262 members [0] = IntPtrType ();
1263 members [1] = IntPtrType ();
1264 ret_type = LLVMStructType (members, 2, FALSE);
1266 g_assert_not_reached ();
1269 case LLVMArgVtypeByVal:
1270 /* Vtype returned normally by val */
1272 case LLVMArgVtypeAsScalar: {
1273 int size = mono_class_value_size (mono_class_from_mono_type (rtype), NULL);
1274 /* LLVM models this by returning an int */
1275 if (size < SIZEOF_VOID_P) {
1276 g_assert (cinfo->ret.nslots == 1);
1277 ret_type = LLVMIntType (size * 8);
1279 g_assert (cinfo->ret.nslots == 1 || cinfo->ret.nslots == 2);
1280 ret_type = LLVMIntType (cinfo->ret.nslots * sizeof (mgreg_t) * 8);
1284 case LLVMArgFpStruct: {
1285 /* Vtype returned as a fp struct */
1286 LLVMTypeRef members [16];
1288 /* Have to create our own structure since we don't map fp structures to LLVM fp structures yet */
1289 for (i = 0; i < cinfo->ret.nslots; ++i)
1290 members [i] = cinfo->ret.esize == 8 ? LLVMDoubleType () : LLVMFloatType ();
1291 ret_type = LLVMStructType (members, cinfo->ret.nslots, FALSE);
1294 case LLVMArgVtypeByRef:
1295 /* Vtype returned using a hidden argument */
1296 ret_type = LLVMVoidType ();
1298 case LLVMArgVtypeRetAddr:
1299 case LLVMArgGsharedvtFixed:
1300 case LLVMArgGsharedvtFixedVtype:
1301 case LLVMArgGsharedvtVariable:
1303 ret_type = LLVMVoidType ();
1309 param_types = g_new0 (LLVMTypeRef, (sig->param_count * 8) + 3);
1311 if (cinfo->ret.storage == LLVMArgVtypeByRef) {
1313 * Has to be the first argument because of the sret argument attribute
1314 * FIXME: This might conflict with passing 'this' as the first argument, but
1315 * this is only used on arm64 which has a dedicated struct return register.
1317 cinfo->vret_arg_pindex = pindex;
1318 param_types [pindex] = type_to_llvm_arg_type (ctx, sig->ret);
1319 if (!ctx_ok (ctx)) {
1320 g_free (param_types);
1323 param_types [pindex] = LLVMPointerType (param_types [pindex], 0);
1326 if (!ctx->llvm_only && cinfo->rgctx_arg) {
1327 cinfo->rgctx_arg_pindex = pindex;
1328 param_types [pindex] = ctx->module->ptr_type;
1331 if (cinfo->imt_arg) {
1332 cinfo->imt_arg_pindex = pindex;
1333 param_types [pindex] = ctx->module->ptr_type;
1337 /* Compute the index in the LLVM signature where the vret arg needs to be passed */
1338 vret_arg_pindex = pindex;
1339 if (cinfo->vret_arg_index == 1) {
1340 /* Add the slots consumed by the first argument */
1341 LLVMArgInfo *ainfo = &cinfo->args [0];
1342 switch (ainfo->storage) {
1343 case LLVMArgVtypeInReg:
1344 for (j = 0; j < 2; ++j) {
1345 if (ainfo->pair_storage [j] == LLVMArgInIReg)
1354 cinfo->vret_arg_pindex = vret_arg_pindex;
1357 if (vretaddr && vret_arg_pindex == pindex)
1358 param_types [pindex ++] = IntPtrType ();
1360 cinfo->this_arg_pindex = pindex;
1361 param_types [pindex ++] = ThisType ();
1362 cinfo->args [0].pindex = cinfo->this_arg_pindex;
1364 if (vretaddr && vret_arg_pindex == pindex)
1365 param_types [pindex ++] = IntPtrType ();
1366 for (i = 0; i < sig->param_count; ++i) {
1367 LLVMArgInfo *ainfo = &cinfo->args [i + sig->hasthis];
1369 if (vretaddr && vret_arg_pindex == pindex)
1370 param_types [pindex ++] = IntPtrType ();
1371 ainfo->pindex = pindex;
1373 switch (ainfo->storage) {
1374 case LLVMArgVtypeInReg:
1375 for (j = 0; j < 2; ++j) {
1376 switch (ainfo->pair_storage [j]) {
1378 param_types [pindex ++] = LLVMIntType (sizeof (gpointer) * 8);
1383 g_assert_not_reached ();
1387 case LLVMArgVtypeByVal:
1388 param_types [pindex] = type_to_llvm_arg_type (ctx, ainfo->type);
1391 param_types [pindex] = LLVMPointerType (param_types [pindex], 0);
1394 case LLVMArgAsIArgs:
1395 param_types [pindex] = LLVMArrayType (IntPtrType (), ainfo->nslots);
1398 case LLVMArgVtypeByRef:
1399 param_types [pindex] = type_to_llvm_arg_type (ctx, ainfo->type);
1402 param_types [pindex] = LLVMPointerType (param_types [pindex], 0);
1405 case LLVMArgAsFpArgs: {
1408 /* Emit dummy fp arguments if needed so the rest is passed on the stack */
1409 for (j = 0; j < ainfo->ndummy_fpargs; ++j)
1410 param_types [pindex ++] = LLVMDoubleType ();
1411 for (j = 0; j < ainfo->nslots; ++j)
1412 param_types [pindex ++] = ainfo->esize == 8 ? LLVMDoubleType () : LLVMFloatType ();
1415 case LLVMArgVtypeAsScalar:
1416 g_assert_not_reached ();
1418 case LLVMArgGsharedvtFixed:
1419 case LLVMArgGsharedvtFixedVtype:
1420 param_types [pindex ++] = LLVMPointerType (type_to_llvm_arg_type (ctx, ainfo->type), 0);
1422 case LLVMArgGsharedvtVariable:
1423 param_types [pindex ++] = LLVMPointerType (IntPtrType (), 0);
1426 param_types [pindex ++] = type_to_llvm_arg_type (ctx, ainfo->type);
1430 if (!ctx_ok (ctx)) {
1431 g_free (param_types);
1434 if (vretaddr && vret_arg_pindex == pindex)
1435 param_types [pindex ++] = IntPtrType ();
1436 if (ctx->llvm_only && cinfo->rgctx_arg) {
1437 /* Pass the rgctx as the last argument */
1438 cinfo->rgctx_arg_pindex = pindex;
1439 param_types [pindex] = ctx->module->ptr_type;
1443 res = LLVMFunctionType (ret_type, param_types, pindex, FALSE);
1444 g_free (param_types);
1450 sig_to_llvm_sig (EmitContext *ctx, MonoMethodSignature *sig)
1452 return sig_to_llvm_sig_full (ctx, sig, NULL);
1456 * LLVMFunctionType1:
1458 * Create an LLVM function type from the arguments.
1460 static G_GNUC_UNUSED LLVMTypeRef
1461 LLVMFunctionType0 (LLVMTypeRef ReturnType,
1464 return LLVMFunctionType (ReturnType, NULL, 0, IsVarArg);
1468 * LLVMFunctionType1:
1470 * Create an LLVM function type from the arguments.
1472 static G_GNUC_UNUSED LLVMTypeRef
1473 LLVMFunctionType1 (LLVMTypeRef ReturnType,
1474 LLVMTypeRef ParamType1,
1477 LLVMTypeRef param_types [1];
1479 param_types [0] = ParamType1;
1481 return LLVMFunctionType (ReturnType, param_types, 1, IsVarArg);
1485 * LLVMFunctionType2:
1487 * Create an LLVM function type from the arguments.
1489 static G_GNUC_UNUSED LLVMTypeRef
1490 LLVMFunctionType2 (LLVMTypeRef ReturnType,
1491 LLVMTypeRef ParamType1,
1492 LLVMTypeRef ParamType2,
1495 LLVMTypeRef param_types [2];
1497 param_types [0] = ParamType1;
1498 param_types [1] = ParamType2;
1500 return LLVMFunctionType (ReturnType, param_types, 2, IsVarArg);
1504 * LLVMFunctionType3:
1506 * Create an LLVM function type from the arguments.
1508 static G_GNUC_UNUSED LLVMTypeRef
1509 LLVMFunctionType3 (LLVMTypeRef ReturnType,
1510 LLVMTypeRef ParamType1,
1511 LLVMTypeRef ParamType2,
1512 LLVMTypeRef ParamType3,
1515 LLVMTypeRef param_types [3];
1517 param_types [0] = ParamType1;
1518 param_types [1] = ParamType2;
1519 param_types [2] = ParamType3;
1521 return LLVMFunctionType (ReturnType, param_types, 3, IsVarArg);
1524 static G_GNUC_UNUSED LLVMTypeRef
1525 LLVMFunctionType5 (LLVMTypeRef ReturnType,
1526 LLVMTypeRef ParamType1,
1527 LLVMTypeRef ParamType2,
1528 LLVMTypeRef ParamType3,
1529 LLVMTypeRef ParamType4,
1530 LLVMTypeRef ParamType5,
1533 LLVMTypeRef param_types [5];
1535 param_types [0] = ParamType1;
1536 param_types [1] = ParamType2;
1537 param_types [2] = ParamType3;
1538 param_types [3] = ParamType4;
1539 param_types [4] = ParamType5;
1541 return LLVMFunctionType (ReturnType, param_types, 5, IsVarArg);
1547 * Create an LLVM builder and remember it so it can be freed later.
1549 static LLVMBuilderRef
1550 create_builder (EmitContext *ctx)
1552 LLVMBuilderRef builder = LLVMCreateBuilder ();
1554 ctx->builders = g_slist_prepend_mempool (ctx->cfg->mempool, ctx->builders, builder);
1560 get_aotconst_name (MonoJumpInfoType type, gconstpointer data, int got_offset)
1565 case MONO_PATCH_INFO_INTERNAL_METHOD:
1566 name = g_strdup_printf ("jit_icall_%s", data);
1568 case MONO_PATCH_INFO_RGCTX_SLOT_INDEX: {
1569 MonoJumpInfoRgctxEntry *entry = (MonoJumpInfoRgctxEntry*)data;
1570 name = g_strdup_printf ("RGCTX_SLOT_INDEX_%s", mono_rgctx_info_type_to_str (entry->info_type));
1574 name = g_strdup_printf ("%s_%d", mono_ji_type_to_string (type), got_offset);
1582 get_aotconst_typed (EmitContext *ctx, MonoJumpInfoType type, gconstpointer data, LLVMTypeRef llvm_type)
1586 LLVMValueRef indexes [2];
1588 LLVMValueRef got_entry_addr, load;
1589 LLVMBuilderRef builder = ctx->builder;
1594 ji = g_new0 (MonoJumpInfo, 1);
1596 ji->data.target = data;
1598 ji = mono_aot_patch_info_dup (ji);
1600 ji->next = cfg->patch_info;
1601 cfg->patch_info = ji;
1603 got_offset = mono_aot_get_got_offset (cfg->patch_info);
1604 ctx->module->max_got_offset = MAX (ctx->module->max_got_offset, got_offset);
1606 * If the got slot is shared, it means its initialized when the aot image is loaded, so we don't need to
1607 * explicitly initialize it.
1609 if (!mono_aot_is_shared_got_offset (got_offset)) {
1610 //mono_print_ji (ji);
1612 ctx->has_got_access = TRUE;
1615 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
1616 indexes [1] = LLVMConstInt (LLVMInt32Type (), (gssize)got_offset, FALSE);
1617 got_entry_addr = LLVMBuildGEP (builder, ctx->module->got_var, indexes, 2, "");
1619 name = get_aotconst_name (type, data, got_offset);
1621 load = LLVMBuildLoad (builder, got_entry_addr, "");
1622 load = convert (ctx, load, llvm_type);
1623 LLVMSetValueName (load, name ? name : "");
1625 load = LLVMBuildLoad (builder, got_entry_addr, name ? name : "");
1628 //set_invariant_load_flag (load);
1634 get_aotconst (EmitContext *ctx, MonoJumpInfoType type, gconstpointer data)
1636 return get_aotconst_typed (ctx, type, data, NULL);
1640 get_callee (EmitContext *ctx, LLVMTypeRef llvm_sig, MonoJumpInfoType type, gconstpointer data)
1642 LLVMValueRef callee;
1644 if (ctx->llvm_only) {
1645 callee_name = mono_aot_get_direct_call_symbol (type, data);
1647 /* Directly callable */
1649 callee = (LLVMValueRef)g_hash_table_lookup (ctx->module->direct_callables, callee_name);
1651 callee = LLVMAddFunction (ctx->lmodule, callee_name, llvm_sig);
1653 LLVMSetVisibility (callee, LLVMHiddenVisibility);
1655 g_hash_table_insert (ctx->module->direct_callables, (char*)callee_name, callee);
1657 /* LLVMTypeRef's are uniqued */
1658 if (LLVMGetElementType (LLVMTypeOf (callee)) != llvm_sig)
1659 return LLVMConstBitCast (callee, LLVMPointerType (llvm_sig, 0));
1661 g_free (callee_name);
1667 * Calls are made through the GOT.
1669 return get_aotconst_typed (ctx, type, data, LLVMPointerType (llvm_sig, 0));
1671 MonoJumpInfo *ji = NULL;
1673 callee_name = mono_aot_get_plt_symbol (type, data);
1677 if (ctx->cfg->compile_aot)
1678 /* Add a patch so referenced wrappers can be compiled in full aot mode */
1679 mono_add_patch_info (ctx->cfg, 0, type, data);
1682 callee = (LLVMValueRef)g_hash_table_lookup (ctx->module->plt_entries, callee_name);
1684 callee = LLVMAddFunction (ctx->lmodule, callee_name, llvm_sig);
1686 LLVMSetVisibility (callee, LLVMHiddenVisibility);
1688 g_hash_table_insert (ctx->module->plt_entries, (char*)callee_name, callee);
1691 if (ctx->cfg->compile_aot) {
1692 ji = g_new0 (MonoJumpInfo, 1);
1694 ji->data.target = data;
1696 g_hash_table_insert (ctx->module->plt_entries_ji, ji, callee);
1704 emit_jit_callee (EmitContext *ctx, const char *name, LLVMTypeRef llvm_sig, gpointer target)
1706 #if LLVM_API_VERSION > 100
1707 LLVMValueRef tramp_var = LLVMAddGlobal (ctx->lmodule, LLVMPointerType (llvm_sig, 0), name);
1708 LLVMSetInitializer (tramp_var, LLVMConstIntToPtr (LLVMConstInt (LLVMInt64Type (), (guint64)(size_t)target, FALSE), LLVMPointerType (llvm_sig, 0)));
1709 LLVMSetLinkage (tramp_var, LLVMExternalLinkage);
1710 LLVMValueRef callee = LLVMBuildLoad (ctx->builder, tramp_var, "");
1713 LLVMValueRef callee = LLVMAddFunction (ctx->lmodule, "", llvm_sig);
1714 LLVMAddGlobalMapping (ctx->module->ee, callee, target);
1720 get_handler_clause (MonoCompile *cfg, MonoBasicBlock *bb)
1722 MonoMethodHeader *header = cfg->header;
1723 MonoExceptionClause *clause;
1727 if (bb->region != -1 && MONO_BBLOCK_IS_IN_REGION (bb, MONO_REGION_TRY))
1728 return (bb->region >> 8) - 1;
1731 for (i = 0; i < header->num_clauses; ++i) {
1732 clause = &header->clauses [i];
1734 if (MONO_OFFSET_IN_CLAUSE (clause, bb->real_offset) && clause->flags == MONO_EXCEPTION_CLAUSE_NONE)
1741 static MonoExceptionClause *
1742 get_most_deep_clause (MonoCompile *cfg, EmitContext *ctx, MonoBasicBlock *bb)
1744 // Since they're sorted by nesting we just need
1745 // the first one that the bb is a member of
1746 MonoExceptionClause *last = NULL;
1748 for (int i = 0; i < cfg->header->num_clauses; i++) {
1749 MonoExceptionClause *curr = &cfg->header->clauses [i];
1751 if (MONO_OFFSET_IN_CLAUSE (curr, bb->real_offset))
1754 if (MONO_OFFSET_IN_CLAUSE (curr, bb->real_offset)) {
1755 if (last && CLAUSE_END(last) > CLAUSE_END(curr))
1769 set_metadata_flag (LLVMValueRef v, const char *flag_name)
1771 LLVMValueRef md_arg;
1774 md_kind = LLVMGetMDKindID (flag_name, strlen (flag_name));
1775 md_arg = LLVMMDString ("mono", 4);
1776 LLVMSetMetadata (v, md_kind, LLVMMDNode (&md_arg, 1));
1780 set_invariant_load_flag (LLVMValueRef v)
1782 LLVMValueRef md_arg;
1784 const char *flag_name;
1786 // FIXME: Cache this
1787 flag_name = "invariant.load";
1788 md_kind = LLVMGetMDKindID (flag_name, strlen (flag_name));
1789 md_arg = LLVMMDString ("<index>", strlen ("<index>"));
1790 LLVMSetMetadata (v, md_kind, LLVMMDNode (&md_arg, 1));
1796 * Emit an LLVM call or invoke instruction depending on whenever the call is inside
1800 emit_call (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, LLVMValueRef callee, LLVMValueRef *args, int pindex)
1802 MonoCompile *cfg = ctx->cfg;
1803 LLVMValueRef lcall = NULL;
1804 LLVMBuilderRef builder = *builder_ref;
1805 MonoExceptionClause *clause;
1807 if (ctx->llvm_only) {
1808 clause = get_most_deep_clause (cfg, ctx, bb);
1811 g_assert (clause->flags == MONO_EXCEPTION_CLAUSE_NONE || clause->flags == MONO_EXCEPTION_CLAUSE_FINALLY);
1814 * Have to use an invoke instead of a call, branching to the
1815 * handler bblock of the clause containing this bblock.
1817 intptr_t key = CLAUSE_END(clause);
1819 LLVMBasicBlockRef lpad_bb = (LLVMBasicBlockRef)g_hash_table_lookup (ctx->exc_meta, (gconstpointer)key);
1821 // FIXME: Find the one that has the lowest end bound for the right start address
1822 // FIXME: Finally + nesting
1825 LLVMBasicBlockRef noex_bb = gen_bb (ctx, "CALL_NOEX_BB");
1828 lcall = LLVMBuildInvoke (builder, callee, args, pindex, noex_bb, lpad_bb, "");
1830 builder = ctx->builder = create_builder (ctx);
1831 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
1833 ctx->bblocks [bb->block_num].end_bblock = noex_bb;
1837 int clause_index = get_handler_clause (cfg, bb);
1839 if (clause_index != -1) {
1840 MonoMethodHeader *header = cfg->header;
1841 MonoExceptionClause *ec = &header->clauses [clause_index];
1842 MonoBasicBlock *tblock;
1843 LLVMBasicBlockRef ex_bb, noex_bb;
1846 * Have to use an invoke instead of a call, branching to the
1847 * handler bblock of the clause containing this bblock.
1850 g_assert (ec->flags == MONO_EXCEPTION_CLAUSE_NONE || ec->flags == MONO_EXCEPTION_CLAUSE_FINALLY);
1852 tblock = cfg->cil_offset_to_bb [ec->handler_offset];
1855 ctx->bblocks [tblock->block_num].invoke_target = TRUE;
1857 ex_bb = get_bb (ctx, tblock);
1859 noex_bb = gen_bb (ctx, "NOEX_BB");
1862 lcall = LLVMBuildInvoke (builder, callee, args, pindex, noex_bb, ex_bb, "");
1864 builder = ctx->builder = create_builder (ctx);
1865 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
1867 ctx->bblocks [bb->block_num].end_bblock = noex_bb;
1872 lcall = LLVMBuildCall (builder, callee, args, pindex, "");
1873 ctx->builder = builder;
1877 *builder_ref = ctx->builder;
1883 emit_load_general (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, int size, LLVMValueRef addr, const char *name, gboolean is_faulting, BarrierKind barrier)
1885 const char *intrins_name;
1886 LLVMValueRef args [16], res;
1887 LLVMTypeRef addr_type;
1888 gboolean use_intrinsics = TRUE;
1890 #if LLVM_API_VERSION > 100
1891 if (is_faulting && bb->region != -1 && !ctx->cfg->llvm_only) {
1892 /* The llvm.mono.load/store intrinsics are not supported by this llvm version, emit an explicit null check instead */
1893 LLVMValueRef cmp = LLVMBuildICmp (*builder_ref, LLVMIntEQ, addr, LLVMConstNull (LLVMTypeOf (addr)), "");
1894 emit_cond_system_exception (ctx, bb, "NullReferenceException", cmp);
1895 *builder_ref = ctx->builder;
1896 use_intrinsics = FALSE;
1900 if (is_faulting && bb->region != -1 && !ctx->cfg->llvm_only && use_intrinsics) {
1901 LLVMAtomicOrdering ordering;
1904 case LLVM_BARRIER_NONE:
1905 ordering = LLVMAtomicOrderingNotAtomic;
1907 case LLVM_BARRIER_ACQ:
1908 ordering = LLVMAtomicOrderingAcquire;
1910 case LLVM_BARRIER_SEQ:
1911 ordering = LLVMAtomicOrderingSequentiallyConsistent;
1914 g_assert_not_reached ();
1919 * We handle loads which can fault by calling a mono specific intrinsic
1920 * using an invoke, so they are handled properly inside try blocks.
1921 * We can't use this outside clauses, since LLVM optimizes intrinsics which
1922 * are marked with IntrReadArgMem.
1926 intrins_name = "llvm.mono.load.i8.p0i8";
1929 intrins_name = "llvm.mono.load.i16.p0i16";
1932 intrins_name = "llvm.mono.load.i32.p0i32";
1935 intrins_name = "llvm.mono.load.i64.p0i64";
1938 g_assert_not_reached ();
1941 addr_type = LLVMTypeOf (addr);
1942 if (addr_type == LLVMPointerType (LLVMDoubleType (), 0) || addr_type == LLVMPointerType (LLVMFloatType (), 0))
1943 addr = LLVMBuildBitCast (*builder_ref, addr, LLVMPointerType (LLVMIntType (size * 8), 0), "");
1946 args [1] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
1947 args [2] = LLVMConstInt (LLVMInt1Type (), TRUE, FALSE);
1948 args [3] = LLVMConstInt (LLVMInt32Type (), ordering, FALSE);
1949 res = emit_call (ctx, bb, builder_ref, get_intrinsic (ctx, intrins_name), args, 4);
1951 if (addr_type == LLVMPointerType (LLVMDoubleType (), 0))
1952 res = LLVMBuildBitCast (*builder_ref, res, LLVMDoubleType (), "");
1953 else if (addr_type == LLVMPointerType (LLVMFloatType (), 0))
1954 res = LLVMBuildBitCast (*builder_ref, res, LLVMFloatType (), "");
1961 * We emit volatile loads for loads which can fault, because otherwise
1962 * LLVM will generate invalid code when encountering a load from a
1965 res = mono_llvm_build_load (*builder_ref, addr, name, is_faulting, barrier);
1967 /* Mark it with a custom metadata */
1970 set_metadata_flag (res, "mono.faulting.load");
1978 emit_load (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, int size, LLVMValueRef addr, const char *name, gboolean is_faulting)
1980 return emit_load_general (ctx, bb, builder_ref, size, addr, name, is_faulting, LLVM_BARRIER_NONE);
1984 emit_store_general (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, int size, LLVMValueRef value, LLVMValueRef addr, gboolean is_faulting, BarrierKind barrier)
1986 const char *intrins_name;
1987 LLVMValueRef args [16];
1988 gboolean use_intrinsics = TRUE;
1990 #if LLVM_API_VERSION > 100
1991 if (is_faulting && bb->region != -1 && !ctx->cfg->llvm_only) {
1992 /* The llvm.mono.load/store intrinsics are not supported by this llvm version, emit an explicit null check instead */
1993 LLVMValueRef cmp = LLVMBuildICmp (*builder_ref, LLVMIntEQ, addr, LLVMConstNull (LLVMTypeOf (addr)), "");
1994 emit_cond_system_exception (ctx, bb, "NullReferenceException", cmp);
1995 *builder_ref = ctx->builder;
1996 use_intrinsics = FALSE;
2000 if (is_faulting && bb->region != -1 && !ctx->cfg->llvm_only && use_intrinsics) {
2001 LLVMAtomicOrdering ordering;
2004 case LLVM_BARRIER_NONE:
2005 ordering = LLVMAtomicOrderingNotAtomic;
2007 case LLVM_BARRIER_REL:
2008 ordering = LLVMAtomicOrderingRelease;
2010 case LLVM_BARRIER_SEQ:
2011 ordering = LLVMAtomicOrderingSequentiallyConsistent;
2014 g_assert_not_reached ();
2020 intrins_name = "llvm.mono.store.i8.p0i8";
2023 intrins_name = "llvm.mono.store.i16.p0i16";
2026 intrins_name = "llvm.mono.store.i32.p0i32";
2029 intrins_name = "llvm.mono.store.i64.p0i64";
2032 g_assert_not_reached ();
2035 if (LLVMTypeOf (value) == LLVMDoubleType () || LLVMTypeOf (value) == LLVMFloatType ()) {
2036 value = LLVMBuildBitCast (*builder_ref, value, LLVMIntType (size * 8), "");
2037 addr = LLVMBuildBitCast (*builder_ref, addr, LLVMPointerType (LLVMIntType (size * 8), 0), "");
2042 args [2] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
2043 args [3] = LLVMConstInt (LLVMInt1Type (), TRUE, FALSE);
2044 args [4] = LLVMConstInt (LLVMInt32Type (), ordering, FALSE);
2045 emit_call (ctx, bb, builder_ref, get_intrinsic (ctx, intrins_name), args, 5);
2047 mono_llvm_build_store (*builder_ref, value, addr, is_faulting, barrier);
2052 emit_store (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, int size, LLVMValueRef value, LLVMValueRef addr, gboolean is_faulting)
2054 emit_store_general (ctx, bb, builder_ref, size, value, addr, is_faulting, LLVM_BARRIER_NONE);
2058 * emit_cond_system_exception:
2060 * Emit code to throw the exception EXC_TYPE if the condition CMP is false.
2061 * Might set the ctx exception.
2064 emit_cond_system_exception (EmitContext *ctx, MonoBasicBlock *bb, const char *exc_type, LLVMValueRef cmp)
2066 LLVMBasicBlockRef ex_bb, ex2_bb = NULL, noex_bb;
2067 LLVMBuilderRef builder;
2068 MonoClass *exc_class;
2069 LLVMValueRef args [2];
2070 LLVMValueRef callee;
2072 ex_bb = gen_bb (ctx, "EX_BB");
2074 ex2_bb = gen_bb (ctx, "EX2_BB");
2075 noex_bb = gen_bb (ctx, "NOEX_BB");
2077 LLVMBuildCondBr (ctx->builder, cmp, ex_bb, noex_bb);
2079 exc_class = mono_class_load_from_name (mono_get_corlib (), "System", exc_type);
2081 /* Emit exception throwing code */
2082 ctx->builder = builder = create_builder (ctx);
2083 LLVMPositionBuilderAtEnd (builder, ex_bb);
2085 if (ctx->cfg->llvm_only) {
2086 static LLVMTypeRef sig;
2089 sig = LLVMFunctionType1 (LLVMVoidType (), LLVMInt32Type (), FALSE);
2090 callee = get_callee (ctx, sig, MONO_PATCH_INFO_JIT_ICALL_ADDR, "mono_llvm_throw_corlib_exception");
2092 LLVMBuildBr (builder, ex2_bb);
2094 ctx->builder = builder = create_builder (ctx);
2095 LLVMPositionBuilderAtEnd (ctx->builder, ex2_bb);
2097 args [0] = LLVMConstInt (LLVMInt32Type (), exc_class->type_token - MONO_TOKEN_TYPE_DEF, FALSE);
2098 emit_call (ctx, bb, &builder, callee, args, 1);
2099 LLVMBuildUnreachable (builder);
2101 ctx->builder = builder = create_builder (ctx);
2102 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
2104 ctx->bblocks [bb->block_num].end_bblock = noex_bb;
2110 callee = ctx->module->throw_corlib_exception;
2113 const char *icall_name;
2115 sig = LLVMFunctionType2 (LLVMVoidType (), LLVMInt32Type (), LLVMPointerType (LLVMInt8Type (), 0), FALSE);
2116 icall_name = "llvm_throw_corlib_exception_abs_trampoline";
2118 if (ctx->cfg->compile_aot) {
2119 callee = get_callee (ctx, sig, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
2122 * Differences between the LLVM/non-LLVM throw corlib exception trampoline:
2123 * - On x86, LLVM generated code doesn't push the arguments
2124 * - The trampoline takes the throw address as an arguments, not a pc offset.
2126 gpointer target = resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
2127 callee = emit_jit_callee (ctx, "llvm_throw_corlib_exception_trampoline", sig, target);
2129 #if LLVM_API_VERSION > 100
2131 * Make sure that ex_bb starts with the invoke, so the block address points to it, and not to the load
2132 * added by emit_jit_callee ().
2134 ex2_bb = gen_bb (ctx, "EX2_BB");
2135 LLVMBuildBr (builder, ex2_bb);
2138 ctx->builder = builder = create_builder (ctx);
2139 LLVMPositionBuilderAtEnd (ctx->builder, ex2_bb);
2141 mono_memory_barrier ();
2142 ctx->module->throw_corlib_exception = callee;
2147 if (IS_TARGET_X86 || IS_TARGET_AMD64)
2148 args [0] = LLVMConstInt (LLVMInt32Type (), exc_class->type_token - MONO_TOKEN_TYPE_DEF, FALSE);
2150 args [0] = LLVMConstInt (LLVMInt32Type (), exc_class->type_token, FALSE);
2153 * The LLVM mono branch contains changes so a block address can be passed as an
2154 * argument to a call.
2156 args [1] = LLVMBlockAddress (ctx->lmethod, ex_bb);
2157 emit_call (ctx, bb, &builder, callee, args, 2);
2159 LLVMBuildUnreachable (builder);
2161 ctx->builder = builder = create_builder (ctx);
2162 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
2164 ctx->bblocks [bb->block_num].end_bblock = noex_bb;
2171 * emit_args_to_vtype:
2173 * Emit code to store the vtype in the arguments args to the address ADDRESS.
2176 emit_args_to_vtype (EmitContext *ctx, LLVMBuilderRef builder, MonoType *t, LLVMValueRef address, LLVMArgInfo *ainfo, LLVMValueRef *args)
2178 int j, size, nslots;
2180 size = mono_class_value_size (mono_class_from_mono_type (t), NULL);
2182 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (t))) {
2183 address = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (LLVMInt8Type (), 0), "");
2186 if (ainfo->storage == LLVMArgAsFpArgs)
2187 nslots = ainfo->nslots;
2191 for (j = 0; j < nslots; ++j) {
2192 LLVMValueRef index [2], addr, daddr;
2193 int part_size = size > sizeof (gpointer) ? sizeof (gpointer) : size;
2194 LLVMTypeRef part_type;
2196 while (part_size != 1 && part_size != 2 && part_size != 4 && part_size < 8)
2199 if (ainfo->pair_storage [j] == LLVMArgNone)
2202 switch (ainfo->pair_storage [j]) {
2203 case LLVMArgInIReg: {
2204 part_type = LLVMIntType (part_size * 8);
2205 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (t))) {
2206 index [0] = LLVMConstInt (LLVMInt32Type (), j * sizeof (gpointer), FALSE);
2207 addr = LLVMBuildGEP (builder, address, index, 1, "");
2209 daddr = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (IntPtrType (), 0), "");
2210 index [0] = LLVMConstInt (LLVMInt32Type (), j, FALSE);
2211 addr = LLVMBuildGEP (builder, daddr, index, 1, "");
2213 LLVMBuildStore (builder, convert (ctx, args [j], part_type), LLVMBuildBitCast (ctx->builder, addr, LLVMPointerType (part_type, 0), ""));
2216 case LLVMArgInFPReg: {
2217 LLVMTypeRef arg_type;
2219 if (ainfo->esize == 8)
2220 arg_type = LLVMDoubleType ();
2222 arg_type = LLVMFloatType ();
2224 index [0] = LLVMConstInt (LLVMInt32Type (), j, FALSE);
2225 daddr = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (arg_type, 0), "");
2226 addr = LLVMBuildGEP (builder, daddr, index, 1, "");
2227 LLVMBuildStore (builder, args [j], addr);
2233 g_assert_not_reached ();
2236 size -= sizeof (gpointer);
2241 * emit_vtype_to_args:
2243 * Emit code to load a vtype at address ADDRESS into scalar arguments. Store the arguments
2244 * into ARGS, and the number of arguments into NARGS.
2247 emit_vtype_to_args (EmitContext *ctx, LLVMBuilderRef builder, MonoType *t, LLVMValueRef address, LLVMArgInfo *ainfo, LLVMValueRef *args, guint32 *nargs)
2250 int j, size, nslots;
2251 LLVMTypeRef arg_type;
2253 size = get_vtype_size (t);
2255 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (t)))
2256 address = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (LLVMInt8Type (), 0), "");
2258 if (ainfo->storage == LLVMArgAsFpArgs)
2259 nslots = ainfo->nslots;
2262 for (j = 0; j < nslots; ++j) {
2263 LLVMValueRef index [2], addr, daddr;
2264 int partsize = size > sizeof (gpointer) ? sizeof (gpointer) : size;
2266 if (ainfo->pair_storage [j] == LLVMArgNone)
2269 switch (ainfo->pair_storage [j]) {
2271 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (t))) {
2272 index [0] = LLVMConstInt (LLVMInt32Type (), j * sizeof (gpointer), FALSE);
2273 addr = LLVMBuildGEP (builder, address, index, 1, "");
2275 daddr = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (IntPtrType (), 0), "");
2276 index [0] = LLVMConstInt (LLVMInt32Type (), j, FALSE);
2277 addr = LLVMBuildGEP (builder, daddr, index, 1, "");
2279 args [pindex ++] = convert (ctx, LLVMBuildLoad (builder, LLVMBuildBitCast (ctx->builder, addr, LLVMPointerType (LLVMIntType (partsize * 8), 0), ""), ""), IntPtrType ());
2281 case LLVMArgInFPReg:
2282 if (ainfo->esize == 8)
2283 arg_type = LLVMDoubleType ();
2285 arg_type = LLVMFloatType ();
2286 daddr = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (arg_type, 0), "");
2287 index [0] = LLVMConstInt (LLVMInt32Type (), j, FALSE);
2288 addr = LLVMBuildGEP (builder, daddr, index, 1, "");
2289 args [pindex ++] = LLVMBuildLoad (builder, addr, "");
2294 g_assert_not_reached ();
2296 size -= sizeof (gpointer);
2303 build_alloca_llvm_type_name (EmitContext *ctx, LLVMTypeRef t, int align, const char *name)
2306 * Have to place all alloca's at the end of the entry bb, since otherwise they would
2307 * get executed every time control reaches them.
2309 LLVMPositionBuilder (ctx->alloca_builder, get_bb (ctx, ctx->cfg->bb_entry), ctx->last_alloca);
2311 ctx->last_alloca = mono_llvm_build_alloca (ctx->alloca_builder, t, NULL, align, name);
2312 return ctx->last_alloca;
2316 build_alloca_llvm_type (EmitContext *ctx, LLVMTypeRef t, int align)
2318 return build_alloca_llvm_type_name (ctx, t, align, "");
2322 build_alloca (EmitContext *ctx, MonoType *t)
2324 MonoClass *k = mono_class_from_mono_type (t);
2327 g_assert (!mini_is_gsharedvt_variable_type (t));
2329 if (MONO_CLASS_IS_SIMD (ctx->cfg, k))
2332 align = mono_class_min_align (k);
2334 /* Sometimes align is not a power of 2 */
2335 while (mono_is_power_of_two (align) == -1)
2338 return build_alloca_llvm_type (ctx, type_to_llvm_type (ctx, t), align);
2342 emit_gsharedvt_ldaddr (EmitContext *ctx, int vreg)
2346 * Compute the address of the local as gsharedvt_locals_var + gsharedvt_info_var->locals_offsets [idx].
2348 MonoCompile *cfg = ctx->cfg;
2349 LLVMBuilderRef builder = ctx->builder;
2350 LLVMValueRef offset, offset_var;
2351 LLVMValueRef info_var = ctx->values [cfg->gsharedvt_info_var->dreg];
2352 LLVMValueRef locals_var = ctx->values [cfg->gsharedvt_locals_var->dreg];
2356 g_assert (info_var);
2357 g_assert (locals_var);
2359 int idx = cfg->gsharedvt_vreg_to_idx [vreg] - 1;
2361 offset = LLVMConstInt (LLVMInt32Type (), MONO_STRUCT_OFFSET (MonoGSharedVtMethodRuntimeInfo, entries) + (idx * sizeof (gpointer)), FALSE);
2362 ptr = LLVMBuildAdd (builder, convert (ctx, info_var, IntPtrType ()), convert (ctx, offset, IntPtrType ()), "");
2364 name = g_strdup_printf ("gsharedvt_local_%d_offset", vreg);
2365 offset_var = LLVMBuildLoad (builder, convert (ctx, ptr, LLVMPointerType (LLVMInt32Type (), 0)), name);
2367 return LLVMBuildAdd (builder, convert (ctx, locals_var, IntPtrType ()), convert (ctx, offset_var, IntPtrType ()), "");
2371 * Put the global into the 'llvm.used' array to prevent it from being optimized away.
2374 mark_as_used (MonoLLVMModule *module, LLVMValueRef global)
2377 module->used = g_ptr_array_sized_new (16);
2378 g_ptr_array_add (module->used, global);
2382 emit_llvm_used (MonoLLVMModule *module)
2384 LLVMModuleRef lmodule = module->lmodule;
2385 LLVMTypeRef used_type;
2386 LLVMValueRef used, *used_elem;
2392 used_type = LLVMArrayType (LLVMPointerType (LLVMInt8Type (), 0), module->used->len);
2393 used = LLVMAddGlobal (lmodule, used_type, "llvm.used");
2394 used_elem = g_new0 (LLVMValueRef, module->used->len);
2395 for (i = 0; i < module->used->len; ++i)
2396 used_elem [i] = LLVMConstBitCast ((LLVMValueRef)g_ptr_array_index (module->used, i), LLVMPointerType (LLVMInt8Type (), 0));
2397 LLVMSetInitializer (used, LLVMConstArray (LLVMPointerType (LLVMInt8Type (), 0), used_elem, module->used->len));
2398 LLVMSetLinkage (used, LLVMAppendingLinkage);
2399 LLVMSetSection (used, "llvm.metadata");
2405 * Emit a function mapping method indexes to their code
2408 emit_get_method (MonoLLVMModule *module)
2410 LLVMModuleRef lmodule = module->lmodule;
2411 LLVMValueRef func, switch_ins, m;
2412 LLVMBasicBlockRef entry_bb, fail_bb, bb, code_start_bb, code_end_bb;
2413 LLVMBasicBlockRef *bbs;
2415 LLVMBuilderRef builder;
2420 * Emit a switch statement. Emitting a table of function addresses is smaller/faster,
2421 * but generating code seems safer.
2423 rtype = LLVMPointerType (LLVMInt8Type (), 0);
2424 func = LLVMAddFunction (lmodule, module->get_method_symbol, LLVMFunctionType1 (rtype, LLVMInt32Type (), FALSE));
2425 LLVMSetLinkage (func, LLVMExternalLinkage);
2426 LLVMSetVisibility (func, LLVMHiddenVisibility);
2427 LLVMAddFunctionAttr (func, LLVMNoUnwindAttribute);
2428 module->get_method = func;
2430 entry_bb = LLVMAppendBasicBlock (func, "ENTRY");
2433 * Return llvm_code_start/llvm_code_end when called with -1/-2.
2434 * Hopefully, the toolchain doesn't reorder these functions. If it does,
2435 * then we will have to find another solution.
2438 name = g_strdup_printf ("BB_CODE_START");
2439 code_start_bb = LLVMAppendBasicBlock (func, name);
2441 builder = LLVMCreateBuilder ();
2442 LLVMPositionBuilderAtEnd (builder, code_start_bb);
2443 LLVMBuildRet (builder, LLVMBuildBitCast (builder, module->code_start, rtype, ""));
2445 name = g_strdup_printf ("BB_CODE_END");
2446 code_end_bb = LLVMAppendBasicBlock (func, name);
2448 builder = LLVMCreateBuilder ();
2449 LLVMPositionBuilderAtEnd (builder, code_end_bb);
2450 LLVMBuildRet (builder, LLVMBuildBitCast (builder, module->code_end, rtype, ""));
2452 bbs = g_new0 (LLVMBasicBlockRef, module->max_method_idx + 1);
2453 for (i = 0; i < module->max_method_idx + 1; ++i) {
2454 name = g_strdup_printf ("BB_%d", i);
2455 bb = LLVMAppendBasicBlock (func, name);
2459 builder = LLVMCreateBuilder ();
2460 LLVMPositionBuilderAtEnd (builder, bb);
2462 m = (LLVMValueRef)g_hash_table_lookup (module->idx_to_lmethod, GINT_TO_POINTER (i));
2464 LLVMBuildRet (builder, LLVMBuildBitCast (builder, m, rtype, ""));
2466 LLVMBuildRet (builder, LLVMConstNull (rtype));
2469 fail_bb = LLVMAppendBasicBlock (func, "FAIL");
2470 builder = LLVMCreateBuilder ();
2471 LLVMPositionBuilderAtEnd (builder, fail_bb);
2472 LLVMBuildRet (builder, LLVMConstNull (rtype));
2474 builder = LLVMCreateBuilder ();
2475 LLVMPositionBuilderAtEnd (builder, entry_bb);
2477 switch_ins = LLVMBuildSwitch (builder, LLVMGetParam (func, 0), fail_bb, 0);
2478 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), -1, FALSE), code_start_bb);
2479 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), -2, FALSE), code_end_bb);
2480 for (i = 0; i < module->max_method_idx + 1; ++i) {
2481 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), i, FALSE), bbs [i]);
2484 mark_as_used (module, func);
2488 * emit_get_unbox_tramp:
2490 * Emit a function mapping method indexes to their unbox trampoline
2493 emit_get_unbox_tramp (MonoLLVMModule *module)
2495 LLVMModuleRef lmodule = module->lmodule;
2496 LLVMValueRef func, switch_ins, m;
2497 LLVMBasicBlockRef entry_bb, fail_bb, bb;
2498 LLVMBasicBlockRef *bbs;
2500 LLVMBuilderRef builder;
2504 /* Similar to emit_get_method () */
2506 rtype = LLVMPointerType (LLVMInt8Type (), 0);
2507 func = LLVMAddFunction (lmodule, module->get_unbox_tramp_symbol, LLVMFunctionType1 (rtype, LLVMInt32Type (), FALSE));
2508 LLVMSetLinkage (func, LLVMExternalLinkage);
2509 LLVMSetVisibility (func, LLVMHiddenVisibility);
2510 LLVMAddFunctionAttr (func, LLVMNoUnwindAttribute);
2511 module->get_unbox_tramp = func;
2513 entry_bb = LLVMAppendBasicBlock (func, "ENTRY");
2515 bbs = g_new0 (LLVMBasicBlockRef, module->max_method_idx + 1);
2516 for (i = 0; i < module->max_method_idx + 1; ++i) {
2517 m = (LLVMValueRef)g_hash_table_lookup (module->idx_to_unbox_tramp, GINT_TO_POINTER (i));
2521 name = g_strdup_printf ("BB_%d", i);
2522 bb = LLVMAppendBasicBlock (func, name);
2526 builder = LLVMCreateBuilder ();
2527 LLVMPositionBuilderAtEnd (builder, bb);
2529 LLVMBuildRet (builder, LLVMBuildBitCast (builder, m, rtype, ""));
2532 fail_bb = LLVMAppendBasicBlock (func, "FAIL");
2533 builder = LLVMCreateBuilder ();
2534 LLVMPositionBuilderAtEnd (builder, fail_bb);
2535 LLVMBuildRet (builder, LLVMConstNull (rtype));
2537 builder = LLVMCreateBuilder ();
2538 LLVMPositionBuilderAtEnd (builder, entry_bb);
2540 switch_ins = LLVMBuildSwitch (builder, LLVMGetParam (func, 0), fail_bb, 0);
2541 for (i = 0; i < module->max_method_idx + 1; ++i) {
2542 m = (LLVMValueRef)g_hash_table_lookup (module->idx_to_unbox_tramp, GINT_TO_POINTER (i));
2546 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), i, FALSE), bbs [i]);
2549 mark_as_used (module, func);
2552 /* Add a function to mark the beginning of LLVM code */
2554 emit_llvm_code_start (MonoLLVMModule *module)
2556 LLVMModuleRef lmodule = module->lmodule;
2558 LLVMBasicBlockRef entry_bb;
2559 LLVMBuilderRef builder;
2561 func = LLVMAddFunction (lmodule, "llvm_code_start", LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE));
2562 LLVMSetLinkage (func, LLVMInternalLinkage);
2563 LLVMAddFunctionAttr (func, LLVMNoUnwindAttribute);
2564 module->code_start = func;
2565 entry_bb = LLVMAppendBasicBlock (func, "ENTRY");
2566 builder = LLVMCreateBuilder ();
2567 LLVMPositionBuilderAtEnd (builder, entry_bb);
2568 LLVMBuildRetVoid (builder);
2572 emit_init_icall_wrapper (MonoLLVMModule *module, const char *name, const char *icall_name, int subtype)
2574 LLVMModuleRef lmodule = module->lmodule;
2575 LLVMValueRef func, indexes [2], got_entry_addr, args [16], callee;
2576 LLVMBasicBlockRef entry_bb;
2577 LLVMBuilderRef builder;
2584 func = LLVMAddFunction (lmodule, name, LLVMFunctionType1 (LLVMVoidType (), LLVMInt32Type (), FALSE));
2585 sig = LLVMFunctionType2 (LLVMVoidType (), IntPtrType (), LLVMInt32Type (), FALSE);
2590 func = LLVMAddFunction (lmodule, name, LLVMFunctionType2 (LLVMVoidType (), LLVMInt32Type (), IntPtrType (), FALSE));
2591 sig = LLVMFunctionType3 (LLVMVoidType (), IntPtrType (), LLVMInt32Type (), IntPtrType (), FALSE);
2594 func = LLVMAddFunction (lmodule, name, LLVMFunctionType2 (LLVMVoidType (), LLVMInt32Type (), ObjRefType (), FALSE));
2595 sig = LLVMFunctionType3 (LLVMVoidType (), IntPtrType (), LLVMInt32Type (), ObjRefType (), FALSE);
2598 g_assert_not_reached ();
2600 LLVMSetLinkage (func, LLVMInternalLinkage);
2601 LLVMAddFunctionAttr (func, LLVMNoInlineAttribute);
2602 mono_llvm_set_preserveall_cc (func);
2603 entry_bb = LLVMAppendBasicBlock (func, "ENTRY");
2604 builder = LLVMCreateBuilder ();
2605 LLVMPositionBuilderAtEnd (builder, entry_bb);
2608 ji = g_new0 (MonoJumpInfo, 1);
2609 ji->type = MONO_PATCH_INFO_AOT_MODULE;
2610 ji = mono_aot_patch_info_dup (ji);
2611 got_offset = mono_aot_get_got_offset (ji);
2612 module->max_got_offset = MAX (module->max_got_offset, got_offset);
2613 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
2614 indexes [1] = LLVMConstInt (LLVMInt32Type (), got_offset, FALSE);
2615 got_entry_addr = LLVMBuildGEP (builder, module->got_var, indexes, 2, "");
2616 args [0] = LLVMBuildPtrToInt (builder, LLVMBuildLoad (builder, got_entry_addr, ""), IntPtrType (), "");
2617 args [1] = LLVMGetParam (func, 0);
2619 args [2] = LLVMGetParam (func, 1);
2621 ji = g_new0 (MonoJumpInfo, 1);
2622 ji->type = MONO_PATCH_INFO_INTERNAL_METHOD;
2623 ji->data.name = icall_name;
2624 ji = mono_aot_patch_info_dup (ji);
2625 got_offset = mono_aot_get_got_offset (ji);
2626 module->max_got_offset = MAX (module->max_got_offset, got_offset);
2627 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
2628 indexes [1] = LLVMConstInt (LLVMInt32Type (), got_offset, FALSE);
2629 got_entry_addr = LLVMBuildGEP (builder, module->got_var, indexes, 2, "");
2630 callee = LLVMBuildLoad (builder, got_entry_addr, "");
2631 callee = LLVMBuildBitCast (builder, callee, LLVMPointerType (sig, 0), "");
2632 LLVMBuildCall (builder, callee, args, LLVMCountParamTypes (sig), "");
2634 // Set the inited flag
2635 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
2636 indexes [1] = LLVMGetParam (func, 0);
2637 LLVMBuildStore (builder, LLVMConstInt (LLVMInt8Type (), 1, FALSE), LLVMBuildGEP (builder, module->inited_var, indexes, 2, ""));
2639 LLVMBuildRetVoid (builder);
2641 LLVMVerifyFunction(func, LLVMAbortProcessAction);
2646 * Emit wrappers around the C icalls used to initialize llvm methods, to
2647 * make the calling code smaller and to enable usage of the llvm
2648 * PreserveAll calling convention.
2651 emit_init_icall_wrappers (MonoLLVMModule *module)
2653 module->init_method = emit_init_icall_wrapper (module, "init_method", "mono_aot_init_llvm_method", 0);
2654 module->init_method_gshared_mrgctx = emit_init_icall_wrapper (module, "init_method_gshared_mrgctx", "mono_aot_init_gshared_method_mrgctx", 1);
2655 module->init_method_gshared_this = emit_init_icall_wrapper (module, "init_method_gshared_this", "mono_aot_init_gshared_method_this", 2);
2656 module->init_method_gshared_vtable = emit_init_icall_wrapper (module, "init_method_gshared_vtable", "mono_aot_init_gshared_method_vtable", 3);
2660 emit_llvm_code_end (MonoLLVMModule *module)
2662 LLVMModuleRef lmodule = module->lmodule;
2664 LLVMBasicBlockRef entry_bb;
2665 LLVMBuilderRef builder;
2667 func = LLVMAddFunction (lmodule, "llvm_code_end", LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE));
2668 LLVMSetLinkage (func, LLVMInternalLinkage);
2669 LLVMAddFunctionAttr (func, LLVMNoUnwindAttribute);
2670 module->code_end = func;
2671 entry_bb = LLVMAppendBasicBlock (func, "ENTRY");
2672 builder = LLVMCreateBuilder ();
2673 LLVMPositionBuilderAtEnd (builder, entry_bb);
2674 LLVMBuildRetVoid (builder);
2678 emit_div_check (EmitContext *ctx, LLVMBuilderRef builder, MonoBasicBlock *bb, MonoInst *ins, LLVMValueRef lhs, LLVMValueRef rhs)
2680 gboolean need_div_check = ctx->cfg->backend->need_div_check;
2683 /* LLVM doesn't know that these can throw an exception since they are not called through an intrinsic */
2684 need_div_check = TRUE;
2686 if (!need_div_check)
2689 switch (ins->opcode) {
2702 case OP_IDIV_UN_IMM:
2703 case OP_LDIV_UN_IMM:
2704 case OP_IREM_UN_IMM:
2705 case OP_LREM_UN_IMM: {
2707 gboolean is_signed = (ins->opcode == OP_IDIV || ins->opcode == OP_LDIV || ins->opcode == OP_IREM || ins->opcode == OP_LREM ||
2708 ins->opcode == OP_IDIV_IMM || ins->opcode == OP_LDIV_IMM || ins->opcode == OP_IREM_IMM || ins->opcode == OP_LREM_IMM);
2710 cmp = LLVMBuildICmp (builder, LLVMIntEQ, rhs, LLVMConstInt (LLVMTypeOf (rhs), 0, FALSE), "");
2711 emit_cond_system_exception (ctx, bb, "DivideByZeroException", cmp);
2714 builder = ctx->builder;
2716 /* b == -1 && a == 0x80000000 */
2718 LLVMValueRef c = (LLVMTypeOf (lhs) == LLVMInt32Type ()) ? LLVMConstInt (LLVMTypeOf (lhs), 0x80000000, FALSE) : LLVMConstInt (LLVMTypeOf (lhs), 0x8000000000000000LL, FALSE);
2719 LLVMValueRef cond1 = LLVMBuildICmp (builder, LLVMIntEQ, rhs, LLVMConstInt (LLVMTypeOf (rhs), -1, FALSE), "");
2720 LLVMValueRef cond2 = LLVMBuildICmp (builder, LLVMIntEQ, lhs, c, "");
2722 cmp = LLVMBuildICmp (builder, LLVMIntEQ, LLVMBuildAnd (builder, cond1, cond2, ""), LLVMConstInt (LLVMInt1Type (), 1, FALSE), "");
2723 emit_cond_system_exception (ctx, bb, "OverflowException", cmp);
2726 builder = ctx->builder;
2738 * Emit code to initialize the GOT slots used by the method.
2741 emit_init_method (EmitContext *ctx)
2743 LLVMValueRef indexes [16], args [16], callee;
2744 LLVMValueRef inited_var, cmp, call;
2745 LLVMBasicBlockRef inited_bb, notinited_bb;
2746 LLVMBuilderRef builder = ctx->builder;
2747 MonoCompile *cfg = ctx->cfg;
2749 ctx->module->max_inited_idx = MAX (ctx->module->max_inited_idx, cfg->method_index);
2751 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
2752 indexes [1] = LLVMConstInt (LLVMInt32Type (), cfg->method_index, FALSE);
2753 inited_var = LLVMBuildLoad (builder, LLVMBuildGEP (builder, ctx->module->inited_var, indexes, 2, ""), "is_inited");
2755 args [0] = inited_var;
2756 args [1] = LLVMConstInt (LLVMInt8Type (), 1, FALSE);
2757 inited_var = LLVMBuildCall (ctx->builder, get_intrinsic (ctx, "llvm.expect.i8"), args, 2, "");
2759 cmp = LLVMBuildICmp (builder, LLVMIntEQ, inited_var, LLVMConstInt (LLVMTypeOf (inited_var), 0, FALSE), "");
2761 inited_bb = ctx->inited_bb;
2762 notinited_bb = gen_bb (ctx, "NOTINITED_BB");
2764 LLVMBuildCondBr (ctx->builder, cmp, notinited_bb, inited_bb);
2766 builder = ctx->builder = create_builder (ctx);
2767 LLVMPositionBuilderAtEnd (ctx->builder, notinited_bb);
2770 if (ctx->rgctx_arg && cfg->method->is_inflated && mono_method_get_context (cfg->method)->method_inst) {
2771 args [0] = LLVMConstInt (LLVMInt32Type (), cfg->method_index, 0);
2772 args [1] = convert (ctx, ctx->rgctx_arg, IntPtrType ());
2773 callee = ctx->module->init_method_gshared_mrgctx;
2774 call = LLVMBuildCall (builder, callee, args, 2, "");
2775 } else if (ctx->rgctx_arg) {
2776 /* A vtable is passed as the rgctx argument */
2777 args [0] = LLVMConstInt (LLVMInt32Type (), cfg->method_index, 0);
2778 args [1] = convert (ctx, ctx->rgctx_arg, IntPtrType ());
2779 callee = ctx->module->init_method_gshared_vtable;
2780 call = LLVMBuildCall (builder, callee, args, 2, "");
2781 } else if (cfg->gshared) {
2782 args [0] = LLVMConstInt (LLVMInt32Type (), cfg->method_index, 0);
2783 args [1] = convert (ctx, ctx->this_arg, ObjRefType ());
2784 callee = ctx->module->init_method_gshared_this;
2785 call = LLVMBuildCall (builder, callee, args, 2, "");
2787 args [0] = LLVMConstInt (LLVMInt32Type (), cfg->method_index, 0);
2788 callee = ctx->module->init_method;
2789 call = LLVMBuildCall (builder, callee, args, 1, "");
2793 * This enables llvm to keep arguments in their original registers/
2794 * scratch registers, since the call will not clobber them.
2796 mono_llvm_set_call_preserveall_cc (call);
2798 LLVMBuildBr (builder, inited_bb);
2799 ctx->bblocks [cfg->bb_entry->block_num].end_bblock = inited_bb;
2801 builder = ctx->builder = create_builder (ctx);
2802 LLVMPositionBuilderAtEnd (ctx->builder, inited_bb);
2806 emit_unbox_tramp (EmitContext *ctx, const char *method_name, LLVMTypeRef method_type, LLVMValueRef method, int method_index)
2809 * Emit unbox trampoline using a tail call
2811 LLVMValueRef tramp, call, *args;
2812 LLVMBuilderRef builder;
2813 LLVMBasicBlockRef lbb;
2814 LLVMCallInfo *linfo;
2818 tramp_name = g_strdup_printf ("ut_%s", method_name);
2819 tramp = LLVMAddFunction (ctx->module->lmodule, tramp_name, method_type);
2820 LLVMSetLinkage (tramp, LLVMInternalLinkage);
2821 LLVMAddFunctionAttr (tramp, LLVMOptimizeForSizeAttribute);
2822 //LLVMAddFunctionAttr (tramp, LLVMNoUnwindAttribute);
2824 // FIXME: Reduce code duplication with mono_llvm_compile_method () etc.
2825 if (!ctx->llvm_only && ctx->rgctx_arg_pindex != -1)
2826 LLVMAddAttribute (LLVMGetParam (tramp, ctx->rgctx_arg_pindex), LLVMInRegAttribute);
2827 if (ctx->cfg->vret_addr) {
2828 LLVMSetValueName (LLVMGetParam (tramp, linfo->vret_arg_pindex), "vret");
2829 if (linfo->ret.storage == LLVMArgVtypeByRef) {
2830 LLVMAddAttribute (LLVMGetParam (tramp, linfo->vret_arg_pindex), LLVMStructRetAttribute);
2831 LLVMAddAttribute (LLVMGetParam (tramp, linfo->vret_arg_pindex), LLVMNoAliasAttribute);
2835 lbb = LLVMAppendBasicBlock (tramp, "");
2836 builder = LLVMCreateBuilder ();
2837 LLVMPositionBuilderAtEnd (builder, lbb);
2839 nargs = LLVMCountParamTypes (method_type);
2840 args = g_new0 (LLVMValueRef, nargs);
2841 for (i = 0; i < nargs; ++i) {
2842 args [i] = LLVMGetParam (tramp, i);
2843 if (i == ctx->this_arg_pindex) {
2844 LLVMTypeRef arg_type = LLVMTypeOf (args [i]);
2846 args [i] = LLVMBuildPtrToInt (builder, args [i], IntPtrType (), "");
2847 args [i] = LLVMBuildAdd (builder, args [i], LLVMConstInt (IntPtrType (), sizeof (MonoObject), FALSE), "");
2848 args [i] = LLVMBuildIntToPtr (builder, args [i], arg_type, "");
2851 call = LLVMBuildCall (builder, method, args, nargs, "");
2852 if (!ctx->llvm_only && ctx->rgctx_arg_pindex != -1)
2853 LLVMAddInstrAttribute (call, 1 + ctx->rgctx_arg_pindex, LLVMInRegAttribute);
2854 if (linfo->ret.storage == LLVMArgVtypeByRef)
2855 LLVMAddInstrAttribute (call, 1 + linfo->vret_arg_pindex, LLVMStructRetAttribute);
2857 // FIXME: This causes assertions in clang
2858 //mono_llvm_set_must_tail (call);
2859 if (LLVMGetReturnType (method_type) == LLVMVoidType ())
2860 LLVMBuildRetVoid (builder);
2862 LLVMBuildRet (builder, call);
2864 g_hash_table_insert (ctx->module->idx_to_unbox_tramp, GINT_TO_POINTER (method_index), tramp);
2870 * Emit code to load/convert arguments.
2873 emit_entry_bb (EmitContext *ctx, LLVMBuilderRef builder)
2876 MonoCompile *cfg = ctx->cfg;
2877 MonoMethodSignature *sig = ctx->sig;
2878 LLVMCallInfo *linfo = ctx->linfo;
2882 LLVMBuilderRef old_builder = ctx->builder;
2883 ctx->builder = builder;
2885 ctx->alloca_builder = create_builder (ctx);
2888 * Handle indirect/volatile variables by allocating memory for them
2889 * using 'alloca', and storing their address in a temporary.
2891 for (i = 0; i < cfg->num_varinfo; ++i) {
2892 MonoInst *var = cfg->varinfo [i];
2895 if (var->opcode == OP_GSHAREDVT_LOCAL || var->opcode == OP_GSHAREDVT_ARG_REGOFFSET) {
2896 } else if (var->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT) || (mini_type_is_vtype (var->inst_vtype) && !MONO_CLASS_IS_SIMD (ctx->cfg, var->klass))) {
2897 vtype = type_to_llvm_type (ctx, var->inst_vtype);
2900 /* Could be already created by an OP_VPHI */
2901 if (!ctx->addresses [var->dreg]) {
2902 ctx->addresses [var->dreg] = build_alloca (ctx, var->inst_vtype);
2903 //LLVMSetValueName (ctx->addresses [var->dreg], g_strdup_printf ("vreg_loc_%d", var->dreg));
2905 ctx->vreg_cli_types [var->dreg] = var->inst_vtype;
2909 names = g_new (char *, sig->param_count);
2910 mono_method_get_param_names (cfg->method, (const char **) names);
2912 for (i = 0; i < sig->param_count; ++i) {
2913 LLVMArgInfo *ainfo = &linfo->args [i + sig->hasthis];
2914 int reg = cfg->args [i + sig->hasthis]->dreg;
2917 pindex = ainfo->pindex;
2919 switch (ainfo->storage) {
2920 case LLVMArgVtypeInReg:
2921 case LLVMArgAsFpArgs: {
2922 LLVMValueRef args [8];
2925 pindex += ainfo->ndummy_fpargs;
2927 /* The argument is received as a set of int/fp arguments, store them into the real argument */
2928 memset (args, 0, sizeof (args));
2929 if (ainfo->storage == LLVMArgVtypeInReg) {
2930 args [0] = LLVMGetParam (ctx->lmethod, pindex);
2931 if (ainfo->pair_storage [1] != LLVMArgNone)
2932 args [1] = LLVMGetParam (ctx->lmethod, pindex + 1);
2934 g_assert (ainfo->nslots <= 8);
2935 for (j = 0; j < ainfo->nslots; ++j)
2936 args [j] = LLVMGetParam (ctx->lmethod, pindex + j);
2938 ctx->addresses [reg] = build_alloca (ctx, ainfo->type);
2940 emit_args_to_vtype (ctx, builder, ainfo->type, ctx->addresses [reg], ainfo, args);
2942 if (ainfo->storage == LLVMArgVtypeInReg && MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (ainfo->type))) {
2943 /* Treat these as normal values */
2944 ctx->values [reg] = LLVMBuildLoad (builder, ctx->addresses [reg], "");
2948 case LLVMArgVtypeByVal: {
2949 ctx->addresses [reg] = LLVMGetParam (ctx->lmethod, pindex);
2951 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (ainfo->type))) {
2952 /* Treat these as normal values */
2953 ctx->values [reg] = LLVMBuildLoad (builder, ctx->addresses [reg], "");
2957 case LLVMArgVtypeByRef: {
2958 /* The argument is passed by ref */
2959 ctx->addresses [reg] = LLVMGetParam (ctx->lmethod, pindex);
2962 case LLVMArgAsIArgs: {
2963 LLVMValueRef arg = LLVMGetParam (ctx->lmethod, pindex);
2966 /* The argument is received as an array of ints, store it into the real argument */
2967 ctx->addresses [reg] = build_alloca (ctx, ainfo->type);
2969 size = mono_class_value_size (mono_class_from_mono_type (ainfo->type), NULL);
2970 if (size < SIZEOF_VOID_P) {
2971 /* The upper bits of the registers might not be valid */
2972 LLVMValueRef val = LLVMBuildExtractValue (builder, arg, 0, "");
2973 LLVMValueRef dest = convert (ctx, ctx->addresses [reg], LLVMPointerType (LLVMIntType (size * 8), 0));
2974 LLVMBuildStore (ctx->builder, LLVMBuildTrunc (builder, val, LLVMIntType (size * 8), ""), dest);
2976 LLVMBuildStore (ctx->builder, arg, convert (ctx, ctx->addresses [reg], LLVMPointerType (LLVMTypeOf (arg), 0)));
2980 case LLVMArgVtypeAsScalar:
2981 g_assert_not_reached ();
2983 case LLVMArgGsharedvtFixed: {
2984 /* These are non-gsharedvt arguments passed by ref, the rest of the IR treats them as scalars */
2985 LLVMValueRef arg = LLVMGetParam (ctx->lmethod, pindex);
2988 name = g_strdup_printf ("arg_%s", names [i]);
2990 name = g_strdup_printf ("arg_%d", i);
2992 ctx->values [reg] = LLVMBuildLoad (builder, convert (ctx, arg, LLVMPointerType (type_to_llvm_type (ctx, ainfo->type), 0)), name);
2995 case LLVMArgGsharedvtFixedVtype: {
2996 LLVMValueRef arg = LLVMGetParam (ctx->lmethod, pindex);
2999 name = g_strdup_printf ("vtype_arg_%s", names [i]);
3001 name = g_strdup_printf ("vtype_arg_%d", i);
3003 /* Non-gsharedvt vtype argument passed by ref, the rest of the IR treats it as a vtype */
3004 g_assert (ctx->addresses [reg]);
3005 LLVMSetValueName (ctx->addresses [reg], name);
3006 LLVMBuildStore (builder, LLVMBuildLoad (builder, convert (ctx, arg, LLVMPointerType (type_to_llvm_type (ctx, ainfo->type), 0)), ""), ctx->addresses [reg]);
3009 case LLVMArgGsharedvtVariable:
3010 /* The IR treats these as variables with addresses */
3011 ctx->addresses [reg] = LLVMGetParam (ctx->lmethod, pindex);
3014 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));
3021 emit_volatile_store (ctx, cfg->vret_addr->dreg);
3023 emit_volatile_store (ctx, cfg->args [0]->dreg);
3024 for (i = 0; i < sig->param_count; ++i)
3025 if (!mini_type_is_vtype (sig->params [i]))
3026 emit_volatile_store (ctx, cfg->args [i + sig->hasthis]->dreg);
3028 if (sig->hasthis && !cfg->rgctx_var && cfg->gshared) {
3029 LLVMValueRef this_alloc;
3032 * The exception handling code needs the location where the this argument was
3033 * stored for gshared methods. We create a separate alloca to hold it, and mark it
3034 * with the "mono.this" custom metadata to tell llvm that it needs to save its
3035 * location into the LSDA.
3037 this_alloc = mono_llvm_build_alloca (builder, ThisType (), LLVMConstInt (LLVMInt32Type (), 1, FALSE), 0, "");
3038 /* This volatile store will keep the alloca alive */
3039 mono_llvm_build_store (builder, ctx->values [cfg->args [0]->dreg], this_alloc, TRUE, LLVM_BARRIER_NONE);
3041 set_metadata_flag (this_alloc, "mono.this");
3044 if (cfg->rgctx_var) {
3045 LLVMValueRef rgctx_alloc, store;
3048 * We handle the rgctx arg similarly to the this pointer.
3050 g_assert (ctx->addresses [cfg->rgctx_var->dreg]);
3051 rgctx_alloc = ctx->addresses [cfg->rgctx_var->dreg];
3052 /* This volatile store will keep the alloca alive */
3053 store = mono_llvm_build_store (builder, convert (ctx, ctx->rgctx_arg, IntPtrType ()), rgctx_alloc, TRUE, LLVM_BARRIER_NONE);
3055 set_metadata_flag (rgctx_alloc, "mono.this");
3058 /* Initialize the method if needed */
3059 if (cfg->compile_aot && ctx->llvm_only) {
3060 /* Emit a location for the initialization code */
3061 ctx->init_bb = gen_bb (ctx, "INIT_BB");
3062 ctx->inited_bb = gen_bb (ctx, "INITED_BB");
3064 LLVMBuildBr (ctx->builder, ctx->init_bb);
3065 builder = ctx->builder = create_builder (ctx);
3066 LLVMPositionBuilderAtEnd (ctx->builder, ctx->inited_bb);
3067 ctx->bblocks [cfg->bb_entry->block_num].end_bblock = ctx->inited_bb;
3070 /* Compute nesting between clauses */
3071 ctx->nested_in = (GSList**)mono_mempool_alloc0 (cfg->mempool, sizeof (GSList*) * cfg->header->num_clauses);
3072 for (i = 0; i < cfg->header->num_clauses; ++i) {
3073 for (j = 0; j < cfg->header->num_clauses; ++j) {
3074 MonoExceptionClause *clause1 = &cfg->header->clauses [i];
3075 MonoExceptionClause *clause2 = &cfg->header->clauses [j];
3077 if (i != j && clause1->try_offset >= clause2->try_offset && clause1->handler_offset <= clause2->handler_offset)
3078 ctx->nested_in [i] = g_slist_prepend_mempool (cfg->mempool, ctx->nested_in [i], GINT_TO_POINTER (j));
3083 * For finally clauses, create an indicator variable telling OP_ENDFINALLY whenever
3084 * it needs to continue normally, or return back to the exception handling system.
3086 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
3090 if (!(bb->region != -1 && (bb->flags & BB_EXCEPTION_HANDLER)))
3093 clause_index = MONO_REGION_CLAUSE_INDEX (bb->region);
3094 g_hash_table_insert (ctx->region_to_handler, GUINT_TO_POINTER (mono_get_block_region_notry (cfg, bb->region)), bb);
3095 g_hash_table_insert (ctx->clause_to_handler, GINT_TO_POINTER (clause_index), bb);
3097 if (bb->in_scount == 0) {
3100 sprintf (name, "finally_ind_bb%d", bb->block_num);
3101 val = LLVMBuildAlloca (builder, LLVMInt32Type (), name);
3102 LLVMBuildStore (builder, LLVMConstInt (LLVMInt32Type (), 0, FALSE), val);
3104 ctx->bblocks [bb->block_num].finally_ind = val;
3106 /* Create a variable to hold the exception var */
3108 ctx->ex_var = LLVMBuildAlloca (builder, ObjRefType (), "exvar");
3112 * Create a new bblock which CALL_HANDLER/landing pads can branch to, because branching to the
3113 * LLVM bblock containing a landing pad causes problems for the
3114 * LLVM optimizer passes.
3116 sprintf (name, "BB%d_CALL_HANDLER_TARGET", bb->block_num);
3117 ctx->bblocks [bb->block_num].call_handler_target_bb = LLVMAppendBasicBlock (ctx->lmethod, name);
3119 ctx->builder = old_builder;
3123 process_call (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, MonoInst *ins)
3125 MonoCompile *cfg = ctx->cfg;
3126 LLVMValueRef *values = ctx->values;
3127 LLVMValueRef *addresses = ctx->addresses;
3128 MonoCallInst *call = (MonoCallInst*)ins;
3129 MonoMethodSignature *sig = call->signature;
3130 LLVMValueRef callee = NULL, lcall;
3132 LLVMCallInfo *cinfo;
3136 LLVMTypeRef llvm_sig;
3138 gboolean is_virtual, calli, preserveall;
3139 LLVMBuilderRef builder = *builder_ref;
3141 if (call->signature->call_convention != MONO_CALL_DEFAULT) {
3142 set_failure (ctx, "non-default callconv");
3146 cinfo = call->cinfo;
3148 if (call->rgctx_arg_reg)
3149 cinfo->rgctx_arg = TRUE;
3150 if (call->imt_arg_reg)
3151 cinfo->imt_arg = TRUE;
3153 vretaddr = (cinfo->ret.storage == LLVMArgVtypeRetAddr || cinfo->ret.storage == LLVMArgVtypeByRef || cinfo->ret.storage == LLVMArgGsharedvtFixed || cinfo->ret.storage == LLVMArgGsharedvtVariable || cinfo->ret.storage == LLVMArgGsharedvtFixedVtype);
3155 llvm_sig = sig_to_llvm_sig_full (ctx, sig, cinfo);
3159 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);
3160 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);
3162 preserveall = FALSE;
3164 /* FIXME: Avoid creating duplicate methods */
3166 if (ins->flags & MONO_INST_HAS_METHOD) {
3170 if (cfg->compile_aot) {
3171 callee = get_callee (ctx, llvm_sig, MONO_PATCH_INFO_METHOD, call->method);
3173 set_failure (ctx, "can't encode patch");
3176 if (cfg->llvm_only && call->method->klass->image->assembly == ctx->module->assembly) {
3178 * Collect instructions representing the callee into a hash so they can be replaced
3179 * by the llvm method for the callee if the callee turns out to be direct
3180 * callable. Currently this only requires it to not fail llvm compilation.
3182 GSList *l = (GSList*)g_hash_table_lookup (ctx->method_to_callers, call->method);
3183 l = g_slist_prepend (l, callee);
3184 g_hash_table_insert (ctx->method_to_callers, call->method, l);
3188 static int tramp_index;
3191 name = g_strdup_printf ("tramp_%d", tramp_index);
3194 #if LLVM_API_VERSION > 100
3196 * Use our trampoline infrastructure for lazy compilation instead of llvm's.
3197 * Make all calls through a global. The address of the global will be saved in
3198 * MonoJitDomainInfo.llvm_jit_callees and updated when the method it refers to is
3201 LLVMValueRef tramp_var = g_hash_table_lookup (ctx->jit_callees, call->method);
3204 mono_create_jit_trampoline (mono_domain_get (),
3205 call->method, &error);
3206 if (!mono_error_ok (&error))
3207 mono_error_raise_exception (&error); /* FIXME: Don't raise here */
3208 tramp_var = LLVMAddGlobal (ctx->lmodule, LLVMPointerType (llvm_sig, 0), name);
3209 LLVMSetInitializer (tramp_var, LLVMConstIntToPtr (LLVMConstInt (LLVMInt64Type (), (guint64)(size_t)target, FALSE), LLVMPointerType (llvm_sig, 0)));
3210 LLVMSetLinkage (tramp_var, LLVMExternalLinkage);
3211 g_hash_table_insert (ctx->jit_callees, call->method, tramp_var);
3213 callee = LLVMBuildLoad (builder, tramp_var, "");
3216 mono_create_jit_trampoline (mono_domain_get (),
3217 call->method, &error);
3218 if (!mono_error_ok (&error))
3219 mono_error_raise_exception (&error); /* FIXME: Don't raise here */
3221 callee = LLVMAddFunction (ctx->lmodule, name, llvm_sig);
3224 if (!mono_error_ok (&error))
3225 mono_error_raise_exception (&error); /* FIXME: Don't raise here */
3226 LLVMAddGlobalMapping (ctx->module->ee, callee, target);
3231 if (!cfg->llvm_only && call->method && strstr (call->method->klass->name, "AsyncVoidMethodBuilder")) {
3232 /* LLVM miscompiles async methods */
3233 set_failure (ctx, "#13734");
3238 MonoJitICallInfo *info = mono_find_jit_icall_by_addr (call->fptr);
3244 memset (&ji, 0, sizeof (ji));
3245 ji.type = MONO_PATCH_INFO_JIT_ICALL_ADDR;
3246 ji.data.target = info->name;
3248 target = mono_resolve_patch_target (cfg->method, cfg->domain, NULL, &ji, FALSE);
3250 if (cfg->compile_aot) {
3251 callee = get_callee (ctx, llvm_sig, MONO_PATCH_INFO_INTERNAL_METHOD, (char*)info->name);
3253 set_failure (ctx, "can't encode patch");
3257 target = (gpointer)mono_icall_get_wrapper (info);
3258 callee = emit_jit_callee (ctx, "", llvm_sig, target);
3261 if (cfg->compile_aot) {
3263 if (cfg->abs_patches) {
3264 MonoJumpInfo *abs_ji = (MonoJumpInfo*)g_hash_table_lookup (cfg->abs_patches, call->fptr);
3266 callee = get_callee (ctx, llvm_sig, abs_ji->type, abs_ji->data.target);
3268 set_failure (ctx, "can't encode patch");
3274 set_failure (ctx, "aot");
3278 #if LLVM_API_VERSION > 100
3279 if (cfg->abs_patches) {
3280 MonoJumpInfo *abs_ji = (MonoJumpInfo*)g_hash_table_lookup (cfg->abs_patches, call->fptr);
3284 target = mono_resolve_patch_target (cfg->method, cfg->domain, NULL, abs_ji, FALSE, &error);
3285 mono_error_assert_ok (&error);
3286 callee = emit_jit_callee (ctx, "", llvm_sig, target);
3288 g_assert_not_reached ();
3291 g_assert_not_reached ();
3294 callee = LLVMAddFunction (ctx->lmodule, "", llvm_sig);
3296 if (cfg->abs_patches) {
3297 MonoJumpInfo *abs_ji = (MonoJumpInfo*)g_hash_table_lookup (cfg->abs_patches, call->fptr);
3302 * FIXME: Some trampolines might have
3303 * their own calling convention on some platforms.
3305 target = mono_resolve_patch_target (cfg->method, cfg->domain, NULL, abs_ji, FALSE, &error);
3306 mono_error_assert_ok (&error);
3307 LLVMAddGlobalMapping (ctx->module->ee, callee, target);
3311 LLVMAddGlobalMapping (ctx->module->ee, callee, (gpointer)call->fptr);
3318 int size = sizeof (gpointer);
3321 g_assert (ins->inst_offset % size == 0);
3322 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
3324 callee = convert (ctx, LLVMBuildLoad (builder, LLVMBuildGEP (builder, convert (ctx, values [ins->inst_basereg], LLVMPointerType (LLVMPointerType (IntPtrType (), 0), 0)), &index, 1, ""), ""), LLVMPointerType (llvm_sig, 0));
3326 callee = convert (ctx, values [ins->sreg1], LLVMPointerType (llvm_sig, 0));
3328 if (ins->flags & MONO_INST_HAS_METHOD) {
3333 * Collect and convert arguments
3335 nargs = (sig->param_count * 16) + sig->hasthis + vretaddr + call->rgctx_reg + call->imt_arg_reg;
3336 len = sizeof (LLVMValueRef) * nargs;
3337 args = (LLVMValueRef*)alloca (len);
3338 memset (args, 0, len);
3339 l = call->out_ireg_args;
3341 if (call->rgctx_arg_reg) {
3342 g_assert (values [call->rgctx_arg_reg]);
3343 g_assert (cinfo->rgctx_arg_pindex < nargs);
3345 * On ARM, the imt/rgctx argument is passed in a caller save register, but some of our trampolines etc. clobber it, leading to
3346 * problems is LLVM moves the arg assignment earlier. To work around this, save the argument into a stack slot and load
3347 * it using a volatile load.
3350 if (!ctx->imt_rgctx_loc)
3351 ctx->imt_rgctx_loc = build_alloca_llvm_type (ctx, ctx->module->ptr_type, sizeof (gpointer));
3352 LLVMBuildStore (builder, convert (ctx, ctx->values [call->rgctx_arg_reg], ctx->module->ptr_type), ctx->imt_rgctx_loc);
3353 args [cinfo->rgctx_arg_pindex] = mono_llvm_build_load (builder, ctx->imt_rgctx_loc, "", TRUE, LLVM_BARRIER_NONE);
3355 args [cinfo->rgctx_arg_pindex] = convert (ctx, values [call->rgctx_arg_reg], ctx->module->ptr_type);
3358 if (call->imt_arg_reg) {
3359 g_assert (!ctx->llvm_only);
3360 g_assert (values [call->imt_arg_reg]);
3361 g_assert (cinfo->imt_arg_pindex < nargs);
3363 if (!ctx->imt_rgctx_loc)
3364 ctx->imt_rgctx_loc = build_alloca_llvm_type (ctx, ctx->module->ptr_type, sizeof (gpointer));
3365 LLVMBuildStore (builder, convert (ctx, ctx->values [call->imt_arg_reg], ctx->module->ptr_type), ctx->imt_rgctx_loc);
3366 args [cinfo->imt_arg_pindex] = mono_llvm_build_load (builder, ctx->imt_rgctx_loc, "", TRUE, LLVM_BARRIER_NONE);
3368 args [cinfo->imt_arg_pindex] = convert (ctx, values [call->imt_arg_reg], ctx->module->ptr_type);
3371 switch (cinfo->ret.storage) {
3372 case LLVMArgGsharedvtVariable: {
3373 MonoInst *var = get_vreg_to_inst (cfg, call->inst.dreg);
3375 if (var && var->opcode == OP_GSHAREDVT_LOCAL) {
3376 args [cinfo->vret_arg_pindex] = convert (ctx, emit_gsharedvt_ldaddr (ctx, var->dreg), IntPtrType ());
3378 g_assert (addresses [call->inst.dreg]);
3379 args [cinfo->vret_arg_pindex] = addresses [call->inst.dreg];
3385 if (!addresses [call->inst.dreg])
3386 addresses [call->inst.dreg] = build_alloca (ctx, sig->ret);
3387 g_assert (cinfo->vret_arg_pindex < nargs);
3388 if (cinfo->ret.storage == LLVMArgVtypeByRef)
3389 args [cinfo->vret_arg_pindex] = addresses [call->inst.dreg];
3391 args [cinfo->vret_arg_pindex] = LLVMBuildPtrToInt (builder, addresses [call->inst.dreg], IntPtrType (), "");
3397 * Sometimes the same method is called with two different signatures (i.e. with and without 'this'), so
3398 * use the real callee for argument type conversion.
3400 LLVMTypeRef callee_type = LLVMGetElementType (LLVMTypeOf (callee));
3401 LLVMTypeRef *param_types = (LLVMTypeRef*)g_alloca (sizeof (LLVMTypeRef) * LLVMCountParamTypes (callee_type));
3402 LLVMGetParamTypes (callee_type, param_types);
3404 for (i = 0; i < sig->param_count + sig->hasthis; ++i) {
3407 LLVMArgInfo *ainfo = &call->cinfo->args [i];
3409 pindex = ainfo->pindex;
3411 regpair = (guint32)(gssize)(l->data);
3412 reg = regpair & 0xffffff;
3413 args [pindex] = values [reg];
3414 switch (ainfo->storage) {
3415 case LLVMArgVtypeInReg:
3416 case LLVMArgAsFpArgs: {
3420 for (j = 0; j < ainfo->ndummy_fpargs; ++j)
3421 args [pindex + j] = LLVMConstNull (LLVMDoubleType ());
3422 pindex += ainfo->ndummy_fpargs;
3424 g_assert (addresses [reg]);
3425 emit_vtype_to_args (ctx, builder, ainfo->type, addresses [reg], ainfo, args + pindex, &nargs);
3429 // FIXME: Get rid of the VMOVE
3432 case LLVMArgVtypeByVal:
3433 g_assert (addresses [reg]);
3434 args [pindex] = addresses [reg];
3436 case LLVMArgVtypeByRef: {
3437 g_assert (addresses [reg]);
3438 args [pindex] = convert (ctx, addresses [reg], LLVMPointerType (type_to_llvm_arg_type (ctx, ainfo->type), 0));
3441 case LLVMArgAsIArgs:
3442 g_assert (addresses [reg]);
3443 args [pindex] = LLVMBuildLoad (ctx->builder, convert (ctx, addresses [reg], LLVMPointerType (LLVMArrayType (IntPtrType (), ainfo->nslots), 0)), "");
3445 case LLVMArgVtypeAsScalar:
3446 g_assert_not_reached ();
3448 case LLVMArgGsharedvtFixed:
3449 case LLVMArgGsharedvtFixedVtype:
3450 g_assert (addresses [reg]);
3451 args [pindex] = convert (ctx, addresses [reg], LLVMPointerType (type_to_llvm_arg_type (ctx, ainfo->type), 0));
3453 case LLVMArgGsharedvtVariable:
3454 g_assert (addresses [reg]);
3455 args [pindex] = convert (ctx, addresses [reg], LLVMPointerType (IntPtrType (), 0));
3458 g_assert (args [pindex]);
3459 if (i == 0 && sig->hasthis)
3460 args [pindex] = convert (ctx, args [pindex], param_types [pindex]);
3462 args [pindex] = convert (ctx, args [pindex], type_to_llvm_arg_type (ctx, ainfo->type));
3465 g_assert (pindex <= nargs);
3470 // FIXME: Align call sites
3476 lcall = emit_call (ctx, bb, &builder, callee, args, LLVMCountParamTypes (llvm_sig));
3479 * Modify cconv and parameter attributes to pass rgctx/imt correctly.
3481 #if defined(MONO_ARCH_IMT_REG) && defined(MONO_ARCH_RGCTX_REG)
3482 g_assert (MONO_ARCH_IMT_REG == MONO_ARCH_RGCTX_REG);
3484 /* The two can't be used together, so use only one LLVM calling conv to pass them */
3485 g_assert (!(call->rgctx_arg_reg && call->imt_arg_reg));
3486 if (!sig->pinvoke && !cfg->llvm_only)
3487 LLVMSetInstructionCallConv (lcall, LLVMMono1CallConv);
3489 mono_llvm_set_call_preserveall_cc (lcall);
3491 if (cinfo->ret.storage == LLVMArgVtypeByRef)
3492 LLVMAddInstrAttribute (lcall, 1 + cinfo->vret_arg_pindex, LLVMStructRetAttribute);
3493 if (!ctx->llvm_only && call->rgctx_arg_reg)
3494 LLVMAddInstrAttribute (lcall, 1 + cinfo->rgctx_arg_pindex, LLVMInRegAttribute);
3495 if (call->imt_arg_reg)
3496 LLVMAddInstrAttribute (lcall, 1 + cinfo->imt_arg_pindex, LLVMInRegAttribute);
3498 /* Add byval attributes if needed */
3499 for (i = 0; i < sig->param_count; ++i) {
3500 LLVMArgInfo *ainfo = &call->cinfo->args [i + sig->hasthis];
3502 if (ainfo && ainfo->storage == LLVMArgVtypeByVal)
3503 LLVMAddInstrAttribute (lcall, 1 + ainfo->pindex, LLVMByValAttribute);
3507 * Convert the result
3509 switch (cinfo->ret.storage) {
3510 case LLVMArgVtypeInReg: {
3511 LLVMValueRef regs [2];
3513 if (LLVMTypeOf (lcall) == LLVMVoidType ())
3517 if (!addresses [ins->dreg])
3518 addresses [ins->dreg] = build_alloca (ctx, sig->ret);
3520 regs [0] = LLVMBuildExtractValue (builder, lcall, 0, "");
3521 if (cinfo->ret.pair_storage [1] != LLVMArgNone)
3522 regs [1] = LLVMBuildExtractValue (builder, lcall, 1, "");
3523 emit_args_to_vtype (ctx, builder, sig->ret, addresses [ins->dreg], &cinfo->ret, regs);
3526 case LLVMArgVtypeByVal:
3527 if (!addresses [call->inst.dreg])
3528 addresses [call->inst.dreg] = build_alloca (ctx, sig->ret);
3529 LLVMBuildStore (builder, lcall, addresses [call->inst.dreg]);
3531 case LLVMArgFpStruct:
3532 if (!addresses [call->inst.dreg])
3533 addresses [call->inst.dreg] = build_alloca (ctx, sig->ret);
3534 LLVMBuildStore (builder, lcall, convert_full (ctx, addresses [call->inst.dreg], LLVMPointerType (LLVMTypeOf (lcall), 0), FALSE));
3536 case LLVMArgVtypeAsScalar:
3537 if (!addresses [call->inst.dreg])
3538 addresses [call->inst.dreg] = build_alloca (ctx, sig->ret);
3539 LLVMBuildStore (builder, lcall, convert_full (ctx, addresses [call->inst.dreg], LLVMPointerType (LLVMTypeOf (lcall), 0), FALSE));
3541 case LLVMArgVtypeRetAddr:
3542 case LLVMArgVtypeByRef:
3543 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (sig->ret))) {
3544 /* Some opcodes like STOREX_MEMBASE access these by value */
3545 g_assert (addresses [call->inst.dreg]);
3546 values [ins->dreg] = LLVMBuildLoad (builder, convert_full (ctx, addresses [call->inst.dreg], LLVMPointerType (type_to_llvm_type (ctx, sig->ret), 0), FALSE), "");
3549 case LLVMArgGsharedvtVariable:
3551 case LLVMArgGsharedvtFixed:
3552 case LLVMArgGsharedvtFixedVtype:
3553 values [ins->dreg] = LLVMBuildLoad (builder, convert_full (ctx, addresses [call->inst.dreg], LLVMPointerType (type_to_llvm_type (ctx, sig->ret), 0), FALSE), "");
3556 if (sig->ret->type != MONO_TYPE_VOID)
3557 /* If the method returns an unsigned value, need to zext it */
3558 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));
3562 *builder_ref = ctx->builder;
3566 emit_llvmonly_throw (EmitContext *ctx, MonoBasicBlock *bb, gboolean rethrow, LLVMValueRef exc)
3568 const char *icall_name = rethrow ? "mono_llvm_rethrow_exception" : "mono_llvm_throw_exception";
3569 LLVMValueRef callee = rethrow ? ctx->module->rethrow : ctx->module->throw_icall;
3571 LLVMTypeRef exc_type = type_to_llvm_type (ctx, &mono_get_exception_class ()->byval_arg);
3574 LLVMTypeRef fun_sig = LLVMFunctionType1 (LLVMVoidType (), exc_type, FALSE);
3576 if (ctx->cfg->compile_aot) {
3577 callee = get_callee (ctx, fun_sig, MONO_PATCH_INFO_JIT_ICALL_ADDR, icall_name);
3579 callee = LLVMAddFunction (ctx->lmodule, icall_name, fun_sig);
3580 LLVMAddGlobalMapping (ctx->module->ee, callee, resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name));
3581 mono_memory_barrier ();
3584 ctx->module->rethrow = callee;
3586 ctx->module->throw_icall = callee;
3590 LLVMValueRef args [2];
3592 args [0] = convert (ctx, exc, exc_type);
3593 emit_call (ctx, bb, &ctx->builder, callee, args, 1);
3595 LLVMBuildUnreachable (ctx->builder);
3597 ctx->builder = create_builder (ctx);
3601 emit_throw (EmitContext *ctx, MonoBasicBlock *bb, gboolean rethrow, LLVMValueRef exc)
3603 MonoMethodSignature *throw_sig;
3604 LLVMValueRef callee, arg;
3605 const char *icall_name;
3607 callee = rethrow ? ctx->module->rethrow : ctx->module->throw_icall;
3608 icall_name = rethrow ? "mono_arch_rethrow_exception" : "mono_arch_throw_exception";
3611 throw_sig = mono_metadata_signature_alloc (mono_get_corlib (), 1);
3612 throw_sig->ret = &mono_get_void_class ()->byval_arg;
3613 throw_sig->params [0] = &mono_get_object_class ()->byval_arg;
3614 if (ctx->cfg->compile_aot) {
3615 callee = get_callee (ctx, sig_to_llvm_sig (ctx, throw_sig), MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
3620 * LLVM doesn't push the exception argument, so we need a different
3623 target = resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, rethrow ? "llvm_rethrow_exception_trampoline" : "llvm_throw_exception_trampoline");
3625 target = resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
3627 callee = emit_jit_callee (ctx, icall_name, sig_to_llvm_sig (ctx, throw_sig), target);
3630 mono_memory_barrier ();
3631 #if LLVM_API_VERSION < 100
3633 ctx->module->rethrow = callee;
3635 ctx->module->throw_icall = callee;
3638 arg = convert (ctx, exc, type_to_llvm_type (ctx, &mono_get_object_class ()->byval_arg));
3639 emit_call (ctx, bb, &ctx->builder, callee, &arg, 1);
3643 emit_resume_eh (EmitContext *ctx, MonoBasicBlock *bb)
3645 const char *icall_name = "mono_llvm_resume_exception";
3646 LLVMValueRef callee = ctx->module->resume_eh;
3648 LLVMTypeRef fun_sig = LLVMFunctionType0 (LLVMVoidType (), FALSE);
3651 if (ctx->cfg->compile_aot) {
3652 callee = get_callee (ctx, fun_sig, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
3654 callee = LLVMAddFunction (ctx->lmodule, icall_name, fun_sig);
3655 LLVMAddGlobalMapping (ctx->module->ee, callee, resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name));
3656 mono_memory_barrier ();
3658 ctx->module->resume_eh = callee;
3662 emit_call (ctx, bb, &ctx->builder, callee, NULL, 0);
3664 LLVMBuildUnreachable (ctx->builder);
3666 ctx->builder = create_builder (ctx);
3670 mono_llvm_emit_clear_exception_call (EmitContext *ctx, LLVMBuilderRef builder)
3672 const char *icall_name = "mono_llvm_clear_exception";
3674 LLVMTypeRef call_sig = LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE);
3675 LLVMValueRef callee = NULL;
3678 if (ctx->cfg->compile_aot) {
3679 callee = get_callee (ctx, call_sig, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
3681 // FIXME: This is broken.
3682 callee = LLVMAddFunction (ctx->lmodule, icall_name, call_sig);
3686 g_assert (builder && callee);
3688 return LLVMBuildCall (builder, callee, NULL, 0, "");
3692 mono_llvm_emit_load_exception_call (EmitContext *ctx, LLVMBuilderRef builder)
3694 const char *icall_name = "mono_llvm_load_exception";
3696 LLVMTypeRef call_sig = LLVMFunctionType (ObjRefType (), NULL, 0, FALSE);
3697 LLVMValueRef callee = NULL;
3700 if (ctx->cfg->compile_aot) {
3701 callee = get_callee (ctx, call_sig, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
3703 // FIXME: This is broken.
3704 callee = LLVMAddFunction (ctx->lmodule, icall_name, call_sig);
3708 g_assert (builder && callee);
3710 return LLVMBuildCall (builder, callee, NULL, 0, icall_name);
3715 mono_llvm_emit_match_exception_call (EmitContext *ctx, LLVMBuilderRef builder, gint32 region_start, gint32 region_end)
3717 const char *icall_name = "mono_llvm_match_exception";
3719 ctx->builder = builder;
3721 const int num_args = 5;
3722 LLVMValueRef args [num_args];
3723 args [0] = convert (ctx, get_aotconst (ctx, MONO_PATCH_INFO_AOT_JIT_INFO, GINT_TO_POINTER (ctx->cfg->method_index)), IntPtrType ());
3724 args [1] = LLVMConstInt (LLVMInt32Type (), region_start, 0);
3725 args [2] = LLVMConstInt (LLVMInt32Type (), region_end, 0);
3726 if (ctx->cfg->rgctx_var) {
3727 LLVMValueRef rgctx_alloc = ctx->addresses [ctx->cfg->rgctx_var->dreg];
3728 g_assert (rgctx_alloc);
3729 args [3] = LLVMBuildLoad (builder, convert (ctx, rgctx_alloc, LLVMPointerType (IntPtrType (), 0)), "");
3731 args [3] = LLVMConstInt (IntPtrType (), 0, 0);
3734 args [4] = convert (ctx, ctx->this_arg, IntPtrType ());
3736 args [4] = LLVMConstInt (IntPtrType (), 0, 0);
3738 LLVMTypeRef match_sig = LLVMFunctionType5 (LLVMInt32Type (), IntPtrType (), LLVMInt32Type (), LLVMInt32Type (), IntPtrType (), IntPtrType (), FALSE);
3739 LLVMValueRef callee = ctx->module->match_exc;
3742 if (ctx->cfg->compile_aot) {
3743 ctx->builder = builder;
3744 // get_callee expects ctx->builder to be the emitting builder
3745 callee = get_callee (ctx, match_sig, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
3747 callee = ctx->module->match_exc = LLVMAddFunction (ctx->lmodule, icall_name, match_sig);
3748 LLVMAddGlobalMapping (ctx->module->ee, ctx->module->match_exc, resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name));
3749 ctx->module->match_exc = callee;
3750 mono_memory_barrier ();
3754 g_assert (builder && callee);
3756 g_assert (ctx->ex_var);
3758 return LLVMBuildCall (builder, callee, args, num_args, icall_name);
3761 // FIXME: This won't work because the code-finding makes this
3763 /*#define MONO_PERSONALITY_DEBUG*/
3765 #ifdef MONO_PERSONALITY_DEBUG
3766 static const gboolean use_debug_personality = TRUE;
3767 static const char *default_personality_name = "mono_debug_personality";
3769 static const gboolean use_debug_personality = FALSE;
3770 static const char *default_personality_name = "__gxx_personality_v0";
3774 default_cpp_lpad_exc_signature (void)
3776 static gboolean inited = FALSE;
3777 static LLVMTypeRef sig;
3780 LLVMTypeRef signature [2];
3781 signature [0] = LLVMPointerType (LLVMInt8Type (), 0);
3782 signature [1] = LLVMInt32Type ();
3783 sig = LLVMStructType (signature, 2, FALSE);
3791 get_mono_personality (EmitContext *ctx)
3793 LLVMValueRef personality = NULL;
3794 static gint32 mapping_inited = FALSE;
3795 LLVMTypeRef personality_type = LLVMFunctionType (LLVMInt32Type (), NULL, 0, TRUE);
3797 if (!use_debug_personality) {
3798 if (ctx->cfg->compile_aot) {
3799 personality = get_intrinsic (ctx, default_personality_name);
3800 } else if (InterlockedCompareExchange (&mapping_inited, 1, 0) == 0) {
3801 personality = LLVMAddFunction (ctx->lmodule, default_personality_name, personality_type);
3802 LLVMAddGlobalMapping (ctx->module->ee, personality, personality);
3805 if (ctx->cfg->compile_aot) {
3806 personality = get_callee (ctx, personality_type, MONO_PATCH_INFO_INTERNAL_METHOD, default_personality_name);
3808 personality = LLVMAddFunction (ctx->lmodule, default_personality_name, personality_type);
3809 LLVMAddGlobalMapping (ctx->module->ee, personality, resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, default_personality_name));
3810 mono_memory_barrier ();
3814 g_assert (personality);
3818 static LLVMBasicBlockRef
3819 emit_landing_pad (EmitContext *ctx, int group_index, int group_size)
3821 MonoCompile *cfg = ctx->cfg;
3822 LLVMBuilderRef old_builder = ctx->builder;
3823 MonoExceptionClause *group_start = cfg->header->clauses + group_index;
3825 LLVMBuilderRef lpadBuilder = create_builder (ctx);
3826 ctx->builder = lpadBuilder;
3828 MonoBasicBlock *handler_bb = cfg->cil_offset_to_bb [CLAUSE_START (group_start)];
3829 g_assert (handler_bb);
3831 // <resultval> = landingpad <somety> personality <type> <pers_fn> <clause>+
3832 LLVMValueRef personality = get_mono_personality (ctx);
3833 g_assert (personality);
3835 char *bb_name = g_strdup_printf ("LPAD%d_BB", group_index);
3836 LLVMBasicBlockRef lpad_bb = gen_bb (ctx, bb_name);
3838 LLVMPositionBuilderAtEnd (lpadBuilder, lpad_bb);
3839 LLVMValueRef landing_pad = LLVMBuildLandingPad (lpadBuilder, default_cpp_lpad_exc_signature (), personality, 0, "");
3840 g_assert (landing_pad);
3842 LLVMValueRef cast = LLVMBuildBitCast (lpadBuilder, ctx->module->sentinel_exception, LLVMPointerType (LLVMInt8Type (), 0), "int8TypeInfo");
3843 LLVMAddClause (landing_pad, cast);
3845 LLVMBasicBlockRef resume_bb = gen_bb (ctx, "RESUME_BB");
3846 LLVMBuilderRef resume_builder = create_builder (ctx);
3847 ctx->builder = resume_builder;
3848 LLVMPositionBuilderAtEnd (resume_builder, resume_bb);
3850 emit_resume_eh (ctx, handler_bb);
3853 ctx->builder = lpadBuilder;
3854 LLVMPositionBuilderAtEnd (lpadBuilder, lpad_bb);
3856 gboolean finally_only = TRUE;
3858 MonoExceptionClause *group_cursor = group_start;
3860 for (int i = 0; i < group_size; i ++) {
3861 if (!(group_cursor->flags & MONO_EXCEPTION_CLAUSE_FINALLY))
3862 finally_only = FALSE;
3868 // Handle landing pad inlining
3870 if (!finally_only) {
3871 // So at each level of the exception stack we will match the exception again.
3872 // During that match, we need to compare against the handler types for the current
3873 // protected region. We send the try start and end so that we can only check against
3874 // handlers for this lexical protected region.
3875 LLVMValueRef match = mono_llvm_emit_match_exception_call (ctx, lpadBuilder, group_start->try_offset, group_start->try_offset + group_start->try_len);
3877 // if returns -1, resume
3878 LLVMValueRef switch_ins = LLVMBuildSwitch (lpadBuilder, match, resume_bb, group_size);
3880 // else move to that target bb
3881 for (int i=0; i < group_size; i++) {
3882 MonoExceptionClause *clause = group_start + i;
3883 int clause_index = clause - cfg->header->clauses;
3884 MonoBasicBlock *handler_bb = (MonoBasicBlock*)g_hash_table_lookup (ctx->clause_to_handler, GINT_TO_POINTER (clause_index));
3885 g_assert (handler_bb);
3886 g_assert (ctx->bblocks [handler_bb->block_num].call_handler_target_bb);
3887 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), clause_index, FALSE), ctx->bblocks [handler_bb->block_num].call_handler_target_bb);
3890 int clause_index = group_start - cfg->header->clauses;
3891 MonoBasicBlock *finally_bb = (MonoBasicBlock*)g_hash_table_lookup (ctx->clause_to_handler, GINT_TO_POINTER (clause_index));
3892 g_assert (finally_bb);
3894 LLVMBuildBr (ctx->builder, ctx->bblocks [finally_bb->block_num].call_handler_target_bb);
3897 ctx->builder = old_builder;
3904 emit_llvmonly_handler_start (EmitContext *ctx, MonoBasicBlock *bb, LLVMBasicBlockRef cbb)
3906 int clause_index = MONO_REGION_CLAUSE_INDEX (bb->region);
3907 MonoExceptionClause *clause = &ctx->cfg->header->clauses [clause_index];
3909 // Make exception available to catch blocks
3910 if (!(clause->flags & MONO_EXCEPTION_CLAUSE_FINALLY)) {
3911 LLVMValueRef mono_exc = mono_llvm_emit_load_exception_call (ctx, ctx->builder);
3913 g_assert (ctx->ex_var);
3914 LLVMBuildStore (ctx->builder, LLVMBuildBitCast (ctx->builder, mono_exc, ObjRefType (), ""), ctx->ex_var);
3916 if (bb->in_scount == 1) {
3917 MonoInst *exvar = bb->in_stack [0];
3918 g_assert (!ctx->values [exvar->dreg]);
3919 g_assert (ctx->ex_var);
3920 ctx->values [exvar->dreg] = LLVMBuildLoad (ctx->builder, ctx->ex_var, "save_exception");
3921 emit_volatile_store (ctx, exvar->dreg);
3924 mono_llvm_emit_clear_exception_call (ctx, ctx->builder);
3927 LLVMBuilderRef handler_builder = create_builder (ctx);
3928 LLVMBasicBlockRef target_bb = ctx->bblocks [bb->block_num].call_handler_target_bb;
3929 LLVMPositionBuilderAtEnd (handler_builder, target_bb);
3931 // Make the handler code end with a jump to cbb
3932 LLVMBuildBr (handler_builder, cbb);
3936 emit_handler_start (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef builder)
3938 MonoCompile *cfg = ctx->cfg;
3939 LLVMValueRef *values = ctx->values;
3940 LLVMModuleRef lmodule = ctx->lmodule;
3941 BBInfo *bblocks = ctx->bblocks;
3943 LLVMValueRef personality;
3944 LLVMValueRef landing_pad;
3945 LLVMBasicBlockRef target_bb;
3947 static int ti_generator;
3949 LLVMValueRef type_info;
3953 // <resultval> = landingpad <somety> personality <type> <pers_fn> <clause>+
3955 if (cfg->compile_aot) {
3956 /* Use a dummy personality function */
3957 personality = LLVMGetNamedFunction (lmodule, "mono_personality");
3958 g_assert (personality);
3960 #if LLVM_API_VERSION > 100
3961 LLVMTypeRef personality_type = LLVMFunctionType (LLVMInt32Type (), NULL, 0, TRUE);
3962 personality = LLVMAddFunction (ctx->lmodule, "mono_personality", personality_type);
3963 LLVMAddFunctionAttr (personality, LLVMNoUnwindAttribute);
3964 LLVMBasicBlockRef entry_bb = LLVMAppendBasicBlock (personality, "ENTRY");
3965 LLVMBuilderRef builder2 = LLVMCreateBuilder ();
3966 LLVMPositionBuilderAtEnd (builder2, entry_bb);
3967 LLVMBuildRet (builder2, LLVMConstInt (LLVMInt32Type (), 0, FALSE));
3969 static gint32 mapping_inited;
3971 personality = LLVMGetNamedFunction (lmodule, "mono_personality");
3973 if (InterlockedCompareExchange (&mapping_inited, 1, 0) == 0)
3974 LLVMAddGlobalMapping (ctx->module->ee, personality, (gpointer)mono_personality);
3978 i8ptr = LLVMPointerType (LLVMInt8Type (), 0);
3980 clause_index = (mono_get_block_region_notry (cfg, bb->region) >> 8) - 1;
3983 * Create the type info
3985 sprintf (ti_name, "type_info_%d", ti_generator);
3988 if (cfg->compile_aot) {
3989 /* decode_eh_frame () in aot-runtime.c will decode this */
3990 type_info = LLVMAddGlobal (lmodule, LLVMInt32Type (), ti_name);
3991 LLVMSetInitializer (type_info, LLVMConstInt (LLVMInt32Type (), clause_index, FALSE));
3994 * These symbols are not really used, the clause_index is embedded into the EH tables generated by DwarfMonoException in LLVM.
3996 LLVMSetLinkage (type_info, LLVMInternalLinkage);
3998 #if LLVM_API_VERSION > 100
3999 type_info = LLVMAddGlobal (lmodule, LLVMInt32Type (), ti_name);
4000 LLVMSetInitializer (type_info, LLVMConstInt (LLVMInt32Type (), clause_index, FALSE));
4005 * After the cfg mempool is freed, the type info will point to stale memory,
4006 * but this is not a problem, since we decode it once in exception_cb during
4009 ti = (gint32*)mono_mempool_alloc (cfg->mempool, sizeof (gint32));
4010 *(gint32*)ti = clause_index;
4012 type_info = LLVMAddGlobal (lmodule, i8ptr, ti_name);
4014 LLVMAddGlobalMapping (ctx->module->ee, type_info, ti);
4019 LLVMTypeRef members [2], ret_type;
4021 members [0] = i8ptr;
4022 members [1] = LLVMInt32Type ();
4023 ret_type = LLVMStructType (members, 2, FALSE);
4025 landing_pad = LLVMBuildLandingPad (builder, ret_type, personality, 1, "");
4026 LLVMAddClause (landing_pad, type_info);
4028 /* Store the exception into the exvar */
4030 LLVMBuildStore (builder, convert (ctx, LLVMBuildExtractValue (builder, landing_pad, 0, "ex_obj"), ObjRefType ()), ctx->ex_var);
4034 * LLVM throw sites are associated with a one landing pad, and LLVM generated
4035 * code expects control to be transferred to this landing pad even in the
4036 * presence of nested clauses. The landing pad needs to branch to the landing
4037 * pads belonging to nested clauses based on the selector value returned by
4038 * the landing pad instruction, which is passed to the landing pad in a
4039 * register by the EH code.
4041 target_bb = bblocks [bb->block_num].call_handler_target_bb;
4042 g_assert (target_bb);
4045 * Branch to the correct landing pad
4047 LLVMValueRef ex_selector = LLVMBuildExtractValue (builder, landing_pad, 1, "ex_selector");
4048 LLVMValueRef switch_ins = LLVMBuildSwitch (builder, ex_selector, target_bb, 0);
4050 for (l = ctx->nested_in [clause_index]; l; l = l->next) {
4051 int nesting_clause_index = GPOINTER_TO_INT (l->data);
4052 MonoBasicBlock *handler_bb;
4054 handler_bb = (MonoBasicBlock*)g_hash_table_lookup (ctx->clause_to_handler, GINT_TO_POINTER (nesting_clause_index));
4055 g_assert (handler_bb);
4057 g_assert (ctx->bblocks [handler_bb->block_num].call_handler_target_bb);
4058 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), nesting_clause_index, FALSE), ctx->bblocks [handler_bb->block_num].call_handler_target_bb);
4061 /* Start a new bblock which CALL_HANDLER can branch to */
4062 target_bb = bblocks [bb->block_num].call_handler_target_bb;
4064 ctx->builder = builder = create_builder (ctx);
4065 LLVMPositionBuilderAtEnd (ctx->builder, target_bb);
4067 ctx->bblocks [bb->block_num].end_bblock = target_bb;
4069 /* Store the exception into the IL level exvar */
4070 if (bb->in_scount == 1) {
4071 g_assert (bb->in_scount == 1);
4072 exvar = bb->in_stack [0];
4074 // FIXME: This is shared with filter clauses ?
4075 g_assert (!values [exvar->dreg]);
4077 g_assert (ctx->ex_var);
4078 values [exvar->dreg] = LLVMBuildLoad (builder, ctx->ex_var, "");
4079 emit_volatile_store (ctx, exvar->dreg);
4085 process_bb (EmitContext *ctx, MonoBasicBlock *bb)
4087 MonoCompile *cfg = ctx->cfg;
4088 MonoMethodSignature *sig = ctx->sig;
4089 LLVMValueRef method = ctx->lmethod;
4090 LLVMValueRef *values = ctx->values;
4091 LLVMValueRef *addresses = ctx->addresses;
4092 LLVMCallInfo *linfo = ctx->linfo;
4093 BBInfo *bblocks = ctx->bblocks;
4095 LLVMBasicBlockRef cbb;
4096 LLVMBuilderRef builder, starting_builder;
4097 gboolean has_terminator;
4099 LLVMValueRef lhs, rhs;
4102 cbb = get_end_bb (ctx, bb);
4104 builder = create_builder (ctx);
4105 ctx->builder = builder;
4106 LLVMPositionBuilderAtEnd (builder, cbb);
4111 if (bb->flags & BB_EXCEPTION_HANDLER) {
4112 if (!ctx->llvm_only && !bblocks [bb->block_num].invoke_target) {
4113 set_failure (ctx, "handler without invokes");
4118 emit_llvmonly_handler_start (ctx, bb, cbb);
4120 emit_handler_start (ctx, bb, builder);
4123 builder = ctx->builder;
4126 has_terminator = FALSE;
4127 starting_builder = builder;
4128 for (ins = bb->code; ins; ins = ins->next) {
4129 const char *spec = LLVM_INS_INFO (ins->opcode);
4131 char dname_buf [128];
4133 emit_dbg_loc (ctx, builder, ins->cil_code);
4138 * Some steps in llc are non-linear in the size of basic blocks, see #5714.
4139 * Start a new bblock. If the llvm optimization passes merge these, we
4140 * can work around that by doing a volatile load + cond branch from
4141 * localloc-ed memory.
4143 //set_failure (ctx, "basic block too long");
4144 cbb = gen_bb (ctx, "CONT_LONG_BB");
4145 LLVMBuildBr (ctx->builder, cbb);
4146 ctx->builder = builder = create_builder (ctx);
4147 LLVMPositionBuilderAtEnd (builder, cbb);
4148 ctx->bblocks [bb->block_num].end_bblock = cbb;
4153 /* There could be instructions after a terminator, skip them */
4156 if (spec [MONO_INST_DEST] != ' ' && !MONO_IS_STORE_MEMBASE (ins)) {
4157 sprintf (dname_buf, "t%d", ins->dreg);
4161 if (spec [MONO_INST_SRC1] != ' ' && spec [MONO_INST_SRC1] != 'v') {
4162 MonoInst *var = get_vreg_to_inst (cfg, ins->sreg1);
4164 if (var && var->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT) && var->opcode != OP_GSHAREDVT_ARG_REGOFFSET) {
4165 lhs = emit_volatile_load (ctx, ins->sreg1);
4167 /* It is ok for SETRET to have an uninitialized argument */
4168 if (!values [ins->sreg1] && ins->opcode != OP_SETRET) {
4169 set_failure (ctx, "sreg1");
4172 lhs = values [ins->sreg1];
4178 if (spec [MONO_INST_SRC2] != ' ' && spec [MONO_INST_SRC2] != ' ') {
4179 MonoInst *var = get_vreg_to_inst (cfg, ins->sreg2);
4180 if (var && var->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT)) {
4181 rhs = emit_volatile_load (ctx, ins->sreg2);
4183 if (!values [ins->sreg2]) {
4184 set_failure (ctx, "sreg2");
4187 rhs = values [ins->sreg2];
4193 //mono_print_ins (ins);
4194 switch (ins->opcode) {
4197 case OP_LIVERANGE_START:
4198 case OP_LIVERANGE_END:
4201 values [ins->dreg] = LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE);
4204 #if SIZEOF_VOID_P == 4
4205 values [ins->dreg] = LLVMConstInt (LLVMInt64Type (), GET_LONG_IMM (ins), FALSE);
4207 values [ins->dreg] = LLVMConstInt (LLVMInt64Type (), (gint64)ins->inst_c0, FALSE);
4211 values [ins->dreg] = LLVMConstReal (LLVMDoubleType (), *(double*)ins->inst_p0);
4215 values [ins->dreg] = LLVMConstReal (LLVMFloatType (), *(float*)ins->inst_p0);
4217 values [ins->dreg] = LLVMConstFPExt (LLVMConstReal (LLVMFloatType (), *(float*)ins->inst_p0), LLVMDoubleType ());
4219 case OP_DUMMY_ICONST:
4220 values [ins->dreg] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
4222 case OP_DUMMY_I8CONST:
4223 values [ins->dreg] = LLVMConstInt (LLVMInt64Type (), 0, FALSE);
4225 case OP_DUMMY_R8CONST:
4226 values [ins->dreg] = LLVMConstReal (LLVMDoubleType (), 0.0f);
4229 LLVMBasicBlockRef target_bb = get_bb (ctx, ins->inst_target_bb);
4230 LLVMBuildBr (builder, target_bb);
4231 has_terminator = TRUE;
4238 LLVMBasicBlockRef new_bb;
4239 LLVMBuilderRef new_builder;
4241 // The default branch is already handled
4242 // FIXME: Handle it here
4244 /* Start new bblock */
4245 sprintf (bb_name, "SWITCH_DEFAULT_BB%d", ctx->default_index ++);
4246 new_bb = LLVMAppendBasicBlock (ctx->lmethod, bb_name);
4248 lhs = convert (ctx, lhs, LLVMInt32Type ());
4249 v = LLVMBuildSwitch (builder, lhs, new_bb, GPOINTER_TO_UINT (ins->klass));
4250 for (i = 0; i < GPOINTER_TO_UINT (ins->klass); ++i) {
4251 MonoBasicBlock *target_bb = ins->inst_many_bb [i];
4253 LLVMAddCase (v, LLVMConstInt (LLVMInt32Type (), i, FALSE), get_bb (ctx, target_bb));
4256 new_builder = create_builder (ctx);
4257 LLVMPositionBuilderAtEnd (new_builder, new_bb);
4258 LLVMBuildUnreachable (new_builder);
4260 has_terminator = TRUE;
4261 g_assert (!ins->next);
4267 switch (linfo->ret.storage) {
4268 case LLVMArgVtypeInReg: {
4269 LLVMTypeRef ret_type = LLVMGetReturnType (LLVMGetElementType (LLVMTypeOf (method)));
4270 LLVMValueRef val, addr, retval;
4273 retval = LLVMGetUndef (ret_type);
4275 if (!addresses [ins->sreg1]) {
4277 * The return type is an LLVM vector type, have to convert between it and the
4278 * real return type which is a struct type.
4280 g_assert (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (sig->ret)));
4281 /* Convert to 2xi64 first */
4282 val = LLVMBuildBitCast (builder, values [ins->sreg1], LLVMVectorType (IntPtrType (), 2), "");
4284 for (i = 0; i < 2; ++i) {
4285 if (linfo->ret.pair_storage [i] == LLVMArgInIReg) {
4286 retval = LLVMBuildInsertValue (builder, retval, LLVMBuildExtractElement (builder, val, LLVMConstInt (LLVMInt32Type (), i, FALSE), ""), i, "");
4288 g_assert (linfo->ret.pair_storage [i] == LLVMArgNone);
4292 addr = LLVMBuildBitCast (builder, addresses [ins->sreg1], LLVMPointerType (ret_type, 0), "");
4293 for (i = 0; i < 2; ++i) {
4294 if (linfo->ret.pair_storage [i] == LLVMArgInIReg) {
4295 LLVMValueRef indexes [2], part_addr;
4297 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
4298 indexes [1] = LLVMConstInt (LLVMInt32Type (), i, FALSE);
4299 part_addr = LLVMBuildGEP (builder, addr, indexes, 2, "");
4301 retval = LLVMBuildInsertValue (builder, retval, LLVMBuildLoad (builder, part_addr, ""), i, "");
4303 g_assert (linfo->ret.pair_storage [i] == LLVMArgNone);
4307 LLVMBuildRet (builder, retval);
4310 case LLVMArgVtypeAsScalar: {
4311 LLVMTypeRef ret_type = LLVMGetReturnType (LLVMGetElementType (LLVMTypeOf (method)));
4312 LLVMValueRef retval;
4314 g_assert (addresses [ins->sreg1]);
4316 retval = LLVMBuildLoad (builder, LLVMBuildBitCast (builder, addresses [ins->sreg1], LLVMPointerType (ret_type, 0), ""), "");
4317 LLVMBuildRet (builder, retval);
4320 case LLVMArgVtypeByVal: {
4321 LLVMValueRef retval;
4323 g_assert (addresses [ins->sreg1]);
4324 retval = LLVMBuildLoad (builder, addresses [ins->sreg1], "");
4325 LLVMBuildRet (builder, retval);
4328 case LLVMArgVtypeByRef: {
4329 LLVMBuildRetVoid (builder);
4332 case LLVMArgGsharedvtFixed: {
4333 LLVMTypeRef ret_type = type_to_llvm_type (ctx, sig->ret);
4334 /* The return value is in lhs, need to store to the vret argument */
4335 /* sreg1 might not be set */
4337 g_assert (cfg->vret_addr);
4338 g_assert (values [cfg->vret_addr->dreg]);
4339 LLVMBuildStore (builder, convert (ctx, lhs, ret_type), convert (ctx, values [cfg->vret_addr->dreg], LLVMPointerType (ret_type, 0)));
4341 LLVMBuildRetVoid (builder);
4344 case LLVMArgGsharedvtFixedVtype: {
4346 LLVMBuildRetVoid (builder);
4349 case LLVMArgGsharedvtVariable: {
4351 LLVMBuildRetVoid (builder);
4354 case LLVMArgVtypeRetAddr: {
4355 LLVMBuildRetVoid (builder);
4358 case LLVMArgFpStruct: {
4359 LLVMTypeRef ret_type = LLVMGetReturnType (LLVMGetElementType (LLVMTypeOf (method)));
4360 LLVMValueRef retval;
4362 g_assert (addresses [ins->sreg1]);
4363 retval = LLVMBuildLoad (builder, convert (ctx, addresses [ins->sreg1], LLVMPointerType (ret_type, 0)), "");
4364 LLVMBuildRet (builder, retval);
4368 case LLVMArgNormal: {
4369 if (!lhs || ctx->is_dead [ins->sreg1]) {
4371 * The method did not set its return value, probably because it
4372 * ends with a throw.
4375 LLVMBuildRetVoid (builder);
4377 LLVMBuildRet (builder, LLVMConstNull (type_to_llvm_type (ctx, sig->ret)));
4379 LLVMBuildRet (builder, convert (ctx, lhs, type_to_llvm_type (ctx, sig->ret)));
4381 has_terminator = TRUE;
4385 g_assert_not_reached ();
4394 case OP_ICOMPARE_IMM:
4395 case OP_LCOMPARE_IMM:
4396 case OP_COMPARE_IMM: {
4398 LLVMValueRef cmp, args [16];
4399 gboolean likely = (ins->flags & MONO_INST_LIKELY) != 0;
4401 if (ins->next->opcode == OP_NOP)
4404 if (ins->next->opcode == OP_BR)
4405 /* The comparison result is not needed */
4408 rel = mono_opcode_to_cond (ins->next->opcode);
4410 if (ins->opcode == OP_ICOMPARE_IMM) {
4411 lhs = convert (ctx, lhs, LLVMInt32Type ());
4412 rhs = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
4414 if (ins->opcode == OP_LCOMPARE_IMM) {
4415 lhs = convert (ctx, lhs, LLVMInt64Type ());
4416 rhs = LLVMConstInt (LLVMInt64Type (), GET_LONG_IMM (ins), FALSE);
4418 if (ins->opcode == OP_LCOMPARE) {
4419 lhs = convert (ctx, lhs, LLVMInt64Type ());
4420 rhs = convert (ctx, rhs, LLVMInt64Type ());
4422 if (ins->opcode == OP_ICOMPARE) {
4423 lhs = convert (ctx, lhs, LLVMInt32Type ());
4424 rhs = convert (ctx, rhs, LLVMInt32Type ());
4428 if (LLVMGetTypeKind (LLVMTypeOf (lhs)) == LLVMPointerTypeKind)
4429 rhs = convert (ctx, rhs, LLVMTypeOf (lhs));
4430 else if (LLVMGetTypeKind (LLVMTypeOf (rhs)) == LLVMPointerTypeKind)
4431 lhs = convert (ctx, lhs, LLVMTypeOf (rhs));
4434 /* We use COMPARE+SETcc/Bcc, llvm uses SETcc+br cond */
4435 if (ins->opcode == OP_FCOMPARE) {
4436 cmp = LLVMBuildFCmp (builder, fpcond_to_llvm_cond [rel], convert (ctx, lhs, LLVMDoubleType ()), convert (ctx, rhs, LLVMDoubleType ()), "");
4437 } else if (ins->opcode == OP_RCOMPARE) {
4438 cmp = LLVMBuildFCmp (builder, fpcond_to_llvm_cond [rel], convert (ctx, lhs, LLVMFloatType ()), convert (ctx, rhs, LLVMFloatType ()), "");
4439 } else if (ins->opcode == OP_COMPARE_IMM) {
4440 if (LLVMGetTypeKind (LLVMTypeOf (lhs)) == LLVMPointerTypeKind && ins->inst_imm == 0)
4441 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], lhs, LLVMConstNull (LLVMTypeOf (lhs)), "");
4443 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE), "");
4444 } else if (ins->opcode == OP_LCOMPARE_IMM) {
4445 if (SIZEOF_REGISTER == 4 && COMPILE_LLVM (cfg)) {
4446 /* The immediate is encoded in two fields */
4447 guint64 l = ((guint64)(guint32)ins->inst_offset << 32) | ((guint32)ins->inst_imm);
4448 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, LLVMInt64Type ()), LLVMConstInt (LLVMInt64Type (), l, FALSE), "");
4450 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, LLVMInt64Type ()), LLVMConstInt (LLVMInt64Type (), ins->inst_imm, FALSE), "");
4453 else if (ins->opcode == OP_COMPARE) {
4454 if (LLVMGetTypeKind (LLVMTypeOf (lhs)) == LLVMPointerTypeKind && LLVMTypeOf (lhs) == LLVMTypeOf (rhs))
4455 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], lhs, rhs, "");
4457 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, IntPtrType ()), convert (ctx, rhs, IntPtrType ()), "");
4459 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], lhs, rhs, "");
4463 args [1] = LLVMConstInt (LLVMInt1Type (), 1, FALSE);
4464 cmp = LLVMBuildCall (ctx->builder, get_intrinsic (ctx, "llvm.expect.i1"), args, 2, "");
4467 if (MONO_IS_COND_BRANCH_OP (ins->next)) {
4468 if (ins->next->inst_true_bb == ins->next->inst_false_bb) {
4470 * If the target bb contains PHI instructions, LLVM requires
4471 * two PHI entries for this bblock, while we only generate one.
4472 * So convert this to an unconditional bblock. (bxc #171).
4474 LLVMBuildBr (builder, get_bb (ctx, ins->next->inst_true_bb));
4476 LLVMBuildCondBr (builder, cmp, get_bb (ctx, ins->next->inst_true_bb), get_bb (ctx, ins->next->inst_false_bb));
4478 has_terminator = TRUE;
4479 } else if (MONO_IS_SETCC (ins->next)) {
4480 sprintf (dname_buf, "t%d", ins->next->dreg);
4482 values [ins->next->dreg] = LLVMBuildZExt (builder, cmp, LLVMInt32Type (), dname);
4484 /* Add stores for volatile variables */
4485 emit_volatile_store (ctx, ins->next->dreg);
4486 } else if (MONO_IS_COND_EXC (ins->next)) {
4487 emit_cond_system_exception (ctx, bb, (const char*)ins->next->inst_p1, cmp);
4490 builder = ctx->builder;
4492 set_failure (ctx, "next");
4510 rel = mono_opcode_to_cond (ins->opcode);
4512 cmp = LLVMBuildFCmp (builder, fpcond_to_llvm_cond [rel], convert (ctx, lhs, LLVMDoubleType ()), convert (ctx, rhs, LLVMDoubleType ()), "");
4513 values [ins->dreg] = LLVMBuildZExt (builder, cmp, LLVMInt32Type (), dname);
4524 rel = mono_opcode_to_cond (ins->opcode);
4526 cmp = LLVMBuildFCmp (builder, fpcond_to_llvm_cond [rel], convert (ctx, lhs, LLVMFloatType ()), convert (ctx, rhs, LLVMFloatType ()), "");
4527 values [ins->dreg] = LLVMBuildZExt (builder, cmp, LLVMInt32Type (), dname);
4535 gboolean empty = TRUE;
4537 /* Check that all input bblocks really branch to us */
4538 for (i = 0; i < bb->in_count; ++i) {
4539 if (bb->in_bb [i]->last_ins && bb->in_bb [i]->last_ins->opcode == OP_NOT_REACHED)
4540 ins->inst_phi_args [i + 1] = -1;
4546 /* LLVM doesn't like phi instructions with zero operands */
4547 ctx->is_dead [ins->dreg] = TRUE;
4551 /* Created earlier, insert it now */
4552 LLVMInsertIntoBuilder (builder, values [ins->dreg]);
4554 for (i = 0; i < ins->inst_phi_args [0]; i++) {
4555 int sreg1 = ins->inst_phi_args [i + 1];
4559 * Count the number of times the incoming bblock branches to us,
4560 * since llvm requires a separate entry for each.
4562 if (bb->in_bb [i]->last_ins && bb->in_bb [i]->last_ins->opcode == OP_SWITCH) {
4563 MonoInst *switch_ins = bb->in_bb [i]->last_ins;
4566 for (j = 0; j < GPOINTER_TO_UINT (switch_ins->klass); ++j) {
4567 if (switch_ins->inst_many_bb [j] == bb)
4574 /* Remember for later */
4575 for (j = 0; j < count; ++j) {
4576 PhiNode *node = (PhiNode*)mono_mempool_alloc0 (ctx->mempool, sizeof (PhiNode));
4579 node->in_bb = bb->in_bb [i];
4581 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);
4591 values [ins->dreg] = lhs;
4595 MonoInst *var = get_vreg_to_inst (cfg, ins->dreg);
4598 values [ins->dreg] = lhs;
4600 if (var && var->klass->byval_arg.type == MONO_TYPE_R4) {
4602 * This is added by the spilling pass in case of the JIT,
4603 * but we have to do it ourselves.
4605 values [ins->dreg] = convert (ctx, values [ins->dreg], LLVMFloatType ());
4609 case OP_MOVE_F_TO_I4: {
4610 values [ins->dreg] = LLVMBuildBitCast (builder, LLVMBuildFPTrunc (builder, lhs, LLVMFloatType (), ""), LLVMInt32Type (), "");
4613 case OP_MOVE_I4_TO_F: {
4614 values [ins->dreg] = LLVMBuildFPExt (builder, LLVMBuildBitCast (builder, lhs, LLVMFloatType (), ""), LLVMDoubleType (), "");
4617 case OP_MOVE_F_TO_I8: {
4618 values [ins->dreg] = LLVMBuildBitCast (builder, lhs, LLVMInt64Type (), "");
4621 case OP_MOVE_I8_TO_F: {
4622 values [ins->dreg] = LLVMBuildBitCast (builder, lhs, LLVMDoubleType (), "");
4655 lhs = convert (ctx, lhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
4656 rhs = convert (ctx, rhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
4658 emit_div_check (ctx, builder, bb, ins, lhs, rhs);
4661 builder = ctx->builder;
4663 switch (ins->opcode) {
4666 values [ins->dreg] = LLVMBuildAdd (builder, lhs, rhs, dname);
4670 values [ins->dreg] = LLVMBuildSub (builder, lhs, rhs, dname);
4674 values [ins->dreg] = LLVMBuildMul (builder, lhs, rhs, dname);
4678 values [ins->dreg] = LLVMBuildSRem (builder, lhs, rhs, dname);
4682 values [ins->dreg] = LLVMBuildURem (builder, lhs, rhs, dname);
4686 values [ins->dreg] = LLVMBuildSDiv (builder, lhs, rhs, dname);
4690 values [ins->dreg] = LLVMBuildUDiv (builder, lhs, rhs, dname);
4694 values [ins->dreg] = LLVMBuildFDiv (builder, lhs, rhs, dname);
4698 values [ins->dreg] = LLVMBuildAnd (builder, lhs, rhs, dname);
4702 values [ins->dreg] = LLVMBuildOr (builder, lhs, rhs, dname);
4706 values [ins->dreg] = LLVMBuildXor (builder, lhs, rhs, dname);
4710 values [ins->dreg] = LLVMBuildShl (builder, lhs, rhs, dname);
4714 values [ins->dreg] = LLVMBuildAShr (builder, lhs, rhs, dname);
4718 values [ins->dreg] = LLVMBuildLShr (builder, lhs, rhs, dname);
4722 values [ins->dreg] = LLVMBuildFAdd (builder, lhs, rhs, dname);
4725 values [ins->dreg] = LLVMBuildFSub (builder, lhs, rhs, dname);
4728 values [ins->dreg] = LLVMBuildFMul (builder, lhs, rhs, dname);
4732 g_assert_not_reached ();
4739 lhs = convert (ctx, lhs, LLVMFloatType ());
4740 rhs = convert (ctx, rhs, LLVMFloatType ());
4741 switch (ins->opcode) {
4743 values [ins->dreg] = LLVMBuildFAdd (builder, lhs, rhs, dname);
4746 values [ins->dreg] = LLVMBuildFSub (builder, lhs, rhs, dname);
4749 values [ins->dreg] = LLVMBuildFMul (builder, lhs, rhs, dname);
4752 values [ins->dreg] = LLVMBuildFDiv (builder, lhs, rhs, dname);
4755 g_assert_not_reached ();
4764 case OP_IREM_UN_IMM:
4766 case OP_IDIV_UN_IMM:
4772 case OP_ISHR_UN_IMM:
4782 case OP_LSHR_UN_IMM:
4788 case OP_SHR_UN_IMM: {
4791 if (spec [MONO_INST_SRC1] == 'l') {
4792 imm = LLVMConstInt (LLVMInt64Type (), GET_LONG_IMM (ins), FALSE);
4794 imm = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
4797 emit_div_check (ctx, builder, bb, ins, lhs, imm);
4800 builder = ctx->builder;
4802 #if SIZEOF_VOID_P == 4
4803 if (ins->opcode == OP_LSHL_IMM || ins->opcode == OP_LSHR_IMM || ins->opcode == OP_LSHR_UN_IMM)
4804 imm = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
4807 if (LLVMGetTypeKind (LLVMTypeOf (lhs)) == LLVMPointerTypeKind)
4808 lhs = convert (ctx, lhs, IntPtrType ());
4809 imm = convert (ctx, imm, LLVMTypeOf (lhs));
4810 switch (ins->opcode) {
4814 values [ins->dreg] = LLVMBuildAdd (builder, lhs, imm, dname);
4818 values [ins->dreg] = LLVMBuildSub (builder, lhs, imm, dname);
4823 values [ins->dreg] = LLVMBuildMul (builder, lhs, imm, dname);
4827 values [ins->dreg] = LLVMBuildSDiv (builder, lhs, imm, dname);
4829 case OP_IDIV_UN_IMM:
4830 case OP_LDIV_UN_IMM:
4831 values [ins->dreg] = LLVMBuildUDiv (builder, lhs, imm, dname);
4835 values [ins->dreg] = LLVMBuildSRem (builder, lhs, imm, dname);
4837 case OP_IREM_UN_IMM:
4838 values [ins->dreg] = LLVMBuildURem (builder, lhs, imm, dname);
4843 values [ins->dreg] = LLVMBuildAnd (builder, lhs, imm, dname);
4847 values [ins->dreg] = LLVMBuildOr (builder, lhs, imm, dname);
4851 values [ins->dreg] = LLVMBuildXor (builder, lhs, imm, dname);
4856 values [ins->dreg] = LLVMBuildShl (builder, lhs, imm, dname);
4861 values [ins->dreg] = LLVMBuildAShr (builder, lhs, imm, dname);
4863 case OP_ISHR_UN_IMM:
4864 /* This is used to implement conv.u4, so the lhs could be an i8 */
4865 lhs = convert (ctx, lhs, LLVMInt32Type ());
4866 imm = convert (ctx, imm, LLVMInt32Type ());
4867 values [ins->dreg] = LLVMBuildLShr (builder, lhs, imm, dname);
4869 case OP_LSHR_UN_IMM:
4871 values [ins->dreg] = LLVMBuildLShr (builder, lhs, imm, dname);
4874 g_assert_not_reached ();
4879 values [ins->dreg] = LLVMBuildSub (builder, LLVMConstInt (LLVMInt32Type (), 0, FALSE), convert (ctx, lhs, LLVMInt32Type ()), dname);
4882 values [ins->dreg] = LLVMBuildSub (builder, LLVMConstInt (LLVMInt64Type (), 0, FALSE), lhs, dname);
4885 lhs = convert (ctx, lhs, LLVMDoubleType ());
4886 values [ins->dreg] = LLVMBuildFSub (builder, LLVMConstReal (LLVMDoubleType (), 0.0), lhs, dname);
4889 lhs = convert (ctx, lhs, LLVMFloatType ());
4890 values [ins->dreg] = LLVMBuildFSub (builder, LLVMConstReal (LLVMFloatType (), 0.0), lhs, dname);
4893 guint32 v = 0xffffffff;
4894 values [ins->dreg] = LLVMBuildXor (builder, LLVMConstInt (LLVMInt32Type (), v, FALSE), convert (ctx, lhs, LLVMInt32Type ()), dname);
4898 guint64 v = 0xffffffffffffffffLL;
4899 values [ins->dreg] = LLVMBuildXor (builder, LLVMConstInt (LLVMInt64Type (), v, FALSE), lhs, dname);
4902 #if defined(TARGET_X86) || defined(TARGET_AMD64)
4904 LLVMValueRef v1, v2;
4906 v1 = LLVMBuildMul (builder, convert (ctx, rhs, IntPtrType ()), LLVMConstInt (IntPtrType (), (1 << ins->backend.shift_amount), FALSE), "");
4907 v2 = LLVMBuildAdd (builder, convert (ctx, lhs, IntPtrType ()), v1, "");
4908 values [ins->dreg] = LLVMBuildAdd (builder, v2, LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE), dname);
4913 case OP_ICONV_TO_I1:
4914 case OP_ICONV_TO_I2:
4915 case OP_ICONV_TO_I4:
4916 case OP_ICONV_TO_U1:
4917 case OP_ICONV_TO_U2:
4918 case OP_ICONV_TO_U4:
4919 case OP_LCONV_TO_I1:
4920 case OP_LCONV_TO_I2:
4921 case OP_LCONV_TO_U1:
4922 case OP_LCONV_TO_U2:
4923 case OP_LCONV_TO_U4: {
4926 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);
4928 /* Have to do two casts since our vregs have type int */
4929 v = LLVMBuildTrunc (builder, lhs, op_to_llvm_type (ins->opcode), "");
4931 values [ins->dreg] = LLVMBuildSExt (builder, v, LLVMInt32Type (), dname);
4933 values [ins->dreg] = LLVMBuildZExt (builder, v, LLVMInt32Type (), dname);
4936 case OP_ICONV_TO_I8:
4937 values [ins->dreg] = LLVMBuildSExt (builder, lhs, LLVMInt64Type (), dname);
4939 case OP_ICONV_TO_U8:
4940 values [ins->dreg] = LLVMBuildZExt (builder, lhs, LLVMInt64Type (), dname);
4942 case OP_FCONV_TO_I4:
4943 case OP_RCONV_TO_I4:
4944 values [ins->dreg] = LLVMBuildFPToSI (builder, lhs, LLVMInt32Type (), dname);
4946 case OP_FCONV_TO_I1:
4947 case OP_RCONV_TO_I1:
4948 values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildFPToSI (builder, lhs, LLVMInt8Type (), dname), LLVMInt32Type (), "");
4950 case OP_FCONV_TO_U1:
4951 case OP_RCONV_TO_U1:
4952 values [ins->dreg] = LLVMBuildZExt (builder, LLVMBuildTrunc (builder, LLVMBuildFPToUI (builder, lhs, IntPtrType (), dname), LLVMInt8Type (), ""), LLVMInt32Type (), "");
4954 case OP_FCONV_TO_I2:
4955 case OP_RCONV_TO_I2:
4956 values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildFPToSI (builder, lhs, LLVMInt16Type (), dname), LLVMInt32Type (), "");
4958 case OP_FCONV_TO_U2:
4959 case OP_RCONV_TO_U2:
4960 values [ins->dreg] = LLVMBuildZExt (builder, LLVMBuildFPToUI (builder, lhs, LLVMInt16Type (), dname), LLVMInt32Type (), "");
4962 case OP_RCONV_TO_U4:
4963 values [ins->dreg] = LLVMBuildFPToUI (builder, lhs, LLVMInt32Type (), dname);
4965 case OP_FCONV_TO_I8:
4966 case OP_RCONV_TO_I8:
4967 values [ins->dreg] = LLVMBuildFPToSI (builder, lhs, LLVMInt64Type (), dname);
4970 values [ins->dreg] = LLVMBuildFPToSI (builder, lhs, IntPtrType (), dname);
4972 case OP_ICONV_TO_R8:
4973 case OP_LCONV_TO_R8:
4974 values [ins->dreg] = LLVMBuildSIToFP (builder, lhs, LLVMDoubleType (), dname);
4976 case OP_ICONV_TO_R_UN:
4977 case OP_LCONV_TO_R_UN:
4978 values [ins->dreg] = LLVMBuildUIToFP (builder, lhs, LLVMDoubleType (), dname);
4980 #if SIZEOF_VOID_P == 4
4983 case OP_LCONV_TO_I4:
4984 values [ins->dreg] = LLVMBuildTrunc (builder, lhs, LLVMInt32Type (), dname);
4986 case OP_ICONV_TO_R4:
4987 case OP_LCONV_TO_R4:
4988 v = LLVMBuildSIToFP (builder, lhs, LLVMFloatType (), "");
4990 values [ins->dreg] = v;
4992 values [ins->dreg] = LLVMBuildFPExt (builder, v, LLVMDoubleType (), dname);
4994 case OP_FCONV_TO_R4:
4995 v = LLVMBuildFPTrunc (builder, lhs, LLVMFloatType (), "");
4997 values [ins->dreg] = v;
4999 values [ins->dreg] = LLVMBuildFPExt (builder, v, LLVMDoubleType (), dname);
5001 case OP_RCONV_TO_R8:
5002 values [ins->dreg] = LLVMBuildFPExt (builder, lhs, LLVMDoubleType (), dname);
5004 case OP_RCONV_TO_R4:
5005 values [ins->dreg] = lhs;
5008 values [ins->dreg] = LLVMBuildSExt (builder, convert (ctx, lhs, LLVMInt32Type ()), LLVMInt64Type (), dname);
5011 values [ins->dreg] = LLVMBuildZExt (builder, convert (ctx, lhs, LLVMInt32Type ()), LLVMInt64Type (), dname);
5014 values [ins->dreg] = LLVMBuildTrunc (builder, lhs, LLVMInt32Type (), dname);
5016 case OP_LOCALLOC_IMM: {
5019 guint32 size = ins->inst_imm;
5020 size = (size + (MONO_ARCH_FRAME_ALIGNMENT - 1)) & ~ (MONO_ARCH_FRAME_ALIGNMENT - 1);
5022 v = mono_llvm_build_alloca (builder, LLVMInt8Type (), LLVMConstInt (LLVMInt32Type (), size, FALSE), MONO_ARCH_FRAME_ALIGNMENT, "");
5024 if (ins->flags & MONO_INST_INIT) {
5025 LLVMValueRef args [5];
5028 args [1] = LLVMConstInt (LLVMInt8Type (), 0, FALSE);
5029 args [2] = LLVMConstInt (LLVMInt32Type (), size, FALSE);
5030 args [3] = LLVMConstInt (LLVMInt32Type (), MONO_ARCH_FRAME_ALIGNMENT, FALSE);
5031 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
5032 LLVMBuildCall (builder, get_intrinsic (ctx, "llvm.memset.p0i8.i32"), args, 5, "");
5035 values [ins->dreg] = v;
5039 LLVMValueRef v, size;
5041 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), "");
5043 v = mono_llvm_build_alloca (builder, LLVMInt8Type (), size, MONO_ARCH_FRAME_ALIGNMENT, "");
5045 if (ins->flags & MONO_INST_INIT) {
5046 LLVMValueRef args [5];
5049 args [1] = LLVMConstInt (LLVMInt8Type (), 0, FALSE);
5051 args [3] = LLVMConstInt (LLVMInt32Type (), MONO_ARCH_FRAME_ALIGNMENT, FALSE);
5052 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
5053 LLVMBuildCall (builder, get_intrinsic (ctx, "llvm.memset.p0i8.i32"), args, 5, "");
5055 values [ins->dreg] = v;
5059 case OP_LOADI1_MEMBASE:
5060 case OP_LOADU1_MEMBASE:
5061 case OP_LOADI2_MEMBASE:
5062 case OP_LOADU2_MEMBASE:
5063 case OP_LOADI4_MEMBASE:
5064 case OP_LOADU4_MEMBASE:
5065 case OP_LOADI8_MEMBASE:
5066 case OP_LOADR4_MEMBASE:
5067 case OP_LOADR8_MEMBASE:
5068 case OP_LOAD_MEMBASE:
5076 LLVMValueRef base, index, addr;
5078 gboolean sext = FALSE, zext = FALSE;
5079 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
5081 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
5086 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)) {
5087 addr = LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE);
5092 if (ins->inst_offset == 0) {
5094 } else if (ins->inst_offset % size != 0) {
5095 /* Unaligned load */
5096 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset, FALSE);
5097 addr = LLVMBuildGEP (builder, convert (ctx, base, LLVMPointerType (LLVMInt8Type (), 0)), &index, 1, "");
5099 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
5100 addr = LLVMBuildGEP (builder, convert (ctx, base, LLVMPointerType (t, 0)), &index, 1, "");
5104 addr = convert (ctx, addr, LLVMPointerType (t, 0));
5106 values [ins->dreg] = emit_load (ctx, bb, &builder, size, addr, dname, is_volatile);
5108 if (!is_volatile && (ins->flags & MONO_INST_INVARIANT_LOAD)) {
5110 * These will signal LLVM that these loads do not alias any stores, and
5111 * they can't fail, allowing them to be hoisted out of loops.
5113 set_invariant_load_flag (values [ins->dreg]);
5114 #if LLVM_API_VERSION < 100
5115 set_metadata_flag (values [ins->dreg], "mono.nofail.load");
5120 values [ins->dreg] = LLVMBuildSExt (builder, values [ins->dreg], LLVMInt32Type (), dname);
5122 values [ins->dreg] = LLVMBuildZExt (builder, values [ins->dreg], LLVMInt32Type (), dname);
5123 else if (!cfg->r4fp && ins->opcode == OP_LOADR4_MEMBASE)
5124 values [ins->dreg] = LLVMBuildFPExt (builder, values [ins->dreg], LLVMDoubleType (), dname);
5128 case OP_STOREI1_MEMBASE_REG:
5129 case OP_STOREI2_MEMBASE_REG:
5130 case OP_STOREI4_MEMBASE_REG:
5131 case OP_STOREI8_MEMBASE_REG:
5132 case OP_STORER4_MEMBASE_REG:
5133 case OP_STORER8_MEMBASE_REG:
5134 case OP_STORE_MEMBASE_REG: {
5136 LLVMValueRef index, addr;
5138 gboolean sext = FALSE, zext = FALSE;
5139 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
5141 if (!values [ins->inst_destbasereg]) {
5142 set_failure (ctx, "inst_destbasereg");
5146 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
5148 if (ins->inst_offset % size != 0) {
5149 /* Unaligned store */
5150 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset, FALSE);
5151 addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (LLVMInt8Type (), 0)), &index, 1, "");
5153 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
5154 addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (t, 0)), &index, 1, "");
5156 emit_store (ctx, bb, &builder, size, convert (ctx, values [ins->sreg1], t), convert (ctx, addr, LLVMPointerType (t, 0)), is_volatile);
5160 case OP_STOREI1_MEMBASE_IMM:
5161 case OP_STOREI2_MEMBASE_IMM:
5162 case OP_STOREI4_MEMBASE_IMM:
5163 case OP_STOREI8_MEMBASE_IMM:
5164 case OP_STORE_MEMBASE_IMM: {
5166 LLVMValueRef index, addr;
5168 gboolean sext = FALSE, zext = FALSE;
5169 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
5171 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
5173 if (ins->inst_offset % size != 0) {
5174 /* Unaligned store */
5175 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset, FALSE);
5176 addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (LLVMInt8Type (), 0)), &index, 1, "");
5178 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
5179 addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (t, 0)), &index, 1, "");
5181 emit_store (ctx, bb, &builder, size, convert (ctx, LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE), t), convert (ctx, addr, LLVMPointerType (t, 0)), is_volatile);
5186 emit_load (ctx, bb, &builder, sizeof (gpointer), convert (ctx, lhs, LLVMPointerType (IntPtrType (), 0)), "", TRUE);
5188 case OP_OUTARG_VTRETADDR:
5196 case OP_VOIDCALL_MEMBASE:
5197 case OP_CALL_MEMBASE:
5198 case OP_LCALL_MEMBASE:
5199 case OP_FCALL_MEMBASE:
5200 case OP_RCALL_MEMBASE:
5201 case OP_VCALL_MEMBASE:
5202 case OP_VOIDCALL_REG:
5207 case OP_VCALL_REG: {
5208 process_call (ctx, bb, &builder, ins);
5213 LLVMValueRef indexes [2];
5214 MonoJumpInfo *tmp_ji, *ji;
5215 LLVMValueRef got_entry_addr;
5219 * FIXME: Can't allocate from the cfg mempool since that is freed if
5220 * the LLVM compile fails.
5222 tmp_ji = g_new0 (MonoJumpInfo, 1);
5223 tmp_ji->type = (MonoJumpInfoType)ins->inst_c1;
5224 tmp_ji->data.target = ins->inst_p0;
5226 ji = mono_aot_patch_info_dup (tmp_ji);
5229 ji->next = cfg->patch_info;
5230 cfg->patch_info = ji;
5232 //mono_add_patch_info (cfg, 0, (MonoJumpInfoType)ins->inst_i1, ins->inst_p0);
5233 got_offset = mono_aot_get_got_offset (cfg->patch_info);
5234 ctx->module->max_got_offset = MAX (ctx->module->max_got_offset, got_offset);
5235 if (!mono_aot_is_shared_got_offset (got_offset)) {
5236 //mono_print_ji (ji);
5238 ctx->has_got_access = TRUE;
5241 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
5242 indexes [1] = LLVMConstInt (LLVMInt32Type (), (gssize)got_offset, FALSE);
5243 got_entry_addr = LLVMBuildGEP (builder, ctx->module->got_var, indexes, 2, "");
5245 name = get_aotconst_name (ji->type, ji->data.target, got_offset);
5246 values [ins->dreg] = LLVMBuildLoad (builder, got_entry_addr, name);
5248 /* Can't use this in llvmonly mode since the got slots are initialized by the methods themselves */
5249 if (!cfg->llvm_only)
5250 set_invariant_load_flag (values [ins->dreg]);
5253 case OP_NOT_REACHED:
5254 LLVMBuildUnreachable (builder);
5255 has_terminator = TRUE;
5256 g_assert (bb->block_num < cfg->max_block_num);
5257 ctx->unreachable [bb->block_num] = TRUE;
5258 /* Might have instructions after this */
5260 MonoInst *next = ins->next;
5262 * FIXME: If later code uses the regs defined by these instructions,
5263 * compilation will fail.
5265 MONO_DELETE_INS (bb, next);
5269 MonoInst *var = ins->inst_i0;
5271 if (var->opcode == OP_VTARG_ADDR) {
5272 /* The variable contains the vtype address */
5273 values [ins->dreg] = values [var->dreg];
5274 } else if (var->opcode == OP_GSHAREDVT_LOCAL) {
5275 values [ins->dreg] = emit_gsharedvt_ldaddr (ctx, var->dreg);
5277 values [ins->dreg] = addresses [var->dreg];
5282 LLVMValueRef args [1];
5284 args [0] = convert (ctx, lhs, LLVMDoubleType ());
5285 values [ins->dreg] = LLVMBuildCall (builder, get_intrinsic (ctx, "llvm.sin.f64"), args, 1, dname);
5289 LLVMValueRef args [1];
5291 args [0] = convert (ctx, lhs, LLVMDoubleType ());
5292 values [ins->dreg] = LLVMBuildCall (builder, get_intrinsic (ctx, "llvm.cos.f64"), args, 1, dname);
5296 LLVMValueRef args [1];
5298 args [0] = convert (ctx, lhs, LLVMDoubleType ());
5299 values [ins->dreg] = LLVMBuildCall (builder, get_intrinsic (ctx, "llvm.sqrt.f64"), args, 1, dname);
5303 LLVMValueRef args [1];
5305 args [0] = convert (ctx, lhs, LLVMDoubleType ());
5306 values [ins->dreg] = LLVMBuildCall (builder, get_intrinsic (ctx, "fabs"), args, 1, dname);
5320 lhs = convert (ctx, lhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
5321 rhs = convert (ctx, rhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
5323 switch (ins->opcode) {
5326 v = LLVMBuildICmp (builder, LLVMIntSLE, lhs, rhs, "");
5330 v = LLVMBuildICmp (builder, LLVMIntSGE, lhs, rhs, "");
5334 v = LLVMBuildICmp (builder, LLVMIntULE, lhs, rhs, "");
5338 v = LLVMBuildICmp (builder, LLVMIntUGE, lhs, rhs, "");
5341 g_assert_not_reached ();
5344 values [ins->dreg] = LLVMBuildSelect (builder, v, lhs, rhs, dname);
5347 case OP_ATOMIC_EXCHANGE_I4:
5348 case OP_ATOMIC_EXCHANGE_I8: {
5349 LLVMValueRef args [2];
5352 if (ins->opcode == OP_ATOMIC_EXCHANGE_I4)
5353 t = LLVMInt32Type ();
5355 t = LLVMInt64Type ();
5357 g_assert (ins->inst_offset == 0);
5359 args [0] = convert (ctx, lhs, LLVMPointerType (t, 0));
5360 args [1] = convert (ctx, rhs, t);
5362 values [ins->dreg] = mono_llvm_build_atomic_rmw (builder, LLVM_ATOMICRMW_OP_XCHG, args [0], args [1]);
5365 case OP_ATOMIC_ADD_I4:
5366 case OP_ATOMIC_ADD_I8: {
5367 LLVMValueRef args [2];
5370 if (ins->opcode == OP_ATOMIC_ADD_I4)
5371 t = LLVMInt32Type ();
5373 t = LLVMInt64Type ();
5375 g_assert (ins->inst_offset == 0);
5377 args [0] = convert (ctx, lhs, LLVMPointerType (t, 0));
5378 args [1] = convert (ctx, rhs, t);
5379 values [ins->dreg] = LLVMBuildAdd (builder, mono_llvm_build_atomic_rmw (builder, LLVM_ATOMICRMW_OP_ADD, args [0], args [1]), args [1], dname);
5382 case OP_ATOMIC_CAS_I4:
5383 case OP_ATOMIC_CAS_I8: {
5384 LLVMValueRef args [3], val;
5387 if (ins->opcode == OP_ATOMIC_CAS_I4)
5388 t = LLVMInt32Type ();
5390 t = LLVMInt64Type ();
5392 args [0] = convert (ctx, lhs, LLVMPointerType (t, 0));
5394 args [1] = convert (ctx, values [ins->sreg3], t);
5396 args [2] = convert (ctx, values [ins->sreg2], t);
5397 val = mono_llvm_build_cmpxchg (builder, args [0], args [1], args [2]);
5398 /* cmpxchg returns a pair */
5399 values [ins->dreg] = LLVMBuildExtractValue (builder, val, 0, "");
5402 case OP_MEMORY_BARRIER: {
5403 mono_llvm_build_fence (builder, (BarrierKind) ins->backend.memory_barrier_kind);
5406 case OP_ATOMIC_LOAD_I1:
5407 case OP_ATOMIC_LOAD_I2:
5408 case OP_ATOMIC_LOAD_I4:
5409 case OP_ATOMIC_LOAD_I8:
5410 case OP_ATOMIC_LOAD_U1:
5411 case OP_ATOMIC_LOAD_U2:
5412 case OP_ATOMIC_LOAD_U4:
5413 case OP_ATOMIC_LOAD_U8:
5414 case OP_ATOMIC_LOAD_R4:
5415 case OP_ATOMIC_LOAD_R8: {
5416 set_failure (ctx, "atomic mono.load intrinsic");
5420 gboolean sext, zext;
5422 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
5423 BarrierKind barrier = (BarrierKind) ins->backend.memory_barrier_kind;
5424 LLVMValueRef index, addr;
5426 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
5431 if (ins->inst_offset != 0) {
5432 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
5433 addr = LLVMBuildGEP (builder, convert (ctx, lhs, LLVMPointerType (t, 0)), &index, 1, "");
5438 addr = convert (ctx, addr, LLVMPointerType (t, 0));
5440 values [ins->dreg] = emit_load_general (ctx, bb, &builder, size, addr, dname, is_volatile, barrier);
5443 values [ins->dreg] = LLVMBuildSExt (builder, values [ins->dreg], LLVMInt32Type (), dname);
5445 values [ins->dreg] = LLVMBuildZExt (builder, values [ins->dreg], LLVMInt32Type (), dname);
5449 case OP_ATOMIC_STORE_I1:
5450 case OP_ATOMIC_STORE_I2:
5451 case OP_ATOMIC_STORE_I4:
5452 case OP_ATOMIC_STORE_I8:
5453 case OP_ATOMIC_STORE_U1:
5454 case OP_ATOMIC_STORE_U2:
5455 case OP_ATOMIC_STORE_U4:
5456 case OP_ATOMIC_STORE_U8:
5457 case OP_ATOMIC_STORE_R4:
5458 case OP_ATOMIC_STORE_R8: {
5459 set_failure (ctx, "atomic mono.store intrinsic");
5463 gboolean sext, zext;
5465 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
5466 BarrierKind barrier = (BarrierKind) ins->backend.memory_barrier_kind;
5467 LLVMValueRef index, addr, value;
5469 if (!values [ins->inst_destbasereg]) {
5470 set_failure (ctx, "inst_destbasereg");
5474 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
5476 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
5477 addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (t, 0)), &index, 1, "");
5478 value = convert (ctx, values [ins->sreg1], t);
5480 emit_store_general (ctx, bb, &builder, size, value, addr, is_volatile, barrier);
5484 case OP_RELAXED_NOP: {
5485 #if defined(TARGET_AMD64) || defined(TARGET_X86)
5486 emit_call (ctx, bb, &builder, get_intrinsic (ctx, "llvm.x86.sse2.pause"), NULL, 0);
5493 #if (defined(TARGET_AMD64) || defined(TARGET_X86)) && defined(__linux__)
5495 // 257 == FS segment register
5496 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 257);
5498 // 256 == GS segment register
5499 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 256);
5502 values [ins->dreg] = LLVMBuildLoad (builder, LLVMBuildIntToPtr (builder, LLVMConstInt (IntPtrType (), ins->inst_offset, TRUE), ptrtype, ""), "");
5503 #elif defined(TARGET_AMD64) && defined(TARGET_OSX)
5504 /* See mono_amd64_emit_tls_get () */
5505 int offset = mono_amd64_get_tls_gs_offset () + (ins->inst_offset * 8);
5507 // 256 == GS segment register
5508 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 256);
5509 values [ins->dreg] = LLVMBuildLoad (builder, LLVMBuildIntToPtr (builder, LLVMConstInt (IntPtrType (), offset, TRUE), ptrtype, ""), "");
5511 set_failure (ctx, "opcode tls-get");
5517 case OP_TLS_GET_REG: {
5518 #if defined(TARGET_AMD64) && defined(TARGET_OSX)
5519 /* See emit_tls_get_reg () */
5520 // 256 == GS segment register
5521 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 256);
5522 values [ins->dreg] = LLVMBuildLoad (builder, LLVMBuildIntToPtr (builder, convert (ctx, lhs, LLVMInt32Type ()), ptrtype, ""), "");
5524 set_failure (ctx, "opcode tls-get");
5530 case OP_TLS_SET_REG: {
5531 #if defined(TARGET_AMD64) && defined(TARGET_OSX)
5532 /* See emit_tls_get_reg () */
5533 // 256 == GS segment register
5534 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 256);
5535 LLVMBuildStore (builder, convert (ctx, lhs, IntPtrType ()), LLVMBuildIntToPtr (builder, convert (ctx, rhs, LLVMInt32Type ()), ptrtype, ""));
5537 set_failure (ctx, "opcode tls-set-reg");
5547 case OP_IADD_OVF_UN:
5549 case OP_ISUB_OVF_UN:
5551 case OP_IMUL_OVF_UN:
5552 #if SIZEOF_VOID_P == 8
5554 case OP_LADD_OVF_UN:
5556 case OP_LSUB_OVF_UN:
5558 case OP_LMUL_OVF_UN:
5561 LLVMValueRef args [2], val, ovf, func;
5563 args [0] = convert (ctx, lhs, op_to_llvm_type (ins->opcode));
5564 args [1] = convert (ctx, rhs, op_to_llvm_type (ins->opcode));
5565 func = get_intrinsic (ctx, ovf_op_to_intrins (ins->opcode));
5567 val = LLVMBuildCall (builder, func, args, 2, "");
5568 values [ins->dreg] = LLVMBuildExtractValue (builder, val, 0, dname);
5569 ovf = LLVMBuildExtractValue (builder, val, 1, "");
5570 emit_cond_system_exception (ctx, bb, "OverflowException", ovf);
5573 builder = ctx->builder;
5579 * We currently model them using arrays. Promotion to local vregs is
5580 * disabled for them in mono_handle_global_vregs () in the LLVM case,
5581 * so we always have an entry in cfg->varinfo for them.
5582 * FIXME: Is this needed ?
5585 MonoClass *klass = ins->klass;
5586 LLVMValueRef args [5];
5590 set_failure (ctx, "!klass");
5594 if (!addresses [ins->dreg])
5595 addresses [ins->dreg] = build_alloca (ctx, &klass->byval_arg);
5596 args [0] = LLVMBuildBitCast (builder, addresses [ins->dreg], LLVMPointerType (LLVMInt8Type (), 0), "");
5597 args [1] = LLVMConstInt (LLVMInt8Type (), 0, FALSE);
5598 args [2] = LLVMConstInt (LLVMInt32Type (), mono_class_value_size (klass, NULL), FALSE);
5600 args [3] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
5601 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
5602 LLVMBuildCall (builder, get_intrinsic (ctx, "llvm.memset.p0i8.i32"), args, 5, "");
5605 case OP_DUMMY_VZERO:
5608 case OP_STOREV_MEMBASE:
5609 case OP_LOADV_MEMBASE:
5611 MonoClass *klass = ins->klass;
5612 LLVMValueRef src = NULL, dst, args [5];
5613 gboolean done = FALSE;
5617 set_failure (ctx, "!klass");
5621 if (mini_is_gsharedvt_klass (klass)) {
5623 set_failure (ctx, "gsharedvt");
5627 switch (ins->opcode) {
5628 case OP_STOREV_MEMBASE:
5629 if (cfg->gen_write_barriers && klass->has_references && ins->inst_destbasereg != cfg->frame_reg &&
5630 LLVMGetInstructionOpcode (values [ins->inst_destbasereg]) != LLVMAlloca) {
5631 /* Decomposed earlier */
5632 g_assert_not_reached ();
5635 if (!addresses [ins->sreg1]) {
5637 g_assert (values [ins->sreg1]);
5638 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));
5639 LLVMBuildStore (builder, values [ins->sreg1], dst);
5642 src = LLVMBuildBitCast (builder, addresses [ins->sreg1], LLVMPointerType (LLVMInt8Type (), 0), "");
5643 dst = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_destbasereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (LLVMInt8Type (), 0));
5646 case OP_LOADV_MEMBASE:
5647 if (!addresses [ins->dreg])
5648 addresses [ins->dreg] = build_alloca (ctx, &klass->byval_arg);
5649 src = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_basereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (LLVMInt8Type (), 0));
5650 dst = LLVMBuildBitCast (builder, addresses [ins->dreg], LLVMPointerType (LLVMInt8Type (), 0), "");
5653 if (!addresses [ins->sreg1])
5654 addresses [ins->sreg1] = build_alloca (ctx, &klass->byval_arg);
5655 if (!addresses [ins->dreg])
5656 addresses [ins->dreg] = build_alloca (ctx, &klass->byval_arg);
5657 src = LLVMBuildBitCast (builder, addresses [ins->sreg1], LLVMPointerType (LLVMInt8Type (), 0), "");
5658 dst = LLVMBuildBitCast (builder, addresses [ins->dreg], LLVMPointerType (LLVMInt8Type (), 0), "");
5661 g_assert_not_reached ();
5671 args [2] = LLVMConstInt (LLVMInt32Type (), mono_class_value_size (klass, NULL), FALSE);
5672 args [3] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
5674 args [3] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
5675 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
5676 LLVMBuildCall (builder, get_intrinsic (ctx, "llvm.memcpy.p0i8.p0i8.i32"), args, 5, "");
5679 case OP_LLVM_OUTARG_VT: {
5680 LLVMArgInfo *ainfo = (LLVMArgInfo*)ins->inst_p0;
5681 MonoType *t = mini_get_underlying_type (ins->inst_vtype);
5683 if (ainfo->storage == LLVMArgGsharedvtVariable) {
5684 MonoInst *var = get_vreg_to_inst (cfg, ins->sreg1);
5686 if (var && var->opcode == OP_GSHAREDVT_LOCAL) {
5687 addresses [ins->dreg] = convert (ctx, emit_gsharedvt_ldaddr (ctx, var->dreg), LLVMPointerType (IntPtrType (), 0));
5689 g_assert (addresses [ins->sreg1]);
5690 addresses [ins->dreg] = addresses [ins->sreg1];
5692 } else if (ainfo->storage == LLVMArgGsharedvtFixed) {
5693 if (!addresses [ins->sreg1]) {
5694 addresses [ins->sreg1] = build_alloca (ctx, t);
5695 g_assert (values [ins->sreg1]);
5697 LLVMBuildStore (builder, convert (ctx, values [ins->sreg1], LLVMGetElementType (LLVMTypeOf (addresses [ins->sreg1]))), addresses [ins->sreg1]);
5698 addresses [ins->dreg] = addresses [ins->sreg1];
5700 if (!addresses [ins->sreg1]) {
5701 addresses [ins->sreg1] = build_alloca (ctx, t);
5702 g_assert (values [ins->sreg1]);
5703 LLVMBuildStore (builder, convert (ctx, values [ins->sreg1], type_to_llvm_type (ctx, t)), addresses [ins->sreg1]);
5705 addresses [ins->dreg] = addresses [ins->sreg1];
5713 #if defined(TARGET_X86) || defined(TARGET_AMD64)
5715 values [ins->dreg] = LLVMConstNull (type_to_llvm_type (ctx, &ins->klass->byval_arg));
5718 case OP_LOADX_MEMBASE: {
5719 LLVMTypeRef t = type_to_llvm_type (ctx, &ins->klass->byval_arg);
5722 src = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_basereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (t, 0));
5723 values [ins->dreg] = mono_llvm_build_aligned_load (builder, src, "", FALSE, 1);
5726 case OP_STOREX_MEMBASE: {
5727 LLVMTypeRef t = LLVMTypeOf (values [ins->sreg1]);
5730 dest = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_destbasereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (t, 0));
5731 mono_llvm_build_aligned_store (builder, values [ins->sreg1], dest, FALSE, 1);
5738 values [ins->dreg] = LLVMBuildAdd (builder, lhs, rhs, "");
5742 values [ins->dreg] = LLVMBuildFAdd (builder, lhs, rhs, "");
5748 values [ins->dreg] = LLVMBuildSub (builder, lhs, rhs, "");
5752 values [ins->dreg] = LLVMBuildFSub (builder, lhs, rhs, "");
5756 values [ins->dreg] = LLVMBuildFMul (builder, lhs, rhs, "");
5760 values [ins->dreg] = LLVMBuildFDiv (builder, lhs, rhs, "");
5763 values [ins->dreg] = LLVMBuildAnd (builder, lhs, rhs, "");
5766 values [ins->dreg] = LLVMBuildOr (builder, lhs, rhs, "");
5769 values [ins->dreg] = LLVMBuildXor (builder, lhs, rhs, "");
5773 values [ins->dreg] = LLVMBuildMul (builder, lhs, rhs, "");
5784 LLVMValueRef v = NULL;
5786 switch (ins->opcode) {
5791 t = LLVMVectorType (LLVMInt32Type (), 4);
5792 rt = LLVMVectorType (LLVMFloatType (), 4);
5798 t = LLVMVectorType (LLVMInt64Type (), 2);
5799 rt = LLVMVectorType (LLVMDoubleType (), 2);
5802 t = LLVMInt32Type ();
5803 rt = LLVMInt32Type ();
5804 g_assert_not_reached ();
5807 lhs = LLVMBuildBitCast (builder, lhs, t, "");
5808 rhs = LLVMBuildBitCast (builder, rhs, t, "");
5809 switch (ins->opcode) {
5812 v = LLVMBuildAnd (builder, lhs, rhs, "");
5816 v = LLVMBuildOr (builder, lhs, rhs, "");
5820 v = LLVMBuildXor (builder, lhs, rhs, "");
5824 v = LLVMBuildAnd (builder, rhs, LLVMBuildNot (builder, lhs, ""), "");
5827 values [ins->dreg] = LLVMBuildBitCast (builder, v, rt, "");
5851 case OP_PADDB_SAT_UN:
5852 case OP_PADDW_SAT_UN:
5853 case OP_PSUBB_SAT_UN:
5854 case OP_PSUBW_SAT_UN:
5862 case OP_PMULW_HIGH_UN: {
5863 LLVMValueRef args [2];
5868 values [ins->dreg] = LLVMBuildCall (builder, get_intrinsic (ctx, simd_op_to_intrins (ins->opcode)), args, 2, dname);
5875 values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildICmp (builder, LLVMIntEQ, lhs, rhs, ""), LLVMTypeOf (lhs), "");
5879 values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildICmp (builder, LLVMIntSGT, lhs, rhs, ""), LLVMTypeOf (lhs), "");
5887 case OP_EXTRACTX_U2:
5889 case OP_EXTRACT_U1: {
5891 gboolean zext = FALSE;
5893 t = simd_op_to_llvm_type (ins->opcode);
5895 switch (ins->opcode) {
5903 case OP_EXTRACTX_U2:
5908 t = LLVMInt32Type ();
5909 g_assert_not_reached ();
5912 lhs = LLVMBuildBitCast (builder, lhs, t, "");
5913 values [ins->dreg] = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), "");
5915 values [ins->dreg] = LLVMBuildZExt (builder, values [ins->dreg], LLVMInt32Type (), "");
5924 case OP_EXPAND_R8: {
5925 LLVMTypeRef t = simd_op_to_llvm_type (ins->opcode);
5926 LLVMValueRef mask [16], v;
5929 for (i = 0; i < 16; ++i)
5930 mask [i] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
5932 v = convert (ctx, values [ins->sreg1], LLVMGetElementType (t));
5934 values [ins->dreg] = LLVMBuildInsertElement (builder, LLVMConstNull (t), v, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
5935 values [ins->dreg] = LLVMBuildShuffleVector (builder, values [ins->dreg], LLVMGetUndef (t), LLVMConstVector (mask, LLVMGetVectorSize (t)), "");
5940 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt8Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
5943 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt16Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
5946 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt32Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
5949 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt64Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
5952 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMFloatType ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
5955 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMDoubleType ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
5966 case OP_EXTRACT_MASK:
5973 v = convert (ctx, values [ins->sreg1], simd_op_to_llvm_type (ins->opcode));
5975 values [ins->dreg] = LLVMBuildCall (builder, get_intrinsic (ctx, simd_op_to_intrins (ins->opcode)), &v, 1, dname);
5981 LLVMValueRef args [3];
5985 args [2] = LLVMConstInt (LLVMInt8Type (), ins->inst_c0, FALSE);
5987 values [ins->dreg] = LLVMBuildCall (builder, get_intrinsic (ctx, simd_op_to_intrins (ins->opcode)), args, 3, dname);
5992 /* This is only used for implementing shifts by non-immediate */
5993 values [ins->dreg] = lhs;
6004 LLVMValueRef args [3];
6007 args [1] = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
6009 values [ins->dreg] = LLVMBuildCall (builder, get_intrinsic (ctx, simd_op_to_intrins (ins->opcode)), args, 2, dname);
6020 case OP_PSHLQ_REG: {
6021 LLVMValueRef args [3];
6024 args [1] = values [ins->sreg2];
6026 values [ins->dreg] = LLVMBuildCall (builder, get_intrinsic (ctx, simd_op_to_intrins (ins->opcode)), args, 2, dname);
6033 case OP_PSHUFLEW_LOW:
6034 case OP_PSHUFLEW_HIGH: {
6036 LLVMValueRef v1 = NULL, v2 = NULL, mask_values [16];
6037 int i, mask_size = 0;
6038 int imask = ins->inst_c0;
6040 /* Convert the x86 shuffle mask to LLVM's */
6041 switch (ins->opcode) {
6044 mask [0] = ((imask >> 0) & 3);
6045 mask [1] = ((imask >> 2) & 3);
6046 mask [2] = ((imask >> 4) & 3) + 4;
6047 mask [3] = ((imask >> 6) & 3) + 4;
6048 v1 = values [ins->sreg1];
6049 v2 = values [ins->sreg2];
6053 mask [0] = ((imask >> 0) & 1);
6054 mask [1] = ((imask >> 1) & 1) + 2;
6055 v1 = values [ins->sreg1];
6056 v2 = values [ins->sreg2];
6058 case OP_PSHUFLEW_LOW:
6060 mask [0] = ((imask >> 0) & 3);
6061 mask [1] = ((imask >> 2) & 3);
6062 mask [2] = ((imask >> 4) & 3);
6063 mask [3] = ((imask >> 6) & 3);
6068 v1 = values [ins->sreg1];
6069 v2 = LLVMGetUndef (LLVMTypeOf (v1));
6071 case OP_PSHUFLEW_HIGH:
6077 mask [4] = 4 + ((imask >> 0) & 3);
6078 mask [5] = 4 + ((imask >> 2) & 3);
6079 mask [6] = 4 + ((imask >> 4) & 3);
6080 mask [7] = 4 + ((imask >> 6) & 3);
6081 v1 = values [ins->sreg1];
6082 v2 = LLVMGetUndef (LLVMTypeOf (v1));
6086 mask [0] = ((imask >> 0) & 3);
6087 mask [1] = ((imask >> 2) & 3);
6088 mask [2] = ((imask >> 4) & 3);
6089 mask [3] = ((imask >> 6) & 3);
6090 v1 = values [ins->sreg1];
6091 v2 = LLVMGetUndef (LLVMTypeOf (v1));
6094 g_assert_not_reached ();
6096 for (i = 0; i < mask_size; ++i)
6097 mask_values [i] = LLVMConstInt (LLVMInt32Type (), mask [i], FALSE);
6099 values [ins->dreg] =
6100 LLVMBuildShuffleVector (builder, v1, v2,
6101 LLVMConstVector (mask_values, mask_size), dname);
6105 case OP_UNPACK_LOWB:
6106 case OP_UNPACK_LOWW:
6107 case OP_UNPACK_LOWD:
6108 case OP_UNPACK_LOWQ:
6109 case OP_UNPACK_LOWPS:
6110 case OP_UNPACK_LOWPD:
6111 case OP_UNPACK_HIGHB:
6112 case OP_UNPACK_HIGHW:
6113 case OP_UNPACK_HIGHD:
6114 case OP_UNPACK_HIGHQ:
6115 case OP_UNPACK_HIGHPS:
6116 case OP_UNPACK_HIGHPD: {
6118 LLVMValueRef mask_values [16];
6119 int i, mask_size = 0;
6120 gboolean low = FALSE;
6122 switch (ins->opcode) {
6123 case OP_UNPACK_LOWB:
6127 case OP_UNPACK_LOWW:
6131 case OP_UNPACK_LOWD:
6132 case OP_UNPACK_LOWPS:
6136 case OP_UNPACK_LOWQ:
6137 case OP_UNPACK_LOWPD:
6141 case OP_UNPACK_HIGHB:
6144 case OP_UNPACK_HIGHW:
6147 case OP_UNPACK_HIGHD:
6148 case OP_UNPACK_HIGHPS:
6151 case OP_UNPACK_HIGHQ:
6152 case OP_UNPACK_HIGHPD:
6156 g_assert_not_reached ();
6160 for (i = 0; i < (mask_size / 2); ++i) {
6162 mask [(i * 2) + 1] = mask_size + i;
6165 for (i = 0; i < (mask_size / 2); ++i) {
6166 mask [(i * 2)] = (mask_size / 2) + i;
6167 mask [(i * 2) + 1] = mask_size + (mask_size / 2) + i;
6171 for (i = 0; i < mask_size; ++i)
6172 mask_values [i] = LLVMConstInt (LLVMInt32Type (), mask [i], FALSE);
6174 values [ins->dreg] =
6175 LLVMBuildShuffleVector (builder, values [ins->sreg1], values [ins->sreg2],
6176 LLVMConstVector (mask_values, mask_size), dname);
6181 LLVMTypeRef t = simd_op_to_llvm_type (ins->opcode);
6182 LLVMValueRef v, val;
6184 v = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
6185 val = LLVMConstNull (t);
6186 val = LLVMBuildInsertElement (builder, val, v, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
6187 val = LLVMBuildInsertElement (builder, val, v, LLVMConstInt (LLVMInt32Type (), 1, FALSE), dname);
6189 values [ins->dreg] = val;
6193 case OP_DUPPS_HIGH: {
6194 LLVMTypeRef t = simd_op_to_llvm_type (ins->opcode);
6195 LLVMValueRef v1, v2, val;
6198 if (ins->opcode == OP_DUPPS_LOW) {
6199 v1 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
6200 v2 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 2, FALSE), "");
6202 v1 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 1, FALSE), "");
6203 v2 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 3, FALSE), "");
6205 val = LLVMConstNull (t);
6206 val = LLVMBuildInsertElement (builder, val, v1, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
6207 val = LLVMBuildInsertElement (builder, val, v1, LLVMConstInt (LLVMInt32Type (), 1, FALSE), "");
6208 val = LLVMBuildInsertElement (builder, val, v2, LLVMConstInt (LLVMInt32Type (), 2, FALSE), "");
6209 val = LLVMBuildInsertElement (builder, val, v2, LLVMConstInt (LLVMInt32Type (), 3, FALSE), "");
6211 values [ins->dreg] = val;
6221 * EXCEPTION HANDLING
6223 case OP_IMPLICIT_EXCEPTION:
6224 /* This marks a place where an implicit exception can happen */
6225 if (bb->region != -1)
6226 set_failure (ctx, "implicit-exception");
6230 gboolean rethrow = (ins->opcode == OP_RETHROW);
6231 if (ctx->llvm_only) {
6232 emit_llvmonly_throw (ctx, bb, rethrow, lhs);
6233 has_terminator = TRUE;
6234 ctx->unreachable [bb->block_num] = TRUE;
6236 emit_throw (ctx, bb, rethrow, lhs);
6237 builder = ctx->builder;
6241 case OP_CALL_HANDLER: {
6243 * We don't 'call' handlers, but instead simply branch to them.
6244 * The code generated by ENDFINALLY will branch back to us.
6246 LLVMBasicBlockRef noex_bb;
6248 BBInfo *info = &bblocks [ins->inst_target_bb->block_num];
6250 bb_list = info->call_handler_return_bbs;
6253 * Set the indicator variable for the finally clause.
6255 lhs = info->finally_ind;
6257 LLVMBuildStore (builder, LLVMConstInt (LLVMInt32Type (), g_slist_length (bb_list) + 1, FALSE), lhs);
6259 /* Branch to the finally clause */
6260 LLVMBuildBr (builder, info->call_handler_target_bb);
6262 noex_bb = gen_bb (ctx, "CALL_HANDLER_CONT_BB");
6263 info->call_handler_return_bbs = g_slist_append_mempool (cfg->mempool, info->call_handler_return_bbs, noex_bb);
6265 builder = ctx->builder = create_builder (ctx);
6266 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
6268 bblocks [bb->block_num].end_bblock = noex_bb;
6271 case OP_START_HANDLER: {
6274 case OP_ENDFINALLY: {
6275 LLVMBasicBlockRef resume_bb;
6276 MonoBasicBlock *handler_bb;
6277 LLVMValueRef val, switch_ins, callee;
6281 handler_bb = (MonoBasicBlock*)g_hash_table_lookup (ctx->region_to_handler, GUINT_TO_POINTER (mono_get_block_region_notry (cfg, bb->region)));
6282 g_assert (handler_bb);
6283 info = &bblocks [handler_bb->block_num];
6284 lhs = info->finally_ind;
6287 bb_list = info->call_handler_return_bbs;
6289 resume_bb = gen_bb (ctx, "ENDFINALLY_RESUME_BB");
6291 /* Load the finally variable */
6292 val = LLVMBuildLoad (builder, lhs, "");
6294 /* Reset the variable */
6295 LLVMBuildStore (builder, LLVMConstInt (LLVMInt32Type (), 0, FALSE), lhs);
6297 /* Branch to either resume_bb, or to the bblocks in bb_list */
6298 switch_ins = LLVMBuildSwitch (builder, val, resume_bb, g_slist_length (bb_list));
6300 * The other targets are added at the end to handle OP_CALL_HANDLER
6301 * opcodes processed later.
6303 info->endfinally_switch_ins_list = g_slist_append_mempool (cfg->mempool, info->endfinally_switch_ins_list, switch_ins);
6305 builder = ctx->builder = create_builder (ctx);
6306 LLVMPositionBuilderAtEnd (ctx->builder, resume_bb);
6308 if (ctx->llvm_only) {
6309 emit_resume_eh (ctx, bb);
6311 if (ctx->cfg->compile_aot) {
6312 callee = get_callee (ctx, LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE), MONO_PATCH_INFO_INTERNAL_METHOD, "llvm_resume_unwind_trampoline");
6314 #if LLVM_API_VERSION > 100
6315 MonoJitICallInfo *info;
6317 info = mono_find_jit_icall_by_name ("llvm_resume_unwind_trampoline");
6319 gpointer target = (void*)info->func;
6320 LLVMTypeRef icall_sig = LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE);
6321 callee = emit_jit_callee (ctx, "llvm_resume_unwind_trampoline", icall_sig, target);
6323 callee = LLVMGetNamedFunction (ctx->lmodule, "llvm_resume_unwind_trampoline");
6326 LLVMBuildCall (builder, callee, NULL, 0, "");
6327 LLVMBuildUnreachable (builder);
6330 has_terminator = TRUE;
6333 case OP_IL_SEQ_POINT:
6338 sprintf (reason, "opcode %s", mono_inst_name (ins->opcode));
6339 set_failure (ctx, reason);
6347 /* Convert the value to the type required by phi nodes */
6348 if (spec [MONO_INST_DEST] != ' ' && !MONO_IS_STORE_MEMBASE (ins) && ctx->vreg_types [ins->dreg]) {
6349 if (!values [ins->dreg])
6351 values [ins->dreg] = addresses [ins->dreg];
6353 values [ins->dreg] = convert (ctx, values [ins->dreg], ctx->vreg_types [ins->dreg]);
6356 /* Add stores for volatile variables */
6357 if (spec [MONO_INST_DEST] != ' ' && spec [MONO_INST_DEST] != 'v' && !MONO_IS_STORE_MEMBASE (ins))
6358 emit_volatile_store (ctx, ins->dreg);
6364 if (!has_terminator && bb->next_bb && (bb == cfg->bb_entry || bb->in_count > 0)) {
6365 LLVMBuildBr (builder, get_bb (ctx, bb->next_bb));
6368 if (bb == cfg->bb_exit && sig->ret->type == MONO_TYPE_VOID) {
6369 emit_dbg_loc (ctx, builder, cfg->header->code + cfg->header->code_size - 1);
6370 LLVMBuildRetVoid (builder);
6373 if (bb == cfg->bb_entry)
6374 ctx->last_alloca = LLVMGetLastInstruction (get_bb (ctx, cfg->bb_entry));
6378 * mono_llvm_check_method_supported:
6380 * Do some quick checks to decide whenever cfg->method can be compiled by LLVM, to avoid
6381 * compiling a method twice.
6384 mono_llvm_check_method_supported (MonoCompile *cfg)
6391 if (cfg->method->save_lmf) {
6392 cfg->exception_message = g_strdup ("lmf");
6393 cfg->disable_llvm = TRUE;
6395 if (cfg->disable_llvm)
6399 * Nested clauses where one of the clauses is a finally clause is
6400 * not supported, because LLVM can't figure out the control flow,
6401 * probably because we resume exception handling by calling our
6402 * own function instead of using the 'resume' llvm instruction.
6404 for (i = 0; i < cfg->header->num_clauses; ++i) {
6405 for (j = 0; j < cfg->header->num_clauses; ++j) {
6406 MonoExceptionClause *clause1 = &cfg->header->clauses [i];
6407 MonoExceptionClause *clause2 = &cfg->header->clauses [j];
6409 // FIXME: Nested try clauses fail in some cases too, i.e. #37273
6410 if (i != j && clause1->try_offset >= clause2->try_offset && clause1->handler_offset <= clause2->handler_offset) {
6411 //(clause1->flags == MONO_EXCEPTION_CLAUSE_FINALLY || clause2->flags == MONO_EXCEPTION_CLAUSE_FINALLY)) {
6412 cfg->exception_message = g_strdup ("nested clauses");
6413 cfg->disable_llvm = TRUE;
6418 if (cfg->disable_llvm)
6422 if (cfg->method->dynamic) {
6423 cfg->exception_message = g_strdup ("dynamic.");
6424 cfg->disable_llvm = TRUE;
6426 if (cfg->disable_llvm)
6430 static LLVMCallInfo*
6431 get_llvm_call_info (MonoCompile *cfg, MonoMethodSignature *sig)
6433 LLVMCallInfo *linfo;
6436 if (cfg->gsharedvt && cfg->llvm_only && mini_is_gsharedvt_variable_signature (sig)) {
6440 * Gsharedvt methods have the following calling convention:
6441 * - all arguments are passed by ref, even non generic ones
6442 * - the return value is returned by ref too, using a vret
6443 * argument passed after 'this'.
6445 n = sig->param_count + sig->hasthis;
6446 linfo = (LLVMCallInfo*)mono_mempool_alloc0 (cfg->mempool, sizeof (LLVMCallInfo) + (sizeof (LLVMArgInfo) * n));
6450 linfo->args [pindex ++].storage = LLVMArgNormal;
6452 if (sig->ret->type != MONO_TYPE_VOID) {
6453 if (mini_is_gsharedvt_variable_type (sig->ret))
6454 linfo->ret.storage = LLVMArgGsharedvtVariable;
6455 else if (mini_type_is_vtype (sig->ret))
6456 linfo->ret.storage = LLVMArgGsharedvtFixedVtype;
6458 linfo->ret.storage = LLVMArgGsharedvtFixed;
6459 linfo->vret_arg_index = pindex;
6461 linfo->ret.storage = LLVMArgNone;
6464 for (i = 0; i < sig->param_count; ++i) {
6465 if (sig->params [i]->byref)
6466 linfo->args [pindex].storage = LLVMArgNormal;
6467 else if (mini_is_gsharedvt_variable_type (sig->params [i]))
6468 linfo->args [pindex].storage = LLVMArgGsharedvtVariable;
6469 else if (mini_type_is_vtype (sig->params [i]))
6470 linfo->args [pindex].storage = LLVMArgGsharedvtFixedVtype;
6472 linfo->args [pindex].storage = LLVMArgGsharedvtFixed;
6473 linfo->args [pindex].type = sig->params [i];
6480 linfo = mono_arch_get_llvm_call_info (cfg, sig);
6481 for (i = 0; i < sig->param_count; ++i)
6482 linfo->args [i + sig->hasthis].type = sig->params [i];
6488 emit_method_inner (EmitContext *ctx);
6491 free_ctx (EmitContext *ctx)
6495 g_free (ctx->values);
6496 g_free (ctx->addresses);
6497 g_free (ctx->vreg_types);
6498 g_free (ctx->vreg_cli_types);
6499 g_free (ctx->is_dead);
6500 g_free (ctx->unreachable);
6501 g_ptr_array_free (ctx->phi_values, TRUE);
6502 g_free (ctx->bblocks);
6503 g_hash_table_destroy (ctx->region_to_handler);
6504 g_hash_table_destroy (ctx->clause_to_handler);
6505 g_hash_table_destroy (ctx->jit_callees);
6506 g_free (ctx->method_name);
6507 g_ptr_array_free (ctx->bblock_list, TRUE);
6509 for (l = ctx->builders; l; l = l->next) {
6510 LLVMBuilderRef builder = (LLVMBuilderRef)l->data;
6511 LLVMDisposeBuilder (builder);
6518 * mono_llvm_emit_method:
6520 * Emit LLVM IL from the mono IL, and compile it to native code using LLVM.
6523 mono_llvm_emit_method (MonoCompile *cfg)
6527 gboolean is_linkonce = FALSE;
6530 /* The code below might acquire the loader lock, so use it for global locking */
6531 mono_loader_lock ();
6533 /* Used to communicate with the callbacks */
6534 mono_native_tls_set_value (current_cfg_tls_id, cfg);
6536 ctx = g_new0 (EmitContext, 1);
6538 ctx->mempool = cfg->mempool;
6541 * This maps vregs to the LLVM instruction defining them
6543 ctx->values = g_new0 (LLVMValueRef, cfg->next_vreg);
6545 * This maps vregs for volatile variables to the LLVM instruction defining their
6548 ctx->addresses = g_new0 (LLVMValueRef, cfg->next_vreg);
6549 ctx->vreg_types = g_new0 (LLVMTypeRef, cfg->next_vreg);
6550 ctx->vreg_cli_types = g_new0 (MonoType*, cfg->next_vreg);
6551 ctx->phi_values = g_ptr_array_sized_new (256);
6553 * This signals whenever the vreg was defined by a phi node with no input vars
6554 * (i.e. all its input bblocks end with NOT_REACHABLE).
6556 ctx->is_dead = g_new0 (gboolean, cfg->next_vreg);
6557 /* Whenever the bblock is unreachable */
6558 ctx->unreachable = g_new0 (gboolean, cfg->max_block_num);
6559 ctx->bblock_list = g_ptr_array_sized_new (256);
6561 ctx->region_to_handler = g_hash_table_new (NULL, NULL);
6562 ctx->clause_to_handler = g_hash_table_new (NULL, NULL);
6563 ctx->method_to_callers = g_hash_table_new (NULL, NULL);
6564 ctx->jit_callees = g_hash_table_new (NULL, NULL);
6565 if (cfg->compile_aot) {
6566 ctx->module = &aot_module;
6570 * Allow the linker to discard duplicate copies of wrappers, generic instances etc. by using the 'linkonce'
6571 * linkage for them. This requires the following:
6572 * - the method needs to have a unique mangled name
6573 * - llvmonly mode, since the code in aot-runtime.c would initialize got slots in the wrong aot image etc.
6575 is_linkonce = ctx->module->llvm_only && ctx->module->static_link && mono_aot_is_linkonce_method (cfg->method);
6577 method_name = mono_aot_get_mangled_method_name (cfg->method);
6579 is_linkonce = FALSE;
6582 printf ("%s %s\n", mono_method_full_name (cfg->method, 1), method_name);
6584 printf ("%s\n", mono_method_full_name (cfg->method, 1));
6588 method_name = mono_aot_get_method_name (cfg);
6589 cfg->llvm_method_name = g_strdup (method_name);
6591 init_jit_module (cfg->domain);
6592 ctx->module = (MonoLLVMModule*)domain_jit_info (cfg->domain)->llvm_module;
6593 method_name = mono_method_full_name (cfg->method, TRUE);
6595 ctx->method_name = method_name;
6596 ctx->is_linkonce = is_linkonce;
6598 #if LLVM_API_VERSION > 100
6599 ctx->lmodule = LLVMModuleCreateWithName ("jit-module");
6601 ctx->lmodule = ctx->module->lmodule;
6603 ctx->llvm_only = ctx->module->llvm_only;
6605 emit_method_inner (ctx);
6607 if (!ctx_ok (ctx)) {
6609 /* Need to add unused phi nodes as they can be referenced by other values */
6610 LLVMBasicBlockRef phi_bb = LLVMAppendBasicBlock (ctx->lmethod, "PHI_BB");
6611 LLVMBuilderRef builder;
6613 builder = create_builder (ctx);
6614 LLVMPositionBuilderAtEnd (builder, phi_bb);
6616 for (i = 0; i < ctx->phi_values->len; ++i) {
6617 LLVMValueRef v = (LLVMValueRef)g_ptr_array_index (ctx->phi_values, i);
6618 if (LLVMGetInstructionParent (v) == NULL)
6619 LLVMInsertIntoBuilder (builder, v);
6622 LLVMDeleteFunction (ctx->lmethod);
6628 mono_native_tls_set_value (current_cfg_tls_id, NULL);
6630 mono_loader_unlock ();
6634 emit_method_inner (EmitContext *ctx)
6636 MonoCompile *cfg = ctx->cfg;
6637 MonoMethodSignature *sig;
6639 LLVMTypeRef method_type;
6640 LLVMValueRef method = NULL;
6641 LLVMValueRef *values = ctx->values;
6642 int i, max_block_num, bb_index;
6643 gboolean last = FALSE;
6644 LLVMCallInfo *linfo;
6645 LLVMModuleRef lmodule = ctx->lmodule;
6647 GPtrArray *bblock_list = ctx->bblock_list;
6648 MonoMethodHeader *header;
6649 MonoExceptionClause *clause;
6652 if (cfg->gsharedvt && !cfg->llvm_only) {
6653 set_failure (ctx, "gsharedvt");
6659 static int count = 0;
6662 if (g_getenv ("LLVM_COUNT")) {
6663 if (count == atoi (g_getenv ("LLVM_COUNT"))) {
6664 printf ("LAST: %s\n", mono_method_full_name (cfg->method, TRUE));
6668 if (count > atoi (g_getenv ("LLVM_COUNT"))) {
6669 set_failure (ctx, "count");
6676 sig = mono_method_signature (cfg->method);
6679 linfo = get_llvm_call_info (cfg, sig);
6685 linfo->rgctx_arg = TRUE;
6686 ctx->method_type = method_type = sig_to_llvm_sig_full (ctx, sig, linfo);
6690 method = LLVMAddFunction (lmodule, ctx->method_name, method_type);
6691 ctx->lmethod = method;
6693 if (!cfg->llvm_only)
6694 LLVMSetFunctionCallConv (method, LLVMMono1CallConv);
6695 LLVMSetLinkage (method, LLVMPrivateLinkage);
6697 LLVMAddFunctionAttr (method, LLVMUWTable);
6699 if (cfg->compile_aot) {
6700 LLVMSetLinkage (method, LLVMInternalLinkage);
6701 if (ctx->module->external_symbols) {
6702 LLVMSetLinkage (method, LLVMExternalLinkage);
6703 LLVMSetVisibility (method, LLVMHiddenVisibility);
6705 if (ctx->is_linkonce) {
6706 LLVMSetLinkage (method, LLVMLinkOnceAnyLinkage);
6707 LLVMSetVisibility (method, LLVMDefaultVisibility);
6710 #if LLVM_API_VERSION > 100
6711 LLVMSetLinkage (method, LLVMExternalLinkage);
6713 LLVMSetLinkage (method, LLVMPrivateLinkage);
6717 if (cfg->method->save_lmf && !cfg->llvm_only) {
6718 set_failure (ctx, "lmf");
6722 if (sig->pinvoke && cfg->method->wrapper_type != MONO_WRAPPER_RUNTIME_INVOKE && !cfg->llvm_only) {
6723 set_failure (ctx, "pinvoke signature");
6727 header = cfg->header;
6728 for (i = 0; i < header->num_clauses; ++i) {
6729 clause = &header->clauses [i];
6730 if (clause->flags != MONO_EXCEPTION_CLAUSE_FINALLY && clause->flags != MONO_EXCEPTION_CLAUSE_NONE) {
6731 set_failure (ctx, "non-finally/catch clause.");
6735 if (header->num_clauses || (cfg->method->iflags & METHOD_IMPL_ATTRIBUTE_NOINLINING) || cfg->no_inline)
6736 /* We can't handle inlined methods with clauses */
6737 LLVMAddFunctionAttr (method, LLVMNoInlineAttribute);
6739 if (linfo->rgctx_arg) {
6740 ctx->rgctx_arg = LLVMGetParam (method, linfo->rgctx_arg_pindex);
6741 ctx->rgctx_arg_pindex = linfo->rgctx_arg_pindex;
6743 * We mark the rgctx parameter with the inreg attribute, which is mapped to
6744 * MONO_ARCH_RGCTX_REG in the Mono calling convention in llvm, i.e.
6745 * CC_X86_64_Mono in X86CallingConv.td.
6747 if (!ctx->llvm_only)
6748 LLVMAddAttribute (ctx->rgctx_arg, LLVMInRegAttribute);
6749 LLVMSetValueName (ctx->rgctx_arg, "rgctx");
6751 ctx->rgctx_arg_pindex = -1;
6753 if (cfg->vret_addr) {
6754 values [cfg->vret_addr->dreg] = LLVMGetParam (method, linfo->vret_arg_pindex);
6755 LLVMSetValueName (values [cfg->vret_addr->dreg], "vret");
6756 if (linfo->ret.storage == LLVMArgVtypeByRef) {
6757 LLVMAddAttribute (LLVMGetParam (method, linfo->vret_arg_pindex), LLVMStructRetAttribute);
6758 LLVMAddAttribute (LLVMGetParam (method, linfo->vret_arg_pindex), LLVMNoAliasAttribute);
6763 ctx->this_arg_pindex = linfo->this_arg_pindex;
6764 ctx->this_arg = LLVMGetParam (method, linfo->this_arg_pindex);
6765 values [cfg->args [0]->dreg] = ctx->this_arg;
6766 LLVMSetValueName (values [cfg->args [0]->dreg], "this");
6769 names = g_new (char *, sig->param_count);
6770 mono_method_get_param_names (cfg->method, (const char **) names);
6772 for (i = 0; i < sig->param_count; ++i) {
6773 LLVMArgInfo *ainfo = &linfo->args [i + sig->hasthis];
6775 int pindex = ainfo->pindex + ainfo->ndummy_fpargs;
6778 for (j = 0; j < ainfo->ndummy_fpargs; ++j) {
6779 name = g_strdup_printf ("dummy_%d_%d", i, j);
6780 LLVMSetValueName (LLVMGetParam (method, ainfo->pindex + j), name);
6784 values [cfg->args [i + sig->hasthis]->dreg] = LLVMGetParam (method, pindex);
6785 if (ainfo->storage == LLVMArgGsharedvtFixed || ainfo->storage == LLVMArgGsharedvtFixedVtype) {
6786 if (names [i] && names [i][0] != '\0')
6787 name = g_strdup_printf ("p_arg_%s", names [i]);
6789 name = g_strdup_printf ("p_arg_%d", i);
6791 if (names [i] && names [i][0] != '\0')
6792 name = g_strdup_printf ("arg_%s", names [i]);
6794 name = g_strdup_printf ("arg_%d", i);
6796 LLVMSetValueName (values [cfg->args [i + sig->hasthis]->dreg], name);
6798 if (ainfo->storage == LLVMArgVtypeByVal)
6799 LLVMAddAttribute (LLVMGetParam (method, pindex), LLVMByValAttribute);
6801 if (ainfo->storage == LLVMArgVtypeByRef) {
6803 cfg->args [i + sig->hasthis]->opcode = OP_VTARG_ADDR;
6808 if (ctx->module->emit_dwarf && cfg->compile_aot && mono_debug_enabled ()) {
6809 ctx->minfo = mono_debug_lookup_method (cfg->method);
6810 ctx->dbg_md = emit_dbg_subprogram (ctx, cfg, method, ctx->method_name);
6814 for (bb = cfg->bb_entry; bb; bb = bb->next_bb)
6815 max_block_num = MAX (max_block_num, bb->block_num);
6816 ctx->bblocks = bblocks = g_new0 (BBInfo, max_block_num + 1);
6818 /* Add branches between non-consecutive bblocks */
6819 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
6820 if (bb->last_ins && MONO_IS_COND_BRANCH_OP (bb->last_ins) &&
6821 bb->next_bb != bb->last_ins->inst_false_bb) {
6823 MonoInst *inst = (MonoInst*)mono_mempool_alloc0 (cfg->mempool, sizeof (MonoInst));
6824 inst->opcode = OP_BR;
6825 inst->inst_target_bb = bb->last_ins->inst_false_bb;
6826 mono_bblock_add_inst (bb, inst);
6831 * The INDIRECT flag added by OP_LDADDR inhibits optimizations, even if the LDADDR
6832 * was later optimized away, so clear these flags, and add them back for the still
6833 * present OP_LDADDR instructions.
6835 for (i = 0; i < cfg->next_vreg; ++i) {
6838 ins = get_vreg_to_inst (cfg, i);
6839 if (ins && ins != cfg->rgctx_var)
6840 ins->flags &= ~MONO_INST_INDIRECT;
6844 * Make a first pass over the code to precreate PHI nodes/set INDIRECT flags.
6846 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
6848 LLVMBuilderRef builder;
6850 char dname_buf[128];
6852 builder = create_builder (ctx);
6854 for (ins = bb->code; ins; ins = ins->next) {
6855 switch (ins->opcode) {
6860 LLVMTypeRef phi_type = llvm_type_to_stack_type (cfg, type_to_llvm_type (ctx, &ins->klass->byval_arg));
6865 if (ins->opcode == OP_VPHI) {
6866 /* Treat valuetype PHI nodes as operating on the address itself */
6867 g_assert (ins->klass);
6868 phi_type = LLVMPointerType (type_to_llvm_type (ctx, &ins->klass->byval_arg), 0);
6872 * Have to precreate these, as they can be referenced by
6873 * earlier instructions.
6875 sprintf (dname_buf, "t%d", ins->dreg);
6877 values [ins->dreg] = LLVMBuildPhi (builder, phi_type, dname);
6879 if (ins->opcode == OP_VPHI)
6880 ctx->addresses [ins->dreg] = values [ins->dreg];
6882 g_ptr_array_add (ctx->phi_values, values [ins->dreg]);
6885 * Set the expected type of the incoming arguments since these have
6886 * to have the same type.
6888 for (i = 0; i < ins->inst_phi_args [0]; i++) {
6889 int sreg1 = ins->inst_phi_args [i + 1];
6892 ctx->vreg_types [sreg1] = phi_type;
6897 ((MonoInst*)ins->inst_p0)->flags |= MONO_INST_INDIRECT;
6906 * Create an ordering for bblocks, use the depth first order first, then
6907 * put the exception handling bblocks last.
6909 for (bb_index = 0; bb_index < cfg->num_bblocks; ++bb_index) {
6910 bb = cfg->bblocks [bb_index];
6911 if (!(bb->region != -1 && !MONO_BBLOCK_IS_IN_REGION (bb, MONO_REGION_TRY))) {
6912 g_ptr_array_add (bblock_list, bb);
6913 bblocks [bb->block_num].added = TRUE;
6917 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
6918 if (!bblocks [bb->block_num].added)
6919 g_ptr_array_add (bblock_list, bb);
6923 * Second pass: generate code.
6926 LLVMBuilderRef entry_builder = create_builder (ctx);
6927 LLVMBasicBlockRef entry_bb = get_bb (ctx, cfg->bb_entry);
6928 LLVMPositionBuilderAtEnd (entry_builder, entry_bb);
6929 emit_entry_bb (ctx, entry_builder);
6931 // Make landing pads first
6932 ctx->exc_meta = g_hash_table_new_full (NULL, NULL, NULL, NULL);
6934 if (ctx->llvm_only) {
6935 size_t group_index = 0;
6936 while (group_index < cfg->header->num_clauses) {
6938 size_t cursor = group_index;
6939 while (cursor < cfg->header->num_clauses &&
6940 CLAUSE_START (&cfg->header->clauses [cursor]) == CLAUSE_START (&cfg->header->clauses [group_index]) &&
6941 CLAUSE_END (&cfg->header->clauses [cursor]) == CLAUSE_END (&cfg->header->clauses [group_index])) {
6946 LLVMBasicBlockRef lpad_bb = emit_landing_pad (ctx, group_index, count);
6947 intptr_t key = CLAUSE_END (&cfg->header->clauses [group_index]);
6948 g_hash_table_insert (ctx->exc_meta, (gpointer)key, lpad_bb);
6950 group_index = cursor;
6954 for (bb_index = 0; bb_index < bblock_list->len; ++bb_index) {
6955 bb = (MonoBasicBlock*)g_ptr_array_index (bblock_list, bb_index);
6957 // Prune unreachable mono BBs.
6958 if (!(bb == cfg->bb_entry || bb->in_count > 0))
6961 process_bb (ctx, bb);
6965 g_hash_table_destroy (ctx->exc_meta);
6967 mono_memory_barrier ();
6969 /* Add incoming phi values */
6970 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
6971 GSList *l, *ins_list;
6973 ins_list = bblocks [bb->block_num].phi_nodes;
6975 for (l = ins_list; l; l = l->next) {
6976 PhiNode *node = (PhiNode*)l->data;
6977 MonoInst *phi = node->phi;
6978 int sreg1 = node->sreg;
6979 LLVMBasicBlockRef in_bb;
6984 in_bb = get_end_bb (ctx, node->in_bb);
6986 if (ctx->unreachable [node->in_bb->block_num])
6989 if (!values [sreg1]) {
6990 /* Can happen with values in EH clauses */
6991 set_failure (ctx, "incoming phi sreg1");
6995 if (phi->opcode == OP_VPHI) {
6996 g_assert (LLVMTypeOf (ctx->addresses [sreg1]) == LLVMTypeOf (values [phi->dreg]));
6997 LLVMAddIncoming (values [phi->dreg], &ctx->addresses [sreg1], &in_bb, 1);
6999 if (LLVMTypeOf (values [sreg1]) != LLVMTypeOf (values [phi->dreg])) {
7000 set_failure (ctx, "incoming phi arg type mismatch");
7003 g_assert (LLVMTypeOf (values [sreg1]) == LLVMTypeOf (values [phi->dreg]));
7004 LLVMAddIncoming (values [phi->dreg], &values [sreg1], &in_bb, 1);
7009 /* Nullify empty phi instructions */
7010 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
7011 GSList *l, *ins_list;
7013 ins_list = bblocks [bb->block_num].phi_nodes;
7015 for (l = ins_list; l; l = l->next) {
7016 PhiNode *node = (PhiNode*)l->data;
7017 MonoInst *phi = node->phi;
7018 LLVMValueRef phi_ins = values [phi->dreg];
7021 /* Already removed */
7024 if (LLVMCountIncoming (phi_ins) == 0) {
7025 mono_llvm_replace_uses_of (phi_ins, LLVMConstNull (LLVMTypeOf (phi_ins)));
7026 LLVMInstructionEraseFromParent (phi_ins);
7027 values [phi->dreg] = NULL;
7032 /* Create the SWITCH statements for ENDFINALLY instructions */
7033 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
7034 BBInfo *info = &bblocks [bb->block_num];
7036 for (l = info->endfinally_switch_ins_list; l; l = l->next) {
7037 LLVMValueRef switch_ins = (LLVMValueRef)l->data;
7038 GSList *bb_list = info->call_handler_return_bbs;
7040 for (i = 0; i < g_slist_length (bb_list); ++i)
7041 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), i + 1, FALSE), (LLVMBasicBlockRef)(g_slist_nth (bb_list, i)->data));
7045 /* Initialize the method if needed */
7046 if (cfg->compile_aot && ctx->llvm_only) {
7047 // FIXME: Add more shared got entries
7048 ctx->builder = create_builder (ctx);
7049 LLVMPositionBuilderAtEnd (ctx->builder, ctx->init_bb);
7051 ctx->module->max_method_idx = MAX (ctx->module->max_method_idx, cfg->method_index);
7053 // FIXME: beforefieldinit
7054 if (ctx->has_got_access || mono_class_get_cctor (cfg->method->klass)) {
7055 emit_init_method (ctx);
7057 LLVMBuildBr (ctx->builder, ctx->inited_bb);
7061 if (cfg->llvm_only) {
7062 GHashTableIter iter;
7064 GSList *callers, *l, *l2;
7067 * Add the contents of ctx->method_to_callers to module->method_to_callers.
7068 * We can't do this earlier, as it contains llvm instructions which can be
7069 * freed if compilation fails.
7070 * FIXME: Get rid of this when all methods can be llvm compiled.
7072 g_hash_table_iter_init (&iter, ctx->method_to_callers);
7073 while (g_hash_table_iter_next (&iter, (void**)&method, (void**)&callers)) {
7074 for (l = callers; l; l = l->next) {
7075 l2 = (GSList*)g_hash_table_lookup (ctx->module->method_to_callers, method);
7076 l2 = g_slist_prepend (l2, l->data);
7077 g_hash_table_insert (ctx->module->method_to_callers, method, l2);
7082 if (cfg->verbose_level > 1)
7083 mono_llvm_dump_value (method);
7085 if (cfg->compile_aot && !cfg->llvm_only)
7086 mark_as_used (ctx->module, method);
7088 if (cfg->compile_aot && !cfg->llvm_only) {
7089 LLVMValueRef md_args [16];
7090 LLVMValueRef md_node;
7093 method_index = mono_aot_get_method_index (cfg->orig_method);
7094 md_args [0] = LLVMMDString (ctx->method_name, strlen (ctx->method_name));
7095 md_args [1] = LLVMConstInt (LLVMInt32Type (), method_index, FALSE);
7096 md_node = LLVMMDNode (md_args, 2);
7097 LLVMAddNamedMetadataOperand (lmodule, "mono.function_indexes", md_node);
7098 //LLVMSetMetadata (method, md_kind, LLVMMDNode (&md_arg, 1));
7101 if (cfg->compile_aot) {
7102 /* Don't generate native code, keep the LLVM IR */
7103 if (cfg->verbose_level)
7104 printf ("%s emitted as %s\n", mono_method_full_name (cfg->method, TRUE), ctx->method_name);
7106 #if LLVM_API_VERSION < 100
7107 /* VerifyFunction can't handle some of the debug info created by DIBuilder in llvm 3.9 */
7108 int err = LLVMVerifyFunction(ctx->lmethod, LLVMPrintMessageAction);
7109 g_assert (err == 0);
7112 //LLVMVerifyFunction(method, 0);
7113 #if LLVM_API_VERSION > 100
7114 MonoDomain *domain = mono_domain_get ();
7115 MonoJitDomainInfo *domain_info;
7116 int nvars = g_hash_table_size (ctx->jit_callees);
7117 LLVMValueRef *callee_vars = g_new0 (LLVMValueRef, nvars);
7118 gpointer *callee_addrs = g_new0 (gpointer, nvars);
7119 GHashTableIter iter;
7125 * Compute the addresses of the LLVM globals pointing to the
7126 * methods called by the current method. Pass it to the trampoline
7127 * code so it can update them after their corresponding method was
7130 g_hash_table_iter_init (&iter, ctx->jit_callees);
7132 while (g_hash_table_iter_next (&iter, NULL, (void**)&var))
7133 callee_vars [i ++] = var;
7135 cfg->native_code = mono_llvm_compile_method (ctx->module->mono_ee, ctx->lmethod, nvars, callee_vars, callee_addrs, &eh_frame);
7137 decode_llvm_eh_info (ctx, eh_frame);
7139 mono_domain_lock (domain);
7140 domain_info = domain_jit_info (domain);
7141 if (!domain_info->llvm_jit_callees)
7142 domain_info->llvm_jit_callees = g_hash_table_new (NULL, NULL);
7143 g_hash_table_iter_init (&iter, ctx->jit_callees);
7145 while (g_hash_table_iter_next (&iter, (void**)&callee, (void**)&var)) {
7146 GSList *addrs = g_hash_table_lookup (domain_info->llvm_jit_callees, callee);
7147 addrs = g_slist_prepend (addrs, callee_addrs [i]);
7148 g_hash_table_insert (domain_info->llvm_jit_callees, callee, addrs);
7151 mono_domain_unlock (domain);
7153 mono_llvm_optimize_method (ctx->module->mono_ee, ctx->lmethod);
7155 if (cfg->verbose_level > 1)
7156 mono_llvm_dump_value (ctx->lmethod);
7158 cfg->native_code = (unsigned char*)LLVMGetPointerToGlobal (ctx->module->ee, ctx->lmethod);
7160 /* Set by emit_cb */
7161 g_assert (cfg->code_len);
7165 if (ctx->module->method_to_lmethod)
7166 g_hash_table_insert (ctx->module->method_to_lmethod, cfg->method, ctx->lmethod);
7167 if (ctx->module->idx_to_lmethod)
7168 g_hash_table_insert (ctx->module->idx_to_lmethod, GINT_TO_POINTER (cfg->method_index), ctx->lmethod);
7170 if (ctx->llvm_only && cfg->orig_method->klass->valuetype && !(cfg->orig_method->flags & METHOD_ATTRIBUTE_STATIC))
7171 emit_unbox_tramp (ctx, ctx->method_name, ctx->method_type, ctx->lmethod, cfg->method_index);
7175 * mono_llvm_create_vars:
7177 * Same as mono_arch_create_vars () for LLVM.
7180 mono_llvm_create_vars (MonoCompile *cfg)
7182 MonoMethodSignature *sig;
7184 sig = mono_method_signature (cfg->method);
7185 if (cfg->gsharedvt && cfg->llvm_only) {
7186 if (mini_is_gsharedvt_variable_signature (sig) && sig->ret->type != MONO_TYPE_VOID) {
7187 cfg->vret_addr = mono_compile_create_var (cfg, &mono_get_intptr_class ()->byval_arg, OP_ARG);
7188 if (G_UNLIKELY (cfg->verbose_level > 1)) {
7189 printf ("vret_addr = ");
7190 mono_print_ins (cfg->vret_addr);
7194 mono_arch_create_vars (cfg);
7199 * mono_llvm_emit_call:
7201 * Same as mono_arch_emit_call () for LLVM.
7204 mono_llvm_emit_call (MonoCompile *cfg, MonoCallInst *call)
7207 MonoMethodSignature *sig;
7208 int i, n, stack_size;
7213 sig = call->signature;
7214 n = sig->param_count + sig->hasthis;
7216 call->cinfo = get_llvm_call_info (cfg, sig);
7218 if (cfg->disable_llvm)
7221 if (sig->call_convention == MONO_CALL_VARARG) {
7222 cfg->exception_message = g_strdup ("varargs");
7223 cfg->disable_llvm = TRUE;
7226 for (i = 0; i < n; ++i) {
7229 ainfo = call->cinfo->args + i;
7231 in = call->args [i];
7233 /* Simply remember the arguments */
7234 switch (ainfo->storage) {
7235 case LLVMArgNormal: {
7236 MonoType *t = (sig->hasthis && i == 0) ? &mono_get_intptr_class ()->byval_arg : ainfo->type;
7239 opcode = mono_type_to_regmove (cfg, t);
7240 if (opcode == OP_FMOVE) {
7241 MONO_INST_NEW (cfg, ins, OP_FMOVE);
7242 ins->dreg = mono_alloc_freg (cfg);
7243 } else if (opcode == OP_LMOVE) {
7244 MONO_INST_NEW (cfg, ins, OP_LMOVE);
7245 ins->dreg = mono_alloc_lreg (cfg);
7246 } else if (opcode == OP_RMOVE) {
7247 MONO_INST_NEW (cfg, ins, OP_RMOVE);
7248 ins->dreg = mono_alloc_freg (cfg);
7250 MONO_INST_NEW (cfg, ins, OP_MOVE);
7251 ins->dreg = mono_alloc_ireg (cfg);
7253 ins->sreg1 = in->dreg;
7256 case LLVMArgVtypeByVal:
7257 case LLVMArgVtypeByRef:
7258 case LLVMArgVtypeInReg:
7259 case LLVMArgVtypeAsScalar:
7260 case LLVMArgAsIArgs:
7261 case LLVMArgAsFpArgs:
7262 case LLVMArgGsharedvtVariable:
7263 case LLVMArgGsharedvtFixed:
7264 case LLVMArgGsharedvtFixedVtype:
7265 MONO_INST_NEW (cfg, ins, OP_LLVM_OUTARG_VT);
7266 ins->dreg = mono_alloc_ireg (cfg);
7267 ins->sreg1 = in->dreg;
7268 ins->inst_p0 = mono_mempool_alloc0 (cfg->mempool, sizeof (LLVMArgInfo));
7269 memcpy (ins->inst_p0, ainfo, sizeof (LLVMArgInfo));
7270 ins->inst_vtype = ainfo->type;
7271 ins->klass = mono_class_from_mono_type (ainfo->type);
7274 cfg->exception_message = g_strdup ("ainfo->storage");
7275 cfg->disable_llvm = TRUE;
7279 if (!cfg->disable_llvm) {
7280 MONO_ADD_INS (cfg->cbb, ins);
7281 mono_call_inst_add_outarg_reg (cfg, call, ins->dreg, 0, FALSE);
7286 static unsigned char*
7287 alloc_cb (LLVMValueRef function, int size)
7291 cfg = (MonoCompile*)mono_native_tls_get_value (current_cfg_tls_id);
7295 return (unsigned char*)mono_domain_code_reserve (cfg->domain, size);
7297 return (unsigned char*)mono_domain_code_reserve (mono_domain_get (), size);
7302 emitted_cb (LLVMValueRef function, void *start, void *end)
7306 cfg = (MonoCompile*)mono_native_tls_get_value (current_cfg_tls_id);
7308 cfg->code_len = (guint8*)end - (guint8*)start;
7312 exception_cb (void *data)
7315 MonoJitExceptionInfo *ei;
7316 guint32 ei_len, i, j, nested_len, nindex;
7317 gpointer *type_info;
7318 int this_reg, this_offset;
7320 cfg = (MonoCompile*)mono_native_tls_get_value (current_cfg_tls_id);
7324 * data points to a DWARF FDE structure, convert it to our unwind format and
7326 * An alternative would be to save it directly, and modify our unwinder to work
7329 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);
7330 if (cfg->verbose_level > 1)
7331 mono_print_unwind_info (cfg->encoded_unwind_ops, cfg->encoded_unwind_ops_len);
7333 /* Count nested clauses */
7335 for (i = 0; i < ei_len; ++i) {
7336 gint32 cindex1 = *(gint32*)type_info [i];
7337 MonoExceptionClause *clause1 = &cfg->header->clauses [cindex1];
7339 for (j = 0; j < cfg->header->num_clauses; ++j) {
7341 MonoExceptionClause *clause2 = &cfg->header->clauses [cindex2];
7343 if (cindex1 != cindex2 && clause1->try_offset >= clause2->try_offset && clause1->handler_offset <= clause2->handler_offset) {
7349 cfg->llvm_ex_info = (MonoJitExceptionInfo*)mono_mempool_alloc0 (cfg->mempool, (ei_len + nested_len) * sizeof (MonoJitExceptionInfo));
7350 cfg->llvm_ex_info_len = ei_len + nested_len;
7351 memcpy (cfg->llvm_ex_info, ei, ei_len * sizeof (MonoJitExceptionInfo));
7352 /* Fill the rest of the information from the type info */
7353 for (i = 0; i < ei_len; ++i) {
7354 gint32 clause_index = *(gint32*)type_info [i];
7355 MonoExceptionClause *clause = &cfg->header->clauses [clause_index];
7357 cfg->llvm_ex_info [i].flags = clause->flags;
7358 cfg->llvm_ex_info [i].data.catch_class = clause->data.catch_class;
7359 cfg->llvm_ex_info [i].clause_index = clause_index;
7363 * For nested clauses, the LLVM produced exception info associates the try interval with
7364 * the innermost handler, while mono expects it to be associated with all nesting clauses.
7365 * So add new clauses which use the IL info (catch class etc.) from the nesting clause,
7366 * and everything else from the nested clause.
7369 for (i = 0; i < ei_len; ++i) {
7370 gint32 cindex1 = *(gint32*)type_info [i];
7371 MonoExceptionClause *clause1 = &cfg->header->clauses [cindex1];
7373 for (j = 0; j < cfg->header->num_clauses; ++j) {
7375 MonoExceptionClause *clause2 = &cfg->header->clauses [cindex2];
7376 MonoJitExceptionInfo *nesting_ei, *nested_ei;
7378 if (cindex1 != cindex2 && clause1->try_offset >= clause2->try_offset && clause1->handler_offset <= clause2->handler_offset) {
7379 /* clause1 is the nested clause */
7380 nested_ei = &cfg->llvm_ex_info [i];
7381 nesting_ei = &cfg->llvm_ex_info [nindex];
7384 memcpy (nesting_ei, nested_ei, sizeof (MonoJitExceptionInfo));
7386 nesting_ei->flags = clause2->flags;
7387 nesting_ei->data.catch_class = clause2->data.catch_class;
7388 nesting_ei->clause_index = cindex2;
7392 g_assert (nindex == ei_len + nested_len);
7393 cfg->llvm_this_reg = this_reg;
7394 cfg->llvm_this_offset = this_offset;
7396 /* type_info [i] is cfg mempool allocated, no need to free it */
7402 #if LLVM_API_VERSION > 100
7404 * decode_llvm_eh_info:
7406 * Decode the EH table emitted by llvm in jit mode, and store
7407 * the result into cfg.
7410 decode_llvm_eh_info (EmitContext *ctx, gpointer eh_frame)
7412 MonoCompile *cfg = ctx->cfg;
7415 MonoLLVMFDEInfo info;
7416 MonoJitExceptionInfo *ei;
7417 guint8 *p = eh_frame;
7418 int version, fde_count, fde_offset;
7419 guint32 ei_len, i, nested_len;
7420 gpointer *type_info;
7424 * Decode the one element EH table emitted by the MonoException class
7428 /* Similar to decode_llvm_mono_eh_frame () in aot-runtime.c */
7431 g_assert (version == 3);
7434 p = (guint8 *)ALIGN_PTR_TO (p, 4);
7436 fde_count = *(guint32*)p;
7440 g_assert (fde_count == 1);
7442 /* The only table entry */
7443 fde_offset = table [1];
7446 cfg->code_len = table [0];
7447 fde_len = table [1] - fde_offset;
7450 fde = (guint8*)eh_frame + fde_offset;
7451 cie = (guint8*)table;
7453 mono_unwind_decode_llvm_mono_fde (fde, fde_len, cie, cfg->native_code, &info);
7455 cfg->encoded_unwind_ops = info.unw_info;
7456 cfg->encoded_unwind_ops_len = info.unw_info_len;
7457 if (cfg->verbose_level > 1)
7458 mono_print_unwind_info (cfg->encoded_unwind_ops, cfg->encoded_unwind_ops_len);
7459 if (info.this_reg != -1) {
7460 cfg->llvm_this_reg = info.this_reg;
7461 cfg->llvm_this_offset = info.this_offset;
7465 ei_len = info.ex_info_len;
7466 type_info = info.type_info;
7468 // Nested clauses are currently disabled
7471 cfg->llvm_ex_info = (MonoJitExceptionInfo*)mono_mempool_alloc0 (cfg->mempool, (ei_len + nested_len) * sizeof (MonoJitExceptionInfo));
7472 cfg->llvm_ex_info_len = ei_len + nested_len;
7473 memcpy (cfg->llvm_ex_info, ei, ei_len * sizeof (MonoJitExceptionInfo));
7474 /* Fill the rest of the information from the type info */
7475 for (i = 0; i < ei_len; ++i) {
7476 gint32 clause_index = *(gint32*)type_info [i];
7477 MonoExceptionClause *clause = &cfg->header->clauses [clause_index];
7479 cfg->llvm_ex_info [i].flags = clause->flags;
7480 cfg->llvm_ex_info [i].data.catch_class = clause->data.catch_class;
7481 cfg->llvm_ex_info [i].clause_index = clause_index;
7487 dlsym_cb (const char *name, void **symbol)
7493 if (!strcmp (name, "__bzero")) {
7494 *symbol = (void*)bzero;
7496 current = mono_dl_open (NULL, 0, NULL);
7499 err = mono_dl_symbol (current, name, symbol);
7501 mono_dl_close (current);
7503 #ifdef MONO_ARCH_HAVE_CREATE_LLVM_NATIVE_THUNK
7504 *symbol = (char*)mono_arch_create_llvm_native_thunk (mono_domain_get (), (guint8*)(*symbol));
7510 AddFunc (LLVMModuleRef module, const char *name, LLVMTypeRef ret_type, LLVMTypeRef *param_types, int nparams)
7512 LLVMAddFunction (module, name, LLVMFunctionType (ret_type, param_types, nparams, FALSE));
7516 AddFunc2 (LLVMModuleRef module, const char *name, LLVMTypeRef ret_type, LLVMTypeRef param_type1, LLVMTypeRef param_type2)
7518 LLVMTypeRef param_types [4];
7520 param_types [0] = param_type1;
7521 param_types [1] = param_type2;
7523 AddFunc (module, name, ret_type, param_types, 2);
7529 INTRINS_SADD_OVF_I32,
7530 INTRINS_UADD_OVF_I32,
7531 INTRINS_SSUB_OVF_I32,
7532 INTRINS_USUB_OVF_I32,
7533 INTRINS_SMUL_OVF_I32,
7534 INTRINS_UMUL_OVF_I32,
7535 INTRINS_SADD_OVF_I64,
7536 INTRINS_UADD_OVF_I64,
7537 INTRINS_SSUB_OVF_I64,
7538 INTRINS_USUB_OVF_I64,
7539 INTRINS_SMUL_OVF_I64,
7540 INTRINS_UMUL_OVF_I64,
7547 #if defined(TARGET_AMD64) || defined(TARGET_X86)
7548 INTRINS_SSE_PMOVMSKB,
7549 INTRINS_SSE_PSRLI_W,
7550 INTRINS_SSE_PSRAI_W,
7551 INTRINS_SSE_PSLLI_W,
7552 INTRINS_SSE_PSRLI_D,
7553 INTRINS_SSE_PSRAI_D,
7554 INTRINS_SSE_PSLLI_D,
7555 INTRINS_SSE_PSRLI_Q,
7556 INTRINS_SSE_PSLLI_Q,
7557 INTRINS_SSE_SQRT_PD,
7558 INTRINS_SSE_SQRT_PS,
7559 INTRINS_SSE_RSQRT_PS,
7561 INTRINS_SSE_CVTTPD2DQ,
7562 INTRINS_SSE_CVTTPS2DQ,
7563 INTRINS_SSE_CVTDQ2PD,
7564 INTRINS_SSE_CVTDQ2PS,
7565 INTRINS_SSE_CVTPD2DQ,
7566 INTRINS_SSE_CVTPS2DQ,
7567 INTRINS_SSE_CVTPD2PS,
7568 INTRINS_SSE_CVTPS2PD,
7571 INTRINS_SSE_PACKSSWB,
7572 INTRINS_SSE_PACKUSWB,
7573 INTRINS_SSE_PACKSSDW,
7574 INTRINS_SSE_PACKUSDW,
7579 INTRINS_SSE_ADDSUBPS,
7584 INTRINS_SSE_ADDSUBPD,
7592 INTRINS_SSE_PADDUSW,
7593 INTRINS_SSE_PSUBUSW,
7601 INTRINS_SSE_PADDUSB,
7602 INTRINS_SSE_PSUBUSB,
7614 static IntrinsicDesc intrinsics[] = {
7615 {INTRINS_MEMSET, "llvm.memset.p0i8.i32"},
7616 {INTRINS_MEMCPY, "llvm.memcpy.p0i8.p0i8.i32"},
7617 {INTRINS_SADD_OVF_I32, "llvm.sadd.with.overflow.i32"},
7618 {INTRINS_UADD_OVF_I32, "llvm.uadd.with.overflow.i32"},
7619 {INTRINS_SSUB_OVF_I32, "llvm.ssub.with.overflow.i32"},
7620 {INTRINS_USUB_OVF_I32, "llvm.usub.with.overflow.i32"},
7621 {INTRINS_SMUL_OVF_I32, "llvm.smul.with.overflow.i32"},
7622 {INTRINS_UMUL_OVF_I32, "llvm.umul.with.overflow.i32"},
7623 {INTRINS_SADD_OVF_I64, "llvm.sadd.with.overflow.i64"},
7624 {INTRINS_UADD_OVF_I64, "llvm.uadd.with.overflow.i64"},
7625 {INTRINS_SSUB_OVF_I64, "llvm.ssub.with.overflow.i64"},
7626 {INTRINS_USUB_OVF_I64, "llvm.usub.with.overflow.i64"},
7627 {INTRINS_SMUL_OVF_I64, "llvm.smul.with.overflow.i64"},
7628 {INTRINS_UMUL_OVF_I64, "llvm.umul.with.overflow.i64"},
7629 {INTRINS_SIN, "llvm.sin.f64"},
7630 {INTRINS_COS, "llvm.cos.f64"},
7631 {INTRINS_SQRT, "llvm.sqrt.f64"},
7632 /* This isn't an intrinsic, instead llvm seems to special case it by name */
7633 {INTRINS_FABS, "fabs"},
7634 {INTRINS_EXPECT_I8, "llvm.expect.i8"},
7635 {INTRINS_EXPECT_I1, "llvm.expect.i1"},
7636 #if defined(TARGET_AMD64) || defined(TARGET_X86)
7637 {INTRINS_SSE_PMOVMSKB, "llvm.x86.sse2.pmovmskb.128"},
7638 {INTRINS_SSE_PSRLI_W, "llvm.x86.sse2.psrli.w"},
7639 {INTRINS_SSE_PSRAI_W, "llvm.x86.sse2.psrai.w"},
7640 {INTRINS_SSE_PSLLI_W, "llvm.x86.sse2.pslli.w"},
7641 {INTRINS_SSE_PSRLI_D, "llvm.x86.sse2.psrli.d"},
7642 {INTRINS_SSE_PSRAI_D, "llvm.x86.sse2.psrai.d"},
7643 {INTRINS_SSE_PSLLI_D, "llvm.x86.sse2.pslli.d"},
7644 {INTRINS_SSE_PSRLI_Q, "llvm.x86.sse2.psrli.q"},
7645 {INTRINS_SSE_PSLLI_Q, "llvm.x86.sse2.pslli.q"},
7646 {INTRINS_SSE_SQRT_PD, "llvm.x86.sse2.sqrt.pd"},
7647 {INTRINS_SSE_SQRT_PS, "llvm.x86.sse.sqrt.ps"},
7648 {INTRINS_SSE_RSQRT_PS, "llvm.x86.sse.rsqrt.ps"},
7649 {INTRINS_SSE_RCP_PS, "llvm.x86.sse.rcp.ps"},
7650 {INTRINS_SSE_CVTTPD2DQ, "llvm.x86.sse2.cvttpd2dq"},
7651 {INTRINS_SSE_CVTTPS2DQ, "llvm.x86.sse2.cvttps2dq"},
7652 {INTRINS_SSE_CVTDQ2PD, "llvm.x86.sse2.cvtdq2pd"},
7653 {INTRINS_SSE_CVTDQ2PS, "llvm.x86.sse2.cvtdq2ps"},
7654 {INTRINS_SSE_CVTPD2DQ, "llvm.x86.sse2.cvtpd2dq"},
7655 {INTRINS_SSE_CVTPS2DQ, "llvm.x86.sse2.cvtps2dq"},
7656 {INTRINS_SSE_CVTPD2PS, "llvm.x86.sse2.cvtpd2ps"},
7657 {INTRINS_SSE_CVTPS2PD, "llvm.x86.sse2.cvtps2pd"},
7658 {INTRINS_SSE_CMPPD, "llvm.x86.sse2.cmp.pd"},
7659 {INTRINS_SSE_CMPPS, "llvm.x86.sse.cmp.ps"},
7660 {INTRINS_SSE_PACKSSWB, "llvm.x86.sse2.packsswb.128"},
7661 {INTRINS_SSE_PACKUSWB, "llvm.x86.sse2.packuswb.128"},
7662 {INTRINS_SSE_PACKSSDW, "llvm.x86.sse2.packssdw.128"},
7663 {INTRINS_SSE_PACKUSDW, "llvm.x86.sse41.packusdw"},
7664 {INTRINS_SSE_MINPS, "llvm.x86.sse.min.ps"},
7665 {INTRINS_SSE_MAXPS, "llvm.x86.sse.max.ps"},
7666 {INTRINS_SSE_HADDPS, "llvm.x86.sse3.hadd.ps"},
7667 {INTRINS_SSE_HSUBPS, "llvm.x86.sse3.hsub.ps"},
7668 {INTRINS_SSE_ADDSUBPS, "llvm.x86.sse3.addsub.ps"},
7669 {INTRINS_SSE_MINPD, "llvm.x86.sse2.min.pd"},
7670 {INTRINS_SSE_MAXPD, "llvm.x86.sse2.max.pd"},
7671 {INTRINS_SSE_HADDPD, "llvm.x86.sse3.hadd.pd"},
7672 {INTRINS_SSE_HSUBPD, "llvm.x86.sse3.hsub.pd"},
7673 {INTRINS_SSE_ADDSUBPD, "llvm.x86.sse3.addsub.pd"},
7674 {INTRINS_SSE_PMINUD, "llvm.x86.sse41.pminud"},
7675 {INTRINS_SSE_PMAXUD, "llvm.x86.sse41.pmaxud"},
7676 {INTRINS_SSE_PMINUW, "llvm.x86.sse41.pminuw"},
7677 {INTRINS_SSE_PMINSW, "llvm.x86.sse2.pmins.w"},
7678 {INTRINS_SSE_PMAXUW, "llvm.x86.sse41.pmaxuw"},
7679 {INTRINS_SSE_PADDSW, "llvm.x86.sse2.padds.w"},
7680 {INTRINS_SSE_PSUBSW, "llvm.x86.sse2.psubs.w"},
7681 {INTRINS_SSE_PADDUSW, "llvm.x86.sse2.paddus.w"},
7682 {INTRINS_SSE_PSUBUSW, "llvm.x86.sse2.psubus.w"},
7683 {INTRINS_SSE_PAVGW, "llvm.x86.sse2.pavg.w"},
7684 {INTRINS_SSE_PMULHW, "llvm.x86.sse2.pmulh.w"},
7685 {INTRINS_SSE_PMULHU, "llvm.x86.sse2.pmulhu.w"},
7686 {INTRINS_SSE_PMINUB, "llvm.x86.sse2.pminu.b"},
7687 {INTRINS_SSE_PMAXUB, "llvm.x86.sse2.pmaxu.b"},
7688 {INTRINS_SE_PADDSB, "llvm.x86.sse2.padds.b"},
7689 {INTRINS_SSE_PSUBSB, "llvm.x86.sse2.psubs.b"},
7690 {INTRINS_SSE_PADDUSB, "llvm.x86.sse2.paddus.b"},
7691 {INTRINS_SSE_PSUBUSB, "llvm.x86.sse2.psubus.b"},
7692 {INTRINS_SSE_PAVGB, "llvm.x86.sse2.pavg.b"},
7693 {INTRINS_SSE_PAUSE, "llvm.x86.sse2.pause"}
7698 add_sse_binary (LLVMModuleRef module, const char *name, int type)
7700 LLVMTypeRef ret_type = type_to_simd_type (type);
7701 AddFunc2 (module, name, ret_type, ret_type, ret_type);
7705 add_intrinsic (LLVMModuleRef module, int id)
7708 LLVMTypeRef ret_type, arg_types [16];
7710 name = g_hash_table_lookup (intrins_id_to_name, GINT_TO_POINTER (id));
7714 case INTRINS_MEMSET: {
7715 LLVMTypeRef params [] = { LLVMPointerType (LLVMInt8Type (), 0), LLVMInt8Type (), LLVMInt32Type (), LLVMInt32Type (), LLVMInt1Type () };
7717 AddFunc (module, name, LLVMVoidType (), params, 5);
7720 case INTRINS_MEMCPY: {
7721 LLVMTypeRef params [] = { LLVMPointerType (LLVMInt8Type (), 0), LLVMPointerType (LLVMInt8Type (), 0), LLVMInt32Type (), LLVMInt32Type (), LLVMInt1Type () };
7723 AddFunc (module, name, LLVMVoidType (), params, 5);
7726 case INTRINS_SADD_OVF_I32:
7727 case INTRINS_UADD_OVF_I32:
7728 case INTRINS_SSUB_OVF_I32:
7729 case INTRINS_USUB_OVF_I32:
7730 case INTRINS_SMUL_OVF_I32:
7731 case INTRINS_UMUL_OVF_I32: {
7732 LLVMTypeRef ovf_res_i32 [] = { LLVMInt32Type (), LLVMInt1Type () };
7733 LLVMTypeRef params [] = { LLVMInt32Type (), LLVMInt32Type () };
7734 LLVMTypeRef ret_type = LLVMStructType (ovf_res_i32, 2, FALSE);
7736 AddFunc (module, name, ret_type, params, 2);
7739 case INTRINS_SADD_OVF_I64:
7740 case INTRINS_UADD_OVF_I64:
7741 case INTRINS_SSUB_OVF_I64:
7742 case INTRINS_USUB_OVF_I64:
7743 case INTRINS_SMUL_OVF_I64:
7744 case INTRINS_UMUL_OVF_I64: {
7745 LLVMTypeRef ovf_res_i64 [] = { LLVMInt64Type (), LLVMInt1Type () };
7746 LLVMTypeRef params [] = { LLVMInt64Type (), LLVMInt64Type () };
7747 LLVMTypeRef ret_type = LLVMStructType (ovf_res_i64, 2, FALSE);
7749 AddFunc (module, name, ret_type, params, 2);
7755 case INTRINS_FABS: {
7756 LLVMTypeRef params [] = { LLVMDoubleType () };
7758 AddFunc (module, name, LLVMDoubleType (), params, 1);
7761 case INTRINS_EXPECT_I8:
7762 AddFunc2 (module, name, LLVMInt8Type (), LLVMInt8Type (), LLVMInt8Type ());
7764 case INTRINS_EXPECT_I1:
7765 AddFunc2 (module, name, LLVMInt1Type (), LLVMInt1Type (), LLVMInt1Type ());
7767 #if defined(TARGET_AMD64) || defined(TARGET_X86)
7768 case INTRINS_SSE_PMOVMSKB:
7770 ret_type = LLVMInt32Type ();
7771 arg_types [0] = type_to_simd_type (MONO_TYPE_I1);
7772 AddFunc (module, name, ret_type, arg_types, 1);
7774 case INTRINS_SSE_PSRLI_W:
7775 case INTRINS_SSE_PSRAI_W:
7776 case INTRINS_SSE_PSLLI_W:
7778 ret_type = type_to_simd_type (MONO_TYPE_I2);
7779 arg_types [0] = ret_type;
7780 arg_types [1] = LLVMInt32Type ();
7781 AddFunc (module, name, ret_type, arg_types, 2);
7783 case INTRINS_SSE_PSRLI_D:
7784 case INTRINS_SSE_PSRAI_D:
7785 case INTRINS_SSE_PSLLI_D:
7786 ret_type = type_to_simd_type (MONO_TYPE_I4);
7787 arg_types [0] = ret_type;
7788 arg_types [1] = LLVMInt32Type ();
7789 AddFunc (module, name, ret_type, arg_types, 2);
7791 case INTRINS_SSE_PSRLI_Q:
7792 case INTRINS_SSE_PSLLI_Q:
7793 ret_type = type_to_simd_type (MONO_TYPE_I8);
7794 arg_types [0] = ret_type;
7795 arg_types [1] = LLVMInt32Type ();
7796 AddFunc (module, name, ret_type, arg_types, 2);
7798 case INTRINS_SSE_SQRT_PD:
7800 ret_type = type_to_simd_type (MONO_TYPE_R8);
7801 arg_types [0] = ret_type;
7802 AddFunc (module, name, ret_type, arg_types, 1);
7804 case INTRINS_SSE_SQRT_PS:
7805 ret_type = type_to_simd_type (MONO_TYPE_R4);
7806 arg_types [0] = ret_type;
7807 AddFunc (module, name, ret_type, arg_types, 1);
7809 case INTRINS_SSE_RSQRT_PS:
7810 ret_type = type_to_simd_type (MONO_TYPE_R4);
7811 arg_types [0] = ret_type;
7812 AddFunc (module, name, ret_type, arg_types, 1);
7814 case INTRINS_SSE_RCP_PS:
7815 ret_type = type_to_simd_type (MONO_TYPE_R4);
7816 arg_types [0] = ret_type;
7817 AddFunc (module, name, ret_type, arg_types, 1);
7819 case INTRINS_SSE_CVTTPD2DQ:
7820 ret_type = type_to_simd_type (MONO_TYPE_I4);
7821 arg_types [0] = type_to_simd_type (MONO_TYPE_R8);
7822 AddFunc (module, name, ret_type, arg_types, 1);
7824 case INTRINS_SSE_CVTTPS2DQ:
7825 ret_type = type_to_simd_type (MONO_TYPE_I4);
7826 arg_types [0] = type_to_simd_type (MONO_TYPE_R4);
7827 AddFunc (module, name, ret_type, arg_types, 1);
7829 case INTRINS_SSE_CVTDQ2PD:
7830 /* Conversion ops */
7831 ret_type = type_to_simd_type (MONO_TYPE_R8);
7832 arg_types [0] = type_to_simd_type (MONO_TYPE_I4);
7833 AddFunc (module, name, ret_type, arg_types, 1);
7835 case INTRINS_SSE_CVTDQ2PS:
7836 ret_type = type_to_simd_type (MONO_TYPE_R4);
7837 arg_types [0] = type_to_simd_type (MONO_TYPE_I4);
7838 AddFunc (module, name, ret_type, arg_types, 1);
7840 case INTRINS_SSE_CVTPD2DQ:
7841 ret_type = type_to_simd_type (MONO_TYPE_I4);
7842 arg_types [0] = type_to_simd_type (MONO_TYPE_R8);
7843 AddFunc (module, name, ret_type, arg_types, 1);
7845 case INTRINS_SSE_CVTPS2DQ:
7846 ret_type = type_to_simd_type (MONO_TYPE_I4);
7847 arg_types [0] = type_to_simd_type (MONO_TYPE_R4);
7848 AddFunc (module, name, ret_type, arg_types, 1);
7850 case INTRINS_SSE_CVTPD2PS:
7851 ret_type = type_to_simd_type (MONO_TYPE_R4);
7852 arg_types [0] = type_to_simd_type (MONO_TYPE_R8);
7853 AddFunc (module, name, ret_type, arg_types, 1);
7855 case INTRINS_SSE_CVTPS2PD:
7856 ret_type = type_to_simd_type (MONO_TYPE_R8);
7857 arg_types [0] = type_to_simd_type (MONO_TYPE_R4);
7858 AddFunc (module, name, ret_type, arg_types, 1);
7860 case INTRINS_SSE_CMPPD:
7862 ret_type = type_to_simd_type (MONO_TYPE_R8);
7863 arg_types [0] = ret_type;
7864 arg_types [1] = ret_type;
7865 arg_types [2] = LLVMInt8Type ();
7866 AddFunc (module, name, ret_type, arg_types, 3);
7868 case INTRINS_SSE_CMPPS:
7869 ret_type = type_to_simd_type (MONO_TYPE_R4);
7870 arg_types [0] = ret_type;
7871 arg_types [1] = ret_type;
7872 arg_types [2] = LLVMInt8Type ();
7873 AddFunc (module, name, ret_type, arg_types, 3);
7875 case INTRINS_SSE_PACKSSWB:
7876 case INTRINS_SSE_PACKUSWB:
7877 case INTRINS_SSE_PACKSSDW:
7879 ret_type = type_to_simd_type (MONO_TYPE_I1);
7880 arg_types [0] = type_to_simd_type (MONO_TYPE_I2);
7881 arg_types [1] = type_to_simd_type (MONO_TYPE_I2);
7882 AddFunc (module, name, ret_type, arg_types, 2);
7884 case INTRINS_SSE_PACKUSDW:
7885 ret_type = type_to_simd_type (MONO_TYPE_I2);
7886 arg_types [0] = type_to_simd_type (MONO_TYPE_I4);
7887 arg_types [1] = type_to_simd_type (MONO_TYPE_I4);
7888 AddFunc (module, name, ret_type, arg_types, 2);
7890 /* SSE Binary ops */
7891 case INTRINS_SSE_PMINUD:
7892 case INTRINS_SSE_PMAXUD:
7893 add_sse_binary (module, name, MONO_TYPE_I4);
7895 case INTRINS_SSE_PMINUW:
7896 case INTRINS_SSE_PMINSW:
7897 case INTRINS_SSE_PMAXUW:
7898 case INTRINS_SSE_PADDSW:
7899 case INTRINS_SSE_PSUBSW:
7900 case INTRINS_SSE_PADDUSW:
7901 case INTRINS_SSE_PSUBUSW:
7902 case INTRINS_SSE_PAVGW:
7903 case INTRINS_SSE_PMULHW:
7904 case INTRINS_SSE_PMULHU:
7905 add_sse_binary (module, name, MONO_TYPE_I2);
7907 case INTRINS_SSE_MINPS:
7908 case INTRINS_SSE_MAXPS:
7909 case INTRINS_SSE_HADDPS:
7910 case INTRINS_SSE_HSUBPS:
7911 case INTRINS_SSE_ADDSUBPS:
7912 add_sse_binary (module, name, MONO_TYPE_R4);
7914 case INTRINS_SSE_MINPD:
7915 case INTRINS_SSE_MAXPD:
7916 case INTRINS_SSE_HADDPD:
7917 case INTRINS_SSE_HSUBPD:
7918 case INTRINS_SSE_ADDSUBPD:
7919 add_sse_binary (module, name, MONO_TYPE_R8);
7921 case INTRINS_SSE_PMINUB:
7922 case INTRINS_SSE_PMAXUB:
7923 case INTRINS_SE_PADDSB:
7924 case INTRINS_SSE_PSUBSB:
7925 case INTRINS_SSE_PADDUSB:
7926 case INTRINS_SSE_PSUBUSB:
7927 case INTRINS_SSE_PAVGB:
7928 add_sse_binary (module, name, MONO_TYPE_I1);
7930 case INTRINS_SSE_PAUSE:
7931 AddFunc (module, "llvm.x86.sse2.pause", LLVMVoidType (), NULL, 0);
7935 g_assert_not_reached ();
7941 get_intrinsic (EmitContext *ctx, const char *name)
7943 #if LLVM_API_VERSION > 100
7947 * Every method is emitted into its own module so
7948 * we can add intrinsics on demand.
7950 res = LLVMGetNamedFunction (ctx->lmodule, name);
7954 /* No locking needed */
7955 id = GPOINTER_TO_INT (g_hash_table_lookup (intrins_name_to_id, name));
7958 printf ("%s\n", name);
7959 g_assert (id != -1);
7960 add_intrinsic (ctx->lmodule, id);
7961 res = LLVMGetNamedFunction (ctx->lmodule, name);
7969 res = LLVMGetNamedFunction (ctx->lmodule, name);
7976 add_intrinsics (LLVMModuleRef module)
7980 /* Emit declarations of instrinsics */
7982 * It would be nicer to emit only the intrinsics actually used, but LLVM's Module
7983 * type doesn't seem to do any locking.
7985 for (i = 0; i < INTRINS_NUM; ++i)
7986 add_intrinsic (module, i);
7990 AddFunc (module, "mono_personality", LLVMVoidType (), NULL, 0);
7992 AddFunc (module, "llvm_resume_unwind_trampoline", LLVMVoidType (), NULL, 0);
7995 /* SSE intrinsics */
7996 #if defined(TARGET_X86) || defined(TARGET_AMD64)
8000 /* Load/Store intrinsics */
8002 LLVMTypeRef arg_types [5];
8006 for (i = 1; i <= 8; i *= 2) {
8007 arg_types [0] = LLVMPointerType (LLVMIntType (i * 8), 0);
8008 arg_types [1] = LLVMInt32Type ();
8009 arg_types [2] = LLVMInt1Type ();
8010 arg_types [3] = LLVMInt32Type ();
8011 sprintf (name, "llvm.mono.load.i%d.p0i%d", i * 8, i * 8);
8012 AddFunc (module, name, LLVMIntType (i * 8), arg_types, 4);
8014 arg_types [0] = LLVMIntType (i * 8);
8015 arg_types [1] = LLVMPointerType (LLVMIntType (i * 8), 0);
8016 arg_types [2] = LLVMInt32Type ();
8017 arg_types [3] = LLVMInt1Type ();
8018 arg_types [4] = LLVMInt32Type ();
8019 sprintf (name, "llvm.mono.store.i%d.p0i%d", i * 8, i * 8);
8020 AddFunc (module, name, LLVMVoidType (), arg_types, 5);
8026 add_types (MonoLLVMModule *module)
8028 module->ptr_type = LLVMPointerType (sizeof (gpointer) == 8 ? LLVMInt64Type () : LLVMInt32Type (), 0);
8032 mono_llvm_init (void)
8037 mono_native_tls_alloc (¤t_cfg_tls_id, NULL);
8039 h = g_hash_table_new (NULL, NULL);
8040 for (i = 0; i < INTRINS_NUM; ++i)
8041 g_hash_table_insert (h, GINT_TO_POINTER (intrinsics [i].id), (gpointer)intrinsics [i].name);
8042 intrins_id_to_name = h;
8044 h = g_hash_table_new (g_str_hash, g_str_equal);
8045 for (i = 0; i < INTRINS_NUM; ++i)
8046 g_hash_table_insert (h, (gpointer)intrinsics [i].name, GINT_TO_POINTER (intrinsics [i].id + 1));
8047 intrins_name_to_id = h;
8051 init_jit_module (MonoDomain *domain)
8053 MonoJitDomainInfo *dinfo;
8054 MonoLLVMModule *module;
8057 dinfo = domain_jit_info (domain);
8058 if (dinfo->llvm_module)
8061 mono_loader_lock ();
8063 if (dinfo->llvm_module) {
8064 mono_loader_unlock ();
8068 module = g_new0 (MonoLLVMModule, 1);
8070 name = g_strdup_printf ("mono-%s", domain->friendly_name);
8071 module->lmodule = LLVMModuleCreateWithName (name);
8072 module->context = LLVMGetGlobalContext ();
8074 module->mono_ee = (MonoEERef*)mono_llvm_create_ee (LLVMCreateModuleProviderForExistingModule (module->lmodule), alloc_cb, emitted_cb, exception_cb, dlsym_cb, &module->ee);
8076 add_intrinsics (module->lmodule);
8079 module->llvm_types = g_hash_table_new (NULL, NULL);
8081 #if LLVM_API_VERSION < 100
8082 MonoJitICallInfo *info;
8084 info = mono_find_jit_icall_by_name ("llvm_resume_unwind_trampoline");
8086 LLVMAddGlobalMapping (module->ee, LLVMGetNamedFunction (module->lmodule, "llvm_resume_unwind_trampoline"), (void*)info->func);
8089 mono_memory_barrier ();
8091 dinfo->llvm_module = module;
8093 mono_loader_unlock ();
8097 mono_llvm_cleanup (void)
8099 MonoLLVMModule *module = &aot_module;
8101 if (module->lmodule)
8102 LLVMDisposeModule (module->lmodule);
8104 if (module->context)
8105 LLVMContextDispose (module->context);
8109 mono_llvm_free_domain_info (MonoDomain *domain)
8111 MonoJitDomainInfo *info = domain_jit_info (domain);
8112 MonoLLVMModule *module = (MonoLLVMModule*)info->llvm_module;
8118 if (module->llvm_types)
8119 g_hash_table_destroy (module->llvm_types);
8121 mono_llvm_dispose_ee (module->mono_ee);
8123 if (module->bb_names) {
8124 for (i = 0; i < module->bb_names_len; ++i)
8125 g_free (module->bb_names [i]);
8126 g_free (module->bb_names);
8128 //LLVMDisposeModule (module->module);
8132 info->llvm_module = NULL;
8136 mono_llvm_create_aot_module (MonoAssembly *assembly, const char *global_prefix, gboolean emit_dwarf, gboolean static_link, gboolean llvm_only)
8138 MonoLLVMModule *module = &aot_module;
8140 /* Delete previous module */
8141 if (module->plt_entries)
8142 g_hash_table_destroy (module->plt_entries);
8143 if (module->lmodule)
8144 LLVMDisposeModule (module->lmodule);
8146 memset (module, 0, sizeof (aot_module));
8148 module->lmodule = LLVMModuleCreateWithName ("aot");
8149 module->assembly = assembly;
8150 module->global_prefix = g_strdup (global_prefix);
8151 module->got_symbol = g_strdup_printf ("%s_llvm_got", global_prefix);
8152 module->eh_frame_symbol = g_strdup_printf ("%s_eh_frame", global_prefix);
8153 module->get_method_symbol = g_strdup_printf ("%s_get_method", global_prefix);
8154 module->get_unbox_tramp_symbol = g_strdup_printf ("%s_get_unbox_tramp", global_prefix);
8155 module->external_symbols = TRUE;
8156 module->emit_dwarf = emit_dwarf;
8157 module->static_link = static_link;
8158 module->llvm_only = llvm_only;
8159 /* The first few entries are reserved */
8160 module->max_got_offset = 16;
8161 module->context = LLVMContextCreate ();
8164 /* clang ignores our debug info because it has an invalid version */
8165 module->emit_dwarf = FALSE;
8167 #if LLVM_API_VERSION > 100
8168 module->emit_dwarf = FALSE;
8171 add_intrinsics (module->lmodule);
8174 #if LLVM_API_VERSION > 100
8175 if (module->emit_dwarf) {
8176 char *dir, *build_info, *s, *cu_name;
8178 module->di_builder = mono_llvm_create_di_builder (module->lmodule);
8181 dir = g_strdup (".");
8182 build_info = mono_get_runtime_build_info ();
8183 s = g_strdup_printf ("Mono AOT Compiler %s (LLVM)", build_info);
8184 cu_name = g_path_get_basename (assembly->image->name);
8185 module->cu = mono_llvm_di_create_compile_unit (module->di_builder, cu_name, dir, s);
8187 g_free (build_info);
8194 * We couldn't compute the type of the LLVM global representing the got because
8195 * its size is only known after all the methods have been emitted. So create
8196 * a dummy variable, and replace all uses it with the real got variable when
8197 * its size is known in mono_llvm_emit_aot_module ().
8200 LLVMTypeRef got_type = LLVMArrayType (module->ptr_type, 0);
8202 module->got_var = LLVMAddGlobal (module->lmodule, got_type, "mono_dummy_got");
8203 LLVMSetInitializer (module->got_var, LLVMConstNull (got_type));
8206 /* Add initialization array */
8208 LLVMTypeRef inited_type = LLVMArrayType (LLVMInt8Type (), 0);
8210 module->inited_var = LLVMAddGlobal (aot_module.lmodule, inited_type, "mono_inited_tmp");
8211 LLVMSetInitializer (module->inited_var, LLVMConstNull (inited_type));
8215 emit_init_icall_wrappers (module);
8217 emit_llvm_code_start (module);
8219 /* Add a dummy personality function */
8220 if (!use_debug_personality) {
8221 LLVMValueRef personality = LLVMAddFunction (module->lmodule, default_personality_name, LLVMFunctionType (LLVMInt32Type (), NULL, 0, TRUE));
8222 LLVMSetLinkage (personality, LLVMExternalLinkage);
8223 mark_as_used (module, personality);
8226 /* Add a reference to the c++ exception we throw/catch */
8228 LLVMTypeRef exc = LLVMPointerType (LLVMInt8Type (), 0);
8229 module->sentinel_exception = LLVMAddGlobal (module->lmodule, exc, "_ZTIPi");
8230 LLVMSetLinkage (module->sentinel_exception, LLVMExternalLinkage);
8231 mono_llvm_set_is_constant (module->sentinel_exception);
8234 module->llvm_types = g_hash_table_new (NULL, NULL);
8235 module->plt_entries = g_hash_table_new (g_str_hash, g_str_equal);
8236 module->plt_entries_ji = g_hash_table_new (NULL, NULL);
8237 module->direct_callables = g_hash_table_new (g_str_hash, g_str_equal);
8238 module->method_to_lmethod = g_hash_table_new (NULL, NULL);
8239 module->idx_to_lmethod = g_hash_table_new (NULL, NULL);
8240 module->idx_to_unbox_tramp = g_hash_table_new (NULL, NULL);
8241 module->method_to_callers = g_hash_table_new (NULL, NULL);
8245 llvm_array_from_uints (LLVMTypeRef el_type, guint32 *values, int nvalues)
8248 LLVMValueRef res, *vals;
8250 vals = g_new0 (LLVMValueRef, nvalues);
8251 for (i = 0; i < nvalues; ++i)
8252 vals [i] = LLVMConstInt (LLVMInt32Type (), values [i], FALSE);
8253 res = LLVMConstArray (LLVMInt32Type (), vals, nvalues);
8259 * mono_llvm_emit_aot_file_info:
8261 * Emit the MonoAotFileInfo structure.
8262 * Same as emit_aot_file_info () in aot-compiler.c.
8265 mono_llvm_emit_aot_file_info (MonoAotFileInfo *info, gboolean has_jitted_code)
8267 MonoLLVMModule *module = &aot_module;
8269 /* Save these for later */
8270 memcpy (&module->aot_info, info, sizeof (MonoAotFileInfo));
8271 module->has_jitted_code = has_jitted_code;
8275 * mono_llvm_emit_aot_data:
8277 * Emit the binary data DATA pointed to by symbol SYMBOL.
8280 mono_llvm_emit_aot_data (const char *symbol, guint8 *data, int data_len)
8282 MonoLLVMModule *module = &aot_module;
8286 type = LLVMArrayType (LLVMInt8Type (), data_len);
8287 d = LLVMAddGlobal (module->lmodule, type, symbol);
8288 LLVMSetVisibility (d, LLVMHiddenVisibility);
8289 LLVMSetLinkage (d, LLVMInternalLinkage);
8290 LLVMSetInitializer (d, mono_llvm_create_constant_data_array (data, data_len));
8291 mono_llvm_set_is_constant (d);
8294 /* Add a reference to a global defined in JITted code */
8296 AddJitGlobal (MonoLLVMModule *module, LLVMTypeRef type, const char *name)
8301 s = g_strdup_printf ("%s%s", module->global_prefix, name);
8302 v = LLVMAddGlobal (module->lmodule, LLVMInt8Type (), s);
8308 emit_aot_file_info (MonoLLVMModule *module)
8310 LLVMTypeRef file_info_type;
8311 LLVMTypeRef *eltypes, eltype;
8312 LLVMValueRef info_var;
8313 LLVMValueRef *fields;
8314 int i, nfields, tindex;
8315 MonoAotFileInfo *info;
8316 LLVMModuleRef lmodule = module->lmodule;
8318 info = &module->aot_info;
8320 /* Create an LLVM type to represent MonoAotFileInfo */
8321 nfields = 2 + MONO_AOT_FILE_INFO_NUM_SYMBOLS + 15 + 5;
8322 eltypes = g_new (LLVMTypeRef, nfields);
8324 eltypes [tindex ++] = LLVMInt32Type ();
8325 eltypes [tindex ++] = LLVMInt32Type ();
8327 for (i = 0; i < MONO_AOT_FILE_INFO_NUM_SYMBOLS; ++i)
8328 eltypes [tindex ++] = LLVMPointerType (LLVMInt8Type (), 0);
8330 for (i = 0; i < 15; ++i)
8331 eltypes [tindex ++] = LLVMInt32Type ();
8333 eltypes [tindex ++] = LLVMArrayType (LLVMInt32Type (), MONO_AOT_TABLE_NUM);
8334 for (i = 0; i < 4; ++i)
8335 eltypes [tindex ++] = LLVMArrayType (LLVMInt32Type (), MONO_AOT_TRAMP_NUM);
8336 g_assert (tindex == nfields);
8337 file_info_type = LLVMStructCreateNamed (module->context, "MonoAotFileInfo");
8338 LLVMStructSetBody (file_info_type, eltypes, nfields, FALSE);
8340 info_var = LLVMAddGlobal (lmodule, file_info_type, "mono_aot_file_info");
8341 if (module->static_link) {
8342 LLVMSetVisibility (info_var, LLVMHiddenVisibility);
8343 LLVMSetLinkage (info_var, LLVMInternalLinkage);
8345 fields = g_new (LLVMValueRef, nfields);
8347 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->version, FALSE);
8348 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->dummy, FALSE);
8352 * We use LLVMGetNamedGlobal () for symbol which are defined in LLVM code, and LLVMAddGlobal ()
8353 * for symbols defined in the .s file emitted by the aot compiler.
8355 eltype = eltypes [tindex];
8356 if (module->llvm_only)
8357 fields [tindex ++] = LLVMConstNull (eltype);
8359 fields [tindex ++] = AddJitGlobal (module, eltype, "jit_got");
8360 fields [tindex ++] = module->got_var;
8361 /* llc defines this directly */
8362 if (!module->llvm_only) {
8363 fields [tindex ++] = LLVMAddGlobal (lmodule, eltype, module->eh_frame_symbol);
8364 fields [tindex ++] = LLVMConstNull (eltype);
8365 fields [tindex ++] = LLVMConstNull (eltype);
8367 fields [tindex ++] = LLVMConstNull (eltype);
8368 fields [tindex ++] = module->get_method;
8369 fields [tindex ++] = module->get_unbox_tramp;
8371 if (module->has_jitted_code) {
8372 fields [tindex ++] = AddJitGlobal (module, eltype, "jit_code_start");
8373 fields [tindex ++] = AddJitGlobal (module, eltype, "jit_code_end");
8375 fields [tindex ++] = LLVMConstNull (eltype);
8376 fields [tindex ++] = LLVMConstNull (eltype);
8378 if (!module->llvm_only)
8379 fields [tindex ++] = AddJitGlobal (module, eltype, "method_addresses");
8381 fields [tindex ++] = LLVMConstNull (eltype);
8382 if (info->flags & MONO_AOT_FILE_FLAG_SEPARATE_DATA) {
8383 for (i = 0; i < MONO_AOT_TABLE_NUM; ++i)
8384 fields [tindex ++] = LLVMConstNull (eltype);
8386 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "blob");
8387 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "class_name_table");
8388 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "class_info_offsets");
8389 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "method_info_offsets");
8390 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "ex_info_offsets");
8391 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "extra_method_info_offsets");
8392 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "extra_method_table");
8393 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "got_info_offsets");
8394 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "llvm_got_info_offsets");
8395 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "image_table");
8397 /* Not needed (mem_end) */
8398 fields [tindex ++] = LLVMConstNull (eltype);
8399 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "assembly_guid");
8400 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "runtime_version");
8401 if (info->trampoline_size [0]) {
8402 fields [tindex ++] = AddJitGlobal (module, eltype, "specific_trampolines");
8403 fields [tindex ++] = AddJitGlobal (module, eltype, "static_rgctx_trampolines");
8404 fields [tindex ++] = AddJitGlobal (module, eltype, "imt_thunks");
8405 fields [tindex ++] = AddJitGlobal (module, eltype, "gsharedvt_arg_trampolines");
8407 fields [tindex ++] = LLVMConstNull (eltype);
8408 fields [tindex ++] = LLVMConstNull (eltype);
8409 fields [tindex ++] = LLVMConstNull (eltype);
8410 fields [tindex ++] = LLVMConstNull (eltype);
8412 if (module->static_link && !module->llvm_only)
8413 fields [tindex ++] = AddJitGlobal (module, eltype, "globals");
8415 fields [tindex ++] = LLVMConstNull (eltype);
8416 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "assembly_name");
8417 if (!module->llvm_only) {
8418 fields [tindex ++] = AddJitGlobal (module, eltype, "plt");
8419 fields [tindex ++] = AddJitGlobal (module, eltype, "plt_end");
8420 fields [tindex ++] = AddJitGlobal (module, eltype, "unwind_info");
8421 fields [tindex ++] = AddJitGlobal (module, eltype, "unbox_trampolines");
8422 fields [tindex ++] = AddJitGlobal (module, eltype, "unbox_trampolines_end");
8423 fields [tindex ++] = AddJitGlobal (module, eltype, "unbox_trampoline_addresses");
8425 fields [tindex ++] = LLVMConstNull (eltype);
8426 fields [tindex ++] = LLVMConstNull (eltype);
8427 fields [tindex ++] = LLVMConstNull (eltype);
8428 fields [tindex ++] = LLVMConstNull (eltype);
8429 fields [tindex ++] = LLVMConstNull (eltype);
8430 fields [tindex ++] = LLVMConstNull (eltype);
8433 for (i = 0; i < MONO_AOT_FILE_INFO_NUM_SYMBOLS; ++i)
8434 fields [2 + i] = LLVMConstBitCast (fields [2 + i], eltype);
8437 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->plt_got_offset_base, FALSE);
8438 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->got_size, FALSE);
8439 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->plt_size, FALSE);
8440 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->nmethods, FALSE);
8441 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->flags, FALSE);
8442 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->opts, FALSE);
8443 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->simd_opts, FALSE);
8444 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->gc_name_index, FALSE);
8445 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->num_rgctx_fetch_trampolines, FALSE);
8446 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->double_align, FALSE);
8447 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->long_align, FALSE);
8448 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->generic_tramp_num, FALSE);
8449 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->tramp_page_size, FALSE);
8450 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->nshared_got_entries, FALSE);
8451 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->datafile_size, FALSE);
8453 fields [tindex ++] = llvm_array_from_uints (LLVMInt32Type (), info->table_offsets, MONO_AOT_TABLE_NUM);
8454 fields [tindex ++] = llvm_array_from_uints (LLVMInt32Type (), info->num_trampolines, MONO_AOT_TRAMP_NUM);
8455 fields [tindex ++] = llvm_array_from_uints (LLVMInt32Type (), info->trampoline_got_offset_base, MONO_AOT_TRAMP_NUM);
8456 fields [tindex ++] = llvm_array_from_uints (LLVMInt32Type (), info->trampoline_size, MONO_AOT_TRAMP_NUM);
8457 fields [tindex ++] = llvm_array_from_uints (LLVMInt32Type (), info->tramp_page_code_offsets, MONO_AOT_TRAMP_NUM);
8458 g_assert (tindex == nfields);
8460 LLVMSetInitializer (info_var, LLVMConstNamedStruct (file_info_type, fields, nfields));
8462 if (module->static_link) {
8466 s = g_strdup_printf ("mono_aot_module_%s_info", module->assembly->aname.name);
8467 /* Get rid of characters which cannot occur in symbols */
8469 for (p = s; *p; ++p) {
8470 if (!(isalnum (*p) || *p == '_'))
8473 var = LLVMAddGlobal (module->lmodule, LLVMPointerType (LLVMInt8Type (), 0), s);
8475 LLVMSetInitializer (var, LLVMConstBitCast (LLVMGetNamedGlobal (module->lmodule, "mono_aot_file_info"), LLVMPointerType (LLVMInt8Type (), 0)));
8476 LLVMSetLinkage (var, LLVMExternalLinkage);
8481 * Emit the aot module into the LLVM bitcode file FILENAME.
8484 mono_llvm_emit_aot_module (const char *filename, const char *cu_name)
8486 LLVMTypeRef got_type, inited_type;
8487 LLVMValueRef real_got, real_inited;
8488 MonoLLVMModule *module = &aot_module;
8490 emit_llvm_code_end (module);
8493 * Create the real got variable and replace all uses of the dummy variable with
8496 got_type = LLVMArrayType (module->ptr_type, module->max_got_offset + 1);
8497 real_got = LLVMAddGlobal (module->lmodule, got_type, module->got_symbol);
8498 LLVMSetInitializer (real_got, LLVMConstNull (got_type));
8499 if (module->external_symbols) {
8500 LLVMSetLinkage (real_got, LLVMExternalLinkage);
8501 LLVMSetVisibility (real_got, LLVMHiddenVisibility);
8503 LLVMSetLinkage (real_got, LLVMInternalLinkage);
8505 mono_llvm_replace_uses_of (module->got_var, real_got);
8507 mark_as_used (&aot_module, real_got);
8509 /* Delete the dummy got so it doesn't become a global */
8510 LLVMDeleteGlobal (module->got_var);
8511 module->got_var = real_got;
8514 * Same for the init_var
8516 if (module->llvm_only) {
8517 inited_type = LLVMArrayType (LLVMInt8Type (), module->max_inited_idx + 1);
8518 real_inited = LLVMAddGlobal (module->lmodule, inited_type, "mono_inited");
8519 LLVMSetInitializer (real_inited, LLVMConstNull (inited_type));
8520 LLVMSetLinkage (real_inited, LLVMInternalLinkage);
8521 mono_llvm_replace_uses_of (module->inited_var, real_inited);
8522 LLVMDeleteGlobal (module->inited_var);
8525 if (module->llvm_only) {
8526 emit_get_method (&aot_module);
8527 emit_get_unbox_tramp (&aot_module);
8530 emit_llvm_used (&aot_module);
8531 emit_dbg_info (&aot_module, filename, cu_name);
8532 emit_aot_file_info (&aot_module);
8535 * Replace GOT entries for directly callable methods with the methods themselves.
8536 * It would be easier to implement this by predefining all methods before compiling
8537 * their bodies, but that couldn't handle the case when a method fails to compile
8540 if (module->llvm_only) {
8541 GHashTableIter iter;
8543 GSList *callers, *l;
8545 g_hash_table_iter_init (&iter, module->method_to_callers);
8546 while (g_hash_table_iter_next (&iter, (void**)&method, (void**)&callers)) {
8547 LLVMValueRef lmethod;
8549 lmethod = (LLVMValueRef)g_hash_table_lookup (module->method_to_lmethod, method);
8551 for (l = callers; l; l = l->next) {
8552 LLVMValueRef caller = (LLVMValueRef)l->data;
8554 mono_llvm_replace_uses_of (caller, lmethod);
8560 /* Replace PLT entries for directly callable methods with the methods themselves */
8562 GHashTableIter iter;
8564 LLVMValueRef callee;
8566 g_hash_table_iter_init (&iter, module->plt_entries_ji);
8567 while (g_hash_table_iter_next (&iter, (void**)&ji, (void**)&callee)) {
8568 if (mono_aot_is_direct_callable (ji)) {
8569 LLVMValueRef lmethod;
8571 lmethod = (LLVMValueRef)g_hash_table_lookup (module->method_to_lmethod, ji->data.method);
8572 /* The types might not match because the caller might pass an rgctx */
8573 if (lmethod && LLVMTypeOf (callee) == LLVMTypeOf (lmethod)) {
8574 mono_llvm_replace_uses_of (callee, lmethod);
8575 mono_aot_mark_unused_llvm_plt_entry (ji);
8585 if (LLVMVerifyModule (module->lmodule, LLVMReturnStatusAction, &verifier_err)) {
8586 g_assert_not_reached ();
8591 LLVMWriteBitcodeToFile (module->lmodule, filename);
8596 md_string (const char *s)
8598 return LLVMMDString (s, strlen (s));
8601 /* Debugging support */
8604 emit_dbg_info (MonoLLVMModule *module, const char *filename, const char *cu_name)
8606 LLVMModuleRef lmodule = module->lmodule;
8607 LLVMValueRef args [16], ver;
8610 * This can only be enabled when LLVM code is emitted into a separate object
8611 * file, since the AOT compiler also emits dwarf info,
8612 * and the abbrev indexes will not be correct since llvm has added its own
8615 if (!module->emit_dwarf)
8618 #if LLVM_API_VERSION > 100
8619 mono_llvm_di_builder_finalize (module->di_builder);
8621 LLVMValueRef cu_args [16], cu;
8623 char *build_info, *s, *dir;
8626 * Emit dwarf info in the form of LLVM metadata. There is some
8627 * out-of-date documentation at:
8628 * http://llvm.org/docs/SourceLevelDebugging.html
8629 * but most of this was gathered from the llvm and
8634 cu_args [n_cuargs ++] = LLVMConstInt (LLVMInt32Type (), DW_TAG_compile_unit, FALSE);
8635 /* CU name/compilation dir */
8636 dir = g_path_get_dirname (filename);
8637 args [0] = LLVMMDString (cu_name, strlen (cu_name));
8638 args [1] = LLVMMDString (dir, strlen (dir));
8639 cu_args [n_cuargs ++] = LLVMMDNode (args, 2);
8642 cu_args [n_cuargs ++] = LLVMConstInt (LLVMInt32Type (), DW_LANG_C99, FALSE);
8644 build_info = mono_get_runtime_build_info ();
8645 s = g_strdup_printf ("Mono AOT Compiler %s (LLVM)", build_info);
8646 cu_args [n_cuargs ++] = LLVMMDString (s, strlen (s));
8647 g_free (build_info);
8649 cu_args [n_cuargs ++] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
8651 cu_args [n_cuargs ++] = LLVMMDString ("", strlen (""));
8652 /* Runtime version */
8653 cu_args [n_cuargs ++] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
8655 cu_args [n_cuargs ++] = LLVMMDNode (args, 0);
8656 cu_args [n_cuargs ++] = LLVMMDNode (args, 0);
8658 if (module->subprogram_mds) {
8662 mds = g_new0 (LLVMValueRef, module->subprogram_mds->len);
8663 for (i = 0; i < module->subprogram_mds->len; ++i)
8664 mds [i] = (LLVMValueRef)g_ptr_array_index (module->subprogram_mds, i);
8665 cu_args [n_cuargs ++] = LLVMMDNode (mds, module->subprogram_mds->len);
8667 cu_args [n_cuargs ++] = LLVMMDNode (args, 0);
8670 cu_args [n_cuargs ++] = LLVMMDNode (args, 0);
8671 /* Imported modules */
8672 cu_args [n_cuargs ++] = LLVMMDNode (args, 0);
8674 cu_args [n_cuargs ++] = LLVMMDString ("", strlen (""));
8675 /* DebugEmissionKind = FullDebug */
8676 cu_args [n_cuargs ++] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
8677 cu = LLVMMDNode (cu_args, n_cuargs);
8678 LLVMAddNamedMetadataOperand (lmodule, "llvm.dbg.cu", cu);
8681 #if LLVM_API_VERSION > 100
8682 args [0] = LLVMConstInt (LLVMInt32Type (), 2, FALSE);
8683 args [1] = LLVMMDString ("Dwarf Version", strlen ("Dwarf Version"));
8684 args [2] = LLVMConstInt (LLVMInt32Type (), 2, FALSE);
8685 ver = LLVMMDNode (args, 3);
8686 LLVMAddNamedMetadataOperand (lmodule, "llvm.module.flags", ver);
8688 args [0] = LLVMConstInt (LLVMInt32Type (), 2, FALSE);
8689 args [1] = LLVMMDString ("Debug Info Version", strlen ("Debug Info Version"));
8690 args [2] = LLVMConstInt (LLVMInt64Type (), 3, FALSE);
8691 ver = LLVMMDNode (args, 3);
8692 LLVMAddNamedMetadataOperand (lmodule, "llvm.module.flags", ver);
8694 args [0] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
8695 args [1] = LLVMMDString ("Dwarf Version", strlen ("Dwarf Version"));
8696 args [2] = LLVMConstInt (LLVMInt32Type (), 2, FALSE);
8697 ver = LLVMMDNode (args, 3);
8698 LLVMAddNamedMetadataOperand (lmodule, "llvm.module.flags", ver);
8700 args [0] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
8701 args [1] = LLVMMDString ("Debug Info Version", strlen ("Debug Info Version"));
8702 args [2] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
8703 ver = LLVMMDNode (args, 3);
8704 LLVMAddNamedMetadataOperand (lmodule, "llvm.module.flags", ver);
8709 emit_dbg_subprogram (EmitContext *ctx, MonoCompile *cfg, LLVMValueRef method, const char *name)
8711 MonoLLVMModule *module = ctx->module;
8712 MonoDebugMethodInfo *minfo = ctx->minfo;
8713 char *source_file, *dir, *filename;
8714 LLVMValueRef md, args [16], ctx_args [16], md_args [64], type_args [16], ctx_md, type_md;
8715 MonoSymSeqPoint *sym_seq_points;
8721 mono_debug_symfile_get_seq_points (minfo, &source_file, NULL, NULL, &sym_seq_points, &n_seq_points);
8723 source_file = g_strdup ("<unknown>");
8724 dir = g_path_get_dirname (source_file);
8725 filename = g_path_get_basename (source_file);
8727 #if LLVM_API_VERSION > 100
8728 return mono_llvm_di_create_function (module->di_builder, module->cu, cfg->method->name, name, dir, filename, n_seq_points ? sym_seq_points [0].line : 1);
8731 ctx_args [0] = LLVMConstInt (LLVMInt32Type (), 0x29, FALSE);
8732 args [0] = md_string (filename);
8733 args [1] = md_string (dir);
8734 ctx_args [1] = LLVMMDNode (args, 2);
8735 ctx_md = LLVMMDNode (ctx_args, 2);
8737 type_args [0] = LLVMConstInt (LLVMInt32Type (), DW_TAG_subroutine_type, FALSE);
8738 type_args [1] = NULL;
8739 type_args [2] = NULL;
8740 type_args [3] = LLVMMDString ("", 0);
8741 type_args [4] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
8742 type_args [5] = LLVMConstInt (LLVMInt64Type (), 0, FALSE);
8743 type_args [6] = LLVMConstInt (LLVMInt64Type (), 0, FALSE);
8744 type_args [7] = LLVMConstInt (LLVMInt64Type (), 0, FALSE);
8745 type_args [8] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
8746 type_args [9] = NULL;
8747 type_args [10] = NULL;
8748 type_args [11] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
8749 type_args [12] = NULL;
8750 type_args [13] = NULL;
8751 type_args [14] = NULL;
8752 type_md = LLVMMDNode (type_args, 14);
8754 /* http://llvm.org/docs/SourceLevelDebugging.html#subprogram-descriptors */
8755 md_args [0] = LLVMConstInt (LLVMInt32Type (), DW_TAG_subprogram, FALSE);
8756 /* Source directory + file pair */
8757 args [0] = md_string (filename);
8758 args [1] = md_string (dir);
8759 md_args [1] = LLVMMDNode (args ,2);
8760 md_args [2] = ctx_md;
8761 md_args [3] = md_string (cfg->method->name);
8762 md_args [4] = md_string (name);
8763 md_args [5] = md_string (name);
8766 md_args [6] = LLVMConstInt (LLVMInt32Type (), sym_seq_points [0].line, FALSE);
8768 md_args [6] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
8770 md_args [7] = type_md;
8772 md_args [8] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
8774 md_args [9] = LLVMConstInt (LLVMInt1Type (), 1, FALSE);
8776 md_args [10] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
8777 /* Index into a virtual function */
8778 md_args [11] = NULL;
8779 md_args [12] = NULL;
8781 md_args [13] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
8783 md_args [14] = LLVMConstInt (LLVMInt1Type (), 1, FALSE);
8784 /* Pointer to LLVM function */
8785 md_args [15] = method;
8786 /* Function template parameter */
8787 md_args [16] = NULL;
8788 /* Function declaration descriptor */
8789 md_args [17] = NULL;
8790 /* List of function variables */
8791 md_args [18] = LLVMMDNode (args, 0);
8793 md_args [19] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
8794 md = LLVMMDNode (md_args, 20);
8796 if (!module->subprogram_mds)
8797 module->subprogram_mds = g_ptr_array_new ();
8798 g_ptr_array_add (module->subprogram_mds, md);
8802 g_free (source_file);
8803 g_free (sym_seq_points);
8809 emit_dbg_loc (EmitContext *ctx, LLVMBuilderRef builder, const unsigned char *cil_code)
8811 MonoCompile *cfg = ctx->cfg;
8813 if (ctx->minfo && cil_code && cil_code >= cfg->header->code && cil_code < cfg->header->code + cfg->header->code_size) {
8814 MonoDebugSourceLocation *loc;
8815 LLVMValueRef loc_md;
8817 loc = mono_debug_symfile_lookup_location (ctx->minfo, cil_code - cfg->header->code);
8820 #if LLVM_API_VERSION > 100
8821 loc_md = mono_llvm_di_create_location (ctx->module->di_builder, ctx->dbg_md, loc->row, loc->column);
8822 mono_llvm_di_set_location (builder, loc_md);
8824 LLVMValueRef md_args [16];
8828 md_args [nmd_args ++] = LLVMConstInt (LLVMInt32Type (), loc->row, FALSE);
8829 md_args [nmd_args ++] = LLVMConstInt (LLVMInt32Type (), loc->column, FALSE);
8830 md_args [nmd_args ++] = ctx->dbg_md;
8831 md_args [nmd_args ++] = NULL;
8832 loc_md = LLVMMDNode (md_args, nmd_args);
8833 LLVMSetCurrentDebugLocation (builder, loc_md);
8835 mono_debug_symfile_free_location (loc);
8841 default_mono_llvm_unhandled_exception (void)
8843 MonoJitTlsData *jit_tls = mono_get_jit_tls ();
8844 MonoObject *target = mono_gchandle_get_target (jit_tls->thrown_exc);
8846 mono_unhandled_exception (target);
8847 exit (mono_environment_exitcode_get ());
8852 - Emit LLVM IR from the mono IR using the LLVM C API.
8853 - The original arch specific code remains, so we can fall back to it if we run
8854 into something we can't handle.
8858 A partial list of issues:
8859 - Handling of opcodes which can throw exceptions.
8861 In the mono JIT, these are implemented using code like this:
8868 push throw_pos - method
8869 call <exception trampoline>
8871 The problematic part is push throw_pos - method, which cannot be represented
8872 in the LLVM IR, since it does not support label values.
8873 -> this can be implemented in AOT mode using inline asm + labels, but cannot
8874 be implemented in JIT mode ?
8875 -> a possible but slower implementation would use the normal exception
8876 throwing code but it would need to control the placement of the throw code
8877 (it needs to be exactly after the compare+branch).
8878 -> perhaps add a PC offset intrinsics ?
8880 - efficient implementation of .ovf opcodes.
8882 These are currently implemented as:
8883 <ins which sets the condition codes>
8886 Some overflow opcodes are now supported by LLVM SVN.
8888 - exception handling, unwinding.
8889 - SSA is disabled for methods with exception handlers
8890 - How to obtain unwind info for LLVM compiled methods ?
8891 -> this is now solved by converting the unwind info generated by LLVM
8893 - LLVM uses the c++ exception handling framework, while we use our home grown
8894 code, and couldn't use the c++ one:
8895 - its not supported under VC++, other exotic platforms.
8896 - it might be impossible to support filter clauses with it.
8900 The trampolines need a predictable call sequence, since they need to disasm
8901 the calling code to obtain register numbers / offsets.
8903 LLVM currently generates this code in non-JIT mode:
8904 mov -0x98(%rax),%eax
8906 Here, the vtable pointer is lost.
8907 -> solution: use one vtable trampoline per class.
8909 - passing/receiving the IMT pointer/RGCTX.
8910 -> solution: pass them as normal arguments ?
8914 LLVM does not allow the specification of argument registers etc. This means
8915 that all calls are made according to the platform ABI.
8917 - passing/receiving vtypes.
8919 Vtypes passed/received in registers are handled by the front end by using
8920 a signature with scalar arguments, and loading the parts of the vtype into those
8923 Vtypes passed on the stack are handled using the 'byval' attribute.
8927 Supported though alloca, we need to emit the load/store code.
8931 The mono JIT uses pointer sized iregs/double fregs, while LLVM uses precisely
8932 typed registers, so we have to keep track of the precise LLVM type of each vreg.
8933 This is made easier because the IR is already in SSA form.
8934 An additional problem is that our IR is not consistent with types, i.e. i32/ia64
8935 types are frequently used incorrectly.
8940 Emit LLVM bytecode into a .bc file, compile it using llc into a .s file, then link
8941 it with the file containing the methods emitted by the JIT and the AOT data
8945 /* FIXME: Normalize some aspects of the mono IR to allow easier translation, like:
8946 * - each bblock should end with a branch
8947 * - setting the return value, making cfg->ret non-volatile
8948 * - avoid some transformations in the JIT which make it harder for us to generate
8950 * - use pointer types to help optimizations.