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/Core.h"
28 #include "llvm-c/ExecutionEngine.h"
29 #include "llvm-c/BitWriter.h"
30 #include "llvm-c/Analysis.h"
32 #include "mini-llvm-cpp.h"
33 #include "aot-compiler.h"
34 #include "mini-llvm.h"
39 extern void *memset(void *, int, size_t);
40 void bzero (void *to, size_t count) { memset (to, 0, count); }
44 #if LLVM_API_VERSION < 4
45 #error "The version of the mono llvm repository is too old."
49 * Information associated by mono with LLVM modules.
52 LLVMModuleRef lmodule;
53 LLVMValueRef throw_icall, rethrow, match_exc, throw_corlib_exception, resume_eh;
54 GHashTable *llvm_types;
56 const char *got_symbol;
57 const char *get_method_symbol;
58 const char *get_unbox_tramp_symbol;
59 GHashTable *plt_entries;
60 GHashTable *plt_entries_ji;
61 GHashTable *method_to_lmethod;
62 GHashTable *direct_callables;
67 GPtrArray *subprogram_mds;
69 LLVMExecutionEngineRef ee;
70 gboolean external_symbols;
75 MonoAssembly *assembly;
77 MonoAotFileInfo aot_info;
78 const char *jit_got_symbol;
79 const char *eh_frame_symbol;
80 LLVMValueRef get_method, get_unbox_tramp;
81 LLVMValueRef init_method, init_method_gshared_mrgctx, init_method_gshared_this, init_method_gshared_vtable;
82 LLVMValueRef code_start, code_end;
83 LLVMValueRef inited_var;
84 int max_inited_idx, max_method_idx;
85 gboolean has_jitted_code;
88 GHashTable *idx_to_lmethod;
89 GHashTable *idx_to_unbox_tramp;
90 /* Maps a MonoMethod to LLVM instructions representing it */
91 GHashTable *method_to_callers;
92 LLVMContextRef context;
93 LLVMValueRef sentinel_exception;
97 * Information associated by the backend with mono basic blocks.
100 LLVMBasicBlockRef bblock, end_bblock;
101 LLVMValueRef finally_ind;
102 gboolean added, invoke_target;
104 * If this bblock is the start of a finally clause, this is a list of bblocks it
105 * needs to branch to in ENDFINALLY.
107 GSList *call_handler_return_bbs;
109 * If this bblock is the start of a finally clause, this is the bblock that
110 * CALL_HANDLER needs to branch to.
112 LLVMBasicBlockRef call_handler_target_bb;
113 /* The list of switch statements generated by ENDFINALLY instructions */
114 GSList *endfinally_switch_ins_list;
119 * Structure containing emit state
122 MonoMemPool *mempool;
124 /* Maps method names to the corresponding LLVMValueRef */
125 GHashTable *emitted_method_decls;
128 LLVMValueRef lmethod;
129 MonoLLVMModule *module;
130 LLVMModuleRef lmodule;
132 int sindex, default_index, ex_index;
133 LLVMBuilderRef builder;
134 LLVMValueRef *values, *addresses;
135 MonoType **vreg_cli_types;
137 MonoMethodSignature *sig;
139 GHashTable *region_to_handler;
140 GHashTable *clause_to_handler;
141 LLVMBuilderRef alloca_builder;
142 LLVMValueRef last_alloca;
143 LLVMValueRef rgctx_arg;
144 LLVMValueRef this_arg;
145 LLVMTypeRef *vreg_types;
146 LLVMBasicBlockRef init_bb, inited_bb;
148 gboolean *unreachable;
150 gboolean has_got_access;
151 int this_arg_pindex, rgctx_arg_pindex;
152 LLVMValueRef imt_rgctx_loc;
153 GHashTable *llvm_types;
155 MonoDebugMethodInfo *minfo;
157 /* For every clause, the clauses it is nested in */
160 GHashTable *exc_meta;
161 GHashTable *method_to_callers;
167 MonoBasicBlock *in_bb;
172 * Instruction metadata
173 * This is the same as ins_info, but LREG != IREG.
181 #define MINI_OP(a,b,dest,src1,src2) dest, src1, src2, ' ',
182 #define MINI_OP3(a,b,dest,src1,src2,src3) dest, src1, src2, src3,
189 /* keep in sync with the enum in mini.h */
192 #include "mini-ops.h"
197 #if SIZEOF_VOID_P == 4
198 #define GET_LONG_IMM(ins) (((guint64)(ins)->inst_ms_word << 32) | (guint64)(guint32)(ins)->inst_ls_word)
200 #define GET_LONG_IMM(ins) ((ins)->inst_imm)
203 #define LLVM_INS_INFO(opcode) (&llvm_ins_info [((opcode) - OP_START - 1) * 4])
206 #define TRACE_FAILURE(msg) do { printf ("%s\n", msg); } while (0)
208 #define TRACE_FAILURE(msg)
212 #define IS_TARGET_X86 1
214 #define IS_TARGET_X86 0
218 #define IS_TARGET_AMD64 1
220 #define IS_TARGET_AMD64 0
223 #define LLVM_FAILURE(ctx, reason) do { \
224 TRACE_FAILURE (reason); \
225 (ctx)->cfg->exception_message = g_strdup (reason); \
226 (ctx)->cfg->disable_llvm = TRUE; \
230 #define CHECK_FAILURE(ctx) do { \
231 if ((ctx)->cfg->disable_llvm) \
235 static LLVMIntPredicate cond_to_llvm_cond [] = {
248 static LLVMRealPredicate fpcond_to_llvm_cond [] = {
261 static MonoNativeTlsKey current_cfg_tls_id;
263 static MonoLLVMModule aot_module;
264 static int memset_param_count, memcpy_param_count;
265 static const char *memset_func_name;
266 static const char *memcpy_func_name;
268 static void init_jit_module (MonoDomain *domain);
270 static void emit_dbg_loc (EmitContext *ctx, LLVMBuilderRef builder, const unsigned char *cil_code);
271 static LLVMValueRef emit_dbg_subprogram (EmitContext *ctx, MonoCompile *cfg, LLVMValueRef method, const char *name);
272 static void emit_dbg_info (MonoLLVMModule *module, const char *filename, const char *cu_name);
277 * The LLVM type with width == sizeof (gpointer)
282 return sizeof (gpointer) == 8 ? LLVMInt64Type () : LLVMInt32Type ();
288 return sizeof (gpointer) == 8 ? LLVMPointerType (LLVMInt64Type (), 0) : LLVMPointerType (LLVMInt32Type (), 0);
294 return sizeof (gpointer) == 8 ? LLVMPointerType (LLVMInt64Type (), 0) : LLVMPointerType (LLVMInt32Type (), 0);
300 * Return the size of the LLVM representation of the vtype T.
303 get_vtype_size (MonoType *t)
307 size = mono_class_value_size (mono_class_from_mono_type (t), NULL);
309 /* LLVMArgAsIArgs depends on this since it stores whole words */
310 while (size < 2 * sizeof (gpointer) && mono_is_power_of_two (size) == -1)
317 * simd_class_to_llvm_type:
319 * Return the LLVM type corresponding to the Mono.SIMD class KLASS
322 simd_class_to_llvm_type (EmitContext *ctx, MonoClass *klass)
324 if (!strcmp (klass->name, "Vector2d")) {
325 return LLVMVectorType (LLVMDoubleType (), 2);
326 } else if (!strcmp (klass->name, "Vector2l")) {
327 return LLVMVectorType (LLVMInt64Type (), 2);
328 } else if (!strcmp (klass->name, "Vector2ul")) {
329 return LLVMVectorType (LLVMInt64Type (), 2);
330 } else if (!strcmp (klass->name, "Vector4i")) {
331 return LLVMVectorType (LLVMInt32Type (), 4);
332 } else if (!strcmp (klass->name, "Vector4ui")) {
333 return LLVMVectorType (LLVMInt32Type (), 4);
334 } else if (!strcmp (klass->name, "Vector4f")) {
335 return LLVMVectorType (LLVMFloatType (), 4);
336 } else if (!strcmp (klass->name, "Vector8s")) {
337 return LLVMVectorType (LLVMInt16Type (), 8);
338 } else if (!strcmp (klass->name, "Vector8us")) {
339 return LLVMVectorType (LLVMInt16Type (), 8);
340 } else if (!strcmp (klass->name, "Vector16sb")) {
341 return LLVMVectorType (LLVMInt8Type (), 16);
342 } else if (!strcmp (klass->name, "Vector16b")) {
343 return LLVMVectorType (LLVMInt8Type (), 16);
345 printf ("%s\n", klass->name);
351 /* Return the 128 bit SIMD type corresponding to the mono type TYPE */
352 static inline G_GNUC_UNUSED LLVMTypeRef
353 type_to_simd_type (int type)
357 return LLVMVectorType (LLVMInt8Type (), 16);
359 return LLVMVectorType (LLVMInt16Type (), 8);
361 return LLVMVectorType (LLVMInt32Type (), 4);
363 return LLVMVectorType (LLVMInt64Type (), 2);
365 return LLVMVectorType (LLVMDoubleType (), 2);
367 return LLVMVectorType (LLVMFloatType (), 4);
369 g_assert_not_reached ();
375 create_llvm_type_for_type (MonoLLVMModule *module, MonoClass *klass)
377 int i, size, nfields, esize;
378 LLVMTypeRef *eltypes;
383 t = &klass->byval_arg;
385 if (mini_type_is_hfa (t, &nfields, &esize)) {
387 * This is needed on arm64 where HFAs are returned in
391 eltypes = g_new (LLVMTypeRef, size);
392 for (i = 0; i < size; ++i)
393 eltypes [i] = esize == 4 ? LLVMFloatType () : LLVMDoubleType ();
395 size = get_vtype_size (t);
397 eltypes = g_new (LLVMTypeRef, size);
398 for (i = 0; i < size; ++i)
399 eltypes [i] = LLVMInt8Type ();
402 name = mono_type_full_name (&klass->byval_arg);
403 ltype = LLVMStructCreateNamed (module->context, name);
404 LLVMStructSetBody (ltype, eltypes, size, FALSE);
414 * Return the LLVM type corresponding to T.
417 type_to_llvm_type (EmitContext *ctx, MonoType *t)
419 t = mini_get_underlying_type (t);
423 return LLVMVoidType ();
425 return LLVMInt8Type ();
427 return LLVMInt16Type ();
429 return LLVMInt32Type ();
431 return LLVMInt8Type ();
433 return LLVMInt16Type ();
435 return LLVMInt32Type ();
436 case MONO_TYPE_BOOLEAN:
437 return LLVMInt8Type ();
440 return LLVMInt64Type ();
442 return LLVMInt16Type ();
444 return LLVMFloatType ();
446 return LLVMDoubleType ();
449 return IntPtrType ();
450 case MONO_TYPE_OBJECT:
451 case MONO_TYPE_CLASS:
452 case MONO_TYPE_ARRAY:
453 case MONO_TYPE_SZARRAY:
454 case MONO_TYPE_STRING:
456 return ObjRefType ();
459 /* Because of generic sharing */
460 return ObjRefType ();
461 case MONO_TYPE_GENERICINST:
462 if (!mono_type_generic_inst_is_valuetype (t))
463 return ObjRefType ();
465 case MONO_TYPE_VALUETYPE:
466 case MONO_TYPE_TYPEDBYREF: {
470 klass = mono_class_from_mono_type (t);
472 if (MONO_CLASS_IS_SIMD (ctx->cfg, klass))
473 return simd_class_to_llvm_type (ctx, klass);
476 return type_to_llvm_type (ctx, mono_class_enum_basetype (klass));
478 ltype = (LLVMTypeRef)g_hash_table_lookup (ctx->module->llvm_types, klass);
480 ltype = create_llvm_type_for_type (ctx->module, klass);
481 g_hash_table_insert (ctx->module->llvm_types, klass, ltype);
487 printf ("X: %d\n", t->type);
488 ctx->cfg->exception_message = g_strdup_printf ("type %s", mono_type_full_name (t));
489 ctx->cfg->disable_llvm = TRUE;
497 * Return whenever T is an unsigned int type.
500 type_is_unsigned (EmitContext *ctx, MonoType *t)
517 * type_to_llvm_arg_type:
519 * Same as type_to_llvm_type, but treat i8/i16 as i32.
522 type_to_llvm_arg_type (EmitContext *ctx, MonoType *t)
524 LLVMTypeRef ptype = type_to_llvm_type (ctx, t);
526 if (ctx->cfg->llvm_only)
530 * This works on all abis except arm64/ios which passes multiple
531 * arguments in one stack slot.
534 if (ptype == LLVMInt8Type () || ptype == LLVMInt16Type ()) {
536 * LLVM generates code which only sets the lower bits, while JITted
537 * code expects all the bits to be set.
539 ptype = LLVMInt32Type ();
547 * llvm_type_to_stack_type:
549 * Return the LLVM type which needs to be used when a value of type TYPE is pushed
552 static G_GNUC_UNUSED LLVMTypeRef
553 llvm_type_to_stack_type (MonoCompile *cfg, LLVMTypeRef type)
557 if (type == LLVMInt8Type ())
558 return LLVMInt32Type ();
559 else if (type == LLVMInt16Type ())
560 return LLVMInt32Type ();
561 else if (!cfg->r4fp && type == LLVMFloatType ())
562 return LLVMDoubleType ();
568 * regtype_to_llvm_type:
570 * Return the LLVM type corresponding to the regtype C used in instruction
574 regtype_to_llvm_type (char c)
578 return LLVMInt32Type ();
580 return LLVMInt64Type ();
582 return LLVMDoubleType ();
591 * Return the LLVM type corresponding to the unary/binary opcode OPCODE.
594 op_to_llvm_type (int opcode)
599 return LLVMInt8Type ();
602 return LLVMInt8Type ();
605 return LLVMInt16Type ();
608 return LLVMInt16Type ();
611 return LLVMInt32Type ();
614 return LLVMInt32Type ();
616 return LLVMInt64Type ();
618 return LLVMFloatType ();
620 return LLVMDoubleType ();
622 return LLVMInt64Type ();
624 return LLVMInt32Type ();
626 return LLVMInt64Type ();
631 return LLVMInt8Type ();
636 return LLVMInt16Type ();
638 return LLVMInt32Type ();
641 return sizeof (gpointer) == 8 ? LLVMInt64Type () : LLVMInt32Type ();
648 return LLVMInt32Type ();
655 return LLVMInt64Type ();
657 printf ("%s\n", mono_inst_name (opcode));
658 g_assert_not_reached ();
663 #define CLAUSE_START(clause) ((clause)->try_offset)
664 #define CLAUSE_END(clause) (((clause))->try_offset + ((clause))->try_len)
667 * load_store_to_llvm_type:
669 * Return the size/sign/zero extension corresponding to the load/store opcode
673 load_store_to_llvm_type (int opcode, int *size, gboolean *sext, gboolean *zext)
679 case OP_LOADI1_MEMBASE:
680 case OP_STOREI1_MEMBASE_REG:
681 case OP_STOREI1_MEMBASE_IMM:
682 case OP_ATOMIC_LOAD_I1:
683 case OP_ATOMIC_STORE_I1:
686 return LLVMInt8Type ();
687 case OP_LOADU1_MEMBASE:
689 case OP_ATOMIC_LOAD_U1:
690 case OP_ATOMIC_STORE_U1:
693 return LLVMInt8Type ();
694 case OP_LOADI2_MEMBASE:
695 case OP_STOREI2_MEMBASE_REG:
696 case OP_STOREI2_MEMBASE_IMM:
697 case OP_ATOMIC_LOAD_I2:
698 case OP_ATOMIC_STORE_I2:
701 return LLVMInt16Type ();
702 case OP_LOADU2_MEMBASE:
704 case OP_ATOMIC_LOAD_U2:
705 case OP_ATOMIC_STORE_U2:
708 return LLVMInt16Type ();
709 case OP_LOADI4_MEMBASE:
710 case OP_LOADU4_MEMBASE:
713 case OP_STOREI4_MEMBASE_REG:
714 case OP_STOREI4_MEMBASE_IMM:
715 case OP_ATOMIC_LOAD_I4:
716 case OP_ATOMIC_STORE_I4:
717 case OP_ATOMIC_LOAD_U4:
718 case OP_ATOMIC_STORE_U4:
720 return LLVMInt32Type ();
721 case OP_LOADI8_MEMBASE:
723 case OP_STOREI8_MEMBASE_REG:
724 case OP_STOREI8_MEMBASE_IMM:
725 case OP_ATOMIC_LOAD_I8:
726 case OP_ATOMIC_STORE_I8:
727 case OP_ATOMIC_LOAD_U8:
728 case OP_ATOMIC_STORE_U8:
730 return LLVMInt64Type ();
731 case OP_LOADR4_MEMBASE:
732 case OP_STORER4_MEMBASE_REG:
733 case OP_ATOMIC_LOAD_R4:
734 case OP_ATOMIC_STORE_R4:
736 return LLVMFloatType ();
737 case OP_LOADR8_MEMBASE:
738 case OP_STORER8_MEMBASE_REG:
739 case OP_ATOMIC_LOAD_R8:
740 case OP_ATOMIC_STORE_R8:
742 return LLVMDoubleType ();
743 case OP_LOAD_MEMBASE:
745 case OP_STORE_MEMBASE_REG:
746 case OP_STORE_MEMBASE_IMM:
747 *size = sizeof (gpointer);
748 return IntPtrType ();
750 g_assert_not_reached ();
758 * Return the LLVM intrinsics corresponding to the overflow opcode OPCODE.
761 ovf_op_to_intrins (int opcode)
765 return "llvm.sadd.with.overflow.i32";
767 return "llvm.uadd.with.overflow.i32";
769 return "llvm.ssub.with.overflow.i32";
771 return "llvm.usub.with.overflow.i32";
773 return "llvm.smul.with.overflow.i32";
775 return "llvm.umul.with.overflow.i32";
777 return "llvm.sadd.with.overflow.i64";
779 return "llvm.uadd.with.overflow.i64";
781 return "llvm.ssub.with.overflow.i64";
783 return "llvm.usub.with.overflow.i64";
785 return "llvm.smul.with.overflow.i64";
787 return "llvm.umul.with.overflow.i64";
789 g_assert_not_reached ();
795 simd_op_to_intrins (int opcode)
798 #if defined(TARGET_X86) || defined(TARGET_AMD64)
800 return "llvm.x86.sse2.min.pd";
802 return "llvm.x86.sse.min.ps";
804 return "llvm.x86.sse41.pminud";
806 return "llvm.x86.sse41.pminuw";
808 return "llvm.x86.sse2.pminu.b";
810 return "llvm.x86.sse2.pmins.w";
812 return "llvm.x86.sse2.max.pd";
814 return "llvm.x86.sse.max.ps";
816 return "llvm.x86.sse3.hadd.pd";
818 return "llvm.x86.sse3.hadd.ps";
820 return "llvm.x86.sse3.hsub.pd";
822 return "llvm.x86.sse3.hsub.ps";
824 return "llvm.x86.sse41.pmaxud";
826 return "llvm.x86.sse41.pmaxuw";
828 return "llvm.x86.sse2.pmaxu.b";
830 return "llvm.x86.sse3.addsub.ps";
832 return "llvm.x86.sse3.addsub.pd";
833 case OP_EXTRACT_MASK:
834 return "llvm.x86.sse2.pmovmskb.128";
837 return "llvm.x86.sse2.psrli.w";
840 return "llvm.x86.sse2.psrli.d";
843 return "llvm.x86.sse2.psrli.q";
846 return "llvm.x86.sse2.pslli.w";
849 return "llvm.x86.sse2.pslli.d";
852 return "llvm.x86.sse2.pslli.q";
855 return "llvm.x86.sse2.psrai.w";
858 return "llvm.x86.sse2.psrai.d";
860 return "llvm.x86.sse2.padds.b";
862 return "llvm.x86.sse2.padds.w";
864 return "llvm.x86.sse2.psubs.b";
866 return "llvm.x86.sse2.psubs.w";
867 case OP_PADDB_SAT_UN:
868 return "llvm.x86.sse2.paddus.b";
869 case OP_PADDW_SAT_UN:
870 return "llvm.x86.sse2.paddus.w";
871 case OP_PSUBB_SAT_UN:
872 return "llvm.x86.sse2.psubus.b";
873 case OP_PSUBW_SAT_UN:
874 return "llvm.x86.sse2.psubus.w";
876 return "llvm.x86.sse2.pavg.b";
878 return "llvm.x86.sse2.pavg.w";
880 return "llvm.x86.sse.sqrt.ps";
882 return "llvm.x86.sse2.sqrt.pd";
884 return "llvm.x86.sse.rsqrt.ps";
886 return "llvm.x86.sse.rcp.ps";
888 return "llvm.x86.sse2.cvtdq2pd";
890 return "llvm.x86.sse2.cvtdq2ps";
892 return "llvm.x86.sse2.cvtpd2dq";
894 return "llvm.x86.sse2.cvtps2dq";
896 return "llvm.x86.sse2.cvtpd2ps";
898 return "llvm.x86.sse2.cvtps2pd";
900 return "llvm.x86.sse2.cvttpd2dq";
902 return "llvm.x86.sse2.cvttps2dq";
904 return "llvm.x86.sse.cmp.ps";
906 return "llvm.x86.sse2.cmp.pd";
908 return "llvm.x86.sse2.packsswb.128";
910 return "llvm.x86.sse2.packssdw.128";
912 return "llvm.x86.sse2.packuswb.128";
914 return "llvm.x86.sse41.packusdw";
916 return "llvm.x86.sse2.pmulh.w";
917 case OP_PMULW_HIGH_UN:
918 return "llvm.x86.sse2.pmulhu.w";
921 g_assert_not_reached ();
927 simd_op_to_llvm_type (int opcode)
929 #if defined(TARGET_X86) || defined(TARGET_AMD64)
933 return type_to_simd_type (MONO_TYPE_R8);
936 return type_to_simd_type (MONO_TYPE_I8);
939 return type_to_simd_type (MONO_TYPE_I4);
944 return type_to_simd_type (MONO_TYPE_I2);
948 return type_to_simd_type (MONO_TYPE_I1);
950 return type_to_simd_type (MONO_TYPE_R4);
953 return type_to_simd_type (MONO_TYPE_I4);
957 return type_to_simd_type (MONO_TYPE_R8);
961 return type_to_simd_type (MONO_TYPE_R4);
962 case OP_EXTRACT_MASK:
963 return type_to_simd_type (MONO_TYPE_I1);
969 return type_to_simd_type (MONO_TYPE_R4);
972 return type_to_simd_type (MONO_TYPE_R8);
974 g_assert_not_reached ();
985 * Return the LLVM basic block corresponding to BB.
987 static LLVMBasicBlockRef
988 get_bb (EmitContext *ctx, MonoBasicBlock *bb)
990 char bb_name_buf [128];
993 if (ctx->bblocks [bb->block_num].bblock == NULL) {
994 if (bb->flags & BB_EXCEPTION_HANDLER) {
995 int clause_index = (mono_get_block_region_notry (ctx->cfg, bb->region) >> 8) - 1;
996 sprintf (bb_name_buf, "EH_CLAUSE%d_BB%d", clause_index, bb->block_num);
997 bb_name = bb_name_buf;
998 } else if (bb->block_num < 256) {
999 if (!ctx->module->bb_names) {
1000 ctx->module->bb_names_len = 256;
1001 ctx->module->bb_names = g_new0 (char*, ctx->module->bb_names_len);
1003 if (!ctx->module->bb_names [bb->block_num]) {
1006 n = g_strdup_printf ("BB%d", bb->block_num);
1007 mono_memory_barrier ();
1008 ctx->module->bb_names [bb->block_num] = n;
1010 bb_name = ctx->module->bb_names [bb->block_num];
1012 sprintf (bb_name_buf, "BB%d", bb->block_num);
1013 bb_name = bb_name_buf;
1016 ctx->bblocks [bb->block_num].bblock = LLVMAppendBasicBlock (ctx->lmethod, bb_name);
1017 ctx->bblocks [bb->block_num].end_bblock = ctx->bblocks [bb->block_num].bblock;
1020 return ctx->bblocks [bb->block_num].bblock;
1026 * Return the last LLVM bblock corresponding to BB.
1027 * This might not be equal to the bb returned by get_bb () since we need to generate
1028 * multiple LLVM bblocks for a mono bblock to handle throwing exceptions.
1030 static LLVMBasicBlockRef
1031 get_end_bb (EmitContext *ctx, MonoBasicBlock *bb)
1034 return ctx->bblocks [bb->block_num].end_bblock;
1037 static LLVMBasicBlockRef
1038 gen_bb (EmitContext *ctx, const char *prefix)
1042 sprintf (bb_name, "%s%d", prefix, ++ ctx->ex_index);
1043 return LLVMAppendBasicBlock (ctx->lmethod, bb_name);
1049 * Return the target of the patch identified by TYPE and TARGET.
1052 resolve_patch (MonoCompile *cfg, MonoJumpInfoType type, gconstpointer target)
1056 memset (&ji, 0, sizeof (ji));
1058 ji.data.target = target;
1060 return mono_resolve_patch_target (cfg->method, cfg->domain, NULL, &ji, FALSE);
1066 * Emit code to convert the LLVM value V to DTYPE.
1069 convert_full (EmitContext *ctx, LLVMValueRef v, LLVMTypeRef dtype, gboolean is_unsigned)
1071 LLVMTypeRef stype = LLVMTypeOf (v);
1073 if (stype != dtype) {
1074 gboolean ext = FALSE;
1077 if (dtype == LLVMInt64Type () && (stype == LLVMInt32Type () || stype == LLVMInt16Type () || stype == LLVMInt8Type ()))
1079 else if (dtype == LLVMInt32Type () && (stype == LLVMInt16Type () || stype == LLVMInt8Type ()))
1081 else if (dtype == LLVMInt16Type () && (stype == LLVMInt8Type ()))
1085 return is_unsigned ? LLVMBuildZExt (ctx->builder, v, dtype, "") : LLVMBuildSExt (ctx->builder, v, dtype, "");
1087 if (dtype == LLVMDoubleType () && stype == LLVMFloatType ())
1088 return LLVMBuildFPExt (ctx->builder, v, dtype, "");
1091 if (stype == LLVMInt64Type () && (dtype == LLVMInt32Type () || dtype == LLVMInt16Type () || dtype == LLVMInt8Type ()))
1092 return LLVMBuildTrunc (ctx->builder, v, dtype, "");
1093 if (stype == LLVMInt32Type () && (dtype == LLVMInt16Type () || dtype == LLVMInt8Type ()))
1094 return LLVMBuildTrunc (ctx->builder, v, dtype, "");
1095 if (stype == LLVMInt16Type () && dtype == LLVMInt8Type ())
1096 return LLVMBuildTrunc (ctx->builder, v, dtype, "");
1097 if (stype == LLVMDoubleType () && dtype == LLVMFloatType ())
1098 return LLVMBuildFPTrunc (ctx->builder, v, dtype, "");
1100 if (LLVMGetTypeKind (stype) == LLVMPointerTypeKind && LLVMGetTypeKind (dtype) == LLVMPointerTypeKind)
1101 return LLVMBuildBitCast (ctx->builder, v, dtype, "");
1102 if (LLVMGetTypeKind (dtype) == LLVMPointerTypeKind)
1103 return LLVMBuildIntToPtr (ctx->builder, v, dtype, "");
1104 if (LLVMGetTypeKind (stype) == LLVMPointerTypeKind)
1105 return LLVMBuildPtrToInt (ctx->builder, v, dtype, "");
1107 if (mono_arch_is_soft_float ()) {
1108 if (stype == LLVMInt32Type () && dtype == LLVMFloatType ())
1109 return LLVMBuildBitCast (ctx->builder, v, dtype, "");
1110 if (stype == LLVMInt32Type () && dtype == LLVMDoubleType ())
1111 return LLVMBuildBitCast (ctx->builder, LLVMBuildZExt (ctx->builder, v, LLVMInt64Type (), ""), dtype, "");
1114 if (LLVMGetTypeKind (stype) == LLVMVectorTypeKind && LLVMGetTypeKind (dtype) == LLVMVectorTypeKind)
1115 return LLVMBuildBitCast (ctx->builder, v, dtype, "");
1118 LLVMDumpValue (LLVMConstNull (dtype));
1119 g_assert_not_reached ();
1127 convert (EmitContext *ctx, LLVMValueRef v, LLVMTypeRef dtype)
1129 return convert_full (ctx, v, dtype, FALSE);
1133 * emit_volatile_load:
1135 * If vreg is volatile, emit a load from its address.
1138 emit_volatile_load (EmitContext *ctx, int vreg)
1142 LLVMValueRef v = LLVMBuildLoad (ctx->builder, ctx->addresses [vreg], "");
1143 t = ctx->vreg_cli_types [vreg];
1144 if (t && !t->byref) {
1146 * Might have to zero extend since llvm doesn't have
1149 if (t->type == MONO_TYPE_U1 || t->type == MONO_TYPE_U2 || t->type == MONO_TYPE_CHAR || t->type == MONO_TYPE_BOOLEAN)
1150 v = LLVMBuildZExt (ctx->builder, v, LLVMInt32Type (), "");
1151 else if (t->type == MONO_TYPE_I1 || t->type == MONO_TYPE_I2)
1152 v = LLVMBuildSExt (ctx->builder, v, LLVMInt32Type (), "");
1153 else if (t->type == MONO_TYPE_U8)
1154 v = LLVMBuildZExt (ctx->builder, v, LLVMInt64Type (), "");
1161 * emit_volatile_store:
1163 * If VREG is volatile, emit a store from its value to its address.
1166 emit_volatile_store (EmitContext *ctx, int vreg)
1168 MonoInst *var = get_vreg_to_inst (ctx->cfg, vreg);
1170 if (var && var->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT)) {
1171 g_assert (ctx->addresses [vreg]);
1172 LLVMBuildStore (ctx->builder, convert (ctx, ctx->values [vreg], type_to_llvm_type (ctx, var->inst_vtype)), ctx->addresses [vreg]);
1177 sig_to_llvm_sig_no_cinfo (EmitContext *ctx, MonoMethodSignature *sig)
1179 LLVMTypeRef ret_type;
1180 LLVMTypeRef *param_types = NULL;
1185 rtype = mini_get_underlying_type (sig->ret);
1186 ret_type = type_to_llvm_type (ctx, rtype);
1187 CHECK_FAILURE (ctx);
1189 param_types = g_new0 (LLVMTypeRef, (sig->param_count * 8) + 3);
1193 param_types [pindex ++] = ThisType ();
1194 for (i = 0; i < sig->param_count; ++i)
1195 param_types [pindex ++] = type_to_llvm_arg_type (ctx, sig->params [i]);
1197 CHECK_FAILURE (ctx);
1199 res = LLVMFunctionType (ret_type, param_types, pindex, FALSE);
1200 g_free (param_types);
1205 g_free (param_types);
1211 * sig_to_llvm_sig_full:
1213 * Return the LLVM signature corresponding to the mono signature SIG using the
1214 * calling convention information in CINFO. Fill out the parameter mapping information in CINFO.
1217 sig_to_llvm_sig_full (EmitContext *ctx, MonoMethodSignature *sig, LLVMCallInfo *cinfo)
1219 LLVMTypeRef ret_type;
1220 LLVMTypeRef *param_types = NULL;
1222 int i, j, pindex, vret_arg_pindex = 0;
1223 gboolean vretaddr = FALSE;
1227 return sig_to_llvm_sig_no_cinfo (ctx, sig);
1229 rtype = mini_get_underlying_type (sig->ret);
1230 ret_type = type_to_llvm_type (ctx, rtype);
1231 CHECK_FAILURE (ctx);
1233 switch (cinfo->ret.storage) {
1234 case LLVMArgVtypeInReg:
1235 /* LLVM models this by returning an aggregate value */
1236 if (cinfo->ret.pair_storage [0] == LLVMArgInIReg && cinfo->ret.pair_storage [1] == LLVMArgNone) {
1237 LLVMTypeRef members [2];
1239 members [0] = IntPtrType ();
1240 ret_type = LLVMStructType (members, 1, FALSE);
1241 } else if (cinfo->ret.pair_storage [0] == LLVMArgNone && cinfo->ret.pair_storage [1] == LLVMArgNone) {
1243 ret_type = LLVMVoidType ();
1244 } else if (cinfo->ret.pair_storage [0] == LLVMArgInIReg && cinfo->ret.pair_storage [1] == LLVMArgInIReg) {
1245 LLVMTypeRef members [2];
1247 members [0] = IntPtrType ();
1248 members [1] = IntPtrType ();
1249 ret_type = LLVMStructType (members, 2, FALSE);
1251 g_assert_not_reached ();
1254 case LLVMArgVtypeByVal:
1255 /* Vtype returned normally by val */
1257 case LLVMArgVtypeAsScalar:
1258 /* LLVM models this by returning an int */
1259 g_assert (cinfo->ret.nslots == 1 || cinfo->ret.nslots == 2);
1260 ret_type = LLVMIntType (cinfo->ret.nslots * sizeof (mgreg_t) * 8);
1262 case LLVMArgFpStruct: {
1263 /* Vtype returned as a fp struct */
1264 LLVMTypeRef members [16];
1266 /* Have to create our own structure since we don't map fp structures to LLVM fp structures yet */
1267 for (i = 0; i < cinfo->ret.nslots; ++i)
1268 members [i] = cinfo->ret.esize == 8 ? LLVMDoubleType () : LLVMFloatType ();
1269 ret_type = LLVMStructType (members, cinfo->ret.nslots, FALSE);
1272 case LLVMArgVtypeByRef:
1273 /* Vtype returned using a hidden argument */
1274 ret_type = LLVMVoidType ();
1276 case LLVMArgVtypeRetAddr:
1277 case LLVMArgScalarRetAddr:
1278 case LLVMArgGsharedvtFixed:
1279 case LLVMArgGsharedvtFixedVtype:
1280 case LLVMArgGsharedvtVariable:
1282 ret_type = LLVMVoidType ();
1288 param_types = g_new0 (LLVMTypeRef, (sig->param_count * 8) + 3);
1290 if (cinfo->ret.storage == LLVMArgVtypeByRef) {
1292 * Has to be the first argument because of the sret argument attribute
1293 * FIXME: This might conflict with passing 'this' as the first argument, but
1294 * this is only used on arm64 which has a dedicated struct return register.
1296 cinfo->vret_arg_pindex = pindex;
1297 param_types [pindex] = type_to_llvm_arg_type (ctx, sig->ret);
1298 CHECK_FAILURE (ctx);
1299 param_types [pindex] = LLVMPointerType (param_types [pindex], 0);
1302 if (!ctx->llvm_only && cinfo->rgctx_arg) {
1303 cinfo->rgctx_arg_pindex = pindex;
1304 param_types [pindex] = ctx->module->ptr_type;
1307 if (cinfo->imt_arg) {
1308 cinfo->imt_arg_pindex = pindex;
1309 param_types [pindex] = ctx->module->ptr_type;
1313 /* Compute the index in the LLVM signature where the vret arg needs to be passed */
1314 vret_arg_pindex = pindex;
1315 if (cinfo->vret_arg_index == 1) {
1316 /* Add the slots consumed by the first argument */
1317 LLVMArgInfo *ainfo = &cinfo->args [0];
1318 switch (ainfo->storage) {
1319 case LLVMArgVtypeInReg:
1320 for (j = 0; j < 2; ++j) {
1321 if (ainfo->pair_storage [j] == LLVMArgInIReg)
1330 cinfo->vret_arg_pindex = vret_arg_pindex;
1333 if (vretaddr && vret_arg_pindex == pindex)
1334 param_types [pindex ++] = IntPtrType ();
1336 cinfo->this_arg_pindex = pindex;
1337 param_types [pindex ++] = ThisType ();
1338 cinfo->args [0].pindex = cinfo->this_arg_pindex;
1340 if (vretaddr && vret_arg_pindex == pindex)
1341 param_types [pindex ++] = IntPtrType ();
1342 for (i = 0; i < sig->param_count; ++i) {
1343 LLVMArgInfo *ainfo = &cinfo->args [i + sig->hasthis];
1345 if (vretaddr && vret_arg_pindex == pindex)
1346 param_types [pindex ++] = IntPtrType ();
1347 ainfo->pindex = pindex;
1349 switch (ainfo->storage) {
1350 case LLVMArgVtypeInReg:
1351 for (j = 0; j < 2; ++j) {
1352 switch (ainfo->pair_storage [j]) {
1354 param_types [pindex ++] = LLVMIntType (sizeof (gpointer) * 8);
1359 g_assert_not_reached ();
1363 case LLVMArgVtypeByVal:
1364 param_types [pindex] = type_to_llvm_arg_type (ctx, ainfo->type);
1365 CHECK_FAILURE (ctx);
1366 param_types [pindex] = LLVMPointerType (param_types [pindex], 0);
1369 case LLVMArgAsIArgs:
1370 param_types [pindex] = LLVMArrayType (IntPtrType (), ainfo->nslots);
1373 case LLVMArgVtypeByRef:
1374 case LLVMArgScalarByRef:
1375 param_types [pindex] = type_to_llvm_arg_type (ctx, ainfo->type);
1376 CHECK_FAILURE (ctx);
1377 param_types [pindex] = LLVMPointerType (param_types [pindex], 0);
1380 case LLVMArgAsFpArgs: {
1383 /* Emit dummy fp arguments if needed so the rest is passed on the stack */
1384 for (j = 0; j < ainfo->ndummy_fpargs; ++j)
1385 param_types [pindex ++] = LLVMDoubleType ();
1386 for (j = 0; j < ainfo->nslots; ++j)
1387 param_types [pindex ++] = ainfo->esize == 8 ? LLVMDoubleType () : LLVMFloatType ();
1390 case LLVMArgVtypeAsScalar:
1391 g_assert_not_reached ();
1393 case LLVMArgGsharedvtFixed:
1394 case LLVMArgGsharedvtFixedVtype:
1395 param_types [pindex ++] = LLVMPointerType (type_to_llvm_arg_type (ctx, ainfo->type), 0);
1397 case LLVMArgGsharedvtVariable:
1398 param_types [pindex ++] = LLVMPointerType (IntPtrType (), 0);
1401 param_types [pindex ++] = type_to_llvm_arg_type (ctx, ainfo->type);
1405 if (vretaddr && vret_arg_pindex == pindex)
1406 param_types [pindex ++] = IntPtrType ();
1407 if (ctx->llvm_only && cinfo->rgctx_arg) {
1408 /* Pass the rgctx as the last argument */
1409 cinfo->rgctx_arg_pindex = pindex;
1410 param_types [pindex] = ctx->module->ptr_type;
1414 CHECK_FAILURE (ctx);
1416 res = LLVMFunctionType (ret_type, param_types, pindex, FALSE);
1417 g_free (param_types);
1422 g_free (param_types);
1428 sig_to_llvm_sig (EmitContext *ctx, MonoMethodSignature *sig)
1430 return sig_to_llvm_sig_full (ctx, sig, NULL);
1434 * LLVMFunctionType1:
1436 * Create an LLVM function type from the arguments.
1438 static G_GNUC_UNUSED LLVMTypeRef
1439 LLVMFunctionType0 (LLVMTypeRef ReturnType,
1442 return LLVMFunctionType (ReturnType, NULL, 0, IsVarArg);
1446 * LLVMFunctionType1:
1448 * Create an LLVM function type from the arguments.
1450 static G_GNUC_UNUSED LLVMTypeRef
1451 LLVMFunctionType1 (LLVMTypeRef ReturnType,
1452 LLVMTypeRef ParamType1,
1455 LLVMTypeRef param_types [1];
1457 param_types [0] = ParamType1;
1459 return LLVMFunctionType (ReturnType, param_types, 1, IsVarArg);
1463 * LLVMFunctionType2:
1465 * Create an LLVM function type from the arguments.
1467 static G_GNUC_UNUSED LLVMTypeRef
1468 LLVMFunctionType2 (LLVMTypeRef ReturnType,
1469 LLVMTypeRef ParamType1,
1470 LLVMTypeRef ParamType2,
1473 LLVMTypeRef param_types [2];
1475 param_types [0] = ParamType1;
1476 param_types [1] = ParamType2;
1478 return LLVMFunctionType (ReturnType, param_types, 2, IsVarArg);
1482 * LLVMFunctionType3:
1484 * Create an LLVM function type from the arguments.
1486 static G_GNUC_UNUSED LLVMTypeRef
1487 LLVMFunctionType3 (LLVMTypeRef ReturnType,
1488 LLVMTypeRef ParamType1,
1489 LLVMTypeRef ParamType2,
1490 LLVMTypeRef ParamType3,
1493 LLVMTypeRef param_types [3];
1495 param_types [0] = ParamType1;
1496 param_types [1] = ParamType2;
1497 param_types [2] = ParamType3;
1499 return LLVMFunctionType (ReturnType, param_types, 3, IsVarArg);
1502 static G_GNUC_UNUSED LLVMTypeRef
1503 LLVMFunctionType5 (LLVMTypeRef ReturnType,
1504 LLVMTypeRef ParamType1,
1505 LLVMTypeRef ParamType2,
1506 LLVMTypeRef ParamType3,
1507 LLVMTypeRef ParamType4,
1508 LLVMTypeRef ParamType5,
1511 LLVMTypeRef param_types [5];
1513 param_types [0] = ParamType1;
1514 param_types [1] = ParamType2;
1515 param_types [2] = ParamType3;
1516 param_types [3] = ParamType4;
1517 param_types [4] = ParamType5;
1519 return LLVMFunctionType (ReturnType, param_types, 5, IsVarArg);
1525 * Create an LLVM builder and remember it so it can be freed later.
1527 static LLVMBuilderRef
1528 create_builder (EmitContext *ctx)
1530 LLVMBuilderRef builder = LLVMCreateBuilder ();
1532 ctx->builders = g_slist_prepend_mempool (ctx->cfg->mempool, ctx->builders, builder);
1538 get_aotconst_name (MonoJumpInfoType type, gconstpointer data, int got_offset)
1543 case MONO_PATCH_INFO_INTERNAL_METHOD:
1544 name = g_strdup_printf ("jit_icall_%s", data);
1546 case MONO_PATCH_INFO_RGCTX_SLOT_INDEX: {
1547 MonoJumpInfoRgctxEntry *entry = (MonoJumpInfoRgctxEntry*)data;
1548 name = g_strdup_printf ("RGCTX_SLOT_INDEX_%s", mono_rgctx_info_type_to_str (entry->info_type));
1552 name = g_strdup_printf ("%s_%d", mono_ji_type_to_string (type), got_offset);
1560 get_aotconst_typed (EmitContext *ctx, MonoJumpInfoType type, gconstpointer data, LLVMTypeRef llvm_type)
1564 LLVMValueRef indexes [2];
1566 LLVMValueRef got_entry_addr, load;
1567 LLVMBuilderRef builder = ctx->builder;
1572 ji = g_new0 (MonoJumpInfo, 1);
1574 ji->data.target = data;
1576 ji = mono_aot_patch_info_dup (ji);
1578 ji->next = cfg->patch_info;
1579 cfg->patch_info = ji;
1581 got_offset = mono_aot_get_got_offset (cfg->patch_info);
1582 ctx->module->max_got_offset = MAX (ctx->module->max_got_offset, got_offset);
1584 * If the got slot is shared, it means its initialized when the aot image is loaded, so we don't need to
1585 * explicitly initialize it.
1587 if (!mono_aot_is_shared_got_offset (got_offset)) {
1588 //mono_print_ji (ji);
1590 ctx->has_got_access = TRUE;
1593 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
1594 indexes [1] = LLVMConstInt (LLVMInt32Type (), (gssize)got_offset, FALSE);
1595 got_entry_addr = LLVMBuildGEP (builder, ctx->module->got_var, indexes, 2, "");
1597 name = get_aotconst_name (type, data, got_offset);
1599 load = convert (ctx, LLVMBuildLoad (builder, got_entry_addr, ""), llvm_type);
1600 LLVMSetValueName (load, name ? name : "");
1602 load = LLVMBuildLoad (builder, got_entry_addr, name ? name : "");
1605 //set_invariant_load_flag (load);
1611 get_aotconst (EmitContext *ctx, MonoJumpInfoType type, gconstpointer data)
1613 return get_aotconst_typed (ctx, type, data, NULL);
1617 get_callee (EmitContext *ctx, LLVMTypeRef llvm_sig, MonoJumpInfoType type, gconstpointer data)
1619 LLVMValueRef callee;
1621 if (ctx->llvm_only) {
1622 callee_name = mono_aot_get_direct_call_symbol (type, data);
1624 /* Directly callable */
1626 callee = (LLVMValueRef)g_hash_table_lookup (ctx->module->direct_callables, callee_name);
1628 callee = LLVMAddFunction (ctx->lmodule, callee_name, llvm_sig);
1630 LLVMSetVisibility (callee, LLVMHiddenVisibility);
1632 g_hash_table_insert (ctx->module->direct_callables, (char*)callee_name, callee);
1634 g_free (callee_name);
1640 * Calls are made through the GOT.
1642 return get_aotconst_typed (ctx, type, data, LLVMPointerType (llvm_sig, 0));
1644 MonoJumpInfo *ji = NULL;
1646 callee_name = mono_aot_get_plt_symbol (type, data);
1650 if (ctx->cfg->compile_aot)
1651 /* Add a patch so referenced wrappers can be compiled in full aot mode */
1652 mono_add_patch_info (ctx->cfg, 0, type, data);
1655 callee = (LLVMValueRef)g_hash_table_lookup (ctx->module->plt_entries, callee_name);
1657 callee = LLVMAddFunction (ctx->lmodule, callee_name, llvm_sig);
1659 LLVMSetVisibility (callee, LLVMHiddenVisibility);
1661 g_hash_table_insert (ctx->module->plt_entries, (char*)callee_name, callee);
1664 if (ctx->cfg->compile_aot) {
1665 ji = g_new0 (MonoJumpInfo, 1);
1667 ji->data.target = data;
1669 g_hash_table_insert (ctx->module->plt_entries_ji, ji, callee);
1677 get_handler_clause (MonoCompile *cfg, MonoBasicBlock *bb)
1679 MonoMethodHeader *header = cfg->header;
1680 MonoExceptionClause *clause;
1684 if (bb->region != -1 && MONO_BBLOCK_IS_IN_REGION (bb, MONO_REGION_TRY))
1685 return (bb->region >> 8) - 1;
1688 for (i = 0; i < header->num_clauses; ++i) {
1689 clause = &header->clauses [i];
1691 if (MONO_OFFSET_IN_CLAUSE (clause, bb->real_offset) && clause->flags == MONO_EXCEPTION_CLAUSE_NONE)
1698 static MonoExceptionClause *
1699 get_most_deep_clause (MonoCompile *cfg, EmitContext *ctx, MonoBasicBlock *bb)
1701 // Since they're sorted by nesting we just need
1702 // the first one that the bb is a member of
1703 MonoExceptionClause *last = NULL;
1705 for (int i = 0; i < cfg->header->num_clauses; i++) {
1706 MonoExceptionClause *curr = &cfg->header->clauses [i];
1708 if (MONO_OFFSET_IN_CLAUSE (curr, bb->real_offset))
1711 if (MONO_OFFSET_IN_CLAUSE (curr, bb->real_offset)) {
1712 if (last && CLAUSE_END(last) > CLAUSE_END(curr))
1726 set_metadata_flag (LLVMValueRef v, const char *flag_name)
1728 LLVMValueRef md_arg;
1731 md_kind = LLVMGetMDKindID (flag_name, strlen (flag_name));
1732 md_arg = LLVMMDString ("mono", 4);
1733 LLVMSetMetadata (v, md_kind, LLVMMDNode (&md_arg, 1));
1737 set_invariant_load_flag (LLVMValueRef v)
1739 LLVMValueRef md_arg;
1741 const char *flag_name;
1743 // FIXME: Cache this
1744 flag_name = "invariant.load";
1745 md_kind = LLVMGetMDKindID (flag_name, strlen (flag_name));
1746 md_arg = LLVMMDString ("<index>", strlen ("<index>"));
1747 LLVMSetMetadata (v, md_kind, LLVMMDNode (&md_arg, 1));
1753 * Emit an LLVM call or invoke instruction depending on whenever the call is inside
1757 emit_call (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, LLVMValueRef callee, LLVMValueRef *args, int pindex)
1759 MonoCompile *cfg = ctx->cfg;
1760 LLVMValueRef lcall = NULL;
1761 LLVMBuilderRef builder = *builder_ref;
1762 MonoExceptionClause *clause;
1764 if (ctx->llvm_only) {
1765 clause = get_most_deep_clause (cfg, ctx, bb);
1768 g_assert (clause->flags == MONO_EXCEPTION_CLAUSE_NONE || clause->flags == MONO_EXCEPTION_CLAUSE_FINALLY);
1771 * Have to use an invoke instead of a call, branching to the
1772 * handler bblock of the clause containing this bblock.
1774 intptr_t key = CLAUSE_END(clause);
1776 LLVMBasicBlockRef lpad_bb = (LLVMBasicBlockRef)g_hash_table_lookup (ctx->exc_meta, (gconstpointer)key);
1778 // FIXME: Find the one that has the lowest end bound for the right start address
1779 // FIXME: Finally + nesting
1782 LLVMBasicBlockRef noex_bb = gen_bb (ctx, "CALL_NOEX_BB");
1785 lcall = LLVMBuildInvoke (builder, callee, args, pindex, noex_bb, lpad_bb, "");
1787 builder = ctx->builder = create_builder (ctx);
1788 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
1790 ctx->bblocks [bb->block_num].end_bblock = noex_bb;
1794 int clause_index = get_handler_clause (cfg, bb);
1796 if (clause_index != -1) {
1797 MonoMethodHeader *header = cfg->header;
1798 MonoExceptionClause *ec = &header->clauses [clause_index];
1799 MonoBasicBlock *tblock;
1800 LLVMBasicBlockRef ex_bb, noex_bb;
1803 * Have to use an invoke instead of a call, branching to the
1804 * handler bblock of the clause containing this bblock.
1807 g_assert (ec->flags == MONO_EXCEPTION_CLAUSE_NONE || ec->flags == MONO_EXCEPTION_CLAUSE_FINALLY);
1809 tblock = cfg->cil_offset_to_bb [ec->handler_offset];
1812 ctx->bblocks [tblock->block_num].invoke_target = TRUE;
1814 ex_bb = get_bb (ctx, tblock);
1816 noex_bb = gen_bb (ctx, "NOEX_BB");
1819 lcall = LLVMBuildInvoke (builder, callee, args, pindex, noex_bb, ex_bb, "");
1821 builder = ctx->builder = create_builder (ctx);
1822 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
1824 ctx->bblocks [bb->block_num].end_bblock = noex_bb;
1829 lcall = LLVMBuildCall (builder, callee, args, pindex, "");
1830 ctx->builder = builder;
1834 *builder_ref = ctx->builder;
1840 emit_load_general (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, int size, LLVMValueRef addr, const char *name, gboolean is_faulting, BarrierKind barrier)
1842 const char *intrins_name;
1843 LLVMValueRef args [16], res;
1844 LLVMTypeRef addr_type;
1846 if (is_faulting && bb->region != -1 && !ctx->cfg->llvm_only) {
1847 LLVMAtomicOrdering ordering;
1850 case LLVM_BARRIER_NONE:
1851 ordering = LLVMAtomicOrderingNotAtomic;
1853 case LLVM_BARRIER_ACQ:
1854 ordering = LLVMAtomicOrderingAcquire;
1856 case LLVM_BARRIER_SEQ:
1857 ordering = LLVMAtomicOrderingSequentiallyConsistent;
1860 g_assert_not_reached ();
1865 * We handle loads which can fault by calling a mono specific intrinsic
1866 * using an invoke, so they are handled properly inside try blocks.
1867 * We can't use this outside clauses, since LLVM optimizes intrinsics which
1868 * are marked with IntrReadArgMem.
1872 intrins_name = "llvm.mono.load.i8.p0i8";
1875 intrins_name = "llvm.mono.load.i16.p0i16";
1878 intrins_name = "llvm.mono.load.i32.p0i32";
1881 intrins_name = "llvm.mono.load.i64.p0i64";
1884 g_assert_not_reached ();
1887 addr_type = LLVMTypeOf (addr);
1888 if (addr_type == LLVMPointerType (LLVMDoubleType (), 0) || addr_type == LLVMPointerType (LLVMFloatType (), 0))
1889 addr = LLVMBuildBitCast (*builder_ref, addr, LLVMPointerType (LLVMIntType (size * 8), 0), "");
1892 args [1] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
1893 args [2] = LLVMConstInt (LLVMInt1Type (), TRUE, FALSE);
1894 args [3] = LLVMConstInt (LLVMInt32Type (), ordering, FALSE);
1895 res = emit_call (ctx, bb, builder_ref, LLVMGetNamedFunction (ctx->lmodule, intrins_name), args, 4);
1897 if (addr_type == LLVMPointerType (LLVMDoubleType (), 0))
1898 res = LLVMBuildBitCast (*builder_ref, res, LLVMDoubleType (), "");
1899 else if (addr_type == LLVMPointerType (LLVMFloatType (), 0))
1900 res = LLVMBuildBitCast (*builder_ref, res, LLVMFloatType (), "");
1907 * We emit volatile loads for loads which can fault, because otherwise
1908 * LLVM will generate invalid code when encountering a load from a
1911 res = mono_llvm_build_load (*builder_ref, addr, name, is_faulting, barrier);
1913 /* Mark it with a custom metadata */
1916 set_metadata_flag (res, "mono.faulting.load");
1924 emit_load (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, int size, LLVMValueRef addr, const char *name, gboolean is_faulting)
1926 return emit_load_general (ctx, bb, builder_ref, size, addr, name, is_faulting, LLVM_BARRIER_NONE);
1930 emit_store_general (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, int size, LLVMValueRef value, LLVMValueRef addr, gboolean is_faulting, BarrierKind barrier)
1932 const char *intrins_name;
1933 LLVMValueRef args [16];
1935 if (is_faulting && bb->region != -1 && !ctx->cfg->llvm_only) {
1936 LLVMAtomicOrdering ordering;
1939 case LLVM_BARRIER_NONE:
1940 ordering = LLVMAtomicOrderingNotAtomic;
1942 case LLVM_BARRIER_REL:
1943 ordering = LLVMAtomicOrderingRelease;
1945 case LLVM_BARRIER_SEQ:
1946 ordering = LLVMAtomicOrderingSequentiallyConsistent;
1949 g_assert_not_reached ();
1955 intrins_name = "llvm.mono.store.i8.p0i8";
1958 intrins_name = "llvm.mono.store.i16.p0i16";
1961 intrins_name = "llvm.mono.store.i32.p0i32";
1964 intrins_name = "llvm.mono.store.i64.p0i64";
1967 g_assert_not_reached ();
1970 if (LLVMTypeOf (value) == LLVMDoubleType () || LLVMTypeOf (value) == LLVMFloatType ()) {
1971 value = LLVMBuildBitCast (*builder_ref, value, LLVMIntType (size * 8), "");
1972 addr = LLVMBuildBitCast (*builder_ref, addr, LLVMPointerType (LLVMIntType (size * 8), 0), "");
1977 args [2] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
1978 args [3] = LLVMConstInt (LLVMInt1Type (), TRUE, FALSE);
1979 args [4] = LLVMConstInt (LLVMInt32Type (), ordering, FALSE);
1980 emit_call (ctx, bb, builder_ref, LLVMGetNamedFunction (ctx->lmodule, intrins_name), args, 5);
1982 mono_llvm_build_store (*builder_ref, value, addr, is_faulting, barrier);
1987 emit_store (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, int size, LLVMValueRef value, LLVMValueRef addr, gboolean is_faulting)
1989 emit_store_general (ctx, bb, builder_ref, size, value, addr, is_faulting, LLVM_BARRIER_NONE);
1993 * emit_cond_system_exception:
1995 * Emit code to throw the exception EXC_TYPE if the condition CMP is false.
1996 * Might set the ctx exception.
1999 emit_cond_system_exception (EmitContext *ctx, MonoBasicBlock *bb, const char *exc_type, LLVMValueRef cmp)
2001 LLVMBasicBlockRef ex_bb, ex2_bb = NULL, noex_bb;
2002 LLVMBuilderRef builder;
2003 MonoClass *exc_class;
2004 LLVMValueRef args [2];
2005 LLVMValueRef callee;
2007 ex_bb = gen_bb (ctx, "EX_BB");
2009 ex2_bb = gen_bb (ctx, "EX2_BB");
2010 noex_bb = gen_bb (ctx, "NOEX_BB");
2012 LLVMBuildCondBr (ctx->builder, cmp, ex_bb, noex_bb);
2014 exc_class = mono_class_from_name (mono_get_corlib (), "System", exc_type);
2015 g_assert (exc_class);
2017 /* Emit exception throwing code */
2018 ctx->builder = builder = create_builder (ctx);
2019 LLVMPositionBuilderAtEnd (builder, ex_bb);
2021 if (ctx->cfg->llvm_only) {
2022 static LLVMTypeRef sig;
2025 sig = LLVMFunctionType1 (LLVMVoidType (), LLVMInt32Type (), FALSE);
2026 callee = get_callee (ctx, sig, MONO_PATCH_INFO_INTERNAL_METHOD, "mono_llvm_throw_corlib_exception");
2028 LLVMBuildBr (builder, ex2_bb);
2030 ctx->builder = builder = create_builder (ctx);
2031 LLVMPositionBuilderAtEnd (ctx->builder, ex2_bb);
2033 args [0] = LLVMConstInt (LLVMInt32Type (), exc_class->type_token - MONO_TOKEN_TYPE_DEF, FALSE);
2034 emit_call (ctx, bb, &builder, callee, args, 1);
2035 LLVMBuildUnreachable (builder);
2037 ctx->builder = builder = create_builder (ctx);
2038 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
2040 ctx->bblocks [bb->block_num].end_bblock = noex_bb;
2046 callee = ctx->module->throw_corlib_exception;
2049 const char *icall_name;
2051 sig = LLVMFunctionType2 (LLVMVoidType (), LLVMInt32Type (), LLVMPointerType (LLVMInt8Type (), 0), FALSE);
2052 icall_name = "llvm_throw_corlib_exception_abs_trampoline";
2054 if (ctx->cfg->compile_aot) {
2055 callee = get_callee (ctx, sig, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
2057 callee = LLVMAddFunction (ctx->lmodule, "llvm_throw_corlib_exception_trampoline", sig);
2060 * Differences between the LLVM/non-LLVM throw corlib exception trampoline:
2061 * - On x86, LLVM generated code doesn't push the arguments
2062 * - The trampoline takes the throw address as an arguments, not a pc offset.
2064 LLVMAddGlobalMapping (ctx->module->ee, callee, resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name));
2066 mono_memory_barrier ();
2067 ctx->module->throw_corlib_exception = callee;
2071 if (IS_TARGET_X86 || IS_TARGET_AMD64)
2072 args [0] = LLVMConstInt (LLVMInt32Type (), exc_class->type_token - MONO_TOKEN_TYPE_DEF, FALSE);
2074 args [0] = LLVMConstInt (LLVMInt32Type (), exc_class->type_token, FALSE);
2077 * The LLVM mono branch contains changes so a block address can be passed as an
2078 * argument to a call.
2080 args [1] = LLVMBlockAddress (ctx->lmethod, ex_bb);
2081 emit_call (ctx, bb, &builder, callee, args, 2);
2083 LLVMBuildUnreachable (builder);
2085 ctx->builder = builder = create_builder (ctx);
2086 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
2088 ctx->bblocks [bb->block_num].end_bblock = noex_bb;
2095 * emit_args_to_vtype:
2097 * Emit code to store the vtype in the arguments args to the address ADDRESS.
2100 emit_args_to_vtype (EmitContext *ctx, LLVMBuilderRef builder, MonoType *t, LLVMValueRef address, LLVMArgInfo *ainfo, LLVMValueRef *args)
2102 int j, size, nslots;
2104 size = get_vtype_size (t);
2106 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (t))) {
2107 address = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (LLVMInt8Type (), 0), "");
2110 if (ainfo->storage == LLVMArgAsFpArgs)
2111 nslots = ainfo->nslots;
2115 for (j = 0; j < nslots; ++j) {
2116 LLVMValueRef index [2], addr, daddr;
2117 int part_size = size > sizeof (gpointer) ? sizeof (gpointer) : size;
2118 LLVMTypeRef part_type;
2120 if (ainfo->pair_storage [j] == LLVMArgNone)
2123 switch (ainfo->pair_storage [j]) {
2124 case LLVMArgInIReg: {
2125 part_type = LLVMIntType (part_size * 8);
2126 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (t))) {
2127 index [0] = LLVMConstInt (LLVMInt32Type (), j * sizeof (gpointer), FALSE);
2128 addr = LLVMBuildGEP (builder, address, index, 1, "");
2130 daddr = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (IntPtrType (), 0), "");
2131 index [0] = LLVMConstInt (LLVMInt32Type (), j, FALSE);
2132 addr = LLVMBuildGEP (builder, daddr, index, 1, "");
2134 LLVMBuildStore (builder, convert (ctx, args [j], part_type), LLVMBuildBitCast (ctx->builder, addr, LLVMPointerType (part_type, 0), ""));
2137 case LLVMArgInFPReg: {
2138 LLVMTypeRef arg_type;
2140 if (ainfo->esize == 8)
2141 arg_type = LLVMDoubleType ();
2143 arg_type = LLVMFloatType ();
2145 index [0] = LLVMConstInt (LLVMInt32Type (), j, FALSE);
2146 daddr = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (arg_type, 0), "");
2147 addr = LLVMBuildGEP (builder, daddr, index, 1, "");
2148 LLVMBuildStore (builder, args [j], addr);
2154 g_assert_not_reached ();
2157 size -= sizeof (gpointer);
2162 * emit_vtype_to_args:
2164 * Emit code to load a vtype at address ADDRESS into scalar arguments. Store the arguments
2165 * into ARGS, and the number of arguments into NARGS.
2168 emit_vtype_to_args (EmitContext *ctx, LLVMBuilderRef builder, MonoType *t, LLVMValueRef address, LLVMArgInfo *ainfo, LLVMValueRef *args, guint32 *nargs)
2171 int j, size, nslots;
2172 LLVMTypeRef arg_type;
2174 size = get_vtype_size (t);
2176 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (t)))
2177 address = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (LLVMInt8Type (), 0), "");
2179 if (ainfo->storage == LLVMArgAsFpArgs)
2180 nslots = ainfo->nslots;
2183 for (j = 0; j < nslots; ++j) {
2184 LLVMValueRef index [2], addr, daddr;
2185 int partsize = size > sizeof (gpointer) ? sizeof (gpointer) : size;
2187 if (ainfo->pair_storage [j] == LLVMArgNone)
2190 switch (ainfo->pair_storage [j]) {
2192 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (t))) {
2193 index [0] = LLVMConstInt (LLVMInt32Type (), j * sizeof (gpointer), FALSE);
2194 addr = LLVMBuildGEP (builder, address, index, 1, "");
2196 daddr = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (IntPtrType (), 0), "");
2197 index [0] = LLVMConstInt (LLVMInt32Type (), j, FALSE);
2198 addr = LLVMBuildGEP (builder, daddr, index, 1, "");
2200 args [pindex ++] = convert (ctx, LLVMBuildLoad (builder, LLVMBuildBitCast (ctx->builder, addr, LLVMPointerType (LLVMIntType (partsize * 8), 0), ""), ""), IntPtrType ());
2202 case LLVMArgInFPReg:
2203 if (ainfo->esize == 8)
2204 arg_type = LLVMDoubleType ();
2206 arg_type = LLVMFloatType ();
2207 daddr = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (arg_type, 0), "");
2208 index [0] = LLVMConstInt (LLVMInt32Type (), j, FALSE);
2209 addr = LLVMBuildGEP (builder, daddr, index, 1, "");
2210 args [pindex ++] = LLVMBuildLoad (builder, addr, "");
2215 g_assert_not_reached ();
2217 size -= sizeof (gpointer);
2224 build_alloca_llvm_type_name (EmitContext *ctx, LLVMTypeRef t, int align, const char *name)
2227 * Have to place all alloca's at the end of the entry bb, since otherwise they would
2228 * get executed every time control reaches them.
2230 LLVMPositionBuilder (ctx->alloca_builder, get_bb (ctx, ctx->cfg->bb_entry), ctx->last_alloca);
2232 ctx->last_alloca = mono_llvm_build_alloca (ctx->alloca_builder, t, NULL, align, name);
2233 return ctx->last_alloca;
2237 build_alloca_llvm_type (EmitContext *ctx, LLVMTypeRef t, int align)
2239 return build_alloca_llvm_type_name (ctx, t, align, "");
2243 build_alloca (EmitContext *ctx, MonoType *t)
2245 MonoClass *k = mono_class_from_mono_type (t);
2248 g_assert (!mini_is_gsharedvt_variable_type (t));
2250 if (MONO_CLASS_IS_SIMD (ctx->cfg, k))
2253 align = mono_class_min_align (k);
2255 /* Sometimes align is not a power of 2 */
2256 while (mono_is_power_of_two (align) == -1)
2259 return build_alloca_llvm_type (ctx, type_to_llvm_type (ctx, t), align);
2263 emit_gsharedvt_ldaddr (EmitContext *ctx, int vreg)
2267 * Compute the address of the local as gsharedvt_locals_var + gsharedvt_info_var->locals_offsets [idx].
2269 MonoCompile *cfg = ctx->cfg;
2270 LLVMBuilderRef builder = ctx->builder;
2271 LLVMValueRef offset, offset_var;
2272 LLVMValueRef info_var = ctx->values [cfg->gsharedvt_info_var->dreg];
2273 LLVMValueRef locals_var = ctx->values [cfg->gsharedvt_locals_var->dreg];
2277 g_assert (info_var);
2278 g_assert (locals_var);
2280 int idx = cfg->gsharedvt_vreg_to_idx [vreg] - 1;
2282 offset = LLVMConstInt (LLVMInt32Type (), MONO_STRUCT_OFFSET (MonoGSharedVtMethodRuntimeInfo, entries) + (idx * sizeof (gpointer)), FALSE);
2283 ptr = LLVMBuildAdd (builder, convert (ctx, info_var, IntPtrType ()), convert (ctx, offset, IntPtrType ()), "");
2285 name = g_strdup_printf ("gsharedvt_local_%d_offset", vreg);
2286 offset_var = LLVMBuildLoad (builder, convert (ctx, ptr, LLVMPointerType (LLVMInt32Type (), 0)), name);
2288 return LLVMBuildAdd (builder, convert (ctx, locals_var, IntPtrType ()), convert (ctx, offset_var, IntPtrType ()), "");
2292 * Put the global into the 'llvm.used' array to prevent it from being optimized away.
2295 mark_as_used (MonoLLVMModule *module, LLVMValueRef global)
2298 module->used = g_ptr_array_sized_new (16);
2299 g_ptr_array_add (module->used, global);
2303 emit_llvm_used (MonoLLVMModule *module)
2305 LLVMModuleRef lmodule = module->lmodule;
2306 LLVMTypeRef used_type;
2307 LLVMValueRef used, *used_elem;
2313 used_type = LLVMArrayType (LLVMPointerType (LLVMInt8Type (), 0), module->used->len);
2314 used = LLVMAddGlobal (lmodule, used_type, "llvm.used");
2315 used_elem = g_new0 (LLVMValueRef, module->used->len);
2316 for (i = 0; i < module->used->len; ++i)
2317 used_elem [i] = LLVMConstBitCast ((LLVMValueRef)g_ptr_array_index (module->used, i), LLVMPointerType (LLVMInt8Type (), 0));
2318 LLVMSetInitializer (used, LLVMConstArray (LLVMPointerType (LLVMInt8Type (), 0), used_elem, module->used->len));
2319 LLVMSetLinkage (used, LLVMAppendingLinkage);
2320 LLVMSetSection (used, "llvm.metadata");
2326 * Emit a function mapping method indexes to their code
2329 emit_get_method (MonoLLVMModule *module)
2331 LLVMModuleRef lmodule = module->lmodule;
2332 LLVMValueRef func, switch_ins, m;
2333 LLVMBasicBlockRef entry_bb, fail_bb, bb, code_start_bb, code_end_bb;
2334 LLVMBasicBlockRef *bbs;
2336 LLVMBuilderRef builder;
2341 * Emit a switch statement. Emitting a table of function addresses is smaller/faster,
2342 * but generating code seems safer.
2344 rtype = LLVMPointerType (LLVMInt8Type (), 0);
2345 func = LLVMAddFunction (lmodule, module->get_method_symbol, LLVMFunctionType1 (rtype, LLVMInt32Type (), FALSE));
2346 LLVMSetLinkage (func, LLVMExternalLinkage);
2347 LLVMSetVisibility (func, LLVMHiddenVisibility);
2348 LLVMAddFunctionAttr (func, LLVMNoUnwindAttribute);
2349 module->get_method = func;
2351 entry_bb = LLVMAppendBasicBlock (func, "ENTRY");
2354 * Return llvm_code_start/llvm_code_end when called with -1/-2.
2355 * Hopefully, the toolchain doesn't reorder these functions. If it does,
2356 * then we will have to find another solution.
2359 name = g_strdup_printf ("BB_CODE_START");
2360 code_start_bb = LLVMAppendBasicBlock (func, name);
2362 builder = LLVMCreateBuilder ();
2363 LLVMPositionBuilderAtEnd (builder, code_start_bb);
2364 LLVMBuildRet (builder, LLVMBuildBitCast (builder, module->code_start, rtype, ""));
2366 name = g_strdup_printf ("BB_CODE_END");
2367 code_end_bb = LLVMAppendBasicBlock (func, name);
2369 builder = LLVMCreateBuilder ();
2370 LLVMPositionBuilderAtEnd (builder, code_end_bb);
2371 LLVMBuildRet (builder, LLVMBuildBitCast (builder, module->code_end, rtype, ""));
2373 bbs = g_new0 (LLVMBasicBlockRef, module->max_method_idx + 1);
2374 for (i = 0; i < module->max_method_idx + 1; ++i) {
2375 name = g_strdup_printf ("BB_%d", i);
2376 bb = LLVMAppendBasicBlock (func, name);
2380 builder = LLVMCreateBuilder ();
2381 LLVMPositionBuilderAtEnd (builder, bb);
2383 m = (LLVMValueRef)g_hash_table_lookup (module->idx_to_lmethod, GINT_TO_POINTER (i));
2385 LLVMBuildRet (builder, LLVMBuildBitCast (builder, m, rtype, ""));
2387 LLVMBuildRet (builder, LLVMConstNull (rtype));
2390 fail_bb = LLVMAppendBasicBlock (func, "FAIL");
2391 builder = LLVMCreateBuilder ();
2392 LLVMPositionBuilderAtEnd (builder, fail_bb);
2393 LLVMBuildRet (builder, LLVMConstNull (rtype));
2395 builder = LLVMCreateBuilder ();
2396 LLVMPositionBuilderAtEnd (builder, entry_bb);
2398 switch_ins = LLVMBuildSwitch (builder, LLVMGetParam (func, 0), fail_bb, 0);
2399 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), -1, FALSE), code_start_bb);
2400 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), -2, FALSE), code_end_bb);
2401 for (i = 0; i < module->max_method_idx + 1; ++i) {
2402 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), i, FALSE), bbs [i]);
2405 mark_as_used (module, func);
2409 * emit_get_unbox_tramp:
2411 * Emit a function mapping method indexes to their unbox trampoline
2414 emit_get_unbox_tramp (MonoLLVMModule *module)
2416 LLVMModuleRef lmodule = module->lmodule;
2417 LLVMValueRef func, switch_ins, m;
2418 LLVMBasicBlockRef entry_bb, fail_bb, bb;
2419 LLVMBasicBlockRef *bbs;
2421 LLVMBuilderRef builder;
2425 /* Similar to emit_get_method () */
2427 rtype = LLVMPointerType (LLVMInt8Type (), 0);
2428 func = LLVMAddFunction (lmodule, module->get_unbox_tramp_symbol, LLVMFunctionType1 (rtype, LLVMInt32Type (), FALSE));
2429 LLVMSetLinkage (func, LLVMExternalLinkage);
2430 LLVMSetVisibility (func, LLVMHiddenVisibility);
2431 LLVMAddFunctionAttr (func, LLVMNoUnwindAttribute);
2432 module->get_unbox_tramp = func;
2434 entry_bb = LLVMAppendBasicBlock (func, "ENTRY");
2436 bbs = g_new0 (LLVMBasicBlockRef, module->max_method_idx + 1);
2437 for (i = 0; i < module->max_method_idx + 1; ++i) {
2438 m = (LLVMValueRef)g_hash_table_lookup (module->idx_to_unbox_tramp, GINT_TO_POINTER (i));
2442 name = g_strdup_printf ("BB_%d", i);
2443 bb = LLVMAppendBasicBlock (func, name);
2447 builder = LLVMCreateBuilder ();
2448 LLVMPositionBuilderAtEnd (builder, bb);
2450 LLVMBuildRet (builder, LLVMBuildBitCast (builder, m, rtype, ""));
2453 fail_bb = LLVMAppendBasicBlock (func, "FAIL");
2454 builder = LLVMCreateBuilder ();
2455 LLVMPositionBuilderAtEnd (builder, fail_bb);
2456 LLVMBuildRet (builder, LLVMConstNull (rtype));
2458 builder = LLVMCreateBuilder ();
2459 LLVMPositionBuilderAtEnd (builder, entry_bb);
2461 switch_ins = LLVMBuildSwitch (builder, LLVMGetParam (func, 0), fail_bb, 0);
2462 for (i = 0; i < module->max_method_idx + 1; ++i) {
2463 m = (LLVMValueRef)g_hash_table_lookup (module->idx_to_unbox_tramp, GINT_TO_POINTER (i));
2467 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), i, FALSE), bbs [i]);
2470 mark_as_used (module, func);
2473 /* Add a function to mark the beginning of LLVM code */
2475 emit_llvm_code_start (MonoLLVMModule *module)
2477 LLVMModuleRef lmodule = module->lmodule;
2479 LLVMBasicBlockRef entry_bb;
2480 LLVMBuilderRef builder;
2482 func = LLVMAddFunction (lmodule, "llvm_code_start", LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE));
2483 LLVMSetLinkage (func, LLVMInternalLinkage);
2484 LLVMAddFunctionAttr (func, LLVMNoUnwindAttribute);
2485 module->code_start = func;
2486 entry_bb = LLVMAppendBasicBlock (func, "ENTRY");
2487 builder = LLVMCreateBuilder ();
2488 LLVMPositionBuilderAtEnd (builder, entry_bb);
2489 LLVMBuildRetVoid (builder);
2493 emit_init_icall_wrapper (MonoLLVMModule *module, const char *name, const char *icall_name, int subtype)
2495 LLVMModuleRef lmodule = module->lmodule;
2496 LLVMValueRef func, indexes [2], got_entry_addr, args [16], callee;
2497 LLVMBasicBlockRef entry_bb;
2498 LLVMBuilderRef builder;
2505 func = LLVMAddFunction (lmodule, name, LLVMFunctionType1 (LLVMVoidType (), LLVMInt32Type (), FALSE));
2506 sig = LLVMFunctionType2 (LLVMVoidType (), IntPtrType (), LLVMInt32Type (), FALSE);
2511 func = LLVMAddFunction (lmodule, name, LLVMFunctionType2 (LLVMVoidType (), LLVMInt32Type (), IntPtrType (), FALSE));
2512 sig = LLVMFunctionType3 (LLVMVoidType (), IntPtrType (), LLVMInt32Type (), IntPtrType (), FALSE);
2515 func = LLVMAddFunction (lmodule, name, LLVMFunctionType2 (LLVMVoidType (), LLVMInt32Type (), ObjRefType (), FALSE));
2516 sig = LLVMFunctionType3 (LLVMVoidType (), IntPtrType (), LLVMInt32Type (), ObjRefType (), FALSE);
2519 g_assert_not_reached ();
2521 LLVMSetLinkage (func, LLVMInternalLinkage);
2522 LLVMAddFunctionAttr (func, LLVMNoInlineAttribute);
2523 mono_llvm_set_preserveall_cc (func);
2524 entry_bb = LLVMAppendBasicBlock (func, "ENTRY");
2525 builder = LLVMCreateBuilder ();
2526 LLVMPositionBuilderAtEnd (builder, entry_bb);
2529 ji = g_new0 (MonoJumpInfo, 1);
2530 ji->type = MONO_PATCH_INFO_AOT_MODULE;
2531 ji = mono_aot_patch_info_dup (ji);
2532 got_offset = mono_aot_get_got_offset (ji);
2533 module->max_got_offset = MAX (module->max_got_offset, got_offset);
2534 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
2535 indexes [1] = LLVMConstInt (LLVMInt32Type (), got_offset, FALSE);
2536 got_entry_addr = LLVMBuildGEP (builder, module->got_var, indexes, 2, "");
2537 args [0] = LLVMBuildPtrToInt (builder, LLVMBuildLoad (builder, got_entry_addr, ""), IntPtrType (), "");
2538 args [1] = LLVMGetParam (func, 0);
2540 args [2] = LLVMGetParam (func, 1);
2542 ji = g_new0 (MonoJumpInfo, 1);
2543 ji->type = MONO_PATCH_INFO_INTERNAL_METHOD;
2544 ji->data.name = icall_name;
2545 ji = mono_aot_patch_info_dup (ji);
2546 got_offset = mono_aot_get_got_offset (ji);
2547 module->max_got_offset = MAX (module->max_got_offset, got_offset);
2548 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
2549 indexes [1] = LLVMConstInt (LLVMInt32Type (), got_offset, FALSE);
2550 got_entry_addr = LLVMBuildGEP (builder, module->got_var, indexes, 2, "");
2551 callee = LLVMBuildLoad (builder, got_entry_addr, "");
2552 callee = LLVMBuildBitCast (builder, callee, LLVMPointerType (sig, 0), "");
2553 LLVMBuildCall (builder, callee, args, LLVMCountParamTypes (sig), "");
2555 // Set the inited flag
2556 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
2557 indexes [1] = LLVMGetParam (func, 0);
2558 LLVMBuildStore (builder, LLVMConstInt (LLVMInt8Type (), 1, FALSE), LLVMBuildGEP (builder, module->inited_var, indexes, 2, ""));
2560 LLVMBuildRetVoid (builder);
2562 LLVMVerifyFunction(func, LLVMAbortProcessAction);
2567 * Emit wrappers around the C icalls used to initialize llvm methods, to
2568 * make the calling code smaller and to enable usage of the llvm
2569 * PreserveAll calling convention.
2572 emit_init_icall_wrappers (MonoLLVMModule *module)
2574 module->init_method = emit_init_icall_wrapper (module, "init_method", "mono_aot_init_llvm_method", 0);
2575 module->init_method_gshared_mrgctx = emit_init_icall_wrapper (module, "init_method_gshared_mrgctx", "mono_aot_init_gshared_method_mrgctx", 1);
2576 module->init_method_gshared_this = emit_init_icall_wrapper (module, "init_method_gshared_this", "mono_aot_init_gshared_method_this", 2);
2577 module->init_method_gshared_vtable = emit_init_icall_wrapper (module, "init_method_gshared_vtable", "mono_aot_init_gshared_method_vtable", 3);
2581 emit_llvm_code_end (MonoLLVMModule *module)
2583 LLVMModuleRef lmodule = module->lmodule;
2585 LLVMBasicBlockRef entry_bb;
2586 LLVMBuilderRef builder;
2588 func = LLVMAddFunction (lmodule, "llvm_code_end", LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE));
2589 LLVMSetLinkage (func, LLVMInternalLinkage);
2590 LLVMAddFunctionAttr (func, LLVMNoUnwindAttribute);
2591 module->code_end = func;
2592 entry_bb = LLVMAppendBasicBlock (func, "ENTRY");
2593 builder = LLVMCreateBuilder ();
2594 LLVMPositionBuilderAtEnd (builder, entry_bb);
2595 LLVMBuildRetVoid (builder);
2599 emit_div_check (EmitContext *ctx, LLVMBuilderRef builder, MonoBasicBlock *bb, MonoInst *ins, LLVMValueRef lhs, LLVMValueRef rhs)
2601 gboolean need_div_check = ctx->cfg->backend->need_div_check;
2604 /* LLVM doesn't know that these can throw an exception since they are not called through an intrinsic */
2605 need_div_check = TRUE;
2607 if (!need_div_check)
2610 switch (ins->opcode) {
2623 case OP_IDIV_UN_IMM:
2624 case OP_LDIV_UN_IMM:
2625 case OP_IREM_UN_IMM:
2626 case OP_LREM_UN_IMM: {
2628 gboolean is_signed = (ins->opcode == OP_IDIV || ins->opcode == OP_LDIV || ins->opcode == OP_IREM || ins->opcode == OP_LREM ||
2629 ins->opcode == OP_IDIV_IMM || ins->opcode == OP_LDIV_IMM || ins->opcode == OP_IREM_IMM || ins->opcode == OP_LREM_IMM);
2631 cmp = LLVMBuildICmp (builder, LLVMIntEQ, rhs, LLVMConstInt (LLVMTypeOf (rhs), 0, FALSE), "");
2632 emit_cond_system_exception (ctx, bb, "DivideByZeroException", cmp);
2633 CHECK_FAILURE (ctx);
2634 builder = ctx->builder;
2636 /* b == -1 && a == 0x80000000 */
2638 LLVMValueRef c = (LLVMTypeOf (lhs) == LLVMInt32Type ()) ? LLVMConstInt (LLVMTypeOf (lhs), 0x80000000, FALSE) : LLVMConstInt (LLVMTypeOf (lhs), 0x8000000000000000LL, FALSE);
2639 LLVMValueRef cond1 = LLVMBuildICmp (builder, LLVMIntEQ, rhs, LLVMConstInt (LLVMTypeOf (rhs), -1, FALSE), "");
2640 LLVMValueRef cond2 = LLVMBuildICmp (builder, LLVMIntEQ, lhs, c, "");
2642 cmp = LLVMBuildICmp (builder, LLVMIntEQ, LLVMBuildAnd (builder, cond1, cond2, ""), LLVMConstInt (LLVMInt1Type (), 1, FALSE), "");
2643 emit_cond_system_exception (ctx, bb, "OverflowException", cmp);
2644 CHECK_FAILURE (ctx);
2645 builder = ctx->builder;
2660 * Emit code to initialize the GOT slots used by the method.
2663 emit_init_method (EmitContext *ctx)
2665 LLVMValueRef indexes [16], args [16], callee;
2666 LLVMValueRef inited_var, cmp, call;
2667 LLVMBasicBlockRef inited_bb, notinited_bb;
2668 LLVMBuilderRef builder = ctx->builder;
2669 MonoCompile *cfg = ctx->cfg;
2671 ctx->module->max_inited_idx = MAX (ctx->module->max_inited_idx, cfg->method_index);
2673 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
2674 indexes [1] = LLVMConstInt (LLVMInt32Type (), cfg->method_index, FALSE);
2675 inited_var = LLVMBuildLoad (builder, LLVMBuildGEP (builder, ctx->module->inited_var, indexes, 2, ""), "is_inited");
2677 args [0] = inited_var;
2678 args [1] = LLVMConstInt (LLVMInt8Type (), 1, FALSE);
2679 inited_var = LLVMBuildCall (ctx->builder, LLVMGetNamedFunction (ctx->lmodule, "llvm.expect.i8"), args, 2, "");
2681 cmp = LLVMBuildICmp (builder, LLVMIntEQ, inited_var, LLVMConstInt (LLVMTypeOf (inited_var), 0, FALSE), "");
2683 inited_bb = ctx->inited_bb;
2684 notinited_bb = gen_bb (ctx, "NOTINITED_BB");
2686 LLVMBuildCondBr (ctx->builder, cmp, notinited_bb, inited_bb);
2688 builder = ctx->builder = create_builder (ctx);
2689 LLVMPositionBuilderAtEnd (ctx->builder, notinited_bb);
2692 if (ctx->rgctx_arg && cfg->method->is_inflated && mono_method_get_context (cfg->method)->method_inst) {
2693 args [0] = LLVMConstInt (LLVMInt32Type (), cfg->method_index, 0);
2694 args [1] = convert (ctx, ctx->rgctx_arg, IntPtrType ());
2695 callee = ctx->module->init_method_gshared_mrgctx;
2696 call = LLVMBuildCall (builder, callee, args, 2, "");
2697 } else if (ctx->rgctx_arg) {
2698 /* A vtable is passed as the rgctx argument */
2699 args [0] = LLVMConstInt (LLVMInt32Type (), cfg->method_index, 0);
2700 args [1] = convert (ctx, ctx->rgctx_arg, IntPtrType ());
2701 callee = ctx->module->init_method_gshared_vtable;
2702 call = LLVMBuildCall (builder, callee, args, 2, "");
2703 } else if (cfg->gshared) {
2704 args [0] = LLVMConstInt (LLVMInt32Type (), cfg->method_index, 0);
2705 args [1] = convert (ctx, ctx->this_arg, ObjRefType ());
2706 callee = ctx->module->init_method_gshared_this;
2707 call = LLVMBuildCall (builder, callee, args, 2, "");
2709 args [0] = LLVMConstInt (LLVMInt32Type (), cfg->method_index, 0);
2710 callee = ctx->module->init_method;
2711 call = LLVMBuildCall (builder, callee, args, 1, "");
2715 * This enables llvm to keep arguments in their original registers/
2716 * scratch registers, since the call will not clobber them.
2718 mono_llvm_set_call_preserveall_cc (call);
2720 LLVMBuildBr (builder, inited_bb);
2721 ctx->bblocks [cfg->bb_entry->block_num].end_bblock = inited_bb;
2723 builder = ctx->builder = create_builder (ctx);
2724 LLVMPositionBuilderAtEnd (ctx->builder, inited_bb);
2728 emit_unbox_tramp (EmitContext *ctx, const char *method_name, LLVMTypeRef method_type, LLVMValueRef method, int method_index)
2731 * Emit unbox trampoline using a tail call
2733 LLVMValueRef tramp, call, *args;
2734 LLVMBuilderRef builder;
2735 LLVMBasicBlockRef lbb;
2739 tramp_name = g_strdup_printf ("ut_%s", method_name);
2740 tramp = LLVMAddFunction (ctx->module->lmodule, tramp_name, method_type);
2741 LLVMSetLinkage (tramp, LLVMInternalLinkage);
2742 if (!ctx->llvm_only && ctx->rgctx_arg_pindex != -1)
2743 LLVMAddAttribute (LLVMGetParam (tramp, ctx->rgctx_arg_pindex), LLVMInRegAttribute);
2745 lbb = LLVMAppendBasicBlock (tramp, "");
2746 builder = LLVMCreateBuilder ();
2747 LLVMPositionBuilderAtEnd (builder, lbb);
2749 nargs = LLVMCountParamTypes (method_type);
2750 args = g_new0 (LLVMValueRef, nargs);
2751 for (i = 0; i < nargs; ++i) {
2752 args [i] = LLVMGetParam (tramp, i);
2753 if (i == ctx->this_arg_pindex) {
2754 LLVMTypeRef arg_type = LLVMTypeOf (args [i]);
2756 args [i] = LLVMBuildPtrToInt (builder, args [i], IntPtrType (), "");
2757 args [i] = LLVMBuildAdd (builder, args [i], LLVMConstInt (IntPtrType (), sizeof (MonoObject), FALSE), "");
2758 args [i] = LLVMBuildIntToPtr (builder, args [i], arg_type, "");
2761 call = LLVMBuildCall (builder, method, args, nargs, "");
2762 if (!ctx->llvm_only && ctx->rgctx_arg_pindex != -1)
2763 LLVMAddInstrAttribute (call, 1 + ctx->rgctx_arg_pindex, LLVMInRegAttribute);
2764 //mono_llvm_set_must_tail (call);
2765 if (LLVMGetReturnType (method_type) == LLVMVoidType ())
2766 LLVMBuildRetVoid (builder);
2768 LLVMBuildRet (builder, call);
2770 g_hash_table_insert (ctx->module->idx_to_unbox_tramp, GINT_TO_POINTER (method_index), tramp);
2776 * Emit code to load/convert arguments.
2779 emit_entry_bb (EmitContext *ctx, LLVMBuilderRef builder)
2782 MonoCompile *cfg = ctx->cfg;
2783 MonoMethodSignature *sig = ctx->sig;
2784 LLVMCallInfo *linfo = ctx->linfo;
2788 LLVMBuilderRef old_builder = ctx->builder;
2789 ctx->builder = builder;
2791 ctx->alloca_builder = create_builder (ctx);
2794 * Handle indirect/volatile variables by allocating memory for them
2795 * using 'alloca', and storing their address in a temporary.
2797 for (i = 0; i < cfg->num_varinfo; ++i) {
2798 MonoInst *var = cfg->varinfo [i];
2801 if (var->opcode == OP_GSHAREDVT_LOCAL || var->opcode == OP_GSHAREDVT_ARG_REGOFFSET) {
2802 } 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))) {
2803 vtype = type_to_llvm_type (ctx, var->inst_vtype);
2804 CHECK_FAILURE (ctx);
2805 /* Could be already created by an OP_VPHI */
2806 if (!ctx->addresses [var->dreg]) {
2807 ctx->addresses [var->dreg] = build_alloca (ctx, var->inst_vtype);
2808 //LLVMSetValueName (ctx->addresses [var->dreg], g_strdup_printf ("vreg_loc_%d", var->dreg));
2810 ctx->vreg_cli_types [var->dreg] = var->inst_vtype;
2814 names = g_new (char *, sig->param_count);
2815 mono_method_get_param_names (cfg->method, (const char **) names);
2817 for (i = 0; i < sig->param_count; ++i) {
2818 LLVMArgInfo *ainfo = &linfo->args [i + sig->hasthis];
2819 int reg = cfg->args [i + sig->hasthis]->dreg;
2822 pindex = ainfo->pindex;
2824 switch (ainfo->storage) {
2825 case LLVMArgVtypeInReg:
2826 case LLVMArgAsFpArgs: {
2827 LLVMValueRef args [8];
2830 pindex += ainfo->ndummy_fpargs;
2832 /* The argument is received as a set of int/fp arguments, store them into the real argument */
2833 memset (args, 0, sizeof (args));
2834 if (ainfo->storage == LLVMArgVtypeInReg) {
2835 args [0] = LLVMGetParam (ctx->lmethod, pindex);
2836 if (ainfo->pair_storage [1] != LLVMArgNone)
2837 args [1] = LLVMGetParam (ctx->lmethod, pindex + 1);
2839 g_assert (ainfo->nslots <= 8);
2840 for (j = 0; j < ainfo->nslots; ++j)
2841 args [j] = LLVMGetParam (ctx->lmethod, pindex + j);
2843 ctx->addresses [reg] = build_alloca (ctx, ainfo->type);
2845 emit_args_to_vtype (ctx, builder, ainfo->type, ctx->addresses [reg], ainfo, args);
2847 if (ainfo->storage == LLVMArgVtypeInReg && MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (ainfo->type))) {
2848 /* Treat these as normal values */
2849 ctx->values [reg] = LLVMBuildLoad (builder, ctx->addresses [reg], "");
2853 case LLVMArgVtypeByVal: {
2854 ctx->addresses [reg] = LLVMGetParam (ctx->lmethod, pindex);
2856 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (ainfo->type))) {
2857 /* Treat these as normal values */
2858 ctx->values [reg] = LLVMBuildLoad (builder, ctx->addresses [reg], "");
2862 case LLVMArgVtypeByRef: {
2863 /* The argument is passed by ref */
2864 ctx->addresses [reg] = LLVMGetParam (ctx->lmethod, pindex);
2867 case LLVMArgScalarByRef: {
2869 name = g_strdup_printf ("arg_%s", names [i]);
2871 name = g_strdup_printf ("arg_%d", i);
2872 ctx->values [reg] = LLVMBuildLoad (builder, LLVMGetParam (ctx->lmethod, pindex), name);
2876 case LLVMArgAsIArgs: {
2877 LLVMValueRef arg = LLVMGetParam (ctx->lmethod, pindex);
2879 ctx->addresses [reg] = build_alloca (ctx, ainfo->type);
2881 /* The argument is received as an array of ints, store it into the real argument */
2882 LLVMBuildStore (ctx->builder, arg, convert (ctx, ctx->addresses [reg], LLVMPointerType (LLVMTypeOf (arg), 0)));
2885 case LLVMArgVtypeAsScalar:
2886 g_assert_not_reached ();
2888 case LLVMArgGsharedvtFixed: {
2889 /* These are non-gsharedvt arguments passed by ref, the rest of the IR treats them as scalars */
2890 LLVMValueRef arg = LLVMGetParam (ctx->lmethod, pindex);
2893 name = g_strdup_printf ("arg_%s", names [i]);
2895 name = g_strdup_printf ("arg_%d", i);
2897 ctx->values [reg] = LLVMBuildLoad (builder, convert (ctx, arg, LLVMPointerType (type_to_llvm_type (ctx, ainfo->type), 0)), name);
2900 case LLVMArgGsharedvtFixedVtype: {
2901 LLVMValueRef arg = LLVMGetParam (ctx->lmethod, pindex);
2904 name = g_strdup_printf ("vtype_arg_%s", names [i]);
2906 name = g_strdup_printf ("vtype_arg_%d", i);
2908 /* Non-gsharedvt vtype argument passed by ref, the rest of the IR treats it as a vtype */
2909 g_assert (ctx->addresses [reg]);
2910 LLVMSetValueName (ctx->addresses [reg], name);
2911 LLVMBuildStore (builder, LLVMBuildLoad (builder, convert (ctx, arg, LLVMPointerType (type_to_llvm_type (ctx, ainfo->type), 0)), ""), ctx->addresses [reg]);
2914 case LLVMArgGsharedvtVariable:
2915 /* The IR treats these as variables with addresses */
2916 ctx->addresses [reg] = LLVMGetParam (ctx->lmethod, pindex);
2919 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));
2926 emit_volatile_store (ctx, cfg->vret_addr->dreg);
2928 emit_volatile_store (ctx, cfg->args [0]->dreg);
2929 for (i = 0; i < sig->param_count; ++i)
2930 if (!mini_type_is_vtype (sig->params [i]))
2931 emit_volatile_store (ctx, cfg->args [i + sig->hasthis]->dreg);
2933 if (sig->hasthis && !cfg->rgctx_var && cfg->gshared) {
2934 LLVMValueRef this_alloc;
2937 * The exception handling code needs the location where the this argument was
2938 * stored for gshared methods. We create a separate alloca to hold it, and mark it
2939 * with the "mono.this" custom metadata to tell llvm that it needs to save its
2940 * location into the LSDA.
2942 this_alloc = mono_llvm_build_alloca (builder, ThisType (), LLVMConstInt (LLVMInt32Type (), 1, FALSE), 0, "");
2943 /* This volatile store will keep the alloca alive */
2944 mono_llvm_build_store (builder, ctx->values [cfg->args [0]->dreg], this_alloc, TRUE, LLVM_BARRIER_NONE);
2946 set_metadata_flag (this_alloc, "mono.this");
2949 if (cfg->rgctx_var) {
2950 LLVMValueRef rgctx_alloc, store;
2953 * We handle the rgctx arg similarly to the this pointer.
2955 g_assert (ctx->addresses [cfg->rgctx_var->dreg]);
2956 rgctx_alloc = ctx->addresses [cfg->rgctx_var->dreg];
2957 /* This volatile store will keep the alloca alive */
2958 store = mono_llvm_build_store (builder, convert (ctx, ctx->rgctx_arg, IntPtrType ()), rgctx_alloc, TRUE, LLVM_BARRIER_NONE);
2960 set_metadata_flag (rgctx_alloc, "mono.this");
2963 /* Initialize the method if needed */
2964 if (cfg->compile_aot && ctx->llvm_only) {
2965 /* Emit a location for the initialization code */
2966 ctx->init_bb = gen_bb (ctx, "INIT_BB");
2967 ctx->inited_bb = gen_bb (ctx, "INITED_BB");
2969 LLVMBuildBr (ctx->builder, ctx->init_bb);
2970 builder = ctx->builder = create_builder (ctx);
2971 LLVMPositionBuilderAtEnd (ctx->builder, ctx->inited_bb);
2972 ctx->bblocks [cfg->bb_entry->block_num].end_bblock = ctx->inited_bb;
2975 /* Compute nesting between clauses */
2976 ctx->nested_in = (GSList**)mono_mempool_alloc0 (cfg->mempool, sizeof (GSList*) * cfg->header->num_clauses);
2977 for (i = 0; i < cfg->header->num_clauses; ++i) {
2978 for (j = 0; j < cfg->header->num_clauses; ++j) {
2979 MonoExceptionClause *clause1 = &cfg->header->clauses [i];
2980 MonoExceptionClause *clause2 = &cfg->header->clauses [j];
2982 if (i != j && clause1->try_offset >= clause2->try_offset && clause1->handler_offset <= clause2->handler_offset)
2983 ctx->nested_in [i] = g_slist_prepend_mempool (cfg->mempool, ctx->nested_in [i], GINT_TO_POINTER (j));
2988 * For finally clauses, create an indicator variable telling OP_ENDFINALLY whenever
2989 * it needs to continue normally, or return back to the exception handling system.
2991 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
2995 if (!(bb->region != -1 && (bb->flags & BB_EXCEPTION_HANDLER)))
2998 clause_index = MONO_REGION_CLAUSE_INDEX (bb->region);
2999 g_hash_table_insert (ctx->region_to_handler, GUINT_TO_POINTER (mono_get_block_region_notry (cfg, bb->region)), bb);
3000 g_hash_table_insert (ctx->clause_to_handler, GINT_TO_POINTER (clause_index), bb);
3002 if (bb->in_scount == 0) {
3005 sprintf (name, "finally_ind_bb%d", bb->block_num);
3006 val = LLVMBuildAlloca (builder, LLVMInt32Type (), name);
3007 LLVMBuildStore (builder, LLVMConstInt (LLVMInt32Type (), 0, FALSE), val);
3009 ctx->bblocks [bb->block_num].finally_ind = val;
3011 /* Create a variable to hold the exception var */
3013 ctx->ex_var = LLVMBuildAlloca (builder, ObjRefType (), "exvar");
3017 * Create a new bblock which CALL_HANDLER/landing pads can branch to, because branching to the
3018 * LLVM bblock containing a landing pad causes problems for the
3019 * LLVM optimizer passes.
3021 sprintf (name, "BB%d_CALL_HANDLER_TARGET", bb->block_num);
3022 ctx->bblocks [bb->block_num].call_handler_target_bb = LLVMAppendBasicBlock (ctx->lmethod, name);
3029 ctx->builder = old_builder;
3033 process_call (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, MonoInst *ins)
3035 MonoCompile *cfg = ctx->cfg;
3036 LLVMModuleRef lmodule = ctx->lmodule;
3037 LLVMValueRef *values = ctx->values;
3038 LLVMValueRef *addresses = ctx->addresses;
3039 MonoCallInst *call = (MonoCallInst*)ins;
3040 MonoMethodSignature *sig = call->signature;
3041 LLVMValueRef callee = NULL, lcall;
3043 LLVMCallInfo *cinfo;
3047 LLVMTypeRef llvm_sig;
3049 gboolean is_virtual, calli, preserveall;
3050 LLVMBuilderRef builder = *builder_ref;
3052 if (call->signature->call_convention != MONO_CALL_DEFAULT)
3053 LLVM_FAILURE (ctx, "non-default callconv");
3055 cinfo = call->cinfo;
3057 if (call->rgctx_arg_reg)
3058 cinfo->rgctx_arg = TRUE;
3059 if (call->imt_arg_reg)
3060 cinfo->imt_arg = TRUE;
3062 vretaddr = (cinfo->ret.storage == LLVMArgVtypeRetAddr || cinfo->ret.storage == LLVMArgVtypeByRef || cinfo->ret.storage == LLVMArgScalarRetAddr || cinfo->ret.storage == LLVMArgGsharedvtFixed || cinfo->ret.storage == LLVMArgGsharedvtVariable || cinfo->ret.storage == LLVMArgGsharedvtFixedVtype);
3064 llvm_sig = sig_to_llvm_sig_full (ctx, sig, cinfo);
3065 CHECK_FAILURE (ctx);
3067 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);
3068 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);
3070 preserveall = FALSE;
3072 /* FIXME: Avoid creating duplicate methods */
3074 if (ins->flags & MONO_INST_HAS_METHOD) {
3078 if (cfg->compile_aot) {
3079 callee = get_callee (ctx, llvm_sig, MONO_PATCH_INFO_METHOD, call->method);
3081 LLVM_FAILURE (ctx, "can't encode patch");
3083 if (cfg->llvm_only && call->method->klass->image->assembly == ctx->module->assembly) {
3085 * Collect instructions representing the callee into a hash so they can be replaced
3086 * by the llvm method for the callee if the callee turns out to be direct
3087 * callable. Currently this only requires it to not fail llvm compilation.
3089 GSList *l = (GSList*)g_hash_table_lookup (ctx->method_to_callers, call->method);
3090 l = g_slist_prepend (l, callee);
3091 g_hash_table_insert (ctx->method_to_callers, call->method, l);
3094 callee = LLVMAddFunction (lmodule, "", llvm_sig);
3097 mono_create_jit_trampoline_in_domain (mono_domain_get (),
3099 LLVMAddGlobalMapping (ctx->module->ee, callee, target);
3103 if (!cfg->llvm_only && call->method && strstr (call->method->klass->name, "AsyncVoidMethodBuilder"))
3104 /* LLVM miscompiles async methods */
3105 LLVM_FAILURE (ctx, "#13734");
3108 MonoJitICallInfo *info = mono_find_jit_icall_by_addr (call->fptr);
3114 memset (&ji, 0, sizeof (ji));
3115 ji.type = MONO_PATCH_INFO_JIT_ICALL_ADDR;
3116 ji.data.target = info->name;
3118 target = mono_resolve_patch_target (cfg->method, cfg->domain, NULL, &ji, FALSE);
3120 if (cfg->compile_aot) {
3121 callee = get_callee (ctx, llvm_sig, MONO_PATCH_INFO_INTERNAL_METHOD, (char*)info->name);
3123 LLVM_FAILURE (ctx, "can't encode patch");
3125 callee = LLVMAddFunction (lmodule, "", llvm_sig);
3126 target = (gpointer)mono_icall_get_wrapper (info);
3127 LLVMAddGlobalMapping (ctx->module->ee, callee, target);
3130 if (cfg->compile_aot) {
3132 if (cfg->abs_patches) {
3133 MonoJumpInfo *abs_ji = (MonoJumpInfo*)g_hash_table_lookup (cfg->abs_patches, call->fptr);
3135 callee = get_callee (ctx, llvm_sig, abs_ji->type, abs_ji->data.target);
3137 LLVM_FAILURE (ctx, "can't encode patch");
3141 LLVM_FAILURE (ctx, "aot");
3143 callee = LLVMAddFunction (lmodule, "", llvm_sig);
3145 if (cfg->abs_patches) {
3146 MonoJumpInfo *abs_ji = (MonoJumpInfo*)g_hash_table_lookup (cfg->abs_patches, call->fptr);
3149 * FIXME: Some trampolines might have
3150 * their own calling convention on some platforms.
3152 #ifndef TARGET_AMD64
3153 if (abs_ji->type == MONO_PATCH_INFO_MONITOR_ENTER || abs_ji->type == MONO_PATCH_INFO_MONITOR_ENTER_V4 ||
3154 abs_ji->type == MONO_PATCH_INFO_MONITOR_EXIT)
3155 LLVM_FAILURE (ctx, "trampoline with own cconv");
3157 target = mono_resolve_patch_target (cfg->method, cfg->domain, NULL, abs_ji, FALSE);
3158 LLVMAddGlobalMapping (ctx->module->ee, callee, target);
3162 LLVMAddGlobalMapping (ctx->module->ee, callee, (gpointer)call->fptr);
3168 int size = sizeof (gpointer);
3171 g_assert (ins->inst_offset % size == 0);
3172 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
3174 callee = convert (ctx, LLVMBuildLoad (builder, LLVMBuildGEP (builder, convert (ctx, values [ins->inst_basereg], LLVMPointerType (LLVMPointerType (IntPtrType (), 0), 0)), &index, 1, ""), ""), LLVMPointerType (llvm_sig, 0));
3176 callee = convert (ctx, values [ins->sreg1], LLVMPointerType (llvm_sig, 0));
3178 if (ins->flags & MONO_INST_HAS_METHOD) {
3183 * Collect and convert arguments
3185 nargs = (sig->param_count * 16) + sig->hasthis + vretaddr + call->rgctx_reg + call->imt_arg_reg;
3186 len = sizeof (LLVMValueRef) * nargs;
3187 args = (LLVMValueRef*)alloca (len);
3188 memset (args, 0, len);
3189 l = call->out_ireg_args;
3191 if (call->rgctx_arg_reg) {
3192 g_assert (values [call->rgctx_arg_reg]);
3193 g_assert (cinfo->rgctx_arg_pindex < nargs);
3195 * On ARM, the imt/rgctx argument is passed in a caller save register, but some of our trampolines etc. clobber it, leading to
3196 * problems is LLVM moves the arg assignment earlier. To work around this, save the argument into a stack slot and load
3197 * it using a volatile load.
3200 if (!ctx->imt_rgctx_loc)
3201 ctx->imt_rgctx_loc = build_alloca_llvm_type (ctx, ctx->module->ptr_type, sizeof (gpointer));
3202 LLVMBuildStore (builder, convert (ctx, ctx->values [call->rgctx_arg_reg], ctx->module->ptr_type), ctx->imt_rgctx_loc);
3203 args [cinfo->rgctx_arg_pindex] = mono_llvm_build_load (builder, ctx->imt_rgctx_loc, "", TRUE, LLVM_BARRIER_NONE);
3205 args [cinfo->rgctx_arg_pindex] = convert (ctx, values [call->rgctx_arg_reg], ctx->module->ptr_type);
3208 if (call->imt_arg_reg) {
3209 g_assert (!ctx->llvm_only);
3210 g_assert (values [call->imt_arg_reg]);
3211 g_assert (cinfo->imt_arg_pindex < nargs);
3213 if (!ctx->imt_rgctx_loc)
3214 ctx->imt_rgctx_loc = build_alloca_llvm_type (ctx, ctx->module->ptr_type, sizeof (gpointer));
3215 LLVMBuildStore (builder, convert (ctx, ctx->values [call->imt_arg_reg], ctx->module->ptr_type), ctx->imt_rgctx_loc);
3216 args [cinfo->imt_arg_pindex] = mono_llvm_build_load (builder, ctx->imt_rgctx_loc, "", TRUE, LLVM_BARRIER_NONE);
3218 args [cinfo->imt_arg_pindex] = convert (ctx, values [call->imt_arg_reg], ctx->module->ptr_type);
3221 switch (cinfo->ret.storage) {
3222 case LLVMArgGsharedvtVariable: {
3223 MonoInst *var = get_vreg_to_inst (cfg, call->inst.dreg);
3225 if (var && var->opcode == OP_GSHAREDVT_LOCAL) {
3226 args [cinfo->vret_arg_pindex] = convert (ctx, emit_gsharedvt_ldaddr (ctx, var->dreg), IntPtrType ());
3228 g_assert (addresses [call->inst.dreg]);
3229 args [cinfo->vret_arg_pindex] = addresses [call->inst.dreg];
3235 if (!addresses [call->inst.dreg])
3236 addresses [call->inst.dreg] = build_alloca (ctx, sig->ret);
3237 g_assert (cinfo->vret_arg_pindex < nargs);
3238 if (cinfo->ret.storage == LLVMArgVtypeByRef)
3239 args [cinfo->vret_arg_pindex] = addresses [call->inst.dreg];
3241 args [cinfo->vret_arg_pindex] = LLVMBuildPtrToInt (builder, addresses [call->inst.dreg], IntPtrType (), "");
3247 * Sometimes the same method is called with two different signatures (i.e. with and without 'this'), so
3248 * use the real callee for argument type conversion.
3250 LLVMTypeRef callee_type = LLVMGetElementType (LLVMTypeOf (callee));
3251 LLVMTypeRef *param_types = (LLVMTypeRef*)g_alloca (sizeof (LLVMTypeRef) * LLVMCountParamTypes (callee_type));
3252 LLVMGetParamTypes (callee_type, param_types);
3254 for (i = 0; i < sig->param_count + sig->hasthis; ++i) {
3257 LLVMArgInfo *ainfo = &call->cinfo->args [i];
3259 pindex = ainfo->pindex;
3261 regpair = (guint32)(gssize)(l->data);
3262 reg = regpair & 0xffffff;
3263 args [pindex] = values [reg];
3264 switch (ainfo->storage) {
3265 case LLVMArgVtypeInReg:
3266 case LLVMArgAsFpArgs: {
3270 for (j = 0; j < ainfo->ndummy_fpargs; ++j)
3271 args [pindex + j] = LLVMConstNull (LLVMDoubleType ());
3272 pindex += ainfo->ndummy_fpargs;
3274 g_assert (addresses [reg]);
3275 emit_vtype_to_args (ctx, builder, ainfo->type, addresses [reg], ainfo, args + pindex, &nargs);
3279 // FIXME: Get rid of the VMOVE
3282 case LLVMArgVtypeByVal:
3283 g_assert (addresses [reg]);
3284 args [pindex] = addresses [reg];
3286 case LLVMArgVtypeByRef:
3287 case LLVMArgScalarByRef: {
3288 g_assert (addresses [reg]);
3289 args [pindex] = convert (ctx, addresses [reg], LLVMPointerType (type_to_llvm_arg_type (ctx, ainfo->type), 0));
3292 case LLVMArgAsIArgs:
3293 g_assert (addresses [reg]);
3294 args [pindex] = LLVMBuildLoad (ctx->builder, convert (ctx, addresses [reg], LLVMPointerType (LLVMArrayType (IntPtrType (), ainfo->nslots), 0)), "");
3296 case LLVMArgVtypeAsScalar:
3297 g_assert_not_reached ();
3299 case LLVMArgGsharedvtFixed:
3300 case LLVMArgGsharedvtFixedVtype:
3301 g_assert (addresses [reg]);
3302 args [pindex] = convert (ctx, addresses [reg], LLVMPointerType (type_to_llvm_arg_type (ctx, ainfo->type), 0));
3304 case LLVMArgGsharedvtVariable:
3305 g_assert (addresses [reg]);
3306 args [pindex] = convert (ctx, addresses [reg], LLVMPointerType (IntPtrType (), 0));
3309 g_assert (args [pindex]);
3310 if (i == 0 && sig->hasthis)
3311 args [pindex] = convert (ctx, args [pindex], param_types [pindex]);
3313 args [pindex] = convert (ctx, args [pindex], type_to_llvm_arg_type (ctx, ainfo->type));
3316 g_assert (pindex <= nargs);
3321 // FIXME: Align call sites
3327 lcall = emit_call (ctx, bb, &builder, callee, args, LLVMCountParamTypes (llvm_sig));
3330 * Modify cconv and parameter attributes to pass rgctx/imt correctly.
3332 #if defined(MONO_ARCH_IMT_REG) && defined(MONO_ARCH_RGCTX_REG)
3333 g_assert (MONO_ARCH_IMT_REG == MONO_ARCH_RGCTX_REG);
3335 /* The two can't be used together, so use only one LLVM calling conv to pass them */
3336 g_assert (!(call->rgctx_arg_reg && call->imt_arg_reg));
3337 if (!sig->pinvoke && !cfg->llvm_only)
3338 LLVMSetInstructionCallConv (lcall, LLVMMono1CallConv);
3340 mono_llvm_set_call_preserveall_cc (lcall);
3342 if (cinfo->ret.storage == LLVMArgVtypeByRef)
3343 LLVMAddInstrAttribute (lcall, 1 + cinfo->vret_arg_pindex, LLVMStructRetAttribute);
3344 if (!ctx->llvm_only && call->rgctx_arg_reg)
3345 LLVMAddInstrAttribute (lcall, 1 + cinfo->rgctx_arg_pindex, LLVMInRegAttribute);
3346 if (call->imt_arg_reg)
3347 LLVMAddInstrAttribute (lcall, 1 + cinfo->imt_arg_pindex, LLVMInRegAttribute);
3349 /* Add byval attributes if needed */
3350 for (i = 0; i < sig->param_count; ++i) {
3351 LLVMArgInfo *ainfo = &call->cinfo->args [i + sig->hasthis];
3353 if (ainfo && ainfo->storage == LLVMArgVtypeByVal)
3354 LLVMAddInstrAttribute (lcall, 1 + ainfo->pindex, LLVMByValAttribute);
3358 * Convert the result
3360 switch (cinfo->ret.storage) {
3361 case LLVMArgVtypeInReg: {
3362 LLVMValueRef regs [2];
3364 if (LLVMTypeOf (lcall) == LLVMVoidType ())
3368 if (!addresses [ins->dreg])
3369 addresses [ins->dreg] = build_alloca (ctx, sig->ret);
3371 regs [0] = LLVMBuildExtractValue (builder, lcall, 0, "");
3372 if (cinfo->ret.pair_storage [1] != LLVMArgNone)
3373 regs [1] = LLVMBuildExtractValue (builder, lcall, 1, "");
3374 emit_args_to_vtype (ctx, builder, sig->ret, addresses [ins->dreg], &cinfo->ret, regs);
3377 case LLVMArgVtypeByVal:
3378 if (!addresses [call->inst.dreg])
3379 addresses [call->inst.dreg] = build_alloca (ctx, sig->ret);
3380 LLVMBuildStore (builder, lcall, addresses [call->inst.dreg]);
3382 case LLVMArgFpStruct:
3383 if (!addresses [call->inst.dreg])
3384 addresses [call->inst.dreg] = build_alloca (ctx, sig->ret);
3385 LLVMBuildStore (builder, lcall, convert_full (ctx, addresses [call->inst.dreg], LLVMPointerType (LLVMTypeOf (lcall), 0), FALSE));
3387 case LLVMArgVtypeAsScalar:
3388 if (!addresses [call->inst.dreg])
3389 addresses [call->inst.dreg] = build_alloca (ctx, sig->ret);
3390 LLVMBuildStore (builder, lcall, convert_full (ctx, addresses [call->inst.dreg], LLVMPointerType (LLVMTypeOf (lcall), 0), FALSE));
3392 case LLVMArgVtypeRetAddr:
3393 case LLVMArgVtypeByRef:
3395 case LLVMArgScalarRetAddr:
3396 /* Normal scalar returned using a vtype return argument */
3397 values [ins->dreg] = LLVMBuildLoad (builder, convert_full (ctx, addresses [call->inst.dreg], LLVMPointerType (type_to_llvm_type (ctx, sig->ret), 0), FALSE), "");
3399 case LLVMArgGsharedvtVariable:
3401 case LLVMArgGsharedvtFixed:
3402 case LLVMArgGsharedvtFixedVtype:
3403 values [ins->dreg] = LLVMBuildLoad (builder, convert_full (ctx, addresses [call->inst.dreg], LLVMPointerType (type_to_llvm_type (ctx, sig->ret), 0), FALSE), "");
3406 if (sig->ret->type != MONO_TYPE_VOID)
3407 /* If the method returns an unsigned value, need to zext it */
3408 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));
3412 *builder_ref = ctx->builder;
3420 emit_llvmonly_throw (EmitContext *ctx, MonoBasicBlock *bb, gboolean rethrow, LLVMValueRef exc)
3422 const char *icall_name = rethrow ? "mono_llvm_rethrow_exception" : "mono_llvm_throw_exception";
3423 LLVMValueRef callee = rethrow ? ctx->module->rethrow : ctx->module->throw_icall;
3425 LLVMTypeRef exc_type = type_to_llvm_type (ctx, &mono_get_exception_class ()->byval_arg);
3428 LLVMTypeRef fun_sig = LLVMFunctionType1 (LLVMVoidType (), exc_type, FALSE);
3430 if (ctx->cfg->compile_aot) {
3431 callee = get_callee (ctx, fun_sig, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
3433 callee = LLVMAddFunction (ctx->lmodule, icall_name, fun_sig);
3434 LLVMAddGlobalMapping (ctx->module->ee, callee, resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name));
3435 mono_memory_barrier ();
3438 ctx->module->rethrow = callee;
3440 ctx->module->throw_icall = callee;
3444 LLVMValueRef args [2];
3446 args [0] = convert (ctx, exc, exc_type);
3447 emit_call (ctx, bb, &ctx->builder, callee, args, 1);
3449 LLVMBuildUnreachable (ctx->builder);
3451 ctx->builder = create_builder (ctx);
3455 emit_throw (EmitContext *ctx, MonoBasicBlock *bb, gboolean rethrow, LLVMValueRef exc)
3457 MonoMethodSignature *throw_sig;
3458 LLVMValueRef callee, arg;
3459 const char *icall_name;
3461 callee = rethrow ? ctx->module->rethrow : ctx->module->throw_icall;
3462 icall_name = rethrow ? "mono_arch_rethrow_exception" : "mono_arch_throw_exception";
3465 throw_sig = mono_metadata_signature_alloc (mono_get_corlib (), 1);
3466 throw_sig->ret = &mono_get_void_class ()->byval_arg;
3467 throw_sig->params [0] = &mono_get_object_class ()->byval_arg;
3468 if (ctx->cfg->compile_aot) {
3469 callee = get_callee (ctx, sig_to_llvm_sig (ctx, throw_sig), MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
3471 callee = LLVMAddFunction (ctx->lmodule, icall_name, sig_to_llvm_sig (ctx, throw_sig));
3475 * LLVM doesn't push the exception argument, so we need a different
3478 LLVMAddGlobalMapping (ctx->module->ee, callee, resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, rethrow ? "llvm_rethrow_exception_trampoline" : "llvm_throw_exception_trampoline"));
3480 LLVMAddGlobalMapping (ctx->module->ee, callee, resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name));
3484 mono_memory_barrier ();
3486 ctx->module->rethrow = callee;
3488 ctx->module->throw_icall = callee;
3490 arg = convert (ctx, exc, type_to_llvm_type (ctx, &mono_get_object_class ()->byval_arg));
3491 emit_call (ctx, bb, &ctx->builder, callee, &arg, 1);
3495 emit_resume_eh (EmitContext *ctx, MonoBasicBlock *bb)
3497 const char *icall_name = "mono_llvm_resume_exception";
3498 LLVMValueRef callee = ctx->module->resume_eh;
3500 LLVMTypeRef fun_sig = LLVMFunctionType0 (LLVMVoidType (), FALSE);
3503 if (ctx->cfg->compile_aot) {
3504 callee = get_callee (ctx, fun_sig, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
3506 callee = LLVMAddFunction (ctx->lmodule, icall_name, fun_sig);
3507 LLVMAddGlobalMapping (ctx->module->ee, callee, resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name));
3508 mono_memory_barrier ();
3510 ctx->module->resume_eh = callee;
3514 emit_call (ctx, bb, &ctx->builder, callee, NULL, 0);
3516 LLVMBuildUnreachable (ctx->builder);
3518 ctx->builder = create_builder (ctx);
3522 mono_llvm_emit_clear_exception_call (EmitContext *ctx, LLVMBuilderRef builder)
3524 const char *icall_name = "mono_llvm_clear_exception";
3526 LLVMTypeRef call_sig = LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE);
3527 LLVMValueRef callee = NULL;
3530 if (ctx->cfg->compile_aot) {
3531 callee = get_callee (ctx, call_sig, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
3533 // FIXME: This is broken.
3534 callee = LLVMAddFunction (ctx->lmodule, icall_name, call_sig);
3538 g_assert (builder && callee);
3540 return LLVMBuildCall (builder, callee, NULL, 0, "");
3544 mono_llvm_emit_load_exception_call (EmitContext *ctx, LLVMBuilderRef builder)
3546 const char *icall_name = "mono_llvm_load_exception";
3548 LLVMTypeRef call_sig = LLVMFunctionType (ObjRefType (), NULL, 0, FALSE);
3549 LLVMValueRef callee = NULL;
3552 if (ctx->cfg->compile_aot) {
3553 callee = get_callee (ctx, call_sig, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
3555 // FIXME: This is broken.
3556 callee = LLVMAddFunction (ctx->lmodule, icall_name, call_sig);
3560 g_assert (builder && callee);
3562 return LLVMBuildCall (builder, callee, NULL, 0, icall_name);
3567 mono_llvm_emit_match_exception_call (EmitContext *ctx, LLVMBuilderRef builder, gint32 region_start, gint32 region_end)
3569 const char *icall_name = "mono_llvm_match_exception";
3571 ctx->builder = builder;
3573 const int num_args = 5;
3574 LLVMValueRef args [num_args];
3575 args [0] = convert (ctx, get_aotconst (ctx, MONO_PATCH_INFO_AOT_JIT_INFO, GINT_TO_POINTER (ctx->cfg->method_index)), IntPtrType ());
3576 args [1] = LLVMConstInt (LLVMInt32Type (), region_start, 0);
3577 args [2] = LLVMConstInt (LLVMInt32Type (), region_end, 0);
3578 if (ctx->cfg->rgctx_var) {
3579 LLVMValueRef rgctx_alloc = ctx->addresses [ctx->cfg->rgctx_var->dreg];
3580 g_assert (rgctx_alloc);
3581 args [3] = LLVMBuildLoad (builder, convert (ctx, rgctx_alloc, LLVMPointerType (IntPtrType (), 0)), "");
3583 args [3] = LLVMConstInt (IntPtrType (), 0, 0);
3586 args [4] = convert (ctx, ctx->this_arg, IntPtrType ());
3588 args [4] = LLVMConstInt (IntPtrType (), 0, 0);
3590 LLVMTypeRef match_sig = LLVMFunctionType5 (LLVMInt32Type (), IntPtrType (), LLVMInt32Type (), LLVMInt32Type (), IntPtrType (), IntPtrType (), FALSE);
3591 LLVMValueRef callee = ctx->module->match_exc;
3594 if (ctx->cfg->compile_aot) {
3595 ctx->builder = builder;
3596 // get_callee expects ctx->builder to be the emitting builder
3597 callee = get_callee (ctx, match_sig, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
3599 callee = ctx->module->match_exc = LLVMAddFunction (ctx->lmodule, icall_name, match_sig);
3600 LLVMAddGlobalMapping (ctx->module->ee, ctx->module->match_exc, resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name));
3601 ctx->module->match_exc = callee;
3602 mono_memory_barrier ();
3606 g_assert (builder && callee);
3608 g_assert (ctx->ex_var);
3610 return LLVMBuildCall (builder, callee, args, num_args, icall_name);
3613 // FIXME: This won't work because the code-finding makes this
3615 /*#define MONO_PERSONALITY_DEBUG*/
3617 #ifdef MONO_PERSONALITY_DEBUG
3618 static const gboolean use_debug_personality = TRUE;
3619 static const char *default_personality_name = "mono_debug_personality";
3621 static const gboolean use_debug_personality = FALSE;
3622 static const char *default_personality_name = "__gxx_personality_v0";
3626 default_cpp_lpad_exc_signature (void)
3628 static gboolean inited = FALSE;
3629 static LLVMTypeRef sig;
3632 LLVMTypeRef signature [2];
3633 signature [0] = LLVMPointerType (LLVMInt8Type (), 0);
3634 signature [1] = LLVMInt32Type ();
3635 sig = LLVMStructType (signature, 2, FALSE);
3643 get_mono_personality (EmitContext *ctx)
3645 LLVMValueRef personality = NULL;
3646 static gint32 mapping_inited = FALSE;
3647 LLVMTypeRef personality_type = LLVMFunctionType (LLVMInt32Type (), NULL, 0, TRUE);
3649 if (!use_debug_personality) {
3650 if (ctx->cfg->compile_aot) {
3651 personality = LLVMGetNamedFunction (ctx->lmodule, default_personality_name);
3652 } else if (InterlockedCompareExchange (&mapping_inited, 1, 0) == 0) {
3653 personality = LLVMAddFunction (ctx->lmodule, default_personality_name, personality_type);
3654 LLVMAddGlobalMapping (ctx->module->ee, personality, personality);
3657 if (ctx->cfg->compile_aot) {
3658 personality = get_callee (ctx, personality_type, MONO_PATCH_INFO_INTERNAL_METHOD, default_personality_name);
3660 personality = LLVMAddFunction (ctx->lmodule, default_personality_name, personality_type);
3661 LLVMAddGlobalMapping (ctx->module->ee, personality, resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, default_personality_name));
3662 mono_memory_barrier ();
3666 g_assert (personality);
3670 static LLVMBasicBlockRef
3671 emit_landing_pad (EmitContext *ctx, int group_index, int group_size)
3673 MonoCompile *cfg = ctx->cfg;
3674 LLVMBuilderRef old_builder = ctx->builder;
3675 MonoExceptionClause *group_start = cfg->header->clauses + group_index;
3677 LLVMBuilderRef lpadBuilder = create_builder (ctx);
3678 ctx->builder = lpadBuilder;
3680 MonoBasicBlock *handler_bb = cfg->cil_offset_to_bb [CLAUSE_START (group_start)];
3681 g_assert (handler_bb);
3683 // <resultval> = landingpad <somety> personality <type> <pers_fn> <clause>+
3684 LLVMValueRef personality = get_mono_personality (ctx);
3685 g_assert (personality);
3687 char *bb_name = g_strdup_printf ("LPAD%d_BB", group_index);
3688 LLVMBasicBlockRef lpad_bb = gen_bb (ctx, bb_name);
3690 LLVMPositionBuilderAtEnd (lpadBuilder, lpad_bb);
3691 LLVMValueRef landing_pad = LLVMBuildLandingPad (lpadBuilder, default_cpp_lpad_exc_signature (), personality, 0, "");
3692 g_assert (landing_pad);
3694 LLVMValueRef cast = LLVMBuildBitCast (lpadBuilder, ctx->module->sentinel_exception, LLVMPointerType (LLVMInt8Type (), 0), "int8TypeInfo");
3695 LLVMAddClause (landing_pad, cast);
3697 LLVMBasicBlockRef resume_bb = gen_bb (ctx, "RESUME_BB");
3698 LLVMBuilderRef resume_builder = create_builder (ctx);
3699 ctx->builder = resume_builder;
3700 LLVMPositionBuilderAtEnd (resume_builder, resume_bb);
3702 emit_resume_eh (ctx, handler_bb);
3705 ctx->builder = lpadBuilder;
3706 LLVMPositionBuilderAtEnd (lpadBuilder, lpad_bb);
3708 gboolean finally_only = TRUE;
3710 MonoExceptionClause *group_cursor = group_start;
3712 for (int i = 0; i < group_size; i ++) {
3713 if (!(group_cursor->flags & MONO_EXCEPTION_CLAUSE_FINALLY))
3714 finally_only = FALSE;
3720 // Handle landing pad inlining
3722 if (!finally_only) {
3723 // So at each level of the exception stack we will match the exception again.
3724 // During that match, we need to compare against the handler types for the current
3725 // protected region. We send the try start and end so that we can only check against
3726 // handlers for this lexical protected region.
3727 LLVMValueRef match = mono_llvm_emit_match_exception_call (ctx, lpadBuilder, group_start->try_offset, group_start->try_offset + group_start->try_len);
3729 // if returns -1, resume
3730 LLVMValueRef switch_ins = LLVMBuildSwitch (lpadBuilder, match, resume_bb, group_size);
3732 // else move to that target bb
3733 for (int i=0; i < group_size; i++) {
3734 MonoExceptionClause *clause = group_start + i;
3735 int clause_index = clause - cfg->header->clauses;
3736 MonoBasicBlock *handler_bb = (MonoBasicBlock*)g_hash_table_lookup (ctx->clause_to_handler, GINT_TO_POINTER (clause_index));
3737 g_assert (handler_bb);
3738 g_assert (ctx->bblocks [handler_bb->block_num].call_handler_target_bb);
3739 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), clause_index, FALSE), ctx->bblocks [handler_bb->block_num].call_handler_target_bb);
3742 int clause_index = group_start - cfg->header->clauses;
3743 MonoBasicBlock *finally_bb = (MonoBasicBlock*)g_hash_table_lookup (ctx->clause_to_handler, GINT_TO_POINTER (clause_index));
3744 g_assert (finally_bb);
3746 LLVMBuildBr (ctx->builder, ctx->bblocks [finally_bb->block_num].call_handler_target_bb);
3749 ctx->builder = old_builder;
3756 emit_llvmonly_handler_start (EmitContext *ctx, MonoBasicBlock *bb, LLVMBasicBlockRef cbb)
3758 int clause_index = MONO_REGION_CLAUSE_INDEX (bb->region);
3759 MonoExceptionClause *clause = &ctx->cfg->header->clauses [clause_index];
3761 // Make exception available to catch blocks
3762 if (!(clause->flags & MONO_EXCEPTION_CLAUSE_FINALLY)) {
3763 LLVMValueRef mono_exc = mono_llvm_emit_load_exception_call (ctx, ctx->builder);
3765 g_assert (ctx->ex_var);
3766 LLVMBuildStore (ctx->builder, LLVMBuildBitCast (ctx->builder, mono_exc, ObjRefType (), ""), ctx->ex_var);
3768 if (bb->in_scount == 1) {
3769 MonoInst *exvar = bb->in_stack [0];
3770 g_assert (!ctx->values [exvar->dreg]);
3771 g_assert (ctx->ex_var);
3772 ctx->values [exvar->dreg] = LLVMBuildLoad (ctx->builder, ctx->ex_var, "save_exception");
3773 emit_volatile_store (ctx, exvar->dreg);
3776 mono_llvm_emit_clear_exception_call (ctx, ctx->builder);
3779 LLVMBuilderRef handler_builder = create_builder (ctx);
3780 LLVMBasicBlockRef target_bb = ctx->bblocks [bb->block_num].call_handler_target_bb;
3781 LLVMPositionBuilderAtEnd (handler_builder, target_bb);
3783 // Make the handler code end with a jump to cbb
3784 LLVMBuildBr (handler_builder, cbb);
3788 emit_handler_start (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef builder)
3790 MonoCompile *cfg = ctx->cfg;
3791 LLVMValueRef *values = ctx->values;
3792 LLVMModuleRef lmodule = ctx->lmodule;
3793 BBInfo *bblocks = ctx->bblocks;
3795 LLVMValueRef personality;
3796 LLVMValueRef landing_pad;
3797 LLVMBasicBlockRef target_bb;
3799 static gint32 mapping_inited;
3800 static int ti_generator;
3803 LLVMValueRef type_info;
3807 // <resultval> = landingpad <somety> personality <type> <pers_fn> <clause>+
3809 if (cfg->compile_aot) {
3810 /* Use a dummy personality function */
3811 personality = LLVMGetNamedFunction (lmodule, "mono_personality");
3812 g_assert (personality);
3814 personality = LLVMGetNamedFunction (lmodule, "mono_personality");
3815 if (InterlockedCompareExchange (&mapping_inited, 1, 0) == 0)
3816 LLVMAddGlobalMapping (ctx->module->ee, personality, (gpointer)mono_personality);
3819 i8ptr = LLVMPointerType (LLVMInt8Type (), 0);
3821 clause_index = (mono_get_block_region_notry (cfg, bb->region) >> 8) - 1;
3824 * Create the type info
3826 sprintf (ti_name, "type_info_%d", ti_generator);
3829 if (cfg->compile_aot) {
3830 /* decode_eh_frame () in aot-runtime.c will decode this */
3831 type_info = LLVMAddGlobal (lmodule, LLVMInt32Type (), ti_name);
3832 LLVMSetInitializer (type_info, LLVMConstInt (LLVMInt32Type (), clause_index, FALSE));
3835 * These symbols are not really used, the clause_index is embedded into the EH tables generated by DwarfMonoException in LLVM.
3837 LLVMSetLinkage (type_info, LLVMInternalLinkage);
3840 * After the cfg mempool is freed, the type info will point to stale memory,
3841 * but this is not a problem, since we decode it once in exception_cb during
3844 ti = (gint32*)mono_mempool_alloc (cfg->mempool, sizeof (gint32));
3845 *(gint32*)ti = clause_index;
3847 type_info = LLVMAddGlobal (lmodule, i8ptr, ti_name);
3849 LLVMAddGlobalMapping (ctx->module->ee, type_info, ti);
3853 LLVMTypeRef members [2], ret_type;
3855 members [0] = i8ptr;
3856 members [1] = LLVMInt32Type ();
3857 ret_type = LLVMStructType (members, 2, FALSE);
3859 landing_pad = LLVMBuildLandingPad (builder, ret_type, personality, 1, "");
3860 LLVMAddClause (landing_pad, type_info);
3862 /* Store the exception into the exvar */
3864 LLVMBuildStore (builder, convert (ctx, LLVMBuildExtractValue (builder, landing_pad, 0, "ex_obj"), ObjRefType ()), ctx->ex_var);
3868 * LLVM throw sites are associated with a one landing pad, and LLVM generated
3869 * code expects control to be transferred to this landing pad even in the
3870 * presence of nested clauses. The landing pad needs to branch to the landing
3871 * pads belonging to nested clauses based on the selector value returned by
3872 * the landing pad instruction, which is passed to the landing pad in a
3873 * register by the EH code.
3875 target_bb = bblocks [bb->block_num].call_handler_target_bb;
3876 g_assert (target_bb);
3879 * Branch to the correct landing pad
3881 LLVMValueRef ex_selector = LLVMBuildExtractValue (builder, landing_pad, 1, "ex_selector");
3882 LLVMValueRef switch_ins = LLVMBuildSwitch (builder, ex_selector, target_bb, 0);
3884 for (l = ctx->nested_in [clause_index]; l; l = l->next) {
3885 int nesting_clause_index = GPOINTER_TO_INT (l->data);
3886 MonoBasicBlock *handler_bb;
3888 handler_bb = (MonoBasicBlock*)g_hash_table_lookup (ctx->clause_to_handler, GINT_TO_POINTER (nesting_clause_index));
3889 g_assert (handler_bb);
3891 g_assert (ctx->bblocks [handler_bb->block_num].call_handler_target_bb);
3892 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), nesting_clause_index, FALSE), ctx->bblocks [handler_bb->block_num].call_handler_target_bb);
3895 /* Start a new bblock which CALL_HANDLER can branch to */
3896 target_bb = bblocks [bb->block_num].call_handler_target_bb;
3898 ctx->builder = builder = create_builder (ctx);
3899 LLVMPositionBuilderAtEnd (ctx->builder, target_bb);
3901 ctx->bblocks [bb->block_num].end_bblock = target_bb;
3903 /* Store the exception into the IL level exvar */
3904 if (bb->in_scount == 1) {
3905 g_assert (bb->in_scount == 1);
3906 exvar = bb->in_stack [0];
3908 // FIXME: This is shared with filter clauses ?
3909 g_assert (!values [exvar->dreg]);
3911 g_assert (ctx->ex_var);
3912 values [exvar->dreg] = LLVMBuildLoad (builder, ctx->ex_var, "");
3913 emit_volatile_store (ctx, exvar->dreg);
3919 process_bb (EmitContext *ctx, MonoBasicBlock *bb)
3921 MonoCompile *cfg = ctx->cfg;
3922 MonoMethodSignature *sig = ctx->sig;
3923 LLVMValueRef method = ctx->lmethod;
3924 LLVMValueRef *values = ctx->values;
3925 LLVMValueRef *addresses = ctx->addresses;
3926 LLVMCallInfo *linfo = ctx->linfo;
3927 LLVMModuleRef lmodule = ctx->lmodule;
3928 BBInfo *bblocks = ctx->bblocks;
3930 LLVMBasicBlockRef cbb;
3931 LLVMBuilderRef builder, starting_builder;
3932 gboolean has_terminator;
3934 LLVMValueRef lhs, rhs;
3937 cbb = get_end_bb (ctx, bb);
3939 builder = create_builder (ctx);
3940 ctx->builder = builder;
3941 LLVMPositionBuilderAtEnd (builder, cbb);
3943 CHECK_FAILURE (ctx);
3945 if (bb->flags & BB_EXCEPTION_HANDLER) {
3946 if (!ctx->llvm_only && !bblocks [bb->block_num].invoke_target) {
3947 LLVM_FAILURE (ctx, "handler without invokes");
3951 emit_llvmonly_handler_start (ctx, bb, cbb);
3953 emit_handler_start (ctx, bb, builder);
3954 CHECK_FAILURE (ctx);
3955 builder = ctx->builder;
3958 has_terminator = FALSE;
3959 starting_builder = builder;
3960 for (ins = bb->code; ins; ins = ins->next) {
3961 const char *spec = LLVM_INS_INFO (ins->opcode);
3963 char dname_buf [128];
3965 emit_dbg_loc (ctx, builder, ins->cil_code);
3970 * Some steps in llc are non-linear in the size of basic blocks, see #5714.
3971 * Start a new bblock. If the llvm optimization passes merge these, we
3972 * can work around that by doing a volatile load + cond branch from
3973 * localloc-ed memory.
3975 //LLVM_FAILURE (ctx, "basic block too long");
3976 cbb = gen_bb (ctx, "CONT_LONG_BB");
3977 LLVMBuildBr (ctx->builder, cbb);
3978 ctx->builder = builder = create_builder (ctx);
3979 LLVMPositionBuilderAtEnd (builder, cbb);
3980 ctx->bblocks [bb->block_num].end_bblock = cbb;
3985 /* There could be instructions after a terminator, skip them */
3988 if (spec [MONO_INST_DEST] != ' ' && !MONO_IS_STORE_MEMBASE (ins)) {
3989 sprintf (dname_buf, "t%d", ins->dreg);
3993 if (spec [MONO_INST_SRC1] != ' ' && spec [MONO_INST_SRC1] != 'v') {
3994 MonoInst *var = get_vreg_to_inst (cfg, ins->sreg1);
3996 if (var && var->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT) && var->opcode != OP_GSHAREDVT_ARG_REGOFFSET) {
3997 lhs = emit_volatile_load (ctx, ins->sreg1);
3999 /* It is ok for SETRET to have an uninitialized argument */
4000 if (!values [ins->sreg1] && ins->opcode != OP_SETRET)
4001 LLVM_FAILURE (ctx, "sreg1");
4002 lhs = values [ins->sreg1];
4008 if (spec [MONO_INST_SRC2] != ' ' && spec [MONO_INST_SRC2] != ' ') {
4009 MonoInst *var = get_vreg_to_inst (cfg, ins->sreg2);
4010 if (var && var->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT)) {
4011 rhs = emit_volatile_load (ctx, ins->sreg2);
4013 if (!values [ins->sreg2])
4014 LLVM_FAILURE (ctx, "sreg2");
4015 rhs = values [ins->sreg2];
4021 //mono_print_ins (ins);
4022 switch (ins->opcode) {
4025 case OP_LIVERANGE_START:
4026 case OP_LIVERANGE_END:
4029 values [ins->dreg] = LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE);
4032 #if SIZEOF_VOID_P == 4
4033 values [ins->dreg] = LLVMConstInt (LLVMInt64Type (), GET_LONG_IMM (ins), FALSE);
4035 values [ins->dreg] = LLVMConstInt (LLVMInt64Type (), (gint64)ins->inst_c0, FALSE);
4039 values [ins->dreg] = LLVMConstReal (LLVMDoubleType (), *(double*)ins->inst_p0);
4043 values [ins->dreg] = LLVMConstReal (LLVMFloatType (), *(float*)ins->inst_p0);
4045 values [ins->dreg] = LLVMConstFPExt (LLVMConstReal (LLVMFloatType (), *(float*)ins->inst_p0), LLVMDoubleType ());
4047 case OP_DUMMY_ICONST:
4048 values [ins->dreg] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
4050 case OP_DUMMY_I8CONST:
4051 values [ins->dreg] = LLVMConstInt (LLVMInt64Type (), 0, FALSE);
4053 case OP_DUMMY_R8CONST:
4054 values [ins->dreg] = LLVMConstReal (LLVMDoubleType (), 0.0f);
4057 LLVMBasicBlockRef target_bb = get_bb (ctx, ins->inst_target_bb);
4058 LLVMBuildBr (builder, target_bb);
4059 has_terminator = TRUE;
4066 LLVMBasicBlockRef new_bb;
4067 LLVMBuilderRef new_builder;
4069 // The default branch is already handled
4070 // FIXME: Handle it here
4072 /* Start new bblock */
4073 sprintf (bb_name, "SWITCH_DEFAULT_BB%d", ctx->default_index ++);
4074 new_bb = LLVMAppendBasicBlock (ctx->lmethod, bb_name);
4076 lhs = convert (ctx, lhs, LLVMInt32Type ());
4077 v = LLVMBuildSwitch (builder, lhs, new_bb, GPOINTER_TO_UINT (ins->klass));
4078 for (i = 0; i < GPOINTER_TO_UINT (ins->klass); ++i) {
4079 MonoBasicBlock *target_bb = ins->inst_many_bb [i];
4081 LLVMAddCase (v, LLVMConstInt (LLVMInt32Type (), i, FALSE), get_bb (ctx, target_bb));
4084 new_builder = create_builder (ctx);
4085 LLVMPositionBuilderAtEnd (new_builder, new_bb);
4086 LLVMBuildUnreachable (new_builder);
4088 has_terminator = TRUE;
4089 g_assert (!ins->next);
4095 switch (linfo->ret.storage) {
4096 case LLVMArgVtypeInReg: {
4097 LLVMTypeRef ret_type = LLVMGetReturnType (LLVMGetElementType (LLVMTypeOf (method)));
4098 LLVMValueRef val, addr, retval;
4101 retval = LLVMGetUndef (ret_type);
4103 if (!addresses [ins->sreg1]) {
4105 * The return type is an LLVM vector type, have to convert between it and the
4106 * real return type which is a struct type.
4108 g_assert (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (sig->ret)));
4109 /* Convert to 2xi64 first */
4110 val = LLVMBuildBitCast (builder, values [ins->sreg1], LLVMVectorType (IntPtrType (), 2), "");
4112 for (i = 0; i < 2; ++i) {
4113 if (linfo->ret.pair_storage [i] == LLVMArgInIReg) {
4114 retval = LLVMBuildInsertValue (builder, retval, LLVMBuildExtractElement (builder, val, LLVMConstInt (LLVMInt32Type (), i, FALSE), ""), i, "");
4116 g_assert (linfo->ret.pair_storage [i] == LLVMArgNone);
4120 addr = LLVMBuildBitCast (builder, addresses [ins->sreg1], LLVMPointerType (ret_type, 0), "");
4121 for (i = 0; i < 2; ++i) {
4122 if (linfo->ret.pair_storage [i] == LLVMArgInIReg) {
4123 LLVMValueRef indexes [2], part_addr;
4125 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
4126 indexes [1] = LLVMConstInt (LLVMInt32Type (), i, FALSE);
4127 part_addr = LLVMBuildGEP (builder, addr, indexes, 2, "");
4129 retval = LLVMBuildInsertValue (builder, retval, LLVMBuildLoad (builder, part_addr, ""), i, "");
4131 g_assert (linfo->ret.pair_storage [i] == LLVMArgNone);
4135 LLVMBuildRet (builder, retval);
4138 case LLVMArgVtypeAsScalar: {
4139 LLVMTypeRef ret_type = LLVMGetReturnType (LLVMGetElementType (LLVMTypeOf (method)));
4140 LLVMValueRef retval;
4143 size = get_vtype_size (sig->ret);
4145 g_assert (addresses [ins->sreg1]);
4147 retval = LLVMBuildLoad (builder, LLVMBuildBitCast (builder, addresses [ins->sreg1], LLVMPointerType (ret_type, 0), ""), "");
4148 LLVMBuildRet (builder, retval);
4151 case LLVMArgVtypeByVal: {
4152 LLVMValueRef retval;
4154 g_assert (addresses [ins->sreg1]);
4155 retval = LLVMBuildLoad (builder, addresses [ins->sreg1], "");
4156 LLVMBuildRet (builder, retval);
4159 case LLVMArgVtypeByRef: {
4160 LLVMBuildRetVoid (builder);
4163 case LLVMArgGsharedvtFixed: {
4164 LLVMTypeRef ret_type = type_to_llvm_type (ctx, sig->ret);
4165 /* The return value is in lhs, need to store to the vret argument */
4166 /* sreg1 might not be set */
4168 g_assert (cfg->vret_addr);
4169 g_assert (values [cfg->vret_addr->dreg]);
4170 LLVMBuildStore (builder, convert (ctx, lhs, ret_type), convert (ctx, values [cfg->vret_addr->dreg], LLVMPointerType (ret_type, 0)));
4172 LLVMBuildRetVoid (builder);
4175 case LLVMArgGsharedvtFixedVtype: {
4177 LLVMBuildRetVoid (builder);
4180 case LLVMArgGsharedvtVariable: {
4182 LLVMBuildRetVoid (builder);
4185 case LLVMArgVtypeRetAddr: {
4186 LLVMBuildRetVoid (builder);
4189 case LLVMArgScalarRetAddr: {
4190 LLVMTypeRef ret_type = type_to_llvm_type (ctx, sig->ret);
4191 LLVMValueRef param = LLVMGetParam (method, linfo->vret_arg_pindex);
4193 /* sreg1 might not be set */
4195 LLVMBuildStore (builder, convert (ctx, lhs, ret_type), convert (ctx, param, LLVMPointerType (ret_type, 0)));
4196 LLVMBuildRetVoid (builder);
4199 case LLVMArgFpStruct: {
4200 LLVMTypeRef ret_type = LLVMGetReturnType (LLVMGetElementType (LLVMTypeOf (method)));
4201 LLVMValueRef retval;
4203 g_assert (addresses [ins->sreg1]);
4204 retval = LLVMBuildLoad (builder, convert (ctx, addresses [ins->sreg1], LLVMPointerType (ret_type, 0)), "");
4205 LLVMBuildRet (builder, retval);
4209 case LLVMArgNormal: {
4210 if (!lhs || ctx->is_dead [ins->sreg1]) {
4212 * The method did not set its return value, probably because it
4213 * ends with a throw.
4216 LLVMBuildRetVoid (builder);
4218 LLVMBuildRet (builder, LLVMConstNull (type_to_llvm_type (ctx, sig->ret)));
4220 LLVMBuildRet (builder, convert (ctx, lhs, type_to_llvm_type (ctx, sig->ret)));
4222 has_terminator = TRUE;
4226 g_assert_not_reached ();
4235 case OP_ICOMPARE_IMM:
4236 case OP_LCOMPARE_IMM:
4237 case OP_COMPARE_IMM: {
4239 LLVMValueRef cmp, args [16];
4240 gboolean likely = (ins->flags & MONO_INST_LIKELY) != 0;
4242 if (ins->next->opcode == OP_NOP)
4245 if (ins->next->opcode == OP_BR)
4246 /* The comparison result is not needed */
4249 rel = mono_opcode_to_cond (ins->next->opcode);
4251 if (ins->opcode == OP_ICOMPARE_IMM) {
4252 lhs = convert (ctx, lhs, LLVMInt32Type ());
4253 rhs = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
4255 if (ins->opcode == OP_LCOMPARE_IMM) {
4256 lhs = convert (ctx, lhs, LLVMInt64Type ());
4257 rhs = LLVMConstInt (LLVMInt64Type (), GET_LONG_IMM (ins), FALSE);
4259 if (ins->opcode == OP_LCOMPARE) {
4260 lhs = convert (ctx, lhs, LLVMInt64Type ());
4261 rhs = convert (ctx, rhs, LLVMInt64Type ());
4263 if (ins->opcode == OP_ICOMPARE) {
4264 lhs = convert (ctx, lhs, LLVMInt32Type ());
4265 rhs = convert (ctx, rhs, LLVMInt32Type ());
4269 if (LLVMGetTypeKind (LLVMTypeOf (lhs)) == LLVMPointerTypeKind)
4270 rhs = convert (ctx, rhs, LLVMTypeOf (lhs));
4271 else if (LLVMGetTypeKind (LLVMTypeOf (rhs)) == LLVMPointerTypeKind)
4272 lhs = convert (ctx, lhs, LLVMTypeOf (rhs));
4275 /* We use COMPARE+SETcc/Bcc, llvm uses SETcc+br cond */
4276 if (ins->opcode == OP_FCOMPARE) {
4277 cmp = LLVMBuildFCmp (builder, fpcond_to_llvm_cond [rel], convert (ctx, lhs, LLVMDoubleType ()), convert (ctx, rhs, LLVMDoubleType ()), "");
4278 } else if (ins->opcode == OP_RCOMPARE) {
4279 cmp = LLVMBuildFCmp (builder, fpcond_to_llvm_cond [rel], convert (ctx, lhs, LLVMFloatType ()), convert (ctx, rhs, LLVMFloatType ()), "");
4280 } else if (ins->opcode == OP_COMPARE_IMM) {
4281 if (LLVMGetTypeKind (LLVMTypeOf (lhs)) == LLVMPointerTypeKind && ins->inst_imm == 0)
4282 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], lhs, LLVMConstNull (LLVMTypeOf (lhs)), "");
4284 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE), "");
4285 } else if (ins->opcode == OP_LCOMPARE_IMM) {
4286 if (SIZEOF_REGISTER == 4 && COMPILE_LLVM (cfg)) {
4287 /* The immediate is encoded in two fields */
4288 guint64 l = ((guint64)(guint32)ins->inst_offset << 32) | ((guint32)ins->inst_imm);
4289 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, LLVMInt64Type ()), LLVMConstInt (LLVMInt64Type (), l, FALSE), "");
4291 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, LLVMInt64Type ()), LLVMConstInt (LLVMInt64Type (), ins->inst_imm, FALSE), "");
4294 else if (ins->opcode == OP_COMPARE) {
4295 if (LLVMGetTypeKind (LLVMTypeOf (lhs)) == LLVMPointerTypeKind && LLVMTypeOf (lhs) == LLVMTypeOf (rhs))
4296 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], lhs, rhs, "");
4298 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, IntPtrType ()), convert (ctx, rhs, IntPtrType ()), "");
4300 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], lhs, rhs, "");
4304 args [1] = LLVMConstInt (LLVMInt1Type (), 1, FALSE);
4305 cmp = LLVMBuildCall (ctx->builder, LLVMGetNamedFunction (ctx->lmodule, "llvm.expect.i1"), args, 2, "");
4308 if (MONO_IS_COND_BRANCH_OP (ins->next)) {
4309 if (ins->next->inst_true_bb == ins->next->inst_false_bb) {
4311 * If the target bb contains PHI instructions, LLVM requires
4312 * two PHI entries for this bblock, while we only generate one.
4313 * So convert this to an unconditional bblock. (bxc #171).
4315 LLVMBuildBr (builder, get_bb (ctx, ins->next->inst_true_bb));
4317 LLVMBuildCondBr (builder, cmp, get_bb (ctx, ins->next->inst_true_bb), get_bb (ctx, ins->next->inst_false_bb));
4319 has_terminator = TRUE;
4320 } else if (MONO_IS_SETCC (ins->next)) {
4321 sprintf (dname_buf, "t%d", ins->next->dreg);
4323 values [ins->next->dreg] = LLVMBuildZExt (builder, cmp, LLVMInt32Type (), dname);
4325 /* Add stores for volatile variables */
4326 emit_volatile_store (ctx, ins->next->dreg);
4327 } else if (MONO_IS_COND_EXC (ins->next)) {
4328 emit_cond_system_exception (ctx, bb, (const char*)ins->next->inst_p1, cmp);
4329 CHECK_FAILURE (ctx);
4330 builder = ctx->builder;
4332 LLVM_FAILURE (ctx, "next");
4348 rel = mono_opcode_to_cond (ins->opcode);
4350 cmp = LLVMBuildFCmp (builder, fpcond_to_llvm_cond [rel], convert (ctx, lhs, LLVMDoubleType ()), convert (ctx, rhs, LLVMDoubleType ()), "");
4351 values [ins->dreg] = LLVMBuildZExt (builder, cmp, LLVMInt32Type (), dname);
4362 rel = mono_opcode_to_cond (ins->opcode);
4364 cmp = LLVMBuildFCmp (builder, fpcond_to_llvm_cond [rel], convert (ctx, lhs, LLVMFloatType ()), convert (ctx, rhs, LLVMFloatType ()), "");
4365 values [ins->dreg] = LLVMBuildZExt (builder, cmp, LLVMInt32Type (), dname);
4373 gboolean empty = TRUE;
4375 /* Check that all input bblocks really branch to us */
4376 for (i = 0; i < bb->in_count; ++i) {
4377 if (bb->in_bb [i]->last_ins && bb->in_bb [i]->last_ins->opcode == OP_NOT_REACHED)
4378 ins->inst_phi_args [i + 1] = -1;
4384 /* LLVM doesn't like phi instructions with zero operands */
4385 ctx->is_dead [ins->dreg] = TRUE;
4389 /* Created earlier, insert it now */
4390 LLVMInsertIntoBuilder (builder, values [ins->dreg]);
4392 for (i = 0; i < ins->inst_phi_args [0]; i++) {
4393 int sreg1 = ins->inst_phi_args [i + 1];
4397 * Count the number of times the incoming bblock branches to us,
4398 * since llvm requires a separate entry for each.
4400 if (bb->in_bb [i]->last_ins && bb->in_bb [i]->last_ins->opcode == OP_SWITCH) {
4401 MonoInst *switch_ins = bb->in_bb [i]->last_ins;
4404 for (j = 0; j < GPOINTER_TO_UINT (switch_ins->klass); ++j) {
4405 if (switch_ins->inst_many_bb [j] == bb)
4412 /* Remember for later */
4413 for (j = 0; j < count; ++j) {
4414 PhiNode *node = (PhiNode*)mono_mempool_alloc0 (ctx->mempool, sizeof (PhiNode));
4417 node->in_bb = bb->in_bb [i];
4419 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);
4429 values [ins->dreg] = lhs;
4433 MonoInst *var = get_vreg_to_inst (cfg, ins->dreg);
4436 values [ins->dreg] = lhs;
4438 if (var && var->klass->byval_arg.type == MONO_TYPE_R4) {
4440 * This is added by the spilling pass in case of the JIT,
4441 * but we have to do it ourselves.
4443 values [ins->dreg] = convert (ctx, values [ins->dreg], LLVMFloatType ());
4447 case OP_MOVE_F_TO_I4: {
4448 values [ins->dreg] = LLVMBuildBitCast (builder, LLVMBuildFPTrunc (builder, lhs, LLVMFloatType (), ""), LLVMInt32Type (), "");
4451 case OP_MOVE_I4_TO_F: {
4452 values [ins->dreg] = LLVMBuildFPExt (builder, LLVMBuildBitCast (builder, lhs, LLVMFloatType (), ""), LLVMDoubleType (), "");
4455 case OP_MOVE_F_TO_I8: {
4456 values [ins->dreg] = LLVMBuildBitCast (builder, lhs, LLVMInt64Type (), "");
4459 case OP_MOVE_I8_TO_F: {
4460 values [ins->dreg] = LLVMBuildBitCast (builder, lhs, LLVMDoubleType (), "");
4493 lhs = convert (ctx, lhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
4494 rhs = convert (ctx, rhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
4496 emit_div_check (ctx, builder, bb, ins, lhs, rhs);
4497 CHECK_FAILURE (ctx);
4498 builder = ctx->builder;
4500 switch (ins->opcode) {
4503 values [ins->dreg] = LLVMBuildAdd (builder, lhs, rhs, dname);
4507 values [ins->dreg] = LLVMBuildSub (builder, lhs, rhs, dname);
4511 values [ins->dreg] = LLVMBuildMul (builder, lhs, rhs, dname);
4515 values [ins->dreg] = LLVMBuildSRem (builder, lhs, rhs, dname);
4519 values [ins->dreg] = LLVMBuildURem (builder, lhs, rhs, dname);
4523 values [ins->dreg] = LLVMBuildSDiv (builder, lhs, rhs, dname);
4527 values [ins->dreg] = LLVMBuildUDiv (builder, lhs, rhs, dname);
4531 values [ins->dreg] = LLVMBuildFDiv (builder, lhs, rhs, dname);
4535 values [ins->dreg] = LLVMBuildAnd (builder, lhs, rhs, dname);
4539 values [ins->dreg] = LLVMBuildOr (builder, lhs, rhs, dname);
4543 values [ins->dreg] = LLVMBuildXor (builder, lhs, rhs, dname);
4547 values [ins->dreg] = LLVMBuildShl (builder, lhs, rhs, dname);
4551 values [ins->dreg] = LLVMBuildAShr (builder, lhs, rhs, dname);
4555 values [ins->dreg] = LLVMBuildLShr (builder, lhs, rhs, dname);
4559 values [ins->dreg] = LLVMBuildFAdd (builder, lhs, rhs, dname);
4562 values [ins->dreg] = LLVMBuildFSub (builder, lhs, rhs, dname);
4565 values [ins->dreg] = LLVMBuildFMul (builder, lhs, rhs, dname);
4569 g_assert_not_reached ();
4576 lhs = convert (ctx, lhs, LLVMFloatType ());
4577 rhs = convert (ctx, rhs, LLVMFloatType ());
4578 switch (ins->opcode) {
4580 values [ins->dreg] = LLVMBuildFAdd (builder, lhs, rhs, dname);
4583 values [ins->dreg] = LLVMBuildFSub (builder, lhs, rhs, dname);
4586 values [ins->dreg] = LLVMBuildFMul (builder, lhs, rhs, dname);
4589 values [ins->dreg] = LLVMBuildFDiv (builder, lhs, rhs, dname);
4592 g_assert_not_reached ();
4601 case OP_IREM_UN_IMM:
4603 case OP_IDIV_UN_IMM:
4609 case OP_ISHR_UN_IMM:
4619 case OP_LSHR_UN_IMM:
4625 case OP_SHR_UN_IMM: {
4628 if (spec [MONO_INST_SRC1] == 'l') {
4629 imm = LLVMConstInt (LLVMInt64Type (), GET_LONG_IMM (ins), FALSE);
4631 imm = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
4634 emit_div_check (ctx, builder, bb, ins, lhs, imm);
4635 CHECK_FAILURE (ctx);
4636 builder = ctx->builder;
4638 #if SIZEOF_VOID_P == 4
4639 if (ins->opcode == OP_LSHL_IMM || ins->opcode == OP_LSHR_IMM || ins->opcode == OP_LSHR_UN_IMM)
4640 imm = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
4643 if (LLVMGetTypeKind (LLVMTypeOf (lhs)) == LLVMPointerTypeKind)
4644 lhs = convert (ctx, lhs, IntPtrType ());
4645 imm = convert (ctx, imm, LLVMTypeOf (lhs));
4646 switch (ins->opcode) {
4650 values [ins->dreg] = LLVMBuildAdd (builder, lhs, imm, dname);
4654 values [ins->dreg] = LLVMBuildSub (builder, lhs, imm, dname);
4659 values [ins->dreg] = LLVMBuildMul (builder, lhs, imm, dname);
4663 values [ins->dreg] = LLVMBuildSDiv (builder, lhs, imm, dname);
4665 case OP_IDIV_UN_IMM:
4666 case OP_LDIV_UN_IMM:
4667 values [ins->dreg] = LLVMBuildUDiv (builder, lhs, imm, dname);
4671 values [ins->dreg] = LLVMBuildSRem (builder, lhs, imm, dname);
4673 case OP_IREM_UN_IMM:
4674 values [ins->dreg] = LLVMBuildURem (builder, lhs, imm, dname);
4679 values [ins->dreg] = LLVMBuildAnd (builder, lhs, imm, dname);
4683 values [ins->dreg] = LLVMBuildOr (builder, lhs, imm, dname);
4687 values [ins->dreg] = LLVMBuildXor (builder, lhs, imm, dname);
4692 values [ins->dreg] = LLVMBuildShl (builder, lhs, imm, dname);
4697 values [ins->dreg] = LLVMBuildAShr (builder, lhs, imm, dname);
4699 case OP_ISHR_UN_IMM:
4700 /* This is used to implement conv.u4, so the lhs could be an i8 */
4701 lhs = convert (ctx, lhs, LLVMInt32Type ());
4702 imm = convert (ctx, imm, LLVMInt32Type ());
4703 values [ins->dreg] = LLVMBuildLShr (builder, lhs, imm, dname);
4705 case OP_LSHR_UN_IMM:
4707 values [ins->dreg] = LLVMBuildLShr (builder, lhs, imm, dname);
4710 g_assert_not_reached ();
4715 values [ins->dreg] = LLVMBuildSub (builder, LLVMConstInt (LLVMInt32Type (), 0, FALSE), convert (ctx, lhs, LLVMInt32Type ()), dname);
4718 values [ins->dreg] = LLVMBuildSub (builder, LLVMConstInt (LLVMInt64Type (), 0, FALSE), lhs, dname);
4721 lhs = convert (ctx, lhs, LLVMDoubleType ());
4722 values [ins->dreg] = LLVMBuildFSub (builder, LLVMConstReal (LLVMDoubleType (), 0.0), lhs, dname);
4725 lhs = convert (ctx, lhs, LLVMFloatType ());
4726 values [ins->dreg] = LLVMBuildFSub (builder, LLVMConstReal (LLVMFloatType (), 0.0), lhs, dname);
4729 guint32 v = 0xffffffff;
4730 values [ins->dreg] = LLVMBuildXor (builder, LLVMConstInt (LLVMInt32Type (), v, FALSE), convert (ctx, lhs, LLVMInt32Type ()), dname);
4734 guint64 v = 0xffffffffffffffffLL;
4735 values [ins->dreg] = LLVMBuildXor (builder, LLVMConstInt (LLVMInt64Type (), v, FALSE), lhs, dname);
4738 #if defined(TARGET_X86) || defined(TARGET_AMD64)
4740 LLVMValueRef v1, v2;
4742 v1 = LLVMBuildMul (builder, convert (ctx, rhs, IntPtrType ()), LLVMConstInt (IntPtrType (), (1 << ins->backend.shift_amount), FALSE), "");
4743 v2 = LLVMBuildAdd (builder, convert (ctx, lhs, IntPtrType ()), v1, "");
4744 values [ins->dreg] = LLVMBuildAdd (builder, v2, LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE), dname);
4749 case OP_ICONV_TO_I1:
4750 case OP_ICONV_TO_I2:
4751 case OP_ICONV_TO_I4:
4752 case OP_ICONV_TO_U1:
4753 case OP_ICONV_TO_U2:
4754 case OP_ICONV_TO_U4:
4755 case OP_LCONV_TO_I1:
4756 case OP_LCONV_TO_I2:
4757 case OP_LCONV_TO_U1:
4758 case OP_LCONV_TO_U2:
4759 case OP_LCONV_TO_U4: {
4762 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);
4764 /* Have to do two casts since our vregs have type int */
4765 v = LLVMBuildTrunc (builder, lhs, op_to_llvm_type (ins->opcode), "");
4767 values [ins->dreg] = LLVMBuildSExt (builder, v, LLVMInt32Type (), dname);
4769 values [ins->dreg] = LLVMBuildZExt (builder, v, LLVMInt32Type (), dname);
4772 case OP_ICONV_TO_I8:
4773 values [ins->dreg] = LLVMBuildSExt (builder, lhs, LLVMInt64Type (), dname);
4775 case OP_ICONV_TO_U8:
4776 values [ins->dreg] = LLVMBuildZExt (builder, lhs, LLVMInt64Type (), dname);
4778 case OP_FCONV_TO_I4:
4779 case OP_RCONV_TO_I4:
4780 values [ins->dreg] = LLVMBuildFPToSI (builder, lhs, LLVMInt32Type (), dname);
4782 case OP_FCONV_TO_I1:
4783 case OP_RCONV_TO_I1:
4784 values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildFPToSI (builder, lhs, LLVMInt8Type (), dname), LLVMInt32Type (), "");
4786 case OP_FCONV_TO_U1:
4787 case OP_RCONV_TO_U1:
4788 values [ins->dreg] = LLVMBuildZExt (builder, LLVMBuildFPToUI (builder, lhs, LLVMInt8Type (), dname), LLVMInt32Type (), "");
4790 case OP_FCONV_TO_I2:
4791 case OP_RCONV_TO_I2:
4792 values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildFPToSI (builder, lhs, LLVMInt16Type (), dname), LLVMInt32Type (), "");
4794 case OP_FCONV_TO_U2:
4795 case OP_RCONV_TO_U2:
4796 values [ins->dreg] = LLVMBuildZExt (builder, LLVMBuildFPToUI (builder, lhs, LLVMInt16Type (), dname), LLVMInt32Type (), "");
4798 case OP_RCONV_TO_U4:
4799 values [ins->dreg] = LLVMBuildFPToUI (builder, lhs, LLVMInt32Type (), dname);
4801 case OP_FCONV_TO_I8:
4802 case OP_RCONV_TO_I8:
4803 values [ins->dreg] = LLVMBuildFPToSI (builder, lhs, LLVMInt64Type (), dname);
4806 values [ins->dreg] = LLVMBuildFPToSI (builder, lhs, IntPtrType (), dname);
4808 case OP_ICONV_TO_R8:
4809 case OP_LCONV_TO_R8:
4810 values [ins->dreg] = LLVMBuildSIToFP (builder, lhs, LLVMDoubleType (), dname);
4812 case OP_ICONV_TO_R_UN:
4813 case OP_LCONV_TO_R_UN:
4814 values [ins->dreg] = LLVMBuildUIToFP (builder, lhs, LLVMDoubleType (), dname);
4816 #if SIZEOF_VOID_P == 4
4819 case OP_LCONV_TO_I4:
4820 values [ins->dreg] = LLVMBuildTrunc (builder, lhs, LLVMInt32Type (), dname);
4822 case OP_ICONV_TO_R4:
4823 case OP_LCONV_TO_R4:
4824 v = LLVMBuildSIToFP (builder, lhs, LLVMFloatType (), "");
4826 values [ins->dreg] = v;
4828 values [ins->dreg] = LLVMBuildFPExt (builder, v, LLVMDoubleType (), dname);
4830 case OP_FCONV_TO_R4:
4831 v = LLVMBuildFPTrunc (builder, lhs, LLVMFloatType (), "");
4833 values [ins->dreg] = v;
4835 values [ins->dreg] = LLVMBuildFPExt (builder, v, LLVMDoubleType (), dname);
4837 case OP_RCONV_TO_R8:
4838 values [ins->dreg] = LLVMBuildFPExt (builder, lhs, LLVMDoubleType (), dname);
4840 case OP_RCONV_TO_R4:
4841 values [ins->dreg] = lhs;
4844 values [ins->dreg] = LLVMBuildSExt (builder, convert (ctx, lhs, LLVMInt32Type ()), LLVMInt64Type (), dname);
4847 values [ins->dreg] = LLVMBuildZExt (builder, convert (ctx, lhs, LLVMInt32Type ()), LLVMInt64Type (), dname);
4850 values [ins->dreg] = LLVMBuildTrunc (builder, lhs, LLVMInt32Type (), dname);
4852 case OP_LOCALLOC_IMM: {
4855 guint32 size = ins->inst_imm;
4856 size = (size + (MONO_ARCH_FRAME_ALIGNMENT - 1)) & ~ (MONO_ARCH_FRAME_ALIGNMENT - 1);
4858 v = mono_llvm_build_alloca (builder, LLVMInt8Type (), LLVMConstInt (LLVMInt32Type (), size, FALSE), MONO_ARCH_FRAME_ALIGNMENT, "");
4860 if (ins->flags & MONO_INST_INIT) {
4861 LLVMValueRef args [5];
4864 args [1] = LLVMConstInt (LLVMInt8Type (), 0, FALSE);
4865 args [2] = LLVMConstInt (LLVMInt32Type (), size, FALSE);
4866 args [3] = LLVMConstInt (LLVMInt32Type (), MONO_ARCH_FRAME_ALIGNMENT, FALSE);
4867 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
4868 LLVMBuildCall (builder, LLVMGetNamedFunction (lmodule, memset_func_name), args, memset_param_count, "");
4871 values [ins->dreg] = v;
4875 LLVMValueRef v, size;
4877 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), "");
4879 v = mono_llvm_build_alloca (builder, LLVMInt8Type (), size, MONO_ARCH_FRAME_ALIGNMENT, "");
4881 if (ins->flags & MONO_INST_INIT) {
4882 LLVMValueRef args [5];
4885 args [1] = LLVMConstInt (LLVMInt8Type (), 0, FALSE);
4887 args [3] = LLVMConstInt (LLVMInt32Type (), MONO_ARCH_FRAME_ALIGNMENT, FALSE);
4888 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
4889 LLVMBuildCall (builder, LLVMGetNamedFunction (lmodule, memset_func_name), args, memset_param_count, "");
4891 values [ins->dreg] = v;
4895 case OP_LOADI1_MEMBASE:
4896 case OP_LOADU1_MEMBASE:
4897 case OP_LOADI2_MEMBASE:
4898 case OP_LOADU2_MEMBASE:
4899 case OP_LOADI4_MEMBASE:
4900 case OP_LOADU4_MEMBASE:
4901 case OP_LOADI8_MEMBASE:
4902 case OP_LOADR4_MEMBASE:
4903 case OP_LOADR8_MEMBASE:
4904 case OP_LOAD_MEMBASE:
4912 LLVMValueRef base, index, addr;
4914 gboolean sext = FALSE, zext = FALSE;
4915 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
4917 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
4922 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)) {
4923 addr = LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE);
4928 if (ins->inst_offset == 0) {
4930 } else if (ins->inst_offset % size != 0) {
4931 /* Unaligned load */
4932 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset, FALSE);
4933 addr = LLVMBuildGEP (builder, convert (ctx, base, LLVMPointerType (LLVMInt8Type (), 0)), &index, 1, "");
4935 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
4936 addr = LLVMBuildGEP (builder, convert (ctx, base, LLVMPointerType (t, 0)), &index, 1, "");
4940 addr = convert (ctx, addr, LLVMPointerType (t, 0));
4942 values [ins->dreg] = emit_load (ctx, bb, &builder, size, addr, dname, is_volatile);
4944 if (!is_volatile && (ins->flags & MONO_INST_INVARIANT_LOAD)) {
4946 * These will signal LLVM that these loads do not alias any stores, and
4947 * they can't fail, allowing them to be hoisted out of loops.
4949 set_invariant_load_flag (values [ins->dreg]);
4950 set_metadata_flag (values [ins->dreg], "mono.nofail.load");
4954 values [ins->dreg] = LLVMBuildSExt (builder, values [ins->dreg], LLVMInt32Type (), dname);
4956 values [ins->dreg] = LLVMBuildZExt (builder, values [ins->dreg], LLVMInt32Type (), dname);
4957 else if (!cfg->r4fp && ins->opcode == OP_LOADR4_MEMBASE)
4958 values [ins->dreg] = LLVMBuildFPExt (builder, values [ins->dreg], LLVMDoubleType (), dname);
4962 case OP_STOREI1_MEMBASE_REG:
4963 case OP_STOREI2_MEMBASE_REG:
4964 case OP_STOREI4_MEMBASE_REG:
4965 case OP_STOREI8_MEMBASE_REG:
4966 case OP_STORER4_MEMBASE_REG:
4967 case OP_STORER8_MEMBASE_REG:
4968 case OP_STORE_MEMBASE_REG: {
4970 LLVMValueRef index, addr;
4972 gboolean sext = FALSE, zext = FALSE;
4973 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
4975 if (!values [ins->inst_destbasereg])
4976 LLVM_FAILURE (ctx, "inst_destbasereg");
4978 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
4980 if (ins->inst_offset % size != 0) {
4981 /* Unaligned store */
4982 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset, FALSE);
4983 addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (LLVMInt8Type (), 0)), &index, 1, "");
4985 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
4986 addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (t, 0)), &index, 1, "");
4988 emit_store (ctx, bb, &builder, size, convert (ctx, values [ins->sreg1], t), convert (ctx, addr, LLVMPointerType (t, 0)), is_volatile);
4992 case OP_STOREI1_MEMBASE_IMM:
4993 case OP_STOREI2_MEMBASE_IMM:
4994 case OP_STOREI4_MEMBASE_IMM:
4995 case OP_STOREI8_MEMBASE_IMM:
4996 case OP_STORE_MEMBASE_IMM: {
4998 LLVMValueRef index, addr;
5000 gboolean sext = FALSE, zext = FALSE;
5001 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
5003 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
5005 if (ins->inst_offset % size != 0) {
5006 /* Unaligned store */
5007 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset, FALSE);
5008 addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (LLVMInt8Type (), 0)), &index, 1, "");
5010 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
5011 addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (t, 0)), &index, 1, "");
5013 emit_store (ctx, bb, &builder, size, convert (ctx, LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE), t), convert (ctx, addr, LLVMPointerType (t, 0)), is_volatile);
5018 emit_load (ctx, bb, &builder, sizeof (gpointer), convert (ctx, lhs, LLVMPointerType (IntPtrType (), 0)), "", TRUE);
5020 case OP_OUTARG_VTRETADDR:
5028 case OP_VOIDCALL_MEMBASE:
5029 case OP_CALL_MEMBASE:
5030 case OP_LCALL_MEMBASE:
5031 case OP_FCALL_MEMBASE:
5032 case OP_RCALL_MEMBASE:
5033 case OP_VCALL_MEMBASE:
5034 case OP_VOIDCALL_REG:
5039 case OP_VCALL_REG: {
5040 process_call (ctx, bb, &builder, ins);
5041 CHECK_FAILURE (ctx);
5046 LLVMValueRef indexes [2];
5047 MonoJumpInfo *tmp_ji, *ji;
5048 LLVMValueRef got_entry_addr;
5052 * FIXME: Can't allocate from the cfg mempool since that is freed if
5053 * the LLVM compile fails.
5055 tmp_ji = g_new0 (MonoJumpInfo, 1);
5056 tmp_ji->type = (MonoJumpInfoType)ins->inst_c1;
5057 tmp_ji->data.target = ins->inst_p0;
5059 ji = mono_aot_patch_info_dup (tmp_ji);
5062 ji->next = cfg->patch_info;
5063 cfg->patch_info = ji;
5065 //mono_add_patch_info (cfg, 0, (MonoJumpInfoType)ins->inst_i1, ins->inst_p0);
5066 got_offset = mono_aot_get_got_offset (cfg->patch_info);
5067 ctx->module->max_got_offset = MAX (ctx->module->max_got_offset, got_offset);
5068 if (!mono_aot_is_shared_got_offset (got_offset)) {
5069 //mono_print_ji (ji);
5071 ctx->has_got_access = TRUE;
5074 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
5075 indexes [1] = LLVMConstInt (LLVMInt32Type (), (gssize)got_offset, FALSE);
5076 got_entry_addr = LLVMBuildGEP (builder, ctx->module->got_var, indexes, 2, "");
5078 name = get_aotconst_name (ji->type, ji->data.target, got_offset);
5079 values [ins->dreg] = LLVMBuildLoad (builder, got_entry_addr, name);
5081 set_invariant_load_flag (values [ins->dreg]);
5084 case OP_NOT_REACHED:
5085 LLVMBuildUnreachable (builder);
5086 has_terminator = TRUE;
5087 g_assert (bb->block_num < cfg->max_block_num);
5088 ctx->unreachable [bb->block_num] = TRUE;
5089 /* Might have instructions after this */
5091 MonoInst *next = ins->next;
5093 * FIXME: If later code uses the regs defined by these instructions,
5094 * compilation will fail.
5096 MONO_DELETE_INS (bb, next);
5100 MonoInst *var = ins->inst_i0;
5102 if (var->opcode == OP_VTARG_ADDR) {
5103 /* The variable contains the vtype address */
5104 values [ins->dreg] = values [var->dreg];
5105 } else if (var->opcode == OP_GSHAREDVT_LOCAL) {
5106 values [ins->dreg] = emit_gsharedvt_ldaddr (ctx, var->dreg);
5108 values [ins->dreg] = addresses [var->dreg];
5113 LLVMValueRef args [1];
5115 args [0] = convert (ctx, lhs, LLVMDoubleType ());
5116 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (lmodule, "llvm.sin.f64"), args, 1, dname);
5120 LLVMValueRef args [1];
5122 args [0] = convert (ctx, lhs, LLVMDoubleType ());
5123 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (lmodule, "llvm.cos.f64"), args, 1, dname);
5127 LLVMValueRef args [1];
5130 /* This no longer seems to happen */
5132 * LLVM optimizes sqrt(nan) into undefined in
5133 * lib/Analysis/ConstantFolding.cpp
5134 * Also, sqrt(NegativeInfinity) is optimized into 0.
5136 LLVM_FAILURE (ctx, "sqrt");
5138 args [0] = convert (ctx, lhs, LLVMDoubleType ());
5139 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (lmodule, "llvm.sqrt.f64"), args, 1, dname);
5143 LLVMValueRef args [1];
5145 args [0] = convert (ctx, lhs, LLVMDoubleType ());
5146 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (lmodule, "fabs"), args, 1, dname);
5160 lhs = convert (ctx, lhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
5161 rhs = convert (ctx, rhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
5163 switch (ins->opcode) {
5166 v = LLVMBuildICmp (builder, LLVMIntSLE, lhs, rhs, "");
5170 v = LLVMBuildICmp (builder, LLVMIntSGE, lhs, rhs, "");
5174 v = LLVMBuildICmp (builder, LLVMIntULE, lhs, rhs, "");
5178 v = LLVMBuildICmp (builder, LLVMIntUGE, lhs, rhs, "");
5181 g_assert_not_reached ();
5184 values [ins->dreg] = LLVMBuildSelect (builder, v, lhs, rhs, dname);
5187 case OP_ATOMIC_EXCHANGE_I4:
5188 case OP_ATOMIC_EXCHANGE_I8: {
5189 LLVMValueRef args [2];
5192 if (ins->opcode == OP_ATOMIC_EXCHANGE_I4)
5193 t = LLVMInt32Type ();
5195 t = LLVMInt64Type ();
5197 g_assert (ins->inst_offset == 0);
5199 args [0] = convert (ctx, lhs, LLVMPointerType (t, 0));
5200 args [1] = convert (ctx, rhs, t);
5202 values [ins->dreg] = mono_llvm_build_atomic_rmw (builder, LLVM_ATOMICRMW_OP_XCHG, args [0], args [1]);
5205 case OP_ATOMIC_ADD_I4:
5206 case OP_ATOMIC_ADD_I8: {
5207 LLVMValueRef args [2];
5210 if (ins->opcode == OP_ATOMIC_ADD_I4)
5211 t = LLVMInt32Type ();
5213 t = LLVMInt64Type ();
5215 g_assert (ins->inst_offset == 0);
5217 args [0] = convert (ctx, lhs, LLVMPointerType (t, 0));
5218 args [1] = convert (ctx, rhs, t);
5219 values [ins->dreg] = LLVMBuildAdd (builder, mono_llvm_build_atomic_rmw (builder, LLVM_ATOMICRMW_OP_ADD, args [0], args [1]), args [1], dname);
5222 case OP_ATOMIC_CAS_I4:
5223 case OP_ATOMIC_CAS_I8: {
5224 LLVMValueRef args [3], val;
5227 if (ins->opcode == OP_ATOMIC_CAS_I4)
5228 t = LLVMInt32Type ();
5230 t = LLVMInt64Type ();
5232 args [0] = convert (ctx, lhs, LLVMPointerType (t, 0));
5234 args [1] = convert (ctx, values [ins->sreg3], t);
5236 args [2] = convert (ctx, values [ins->sreg2], t);
5237 val = mono_llvm_build_cmpxchg (builder, args [0], args [1], args [2]);
5238 /* cmpxchg returns a pair */
5239 values [ins->dreg] = LLVMBuildExtractValue (builder, val, 0, "");
5242 case OP_MEMORY_BARRIER: {
5243 mono_llvm_build_fence (builder, (BarrierKind) ins->backend.memory_barrier_kind);
5246 case OP_ATOMIC_LOAD_I1:
5247 case OP_ATOMIC_LOAD_I2:
5248 case OP_ATOMIC_LOAD_I4:
5249 case OP_ATOMIC_LOAD_I8:
5250 case OP_ATOMIC_LOAD_U1:
5251 case OP_ATOMIC_LOAD_U2:
5252 case OP_ATOMIC_LOAD_U4:
5253 case OP_ATOMIC_LOAD_U8:
5254 case OP_ATOMIC_LOAD_R4:
5255 case OP_ATOMIC_LOAD_R8: {
5256 LLVM_FAILURE (ctx, "atomic mono.load intrinsic");
5259 gboolean sext, zext;
5261 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
5262 BarrierKind barrier = (BarrierKind) ins->backend.memory_barrier_kind;
5263 LLVMValueRef index, addr;
5265 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
5270 if (ins->inst_offset != 0) {
5271 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
5272 addr = LLVMBuildGEP (builder, convert (ctx, lhs, LLVMPointerType (t, 0)), &index, 1, "");
5277 addr = convert (ctx, addr, LLVMPointerType (t, 0));
5279 values [ins->dreg] = emit_load_general (ctx, bb, &builder, size, addr, dname, is_volatile, barrier);
5282 values [ins->dreg] = LLVMBuildSExt (builder, values [ins->dreg], LLVMInt32Type (), dname);
5284 values [ins->dreg] = LLVMBuildZExt (builder, values [ins->dreg], LLVMInt32Type (), dname);
5287 case OP_ATOMIC_STORE_I1:
5288 case OP_ATOMIC_STORE_I2:
5289 case OP_ATOMIC_STORE_I4:
5290 case OP_ATOMIC_STORE_I8:
5291 case OP_ATOMIC_STORE_U1:
5292 case OP_ATOMIC_STORE_U2:
5293 case OP_ATOMIC_STORE_U4:
5294 case OP_ATOMIC_STORE_U8:
5295 case OP_ATOMIC_STORE_R4:
5296 case OP_ATOMIC_STORE_R8: {
5297 LLVM_FAILURE (ctx, "atomic mono.store intrinsic");
5300 gboolean sext, zext;
5302 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
5303 BarrierKind barrier = (BarrierKind) ins->backend.memory_barrier_kind;
5304 LLVMValueRef index, addr, value;
5306 if (!values [ins->inst_destbasereg])
5307 LLVM_FAILURE (ctx, "inst_destbasereg");
5309 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
5311 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
5312 addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (t, 0)), &index, 1, "");
5313 value = convert (ctx, values [ins->sreg1], t);
5315 emit_store_general (ctx, bb, &builder, size, value, addr, is_volatile, barrier);
5318 case OP_RELAXED_NOP: {
5319 #if defined(TARGET_AMD64) || defined(TARGET_X86)
5320 emit_call (ctx, bb, &builder, LLVMGetNamedFunction (ctx->lmodule, "llvm.x86.sse2.pause"), NULL, 0);
5327 #if (defined(TARGET_AMD64) || defined(TARGET_X86)) && defined(__linux__)
5329 // 257 == FS segment register
5330 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 257);
5332 // 256 == GS segment register
5333 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 256);
5336 values [ins->dreg] = LLVMBuildLoad (builder, LLVMBuildIntToPtr (builder, LLVMConstInt (IntPtrType (), ins->inst_offset, TRUE), ptrtype, ""), "");
5337 #elif defined(TARGET_AMD64) && defined(TARGET_OSX)
5338 /* See mono_amd64_emit_tls_get () */
5339 int offset = mono_amd64_get_tls_gs_offset () + (ins->inst_offset * 8);
5341 // 256 == GS segment register
5342 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 256);
5343 values [ins->dreg] = LLVMBuildLoad (builder, LLVMBuildIntToPtr (builder, LLVMConstInt (IntPtrType (), offset, TRUE), ptrtype, ""), "");
5345 LLVM_FAILURE (ctx, "opcode tls-get");
5350 case OP_TLS_GET_REG: {
5351 #if defined(TARGET_AMD64) && defined(TARGET_OSX)
5352 /* See emit_tls_get_reg () */
5353 // 256 == GS segment register
5354 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 256);
5355 values [ins->dreg] = LLVMBuildLoad (builder, LLVMBuildIntToPtr (builder, convert (ctx, lhs, LLVMInt32Type ()), ptrtype, ""), "");
5357 LLVM_FAILURE (ctx, "opcode tls-get");
5362 case OP_TLS_SET_REG: {
5363 #if defined(TARGET_AMD64) && defined(TARGET_OSX)
5364 /* See emit_tls_get_reg () */
5365 // 256 == GS segment register
5366 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 256);
5367 LLVMBuildStore (builder, convert (ctx, lhs, IntPtrType ()), LLVMBuildIntToPtr (builder, convert (ctx, rhs, LLVMInt32Type ()), ptrtype, ""));
5369 LLVM_FAILURE (ctx, "opcode tls-set-reg");
5378 case OP_IADD_OVF_UN:
5380 case OP_ISUB_OVF_UN:
5382 case OP_IMUL_OVF_UN:
5383 #if SIZEOF_VOID_P == 8
5385 case OP_LADD_OVF_UN:
5387 case OP_LSUB_OVF_UN:
5389 case OP_LMUL_OVF_UN:
5392 LLVMValueRef args [2], val, ovf, func;
5394 args [0] = convert (ctx, lhs, op_to_llvm_type (ins->opcode));
5395 args [1] = convert (ctx, rhs, op_to_llvm_type (ins->opcode));
5396 func = LLVMGetNamedFunction (lmodule, ovf_op_to_intrins (ins->opcode));
5398 val = LLVMBuildCall (builder, func, args, 2, "");
5399 values [ins->dreg] = LLVMBuildExtractValue (builder, val, 0, dname);
5400 ovf = LLVMBuildExtractValue (builder, val, 1, "");
5401 emit_cond_system_exception (ctx, bb, "OverflowException", ovf);
5402 CHECK_FAILURE (ctx);
5403 builder = ctx->builder;
5409 * We currently model them using arrays. Promotion to local vregs is
5410 * disabled for them in mono_handle_global_vregs () in the LLVM case,
5411 * so we always have an entry in cfg->varinfo for them.
5412 * FIXME: Is this needed ?
5415 MonoClass *klass = ins->klass;
5416 LLVMValueRef args [5];
5420 LLVM_FAILURE (ctx, "!klass");
5424 if (!addresses [ins->dreg])
5425 addresses [ins->dreg] = build_alloca (ctx, &klass->byval_arg);
5426 args [0] = LLVMBuildBitCast (builder, addresses [ins->dreg], LLVMPointerType (LLVMInt8Type (), 0), "");
5427 args [1] = LLVMConstInt (LLVMInt8Type (), 0, FALSE);
5428 args [2] = LLVMConstInt (LLVMInt32Type (), mono_class_value_size (klass, NULL), FALSE);
5430 args [3] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
5431 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
5432 LLVMBuildCall (builder, LLVMGetNamedFunction (lmodule, memset_func_name), args, memset_param_count, "");
5435 case OP_DUMMY_VZERO:
5438 case OP_STOREV_MEMBASE:
5439 case OP_LOADV_MEMBASE:
5441 MonoClass *klass = ins->klass;
5442 LLVMValueRef src = NULL, dst, args [5];
5443 gboolean done = FALSE;
5447 LLVM_FAILURE (ctx, "!klass");
5451 if (mini_is_gsharedvt_klass (klass)) {
5453 LLVM_FAILURE (ctx, "gsharedvt");
5457 switch (ins->opcode) {
5458 case OP_STOREV_MEMBASE:
5459 if (cfg->gen_write_barriers && klass->has_references && ins->inst_destbasereg != cfg->frame_reg &&
5460 LLVMGetInstructionOpcode (values [ins->inst_destbasereg]) != LLVMAlloca) {
5461 /* Decomposed earlier */
5462 g_assert_not_reached ();
5465 if (!addresses [ins->sreg1]) {
5467 g_assert (values [ins->sreg1]);
5468 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));
5469 LLVMBuildStore (builder, values [ins->sreg1], dst);
5472 src = LLVMBuildBitCast (builder, addresses [ins->sreg1], LLVMPointerType (LLVMInt8Type (), 0), "");
5473 dst = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_destbasereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (LLVMInt8Type (), 0));
5476 case OP_LOADV_MEMBASE:
5477 if (!addresses [ins->dreg])
5478 addresses [ins->dreg] = build_alloca (ctx, &klass->byval_arg);
5479 src = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_basereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (LLVMInt8Type (), 0));
5480 dst = LLVMBuildBitCast (builder, addresses [ins->dreg], LLVMPointerType (LLVMInt8Type (), 0), "");
5483 if (!addresses [ins->sreg1])
5484 addresses [ins->sreg1] = build_alloca (ctx, &klass->byval_arg);
5485 if (!addresses [ins->dreg])
5486 addresses [ins->dreg] = build_alloca (ctx, &klass->byval_arg);
5487 src = LLVMBuildBitCast (builder, addresses [ins->sreg1], LLVMPointerType (LLVMInt8Type (), 0), "");
5488 dst = LLVMBuildBitCast (builder, addresses [ins->dreg], LLVMPointerType (LLVMInt8Type (), 0), "");
5491 g_assert_not_reached ();
5493 CHECK_FAILURE (ctx);
5500 args [2] = LLVMConstInt (LLVMInt32Type (), mono_class_value_size (klass, NULL), FALSE);
5501 args [3] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
5503 args [3] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
5504 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
5505 LLVMBuildCall (builder, LLVMGetNamedFunction (lmodule, memcpy_func_name), args, memcpy_param_count, "");
5508 case OP_LLVM_OUTARG_VT: {
5509 LLVMArgInfo *ainfo = (LLVMArgInfo*)ins->inst_p0;
5510 MonoType *t = mini_get_underlying_type (ins->inst_vtype);
5512 if (ainfo->storage == LLVMArgScalarByRef) {
5513 LLVMTypeRef argtype;
5514 LLVMValueRef loc, v;
5516 argtype = type_to_llvm_arg_type (ctx, t);
5517 loc = build_alloca_llvm_type (ctx, argtype, 0);
5518 v = convert (ctx, values [ins->sreg1], argtype);
5519 LLVMBuildStore (ctx->builder, v, loc);
5520 addresses [ins->dreg] = loc;
5521 } else if (ainfo->storage == LLVMArgGsharedvtVariable) {
5522 MonoInst *var = get_vreg_to_inst (cfg, ins->sreg1);
5524 if (var && var->opcode == OP_GSHAREDVT_LOCAL) {
5525 addresses [ins->dreg] = convert (ctx, emit_gsharedvt_ldaddr (ctx, var->dreg), LLVMPointerType (IntPtrType (), 0));
5527 g_assert (addresses [ins->sreg1]);
5528 addresses [ins->dreg] = addresses [ins->sreg1];
5530 } else if (ainfo->storage == LLVMArgGsharedvtFixed) {
5531 if (!addresses [ins->sreg1]) {
5532 addresses [ins->sreg1] = build_alloca (ctx, t);
5533 g_assert (values [ins->sreg1]);
5535 LLVMBuildStore (builder, convert (ctx, values [ins->sreg1], LLVMGetElementType (LLVMTypeOf (addresses [ins->sreg1]))), addresses [ins->sreg1]);
5536 addresses [ins->dreg] = addresses [ins->sreg1];
5538 if (!addresses [ins->sreg1]) {
5539 addresses [ins->sreg1] = build_alloca (ctx, t);
5540 g_assert (values [ins->sreg1]);
5541 LLVMBuildStore (builder, convert (ctx, values [ins->sreg1], type_to_llvm_type (ctx, t)), addresses [ins->sreg1]);
5543 addresses [ins->dreg] = addresses [ins->sreg1];
5551 #if defined(TARGET_X86) || defined(TARGET_AMD64)
5553 values [ins->dreg] = LLVMConstNull (type_to_llvm_type (ctx, &ins->klass->byval_arg));
5556 case OP_LOADX_MEMBASE: {
5557 LLVMTypeRef t = type_to_llvm_type (ctx, &ins->klass->byval_arg);
5560 src = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_basereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (t, 0));
5561 values [ins->dreg] = mono_llvm_build_aligned_load (builder, src, "", FALSE, 1);
5564 case OP_STOREX_MEMBASE: {
5565 LLVMTypeRef t = LLVMTypeOf (values [ins->sreg1]);
5568 dest = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_destbasereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (t, 0));
5569 mono_llvm_build_aligned_store (builder, values [ins->sreg1], dest, FALSE, 1);
5576 values [ins->dreg] = LLVMBuildAdd (builder, lhs, rhs, "");
5580 values [ins->dreg] = LLVMBuildFAdd (builder, lhs, rhs, "");
5586 values [ins->dreg] = LLVMBuildSub (builder, lhs, rhs, "");
5590 values [ins->dreg] = LLVMBuildFSub (builder, lhs, rhs, "");
5594 values [ins->dreg] = LLVMBuildFMul (builder, lhs, rhs, "");
5598 values [ins->dreg] = LLVMBuildFDiv (builder, lhs, rhs, "");
5601 values [ins->dreg] = LLVMBuildAnd (builder, lhs, rhs, "");
5604 values [ins->dreg] = LLVMBuildOr (builder, lhs, rhs, "");
5607 values [ins->dreg] = LLVMBuildXor (builder, lhs, rhs, "");
5611 values [ins->dreg] = LLVMBuildMul (builder, lhs, rhs, "");
5622 LLVMValueRef v = NULL;
5624 switch (ins->opcode) {
5629 t = LLVMVectorType (LLVMInt32Type (), 4);
5630 rt = LLVMVectorType (LLVMFloatType (), 4);
5636 t = LLVMVectorType (LLVMInt64Type (), 2);
5637 rt = LLVMVectorType (LLVMDoubleType (), 2);
5640 t = LLVMInt32Type ();
5641 rt = LLVMInt32Type ();
5642 g_assert_not_reached ();
5645 lhs = LLVMBuildBitCast (builder, lhs, t, "");
5646 rhs = LLVMBuildBitCast (builder, rhs, t, "");
5647 switch (ins->opcode) {
5650 v = LLVMBuildAnd (builder, lhs, rhs, "");
5654 v = LLVMBuildOr (builder, lhs, rhs, "");
5658 v = LLVMBuildXor (builder, lhs, rhs, "");
5662 v = LLVMBuildAnd (builder, rhs, LLVMBuildNot (builder, lhs, ""), "");
5665 values [ins->dreg] = LLVMBuildBitCast (builder, v, rt, "");
5689 case OP_PADDB_SAT_UN:
5690 case OP_PADDW_SAT_UN:
5691 case OP_PSUBB_SAT_UN:
5692 case OP_PSUBW_SAT_UN:
5700 case OP_PMULW_HIGH_UN: {
5701 LLVMValueRef args [2];
5706 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (lmodule, simd_op_to_intrins (ins->opcode)), args, 2, dname);
5713 values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildICmp (builder, LLVMIntEQ, lhs, rhs, ""), LLVMTypeOf (lhs), "");
5717 values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildICmp (builder, LLVMIntSGT, lhs, rhs, ""), LLVMTypeOf (lhs), "");
5725 case OP_EXTRACTX_U2:
5727 case OP_EXTRACT_U1: {
5729 gboolean zext = FALSE;
5731 t = simd_op_to_llvm_type (ins->opcode);
5733 switch (ins->opcode) {
5741 case OP_EXTRACTX_U2:
5746 t = LLVMInt32Type ();
5747 g_assert_not_reached ();
5750 lhs = LLVMBuildBitCast (builder, lhs, t, "");
5751 values [ins->dreg] = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), "");
5753 values [ins->dreg] = LLVMBuildZExt (builder, values [ins->dreg], LLVMInt32Type (), "");
5762 case OP_EXPAND_R8: {
5763 LLVMTypeRef t = simd_op_to_llvm_type (ins->opcode);
5764 LLVMValueRef mask [16], v;
5767 for (i = 0; i < 16; ++i)
5768 mask [i] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
5770 v = convert (ctx, values [ins->sreg1], LLVMGetElementType (t));
5772 values [ins->dreg] = LLVMBuildInsertElement (builder, LLVMConstNull (t), v, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
5773 values [ins->dreg] = LLVMBuildShuffleVector (builder, values [ins->dreg], LLVMGetUndef (t), LLVMConstVector (mask, LLVMGetVectorSize (t)), "");
5778 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt8Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
5781 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt16Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
5784 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt32Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
5787 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt64Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
5790 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMFloatType ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
5793 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMDoubleType ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
5804 case OP_EXTRACT_MASK:
5811 v = convert (ctx, values [ins->sreg1], simd_op_to_llvm_type (ins->opcode));
5813 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (lmodule, simd_op_to_intrins (ins->opcode)), &v, 1, dname);
5819 LLVMValueRef args [3];
5823 args [2] = LLVMConstInt (LLVMInt8Type (), ins->inst_c0, FALSE);
5825 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (lmodule, simd_op_to_intrins (ins->opcode)), args, 3, dname);
5830 /* This is only used for implementing shifts by non-immediate */
5831 values [ins->dreg] = lhs;
5842 LLVMValueRef args [3];
5845 args [1] = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
5847 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (lmodule, simd_op_to_intrins (ins->opcode)), args, 2, dname);
5858 case OP_PSHLQ_REG: {
5859 LLVMValueRef args [3];
5862 args [1] = values [ins->sreg2];
5864 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (lmodule, simd_op_to_intrins (ins->opcode)), args, 2, dname);
5871 case OP_PSHUFLEW_LOW:
5872 case OP_PSHUFLEW_HIGH: {
5874 LLVMValueRef v1 = NULL, v2 = NULL, mask_values [16];
5875 int i, mask_size = 0;
5876 int imask = ins->inst_c0;
5878 /* Convert the x86 shuffle mask to LLVM's */
5879 switch (ins->opcode) {
5882 mask [0] = ((imask >> 0) & 3);
5883 mask [1] = ((imask >> 2) & 3);
5884 mask [2] = ((imask >> 4) & 3) + 4;
5885 mask [3] = ((imask >> 6) & 3) + 4;
5886 v1 = values [ins->sreg1];
5887 v2 = values [ins->sreg2];
5891 mask [0] = ((imask >> 0) & 1);
5892 mask [1] = ((imask >> 1) & 1) + 2;
5893 v1 = values [ins->sreg1];
5894 v2 = values [ins->sreg2];
5896 case OP_PSHUFLEW_LOW:
5898 mask [0] = ((imask >> 0) & 3);
5899 mask [1] = ((imask >> 2) & 3);
5900 mask [2] = ((imask >> 4) & 3);
5901 mask [3] = ((imask >> 6) & 3);
5906 v1 = values [ins->sreg1];
5907 v2 = LLVMGetUndef (LLVMTypeOf (v1));
5909 case OP_PSHUFLEW_HIGH:
5915 mask [4] = 4 + ((imask >> 0) & 3);
5916 mask [5] = 4 + ((imask >> 2) & 3);
5917 mask [6] = 4 + ((imask >> 4) & 3);
5918 mask [7] = 4 + ((imask >> 6) & 3);
5919 v1 = values [ins->sreg1];
5920 v2 = LLVMGetUndef (LLVMTypeOf (v1));
5924 mask [0] = ((imask >> 0) & 3);
5925 mask [1] = ((imask >> 2) & 3);
5926 mask [2] = ((imask >> 4) & 3);
5927 mask [3] = ((imask >> 6) & 3);
5928 v1 = values [ins->sreg1];
5929 v2 = LLVMGetUndef (LLVMTypeOf (v1));
5932 g_assert_not_reached ();
5934 for (i = 0; i < mask_size; ++i)
5935 mask_values [i] = LLVMConstInt (LLVMInt32Type (), mask [i], FALSE);
5937 values [ins->dreg] =
5938 LLVMBuildShuffleVector (builder, v1, v2,
5939 LLVMConstVector (mask_values, mask_size), dname);
5943 case OP_UNPACK_LOWB:
5944 case OP_UNPACK_LOWW:
5945 case OP_UNPACK_LOWD:
5946 case OP_UNPACK_LOWQ:
5947 case OP_UNPACK_LOWPS:
5948 case OP_UNPACK_LOWPD:
5949 case OP_UNPACK_HIGHB:
5950 case OP_UNPACK_HIGHW:
5951 case OP_UNPACK_HIGHD:
5952 case OP_UNPACK_HIGHQ:
5953 case OP_UNPACK_HIGHPS:
5954 case OP_UNPACK_HIGHPD: {
5956 LLVMValueRef mask_values [16];
5957 int i, mask_size = 0;
5958 gboolean low = FALSE;
5960 switch (ins->opcode) {
5961 case OP_UNPACK_LOWB:
5965 case OP_UNPACK_LOWW:
5969 case OP_UNPACK_LOWD:
5970 case OP_UNPACK_LOWPS:
5974 case OP_UNPACK_LOWQ:
5975 case OP_UNPACK_LOWPD:
5979 case OP_UNPACK_HIGHB:
5982 case OP_UNPACK_HIGHW:
5985 case OP_UNPACK_HIGHD:
5986 case OP_UNPACK_HIGHPS:
5989 case OP_UNPACK_HIGHQ:
5990 case OP_UNPACK_HIGHPD:
5994 g_assert_not_reached ();
5998 for (i = 0; i < (mask_size / 2); ++i) {
6000 mask [(i * 2) + 1] = mask_size + i;
6003 for (i = 0; i < (mask_size / 2); ++i) {
6004 mask [(i * 2)] = (mask_size / 2) + i;
6005 mask [(i * 2) + 1] = mask_size + (mask_size / 2) + i;
6009 for (i = 0; i < mask_size; ++i)
6010 mask_values [i] = LLVMConstInt (LLVMInt32Type (), mask [i], FALSE);
6012 values [ins->dreg] =
6013 LLVMBuildShuffleVector (builder, values [ins->sreg1], values [ins->sreg2],
6014 LLVMConstVector (mask_values, mask_size), dname);
6019 LLVMTypeRef t = simd_op_to_llvm_type (ins->opcode);
6020 LLVMValueRef v, val;
6022 v = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
6023 val = LLVMConstNull (t);
6024 val = LLVMBuildInsertElement (builder, val, v, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
6025 val = LLVMBuildInsertElement (builder, val, v, LLVMConstInt (LLVMInt32Type (), 1, FALSE), dname);
6027 values [ins->dreg] = val;
6031 case OP_DUPPS_HIGH: {
6032 LLVMTypeRef t = simd_op_to_llvm_type (ins->opcode);
6033 LLVMValueRef v1, v2, val;
6036 if (ins->opcode == OP_DUPPS_LOW) {
6037 v1 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
6038 v2 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 2, FALSE), "");
6040 v1 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 1, FALSE), "");
6041 v2 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 3, FALSE), "");
6043 val = LLVMConstNull (t);
6044 val = LLVMBuildInsertElement (builder, val, v1, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
6045 val = LLVMBuildInsertElement (builder, val, v1, LLVMConstInt (LLVMInt32Type (), 1, FALSE), "");
6046 val = LLVMBuildInsertElement (builder, val, v2, LLVMConstInt (LLVMInt32Type (), 2, FALSE), "");
6047 val = LLVMBuildInsertElement (builder, val, v2, LLVMConstInt (LLVMInt32Type (), 3, FALSE), "");
6049 values [ins->dreg] = val;
6059 * EXCEPTION HANDLING
6061 case OP_IMPLICIT_EXCEPTION:
6062 /* This marks a place where an implicit exception can happen */
6063 if (bb->region != -1)
6064 LLVM_FAILURE (ctx, "implicit-exception");
6068 gboolean rethrow = (ins->opcode == OP_RETHROW);
6069 if (ctx->llvm_only) {
6070 emit_llvmonly_throw (ctx, bb, rethrow, lhs);
6071 has_terminator = TRUE;
6072 ctx->unreachable [bb->block_num] = TRUE;
6074 emit_throw (ctx, bb, rethrow, lhs);
6075 builder = ctx->builder;
6079 case OP_CALL_HANDLER: {
6081 * We don't 'call' handlers, but instead simply branch to them.
6082 * The code generated by ENDFINALLY will branch back to us.
6084 LLVMBasicBlockRef noex_bb;
6086 BBInfo *info = &bblocks [ins->inst_target_bb->block_num];
6088 bb_list = info->call_handler_return_bbs;
6091 * Set the indicator variable for the finally clause.
6093 lhs = info->finally_ind;
6095 LLVMBuildStore (builder, LLVMConstInt (LLVMInt32Type (), g_slist_length (bb_list) + 1, FALSE), lhs);
6097 /* Branch to the finally clause */
6098 LLVMBuildBr (builder, info->call_handler_target_bb);
6100 noex_bb = gen_bb (ctx, "CALL_HANDLER_CONT_BB");
6101 info->call_handler_return_bbs = g_slist_append_mempool (cfg->mempool, info->call_handler_return_bbs, noex_bb);
6103 builder = ctx->builder = create_builder (ctx);
6104 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
6106 bblocks [bb->block_num].end_bblock = noex_bb;
6109 case OP_START_HANDLER: {
6112 case OP_ENDFINALLY: {
6113 LLVMBasicBlockRef resume_bb;
6114 MonoBasicBlock *handler_bb;
6115 LLVMValueRef val, switch_ins, callee;
6119 handler_bb = (MonoBasicBlock*)g_hash_table_lookup (ctx->region_to_handler, GUINT_TO_POINTER (mono_get_block_region_notry (cfg, bb->region)));
6120 g_assert (handler_bb);
6121 info = &bblocks [handler_bb->block_num];
6122 lhs = info->finally_ind;
6125 bb_list = info->call_handler_return_bbs;
6127 resume_bb = gen_bb (ctx, "ENDFINALLY_RESUME_BB");
6129 /* Load the finally variable */
6130 val = LLVMBuildLoad (builder, lhs, "");
6132 /* Reset the variable */
6133 LLVMBuildStore (builder, LLVMConstInt (LLVMInt32Type (), 0, FALSE), lhs);
6135 /* Branch to either resume_bb, or to the bblocks in bb_list */
6136 switch_ins = LLVMBuildSwitch (builder, val, resume_bb, g_slist_length (bb_list));
6138 * The other targets are added at the end to handle OP_CALL_HANDLER
6139 * opcodes processed later.
6141 info->endfinally_switch_ins_list = g_slist_append_mempool (cfg->mempool, info->endfinally_switch_ins_list, switch_ins);
6143 builder = ctx->builder = create_builder (ctx);
6144 LLVMPositionBuilderAtEnd (ctx->builder, resume_bb);
6146 if (ctx->llvm_only) {
6147 emit_resume_eh (ctx, bb);
6149 if (ctx->cfg->compile_aot) {
6150 callee = get_callee (ctx, LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE), MONO_PATCH_INFO_INTERNAL_METHOD, "llvm_resume_unwind_trampoline");
6152 callee = LLVMGetNamedFunction (lmodule, "llvm_resume_unwind_trampoline");
6154 LLVMBuildCall (builder, callee, NULL, 0, "");
6155 LLVMBuildUnreachable (builder);
6158 has_terminator = TRUE;
6161 case OP_IL_SEQ_POINT:
6166 sprintf (reason, "opcode %s", mono_inst_name (ins->opcode));
6167 LLVM_FAILURE (ctx, reason);
6172 /* Convert the value to the type required by phi nodes */
6173 if (spec [MONO_INST_DEST] != ' ' && !MONO_IS_STORE_MEMBASE (ins) && ctx->vreg_types [ins->dreg]) {
6174 if (!values [ins->dreg])
6176 values [ins->dreg] = addresses [ins->dreg];
6178 values [ins->dreg] = convert (ctx, values [ins->dreg], ctx->vreg_types [ins->dreg]);
6181 /* Add stores for volatile variables */
6182 if (spec [MONO_INST_DEST] != ' ' && spec [MONO_INST_DEST] != 'v' && !MONO_IS_STORE_MEMBASE (ins))
6183 emit_volatile_store (ctx, ins->dreg);
6186 if (!has_terminator && bb->next_bb && (bb == cfg->bb_entry || bb->in_count > 0)) {
6187 LLVMBuildBr (builder, get_bb (ctx, bb->next_bb));
6190 if (bb == cfg->bb_exit && sig->ret->type == MONO_TYPE_VOID) {
6191 emit_dbg_loc (ctx, builder, cfg->header->code + cfg->header->code_size - 1);
6192 LLVMBuildRetVoid (builder);
6195 if (bb == cfg->bb_entry)
6196 ctx->last_alloca = LLVMGetLastInstruction (get_bb (ctx, cfg->bb_entry));
6205 * mono_llvm_check_method_supported:
6207 * Do some quick checks to decide whenever cfg->method can be compiled by LLVM, to avoid
6208 * compiling a method twice.
6211 mono_llvm_check_method_supported (MonoCompile *cfg)
6218 if (cfg->method->save_lmf) {
6219 cfg->exception_message = g_strdup ("lmf");
6220 cfg->disable_llvm = TRUE;
6222 if (cfg->disable_llvm)
6226 * Nested clauses where one of the clauses is a finally clause is
6227 * not supported, because LLVM can't figure out the control flow,
6228 * probably because we resume exception handling by calling our
6229 * own function instead of using the 'resume' llvm instruction.
6231 for (i = 0; i < cfg->header->num_clauses; ++i) {
6232 for (j = 0; j < cfg->header->num_clauses; ++j) {
6233 MonoExceptionClause *clause1 = &cfg->header->clauses [i];
6234 MonoExceptionClause *clause2 = &cfg->header->clauses [j];
6236 // FIXME: Nested try clauses fail in some cases too, i.e. #37273
6237 if (i != j && clause1->try_offset >= clause2->try_offset && clause1->handler_offset <= clause2->handler_offset) {
6238 //(clause1->flags == MONO_EXCEPTION_CLAUSE_FINALLY || clause2->flags == MONO_EXCEPTION_CLAUSE_FINALLY)) {
6239 cfg->exception_message = g_strdup ("nested clauses");
6240 cfg->disable_llvm = TRUE;
6245 if (cfg->disable_llvm)
6249 if (cfg->method->dynamic) {
6250 cfg->exception_message = g_strdup ("dynamic.");
6251 cfg->disable_llvm = TRUE;
6253 if (cfg->disable_llvm)
6257 static LLVMCallInfo*
6258 get_llvm_call_info (MonoCompile *cfg, MonoMethodSignature *sig)
6260 LLVMCallInfo *linfo;
6263 if (cfg->gsharedvt && cfg->llvm_only && mini_is_gsharedvt_variable_signature (sig)) {
6267 * Gsharedvt methods have the following calling convention:
6268 * - all arguments are passed by ref, even non generic ones
6269 * - the return value is returned by ref too, using a vret
6270 * argument passed after 'this'.
6272 n = sig->param_count + sig->hasthis;
6273 linfo = (LLVMCallInfo*)mono_mempool_alloc0 (cfg->mempool, sizeof (LLVMCallInfo) + (sizeof (LLVMArgInfo) * n));
6277 linfo->args [pindex ++].storage = LLVMArgNormal;
6279 if (sig->ret->type != MONO_TYPE_VOID) {
6280 if (mini_is_gsharedvt_variable_type (sig->ret))
6281 linfo->ret.storage = LLVMArgGsharedvtVariable;
6282 else if (mini_type_is_vtype (sig->ret))
6283 linfo->ret.storage = LLVMArgGsharedvtFixedVtype;
6285 linfo->ret.storage = LLVMArgGsharedvtFixed;
6286 linfo->vret_arg_index = pindex;
6288 linfo->ret.storage = LLVMArgNone;
6291 for (i = 0; i < sig->param_count; ++i) {
6292 if (sig->params [i]->byref)
6293 linfo->args [pindex].storage = LLVMArgNormal;
6294 else if (mini_is_gsharedvt_variable_type (sig->params [i]))
6295 linfo->args [pindex].storage = LLVMArgGsharedvtVariable;
6296 else if (mini_type_is_vtype (sig->params [i]))
6297 linfo->args [pindex].storage = LLVMArgGsharedvtFixedVtype;
6299 linfo->args [pindex].storage = LLVMArgGsharedvtFixed;
6300 linfo->args [pindex].type = sig->params [i];
6307 linfo = mono_arch_get_llvm_call_info (cfg, sig);
6308 for (i = 0; i < sig->param_count; ++i)
6309 linfo->args [i + sig->hasthis].type = sig->params [i];
6315 * mono_llvm_emit_method:
6317 * Emit LLVM IL from the mono IL, and compile it to native code using LLVM.
6320 mono_llvm_emit_method (MonoCompile *cfg)
6323 MonoMethodSignature *sig;
6325 LLVMTypeRef method_type;
6326 LLVMValueRef method = NULL;
6328 LLVMValueRef *values;
6329 int i, max_block_num, bb_index;
6330 gboolean last = FALSE, is_linkonce = FALSE;
6331 GPtrArray *phi_values;
6332 LLVMCallInfo *linfo;
6334 LLVMModuleRef lmodule;
6336 GPtrArray *bblock_list;
6337 MonoMethodHeader *header;
6338 MonoExceptionClause *clause;
6341 /* The code below might acquire the loader lock, so use it for global locking */
6342 mono_loader_lock ();
6344 /* Used to communicate with the callbacks */
6345 mono_native_tls_set_value (current_cfg_tls_id, cfg);
6347 ctx = g_new0 (EmitContext, 1);
6349 ctx->mempool = cfg->mempool;
6352 * This maps vregs to the LLVM instruction defining them
6354 values = g_new0 (LLVMValueRef, cfg->next_vreg);
6356 * This maps vregs for volatile variables to the LLVM instruction defining their
6359 ctx->addresses = g_new0 (LLVMValueRef, cfg->next_vreg);
6360 ctx->vreg_types = g_new0 (LLVMTypeRef, cfg->next_vreg);
6361 ctx->vreg_cli_types = g_new0 (MonoType*, cfg->next_vreg);
6362 phi_values = g_ptr_array_sized_new (256);
6364 * This signals whenever the vreg was defined by a phi node with no input vars
6365 * (i.e. all its input bblocks end with NOT_REACHABLE).
6367 ctx->is_dead = g_new0 (gboolean, cfg->next_vreg);
6368 /* Whenever the bblock is unreachable */
6369 ctx->unreachable = g_new0 (gboolean, cfg->max_block_num);
6370 bblock_list = g_ptr_array_sized_new (256);
6372 ctx->values = values;
6373 ctx->region_to_handler = g_hash_table_new (NULL, NULL);
6374 ctx->clause_to_handler = g_hash_table_new (NULL, NULL);
6375 ctx->method_to_callers = g_hash_table_new (NULL, NULL);
6377 if (cfg->compile_aot) {
6378 ctx->module = &aot_module;
6382 * Allow the linker to discard duplicate copies of wrappers, generic instances etc. by using the 'linkonce'
6383 * linkage for them. This requires the following:
6384 * - the method needs to have a unique mangled name
6385 * - llvmonly mode, since the code in aot-runtime.c would initialize got slots in the wrong aot image etc.
6387 is_linkonce = ctx->module->llvm_only && ctx->module->static_link && mono_aot_is_linkonce_method (cfg->method);
6389 method_name = mono_aot_get_mangled_method_name (cfg->method);
6391 is_linkonce = FALSE;
6394 printf ("%s %s\n", mono_method_full_name (cfg->method, 1), method_name);
6396 printf ("%s\n", mono_method_full_name (cfg->method, 1));
6400 method_name = mono_aot_get_method_name (cfg);
6401 cfg->llvm_method_name = g_strdup (method_name);
6403 init_jit_module (cfg->domain);
6404 ctx->module = (MonoLLVMModule*)domain_jit_info (cfg->domain)->llvm_module;
6405 method_name = mono_method_full_name (cfg->method, TRUE);
6408 lmodule = ctx->lmodule = ctx->module->lmodule;
6409 ctx->llvm_only = ctx->module->llvm_only;
6411 if (cfg->gsharedvt && !cfg->llvm_only)
6412 LLVM_FAILURE (ctx, "gsharedvt");
6416 static int count = 0;
6419 if (g_getenv ("LLVM_COUNT")) {
6420 if (count == atoi (g_getenv ("LLVM_COUNT"))) {
6421 printf ("LAST: %s\n", mono_method_full_name (cfg->method, TRUE));
6425 if (count > atoi (g_getenv ("LLVM_COUNT")))
6426 LLVM_FAILURE (ctx, "");
6431 sig = mono_method_signature (cfg->method);
6434 linfo = get_llvm_call_info (cfg, sig);
6436 CHECK_FAILURE (ctx);
6439 linfo->rgctx_arg = TRUE;
6440 method_type = sig_to_llvm_sig_full (ctx, sig, linfo);
6441 CHECK_FAILURE (ctx);
6443 method = LLVMAddFunction (lmodule, method_name, method_type);
6444 ctx->lmethod = method;
6446 if (!cfg->llvm_only)
6447 LLVMSetFunctionCallConv (method, LLVMMono1CallConv);
6448 LLVMSetLinkage (method, LLVMPrivateLinkage);
6450 LLVMAddFunctionAttr (method, LLVMUWTable);
6452 if (cfg->compile_aot) {
6453 LLVMSetLinkage (method, LLVMInternalLinkage);
6454 if (ctx->module->external_symbols) {
6455 LLVMSetLinkage (method, LLVMExternalLinkage);
6456 LLVMSetVisibility (method, LLVMHiddenVisibility);
6459 LLVMSetLinkage (method, LLVMLinkOnceAnyLinkage);
6460 LLVMSetVisibility (method, LLVMDefaultVisibility);
6463 LLVMSetLinkage (method, LLVMPrivateLinkage);
6466 if (cfg->method->save_lmf && !cfg->llvm_only)
6467 LLVM_FAILURE (ctx, "lmf");
6469 if (sig->pinvoke && cfg->method->wrapper_type != MONO_WRAPPER_RUNTIME_INVOKE && !cfg->llvm_only)
6470 LLVM_FAILURE (ctx, "pinvoke signature");
6472 header = cfg->header;
6473 for (i = 0; i < header->num_clauses; ++i) {
6474 clause = &header->clauses [i];
6475 if (clause->flags != MONO_EXCEPTION_CLAUSE_FINALLY && clause->flags != MONO_EXCEPTION_CLAUSE_NONE)
6476 LLVM_FAILURE (ctx, "non-finally/catch clause.");
6478 if (header->num_clauses || (cfg->method->iflags & METHOD_IMPL_ATTRIBUTE_NOINLINING) || cfg->no_inline)
6479 /* We can't handle inlined methods with clauses */
6480 LLVMAddFunctionAttr (method, LLVMNoInlineAttribute);
6482 if (linfo->rgctx_arg) {
6483 ctx->rgctx_arg = LLVMGetParam (method, linfo->rgctx_arg_pindex);
6484 ctx->rgctx_arg_pindex = linfo->rgctx_arg_pindex;
6486 * We mark the rgctx parameter with the inreg attribute, which is mapped to
6487 * MONO_ARCH_RGCTX_REG in the Mono calling convention in llvm, i.e.
6488 * CC_X86_64_Mono in X86CallingConv.td.
6490 if (!ctx->llvm_only)
6491 LLVMAddAttribute (ctx->rgctx_arg, LLVMInRegAttribute);
6492 LLVMSetValueName (ctx->rgctx_arg, "rgctx");
6494 ctx->rgctx_arg_pindex = -1;
6496 if (cfg->vret_addr) {
6497 values [cfg->vret_addr->dreg] = LLVMGetParam (method, linfo->vret_arg_pindex);
6498 LLVMSetValueName (values [cfg->vret_addr->dreg], "vret");
6499 if (linfo->ret.storage == LLVMArgVtypeByRef) {
6500 LLVMAddAttribute (LLVMGetParam (method, linfo->vret_arg_pindex), LLVMStructRetAttribute);
6501 LLVMAddAttribute (LLVMGetParam (method, linfo->vret_arg_pindex), LLVMNoAliasAttribute);
6503 } else if (linfo->ret.storage == LLVMArgScalarRetAddr) {
6504 LLVMValueRef param = LLVMGetParam (method, linfo->vret_arg_pindex);
6505 LLVMSetValueName (param, "vret");
6509 ctx->this_arg_pindex = linfo->this_arg_pindex;
6510 ctx->this_arg = LLVMGetParam (method, linfo->this_arg_pindex);
6511 values [cfg->args [0]->dreg] = ctx->this_arg;
6512 LLVMSetValueName (values [cfg->args [0]->dreg], "this");
6515 names = g_new (char *, sig->param_count);
6516 mono_method_get_param_names (cfg->method, (const char **) names);
6518 for (i = 0; i < sig->param_count; ++i) {
6519 LLVMArgInfo *ainfo = &linfo->args [i + sig->hasthis];
6521 int pindex = ainfo->pindex + ainfo->ndummy_fpargs;
6524 for (j = 0; j < ainfo->ndummy_fpargs; ++j) {
6525 name = g_strdup_printf ("dummy_%d_%d", i, j);
6526 LLVMSetValueName (LLVMGetParam (method, ainfo->pindex + j), name);
6530 values [cfg->args [i + sig->hasthis]->dreg] = LLVMGetParam (method, pindex);
6531 if (ainfo->storage == LLVMArgScalarByRef) {
6532 if (names [i] && names [i][0] != '\0')
6533 name = g_strdup_printf ("p_arg_%s", names [i]);
6535 name = g_strdup_printf ("p_arg_%d", i);
6536 } else if (ainfo->storage == LLVMArgGsharedvtFixed || ainfo->storage == LLVMArgGsharedvtFixedVtype) {
6537 if (names [i] && names [i][0] != '\0')
6538 name = g_strdup_printf ("p_arg_%s", names [i]);
6540 name = g_strdup_printf ("p_arg_%d", i);
6542 if (names [i] && names [i][0] != '\0')
6543 name = g_strdup_printf ("arg_%s", names [i]);
6545 name = g_strdup_printf ("arg_%d", i);
6547 LLVMSetValueName (values [cfg->args [i + sig->hasthis]->dreg], name);
6549 if (ainfo->storage == LLVMArgVtypeByVal)
6550 LLVMAddAttribute (LLVMGetParam (method, pindex), LLVMByValAttribute);
6552 if (ainfo->storage == LLVMArgVtypeByRef) {
6554 cfg->args [i + sig->hasthis]->opcode = OP_VTARG_ADDR;
6559 if (ctx->module->emit_dwarf && cfg->compile_aot && mono_debug_enabled ()) {
6560 ctx->minfo = mono_debug_lookup_method (cfg->method);
6561 ctx->dbg_md = emit_dbg_subprogram (ctx, cfg, method, method_name);
6565 for (bb = cfg->bb_entry; bb; bb = bb->next_bb)
6566 max_block_num = MAX (max_block_num, bb->block_num);
6567 ctx->bblocks = bblocks = g_new0 (BBInfo, max_block_num + 1);
6569 /* Add branches between non-consecutive bblocks */
6570 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
6571 if (bb->last_ins && MONO_IS_COND_BRANCH_OP (bb->last_ins) &&
6572 bb->next_bb != bb->last_ins->inst_false_bb) {
6574 MonoInst *inst = (MonoInst*)mono_mempool_alloc0 (cfg->mempool, sizeof (MonoInst));
6575 inst->opcode = OP_BR;
6576 inst->inst_target_bb = bb->last_ins->inst_false_bb;
6577 mono_bblock_add_inst (bb, inst);
6582 * The INDIRECT flag added by OP_LDADDR inhibits optimizations, even if the LDADDR
6583 * was later optimized away, so clear these flags, and add them back for the still
6584 * present OP_LDADDR instructions.
6586 for (i = 0; i < cfg->next_vreg; ++i) {
6589 ins = get_vreg_to_inst (cfg, i);
6590 if (ins && ins != cfg->rgctx_var)
6591 ins->flags &= ~MONO_INST_INDIRECT;
6595 * Make a first pass over the code to precreate PHI nodes/set INDIRECT flags.
6597 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
6599 LLVMBuilderRef builder;
6601 char dname_buf[128];
6603 builder = create_builder (ctx);
6605 for (ins = bb->code; ins; ins = ins->next) {
6606 switch (ins->opcode) {
6611 LLVMTypeRef phi_type = llvm_type_to_stack_type (cfg, type_to_llvm_type (ctx, &ins->klass->byval_arg));
6613 CHECK_FAILURE (ctx);
6615 if (ins->opcode == OP_VPHI) {
6616 /* Treat valuetype PHI nodes as operating on the address itself */
6617 g_assert (ins->klass);
6618 phi_type = LLVMPointerType (type_to_llvm_type (ctx, &ins->klass->byval_arg), 0);
6622 * Have to precreate these, as they can be referenced by
6623 * earlier instructions.
6625 sprintf (dname_buf, "t%d", ins->dreg);
6627 values [ins->dreg] = LLVMBuildPhi (builder, phi_type, dname);
6629 if (ins->opcode == OP_VPHI)
6630 ctx->addresses [ins->dreg] = values [ins->dreg];
6632 g_ptr_array_add (phi_values, values [ins->dreg]);
6635 * Set the expected type of the incoming arguments since these have
6636 * to have the same type.
6638 for (i = 0; i < ins->inst_phi_args [0]; i++) {
6639 int sreg1 = ins->inst_phi_args [i + 1];
6642 ctx->vreg_types [sreg1] = phi_type;
6647 ((MonoInst*)ins->inst_p0)->flags |= MONO_INST_INDIRECT;
6656 * Create an ordering for bblocks, use the depth first order first, then
6657 * put the exception handling bblocks last.
6659 for (bb_index = 0; bb_index < cfg->num_bblocks; ++bb_index) {
6660 bb = cfg->bblocks [bb_index];
6661 if (!(bb->region != -1 && !MONO_BBLOCK_IS_IN_REGION (bb, MONO_REGION_TRY))) {
6662 g_ptr_array_add (bblock_list, bb);
6663 bblocks [bb->block_num].added = TRUE;
6667 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
6668 if (!bblocks [bb->block_num].added)
6669 g_ptr_array_add (bblock_list, bb);
6673 * Second pass: generate code.
6676 LLVMBuilderRef entry_builder = create_builder (ctx);
6677 LLVMBasicBlockRef entry_bb = get_bb (ctx, cfg->bb_entry);
6678 LLVMPositionBuilderAtEnd (entry_builder, entry_bb);
6679 emit_entry_bb (ctx, entry_builder);
6681 // Make landing pads first
6682 ctx->exc_meta = g_hash_table_new_full (NULL, NULL, NULL, NULL);
6684 if (ctx->llvm_only) {
6685 size_t group_index = 0;
6686 while (group_index < cfg->header->num_clauses) {
6688 size_t cursor = group_index;
6689 while (cursor < cfg->header->num_clauses &&
6690 CLAUSE_START (&cfg->header->clauses [cursor]) == CLAUSE_START (&cfg->header->clauses [group_index]) &&
6691 CLAUSE_END (&cfg->header->clauses [cursor]) == CLAUSE_END (&cfg->header->clauses [group_index])) {
6696 LLVMBasicBlockRef lpad_bb = emit_landing_pad (ctx, group_index, count);
6697 intptr_t key = CLAUSE_END (&cfg->header->clauses [group_index]);
6698 g_hash_table_insert (ctx->exc_meta, (gpointer)key, lpad_bb);
6700 group_index = cursor;
6704 for (bb_index = 0; bb_index < bblock_list->len; ++bb_index) {
6705 bb = (MonoBasicBlock*)g_ptr_array_index (bblock_list, bb_index);
6707 // Prune unreachable mono BBs.
6708 if (!(bb == cfg->bb_entry || bb->in_count > 0))
6711 process_bb (ctx, bb);
6712 CHECK_FAILURE (ctx);
6714 g_hash_table_destroy (ctx->exc_meta);
6716 mono_memory_barrier ();
6718 /* Add incoming phi values */
6719 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
6720 GSList *l, *ins_list;
6722 ins_list = bblocks [bb->block_num].phi_nodes;
6724 for (l = ins_list; l; l = l->next) {
6725 PhiNode *node = (PhiNode*)l->data;
6726 MonoInst *phi = node->phi;
6727 int sreg1 = node->sreg;
6728 LLVMBasicBlockRef in_bb;
6733 in_bb = get_end_bb (ctx, node->in_bb);
6735 if (ctx->unreachable [node->in_bb->block_num])
6738 if (!values [sreg1])
6739 /* Can happen with values in EH clauses */
6740 LLVM_FAILURE (ctx, "incoming phi sreg1");
6742 if (phi->opcode == OP_VPHI) {
6743 g_assert (LLVMTypeOf (ctx->addresses [sreg1]) == LLVMTypeOf (values [phi->dreg]));
6744 LLVMAddIncoming (values [phi->dreg], &ctx->addresses [sreg1], &in_bb, 1);
6746 if (LLVMTypeOf (values [sreg1]) != LLVMTypeOf (values [phi->dreg]))
6748 LLVM_FAILURE (ctx, "incoming phi arg type mismatch");
6749 g_assert (LLVMTypeOf (values [sreg1]) == LLVMTypeOf (values [phi->dreg]));
6750 LLVMAddIncoming (values [phi->dreg], &values [sreg1], &in_bb, 1);
6755 /* Nullify empty phi instructions */
6756 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
6757 GSList *l, *ins_list;
6759 ins_list = bblocks [bb->block_num].phi_nodes;
6761 for (l = ins_list; l; l = l->next) {
6762 PhiNode *node = (PhiNode*)l->data;
6763 MonoInst *phi = node->phi;
6764 LLVMValueRef phi_ins = values [phi->dreg];
6767 /* Already removed */
6770 if (LLVMCountIncoming (phi_ins) == 0) {
6771 mono_llvm_replace_uses_of (phi_ins, LLVMConstNull (LLVMTypeOf (phi_ins)));
6772 LLVMInstructionEraseFromParent (phi_ins);
6773 values [phi->dreg] = NULL;
6778 /* Create the SWITCH statements for ENDFINALLY instructions */
6779 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
6780 BBInfo *info = &bblocks [bb->block_num];
6782 for (l = info->endfinally_switch_ins_list; l; l = l->next) {
6783 LLVMValueRef switch_ins = (LLVMValueRef)l->data;
6784 GSList *bb_list = info->call_handler_return_bbs;
6786 for (i = 0; i < g_slist_length (bb_list); ++i)
6787 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), i + 1, FALSE), (LLVMBasicBlockRef)(g_slist_nth (bb_list, i)->data));
6791 /* Initialize the method if needed */
6792 if (cfg->compile_aot && ctx->llvm_only) {
6793 // FIXME: Add more shared got entries
6794 ctx->builder = create_builder (ctx);
6795 LLVMPositionBuilderAtEnd (ctx->builder, ctx->init_bb);
6797 ctx->module->max_method_idx = MAX (ctx->module->max_method_idx, cfg->method_index);
6799 // FIXME: beforefieldinit
6800 if (ctx->has_got_access || mono_class_get_cctor (cfg->method->klass)) {
6801 emit_init_method (ctx);
6803 LLVMBuildBr (ctx->builder, ctx->inited_bb);
6807 if (cfg->llvm_only) {
6808 GHashTableIter iter;
6810 GSList *callers, *l, *l2;
6813 * Add the contents of ctx->method_to_callers to module->method_to_callers.
6814 * We can't do this earlier, as it contains llvm instructions which can be
6815 * freed if compilation fails.
6816 * FIXME: Get rid of this when all methods can be llvm compiled.
6818 g_hash_table_iter_init (&iter, ctx->method_to_callers);
6819 while (g_hash_table_iter_next (&iter, (void**)&method, (void**)&callers)) {
6820 for (l = callers; l; l = l->next) {
6821 l2 = (GSList*)g_hash_table_lookup (ctx->module->method_to_callers, method);
6822 l2 = g_slist_prepend (l2, l->data);
6823 g_hash_table_insert (ctx->module->method_to_callers, method, l2);
6828 if (cfg->verbose_level > 1)
6829 mono_llvm_dump_value (method);
6831 if (cfg->compile_aot && !cfg->llvm_only)
6832 mark_as_used (ctx->module, method);
6834 if (cfg->compile_aot) {
6835 LLVMValueRef md_args [16];
6836 LLVMValueRef md_node;
6839 method_index = mono_aot_get_method_index (cfg->orig_method);
6840 md_args [0] = LLVMMDString (method_name, strlen (method_name));
6841 md_args [1] = LLVMConstInt (LLVMInt32Type (), method_index, FALSE);
6842 md_node = LLVMMDNode (md_args, 2);
6843 LLVMAddNamedMetadataOperand (lmodule, "mono.function_indexes", md_node);
6844 //LLVMSetMetadata (method, md_kind, LLVMMDNode (&md_arg, 1));
6847 if (cfg->compile_aot) {
6848 /* Don't generate native code, keep the LLVM IR */
6849 if (cfg->verbose_level)
6850 printf ("%s emitted as %s\n", mono_method_full_name (cfg->method, TRUE), method_name);
6852 int err = LLVMVerifyFunction(method, LLVMPrintMessageAction);
6853 g_assert (err == 0);
6855 //LLVMVerifyFunction(method, 0);
6856 mono_llvm_optimize_method (ctx->module->mono_ee, method);
6858 if (cfg->verbose_level > 1)
6859 mono_llvm_dump_value (method);
6861 cfg->native_code = (unsigned char*)LLVMGetPointerToGlobal (ctx->module->ee, method);
6863 /* Set by emit_cb */
6864 g_assert (cfg->code_len);
6866 /* FIXME: Free the LLVM IL for the function */
6869 if (ctx->module->method_to_lmethod)
6870 g_hash_table_insert (ctx->module->method_to_lmethod, cfg->method, method);
6871 if (ctx->module->idx_to_lmethod)
6872 g_hash_table_insert (ctx->module->idx_to_lmethod, GINT_TO_POINTER (cfg->method_index), method);
6874 if (ctx->llvm_only && cfg->orig_method->klass->valuetype && !(cfg->orig_method->flags & METHOD_ATTRIBUTE_STATIC))
6875 emit_unbox_tramp (ctx, method_name, method_type, method, cfg->method_index);
6882 /* Need to add unused phi nodes as they can be referenced by other values */
6883 LLVMBasicBlockRef phi_bb = LLVMAppendBasicBlock (method, "PHI_BB");
6884 LLVMBuilderRef builder;
6886 builder = create_builder (ctx);
6887 LLVMPositionBuilderAtEnd (builder, phi_bb);
6889 for (i = 0; i < phi_values->len; ++i) {
6890 LLVMValueRef v = (LLVMValueRef)g_ptr_array_index (phi_values, i);
6891 if (LLVMGetInstructionParent (v) == NULL)
6892 LLVMInsertIntoBuilder (builder, v);
6895 LLVMDeleteFunction (method);
6900 g_free (ctx->addresses);
6901 g_free (ctx->vreg_types);
6902 g_free (ctx->vreg_cli_types);
6903 g_free (ctx->is_dead);
6904 g_free (ctx->unreachable);
6905 g_ptr_array_free (phi_values, TRUE);
6906 g_free (ctx->bblocks);
6907 g_hash_table_destroy (ctx->region_to_handler);
6908 g_hash_table_destroy (ctx->clause_to_handler);
6909 g_free (method_name);
6910 g_ptr_array_free (bblock_list, TRUE);
6912 for (l = ctx->builders; l; l = l->next) {
6913 LLVMBuilderRef builder = (LLVMBuilderRef)l->data;
6914 LLVMDisposeBuilder (builder);
6919 mono_native_tls_set_value (current_cfg_tls_id, NULL);
6921 mono_loader_unlock ();
6925 * mono_llvm_create_vars:
6927 * Same as mono_arch_create_vars () for LLVM.
6930 mono_llvm_create_vars (MonoCompile *cfg)
6932 MonoMethodSignature *sig;
6934 sig = mono_method_signature (cfg->method);
6935 if (cfg->gsharedvt && cfg->llvm_only) {
6936 if (mini_is_gsharedvt_variable_signature (sig) && sig->ret->type != MONO_TYPE_VOID) {
6937 cfg->vret_addr = mono_compile_create_var (cfg, &mono_get_int32_class ()->byval_arg, OP_ARG);
6938 if (G_UNLIKELY (cfg->verbose_level > 1)) {
6939 printf ("vret_addr = ");
6940 mono_print_ins (cfg->vret_addr);
6944 mono_arch_create_vars (cfg);
6949 * mono_llvm_emit_call:
6951 * Same as mono_arch_emit_call () for LLVM.
6954 mono_llvm_emit_call (MonoCompile *cfg, MonoCallInst *call)
6957 MonoMethodSignature *sig;
6958 int i, n, stack_size;
6963 sig = call->signature;
6964 n = sig->param_count + sig->hasthis;
6966 call->cinfo = get_llvm_call_info (cfg, sig);
6968 if (cfg->disable_llvm)
6971 if (sig->call_convention == MONO_CALL_VARARG) {
6972 cfg->exception_message = g_strdup ("varargs");
6973 cfg->disable_llvm = TRUE;
6976 for (i = 0; i < n; ++i) {
6979 ainfo = call->cinfo->args + i;
6981 in = call->args [i];
6983 /* Simply remember the arguments */
6984 switch (ainfo->storage) {
6985 case LLVMArgNormal: {
6986 MonoType *t = (sig->hasthis && i == 0) ? &mono_get_intptr_class ()->byval_arg : ainfo->type;
6989 opcode = mono_type_to_regmove (cfg, t);
6990 if (opcode == OP_FMOVE) {
6991 MONO_INST_NEW (cfg, ins, OP_FMOVE);
6992 ins->dreg = mono_alloc_freg (cfg);
6993 } else if (opcode == OP_LMOVE) {
6994 MONO_INST_NEW (cfg, ins, OP_LMOVE);
6995 ins->dreg = mono_alloc_lreg (cfg);
6996 } else if (opcode == OP_RMOVE) {
6997 MONO_INST_NEW (cfg, ins, OP_RMOVE);
6998 ins->dreg = mono_alloc_freg (cfg);
7000 MONO_INST_NEW (cfg, ins, OP_MOVE);
7001 ins->dreg = mono_alloc_ireg (cfg);
7003 ins->sreg1 = in->dreg;
7006 case LLVMArgVtypeByVal:
7007 case LLVMArgVtypeByRef:
7008 case LLVMArgVtypeInReg:
7009 case LLVMArgVtypeAsScalar:
7010 case LLVMArgScalarByRef:
7011 case LLVMArgAsIArgs:
7012 case LLVMArgAsFpArgs:
7013 case LLVMArgGsharedvtVariable:
7014 case LLVMArgGsharedvtFixed:
7015 case LLVMArgGsharedvtFixedVtype:
7016 MONO_INST_NEW (cfg, ins, OP_LLVM_OUTARG_VT);
7017 ins->dreg = mono_alloc_ireg (cfg);
7018 ins->sreg1 = in->dreg;
7019 ins->inst_p0 = mono_mempool_alloc0 (cfg->mempool, sizeof (LLVMArgInfo));
7020 memcpy (ins->inst_p0, ainfo, sizeof (LLVMArgInfo));
7021 ins->inst_vtype = ainfo->type;
7022 ins->klass = mono_class_from_mono_type (ainfo->type);
7025 cfg->exception_message = g_strdup ("ainfo->storage");
7026 cfg->disable_llvm = TRUE;
7030 if (!cfg->disable_llvm) {
7031 MONO_ADD_INS (cfg->cbb, ins);
7032 mono_call_inst_add_outarg_reg (cfg, call, ins->dreg, 0, FALSE);
7037 static unsigned char*
7038 alloc_cb (LLVMValueRef function, int size)
7042 cfg = (MonoCompile*)mono_native_tls_get_value (current_cfg_tls_id);
7046 return (unsigned char*)mono_domain_code_reserve (cfg->domain, size);
7048 return (unsigned char*)mono_domain_code_reserve (mono_domain_get (), size);
7053 emitted_cb (LLVMValueRef function, void *start, void *end)
7057 cfg = (MonoCompile*)mono_native_tls_get_value (current_cfg_tls_id);
7059 cfg->code_len = (guint8*)end - (guint8*)start;
7063 exception_cb (void *data)
7066 MonoJitExceptionInfo *ei;
7067 guint32 ei_len, i, j, nested_len, nindex;
7068 gpointer *type_info;
7069 int this_reg, this_offset;
7071 cfg = (MonoCompile*)mono_native_tls_get_value (current_cfg_tls_id);
7075 * data points to a DWARF FDE structure, convert it to our unwind format and
7077 * An alternative would be to save it directly, and modify our unwinder to work
7080 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);
7081 if (cfg->verbose_level > 1)
7082 mono_print_unwind_info (cfg->encoded_unwind_ops, cfg->encoded_unwind_ops_len);
7084 /* Count nested clauses */
7086 for (i = 0; i < ei_len; ++i) {
7087 gint32 cindex1 = *(gint32*)type_info [i];
7088 MonoExceptionClause *clause1 = &cfg->header->clauses [cindex1];
7090 for (j = 0; j < cfg->header->num_clauses; ++j) {
7092 MonoExceptionClause *clause2 = &cfg->header->clauses [cindex2];
7094 if (cindex1 != cindex2 && clause1->try_offset >= clause2->try_offset && clause1->handler_offset <= clause2->handler_offset) {
7100 cfg->llvm_ex_info = (MonoJitExceptionInfo*)mono_mempool_alloc0 (cfg->mempool, (ei_len + nested_len) * sizeof (MonoJitExceptionInfo));
7101 cfg->llvm_ex_info_len = ei_len + nested_len;
7102 memcpy (cfg->llvm_ex_info, ei, ei_len * sizeof (MonoJitExceptionInfo));
7103 /* Fill the rest of the information from the type info */
7104 for (i = 0; i < ei_len; ++i) {
7105 gint32 clause_index = *(gint32*)type_info [i];
7106 MonoExceptionClause *clause = &cfg->header->clauses [clause_index];
7108 cfg->llvm_ex_info [i].flags = clause->flags;
7109 cfg->llvm_ex_info [i].data.catch_class = clause->data.catch_class;
7110 cfg->llvm_ex_info [i].clause_index = clause_index;
7114 * For nested clauses, the LLVM produced exception info associates the try interval with
7115 * the innermost handler, while mono expects it to be associated with all nesting clauses.
7116 * So add new clauses which use the IL info (catch class etc.) from the nesting clause,
7117 * and everything else from the nested clause.
7120 for (i = 0; i < ei_len; ++i) {
7121 gint32 cindex1 = *(gint32*)type_info [i];
7122 MonoExceptionClause *clause1 = &cfg->header->clauses [cindex1];
7124 for (j = 0; j < cfg->header->num_clauses; ++j) {
7126 MonoExceptionClause *clause2 = &cfg->header->clauses [cindex2];
7127 MonoJitExceptionInfo *nesting_ei, *nested_ei;
7129 if (cindex1 != cindex2 && clause1->try_offset >= clause2->try_offset && clause1->handler_offset <= clause2->handler_offset) {
7130 /* clause1 is the nested clause */
7131 nested_ei = &cfg->llvm_ex_info [i];
7132 nesting_ei = &cfg->llvm_ex_info [nindex];
7135 memcpy (nesting_ei, nested_ei, sizeof (MonoJitExceptionInfo));
7137 nesting_ei->flags = clause2->flags;
7138 nesting_ei->data.catch_class = clause2->data.catch_class;
7139 nesting_ei->clause_index = cindex2;
7143 g_assert (nindex == ei_len + nested_len);
7144 cfg->llvm_this_reg = this_reg;
7145 cfg->llvm_this_offset = this_offset;
7147 /* type_info [i] is cfg mempool allocated, no need to free it */
7154 dlsym_cb (const char *name, void **symbol)
7160 if (!strcmp (name, "__bzero")) {
7161 *symbol = (void*)bzero;
7163 current = mono_dl_open (NULL, 0, NULL);
7166 err = mono_dl_symbol (current, name, symbol);
7168 mono_dl_close (current);
7170 #ifdef MONO_ARCH_HAVE_CREATE_LLVM_NATIVE_THUNK
7171 *symbol = (char*)mono_arch_create_llvm_native_thunk (mono_domain_get (), (guint8*)(*symbol));
7177 AddFunc (LLVMModuleRef module, const char *name, LLVMTypeRef ret_type, LLVMTypeRef *param_types, int nparams)
7179 LLVMAddFunction (module, name, LLVMFunctionType (ret_type, param_types, nparams, FALSE));
7183 AddFunc2 (LLVMModuleRef module, const char *name, LLVMTypeRef ret_type, LLVMTypeRef param_type1, LLVMTypeRef param_type2)
7185 LLVMTypeRef param_types [4];
7187 param_types [0] = param_type1;
7188 param_types [1] = param_type2;
7190 AddFunc (module, name, ret_type, param_types, 2);
7194 add_intrinsics (LLVMModuleRef module)
7196 /* Emit declarations of instrinsics */
7198 * It would be nicer to emit only the intrinsics actually used, but LLVM's Module
7199 * type doesn't seem to do any locking.
7202 LLVMTypeRef params [] = { LLVMPointerType (LLVMInt8Type (), 0), LLVMInt8Type (), LLVMInt32Type (), LLVMInt32Type (), LLVMInt1Type () };
7204 memset_param_count = 5;
7205 memset_func_name = "llvm.memset.p0i8.i32";
7207 AddFunc (module, memset_func_name, LLVMVoidType (), params, memset_param_count);
7211 LLVMTypeRef params [] = { LLVMPointerType (LLVMInt8Type (), 0), LLVMPointerType (LLVMInt8Type (), 0), LLVMInt32Type (), LLVMInt32Type (), LLVMInt1Type () };
7213 memcpy_param_count = 5;
7214 memcpy_func_name = "llvm.memcpy.p0i8.p0i8.i32";
7216 AddFunc (module, memcpy_func_name, LLVMVoidType (), params, memcpy_param_count);
7220 LLVMTypeRef params [] = { LLVMDoubleType () };
7222 AddFunc (module, "llvm.sin.f64", LLVMDoubleType (), params, 1);
7223 AddFunc (module, "llvm.cos.f64", LLVMDoubleType (), params, 1);
7224 AddFunc (module, "llvm.sqrt.f64", LLVMDoubleType (), params, 1);
7226 /* This isn't an intrinsic, instead llvm seems to special case it by name */
7227 AddFunc (module, "fabs", LLVMDoubleType (), params, 1);
7231 LLVMTypeRef ovf_res_i32 [] = { LLVMInt32Type (), LLVMInt1Type () };
7232 LLVMTypeRef params [] = { LLVMInt32Type (), LLVMInt32Type () };
7233 LLVMTypeRef ret_type = LLVMStructType (ovf_res_i32, 2, FALSE);
7235 AddFunc (module, "llvm.sadd.with.overflow.i32", ret_type, params, 2);
7236 AddFunc (module, "llvm.sadd.with.overflow.i32", ret_type, params, 2);
7237 AddFunc (module, "llvm.uadd.with.overflow.i32", ret_type, params, 2);
7238 AddFunc (module, "llvm.ssub.with.overflow.i32", ret_type, params, 2);
7239 AddFunc (module, "llvm.usub.with.overflow.i32", ret_type, params, 2);
7240 AddFunc (module, "llvm.smul.with.overflow.i32", ret_type, params, 2);
7241 AddFunc (module, "llvm.umul.with.overflow.i32", ret_type, params, 2);
7245 LLVMTypeRef ovf_res_i64 [] = { LLVMInt64Type (), LLVMInt1Type () };
7246 LLVMTypeRef params [] = { LLVMInt64Type (), LLVMInt64Type () };
7247 LLVMTypeRef ret_type = LLVMStructType (ovf_res_i64, 2, FALSE);
7249 AddFunc (module, "llvm.sadd.with.overflow.i64", ret_type, params, 2);
7250 AddFunc (module, "llvm.uadd.with.overflow.i64", ret_type, params, 2);
7251 AddFunc (module, "llvm.ssub.with.overflow.i64", ret_type, params, 2);
7252 AddFunc (module, "llvm.usub.with.overflow.i64", ret_type, params, 2);
7253 AddFunc (module, "llvm.smul.with.overflow.i64", ret_type, params, 2);
7254 AddFunc (module, "llvm.umul.with.overflow.i64", ret_type, params, 2);
7257 AddFunc2 (module, "llvm.expect.i8", LLVMInt8Type (), LLVMInt8Type (), LLVMInt8Type ());
7258 AddFunc2 (module, "llvm.expect.i1", LLVMInt1Type (), LLVMInt1Type (), LLVMInt1Type ());
7262 AddFunc (module, "mono_personality", LLVMVoidType (), NULL, 0);
7264 AddFunc (module, "llvm_resume_unwind_trampoline", LLVMVoidType (), NULL, 0);
7267 /* SSE intrinsics */
7268 #if defined(TARGET_X86) || defined(TARGET_AMD64)
7270 LLVMTypeRef ret_type, arg_types [16];
7273 ret_type = type_to_simd_type (MONO_TYPE_I4);
7274 arg_types [0] = ret_type;
7275 arg_types [1] = ret_type;
7276 AddFunc (module, "llvm.x86.sse41.pminud", ret_type, arg_types, 2);
7277 AddFunc (module, "llvm.x86.sse41.pmaxud", ret_type, arg_types, 2);
7279 ret_type = type_to_simd_type (MONO_TYPE_I2);
7280 arg_types [0] = ret_type;
7281 arg_types [1] = ret_type;
7282 AddFunc (module, "llvm.x86.sse41.pminuw", ret_type, arg_types, 2);
7283 AddFunc (module, "llvm.x86.sse2.pmins.w", ret_type, arg_types, 2);
7284 AddFunc (module, "llvm.x86.sse41.pmaxuw", ret_type, arg_types, 2);
7285 AddFunc (module, "llvm.x86.sse2.padds.w", ret_type, arg_types, 2);
7286 AddFunc (module, "llvm.x86.sse2.psubs.w", ret_type, arg_types, 2);
7287 AddFunc (module, "llvm.x86.sse2.paddus.w", ret_type, arg_types, 2);
7288 AddFunc (module, "llvm.x86.sse2.psubus.w", ret_type, arg_types, 2);
7289 AddFunc (module, "llvm.x86.sse2.pavg.w", ret_type, arg_types, 2);
7290 AddFunc (module, "llvm.x86.sse2.pmulh.w", ret_type, arg_types, 2);
7291 AddFunc (module, "llvm.x86.sse2.pmulhu.w", ret_type, arg_types, 2);
7293 ret_type = type_to_simd_type (MONO_TYPE_I1);
7294 arg_types [0] = ret_type;
7295 arg_types [1] = ret_type;
7296 AddFunc (module, "llvm.x86.sse2.pminu.b", ret_type, arg_types, 2);
7297 AddFunc (module, "llvm.x86.sse2.pmaxu.b", ret_type, arg_types, 2);
7298 AddFunc (module, "llvm.x86.sse2.padds.b", ret_type, arg_types, 2);
7299 AddFunc (module, "llvm.x86.sse2.psubs.b", ret_type, arg_types, 2);
7300 AddFunc (module, "llvm.x86.sse2.paddus.b", ret_type, arg_types, 2);
7301 AddFunc (module, "llvm.x86.sse2.psubus.b", ret_type, arg_types, 2);
7302 AddFunc (module, "llvm.x86.sse2.pavg.b", ret_type, arg_types, 2);
7304 ret_type = type_to_simd_type (MONO_TYPE_R8);
7305 arg_types [0] = ret_type;
7306 arg_types [1] = ret_type;
7307 AddFunc (module, "llvm.x86.sse2.min.pd", ret_type, arg_types, 2);
7308 AddFunc (module, "llvm.x86.sse2.max.pd", ret_type, arg_types, 2);
7309 AddFunc (module, "llvm.x86.sse3.hadd.pd", ret_type, arg_types, 2);
7310 AddFunc (module, "llvm.x86.sse3.hsub.pd", ret_type, arg_types, 2);
7311 AddFunc (module, "llvm.x86.sse3.addsub.pd", ret_type, arg_types, 2);
7313 ret_type = type_to_simd_type (MONO_TYPE_R4);
7314 arg_types [0] = ret_type;
7315 arg_types [1] = ret_type;
7316 AddFunc (module, "llvm.x86.sse.min.ps", ret_type, arg_types, 2);
7317 AddFunc (module, "llvm.x86.sse.max.ps", ret_type, arg_types, 2);
7318 AddFunc (module, "llvm.x86.sse3.hadd.ps", ret_type, arg_types, 2);
7319 AddFunc (module, "llvm.x86.sse3.hsub.ps", ret_type, arg_types, 2);
7320 AddFunc (module, "llvm.x86.sse3.addsub.ps", ret_type, arg_types, 2);
7323 ret_type = type_to_simd_type (MONO_TYPE_I1);
7324 arg_types [0] = type_to_simd_type (MONO_TYPE_I2);
7325 arg_types [1] = type_to_simd_type (MONO_TYPE_I2);
7326 AddFunc (module, "llvm.x86.sse2.packsswb.128", ret_type, arg_types, 2);
7327 AddFunc (module, "llvm.x86.sse2.packuswb.128", ret_type, arg_types, 2);
7328 ret_type = type_to_simd_type (MONO_TYPE_I2);
7329 arg_types [0] = type_to_simd_type (MONO_TYPE_I4);
7330 arg_types [1] = type_to_simd_type (MONO_TYPE_I4);
7331 AddFunc (module, "llvm.x86.sse2.packssdw.128", ret_type, arg_types, 2);
7332 AddFunc (module, "llvm.x86.sse41.packusdw", ret_type, arg_types, 2);
7335 ret_type = type_to_simd_type (MONO_TYPE_R8);
7336 arg_types [0] = ret_type;
7337 arg_types [1] = ret_type;
7338 arg_types [2] = LLVMInt8Type ();
7339 AddFunc (module, "llvm.x86.sse2.cmp.pd", ret_type, arg_types, 3);
7340 ret_type = type_to_simd_type (MONO_TYPE_R4);
7341 arg_types [0] = ret_type;
7342 arg_types [1] = ret_type;
7343 arg_types [2] = LLVMInt8Type ();
7344 AddFunc (module, "llvm.x86.sse.cmp.ps", ret_type, arg_types, 3);
7346 /* Conversion ops */
7347 ret_type = type_to_simd_type (MONO_TYPE_R8);
7348 arg_types [0] = type_to_simd_type (MONO_TYPE_I4);
7349 AddFunc (module, "llvm.x86.sse2.cvtdq2pd", ret_type, arg_types, 1);
7350 ret_type = type_to_simd_type (MONO_TYPE_R4);
7351 arg_types [0] = type_to_simd_type (MONO_TYPE_I4);
7352 AddFunc (module, "llvm.x86.sse2.cvtdq2ps", ret_type, arg_types, 1);
7353 ret_type = type_to_simd_type (MONO_TYPE_I4);
7354 arg_types [0] = type_to_simd_type (MONO_TYPE_R8);
7355 AddFunc (module, "llvm.x86.sse2.cvtpd2dq", ret_type, arg_types, 1);
7356 ret_type = type_to_simd_type (MONO_TYPE_I4);
7357 arg_types [0] = type_to_simd_type (MONO_TYPE_R4);
7358 AddFunc (module, "llvm.x86.sse2.cvtps2dq", ret_type, arg_types, 1);
7359 ret_type = type_to_simd_type (MONO_TYPE_R4);
7360 arg_types [0] = type_to_simd_type (MONO_TYPE_R8);
7361 AddFunc (module, "llvm.x86.sse2.cvtpd2ps", ret_type, arg_types, 1);
7362 ret_type = type_to_simd_type (MONO_TYPE_R8);
7363 arg_types [0] = type_to_simd_type (MONO_TYPE_R4);
7364 AddFunc (module, "llvm.x86.sse2.cvtps2pd", ret_type, arg_types, 1);
7366 ret_type = type_to_simd_type (MONO_TYPE_I4);
7367 arg_types [0] = type_to_simd_type (MONO_TYPE_R8);
7368 AddFunc (module, "llvm.x86.sse2.cvttpd2dq", ret_type, arg_types, 1);
7369 ret_type = type_to_simd_type (MONO_TYPE_I4);
7370 arg_types [0] = type_to_simd_type (MONO_TYPE_R4);
7371 AddFunc (module, "llvm.x86.sse2.cvttps2dq", ret_type, arg_types, 1);
7374 ret_type = type_to_simd_type (MONO_TYPE_R8);
7375 arg_types [0] = ret_type;
7376 AddFunc (module, "llvm.x86.sse2.sqrt.pd", ret_type, arg_types, 1);
7377 ret_type = type_to_simd_type (MONO_TYPE_R4);
7378 arg_types [0] = ret_type;
7379 AddFunc (module, "llvm.x86.sse.sqrt.ps", ret_type, arg_types, 1);
7380 ret_type = type_to_simd_type (MONO_TYPE_R4);
7381 arg_types [0] = ret_type;
7382 AddFunc (module, "llvm.x86.sse.rsqrt.ps", ret_type, arg_types, 1);
7383 ret_type = type_to_simd_type (MONO_TYPE_R4);
7384 arg_types [0] = ret_type;
7385 AddFunc (module, "llvm.x86.sse.rcp.ps", ret_type, arg_types, 1);
7388 ret_type = type_to_simd_type (MONO_TYPE_I2);
7389 arg_types [0] = ret_type;
7390 arg_types [1] = LLVMInt32Type ();
7391 AddFunc (module, "llvm.x86.sse2.psrli.w", ret_type, arg_types, 2);
7392 AddFunc (module, "llvm.x86.sse2.psrai.w", ret_type, arg_types, 2);
7393 AddFunc (module, "llvm.x86.sse2.pslli.w", ret_type, arg_types, 2);
7394 ret_type = type_to_simd_type (MONO_TYPE_I4);
7395 arg_types [0] = ret_type;
7396 arg_types [1] = LLVMInt32Type ();
7397 AddFunc (module, "llvm.x86.sse2.psrli.d", ret_type, arg_types, 2);
7398 AddFunc (module, "llvm.x86.sse2.psrai.d", ret_type, arg_types, 2);
7399 AddFunc (module, "llvm.x86.sse2.pslli.d", ret_type, arg_types, 2);
7400 ret_type = type_to_simd_type (MONO_TYPE_I8);
7401 arg_types [0] = ret_type;
7402 arg_types [1] = LLVMInt32Type ();
7403 AddFunc (module, "llvm.x86.sse2.psrli.q", ret_type, arg_types, 2);
7404 AddFunc (module, "llvm.x86.sse2.pslli.q", ret_type, arg_types, 2);
7407 ret_type = LLVMInt32Type ();
7408 arg_types [0] = type_to_simd_type (MONO_TYPE_I1);
7409 AddFunc (module, "llvm.x86.sse2.pmovmskb.128", ret_type, arg_types, 1);
7412 AddFunc (module, "llvm.x86.sse2.pause", LLVMVoidType (), NULL, 0);
7415 /* Load/Store intrinsics */
7417 LLVMTypeRef arg_types [5];
7421 for (i = 1; i <= 8; i *= 2) {
7422 arg_types [0] = LLVMPointerType (LLVMIntType (i * 8), 0);
7423 arg_types [1] = LLVMInt32Type ();
7424 arg_types [2] = LLVMInt1Type ();
7425 arg_types [3] = LLVMInt32Type ();
7426 sprintf (name, "llvm.mono.load.i%d.p0i%d", i * 8, i * 8);
7427 AddFunc (module, name, LLVMIntType (i * 8), arg_types, 4);
7429 arg_types [0] = LLVMIntType (i * 8);
7430 arg_types [1] = LLVMPointerType (LLVMIntType (i * 8), 0);
7431 arg_types [2] = LLVMInt32Type ();
7432 arg_types [3] = LLVMInt1Type ();
7433 arg_types [4] = LLVMInt32Type ();
7434 sprintf (name, "llvm.mono.store.i%d.p0i%d", i * 8, i * 8);
7435 AddFunc (module, name, LLVMVoidType (), arg_types, 5);
7441 add_types (MonoLLVMModule *module)
7443 module->ptr_type = LLVMPointerType (sizeof (gpointer) == 8 ? LLVMInt64Type () : LLVMInt32Type (), 0);
7447 mono_llvm_init (void)
7449 mono_native_tls_alloc (¤t_cfg_tls_id, NULL);
7453 init_jit_module (MonoDomain *domain)
7455 MonoJitICallInfo *info;
7456 MonoJitDomainInfo *dinfo;
7457 MonoLLVMModule *module;
7460 dinfo = domain_jit_info (domain);
7461 if (dinfo->llvm_module)
7464 mono_loader_lock ();
7466 if (dinfo->llvm_module) {
7467 mono_loader_unlock ();
7471 module = g_new0 (MonoLLVMModule, 1);
7473 name = g_strdup_printf ("mono-%s", domain->friendly_name);
7474 module->lmodule = LLVMModuleCreateWithName (name);
7475 module->context = LLVMGetGlobalContext ();
7477 module->mono_ee = (MonoEERef*)mono_llvm_create_ee (LLVMCreateModuleProviderForExistingModule (module->lmodule), alloc_cb, emitted_cb, exception_cb, dlsym_cb, &module->ee);
7479 add_intrinsics (module->lmodule);
7482 module->llvm_types = g_hash_table_new (NULL, NULL);
7484 info = mono_find_jit_icall_by_name ("llvm_resume_unwind_trampoline");
7486 LLVMAddGlobalMapping (module->ee, LLVMGetNamedFunction (module->lmodule, "llvm_resume_unwind_trampoline"), (void*)info->func);
7488 mono_memory_barrier ();
7490 dinfo->llvm_module = module;
7492 mono_loader_unlock ();
7496 mono_llvm_cleanup (void)
7498 MonoLLVMModule *module = &aot_module;
7500 if (module->lmodule)
7501 LLVMDisposeModule (module->lmodule);
7503 if (module->context)
7504 LLVMContextDispose (module->context);
7508 mono_llvm_free_domain_info (MonoDomain *domain)
7510 MonoJitDomainInfo *info = domain_jit_info (domain);
7511 MonoLLVMModule *module = (MonoLLVMModule*)info->llvm_module;
7517 if (module->llvm_types)
7518 g_hash_table_destroy (module->llvm_types);
7520 mono_llvm_dispose_ee (module->mono_ee);
7522 if (module->bb_names) {
7523 for (i = 0; i < module->bb_names_len; ++i)
7524 g_free (module->bb_names [i]);
7525 g_free (module->bb_names);
7527 //LLVMDisposeModule (module->module);
7531 info->llvm_module = NULL;
7535 mono_llvm_create_aot_module (MonoAssembly *assembly, const char *global_prefix, gboolean emit_dwarf, gboolean static_link, gboolean llvm_only)
7537 MonoLLVMModule *module = &aot_module;
7539 /* Delete previous module */
7540 if (module->plt_entries)
7541 g_hash_table_destroy (module->plt_entries);
7542 if (module->lmodule)
7543 LLVMDisposeModule (module->lmodule);
7545 memset (module, 0, sizeof (aot_module));
7547 module->lmodule = LLVMModuleCreateWithName ("aot");
7548 module->assembly = assembly;
7549 module->global_prefix = g_strdup (global_prefix);
7550 module->got_symbol = g_strdup_printf ("%s_llvm_got", global_prefix);
7551 module->eh_frame_symbol = g_strdup_printf ("%s_eh_frame", global_prefix);
7552 module->get_method_symbol = g_strdup_printf ("%s_get_method", global_prefix);
7553 module->get_unbox_tramp_symbol = g_strdup_printf ("%s_get_unbox_tramp", global_prefix);
7554 module->external_symbols = TRUE;
7555 module->emit_dwarf = emit_dwarf;
7556 module->static_link = static_link;
7557 module->llvm_only = llvm_only;
7558 /* The first few entries are reserved */
7559 module->max_got_offset = 16;
7560 module->context = LLVMContextCreate ();
7563 /* clang ignores our debug info because it has an invalid version */
7564 module->emit_dwarf = FALSE;
7566 add_intrinsics (module->lmodule);
7571 * We couldn't compute the type of the LLVM global representing the got because
7572 * its size is only known after all the methods have been emitted. So create
7573 * a dummy variable, and replace all uses it with the real got variable when
7574 * its size is known in mono_llvm_emit_aot_module ().
7577 LLVMTypeRef got_type = LLVMArrayType (module->ptr_type, 0);
7579 module->got_var = LLVMAddGlobal (module->lmodule, got_type, "mono_dummy_got");
7580 LLVMSetInitializer (module->got_var, LLVMConstNull (got_type));
7583 /* Add initialization array */
7585 LLVMTypeRef inited_type = LLVMArrayType (LLVMInt8Type (), 0);
7587 module->inited_var = LLVMAddGlobal (aot_module.lmodule, inited_type, "mono_inited_tmp");
7588 LLVMSetInitializer (module->inited_var, LLVMConstNull (inited_type));
7592 emit_init_icall_wrappers (module);
7594 emit_llvm_code_start (module);
7596 /* Add a dummy personality function */
7597 if (!use_debug_personality) {
7598 LLVMValueRef personality = LLVMAddFunction (module->lmodule, default_personality_name, LLVMFunctionType (LLVMInt32Type (), NULL, 0, TRUE));
7599 LLVMSetLinkage (personality, LLVMExternalLinkage);
7600 mark_as_used (module, personality);
7603 /* Add a reference to the c++ exception we throw/catch */
7605 LLVMTypeRef exc = LLVMPointerType (LLVMInt8Type (), 0);
7606 module->sentinel_exception = LLVMAddGlobal (module->lmodule, exc, "_ZTIPi");
7607 LLVMSetLinkage (module->sentinel_exception, LLVMExternalLinkage);
7608 mono_llvm_set_is_constant (module->sentinel_exception);
7611 module->llvm_types = g_hash_table_new (NULL, NULL);
7612 module->plt_entries = g_hash_table_new (g_str_hash, g_str_equal);
7613 module->plt_entries_ji = g_hash_table_new (NULL, NULL);
7614 module->direct_callables = g_hash_table_new (g_str_hash, g_str_equal);
7615 module->method_to_lmethod = g_hash_table_new (NULL, NULL);
7616 module->idx_to_lmethod = g_hash_table_new (NULL, NULL);
7617 module->idx_to_unbox_tramp = g_hash_table_new (NULL, NULL);
7618 module->method_to_callers = g_hash_table_new (NULL, NULL);
7622 llvm_array_from_uints (LLVMTypeRef el_type, guint32 *values, int nvalues)
7625 LLVMValueRef res, *vals;
7627 vals = g_new0 (LLVMValueRef, nvalues);
7628 for (i = 0; i < nvalues; ++i)
7629 vals [i] = LLVMConstInt (LLVMInt32Type (), values [i], FALSE);
7630 res = LLVMConstArray (LLVMInt32Type (), vals, nvalues);
7636 * mono_llvm_emit_aot_file_info:
7638 * Emit the MonoAotFileInfo structure.
7639 * Same as emit_aot_file_info () in aot-compiler.c.
7642 mono_llvm_emit_aot_file_info (MonoAotFileInfo *info, gboolean has_jitted_code)
7644 MonoLLVMModule *module = &aot_module;
7646 /* Save these for later */
7647 memcpy (&module->aot_info, info, sizeof (MonoAotFileInfo));
7648 module->has_jitted_code = has_jitted_code;
7652 * mono_llvm_emit_aot_data:
7654 * Emit the binary data DATA pointed to by symbol SYMBOL.
7657 mono_llvm_emit_aot_data (const char *symbol, guint8 *data, int data_len)
7659 MonoLLVMModule *module = &aot_module;
7663 type = LLVMArrayType (LLVMInt8Type (), data_len);
7664 d = LLVMAddGlobal (module->lmodule, type, symbol);
7665 LLVMSetVisibility (d, LLVMHiddenVisibility);
7666 LLVMSetLinkage (d, LLVMInternalLinkage);
7667 LLVMSetInitializer (d, mono_llvm_create_constant_data_array (data, data_len));
7668 mono_llvm_set_is_constant (d);
7671 /* Add a reference to a global defined in JITted code */
7673 AddJitGlobal (MonoLLVMModule *module, LLVMTypeRef type, const char *name)
7678 s = g_strdup_printf ("%s%s", module->global_prefix, name);
7679 v = LLVMAddGlobal (module->lmodule, LLVMInt8Type (), s);
7685 emit_aot_file_info (MonoLLVMModule *module)
7687 LLVMTypeRef file_info_type;
7688 LLVMTypeRef *eltypes, eltype;
7689 LLVMValueRef info_var;
7690 LLVMValueRef *fields;
7691 int i, nfields, tindex;
7692 MonoAotFileInfo *info;
7693 LLVMModuleRef lmodule = module->lmodule;
7695 info = &module->aot_info;
7697 /* Create an LLVM type to represent MonoAotFileInfo */
7698 nfields = 2 + MONO_AOT_FILE_INFO_NUM_SYMBOLS + 15 + 5;
7699 eltypes = g_new (LLVMTypeRef, nfields);
7701 eltypes [tindex ++] = LLVMInt32Type ();
7702 eltypes [tindex ++] = LLVMInt32Type ();
7704 for (i = 0; i < MONO_AOT_FILE_INFO_NUM_SYMBOLS; ++i)
7705 eltypes [tindex ++] = LLVMPointerType (LLVMInt8Type (), 0);
7707 for (i = 0; i < 15; ++i)
7708 eltypes [tindex ++] = LLVMInt32Type ();
7710 eltypes [tindex ++] = LLVMArrayType (LLVMInt32Type (), MONO_AOT_TABLE_NUM);
7711 for (i = 0; i < 4; ++i)
7712 eltypes [tindex ++] = LLVMArrayType (LLVMInt32Type (), MONO_AOT_TRAMP_NUM);
7713 g_assert (tindex == nfields);
7714 file_info_type = LLVMStructCreateNamed (module->context, "MonoAotFileInfo");
7715 LLVMStructSetBody (file_info_type, eltypes, nfields, FALSE);
7717 info_var = LLVMAddGlobal (lmodule, file_info_type, "mono_aot_file_info");
7718 if (module->static_link) {
7719 LLVMSetVisibility (info_var, LLVMHiddenVisibility);
7720 LLVMSetLinkage (info_var, LLVMInternalLinkage);
7722 fields = g_new (LLVMValueRef, nfields);
7724 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->version, FALSE);
7725 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->dummy, FALSE);
7729 * We use LLVMGetNamedGlobal () for symbol which are defined in LLVM code, and LLVMAddGlobal ()
7730 * for symbols defined in the .s file emitted by the aot compiler.
7732 eltype = eltypes [tindex];
7733 if (module->llvm_only)
7734 fields [tindex ++] = LLVMConstNull (eltype);
7736 fields [tindex ++] = AddJitGlobal (module, eltype, "jit_got");
7737 fields [tindex ++] = module->got_var;
7738 /* llc defines this directly */
7739 if (!module->llvm_only) {
7740 fields [tindex ++] = LLVMAddGlobal (lmodule, eltype, module->eh_frame_symbol);
7741 fields [tindex ++] = LLVMConstNull (eltype);
7742 fields [tindex ++] = LLVMConstNull (eltype);
7744 fields [tindex ++] = LLVMConstNull (eltype);
7745 fields [tindex ++] = module->get_method;
7746 fields [tindex ++] = module->get_unbox_tramp;
7748 if (module->has_jitted_code) {
7749 fields [tindex ++] = AddJitGlobal (module, eltype, "jit_code_start");
7750 fields [tindex ++] = AddJitGlobal (module, eltype, "jit_code_end");
7752 fields [tindex ++] = LLVMConstNull (eltype);
7753 fields [tindex ++] = LLVMConstNull (eltype);
7755 if (!module->llvm_only)
7756 fields [tindex ++] = AddJitGlobal (module, eltype, "method_addresses");
7758 fields [tindex ++] = LLVMConstNull (eltype);
7759 if (info->flags & MONO_AOT_FILE_FLAG_SEPARATE_DATA) {
7760 for (i = 0; i < MONO_AOT_TABLE_NUM; ++i)
7761 fields [tindex ++] = LLVMConstNull (eltype);
7763 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "blob");
7764 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "class_name_table");
7765 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "class_info_offsets");
7766 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "method_info_offsets");
7767 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "ex_info_offsets");
7768 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "extra_method_info_offsets");
7769 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "extra_method_table");
7770 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "got_info_offsets");
7771 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "llvm_got_info_offsets");
7772 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "image_table");
7774 /* Not needed (mem_end) */
7775 fields [tindex ++] = LLVMConstNull (eltype);
7776 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "assembly_guid");
7777 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "runtime_version");
7778 if (info->trampoline_size [0]) {
7779 fields [tindex ++] = AddJitGlobal (module, eltype, "specific_trampolines");
7780 fields [tindex ++] = AddJitGlobal (module, eltype, "static_rgctx_trampolines");
7781 fields [tindex ++] = AddJitGlobal (module, eltype, "imt_thunks");
7782 fields [tindex ++] = AddJitGlobal (module, eltype, "gsharedvt_arg_trampolines");
7784 fields [tindex ++] = LLVMConstNull (eltype);
7785 fields [tindex ++] = LLVMConstNull (eltype);
7786 fields [tindex ++] = LLVMConstNull (eltype);
7787 fields [tindex ++] = LLVMConstNull (eltype);
7789 if (module->static_link && !module->llvm_only)
7790 fields [tindex ++] = AddJitGlobal (module, eltype, "globals");
7792 fields [tindex ++] = LLVMConstNull (eltype);
7793 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "assembly_name");
7794 if (!module->llvm_only) {
7795 fields [tindex ++] = AddJitGlobal (module, eltype, "plt");
7796 fields [tindex ++] = AddJitGlobal (module, eltype, "plt_end");
7797 fields [tindex ++] = AddJitGlobal (module, eltype, "unwind_info");
7798 fields [tindex ++] = AddJitGlobal (module, eltype, "unbox_trampolines");
7799 fields [tindex ++] = AddJitGlobal (module, eltype, "unbox_trampolines_end");
7800 fields [tindex ++] = AddJitGlobal (module, eltype, "unbox_trampoline_addresses");
7802 fields [tindex ++] = LLVMConstNull (eltype);
7803 fields [tindex ++] = LLVMConstNull (eltype);
7804 fields [tindex ++] = LLVMConstNull (eltype);
7805 fields [tindex ++] = LLVMConstNull (eltype);
7806 fields [tindex ++] = LLVMConstNull (eltype);
7807 fields [tindex ++] = LLVMConstNull (eltype);
7810 for (i = 0; i < MONO_AOT_FILE_INFO_NUM_SYMBOLS; ++i)
7811 fields [2 + i] = LLVMConstBitCast (fields [2 + i], eltype);
7814 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->plt_got_offset_base, FALSE);
7815 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->got_size, FALSE);
7816 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->plt_size, FALSE);
7817 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->nmethods, FALSE);
7818 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->flags, FALSE);
7819 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->opts, FALSE);
7820 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->simd_opts, FALSE);
7821 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->gc_name_index, FALSE);
7822 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->num_rgctx_fetch_trampolines, FALSE);
7823 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->double_align, FALSE);
7824 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->long_align, FALSE);
7825 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->generic_tramp_num, FALSE);
7826 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->tramp_page_size, FALSE);
7827 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->nshared_got_entries, FALSE);
7828 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->datafile_size, FALSE);
7830 fields [tindex ++] = llvm_array_from_uints (LLVMInt32Type (), info->table_offsets, MONO_AOT_TABLE_NUM);
7831 fields [tindex ++] = llvm_array_from_uints (LLVMInt32Type (), info->num_trampolines, MONO_AOT_TRAMP_NUM);
7832 fields [tindex ++] = llvm_array_from_uints (LLVMInt32Type (), info->trampoline_got_offset_base, MONO_AOT_TRAMP_NUM);
7833 fields [tindex ++] = llvm_array_from_uints (LLVMInt32Type (), info->trampoline_size, MONO_AOT_TRAMP_NUM);
7834 fields [tindex ++] = llvm_array_from_uints (LLVMInt32Type (), info->tramp_page_code_offsets, MONO_AOT_TRAMP_NUM);
7835 g_assert (tindex == nfields);
7837 LLVMSetInitializer (info_var, LLVMConstNamedStruct (file_info_type, fields, nfields));
7839 if (module->static_link) {
7843 s = g_strdup_printf ("mono_aot_module_%s_info", module->assembly->aname.name);
7844 /* Get rid of characters which cannot occur in symbols */
7846 for (p = s; *p; ++p) {
7847 if (!(isalnum (*p) || *p == '_'))
7850 var = LLVMAddGlobal (module->lmodule, LLVMPointerType (LLVMInt8Type (), 0), s);
7852 LLVMSetInitializer (var, LLVMConstBitCast (LLVMGetNamedGlobal (module->lmodule, "mono_aot_file_info"), LLVMPointerType (LLVMInt8Type (), 0)));
7853 LLVMSetLinkage (var, LLVMExternalLinkage);
7858 * Emit the aot module into the LLVM bitcode file FILENAME.
7861 mono_llvm_emit_aot_module (const char *filename, const char *cu_name)
7863 LLVMTypeRef got_type, inited_type;
7864 LLVMValueRef real_got, real_inited;
7865 MonoLLVMModule *module = &aot_module;
7867 emit_llvm_code_end (module);
7870 * Create the real got variable and replace all uses of the dummy variable with
7873 got_type = LLVMArrayType (module->ptr_type, module->max_got_offset + 1);
7874 real_got = LLVMAddGlobal (module->lmodule, got_type, module->got_symbol);
7875 LLVMSetInitializer (real_got, LLVMConstNull (got_type));
7876 if (module->external_symbols) {
7877 LLVMSetLinkage (real_got, LLVMExternalLinkage);
7878 LLVMSetVisibility (real_got, LLVMHiddenVisibility);
7880 LLVMSetLinkage (real_got, LLVMInternalLinkage);
7882 mono_llvm_replace_uses_of (module->got_var, real_got);
7884 mark_as_used (&aot_module, real_got);
7886 /* Delete the dummy got so it doesn't become a global */
7887 LLVMDeleteGlobal (module->got_var);
7888 module->got_var = real_got;
7891 * Same for the init_var
7893 if (module->llvm_only) {
7894 inited_type = LLVMArrayType (LLVMInt8Type (), module->max_inited_idx + 1);
7895 real_inited = LLVMAddGlobal (module->lmodule, inited_type, "mono_inited");
7896 LLVMSetInitializer (real_inited, LLVMConstNull (inited_type));
7897 LLVMSetLinkage (real_inited, LLVMInternalLinkage);
7898 mono_llvm_replace_uses_of (module->inited_var, real_inited);
7899 LLVMDeleteGlobal (module->inited_var);
7902 if (module->llvm_only) {
7903 emit_get_method (&aot_module);
7904 emit_get_unbox_tramp (&aot_module);
7907 emit_llvm_used (&aot_module);
7908 emit_dbg_info (&aot_module, filename, cu_name);
7909 emit_aot_file_info (&aot_module);
7912 * Replace GOT entries for directly callable methods with the methods themselves.
7913 * It would be easier to implement this by predefining all methods before compiling
7914 * their bodies, but that couldn't handle the case when a method fails to compile
7917 if (module->llvm_only) {
7918 GHashTableIter iter;
7920 GSList *callers, *l;
7922 g_hash_table_iter_init (&iter, module->method_to_callers);
7923 while (g_hash_table_iter_next (&iter, (void**)&method, (void**)&callers)) {
7924 LLVMValueRef lmethod;
7926 lmethod = (LLVMValueRef)g_hash_table_lookup (module->method_to_lmethod, method);
7928 for (l = callers; l; l = l->next) {
7929 LLVMValueRef caller = (LLVMValueRef)l->data;
7931 mono_llvm_replace_uses_of (caller, lmethod);
7937 /* Replace PLT entries for directly callable methods with the methods themselves */
7939 GHashTableIter iter;
7941 LLVMValueRef callee;
7943 g_hash_table_iter_init (&iter, module->plt_entries_ji);
7944 while (g_hash_table_iter_next (&iter, (void**)&ji, (void**)&callee)) {
7945 if (mono_aot_is_direct_callable (ji)) {
7946 LLVMValueRef lmethod;
7948 lmethod = (LLVMValueRef)g_hash_table_lookup (module->method_to_lmethod, ji->data.method);
7949 /* The types might not match because the caller might pass an rgctx */
7950 if (lmethod && LLVMTypeOf (callee) == LLVMTypeOf (lmethod)) {
7951 mono_llvm_replace_uses_of (callee, lmethod);
7952 mono_aot_mark_unused_llvm_plt_entry (ji);
7962 if (LLVMVerifyModule (module->module, LLVMReturnStatusAction, &verifier_err)) {
7963 g_assert_not_reached ();
7968 LLVMWriteBitcodeToFile (module->lmodule, filename);
7973 md_string (const char *s)
7975 return LLVMMDString (s, strlen (s));
7978 /* Debugging support */
7981 emit_dbg_info (MonoLLVMModule *module, const char *filename, const char *cu_name)
7983 LLVMModuleRef lmodule = module->lmodule;
7984 LLVMValueRef args [16], cu_args [16], cu, ver;
7986 char *build_info, *s, *dir;
7989 * This can only be enabled when LLVM code is emitted into a separate object
7990 * file, since the AOT compiler also emits dwarf info,
7991 * and the abbrev indexes will not be correct since llvm has added its own
7994 if (!module->emit_dwarf)
7998 * Emit dwarf info in the form of LLVM metadata. There is some
7999 * out-of-date documentation at:
8000 * http://llvm.org/docs/SourceLevelDebugging.html
8001 * but most of this was gathered from the llvm and
8006 cu_args [n_cuargs ++] = LLVMConstInt (LLVMInt32Type (), DW_TAG_compile_unit, FALSE);
8007 /* CU name/compilation dir */
8008 dir = g_path_get_dirname (filename);
8009 args [0] = LLVMMDString (cu_name, strlen (cu_name));
8010 args [1] = LLVMMDString (dir, strlen (dir));
8011 cu_args [n_cuargs ++] = LLVMMDNode (args, 2);
8014 cu_args [n_cuargs ++] = LLVMConstInt (LLVMInt32Type (), DW_LANG_C99, FALSE);
8016 build_info = mono_get_runtime_build_info ();
8017 s = g_strdup_printf ("Mono AOT Compiler %s (LLVM)", build_info);
8018 cu_args [n_cuargs ++] = LLVMMDString (s, strlen (s));
8019 g_free (build_info);
8021 cu_args [n_cuargs ++] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
8023 cu_args [n_cuargs ++] = LLVMMDString ("", strlen (""));
8024 /* Runtime version */
8025 cu_args [n_cuargs ++] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
8027 cu_args [n_cuargs ++] = LLVMMDNode (args, 0);
8028 cu_args [n_cuargs ++] = LLVMMDNode (args, 0);
8030 if (module->subprogram_mds) {
8034 mds = g_new0 (LLVMValueRef, module->subprogram_mds->len);
8035 for (i = 0; i < module->subprogram_mds->len; ++i)
8036 mds [i] = (LLVMValueRef)g_ptr_array_index (module->subprogram_mds, i);
8037 cu_args [n_cuargs ++] = LLVMMDNode (mds, module->subprogram_mds->len);
8039 cu_args [n_cuargs ++] = LLVMMDNode (args, 0);
8042 cu_args [n_cuargs ++] = LLVMMDNode (args, 0);
8043 /* Imported modules */
8044 cu_args [n_cuargs ++] = LLVMMDNode (args, 0);
8046 cu_args [n_cuargs ++] = LLVMMDString ("", strlen (""));
8047 /* DebugEmissionKind = FullDebug */
8048 cu_args [n_cuargs ++] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
8049 cu = LLVMMDNode (cu_args, n_cuargs);
8050 LLVMAddNamedMetadataOperand (lmodule, "llvm.dbg.cu", cu);
8052 args [0] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
8053 args [1] = LLVMMDString ("Dwarf Version", strlen ("Dwarf Version"));
8054 args [2] = LLVMConstInt (LLVMInt32Type (), 2, FALSE);
8055 ver = LLVMMDNode (args, 3);
8056 LLVMAddNamedMetadataOperand (lmodule, "llvm.module.flags", ver);
8058 args [0] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
8059 args [1] = LLVMMDString ("Debug Info Version", strlen ("Debug Info Version"));
8060 args [2] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
8061 ver = LLVMMDNode (args, 3);
8062 LLVMAddNamedMetadataOperand (lmodule, "llvm.module.flags", ver);
8066 emit_dbg_subprogram (EmitContext *ctx, MonoCompile *cfg, LLVMValueRef method, const char *name)
8068 MonoLLVMModule *module = ctx->module;
8069 MonoDebugMethodInfo *minfo = ctx->minfo;
8070 char *source_file, *dir, *filename;
8071 LLVMValueRef md, args [16], ctx_args [16], md_args [64], type_args [16], ctx_md, type_md;
8072 MonoSymSeqPoint *sym_seq_points;
8078 mono_debug_symfile_get_seq_points (minfo, &source_file, NULL, NULL, &sym_seq_points, &n_seq_points);
8080 source_file = g_strdup ("<unknown>");
8081 dir = g_path_get_dirname (source_file);
8082 filename = g_path_get_basename (source_file);
8084 ctx_args [0] = LLVMConstInt (LLVMInt32Type (), 0x29, FALSE);
8085 args [0] = md_string (filename);
8086 args [1] = md_string (dir);
8087 ctx_args [1] = LLVMMDNode (args, 2);
8088 ctx_md = LLVMMDNode (ctx_args, 2);
8090 type_args [0] = LLVMConstInt (LLVMInt32Type (), DW_TAG_subroutine_type, FALSE);
8091 type_args [1] = NULL;
8092 type_args [2] = NULL;
8093 type_args [3] = LLVMMDString ("", 0);
8094 type_args [4] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
8095 type_args [5] = LLVMConstInt (LLVMInt64Type (), 0, FALSE);
8096 type_args [6] = LLVMConstInt (LLVMInt64Type (), 0, FALSE);
8097 type_args [7] = LLVMConstInt (LLVMInt64Type (), 0, FALSE);
8098 type_args [8] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
8099 type_args [9] = NULL;
8100 type_args [10] = NULL;
8101 type_args [11] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
8102 type_args [12] = NULL;
8103 type_args [13] = NULL;
8104 type_args [14] = NULL;
8105 type_md = LLVMMDNode (type_args, 14);
8107 /* http://llvm.org/docs/SourceLevelDebugging.html#subprogram-descriptors */
8108 md_args [0] = LLVMConstInt (LLVMInt32Type (), DW_TAG_subprogram, FALSE);
8109 /* Source directory + file pair */
8110 args [0] = md_string (filename);
8111 args [1] = md_string (dir);
8112 md_args [1] = LLVMMDNode (args ,2);
8113 md_args [2] = ctx_md;
8114 md_args [3] = md_string (cfg->method->name);
8115 md_args [4] = md_string (name);
8116 md_args [5] = md_string (name);
8119 md_args [6] = LLVMConstInt (LLVMInt32Type (), sym_seq_points [0].line, FALSE);
8121 md_args [6] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
8123 md_args [7] = type_md;
8125 md_args [8] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
8127 md_args [9] = LLVMConstInt (LLVMInt1Type (), 1, FALSE);
8129 md_args [10] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
8130 /* Index into a virtual function */
8131 md_args [11] = NULL;
8132 md_args [12] = NULL;
8134 md_args [13] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
8136 md_args [14] = LLVMConstInt (LLVMInt1Type (), 1, FALSE);
8137 /* Pointer to LLVM function */
8138 md_args [15] = method;
8139 /* Function template parameter */
8140 md_args [16] = NULL;
8141 /* Function declaration descriptor */
8142 md_args [17] = NULL;
8143 /* List of function variables */
8144 md_args [18] = LLVMMDNode (args, 0);
8146 md_args [19] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
8147 md = LLVMMDNode (md_args, 20);
8149 if (!module->subprogram_mds)
8150 module->subprogram_mds = g_ptr_array_new ();
8151 g_ptr_array_add (module->subprogram_mds, md);
8155 g_free (source_file);
8156 g_free (sym_seq_points);
8162 emit_dbg_loc (EmitContext *ctx, LLVMBuilderRef builder, const unsigned char *cil_code)
8164 MonoCompile *cfg = ctx->cfg;
8166 if (ctx->minfo && cil_code && cil_code >= cfg->header->code && cil_code < cfg->header->code + cfg->header->code_size) {
8167 MonoDebugSourceLocation *loc;
8168 LLVMValueRef loc_md, md_args [16];
8171 loc = mono_debug_symfile_lookup_location (ctx->minfo, cil_code - cfg->header->code);
8175 md_args [nmd_args ++] = LLVMConstInt (LLVMInt32Type (), loc->row, FALSE);
8176 md_args [nmd_args ++] = LLVMConstInt (LLVMInt32Type (), loc->column, FALSE);
8177 md_args [nmd_args ++] = ctx->dbg_md;
8178 md_args [nmd_args ++] = NULL;
8179 loc_md = LLVMMDNode (md_args, nmd_args);
8180 LLVMSetCurrentDebugLocation (builder, loc_md);
8181 mono_debug_symfile_free_location (loc);
8187 default_mono_llvm_unhandled_exception (void)
8189 MonoJitTlsData *jit_tls = mono_get_jit_tls ();
8190 MonoObject *target = mono_gchandle_get_target (jit_tls->thrown_exc);
8192 mono_unhandled_exception (target);
8193 exit (mono_environment_exitcode_get ());
8198 - Emit LLVM IR from the mono IR using the LLVM C API.
8199 - The original arch specific code remains, so we can fall back to it if we run
8200 into something we can't handle.
8204 A partial list of issues:
8205 - Handling of opcodes which can throw exceptions.
8207 In the mono JIT, these are implemented using code like this:
8214 push throw_pos - method
8215 call <exception trampoline>
8217 The problematic part is push throw_pos - method, which cannot be represented
8218 in the LLVM IR, since it does not support label values.
8219 -> this can be implemented in AOT mode using inline asm + labels, but cannot
8220 be implemented in JIT mode ?
8221 -> a possible but slower implementation would use the normal exception
8222 throwing code but it would need to control the placement of the throw code
8223 (it needs to be exactly after the compare+branch).
8224 -> perhaps add a PC offset intrinsics ?
8226 - efficient implementation of .ovf opcodes.
8228 These are currently implemented as:
8229 <ins which sets the condition codes>
8232 Some overflow opcodes are now supported by LLVM SVN.
8234 - exception handling, unwinding.
8235 - SSA is disabled for methods with exception handlers
8236 - How to obtain unwind info for LLVM compiled methods ?
8237 -> this is now solved by converting the unwind info generated by LLVM
8239 - LLVM uses the c++ exception handling framework, while we use our home grown
8240 code, and couldn't use the c++ one:
8241 - its not supported under VC++, other exotic platforms.
8242 - it might be impossible to support filter clauses with it.
8246 The trampolines need a predictable call sequence, since they need to disasm
8247 the calling code to obtain register numbers / offsets.
8249 LLVM currently generates this code in non-JIT mode:
8250 mov -0x98(%rax),%eax
8252 Here, the vtable pointer is lost.
8253 -> solution: use one vtable trampoline per class.
8255 - passing/receiving the IMT pointer/RGCTX.
8256 -> solution: pass them as normal arguments ?
8260 LLVM does not allow the specification of argument registers etc. This means
8261 that all calls are made according to the platform ABI.
8263 - passing/receiving vtypes.
8265 Vtypes passed/received in registers are handled by the front end by using
8266 a signature with scalar arguments, and loading the parts of the vtype into those
8269 Vtypes passed on the stack are handled using the 'byval' attribute.
8273 Supported though alloca, we need to emit the load/store code.
8277 The mono JIT uses pointer sized iregs/double fregs, while LLVM uses precisely
8278 typed registers, so we have to keep track of the precise LLVM type of each vreg.
8279 This is made easier because the IR is already in SSA form.
8280 An additional problem is that our IR is not consistent with types, i.e. i32/ia64
8281 types are frequently used incorrectly.
8286 Emit LLVM bytecode into a .bc file, compile it using llc into a .s file, then link
8287 it with the file containing the methods emitted by the JIT and the AOT data
8291 /* FIXME: Normalize some aspects of the mono IR to allow easier translation, like:
8292 * - each bblock should end with a branch
8293 * - setting the return value, making cfg->ret non-volatile
8294 * - avoid some transformations in the JIT which make it harder for us to generate
8296 * - use pointer types to help optimizations.