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)
6 * Licensed under the MIT license. See LICENSE file in the project root for full license information.
10 #include <mono/metadata/debug-helpers.h>
11 #include <mono/metadata/debug-mono-symfile.h>
12 #include <mono/metadata/mempool-internals.h>
13 #include <mono/metadata/environment.h>
14 #include <mono/metadata/object-internals.h>
15 #include <mono/metadata/abi-details.h>
16 #include <mono/utils/mono-tls.h>
17 #include <mono/utils/mono-dl.h>
18 #include <mono/utils/mono-time.h>
19 #include <mono/utils/freebsd-dwarf.h>
21 #ifndef __STDC_LIMIT_MACROS
22 #define __STDC_LIMIT_MACROS
24 #ifndef __STDC_CONSTANT_MACROS
25 #define __STDC_CONSTANT_MACROS
28 #include "llvm-c/BitWriter.h"
29 #include "llvm-c/Analysis.h"
31 #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."
48 #define ALIGN_PTR_TO(ptr,align) (gpointer)((((gssize)(ptr)) + (align - 1)) & (~(align - 1)))
51 * Information associated by mono with LLVM modules.
54 LLVMModuleRef lmodule;
55 LLVMValueRef throw_icall, rethrow, match_exc, throw_corlib_exception, resume_eh;
56 GHashTable *llvm_types;
58 const char *got_symbol;
59 const char *get_method_symbol;
60 const char *get_unbox_tramp_symbol;
61 GHashTable *plt_entries;
62 GHashTable *plt_entries_ji;
63 GHashTable *method_to_lmethod;
64 GHashTable *direct_callables;
69 GPtrArray *subprogram_mds;
71 LLVMExecutionEngineRef ee;
72 gboolean external_symbols;
77 MonoAssembly *assembly;
79 MonoAotFileInfo aot_info;
80 const char *jit_got_symbol;
81 const char *eh_frame_symbol;
82 LLVMValueRef get_method, get_unbox_tramp;
83 LLVMValueRef init_method, init_method_gshared_mrgctx, init_method_gshared_this, init_method_gshared_vtable;
84 LLVMValueRef code_start, code_end;
85 LLVMValueRef inited_var;
86 int max_inited_idx, max_method_idx;
87 gboolean has_jitted_code;
90 GHashTable *idx_to_lmethod;
91 GHashTable *idx_to_unbox_tramp;
92 /* Maps a MonoMethod to LLVM instructions representing it */
93 GHashTable *method_to_callers;
94 LLVMContextRef context;
95 LLVMValueRef sentinel_exception;
96 void *di_builder, *cu;
100 * Information associated by the backend with mono basic blocks.
103 LLVMBasicBlockRef bblock, end_bblock;
104 LLVMValueRef finally_ind;
105 gboolean added, invoke_target;
107 * If this bblock is the start of a finally clause, this is a list of bblocks it
108 * needs to branch to in ENDFINALLY.
110 GSList *call_handler_return_bbs;
112 * If this bblock is the start of a finally clause, this is the bblock that
113 * CALL_HANDLER needs to branch to.
115 LLVMBasicBlockRef call_handler_target_bb;
116 /* The list of switch statements generated by ENDFINALLY instructions */
117 GSList *endfinally_switch_ins_list;
122 * Structure containing emit state
125 MonoMemPool *mempool;
127 /* Maps method names to the corresponding LLVMValueRef */
128 GHashTable *emitted_method_decls;
131 LLVMValueRef lmethod;
132 MonoLLVMModule *module;
133 LLVMModuleRef lmodule;
135 int sindex, default_index, ex_index;
136 LLVMBuilderRef builder;
137 LLVMValueRef *values, *addresses;
138 MonoType **vreg_cli_types;
140 MonoMethodSignature *sig;
142 GHashTable *region_to_handler;
143 GHashTable *clause_to_handler;
144 LLVMBuilderRef alloca_builder;
145 LLVMValueRef last_alloca;
146 LLVMValueRef rgctx_arg;
147 LLVMValueRef this_arg;
148 LLVMTypeRef *vreg_types;
149 LLVMTypeRef method_type;
150 LLVMBasicBlockRef init_bb, inited_bb;
152 gboolean *unreachable;
154 gboolean has_got_access;
155 gboolean is_linkonce;
156 int this_arg_pindex, rgctx_arg_pindex;
157 LLVMValueRef imt_rgctx_loc;
158 GHashTable *llvm_types;
160 MonoDebugMethodInfo *minfo;
162 /* For every clause, the clauses it is nested in */
165 GHashTable *exc_meta;
166 GHashTable *method_to_callers;
167 GPtrArray *phi_values;
168 GPtrArray *bblock_list;
170 GHashTable *jit_callees;
176 MonoBasicBlock *in_bb;
181 * Instruction metadata
182 * This is the same as ins_info, but LREG != IREG.
190 #define MINI_OP(a,b,dest,src1,src2) dest, src1, src2, ' ',
191 #define MINI_OP3(a,b,dest,src1,src2,src3) dest, src1, src2, src3,
198 /* keep in sync with the enum in mini.h */
201 #include "mini-ops.h"
206 #if SIZEOF_VOID_P == 4
207 #define GET_LONG_IMM(ins) (((guint64)(ins)->inst_ms_word << 32) | (guint64)(guint32)(ins)->inst_ls_word)
209 #define GET_LONG_IMM(ins) ((ins)->inst_imm)
212 #define LLVM_INS_INFO(opcode) (&llvm_ins_info [((opcode) - OP_START - 1) * 4])
215 #define TRACE_FAILURE(msg) do { printf ("%s\n", msg); } while (0)
217 #define TRACE_FAILURE(msg)
221 #define IS_TARGET_X86 1
223 #define IS_TARGET_X86 0
227 #define IS_TARGET_AMD64 1
229 #define IS_TARGET_AMD64 0
232 #define ctx_ok(ctx) (!(ctx)->cfg->disable_llvm)
234 static LLVMIntPredicate cond_to_llvm_cond [] = {
247 static LLVMRealPredicate fpcond_to_llvm_cond [] = {
260 static MonoNativeTlsKey current_cfg_tls_id;
262 static MonoLLVMModule aot_module;
264 static GHashTable *intrins_id_to_name;
265 static GHashTable *intrins_name_to_id;
267 static void init_jit_module (MonoDomain *domain);
269 static void emit_dbg_loc (EmitContext *ctx, LLVMBuilderRef builder, const unsigned char *cil_code);
270 static LLVMValueRef emit_dbg_subprogram (EmitContext *ctx, MonoCompile *cfg, LLVMValueRef method, const char *name);
271 static void emit_dbg_info (MonoLLVMModule *module, const char *filename, const char *cu_name);
272 static void emit_cond_system_exception (EmitContext *ctx, MonoBasicBlock *bb, const char *exc_type, LLVMValueRef cmp);
273 static LLVMValueRef get_intrinsic (EmitContext *ctx, const char *name);
274 static void decode_llvm_eh_info (EmitContext *ctx, gpointer eh_frame);
277 set_failure (EmitContext *ctx, const char *message)
279 TRACE_FAILURE (reason);
280 ctx->cfg->exception_message = g_strdup (message);
281 ctx->cfg->disable_llvm = TRUE;
287 * The LLVM type with width == sizeof (gpointer)
292 return sizeof (gpointer) == 8 ? LLVMInt64Type () : LLVMInt32Type ();
298 return sizeof (gpointer) == 8 ? LLVMPointerType (LLVMInt64Type (), 0) : LLVMPointerType (LLVMInt32Type (), 0);
304 return sizeof (gpointer) == 8 ? LLVMPointerType (LLVMInt64Type (), 0) : LLVMPointerType (LLVMInt32Type (), 0);
310 * Return the size of the LLVM representation of the vtype T.
313 get_vtype_size (MonoType *t)
317 size = mono_class_value_size (mono_class_from_mono_type (t), NULL);
319 /* LLVMArgAsIArgs depends on this since it stores whole words */
320 while (size < 2 * sizeof (gpointer) && mono_is_power_of_two (size) == -1)
327 * simd_class_to_llvm_type:
329 * Return the LLVM type corresponding to the Mono.SIMD class KLASS
332 simd_class_to_llvm_type (EmitContext *ctx, MonoClass *klass)
334 if (!strcmp (klass->name, "Vector2d")) {
335 return LLVMVectorType (LLVMDoubleType (), 2);
336 } else if (!strcmp (klass->name, "Vector2l")) {
337 return LLVMVectorType (LLVMInt64Type (), 2);
338 } else if (!strcmp (klass->name, "Vector2ul")) {
339 return LLVMVectorType (LLVMInt64Type (), 2);
340 } else if (!strcmp (klass->name, "Vector4i")) {
341 return LLVMVectorType (LLVMInt32Type (), 4);
342 } else if (!strcmp (klass->name, "Vector4ui")) {
343 return LLVMVectorType (LLVMInt32Type (), 4);
344 } else if (!strcmp (klass->name, "Vector4f")) {
345 return LLVMVectorType (LLVMFloatType (), 4);
346 } else if (!strcmp (klass->name, "Vector8s")) {
347 return LLVMVectorType (LLVMInt16Type (), 8);
348 } else if (!strcmp (klass->name, "Vector8us")) {
349 return LLVMVectorType (LLVMInt16Type (), 8);
350 } else if (!strcmp (klass->name, "Vector16sb")) {
351 return LLVMVectorType (LLVMInt8Type (), 16);
352 } else if (!strcmp (klass->name, "Vector16b")) {
353 return LLVMVectorType (LLVMInt8Type (), 16);
355 printf ("%s\n", klass->name);
361 /* Return the 128 bit SIMD type corresponding to the mono type TYPE */
362 static inline G_GNUC_UNUSED LLVMTypeRef
363 type_to_simd_type (int type)
367 return LLVMVectorType (LLVMInt8Type (), 16);
369 return LLVMVectorType (LLVMInt16Type (), 8);
371 return LLVMVectorType (LLVMInt32Type (), 4);
373 return LLVMVectorType (LLVMInt64Type (), 2);
375 return LLVMVectorType (LLVMDoubleType (), 2);
377 return LLVMVectorType (LLVMFloatType (), 4);
379 g_assert_not_reached ();
385 create_llvm_type_for_type (MonoLLVMModule *module, MonoClass *klass)
387 int i, size, nfields, esize;
388 LLVMTypeRef *eltypes;
393 t = &klass->byval_arg;
395 if (mini_type_is_hfa (t, &nfields, &esize)) {
397 * This is needed on arm64 where HFAs are returned in
401 eltypes = g_new (LLVMTypeRef, size);
402 for (i = 0; i < size; ++i)
403 eltypes [i] = esize == 4 ? LLVMFloatType () : LLVMDoubleType ();
405 size = get_vtype_size (t);
407 eltypes = g_new (LLVMTypeRef, size);
408 for (i = 0; i < size; ++i)
409 eltypes [i] = LLVMInt8Type ();
412 name = mono_type_full_name (&klass->byval_arg);
413 ltype = LLVMStructCreateNamed (module->context, name);
414 LLVMStructSetBody (ltype, eltypes, size, FALSE);
424 * Return the LLVM type corresponding to T.
427 type_to_llvm_type (EmitContext *ctx, MonoType *t)
429 t = mini_get_underlying_type (t);
433 return LLVMVoidType ();
435 return LLVMInt8Type ();
437 return LLVMInt16Type ();
439 return LLVMInt32Type ();
441 return LLVMInt8Type ();
443 return LLVMInt16Type ();
445 return LLVMInt32Type ();
446 case MONO_TYPE_BOOLEAN:
447 return LLVMInt8Type ();
450 return LLVMInt64Type ();
452 return LLVMInt16Type ();
454 return LLVMFloatType ();
456 return LLVMDoubleType ();
459 return IntPtrType ();
460 case MONO_TYPE_OBJECT:
461 case MONO_TYPE_CLASS:
462 case MONO_TYPE_ARRAY:
463 case MONO_TYPE_SZARRAY:
464 case MONO_TYPE_STRING:
466 return ObjRefType ();
469 /* Because of generic sharing */
470 return ObjRefType ();
471 case MONO_TYPE_GENERICINST:
472 if (!mono_type_generic_inst_is_valuetype (t))
473 return ObjRefType ();
475 case MONO_TYPE_VALUETYPE:
476 case MONO_TYPE_TYPEDBYREF: {
480 klass = mono_class_from_mono_type (t);
482 if (MONO_CLASS_IS_SIMD (ctx->cfg, klass))
483 return simd_class_to_llvm_type (ctx, klass);
486 return type_to_llvm_type (ctx, mono_class_enum_basetype (klass));
488 ltype = (LLVMTypeRef)g_hash_table_lookup (ctx->module->llvm_types, klass);
490 ltype = create_llvm_type_for_type (ctx->module, klass);
491 g_hash_table_insert (ctx->module->llvm_types, klass, ltype);
497 printf ("X: %d\n", t->type);
498 ctx->cfg->exception_message = g_strdup_printf ("type %s", mono_type_full_name (t));
499 ctx->cfg->disable_llvm = TRUE;
507 * Return whenever T is an unsigned int type.
510 type_is_unsigned (EmitContext *ctx, MonoType *t)
512 t = mini_get_underlying_type (t);
528 * type_to_llvm_arg_type:
530 * Same as type_to_llvm_type, but treat i8/i16 as i32.
533 type_to_llvm_arg_type (EmitContext *ctx, MonoType *t)
535 LLVMTypeRef ptype = type_to_llvm_type (ctx, t);
537 if (ctx->cfg->llvm_only)
541 * This works on all abis except arm64/ios which passes multiple
542 * arguments in one stack slot.
545 if (ptype == LLVMInt8Type () || ptype == LLVMInt16Type ()) {
547 * LLVM generates code which only sets the lower bits, while JITted
548 * code expects all the bits to be set.
550 ptype = LLVMInt32Type ();
558 * llvm_type_to_stack_type:
560 * Return the LLVM type which needs to be used when a value of type TYPE is pushed
563 static G_GNUC_UNUSED LLVMTypeRef
564 llvm_type_to_stack_type (MonoCompile *cfg, LLVMTypeRef type)
568 if (type == LLVMInt8Type ())
569 return LLVMInt32Type ();
570 else if (type == LLVMInt16Type ())
571 return LLVMInt32Type ();
572 else if (!cfg->r4fp && type == LLVMFloatType ())
573 return LLVMDoubleType ();
579 * regtype_to_llvm_type:
581 * Return the LLVM type corresponding to the regtype C used in instruction
585 regtype_to_llvm_type (char c)
589 return LLVMInt32Type ();
591 return LLVMInt64Type ();
593 return LLVMDoubleType ();
602 * Return the LLVM type corresponding to the unary/binary opcode OPCODE.
605 op_to_llvm_type (int opcode)
610 return LLVMInt8Type ();
613 return LLVMInt8Type ();
616 return LLVMInt16Type ();
619 return LLVMInt16Type ();
622 return LLVMInt32Type ();
625 return LLVMInt32Type ();
627 return LLVMInt64Type ();
629 return LLVMFloatType ();
631 return LLVMDoubleType ();
633 return LLVMInt64Type ();
635 return LLVMInt32Type ();
637 return LLVMInt64Type ();
642 return LLVMInt8Type ();
647 return LLVMInt16Type ();
649 return LLVMInt32Type ();
652 return sizeof (gpointer) == 8 ? LLVMInt64Type () : LLVMInt32Type ();
659 return LLVMInt32Type ();
666 return LLVMInt64Type ();
668 printf ("%s\n", mono_inst_name (opcode));
669 g_assert_not_reached ();
674 #define CLAUSE_START(clause) ((clause)->try_offset)
675 #define CLAUSE_END(clause) (((clause))->try_offset + ((clause))->try_len)
678 * load_store_to_llvm_type:
680 * Return the size/sign/zero extension corresponding to the load/store opcode
684 load_store_to_llvm_type (int opcode, int *size, gboolean *sext, gboolean *zext)
690 case OP_LOADI1_MEMBASE:
691 case OP_STOREI1_MEMBASE_REG:
692 case OP_STOREI1_MEMBASE_IMM:
693 case OP_ATOMIC_LOAD_I1:
694 case OP_ATOMIC_STORE_I1:
697 return LLVMInt8Type ();
698 case OP_LOADU1_MEMBASE:
700 case OP_ATOMIC_LOAD_U1:
701 case OP_ATOMIC_STORE_U1:
704 return LLVMInt8Type ();
705 case OP_LOADI2_MEMBASE:
706 case OP_STOREI2_MEMBASE_REG:
707 case OP_STOREI2_MEMBASE_IMM:
708 case OP_ATOMIC_LOAD_I2:
709 case OP_ATOMIC_STORE_I2:
712 return LLVMInt16Type ();
713 case OP_LOADU2_MEMBASE:
715 case OP_ATOMIC_LOAD_U2:
716 case OP_ATOMIC_STORE_U2:
719 return LLVMInt16Type ();
720 case OP_LOADI4_MEMBASE:
721 case OP_LOADU4_MEMBASE:
724 case OP_STOREI4_MEMBASE_REG:
725 case OP_STOREI4_MEMBASE_IMM:
726 case OP_ATOMIC_LOAD_I4:
727 case OP_ATOMIC_STORE_I4:
728 case OP_ATOMIC_LOAD_U4:
729 case OP_ATOMIC_STORE_U4:
731 return LLVMInt32Type ();
732 case OP_LOADI8_MEMBASE:
734 case OP_STOREI8_MEMBASE_REG:
735 case OP_STOREI8_MEMBASE_IMM:
736 case OP_ATOMIC_LOAD_I8:
737 case OP_ATOMIC_STORE_I8:
738 case OP_ATOMIC_LOAD_U8:
739 case OP_ATOMIC_STORE_U8:
741 return LLVMInt64Type ();
742 case OP_LOADR4_MEMBASE:
743 case OP_STORER4_MEMBASE_REG:
744 case OP_ATOMIC_LOAD_R4:
745 case OP_ATOMIC_STORE_R4:
747 return LLVMFloatType ();
748 case OP_LOADR8_MEMBASE:
749 case OP_STORER8_MEMBASE_REG:
750 case OP_ATOMIC_LOAD_R8:
751 case OP_ATOMIC_STORE_R8:
753 return LLVMDoubleType ();
754 case OP_LOAD_MEMBASE:
756 case OP_STORE_MEMBASE_REG:
757 case OP_STORE_MEMBASE_IMM:
758 *size = sizeof (gpointer);
759 return IntPtrType ();
761 g_assert_not_reached ();
769 * Return the LLVM intrinsics corresponding to the overflow opcode OPCODE.
772 ovf_op_to_intrins (int opcode)
776 return "llvm.sadd.with.overflow.i32";
778 return "llvm.uadd.with.overflow.i32";
780 return "llvm.ssub.with.overflow.i32";
782 return "llvm.usub.with.overflow.i32";
784 return "llvm.smul.with.overflow.i32";
786 return "llvm.umul.with.overflow.i32";
788 return "llvm.sadd.with.overflow.i64";
790 return "llvm.uadd.with.overflow.i64";
792 return "llvm.ssub.with.overflow.i64";
794 return "llvm.usub.with.overflow.i64";
796 return "llvm.smul.with.overflow.i64";
798 return "llvm.umul.with.overflow.i64";
800 g_assert_not_reached ();
806 simd_op_to_intrins (int opcode)
809 #if defined(TARGET_X86) || defined(TARGET_AMD64)
811 return "llvm.x86.sse2.min.pd";
813 return "llvm.x86.sse.min.ps";
815 return "llvm.x86.sse41.pminud";
817 return "llvm.x86.sse41.pminuw";
819 return "llvm.x86.sse2.pminu.b";
821 return "llvm.x86.sse2.pmins.w";
823 return "llvm.x86.sse2.max.pd";
825 return "llvm.x86.sse.max.ps";
827 return "llvm.x86.sse3.hadd.pd";
829 return "llvm.x86.sse3.hadd.ps";
831 return "llvm.x86.sse3.hsub.pd";
833 return "llvm.x86.sse3.hsub.ps";
835 return "llvm.x86.sse41.pmaxud";
837 return "llvm.x86.sse41.pmaxuw";
839 return "llvm.x86.sse2.pmaxu.b";
841 return "llvm.x86.sse3.addsub.ps";
843 return "llvm.x86.sse3.addsub.pd";
844 case OP_EXTRACT_MASK:
845 return "llvm.x86.sse2.pmovmskb.128";
848 return "llvm.x86.sse2.psrli.w";
851 return "llvm.x86.sse2.psrli.d";
854 return "llvm.x86.sse2.psrli.q";
857 return "llvm.x86.sse2.pslli.w";
860 return "llvm.x86.sse2.pslli.d";
863 return "llvm.x86.sse2.pslli.q";
866 return "llvm.x86.sse2.psrai.w";
869 return "llvm.x86.sse2.psrai.d";
871 return "llvm.x86.sse2.padds.b";
873 return "llvm.x86.sse2.padds.w";
875 return "llvm.x86.sse2.psubs.b";
877 return "llvm.x86.sse2.psubs.w";
878 case OP_PADDB_SAT_UN:
879 return "llvm.x86.sse2.paddus.b";
880 case OP_PADDW_SAT_UN:
881 return "llvm.x86.sse2.paddus.w";
882 case OP_PSUBB_SAT_UN:
883 return "llvm.x86.sse2.psubus.b";
884 case OP_PSUBW_SAT_UN:
885 return "llvm.x86.sse2.psubus.w";
887 return "llvm.x86.sse2.pavg.b";
889 return "llvm.x86.sse2.pavg.w";
891 return "llvm.x86.sse.sqrt.ps";
893 return "llvm.x86.sse2.sqrt.pd";
895 return "llvm.x86.sse.rsqrt.ps";
897 return "llvm.x86.sse.rcp.ps";
899 return "llvm.x86.sse2.cvtdq2pd";
901 return "llvm.x86.sse2.cvtdq2ps";
903 return "llvm.x86.sse2.cvtpd2dq";
905 return "llvm.x86.sse2.cvtps2dq";
907 return "llvm.x86.sse2.cvtpd2ps";
909 return "llvm.x86.sse2.cvtps2pd";
911 return "llvm.x86.sse2.cvttpd2dq";
913 return "llvm.x86.sse2.cvttps2dq";
915 return "llvm.x86.sse.cmp.ps";
917 return "llvm.x86.sse2.cmp.pd";
919 return "llvm.x86.sse2.packsswb.128";
921 return "llvm.x86.sse2.packssdw.128";
923 return "llvm.x86.sse2.packuswb.128";
925 return "llvm.x86.sse41.packusdw";
927 return "llvm.x86.sse2.pmulh.w";
928 case OP_PMULW_HIGH_UN:
929 return "llvm.x86.sse2.pmulhu.w";
932 g_assert_not_reached ();
938 simd_op_to_llvm_type (int opcode)
940 #if defined(TARGET_X86) || defined(TARGET_AMD64)
944 return type_to_simd_type (MONO_TYPE_R8);
947 return type_to_simd_type (MONO_TYPE_I8);
950 return type_to_simd_type (MONO_TYPE_I4);
955 return type_to_simd_type (MONO_TYPE_I2);
959 return type_to_simd_type (MONO_TYPE_I1);
961 return type_to_simd_type (MONO_TYPE_R4);
964 return type_to_simd_type (MONO_TYPE_I4);
968 return type_to_simd_type (MONO_TYPE_R8);
972 return type_to_simd_type (MONO_TYPE_R4);
973 case OP_EXTRACT_MASK:
974 return type_to_simd_type (MONO_TYPE_I1);
980 return type_to_simd_type (MONO_TYPE_R4);
983 return type_to_simd_type (MONO_TYPE_R8);
985 g_assert_not_reached ();
996 * Return the LLVM basic block corresponding to BB.
998 static LLVMBasicBlockRef
999 get_bb (EmitContext *ctx, MonoBasicBlock *bb)
1001 char bb_name_buf [128];
1004 if (ctx->bblocks [bb->block_num].bblock == NULL) {
1005 if (bb->flags & BB_EXCEPTION_HANDLER) {
1006 int clause_index = (mono_get_block_region_notry (ctx->cfg, bb->region) >> 8) - 1;
1007 sprintf (bb_name_buf, "EH_CLAUSE%d_BB%d", clause_index, bb->block_num);
1008 bb_name = bb_name_buf;
1009 } else if (bb->block_num < 256) {
1010 if (!ctx->module->bb_names) {
1011 ctx->module->bb_names_len = 256;
1012 ctx->module->bb_names = g_new0 (char*, ctx->module->bb_names_len);
1014 if (!ctx->module->bb_names [bb->block_num]) {
1017 n = g_strdup_printf ("BB%d", bb->block_num);
1018 mono_memory_barrier ();
1019 ctx->module->bb_names [bb->block_num] = n;
1021 bb_name = ctx->module->bb_names [bb->block_num];
1023 sprintf (bb_name_buf, "BB%d", bb->block_num);
1024 bb_name = bb_name_buf;
1027 ctx->bblocks [bb->block_num].bblock = LLVMAppendBasicBlock (ctx->lmethod, bb_name);
1028 ctx->bblocks [bb->block_num].end_bblock = ctx->bblocks [bb->block_num].bblock;
1031 return ctx->bblocks [bb->block_num].bblock;
1037 * Return the last LLVM bblock corresponding to BB.
1038 * This might not be equal to the bb returned by get_bb () since we need to generate
1039 * multiple LLVM bblocks for a mono bblock to handle throwing exceptions.
1041 static LLVMBasicBlockRef
1042 get_end_bb (EmitContext *ctx, MonoBasicBlock *bb)
1045 return ctx->bblocks [bb->block_num].end_bblock;
1048 static LLVMBasicBlockRef
1049 gen_bb (EmitContext *ctx, const char *prefix)
1053 sprintf (bb_name, "%s%d", prefix, ++ ctx->ex_index);
1054 return LLVMAppendBasicBlock (ctx->lmethod, bb_name);
1060 * Return the target of the patch identified by TYPE and TARGET.
1063 resolve_patch (MonoCompile *cfg, MonoJumpInfoType type, gconstpointer target)
1069 memset (&ji, 0, sizeof (ji));
1071 ji.data.target = target;
1073 res = mono_resolve_patch_target (cfg->method, cfg->domain, NULL, &ji, FALSE, &error);
1074 mono_error_assert_ok (&error);
1082 * Emit code to convert the LLVM value V to DTYPE.
1085 convert_full (EmitContext *ctx, LLVMValueRef v, LLVMTypeRef dtype, gboolean is_unsigned)
1087 LLVMTypeRef stype = LLVMTypeOf (v);
1089 if (stype != dtype) {
1090 gboolean ext = FALSE;
1093 if (dtype == LLVMInt64Type () && (stype == LLVMInt32Type () || stype == LLVMInt16Type () || stype == LLVMInt8Type ()))
1095 else if (dtype == LLVMInt32Type () && (stype == LLVMInt16Type () || stype == LLVMInt8Type ()))
1097 else if (dtype == LLVMInt16Type () && (stype == LLVMInt8Type ()))
1101 return is_unsigned ? LLVMBuildZExt (ctx->builder, v, dtype, "") : LLVMBuildSExt (ctx->builder, v, dtype, "");
1103 if (dtype == LLVMDoubleType () && stype == LLVMFloatType ())
1104 return LLVMBuildFPExt (ctx->builder, v, dtype, "");
1107 if (stype == LLVMInt64Type () && (dtype == LLVMInt32Type () || dtype == LLVMInt16Type () || dtype == LLVMInt8Type ()))
1108 return LLVMBuildTrunc (ctx->builder, v, dtype, "");
1109 if (stype == LLVMInt32Type () && (dtype == LLVMInt16Type () || dtype == LLVMInt8Type ()))
1110 return LLVMBuildTrunc (ctx->builder, v, dtype, "");
1111 if (stype == LLVMInt16Type () && dtype == LLVMInt8Type ())
1112 return LLVMBuildTrunc (ctx->builder, v, dtype, "");
1113 if (stype == LLVMDoubleType () && dtype == LLVMFloatType ())
1114 return LLVMBuildFPTrunc (ctx->builder, v, dtype, "");
1116 if (LLVMGetTypeKind (stype) == LLVMPointerTypeKind && LLVMGetTypeKind (dtype) == LLVMPointerTypeKind)
1117 return LLVMBuildBitCast (ctx->builder, v, dtype, "");
1118 if (LLVMGetTypeKind (dtype) == LLVMPointerTypeKind)
1119 return LLVMBuildIntToPtr (ctx->builder, v, dtype, "");
1120 if (LLVMGetTypeKind (stype) == LLVMPointerTypeKind)
1121 return LLVMBuildPtrToInt (ctx->builder, v, dtype, "");
1123 if (mono_arch_is_soft_float ()) {
1124 if (stype == LLVMInt32Type () && dtype == LLVMFloatType ())
1125 return LLVMBuildBitCast (ctx->builder, v, dtype, "");
1126 if (stype == LLVMInt32Type () && dtype == LLVMDoubleType ())
1127 return LLVMBuildBitCast (ctx->builder, LLVMBuildZExt (ctx->builder, v, LLVMInt64Type (), ""), dtype, "");
1130 if (LLVMGetTypeKind (stype) == LLVMVectorTypeKind && LLVMGetTypeKind (dtype) == LLVMVectorTypeKind)
1131 return LLVMBuildBitCast (ctx->builder, v, dtype, "");
1134 LLVMDumpValue (LLVMConstNull (dtype));
1135 g_assert_not_reached ();
1143 convert (EmitContext *ctx, LLVMValueRef v, LLVMTypeRef dtype)
1145 return convert_full (ctx, v, dtype, FALSE);
1149 * emit_volatile_load:
1151 * If vreg is volatile, emit a load from its address.
1154 emit_volatile_load (EmitContext *ctx, int vreg)
1158 LLVMValueRef v = LLVMBuildLoad (ctx->builder, ctx->addresses [vreg], "");
1159 t = ctx->vreg_cli_types [vreg];
1160 if (t && !t->byref) {
1162 * Might have to zero extend since llvm doesn't have
1165 if (t->type == MONO_TYPE_U1 || t->type == MONO_TYPE_U2 || t->type == MONO_TYPE_CHAR || t->type == MONO_TYPE_BOOLEAN)
1166 v = LLVMBuildZExt (ctx->builder, v, LLVMInt32Type (), "");
1167 else if (t->type == MONO_TYPE_I1 || t->type == MONO_TYPE_I2)
1168 v = LLVMBuildSExt (ctx->builder, v, LLVMInt32Type (), "");
1169 else if (t->type == MONO_TYPE_U8)
1170 v = LLVMBuildZExt (ctx->builder, v, LLVMInt64Type (), "");
1177 * emit_volatile_store:
1179 * If VREG is volatile, emit a store from its value to its address.
1182 emit_volatile_store (EmitContext *ctx, int vreg)
1184 MonoInst *var = get_vreg_to_inst (ctx->cfg, vreg);
1186 if (var && var->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT)) {
1187 g_assert (ctx->addresses [vreg]);
1188 LLVMBuildStore (ctx->builder, convert (ctx, ctx->values [vreg], type_to_llvm_type (ctx, var->inst_vtype)), ctx->addresses [vreg]);
1193 sig_to_llvm_sig_no_cinfo (EmitContext *ctx, MonoMethodSignature *sig)
1195 LLVMTypeRef ret_type;
1196 LLVMTypeRef *param_types = NULL;
1201 rtype = mini_get_underlying_type (sig->ret);
1202 ret_type = type_to_llvm_type (ctx, rtype);
1206 param_types = g_new0 (LLVMTypeRef, (sig->param_count * 8) + 3);
1210 param_types [pindex ++] = ThisType ();
1211 for (i = 0; i < sig->param_count; ++i)
1212 param_types [pindex ++] = type_to_llvm_arg_type (ctx, sig->params [i]);
1214 if (!ctx_ok (ctx)) {
1215 g_free (param_types);
1219 res = LLVMFunctionType (ret_type, param_types, pindex, FALSE);
1220 g_free (param_types);
1226 * sig_to_llvm_sig_full:
1228 * Return the LLVM signature corresponding to the mono signature SIG using the
1229 * calling convention information in CINFO. Fill out the parameter mapping information in CINFO.
1232 sig_to_llvm_sig_full (EmitContext *ctx, MonoMethodSignature *sig, LLVMCallInfo *cinfo)
1234 LLVMTypeRef ret_type;
1235 LLVMTypeRef *param_types = NULL;
1237 int i, j, pindex, vret_arg_pindex = 0;
1238 gboolean vretaddr = FALSE;
1242 return sig_to_llvm_sig_no_cinfo (ctx, sig);
1244 rtype = mini_get_underlying_type (sig->ret);
1245 ret_type = type_to_llvm_type (ctx, rtype);
1249 switch (cinfo->ret.storage) {
1250 case LLVMArgVtypeInReg:
1251 /* LLVM models this by returning an aggregate value */
1252 if (cinfo->ret.pair_storage [0] == LLVMArgInIReg && cinfo->ret.pair_storage [1] == LLVMArgNone) {
1253 LLVMTypeRef members [2];
1255 members [0] = IntPtrType ();
1256 ret_type = LLVMStructType (members, 1, FALSE);
1257 } else if (cinfo->ret.pair_storage [0] == LLVMArgNone && cinfo->ret.pair_storage [1] == LLVMArgNone) {
1259 ret_type = LLVMVoidType ();
1260 } else if (cinfo->ret.pair_storage [0] == LLVMArgInIReg && cinfo->ret.pair_storage [1] == LLVMArgInIReg) {
1261 LLVMTypeRef members [2];
1263 members [0] = IntPtrType ();
1264 members [1] = IntPtrType ();
1265 ret_type = LLVMStructType (members, 2, FALSE);
1267 g_assert_not_reached ();
1270 case LLVMArgVtypeByVal:
1271 /* Vtype returned normally by val */
1273 case LLVMArgVtypeAsScalar: {
1274 int size = mono_class_value_size (mono_class_from_mono_type (rtype), NULL);
1275 /* LLVM models this by returning an int */
1276 if (size < SIZEOF_VOID_P) {
1277 g_assert (cinfo->ret.nslots == 1);
1278 ret_type = LLVMIntType (size * 8);
1280 g_assert (cinfo->ret.nslots == 1 || cinfo->ret.nslots == 2);
1281 ret_type = LLVMIntType (cinfo->ret.nslots * sizeof (mgreg_t) * 8);
1285 case LLVMArgFpStruct: {
1286 /* Vtype returned as a fp struct */
1287 LLVMTypeRef members [16];
1289 /* Have to create our own structure since we don't map fp structures to LLVM fp structures yet */
1290 for (i = 0; i < cinfo->ret.nslots; ++i)
1291 members [i] = cinfo->ret.esize == 8 ? LLVMDoubleType () : LLVMFloatType ();
1292 ret_type = LLVMStructType (members, cinfo->ret.nslots, FALSE);
1295 case LLVMArgVtypeByRef:
1296 /* Vtype returned using a hidden argument */
1297 ret_type = LLVMVoidType ();
1299 case LLVMArgVtypeRetAddr:
1300 case LLVMArgGsharedvtFixed:
1301 case LLVMArgGsharedvtFixedVtype:
1302 case LLVMArgGsharedvtVariable:
1304 ret_type = LLVMVoidType ();
1310 param_types = g_new0 (LLVMTypeRef, (sig->param_count * 8) + 3);
1312 if (cinfo->ret.storage == LLVMArgVtypeByRef) {
1314 * Has to be the first argument because of the sret argument attribute
1315 * FIXME: This might conflict with passing 'this' as the first argument, but
1316 * this is only used on arm64 which has a dedicated struct return register.
1318 cinfo->vret_arg_pindex = pindex;
1319 param_types [pindex] = type_to_llvm_arg_type (ctx, sig->ret);
1320 if (!ctx_ok (ctx)) {
1321 g_free (param_types);
1324 param_types [pindex] = LLVMPointerType (param_types [pindex], 0);
1327 if (!ctx->llvm_only && cinfo->rgctx_arg) {
1328 cinfo->rgctx_arg_pindex = pindex;
1329 param_types [pindex] = ctx->module->ptr_type;
1332 if (cinfo->imt_arg) {
1333 cinfo->imt_arg_pindex = pindex;
1334 param_types [pindex] = ctx->module->ptr_type;
1338 /* Compute the index in the LLVM signature where the vret arg needs to be passed */
1339 vret_arg_pindex = pindex;
1340 if (cinfo->vret_arg_index == 1) {
1341 /* Add the slots consumed by the first argument */
1342 LLVMArgInfo *ainfo = &cinfo->args [0];
1343 switch (ainfo->storage) {
1344 case LLVMArgVtypeInReg:
1345 for (j = 0; j < 2; ++j) {
1346 if (ainfo->pair_storage [j] == LLVMArgInIReg)
1355 cinfo->vret_arg_pindex = vret_arg_pindex;
1358 if (vretaddr && vret_arg_pindex == pindex)
1359 param_types [pindex ++] = IntPtrType ();
1361 cinfo->this_arg_pindex = pindex;
1362 param_types [pindex ++] = ThisType ();
1363 cinfo->args [0].pindex = cinfo->this_arg_pindex;
1365 if (vretaddr && vret_arg_pindex == pindex)
1366 param_types [pindex ++] = IntPtrType ();
1367 for (i = 0; i < sig->param_count; ++i) {
1368 LLVMArgInfo *ainfo = &cinfo->args [i + sig->hasthis];
1370 if (vretaddr && vret_arg_pindex == pindex)
1371 param_types [pindex ++] = IntPtrType ();
1372 ainfo->pindex = pindex;
1374 switch (ainfo->storage) {
1375 case LLVMArgVtypeInReg:
1376 for (j = 0; j < 2; ++j) {
1377 switch (ainfo->pair_storage [j]) {
1379 param_types [pindex ++] = LLVMIntType (sizeof (gpointer) * 8);
1384 g_assert_not_reached ();
1388 case LLVMArgVtypeByVal:
1389 param_types [pindex] = type_to_llvm_arg_type (ctx, ainfo->type);
1392 param_types [pindex] = LLVMPointerType (param_types [pindex], 0);
1395 case LLVMArgAsIArgs:
1396 param_types [pindex] = LLVMArrayType (IntPtrType (), ainfo->nslots);
1399 case LLVMArgVtypeByRef:
1400 param_types [pindex] = type_to_llvm_arg_type (ctx, ainfo->type);
1403 param_types [pindex] = LLVMPointerType (param_types [pindex], 0);
1406 case LLVMArgAsFpArgs: {
1409 /* Emit dummy fp arguments if needed so the rest is passed on the stack */
1410 for (j = 0; j < ainfo->ndummy_fpargs; ++j)
1411 param_types [pindex ++] = LLVMDoubleType ();
1412 for (j = 0; j < ainfo->nslots; ++j)
1413 param_types [pindex ++] = ainfo->esize == 8 ? LLVMDoubleType () : LLVMFloatType ();
1416 case LLVMArgVtypeAsScalar:
1417 g_assert_not_reached ();
1419 case LLVMArgGsharedvtFixed:
1420 case LLVMArgGsharedvtFixedVtype:
1421 param_types [pindex ++] = LLVMPointerType (type_to_llvm_arg_type (ctx, ainfo->type), 0);
1423 case LLVMArgGsharedvtVariable:
1424 param_types [pindex ++] = LLVMPointerType (IntPtrType (), 0);
1427 param_types [pindex ++] = type_to_llvm_arg_type (ctx, ainfo->type);
1431 if (!ctx_ok (ctx)) {
1432 g_free (param_types);
1435 if (vretaddr && vret_arg_pindex == pindex)
1436 param_types [pindex ++] = IntPtrType ();
1437 if (ctx->llvm_only && cinfo->rgctx_arg) {
1438 /* Pass the rgctx as the last argument */
1439 cinfo->rgctx_arg_pindex = pindex;
1440 param_types [pindex] = ctx->module->ptr_type;
1444 res = LLVMFunctionType (ret_type, param_types, pindex, FALSE);
1445 g_free (param_types);
1451 sig_to_llvm_sig (EmitContext *ctx, MonoMethodSignature *sig)
1453 return sig_to_llvm_sig_full (ctx, sig, NULL);
1457 * LLVMFunctionType1:
1459 * Create an LLVM function type from the arguments.
1461 static G_GNUC_UNUSED LLVMTypeRef
1462 LLVMFunctionType0 (LLVMTypeRef ReturnType,
1465 return LLVMFunctionType (ReturnType, NULL, 0, IsVarArg);
1469 * LLVMFunctionType1:
1471 * Create an LLVM function type from the arguments.
1473 static G_GNUC_UNUSED LLVMTypeRef
1474 LLVMFunctionType1 (LLVMTypeRef ReturnType,
1475 LLVMTypeRef ParamType1,
1478 LLVMTypeRef param_types [1];
1480 param_types [0] = ParamType1;
1482 return LLVMFunctionType (ReturnType, param_types, 1, IsVarArg);
1486 * LLVMFunctionType2:
1488 * Create an LLVM function type from the arguments.
1490 static G_GNUC_UNUSED LLVMTypeRef
1491 LLVMFunctionType2 (LLVMTypeRef ReturnType,
1492 LLVMTypeRef ParamType1,
1493 LLVMTypeRef ParamType2,
1496 LLVMTypeRef param_types [2];
1498 param_types [0] = ParamType1;
1499 param_types [1] = ParamType2;
1501 return LLVMFunctionType (ReturnType, param_types, 2, IsVarArg);
1505 * LLVMFunctionType3:
1507 * Create an LLVM function type from the arguments.
1509 static G_GNUC_UNUSED LLVMTypeRef
1510 LLVMFunctionType3 (LLVMTypeRef ReturnType,
1511 LLVMTypeRef ParamType1,
1512 LLVMTypeRef ParamType2,
1513 LLVMTypeRef ParamType3,
1516 LLVMTypeRef param_types [3];
1518 param_types [0] = ParamType1;
1519 param_types [1] = ParamType2;
1520 param_types [2] = ParamType3;
1522 return LLVMFunctionType (ReturnType, param_types, 3, IsVarArg);
1525 static G_GNUC_UNUSED LLVMTypeRef
1526 LLVMFunctionType5 (LLVMTypeRef ReturnType,
1527 LLVMTypeRef ParamType1,
1528 LLVMTypeRef ParamType2,
1529 LLVMTypeRef ParamType3,
1530 LLVMTypeRef ParamType4,
1531 LLVMTypeRef ParamType5,
1534 LLVMTypeRef param_types [5];
1536 param_types [0] = ParamType1;
1537 param_types [1] = ParamType2;
1538 param_types [2] = ParamType3;
1539 param_types [3] = ParamType4;
1540 param_types [4] = ParamType5;
1542 return LLVMFunctionType (ReturnType, param_types, 5, IsVarArg);
1548 * Create an LLVM builder and remember it so it can be freed later.
1550 static LLVMBuilderRef
1551 create_builder (EmitContext *ctx)
1553 LLVMBuilderRef builder = LLVMCreateBuilder ();
1555 ctx->builders = g_slist_prepend_mempool (ctx->cfg->mempool, ctx->builders, builder);
1561 get_aotconst_name (MonoJumpInfoType type, gconstpointer data, int got_offset)
1566 case MONO_PATCH_INFO_INTERNAL_METHOD:
1567 name = g_strdup_printf ("jit_icall_%s", data);
1569 case MONO_PATCH_INFO_RGCTX_SLOT_INDEX: {
1570 MonoJumpInfoRgctxEntry *entry = (MonoJumpInfoRgctxEntry*)data;
1571 name = g_strdup_printf ("RGCTX_SLOT_INDEX_%s", mono_rgctx_info_type_to_str (entry->info_type));
1575 name = g_strdup_printf ("%s_%d", mono_ji_type_to_string (type), got_offset);
1583 get_aotconst_typed (EmitContext *ctx, MonoJumpInfoType type, gconstpointer data, LLVMTypeRef llvm_type)
1587 LLVMValueRef indexes [2];
1589 LLVMValueRef got_entry_addr, load;
1590 LLVMBuilderRef builder = ctx->builder;
1595 ji = g_new0 (MonoJumpInfo, 1);
1597 ji->data.target = data;
1599 ji = mono_aot_patch_info_dup (ji);
1601 ji->next = cfg->patch_info;
1602 cfg->patch_info = ji;
1604 got_offset = mono_aot_get_got_offset (cfg->patch_info);
1605 ctx->module->max_got_offset = MAX (ctx->module->max_got_offset, got_offset);
1607 * If the got slot is shared, it means its initialized when the aot image is loaded, so we don't need to
1608 * explicitly initialize it.
1610 if (!mono_aot_is_shared_got_offset (got_offset)) {
1611 //mono_print_ji (ji);
1613 ctx->has_got_access = TRUE;
1616 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
1617 indexes [1] = LLVMConstInt (LLVMInt32Type (), (gssize)got_offset, FALSE);
1618 got_entry_addr = LLVMBuildGEP (builder, ctx->module->got_var, indexes, 2, "");
1620 name = get_aotconst_name (type, data, got_offset);
1622 load = LLVMBuildLoad (builder, got_entry_addr, "");
1623 load = convert (ctx, load, llvm_type);
1624 LLVMSetValueName (load, name ? name : "");
1626 load = LLVMBuildLoad (builder, got_entry_addr, name ? name : "");
1629 //set_invariant_load_flag (load);
1635 get_aotconst (EmitContext *ctx, MonoJumpInfoType type, gconstpointer data)
1637 return get_aotconst_typed (ctx, type, data, NULL);
1641 get_callee (EmitContext *ctx, LLVMTypeRef llvm_sig, MonoJumpInfoType type, gconstpointer data)
1643 LLVMValueRef callee;
1645 if (ctx->llvm_only) {
1646 callee_name = mono_aot_get_direct_call_symbol (type, data);
1648 /* Directly callable */
1650 callee = (LLVMValueRef)g_hash_table_lookup (ctx->module->direct_callables, callee_name);
1652 callee = LLVMAddFunction (ctx->lmodule, callee_name, llvm_sig);
1654 LLVMSetVisibility (callee, LLVMHiddenVisibility);
1656 g_hash_table_insert (ctx->module->direct_callables, (char*)callee_name, callee);
1658 /* LLVMTypeRef's are uniqued */
1659 if (LLVMGetElementType (LLVMTypeOf (callee)) != llvm_sig)
1660 return LLVMConstBitCast (callee, LLVMPointerType (llvm_sig, 0));
1662 g_free (callee_name);
1668 * Calls are made through the GOT.
1670 return get_aotconst_typed (ctx, type, data, LLVMPointerType (llvm_sig, 0));
1672 MonoJumpInfo *ji = NULL;
1674 callee_name = mono_aot_get_plt_symbol (type, data);
1678 if (ctx->cfg->compile_aot)
1679 /* Add a patch so referenced wrappers can be compiled in full aot mode */
1680 mono_add_patch_info (ctx->cfg, 0, type, data);
1683 callee = (LLVMValueRef)g_hash_table_lookup (ctx->module->plt_entries, callee_name);
1685 callee = LLVMAddFunction (ctx->lmodule, callee_name, llvm_sig);
1687 LLVMSetVisibility (callee, LLVMHiddenVisibility);
1689 g_hash_table_insert (ctx->module->plt_entries, (char*)callee_name, callee);
1692 if (ctx->cfg->compile_aot) {
1693 ji = g_new0 (MonoJumpInfo, 1);
1695 ji->data.target = data;
1697 g_hash_table_insert (ctx->module->plt_entries_ji, ji, callee);
1705 emit_jit_callee (EmitContext *ctx, const char *name, LLVMTypeRef llvm_sig, gpointer target)
1707 #if LLVM_API_VERSION > 100
1708 LLVMValueRef tramp_var = LLVMAddGlobal (ctx->lmodule, LLVMPointerType (llvm_sig, 0), name);
1709 LLVMSetInitializer (tramp_var, LLVMConstIntToPtr (LLVMConstInt (LLVMInt64Type (), (guint64)(size_t)target, FALSE), LLVMPointerType (llvm_sig, 0)));
1710 LLVMSetLinkage (tramp_var, LLVMExternalLinkage);
1711 LLVMValueRef callee = LLVMBuildLoad (ctx->builder, tramp_var, "");
1714 LLVMValueRef callee = LLVMAddFunction (ctx->lmodule, "", llvm_sig);
1715 LLVMAddGlobalMapping (ctx->module->ee, callee, target);
1721 get_handler_clause (MonoCompile *cfg, MonoBasicBlock *bb)
1723 MonoMethodHeader *header = cfg->header;
1724 MonoExceptionClause *clause;
1728 if (bb->region != -1 && MONO_BBLOCK_IS_IN_REGION (bb, MONO_REGION_TRY))
1729 return (bb->region >> 8) - 1;
1732 for (i = 0; i < header->num_clauses; ++i) {
1733 clause = &header->clauses [i];
1735 if (MONO_OFFSET_IN_CLAUSE (clause, bb->real_offset) && clause->flags == MONO_EXCEPTION_CLAUSE_NONE)
1742 static MonoExceptionClause *
1743 get_most_deep_clause (MonoCompile *cfg, EmitContext *ctx, MonoBasicBlock *bb)
1745 // Since they're sorted by nesting we just need
1746 // the first one that the bb is a member of
1747 for (int i = 0; i < cfg->header->num_clauses; i++) {
1748 MonoExceptionClause *curr = &cfg->header->clauses [i];
1750 if (MONO_OFFSET_IN_CLAUSE (curr, bb->real_offset))
1758 set_metadata_flag (LLVMValueRef v, const char *flag_name)
1760 LLVMValueRef md_arg;
1763 md_kind = LLVMGetMDKindID (flag_name, strlen (flag_name));
1764 md_arg = LLVMMDString ("mono", 4);
1765 LLVMSetMetadata (v, md_kind, LLVMMDNode (&md_arg, 1));
1769 set_invariant_load_flag (LLVMValueRef v)
1771 LLVMValueRef md_arg;
1773 const char *flag_name;
1775 // FIXME: Cache this
1776 flag_name = "invariant.load";
1777 md_kind = LLVMGetMDKindID (flag_name, strlen (flag_name));
1778 md_arg = LLVMMDString ("<index>", strlen ("<index>"));
1779 LLVMSetMetadata (v, md_kind, LLVMMDNode (&md_arg, 1));
1785 * Emit an LLVM call or invoke instruction depending on whenever the call is inside
1789 emit_call (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, LLVMValueRef callee, LLVMValueRef *args, int pindex)
1791 MonoCompile *cfg = ctx->cfg;
1792 LLVMValueRef lcall = NULL;
1793 LLVMBuilderRef builder = *builder_ref;
1794 MonoExceptionClause *clause;
1796 if (ctx->llvm_only) {
1797 clause = get_most_deep_clause (cfg, ctx, bb);
1800 g_assert (clause->flags == MONO_EXCEPTION_CLAUSE_NONE || clause->flags == MONO_EXCEPTION_CLAUSE_FINALLY);
1803 * Have to use an invoke instead of a call, branching to the
1804 * handler bblock of the clause containing this bblock.
1806 intptr_t key = CLAUSE_END(clause);
1808 LLVMBasicBlockRef lpad_bb = (LLVMBasicBlockRef)g_hash_table_lookup (ctx->exc_meta, (gconstpointer)key);
1810 // FIXME: Find the one that has the lowest end bound for the right start address
1811 // FIXME: Finally + nesting
1814 LLVMBasicBlockRef noex_bb = gen_bb (ctx, "CALL_NOEX_BB");
1817 lcall = LLVMBuildInvoke (builder, callee, args, pindex, noex_bb, lpad_bb, "");
1819 builder = ctx->builder = create_builder (ctx);
1820 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
1822 ctx->bblocks [bb->block_num].end_bblock = noex_bb;
1826 int clause_index = get_handler_clause (cfg, bb);
1828 if (clause_index != -1) {
1829 MonoMethodHeader *header = cfg->header;
1830 MonoExceptionClause *ec = &header->clauses [clause_index];
1831 MonoBasicBlock *tblock;
1832 LLVMBasicBlockRef ex_bb, noex_bb;
1835 * Have to use an invoke instead of a call, branching to the
1836 * handler bblock of the clause containing this bblock.
1839 g_assert (ec->flags == MONO_EXCEPTION_CLAUSE_NONE || ec->flags == MONO_EXCEPTION_CLAUSE_FINALLY);
1841 tblock = cfg->cil_offset_to_bb [ec->handler_offset];
1844 ctx->bblocks [tblock->block_num].invoke_target = TRUE;
1846 ex_bb = get_bb (ctx, tblock);
1848 noex_bb = gen_bb (ctx, "NOEX_BB");
1851 lcall = LLVMBuildInvoke (builder, callee, args, pindex, noex_bb, ex_bb, "");
1853 builder = ctx->builder = create_builder (ctx);
1854 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
1856 ctx->bblocks [bb->block_num].end_bblock = noex_bb;
1861 lcall = LLVMBuildCall (builder, callee, args, pindex, "");
1862 ctx->builder = builder;
1866 *builder_ref = ctx->builder;
1872 emit_load_general (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, int size, LLVMValueRef addr, const char *name, gboolean is_faulting, BarrierKind barrier)
1874 const char *intrins_name;
1875 LLVMValueRef args [16], res;
1876 LLVMTypeRef addr_type;
1877 gboolean use_intrinsics = TRUE;
1879 #if LLVM_API_VERSION > 100
1880 if (is_faulting && bb->region != -1 && !ctx->cfg->llvm_only) {
1881 /* The llvm.mono.load/store intrinsics are not supported by this llvm version, emit an explicit null check instead */
1882 LLVMValueRef cmp = LLVMBuildICmp (*builder_ref, LLVMIntEQ, addr, LLVMConstNull (LLVMTypeOf (addr)), "");
1883 emit_cond_system_exception (ctx, bb, "NullReferenceException", cmp);
1884 *builder_ref = ctx->builder;
1885 use_intrinsics = FALSE;
1889 if (is_faulting && bb->region != -1 && !ctx->cfg->llvm_only && use_intrinsics) {
1890 LLVMAtomicOrdering ordering;
1893 case LLVM_BARRIER_NONE:
1894 ordering = LLVMAtomicOrderingNotAtomic;
1896 case LLVM_BARRIER_ACQ:
1897 ordering = LLVMAtomicOrderingAcquire;
1899 case LLVM_BARRIER_SEQ:
1900 ordering = LLVMAtomicOrderingSequentiallyConsistent;
1903 g_assert_not_reached ();
1908 * We handle loads which can fault by calling a mono specific intrinsic
1909 * using an invoke, so they are handled properly inside try blocks.
1910 * We can't use this outside clauses, since LLVM optimizes intrinsics which
1911 * are marked with IntrReadArgMem.
1915 intrins_name = "llvm.mono.load.i8.p0i8";
1918 intrins_name = "llvm.mono.load.i16.p0i16";
1921 intrins_name = "llvm.mono.load.i32.p0i32";
1924 intrins_name = "llvm.mono.load.i64.p0i64";
1927 g_assert_not_reached ();
1930 addr_type = LLVMTypeOf (addr);
1931 if (addr_type == LLVMPointerType (LLVMDoubleType (), 0) || addr_type == LLVMPointerType (LLVMFloatType (), 0))
1932 addr = LLVMBuildBitCast (*builder_ref, addr, LLVMPointerType (LLVMIntType (size * 8), 0), "");
1935 args [1] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
1936 args [2] = LLVMConstInt (LLVMInt1Type (), TRUE, FALSE);
1937 args [3] = LLVMConstInt (LLVMInt32Type (), ordering, FALSE);
1938 res = emit_call (ctx, bb, builder_ref, get_intrinsic (ctx, intrins_name), args, 4);
1940 if (addr_type == LLVMPointerType (LLVMDoubleType (), 0))
1941 res = LLVMBuildBitCast (*builder_ref, res, LLVMDoubleType (), "");
1942 else if (addr_type == LLVMPointerType (LLVMFloatType (), 0))
1943 res = LLVMBuildBitCast (*builder_ref, res, LLVMFloatType (), "");
1950 * We emit volatile loads for loads which can fault, because otherwise
1951 * LLVM will generate invalid code when encountering a load from a
1954 res = mono_llvm_build_load (*builder_ref, addr, name, is_faulting, barrier);
1956 /* Mark it with a custom metadata */
1959 set_metadata_flag (res, "mono.faulting.load");
1967 emit_load (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, int size, LLVMValueRef addr, const char *name, gboolean is_faulting)
1969 return emit_load_general (ctx, bb, builder_ref, size, addr, name, is_faulting, LLVM_BARRIER_NONE);
1973 emit_store_general (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, int size, LLVMValueRef value, LLVMValueRef addr, gboolean is_faulting, BarrierKind barrier)
1975 const char *intrins_name;
1976 LLVMValueRef args [16];
1977 gboolean use_intrinsics = TRUE;
1979 #if LLVM_API_VERSION > 100
1980 if (is_faulting && bb->region != -1 && !ctx->cfg->llvm_only) {
1981 /* The llvm.mono.load/store intrinsics are not supported by this llvm version, emit an explicit null check instead */
1982 LLVMValueRef cmp = LLVMBuildICmp (*builder_ref, LLVMIntEQ, addr, LLVMConstNull (LLVMTypeOf (addr)), "");
1983 emit_cond_system_exception (ctx, bb, "NullReferenceException", cmp);
1984 *builder_ref = ctx->builder;
1985 use_intrinsics = FALSE;
1989 if (is_faulting && bb->region != -1 && !ctx->cfg->llvm_only && use_intrinsics) {
1990 LLVMAtomicOrdering ordering;
1993 case LLVM_BARRIER_NONE:
1994 ordering = LLVMAtomicOrderingNotAtomic;
1996 case LLVM_BARRIER_REL:
1997 ordering = LLVMAtomicOrderingRelease;
1999 case LLVM_BARRIER_SEQ:
2000 ordering = LLVMAtomicOrderingSequentiallyConsistent;
2003 g_assert_not_reached ();
2009 intrins_name = "llvm.mono.store.i8.p0i8";
2012 intrins_name = "llvm.mono.store.i16.p0i16";
2015 intrins_name = "llvm.mono.store.i32.p0i32";
2018 intrins_name = "llvm.mono.store.i64.p0i64";
2021 g_assert_not_reached ();
2024 if (LLVMTypeOf (value) == LLVMDoubleType () || LLVMTypeOf (value) == LLVMFloatType ()) {
2025 value = LLVMBuildBitCast (*builder_ref, value, LLVMIntType (size * 8), "");
2026 addr = LLVMBuildBitCast (*builder_ref, addr, LLVMPointerType (LLVMIntType (size * 8), 0), "");
2031 args [2] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
2032 args [3] = LLVMConstInt (LLVMInt1Type (), TRUE, FALSE);
2033 args [4] = LLVMConstInt (LLVMInt32Type (), ordering, FALSE);
2034 emit_call (ctx, bb, builder_ref, get_intrinsic (ctx, intrins_name), args, 5);
2036 mono_llvm_build_store (*builder_ref, value, addr, is_faulting, barrier);
2041 emit_store (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, int size, LLVMValueRef value, LLVMValueRef addr, gboolean is_faulting)
2043 emit_store_general (ctx, bb, builder_ref, size, value, addr, is_faulting, LLVM_BARRIER_NONE);
2047 * emit_cond_system_exception:
2049 * Emit code to throw the exception EXC_TYPE if the condition CMP is false.
2050 * Might set the ctx exception.
2053 emit_cond_system_exception (EmitContext *ctx, MonoBasicBlock *bb, const char *exc_type, LLVMValueRef cmp)
2055 LLVMBasicBlockRef ex_bb, ex2_bb = NULL, noex_bb;
2056 LLVMBuilderRef builder;
2057 MonoClass *exc_class;
2058 LLVMValueRef args [2];
2059 LLVMValueRef callee;
2060 gboolean no_pc = FALSE;
2062 if (IS_TARGET_AMD64)
2063 /* Some platforms don't require the pc argument */
2066 ex_bb = gen_bb (ctx, "EX_BB");
2068 ex2_bb = gen_bb (ctx, "EX2_BB");
2069 noex_bb = gen_bb (ctx, "NOEX_BB");
2071 LLVMBuildCondBr (ctx->builder, cmp, ex_bb, noex_bb);
2073 exc_class = mono_class_load_from_name (mono_get_corlib (), "System", exc_type);
2075 /* Emit exception throwing code */
2076 ctx->builder = builder = create_builder (ctx);
2077 LLVMPositionBuilderAtEnd (builder, ex_bb);
2079 if (ctx->cfg->llvm_only) {
2080 static LLVMTypeRef sig;
2083 sig = LLVMFunctionType1 (LLVMVoidType (), LLVMInt32Type (), FALSE);
2084 callee = get_callee (ctx, sig, MONO_PATCH_INFO_JIT_ICALL_ADDR, "mono_llvm_throw_corlib_exception");
2086 LLVMBuildBr (builder, ex2_bb);
2088 ctx->builder = builder = create_builder (ctx);
2089 LLVMPositionBuilderAtEnd (ctx->builder, ex2_bb);
2091 args [0] = LLVMConstInt (LLVMInt32Type (), exc_class->type_token - MONO_TOKEN_TYPE_DEF, FALSE);
2092 emit_call (ctx, bb, &builder, callee, args, 1);
2093 LLVMBuildUnreachable (builder);
2095 ctx->builder = builder = create_builder (ctx);
2096 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
2098 ctx->bblocks [bb->block_num].end_bblock = noex_bb;
2104 callee = ctx->module->throw_corlib_exception;
2107 const char *icall_name;
2110 sig = LLVMFunctionType1 (LLVMVoidType (), LLVMInt32Type (), FALSE);
2112 sig = LLVMFunctionType2 (LLVMVoidType (), LLVMInt32Type (), LLVMPointerType (LLVMInt8Type (), 0), FALSE);
2113 icall_name = "llvm_throw_corlib_exception_abs_trampoline";
2115 if (ctx->cfg->compile_aot) {
2116 callee = get_callee (ctx, sig, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
2119 * Differences between the LLVM/non-LLVM throw corlib exception trampoline:
2120 * - On x86, LLVM generated code doesn't push the arguments
2121 * - The trampoline takes the throw address as an arguments, not a pc offset.
2123 gpointer target = resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
2124 callee = emit_jit_callee (ctx, "llvm_throw_corlib_exception_trampoline", sig, target);
2126 #if LLVM_API_VERSION > 100
2128 * Make sure that ex_bb starts with the invoke, so the block address points to it, and not to the load
2129 * added by emit_jit_callee ().
2131 ex2_bb = gen_bb (ctx, "EX2_BB");
2132 LLVMBuildBr (builder, ex2_bb);
2135 ctx->builder = builder = create_builder (ctx);
2136 LLVMPositionBuilderAtEnd (ctx->builder, ex2_bb);
2138 mono_memory_barrier ();
2139 ctx->module->throw_corlib_exception = callee;
2144 args [0] = LLVMConstInt (LLVMInt32Type (), exc_class->type_token - MONO_TOKEN_TYPE_DEF, FALSE);
2147 * The LLVM mono branch contains changes so a block address can be passed as an
2148 * argument to a call.
2151 emit_call (ctx, bb, &builder, callee, args, 1);
2153 args [1] = LLVMBlockAddress (ctx->lmethod, ex_bb);
2154 emit_call (ctx, bb, &builder, callee, args, 2);
2157 LLVMBuildUnreachable (builder);
2159 ctx->builder = builder = create_builder (ctx);
2160 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
2162 ctx->bblocks [bb->block_num].end_bblock = noex_bb;
2169 * emit_args_to_vtype:
2171 * Emit code to store the vtype in the arguments args to the address ADDRESS.
2174 emit_args_to_vtype (EmitContext *ctx, LLVMBuilderRef builder, MonoType *t, LLVMValueRef address, LLVMArgInfo *ainfo, LLVMValueRef *args)
2176 int j, size, nslots;
2178 size = mono_class_value_size (mono_class_from_mono_type (t), NULL);
2180 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (t))) {
2181 address = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (LLVMInt8Type (), 0), "");
2184 if (ainfo->storage == LLVMArgAsFpArgs)
2185 nslots = ainfo->nslots;
2189 for (j = 0; j < nslots; ++j) {
2190 LLVMValueRef index [2], addr, daddr;
2191 int part_size = size > sizeof (gpointer) ? sizeof (gpointer) : size;
2192 LLVMTypeRef part_type;
2194 while (part_size != 1 && part_size != 2 && part_size != 4 && part_size < 8)
2197 if (ainfo->pair_storage [j] == LLVMArgNone)
2200 switch (ainfo->pair_storage [j]) {
2201 case LLVMArgInIReg: {
2202 part_type = LLVMIntType (part_size * 8);
2203 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (t))) {
2204 index [0] = LLVMConstInt (LLVMInt32Type (), j * sizeof (gpointer), FALSE);
2205 addr = LLVMBuildGEP (builder, address, index, 1, "");
2207 daddr = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (IntPtrType (), 0), "");
2208 index [0] = LLVMConstInt (LLVMInt32Type (), j, FALSE);
2209 addr = LLVMBuildGEP (builder, daddr, index, 1, "");
2211 LLVMBuildStore (builder, convert (ctx, args [j], part_type), LLVMBuildBitCast (ctx->builder, addr, LLVMPointerType (part_type, 0), ""));
2214 case LLVMArgInFPReg: {
2215 LLVMTypeRef arg_type;
2217 if (ainfo->esize == 8)
2218 arg_type = LLVMDoubleType ();
2220 arg_type = LLVMFloatType ();
2222 index [0] = LLVMConstInt (LLVMInt32Type (), j, FALSE);
2223 daddr = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (arg_type, 0), "");
2224 addr = LLVMBuildGEP (builder, daddr, index, 1, "");
2225 LLVMBuildStore (builder, args [j], addr);
2231 g_assert_not_reached ();
2234 size -= sizeof (gpointer);
2239 * emit_vtype_to_args:
2241 * Emit code to load a vtype at address ADDRESS into scalar arguments. Store the arguments
2242 * into ARGS, and the number of arguments into NARGS.
2245 emit_vtype_to_args (EmitContext *ctx, LLVMBuilderRef builder, MonoType *t, LLVMValueRef address, LLVMArgInfo *ainfo, LLVMValueRef *args, guint32 *nargs)
2248 int j, size, nslots;
2249 LLVMTypeRef arg_type;
2251 size = get_vtype_size (t);
2253 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (t)))
2254 address = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (LLVMInt8Type (), 0), "");
2256 if (ainfo->storage == LLVMArgAsFpArgs)
2257 nslots = ainfo->nslots;
2260 for (j = 0; j < nslots; ++j) {
2261 LLVMValueRef index [2], addr, daddr;
2262 int partsize = size > sizeof (gpointer) ? sizeof (gpointer) : size;
2264 if (ainfo->pair_storage [j] == LLVMArgNone)
2267 switch (ainfo->pair_storage [j]) {
2269 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (t))) {
2270 index [0] = LLVMConstInt (LLVMInt32Type (), j * sizeof (gpointer), FALSE);
2271 addr = LLVMBuildGEP (builder, address, index, 1, "");
2273 daddr = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (IntPtrType (), 0), "");
2274 index [0] = LLVMConstInt (LLVMInt32Type (), j, FALSE);
2275 addr = LLVMBuildGEP (builder, daddr, index, 1, "");
2277 args [pindex ++] = convert (ctx, LLVMBuildLoad (builder, LLVMBuildBitCast (ctx->builder, addr, LLVMPointerType (LLVMIntType (partsize * 8), 0), ""), ""), IntPtrType ());
2279 case LLVMArgInFPReg:
2280 if (ainfo->esize == 8)
2281 arg_type = LLVMDoubleType ();
2283 arg_type = LLVMFloatType ();
2284 daddr = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (arg_type, 0), "");
2285 index [0] = LLVMConstInt (LLVMInt32Type (), j, FALSE);
2286 addr = LLVMBuildGEP (builder, daddr, index, 1, "");
2287 args [pindex ++] = LLVMBuildLoad (builder, addr, "");
2292 g_assert_not_reached ();
2294 size -= sizeof (gpointer);
2301 build_alloca_llvm_type_name (EmitContext *ctx, LLVMTypeRef t, int align, const char *name)
2304 * Have to place all alloca's at the end of the entry bb, since otherwise they would
2305 * get executed every time control reaches them.
2307 LLVMPositionBuilder (ctx->alloca_builder, get_bb (ctx, ctx->cfg->bb_entry), ctx->last_alloca);
2309 ctx->last_alloca = mono_llvm_build_alloca (ctx->alloca_builder, t, NULL, align, name);
2310 return ctx->last_alloca;
2314 build_alloca_llvm_type (EmitContext *ctx, LLVMTypeRef t, int align)
2316 return build_alloca_llvm_type_name (ctx, t, align, "");
2320 build_alloca (EmitContext *ctx, MonoType *t)
2322 MonoClass *k = mono_class_from_mono_type (t);
2325 g_assert (!mini_is_gsharedvt_variable_type (t));
2327 if (MONO_CLASS_IS_SIMD (ctx->cfg, k))
2330 align = mono_class_min_align (k);
2332 /* Sometimes align is not a power of 2 */
2333 while (mono_is_power_of_two (align) == -1)
2336 return build_alloca_llvm_type (ctx, type_to_llvm_type (ctx, t), align);
2340 emit_gsharedvt_ldaddr (EmitContext *ctx, int vreg)
2344 * Compute the address of the local as gsharedvt_locals_var + gsharedvt_info_var->locals_offsets [idx].
2346 MonoCompile *cfg = ctx->cfg;
2347 LLVMBuilderRef builder = ctx->builder;
2348 LLVMValueRef offset, offset_var;
2349 LLVMValueRef info_var = ctx->values [cfg->gsharedvt_info_var->dreg];
2350 LLVMValueRef locals_var = ctx->values [cfg->gsharedvt_locals_var->dreg];
2354 g_assert (info_var);
2355 g_assert (locals_var);
2357 int idx = cfg->gsharedvt_vreg_to_idx [vreg] - 1;
2359 offset = LLVMConstInt (LLVMInt32Type (), MONO_STRUCT_OFFSET (MonoGSharedVtMethodRuntimeInfo, entries) + (idx * sizeof (gpointer)), FALSE);
2360 ptr = LLVMBuildAdd (builder, convert (ctx, info_var, IntPtrType ()), convert (ctx, offset, IntPtrType ()), "");
2362 name = g_strdup_printf ("gsharedvt_local_%d_offset", vreg);
2363 offset_var = LLVMBuildLoad (builder, convert (ctx, ptr, LLVMPointerType (LLVMInt32Type (), 0)), name);
2365 return LLVMBuildAdd (builder, convert (ctx, locals_var, IntPtrType ()), convert (ctx, offset_var, IntPtrType ()), "");
2369 * Put the global into the 'llvm.used' array to prevent it from being optimized away.
2372 mark_as_used (MonoLLVMModule *module, LLVMValueRef global)
2375 module->used = g_ptr_array_sized_new (16);
2376 g_ptr_array_add (module->used, global);
2380 emit_llvm_used (MonoLLVMModule *module)
2382 LLVMModuleRef lmodule = module->lmodule;
2383 LLVMTypeRef used_type;
2384 LLVMValueRef used, *used_elem;
2390 used_type = LLVMArrayType (LLVMPointerType (LLVMInt8Type (), 0), module->used->len);
2391 used = LLVMAddGlobal (lmodule, used_type, "llvm.used");
2392 used_elem = g_new0 (LLVMValueRef, module->used->len);
2393 for (i = 0; i < module->used->len; ++i)
2394 used_elem [i] = LLVMConstBitCast ((LLVMValueRef)g_ptr_array_index (module->used, i), LLVMPointerType (LLVMInt8Type (), 0));
2395 LLVMSetInitializer (used, LLVMConstArray (LLVMPointerType (LLVMInt8Type (), 0), used_elem, module->used->len));
2396 LLVMSetLinkage (used, LLVMAppendingLinkage);
2397 LLVMSetSection (used, "llvm.metadata");
2403 * Emit a function mapping method indexes to their code
2406 emit_get_method (MonoLLVMModule *module)
2408 LLVMModuleRef lmodule = module->lmodule;
2409 LLVMValueRef func, switch_ins, m;
2410 LLVMBasicBlockRef entry_bb, fail_bb, bb, code_start_bb, code_end_bb;
2411 LLVMBasicBlockRef *bbs;
2413 LLVMBuilderRef builder;
2418 * Emit a switch statement. Emitting a table of function addresses is smaller/faster,
2419 * but generating code seems safer.
2421 rtype = LLVMPointerType (LLVMInt8Type (), 0);
2422 func = LLVMAddFunction (lmodule, module->get_method_symbol, LLVMFunctionType1 (rtype, LLVMInt32Type (), FALSE));
2423 LLVMSetLinkage (func, LLVMExternalLinkage);
2424 LLVMSetVisibility (func, LLVMHiddenVisibility);
2425 LLVMAddFunctionAttr (func, LLVMNoUnwindAttribute);
2426 module->get_method = func;
2428 entry_bb = LLVMAppendBasicBlock (func, "ENTRY");
2431 * Return llvm_code_start/llvm_code_end when called with -1/-2.
2432 * Hopefully, the toolchain doesn't reorder these functions. If it does,
2433 * then we will have to find another solution.
2436 name = g_strdup_printf ("BB_CODE_START");
2437 code_start_bb = LLVMAppendBasicBlock (func, name);
2439 builder = LLVMCreateBuilder ();
2440 LLVMPositionBuilderAtEnd (builder, code_start_bb);
2441 LLVMBuildRet (builder, LLVMBuildBitCast (builder, module->code_start, rtype, ""));
2443 name = g_strdup_printf ("BB_CODE_END");
2444 code_end_bb = LLVMAppendBasicBlock (func, name);
2446 builder = LLVMCreateBuilder ();
2447 LLVMPositionBuilderAtEnd (builder, code_end_bb);
2448 LLVMBuildRet (builder, LLVMBuildBitCast (builder, module->code_end, rtype, ""));
2450 bbs = g_new0 (LLVMBasicBlockRef, module->max_method_idx + 1);
2451 for (i = 0; i < module->max_method_idx + 1; ++i) {
2452 name = g_strdup_printf ("BB_%d", i);
2453 bb = LLVMAppendBasicBlock (func, name);
2457 builder = LLVMCreateBuilder ();
2458 LLVMPositionBuilderAtEnd (builder, bb);
2460 m = (LLVMValueRef)g_hash_table_lookup (module->idx_to_lmethod, GINT_TO_POINTER (i));
2462 LLVMBuildRet (builder, LLVMBuildBitCast (builder, m, rtype, ""));
2464 LLVMBuildRet (builder, LLVMConstNull (rtype));
2467 fail_bb = LLVMAppendBasicBlock (func, "FAIL");
2468 builder = LLVMCreateBuilder ();
2469 LLVMPositionBuilderAtEnd (builder, fail_bb);
2470 LLVMBuildRet (builder, LLVMConstNull (rtype));
2472 builder = LLVMCreateBuilder ();
2473 LLVMPositionBuilderAtEnd (builder, entry_bb);
2475 switch_ins = LLVMBuildSwitch (builder, LLVMGetParam (func, 0), fail_bb, 0);
2476 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), -1, FALSE), code_start_bb);
2477 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), -2, FALSE), code_end_bb);
2478 for (i = 0; i < module->max_method_idx + 1; ++i) {
2479 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), i, FALSE), bbs [i]);
2482 mark_as_used (module, func);
2486 * emit_get_unbox_tramp:
2488 * Emit a function mapping method indexes to their unbox trampoline
2491 emit_get_unbox_tramp (MonoLLVMModule *module)
2493 LLVMModuleRef lmodule = module->lmodule;
2494 LLVMValueRef func, switch_ins, m;
2495 LLVMBasicBlockRef entry_bb, fail_bb, bb;
2496 LLVMBasicBlockRef *bbs;
2498 LLVMBuilderRef builder;
2502 /* Similar to emit_get_method () */
2504 rtype = LLVMPointerType (LLVMInt8Type (), 0);
2505 func = LLVMAddFunction (lmodule, module->get_unbox_tramp_symbol, LLVMFunctionType1 (rtype, LLVMInt32Type (), FALSE));
2506 LLVMSetLinkage (func, LLVMExternalLinkage);
2507 LLVMSetVisibility (func, LLVMHiddenVisibility);
2508 LLVMAddFunctionAttr (func, LLVMNoUnwindAttribute);
2509 module->get_unbox_tramp = func;
2511 entry_bb = LLVMAppendBasicBlock (func, "ENTRY");
2513 bbs = g_new0 (LLVMBasicBlockRef, module->max_method_idx + 1);
2514 for (i = 0; i < module->max_method_idx + 1; ++i) {
2515 m = (LLVMValueRef)g_hash_table_lookup (module->idx_to_unbox_tramp, GINT_TO_POINTER (i));
2519 name = g_strdup_printf ("BB_%d", i);
2520 bb = LLVMAppendBasicBlock (func, name);
2524 builder = LLVMCreateBuilder ();
2525 LLVMPositionBuilderAtEnd (builder, bb);
2527 LLVMBuildRet (builder, LLVMBuildBitCast (builder, m, rtype, ""));
2530 fail_bb = LLVMAppendBasicBlock (func, "FAIL");
2531 builder = LLVMCreateBuilder ();
2532 LLVMPositionBuilderAtEnd (builder, fail_bb);
2533 LLVMBuildRet (builder, LLVMConstNull (rtype));
2535 builder = LLVMCreateBuilder ();
2536 LLVMPositionBuilderAtEnd (builder, entry_bb);
2538 switch_ins = LLVMBuildSwitch (builder, LLVMGetParam (func, 0), fail_bb, 0);
2539 for (i = 0; i < module->max_method_idx + 1; ++i) {
2540 m = (LLVMValueRef)g_hash_table_lookup (module->idx_to_unbox_tramp, GINT_TO_POINTER (i));
2544 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), i, FALSE), bbs [i]);
2547 mark_as_used (module, func);
2550 /* Add a function to mark the beginning of LLVM code */
2552 emit_llvm_code_start (MonoLLVMModule *module)
2554 LLVMModuleRef lmodule = module->lmodule;
2556 LLVMBasicBlockRef entry_bb;
2557 LLVMBuilderRef builder;
2559 func = LLVMAddFunction (lmodule, "llvm_code_start", LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE));
2560 LLVMSetLinkage (func, LLVMInternalLinkage);
2561 LLVMAddFunctionAttr (func, LLVMNoUnwindAttribute);
2562 module->code_start = func;
2563 entry_bb = LLVMAppendBasicBlock (func, "ENTRY");
2564 builder = LLVMCreateBuilder ();
2565 LLVMPositionBuilderAtEnd (builder, entry_bb);
2566 LLVMBuildRetVoid (builder);
2570 emit_init_icall_wrapper (MonoLLVMModule *module, const char *name, const char *icall_name, int subtype)
2572 LLVMModuleRef lmodule = module->lmodule;
2573 LLVMValueRef func, indexes [2], got_entry_addr, args [16], callee;
2574 LLVMBasicBlockRef entry_bb;
2575 LLVMBuilderRef builder;
2582 func = LLVMAddFunction (lmodule, name, LLVMFunctionType1 (LLVMVoidType (), LLVMInt32Type (), FALSE));
2583 sig = LLVMFunctionType2 (LLVMVoidType (), IntPtrType (), LLVMInt32Type (), FALSE);
2588 func = LLVMAddFunction (lmodule, name, LLVMFunctionType2 (LLVMVoidType (), LLVMInt32Type (), IntPtrType (), FALSE));
2589 sig = LLVMFunctionType3 (LLVMVoidType (), IntPtrType (), LLVMInt32Type (), IntPtrType (), FALSE);
2592 func = LLVMAddFunction (lmodule, name, LLVMFunctionType2 (LLVMVoidType (), LLVMInt32Type (), ObjRefType (), FALSE));
2593 sig = LLVMFunctionType3 (LLVMVoidType (), IntPtrType (), LLVMInt32Type (), ObjRefType (), FALSE);
2596 g_assert_not_reached ();
2598 LLVMSetLinkage (func, LLVMInternalLinkage);
2599 LLVMAddFunctionAttr (func, LLVMNoInlineAttribute);
2600 mono_llvm_set_preserveall_cc (func);
2601 entry_bb = LLVMAppendBasicBlock (func, "ENTRY");
2602 builder = LLVMCreateBuilder ();
2603 LLVMPositionBuilderAtEnd (builder, entry_bb);
2606 ji = g_new0 (MonoJumpInfo, 1);
2607 ji->type = MONO_PATCH_INFO_AOT_MODULE;
2608 ji = mono_aot_patch_info_dup (ji);
2609 got_offset = mono_aot_get_got_offset (ji);
2610 module->max_got_offset = MAX (module->max_got_offset, got_offset);
2611 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
2612 indexes [1] = LLVMConstInt (LLVMInt32Type (), got_offset, FALSE);
2613 got_entry_addr = LLVMBuildGEP (builder, module->got_var, indexes, 2, "");
2614 args [0] = LLVMBuildPtrToInt (builder, LLVMBuildLoad (builder, got_entry_addr, ""), IntPtrType (), "");
2615 args [1] = LLVMGetParam (func, 0);
2617 args [2] = LLVMGetParam (func, 1);
2619 ji = g_new0 (MonoJumpInfo, 1);
2620 ji->type = MONO_PATCH_INFO_INTERNAL_METHOD;
2621 ji->data.name = icall_name;
2622 ji = mono_aot_patch_info_dup (ji);
2623 got_offset = mono_aot_get_got_offset (ji);
2624 module->max_got_offset = MAX (module->max_got_offset, got_offset);
2625 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
2626 indexes [1] = LLVMConstInt (LLVMInt32Type (), got_offset, FALSE);
2627 got_entry_addr = LLVMBuildGEP (builder, module->got_var, indexes, 2, "");
2628 callee = LLVMBuildLoad (builder, got_entry_addr, "");
2629 callee = LLVMBuildBitCast (builder, callee, LLVMPointerType (sig, 0), "");
2630 LLVMBuildCall (builder, callee, args, LLVMCountParamTypes (sig), "");
2632 // Set the inited flag
2633 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
2634 indexes [1] = LLVMGetParam (func, 0);
2635 LLVMBuildStore (builder, LLVMConstInt (LLVMInt8Type (), 1, FALSE), LLVMBuildGEP (builder, module->inited_var, indexes, 2, ""));
2637 LLVMBuildRetVoid (builder);
2639 LLVMVerifyFunction(func, LLVMAbortProcessAction);
2644 * Emit wrappers around the C icalls used to initialize llvm methods, to
2645 * make the calling code smaller and to enable usage of the llvm
2646 * PreserveAll calling convention.
2649 emit_init_icall_wrappers (MonoLLVMModule *module)
2651 module->init_method = emit_init_icall_wrapper (module, "init_method", "mono_aot_init_llvm_method", 0);
2652 module->init_method_gshared_mrgctx = emit_init_icall_wrapper (module, "init_method_gshared_mrgctx", "mono_aot_init_gshared_method_mrgctx", 1);
2653 module->init_method_gshared_this = emit_init_icall_wrapper (module, "init_method_gshared_this", "mono_aot_init_gshared_method_this", 2);
2654 module->init_method_gshared_vtable = emit_init_icall_wrapper (module, "init_method_gshared_vtable", "mono_aot_init_gshared_method_vtable", 3);
2658 emit_llvm_code_end (MonoLLVMModule *module)
2660 LLVMModuleRef lmodule = module->lmodule;
2662 LLVMBasicBlockRef entry_bb;
2663 LLVMBuilderRef builder;
2665 func = LLVMAddFunction (lmodule, "llvm_code_end", LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE));
2666 LLVMSetLinkage (func, LLVMInternalLinkage);
2667 LLVMAddFunctionAttr (func, LLVMNoUnwindAttribute);
2668 module->code_end = func;
2669 entry_bb = LLVMAppendBasicBlock (func, "ENTRY");
2670 builder = LLVMCreateBuilder ();
2671 LLVMPositionBuilderAtEnd (builder, entry_bb);
2672 LLVMBuildRetVoid (builder);
2676 emit_div_check (EmitContext *ctx, LLVMBuilderRef builder, MonoBasicBlock *bb, MonoInst *ins, LLVMValueRef lhs, LLVMValueRef rhs)
2678 gboolean need_div_check = ctx->cfg->backend->need_div_check;
2681 /* LLVM doesn't know that these can throw an exception since they are not called through an intrinsic */
2682 need_div_check = TRUE;
2684 if (!need_div_check)
2687 switch (ins->opcode) {
2700 case OP_IDIV_UN_IMM:
2701 case OP_LDIV_UN_IMM:
2702 case OP_IREM_UN_IMM:
2703 case OP_LREM_UN_IMM: {
2705 gboolean is_signed = (ins->opcode == OP_IDIV || ins->opcode == OP_LDIV || ins->opcode == OP_IREM || ins->opcode == OP_LREM ||
2706 ins->opcode == OP_IDIV_IMM || ins->opcode == OP_LDIV_IMM || ins->opcode == OP_IREM_IMM || ins->opcode == OP_LREM_IMM);
2708 cmp = LLVMBuildICmp (builder, LLVMIntEQ, rhs, LLVMConstInt (LLVMTypeOf (rhs), 0, FALSE), "");
2709 emit_cond_system_exception (ctx, bb, "DivideByZeroException", cmp);
2712 builder = ctx->builder;
2714 /* b == -1 && a == 0x80000000 */
2716 LLVMValueRef c = (LLVMTypeOf (lhs) == LLVMInt32Type ()) ? LLVMConstInt (LLVMTypeOf (lhs), 0x80000000, FALSE) : LLVMConstInt (LLVMTypeOf (lhs), 0x8000000000000000LL, FALSE);
2717 LLVMValueRef cond1 = LLVMBuildICmp (builder, LLVMIntEQ, rhs, LLVMConstInt (LLVMTypeOf (rhs), -1, FALSE), "");
2718 LLVMValueRef cond2 = LLVMBuildICmp (builder, LLVMIntEQ, lhs, c, "");
2720 cmp = LLVMBuildICmp (builder, LLVMIntEQ, LLVMBuildAnd (builder, cond1, cond2, ""), LLVMConstInt (LLVMInt1Type (), 1, FALSE), "");
2721 emit_cond_system_exception (ctx, bb, "OverflowException", cmp);
2724 builder = ctx->builder;
2736 * Emit code to initialize the GOT slots used by the method.
2739 emit_init_method (EmitContext *ctx)
2741 LLVMValueRef indexes [16], args [16], callee;
2742 LLVMValueRef inited_var, cmp, call;
2743 LLVMBasicBlockRef inited_bb, notinited_bb;
2744 LLVMBuilderRef builder = ctx->builder;
2745 MonoCompile *cfg = ctx->cfg;
2747 ctx->module->max_inited_idx = MAX (ctx->module->max_inited_idx, cfg->method_index);
2749 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
2750 indexes [1] = LLVMConstInt (LLVMInt32Type (), cfg->method_index, FALSE);
2751 inited_var = LLVMBuildLoad (builder, LLVMBuildGEP (builder, ctx->module->inited_var, indexes, 2, ""), "is_inited");
2753 args [0] = inited_var;
2754 args [1] = LLVMConstInt (LLVMInt8Type (), 1, FALSE);
2755 inited_var = LLVMBuildCall (ctx->builder, get_intrinsic (ctx, "llvm.expect.i8"), args, 2, "");
2757 cmp = LLVMBuildICmp (builder, LLVMIntEQ, inited_var, LLVMConstInt (LLVMTypeOf (inited_var), 0, FALSE), "");
2759 inited_bb = ctx->inited_bb;
2760 notinited_bb = gen_bb (ctx, "NOTINITED_BB");
2762 LLVMBuildCondBr (ctx->builder, cmp, notinited_bb, inited_bb);
2764 builder = ctx->builder = create_builder (ctx);
2765 LLVMPositionBuilderAtEnd (ctx->builder, notinited_bb);
2768 if (ctx->rgctx_arg && cfg->method->is_inflated && mono_method_get_context (cfg->method)->method_inst) {
2769 args [0] = LLVMConstInt (LLVMInt32Type (), cfg->method_index, 0);
2770 args [1] = convert (ctx, ctx->rgctx_arg, IntPtrType ());
2771 callee = ctx->module->init_method_gshared_mrgctx;
2772 call = LLVMBuildCall (builder, callee, args, 2, "");
2773 } else if (ctx->rgctx_arg) {
2774 /* A vtable is passed as the rgctx argument */
2775 args [0] = LLVMConstInt (LLVMInt32Type (), cfg->method_index, 0);
2776 args [1] = convert (ctx, ctx->rgctx_arg, IntPtrType ());
2777 callee = ctx->module->init_method_gshared_vtable;
2778 call = LLVMBuildCall (builder, callee, args, 2, "");
2779 } else if (cfg->gshared) {
2780 args [0] = LLVMConstInt (LLVMInt32Type (), cfg->method_index, 0);
2781 args [1] = convert (ctx, ctx->this_arg, ObjRefType ());
2782 callee = ctx->module->init_method_gshared_this;
2783 call = LLVMBuildCall (builder, callee, args, 2, "");
2785 args [0] = LLVMConstInt (LLVMInt32Type (), cfg->method_index, 0);
2786 callee = ctx->module->init_method;
2787 call = LLVMBuildCall (builder, callee, args, 1, "");
2791 * This enables llvm to keep arguments in their original registers/
2792 * scratch registers, since the call will not clobber them.
2794 mono_llvm_set_call_preserveall_cc (call);
2796 LLVMBuildBr (builder, inited_bb);
2797 ctx->bblocks [cfg->bb_entry->block_num].end_bblock = inited_bb;
2799 builder = ctx->builder = create_builder (ctx);
2800 LLVMPositionBuilderAtEnd (ctx->builder, inited_bb);
2804 emit_unbox_tramp (EmitContext *ctx, const char *method_name, LLVMTypeRef method_type, LLVMValueRef method, int method_index)
2807 * Emit unbox trampoline using a tail call
2809 LLVMValueRef tramp, call, *args;
2810 LLVMBuilderRef builder;
2811 LLVMBasicBlockRef lbb;
2812 LLVMCallInfo *linfo;
2816 tramp_name = g_strdup_printf ("ut_%s", method_name);
2817 tramp = LLVMAddFunction (ctx->module->lmodule, tramp_name, method_type);
2818 LLVMSetLinkage (tramp, LLVMInternalLinkage);
2819 LLVMAddFunctionAttr (tramp, LLVMOptimizeForSizeAttribute);
2820 //LLVMAddFunctionAttr (tramp, LLVMNoUnwindAttribute);
2822 // FIXME: Reduce code duplication with mono_llvm_compile_method () etc.
2823 if (!ctx->llvm_only && ctx->rgctx_arg_pindex != -1)
2824 LLVMAddAttribute (LLVMGetParam (tramp, ctx->rgctx_arg_pindex), LLVMInRegAttribute);
2825 if (ctx->cfg->vret_addr) {
2826 LLVMSetValueName (LLVMGetParam (tramp, linfo->vret_arg_pindex), "vret");
2827 if (linfo->ret.storage == LLVMArgVtypeByRef) {
2828 LLVMAddAttribute (LLVMGetParam (tramp, linfo->vret_arg_pindex), LLVMStructRetAttribute);
2829 LLVMAddAttribute (LLVMGetParam (tramp, linfo->vret_arg_pindex), LLVMNoAliasAttribute);
2833 lbb = LLVMAppendBasicBlock (tramp, "");
2834 builder = LLVMCreateBuilder ();
2835 LLVMPositionBuilderAtEnd (builder, lbb);
2837 nargs = LLVMCountParamTypes (method_type);
2838 args = g_new0 (LLVMValueRef, nargs);
2839 for (i = 0; i < nargs; ++i) {
2840 args [i] = LLVMGetParam (tramp, i);
2841 if (i == ctx->this_arg_pindex) {
2842 LLVMTypeRef arg_type = LLVMTypeOf (args [i]);
2844 args [i] = LLVMBuildPtrToInt (builder, args [i], IntPtrType (), "");
2845 args [i] = LLVMBuildAdd (builder, args [i], LLVMConstInt (IntPtrType (), sizeof (MonoObject), FALSE), "");
2846 args [i] = LLVMBuildIntToPtr (builder, args [i], arg_type, "");
2849 call = LLVMBuildCall (builder, method, args, nargs, "");
2850 if (!ctx->llvm_only && ctx->rgctx_arg_pindex != -1)
2851 LLVMAddInstrAttribute (call, 1 + ctx->rgctx_arg_pindex, LLVMInRegAttribute);
2852 if (linfo->ret.storage == LLVMArgVtypeByRef)
2853 LLVMAddInstrAttribute (call, 1 + linfo->vret_arg_pindex, LLVMStructRetAttribute);
2855 // FIXME: This causes assertions in clang
2856 //mono_llvm_set_must_tail (call);
2857 if (LLVMGetReturnType (method_type) == LLVMVoidType ())
2858 LLVMBuildRetVoid (builder);
2860 LLVMBuildRet (builder, call);
2862 g_hash_table_insert (ctx->module->idx_to_unbox_tramp, GINT_TO_POINTER (method_index), tramp);
2868 * Emit code to load/convert arguments.
2871 emit_entry_bb (EmitContext *ctx, LLVMBuilderRef builder)
2874 MonoCompile *cfg = ctx->cfg;
2875 MonoMethodSignature *sig = ctx->sig;
2876 LLVMCallInfo *linfo = ctx->linfo;
2880 LLVMBuilderRef old_builder = ctx->builder;
2881 ctx->builder = builder;
2883 ctx->alloca_builder = create_builder (ctx);
2886 * Handle indirect/volatile variables by allocating memory for them
2887 * using 'alloca', and storing their address in a temporary.
2889 for (i = 0; i < cfg->num_varinfo; ++i) {
2890 MonoInst *var = cfg->varinfo [i];
2893 if (var->opcode == OP_GSHAREDVT_LOCAL || var->opcode == OP_GSHAREDVT_ARG_REGOFFSET) {
2894 } 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))) {
2895 vtype = type_to_llvm_type (ctx, var->inst_vtype);
2898 /* Could be already created by an OP_VPHI */
2899 if (!ctx->addresses [var->dreg]) {
2900 ctx->addresses [var->dreg] = build_alloca (ctx, var->inst_vtype);
2901 //LLVMSetValueName (ctx->addresses [var->dreg], g_strdup_printf ("vreg_loc_%d", var->dreg));
2903 ctx->vreg_cli_types [var->dreg] = var->inst_vtype;
2907 names = g_new (char *, sig->param_count);
2908 mono_method_get_param_names (cfg->method, (const char **) names);
2910 for (i = 0; i < sig->param_count; ++i) {
2911 LLVMArgInfo *ainfo = &linfo->args [i + sig->hasthis];
2912 int reg = cfg->args [i + sig->hasthis]->dreg;
2915 pindex = ainfo->pindex;
2917 switch (ainfo->storage) {
2918 case LLVMArgVtypeInReg:
2919 case LLVMArgAsFpArgs: {
2920 LLVMValueRef args [8];
2923 pindex += ainfo->ndummy_fpargs;
2925 /* The argument is received as a set of int/fp arguments, store them into the real argument */
2926 memset (args, 0, sizeof (args));
2927 if (ainfo->storage == LLVMArgVtypeInReg) {
2928 args [0] = LLVMGetParam (ctx->lmethod, pindex);
2929 if (ainfo->pair_storage [1] != LLVMArgNone)
2930 args [1] = LLVMGetParam (ctx->lmethod, pindex + 1);
2932 g_assert (ainfo->nslots <= 8);
2933 for (j = 0; j < ainfo->nslots; ++j)
2934 args [j] = LLVMGetParam (ctx->lmethod, pindex + j);
2936 ctx->addresses [reg] = build_alloca (ctx, ainfo->type);
2938 emit_args_to_vtype (ctx, builder, ainfo->type, ctx->addresses [reg], ainfo, args);
2940 if (ainfo->storage == LLVMArgVtypeInReg && MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (ainfo->type))) {
2941 /* Treat these as normal values */
2942 ctx->values [reg] = LLVMBuildLoad (builder, ctx->addresses [reg], "");
2946 case LLVMArgVtypeByVal: {
2947 ctx->addresses [reg] = LLVMGetParam (ctx->lmethod, pindex);
2949 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (ainfo->type))) {
2950 /* Treat these as normal values */
2951 ctx->values [reg] = LLVMBuildLoad (builder, ctx->addresses [reg], "");
2955 case LLVMArgVtypeByRef: {
2956 /* The argument is passed by ref */
2957 ctx->addresses [reg] = LLVMGetParam (ctx->lmethod, pindex);
2960 case LLVMArgAsIArgs: {
2961 LLVMValueRef arg = LLVMGetParam (ctx->lmethod, pindex);
2964 /* The argument is received as an array of ints, store it into the real argument */
2965 ctx->addresses [reg] = build_alloca (ctx, ainfo->type);
2967 size = mono_class_value_size (mono_class_from_mono_type (ainfo->type), NULL);
2968 if (size < SIZEOF_VOID_P) {
2969 /* The upper bits of the registers might not be valid */
2970 LLVMValueRef val = LLVMBuildExtractValue (builder, arg, 0, "");
2971 LLVMValueRef dest = convert (ctx, ctx->addresses [reg], LLVMPointerType (LLVMIntType (size * 8), 0));
2972 LLVMBuildStore (ctx->builder, LLVMBuildTrunc (builder, val, LLVMIntType (size * 8), ""), dest);
2974 LLVMBuildStore (ctx->builder, arg, convert (ctx, ctx->addresses [reg], LLVMPointerType (LLVMTypeOf (arg), 0)));
2978 case LLVMArgVtypeAsScalar:
2979 g_assert_not_reached ();
2981 case LLVMArgGsharedvtFixed: {
2982 /* These are non-gsharedvt arguments passed by ref, the rest of the IR treats them as scalars */
2983 LLVMValueRef arg = LLVMGetParam (ctx->lmethod, pindex);
2986 name = g_strdup_printf ("arg_%s", names [i]);
2988 name = g_strdup_printf ("arg_%d", i);
2990 ctx->values [reg] = LLVMBuildLoad (builder, convert (ctx, arg, LLVMPointerType (type_to_llvm_type (ctx, ainfo->type), 0)), name);
2993 case LLVMArgGsharedvtFixedVtype: {
2994 LLVMValueRef arg = LLVMGetParam (ctx->lmethod, pindex);
2997 name = g_strdup_printf ("vtype_arg_%s", names [i]);
2999 name = g_strdup_printf ("vtype_arg_%d", i);
3001 /* Non-gsharedvt vtype argument passed by ref, the rest of the IR treats it as a vtype */
3002 g_assert (ctx->addresses [reg]);
3003 LLVMSetValueName (ctx->addresses [reg], name);
3004 LLVMBuildStore (builder, LLVMBuildLoad (builder, convert (ctx, arg, LLVMPointerType (type_to_llvm_type (ctx, ainfo->type), 0)), ""), ctx->addresses [reg]);
3007 case LLVMArgGsharedvtVariable:
3008 /* The IR treats these as variables with addresses */
3009 ctx->addresses [reg] = LLVMGetParam (ctx->lmethod, pindex);
3012 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));
3019 emit_volatile_store (ctx, cfg->vret_addr->dreg);
3021 emit_volatile_store (ctx, cfg->args [0]->dreg);
3022 for (i = 0; i < sig->param_count; ++i)
3023 if (!mini_type_is_vtype (sig->params [i]))
3024 emit_volatile_store (ctx, cfg->args [i + sig->hasthis]->dreg);
3026 if (sig->hasthis && !cfg->rgctx_var && cfg->gshared) {
3027 LLVMValueRef this_alloc;
3030 * The exception handling code needs the location where the this argument was
3031 * stored for gshared methods. We create a separate alloca to hold it, and mark it
3032 * with the "mono.this" custom metadata to tell llvm that it needs to save its
3033 * location into the LSDA.
3035 this_alloc = mono_llvm_build_alloca (builder, ThisType (), LLVMConstInt (LLVMInt32Type (), 1, FALSE), 0, "");
3036 /* This volatile store will keep the alloca alive */
3037 mono_llvm_build_store (builder, ctx->values [cfg->args [0]->dreg], this_alloc, TRUE, LLVM_BARRIER_NONE);
3039 set_metadata_flag (this_alloc, "mono.this");
3042 if (cfg->rgctx_var) {
3043 LLVMValueRef rgctx_alloc, store;
3046 * We handle the rgctx arg similarly to the this pointer.
3048 g_assert (ctx->addresses [cfg->rgctx_var->dreg]);
3049 rgctx_alloc = ctx->addresses [cfg->rgctx_var->dreg];
3050 /* This volatile store will keep the alloca alive */
3051 store = mono_llvm_build_store (builder, convert (ctx, ctx->rgctx_arg, IntPtrType ()), rgctx_alloc, TRUE, LLVM_BARRIER_NONE);
3053 set_metadata_flag (rgctx_alloc, "mono.this");
3056 /* Initialize the method if needed */
3057 if (cfg->compile_aot && ctx->llvm_only) {
3058 /* Emit a location for the initialization code */
3059 ctx->init_bb = gen_bb (ctx, "INIT_BB");
3060 ctx->inited_bb = gen_bb (ctx, "INITED_BB");
3062 LLVMBuildBr (ctx->builder, ctx->init_bb);
3063 builder = ctx->builder = create_builder (ctx);
3064 LLVMPositionBuilderAtEnd (ctx->builder, ctx->inited_bb);
3065 ctx->bblocks [cfg->bb_entry->block_num].end_bblock = ctx->inited_bb;
3068 /* Compute nesting between clauses */
3069 ctx->nested_in = (GSList**)mono_mempool_alloc0 (cfg->mempool, sizeof (GSList*) * cfg->header->num_clauses);
3070 for (i = 0; i < cfg->header->num_clauses; ++i) {
3071 for (j = 0; j < cfg->header->num_clauses; ++j) {
3072 MonoExceptionClause *clause1 = &cfg->header->clauses [i];
3073 MonoExceptionClause *clause2 = &cfg->header->clauses [j];
3075 if (i != j && clause1->try_offset >= clause2->try_offset && clause1->handler_offset <= clause2->handler_offset)
3076 ctx->nested_in [i] = g_slist_prepend_mempool (cfg->mempool, ctx->nested_in [i], GINT_TO_POINTER (j));
3081 * For finally clauses, create an indicator variable telling OP_ENDFINALLY whenever
3082 * it needs to continue normally, or return back to the exception handling system.
3084 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
3088 if (!(bb->region != -1 && (bb->flags & BB_EXCEPTION_HANDLER)))
3091 clause_index = MONO_REGION_CLAUSE_INDEX (bb->region);
3092 g_hash_table_insert (ctx->region_to_handler, GUINT_TO_POINTER (mono_get_block_region_notry (cfg, bb->region)), bb);
3093 g_hash_table_insert (ctx->clause_to_handler, GINT_TO_POINTER (clause_index), bb);
3095 if (bb->in_scount == 0) {
3098 sprintf (name, "finally_ind_bb%d", bb->block_num);
3099 val = LLVMBuildAlloca (builder, LLVMInt32Type (), name);
3100 LLVMBuildStore (builder, LLVMConstInt (LLVMInt32Type (), 0, FALSE), val);
3102 ctx->bblocks [bb->block_num].finally_ind = val;
3104 /* Create a variable to hold the exception var */
3106 ctx->ex_var = LLVMBuildAlloca (builder, ObjRefType (), "exvar");
3110 * Create a new bblock which CALL_HANDLER/landing pads can branch to, because branching to the
3111 * LLVM bblock containing a landing pad causes problems for the
3112 * LLVM optimizer passes.
3114 sprintf (name, "BB%d_CALL_HANDLER_TARGET", bb->block_num);
3115 ctx->bblocks [bb->block_num].call_handler_target_bb = LLVMAppendBasicBlock (ctx->lmethod, name);
3117 ctx->builder = old_builder;
3121 process_call (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, MonoInst *ins)
3123 MonoCompile *cfg = ctx->cfg;
3124 LLVMValueRef *values = ctx->values;
3125 LLVMValueRef *addresses = ctx->addresses;
3126 MonoCallInst *call = (MonoCallInst*)ins;
3127 MonoMethodSignature *sig = call->signature;
3128 LLVMValueRef callee = NULL, lcall;
3130 LLVMCallInfo *cinfo;
3134 LLVMTypeRef llvm_sig;
3136 gboolean is_virtual, calli, preserveall;
3137 LLVMBuilderRef builder = *builder_ref;
3139 if ((call->signature->call_convention != MONO_CALL_DEFAULT) && !((call->signature->call_convention == MONO_CALL_C) && ctx->llvm_only)) {
3140 set_failure (ctx, "non-default callconv");
3144 cinfo = call->cinfo;
3146 if (call->rgctx_arg_reg)
3147 cinfo->rgctx_arg = TRUE;
3148 if (call->imt_arg_reg)
3149 cinfo->imt_arg = TRUE;
3151 vretaddr = (cinfo->ret.storage == LLVMArgVtypeRetAddr || cinfo->ret.storage == LLVMArgVtypeByRef || cinfo->ret.storage == LLVMArgGsharedvtFixed || cinfo->ret.storage == LLVMArgGsharedvtVariable || cinfo->ret.storage == LLVMArgGsharedvtFixedVtype);
3153 llvm_sig = sig_to_llvm_sig_full (ctx, sig, cinfo);
3157 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);
3158 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);
3160 preserveall = FALSE;
3162 /* FIXME: Avoid creating duplicate methods */
3164 if (ins->flags & MONO_INST_HAS_METHOD) {
3168 if (cfg->compile_aot) {
3169 callee = get_callee (ctx, llvm_sig, MONO_PATCH_INFO_METHOD, call->method);
3171 set_failure (ctx, "can't encode patch");
3174 if (cfg->llvm_only && call->method->klass->image->assembly == ctx->module->assembly) {
3176 * Collect instructions representing the callee into a hash so they can be replaced
3177 * by the llvm method for the callee if the callee turns out to be direct
3178 * callable. Currently this only requires it to not fail llvm compilation.
3180 GSList *l = (GSList*)g_hash_table_lookup (ctx->method_to_callers, call->method);
3181 l = g_slist_prepend (l, callee);
3182 g_hash_table_insert (ctx->method_to_callers, call->method, l);
3186 static int tramp_index;
3189 name = g_strdup_printf ("tramp_%d", tramp_index);
3192 #if LLVM_API_VERSION > 100
3194 * Use our trampoline infrastructure for lazy compilation instead of llvm's.
3195 * Make all calls through a global. The address of the global will be saved in
3196 * MonoJitDomainInfo.llvm_jit_callees and updated when the method it refers to is
3199 LLVMValueRef tramp_var = g_hash_table_lookup (ctx->jit_callees, call->method);
3202 mono_create_jit_trampoline (mono_domain_get (),
3203 call->method, &error);
3204 if (!mono_error_ok (&error))
3205 mono_error_raise_exception (&error); /* FIXME: Don't raise here */
3206 tramp_var = LLVMAddGlobal (ctx->lmodule, LLVMPointerType (llvm_sig, 0), name);
3207 LLVMSetInitializer (tramp_var, LLVMConstIntToPtr (LLVMConstInt (LLVMInt64Type (), (guint64)(size_t)target, FALSE), LLVMPointerType (llvm_sig, 0)));
3208 LLVMSetLinkage (tramp_var, LLVMExternalLinkage);
3209 g_hash_table_insert (ctx->jit_callees, call->method, tramp_var);
3211 callee = LLVMBuildLoad (builder, tramp_var, "");
3214 mono_create_jit_trampoline (mono_domain_get (),
3215 call->method, &error);
3216 if (!mono_error_ok (&error))
3217 mono_error_raise_exception (&error); /* FIXME: Don't raise here */
3219 callee = LLVMAddFunction (ctx->lmodule, name, llvm_sig);
3222 if (!mono_error_ok (&error))
3223 mono_error_raise_exception (&error); /* FIXME: Don't raise here */
3224 LLVMAddGlobalMapping (ctx->module->ee, callee, target);
3229 if (!cfg->llvm_only && call->method && strstr (call->method->klass->name, "AsyncVoidMethodBuilder")) {
3230 /* LLVM miscompiles async methods */
3231 set_failure (ctx, "#13734");
3236 MonoJitICallInfo *info = mono_find_jit_icall_by_addr (call->fptr);
3242 memset (&ji, 0, sizeof (ji));
3243 ji.type = MONO_PATCH_INFO_JIT_ICALL_ADDR;
3244 ji.data.target = info->name;
3246 target = mono_resolve_patch_target (cfg->method, cfg->domain, NULL, &ji, FALSE);
3248 if (cfg->compile_aot) {
3249 callee = get_callee (ctx, llvm_sig, MONO_PATCH_INFO_INTERNAL_METHOD, (char*)info->name);
3251 set_failure (ctx, "can't encode patch");
3255 target = (gpointer)mono_icall_get_wrapper (info);
3256 callee = emit_jit_callee (ctx, "", llvm_sig, target);
3259 if (cfg->compile_aot) {
3261 if (cfg->abs_patches) {
3262 MonoJumpInfo *abs_ji = (MonoJumpInfo*)g_hash_table_lookup (cfg->abs_patches, call->fptr);
3264 callee = get_callee (ctx, llvm_sig, abs_ji->type, abs_ji->data.target);
3266 set_failure (ctx, "can't encode patch");
3272 set_failure (ctx, "aot");
3276 #if LLVM_API_VERSION > 100
3277 if (cfg->abs_patches) {
3278 MonoJumpInfo *abs_ji = (MonoJumpInfo*)g_hash_table_lookup (cfg->abs_patches, call->fptr);
3282 target = mono_resolve_patch_target (cfg->method, cfg->domain, NULL, abs_ji, FALSE, &error);
3283 mono_error_assert_ok (&error);
3284 callee = emit_jit_callee (ctx, "", llvm_sig, target);
3286 g_assert_not_reached ();
3289 g_assert_not_reached ();
3292 callee = LLVMAddFunction (ctx->lmodule, "", llvm_sig);
3294 if (cfg->abs_patches) {
3295 MonoJumpInfo *abs_ji = (MonoJumpInfo*)g_hash_table_lookup (cfg->abs_patches, call->fptr);
3300 * FIXME: Some trampolines might have
3301 * their own calling convention on some platforms.
3303 target = mono_resolve_patch_target (cfg->method, cfg->domain, NULL, abs_ji, FALSE, &error);
3304 mono_error_assert_ok (&error);
3305 LLVMAddGlobalMapping (ctx->module->ee, callee, target);
3309 LLVMAddGlobalMapping (ctx->module->ee, callee, (gpointer)call->fptr);
3316 int size = sizeof (gpointer);
3319 g_assert (ins->inst_offset % size == 0);
3320 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
3322 callee = convert (ctx, LLVMBuildLoad (builder, LLVMBuildGEP (builder, convert (ctx, values [ins->inst_basereg], LLVMPointerType (LLVMPointerType (IntPtrType (), 0), 0)), &index, 1, ""), ""), LLVMPointerType (llvm_sig, 0));
3324 callee = convert (ctx, values [ins->sreg1], LLVMPointerType (llvm_sig, 0));
3326 if (ins->flags & MONO_INST_HAS_METHOD) {
3331 * Collect and convert arguments
3333 nargs = (sig->param_count * 16) + sig->hasthis + vretaddr + call->rgctx_reg + call->imt_arg_reg;
3334 len = sizeof (LLVMValueRef) * nargs;
3335 args = (LLVMValueRef*)alloca (len);
3336 memset (args, 0, len);
3337 l = call->out_ireg_args;
3339 if (call->rgctx_arg_reg) {
3340 g_assert (values [call->rgctx_arg_reg]);
3341 g_assert (cinfo->rgctx_arg_pindex < nargs);
3343 * On ARM, the imt/rgctx argument is passed in a caller save register, but some of our trampolines etc. clobber it, leading to
3344 * problems is LLVM moves the arg assignment earlier. To work around this, save the argument into a stack slot and load
3345 * it using a volatile load.
3348 if (!ctx->imt_rgctx_loc)
3349 ctx->imt_rgctx_loc = build_alloca_llvm_type (ctx, ctx->module->ptr_type, sizeof (gpointer));
3350 LLVMBuildStore (builder, convert (ctx, ctx->values [call->rgctx_arg_reg], ctx->module->ptr_type), ctx->imt_rgctx_loc);
3351 args [cinfo->rgctx_arg_pindex] = mono_llvm_build_load (builder, ctx->imt_rgctx_loc, "", TRUE, LLVM_BARRIER_NONE);
3353 args [cinfo->rgctx_arg_pindex] = convert (ctx, values [call->rgctx_arg_reg], ctx->module->ptr_type);
3356 if (call->imt_arg_reg) {
3357 g_assert (!ctx->llvm_only);
3358 g_assert (values [call->imt_arg_reg]);
3359 g_assert (cinfo->imt_arg_pindex < nargs);
3361 if (!ctx->imt_rgctx_loc)
3362 ctx->imt_rgctx_loc = build_alloca_llvm_type (ctx, ctx->module->ptr_type, sizeof (gpointer));
3363 LLVMBuildStore (builder, convert (ctx, ctx->values [call->imt_arg_reg], ctx->module->ptr_type), ctx->imt_rgctx_loc);
3364 args [cinfo->imt_arg_pindex] = mono_llvm_build_load (builder, ctx->imt_rgctx_loc, "", TRUE, LLVM_BARRIER_NONE);
3366 args [cinfo->imt_arg_pindex] = convert (ctx, values [call->imt_arg_reg], ctx->module->ptr_type);
3369 switch (cinfo->ret.storage) {
3370 case LLVMArgGsharedvtVariable: {
3371 MonoInst *var = get_vreg_to_inst (cfg, call->inst.dreg);
3373 if (var && var->opcode == OP_GSHAREDVT_LOCAL) {
3374 args [cinfo->vret_arg_pindex] = convert (ctx, emit_gsharedvt_ldaddr (ctx, var->dreg), IntPtrType ());
3376 g_assert (addresses [call->inst.dreg]);
3377 args [cinfo->vret_arg_pindex] = addresses [call->inst.dreg];
3383 if (!addresses [call->inst.dreg])
3384 addresses [call->inst.dreg] = build_alloca (ctx, sig->ret);
3385 g_assert (cinfo->vret_arg_pindex < nargs);
3386 if (cinfo->ret.storage == LLVMArgVtypeByRef)
3387 args [cinfo->vret_arg_pindex] = addresses [call->inst.dreg];
3389 args [cinfo->vret_arg_pindex] = LLVMBuildPtrToInt (builder, addresses [call->inst.dreg], IntPtrType (), "");
3395 * Sometimes the same method is called with two different signatures (i.e. with and without 'this'), so
3396 * use the real callee for argument type conversion.
3398 LLVMTypeRef callee_type = LLVMGetElementType (LLVMTypeOf (callee));
3399 LLVMTypeRef *param_types = (LLVMTypeRef*)g_alloca (sizeof (LLVMTypeRef) * LLVMCountParamTypes (callee_type));
3400 LLVMGetParamTypes (callee_type, param_types);
3402 for (i = 0; i < sig->param_count + sig->hasthis; ++i) {
3405 LLVMArgInfo *ainfo = &call->cinfo->args [i];
3407 pindex = ainfo->pindex;
3409 regpair = (guint32)(gssize)(l->data);
3410 reg = regpair & 0xffffff;
3411 args [pindex] = values [reg];
3412 switch (ainfo->storage) {
3413 case LLVMArgVtypeInReg:
3414 case LLVMArgAsFpArgs: {
3418 for (j = 0; j < ainfo->ndummy_fpargs; ++j)
3419 args [pindex + j] = LLVMConstNull (LLVMDoubleType ());
3420 pindex += ainfo->ndummy_fpargs;
3422 g_assert (addresses [reg]);
3423 emit_vtype_to_args (ctx, builder, ainfo->type, addresses [reg], ainfo, args + pindex, &nargs);
3427 // FIXME: Get rid of the VMOVE
3430 case LLVMArgVtypeByVal:
3431 g_assert (addresses [reg]);
3432 args [pindex] = addresses [reg];
3434 case LLVMArgVtypeByRef: {
3435 g_assert (addresses [reg]);
3436 args [pindex] = convert (ctx, addresses [reg], LLVMPointerType (type_to_llvm_arg_type (ctx, ainfo->type), 0));
3439 case LLVMArgAsIArgs:
3440 g_assert (addresses [reg]);
3441 args [pindex] = LLVMBuildLoad (ctx->builder, convert (ctx, addresses [reg], LLVMPointerType (LLVMArrayType (IntPtrType (), ainfo->nslots), 0)), "");
3443 case LLVMArgVtypeAsScalar:
3444 g_assert_not_reached ();
3446 case LLVMArgGsharedvtFixed:
3447 case LLVMArgGsharedvtFixedVtype:
3448 g_assert (addresses [reg]);
3449 args [pindex] = convert (ctx, addresses [reg], LLVMPointerType (type_to_llvm_arg_type (ctx, ainfo->type), 0));
3451 case LLVMArgGsharedvtVariable:
3452 g_assert (addresses [reg]);
3453 args [pindex] = convert (ctx, addresses [reg], LLVMPointerType (IntPtrType (), 0));
3456 g_assert (args [pindex]);
3457 if (i == 0 && sig->hasthis)
3458 args [pindex] = convert (ctx, args [pindex], param_types [pindex]);
3460 args [pindex] = convert (ctx, args [pindex], type_to_llvm_arg_type (ctx, ainfo->type));
3463 g_assert (pindex <= nargs);
3468 // FIXME: Align call sites
3474 lcall = emit_call (ctx, bb, &builder, callee, args, LLVMCountParamTypes (llvm_sig));
3477 * Modify cconv and parameter attributes to pass rgctx/imt correctly.
3479 #if defined(MONO_ARCH_IMT_REG) && defined(MONO_ARCH_RGCTX_REG)
3480 g_assert (MONO_ARCH_IMT_REG == MONO_ARCH_RGCTX_REG);
3482 /* The two can't be used together, so use only one LLVM calling conv to pass them */
3483 g_assert (!(call->rgctx_arg_reg && call->imt_arg_reg));
3484 if (!sig->pinvoke && !cfg->llvm_only)
3485 LLVMSetInstructionCallConv (lcall, LLVMMono1CallConv);
3487 mono_llvm_set_call_preserveall_cc (lcall);
3489 if (cinfo->ret.storage == LLVMArgVtypeByRef)
3490 LLVMAddInstrAttribute (lcall, 1 + cinfo->vret_arg_pindex, LLVMStructRetAttribute);
3491 if (!ctx->llvm_only && call->rgctx_arg_reg)
3492 LLVMAddInstrAttribute (lcall, 1 + cinfo->rgctx_arg_pindex, LLVMInRegAttribute);
3493 if (call->imt_arg_reg)
3494 LLVMAddInstrAttribute (lcall, 1 + cinfo->imt_arg_pindex, LLVMInRegAttribute);
3496 /* Add byval attributes if needed */
3497 for (i = 0; i < sig->param_count; ++i) {
3498 LLVMArgInfo *ainfo = &call->cinfo->args [i + sig->hasthis];
3500 if (ainfo && ainfo->storage == LLVMArgVtypeByVal)
3501 LLVMAddInstrAttribute (lcall, 1 + ainfo->pindex, LLVMByValAttribute);
3505 * Convert the result
3507 switch (cinfo->ret.storage) {
3508 case LLVMArgVtypeInReg: {
3509 LLVMValueRef regs [2];
3511 if (LLVMTypeOf (lcall) == LLVMVoidType ())
3515 if (!addresses [ins->dreg])
3516 addresses [ins->dreg] = build_alloca (ctx, sig->ret);
3518 regs [0] = LLVMBuildExtractValue (builder, lcall, 0, "");
3519 if (cinfo->ret.pair_storage [1] != LLVMArgNone)
3520 regs [1] = LLVMBuildExtractValue (builder, lcall, 1, "");
3521 emit_args_to_vtype (ctx, builder, sig->ret, addresses [ins->dreg], &cinfo->ret, regs);
3524 case LLVMArgVtypeByVal:
3525 if (!addresses [call->inst.dreg])
3526 addresses [call->inst.dreg] = build_alloca (ctx, sig->ret);
3527 LLVMBuildStore (builder, lcall, addresses [call->inst.dreg]);
3529 case LLVMArgFpStruct:
3530 if (!addresses [call->inst.dreg])
3531 addresses [call->inst.dreg] = build_alloca (ctx, sig->ret);
3532 LLVMBuildStore (builder, lcall, convert_full (ctx, addresses [call->inst.dreg], LLVMPointerType (LLVMTypeOf (lcall), 0), FALSE));
3534 case LLVMArgVtypeAsScalar:
3535 if (!addresses [call->inst.dreg])
3536 addresses [call->inst.dreg] = build_alloca (ctx, sig->ret);
3537 LLVMBuildStore (builder, lcall, convert_full (ctx, addresses [call->inst.dreg], LLVMPointerType (LLVMTypeOf (lcall), 0), FALSE));
3539 case LLVMArgVtypeRetAddr:
3540 case LLVMArgVtypeByRef:
3541 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (sig->ret))) {
3542 /* Some opcodes like STOREX_MEMBASE access these by value */
3543 g_assert (addresses [call->inst.dreg]);
3544 values [ins->dreg] = LLVMBuildLoad (builder, convert_full (ctx, addresses [call->inst.dreg], LLVMPointerType (type_to_llvm_type (ctx, sig->ret), 0), FALSE), "");
3547 case LLVMArgGsharedvtVariable:
3549 case LLVMArgGsharedvtFixed:
3550 case LLVMArgGsharedvtFixedVtype:
3551 values [ins->dreg] = LLVMBuildLoad (builder, convert_full (ctx, addresses [call->inst.dreg], LLVMPointerType (type_to_llvm_type (ctx, sig->ret), 0), FALSE), "");
3554 if (sig->ret->type != MONO_TYPE_VOID)
3555 /* If the method returns an unsigned value, need to zext it */
3556 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));
3560 *builder_ref = ctx->builder;
3564 emit_llvmonly_throw (EmitContext *ctx, MonoBasicBlock *bb, gboolean rethrow, LLVMValueRef exc)
3566 const char *icall_name = rethrow ? "mono_llvm_rethrow_exception" : "mono_llvm_throw_exception";
3567 LLVMValueRef callee = rethrow ? ctx->module->rethrow : ctx->module->throw_icall;
3569 LLVMTypeRef exc_type = type_to_llvm_type (ctx, &mono_get_exception_class ()->byval_arg);
3572 LLVMTypeRef fun_sig = LLVMFunctionType1 (LLVMVoidType (), exc_type, FALSE);
3574 if (ctx->cfg->compile_aot) {
3575 callee = get_callee (ctx, fun_sig, MONO_PATCH_INFO_JIT_ICALL_ADDR, icall_name);
3577 callee = LLVMAddFunction (ctx->lmodule, icall_name, fun_sig);
3578 LLVMAddGlobalMapping (ctx->module->ee, callee, resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name));
3579 mono_memory_barrier ();
3582 ctx->module->rethrow = callee;
3584 ctx->module->throw_icall = callee;
3588 LLVMValueRef args [2];
3590 args [0] = convert (ctx, exc, exc_type);
3591 emit_call (ctx, bb, &ctx->builder, callee, args, 1);
3593 LLVMBuildUnreachable (ctx->builder);
3595 ctx->builder = create_builder (ctx);
3599 emit_throw (EmitContext *ctx, MonoBasicBlock *bb, gboolean rethrow, LLVMValueRef exc)
3601 MonoMethodSignature *throw_sig;
3602 LLVMValueRef callee, arg;
3603 const char *icall_name;
3605 callee = rethrow ? ctx->module->rethrow : ctx->module->throw_icall;
3606 icall_name = rethrow ? "mono_arch_rethrow_exception" : "mono_arch_throw_exception";
3609 throw_sig = mono_metadata_signature_alloc (mono_get_corlib (), 1);
3610 throw_sig->ret = &mono_get_void_class ()->byval_arg;
3611 throw_sig->params [0] = &mono_get_object_class ()->byval_arg;
3612 if (ctx->cfg->compile_aot) {
3613 callee = get_callee (ctx, sig_to_llvm_sig (ctx, throw_sig), MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
3618 * LLVM doesn't push the exception argument, so we need a different
3621 target = resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, rethrow ? "llvm_rethrow_exception_trampoline" : "llvm_throw_exception_trampoline");
3623 target = resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
3625 callee = emit_jit_callee (ctx, icall_name, sig_to_llvm_sig (ctx, throw_sig), target);
3628 mono_memory_barrier ();
3629 #if LLVM_API_VERSION < 100
3631 ctx->module->rethrow = callee;
3633 ctx->module->throw_icall = callee;
3636 arg = convert (ctx, exc, type_to_llvm_type (ctx, &mono_get_object_class ()->byval_arg));
3637 emit_call (ctx, bb, &ctx->builder, callee, &arg, 1);
3641 emit_resume_eh (EmitContext *ctx, MonoBasicBlock *bb)
3643 const char *icall_name = "mono_llvm_resume_exception";
3644 LLVMValueRef callee = ctx->module->resume_eh;
3646 LLVMTypeRef fun_sig = LLVMFunctionType0 (LLVMVoidType (), FALSE);
3649 if (ctx->cfg->compile_aot) {
3650 callee = get_callee (ctx, fun_sig, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
3652 callee = LLVMAddFunction (ctx->lmodule, icall_name, fun_sig);
3653 LLVMAddGlobalMapping (ctx->module->ee, callee, resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name));
3654 mono_memory_barrier ();
3656 ctx->module->resume_eh = callee;
3660 emit_call (ctx, bb, &ctx->builder, callee, NULL, 0);
3662 LLVMBuildUnreachable (ctx->builder);
3664 ctx->builder = create_builder (ctx);
3668 mono_llvm_emit_clear_exception_call (EmitContext *ctx, LLVMBuilderRef builder)
3670 const char *icall_name = "mono_llvm_clear_exception";
3672 LLVMTypeRef call_sig = LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE);
3673 LLVMValueRef callee = NULL;
3676 if (ctx->cfg->compile_aot) {
3677 callee = get_callee (ctx, call_sig, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
3679 // FIXME: This is broken.
3680 callee = LLVMAddFunction (ctx->lmodule, icall_name, call_sig);
3684 g_assert (builder && callee);
3686 return LLVMBuildCall (builder, callee, NULL, 0, "");
3690 mono_llvm_emit_load_exception_call (EmitContext *ctx, LLVMBuilderRef builder)
3692 const char *icall_name = "mono_llvm_load_exception";
3694 LLVMTypeRef call_sig = LLVMFunctionType (ObjRefType (), NULL, 0, FALSE);
3695 LLVMValueRef callee = NULL;
3698 if (ctx->cfg->compile_aot) {
3699 callee = get_callee (ctx, call_sig, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
3701 // FIXME: This is broken.
3702 callee = LLVMAddFunction (ctx->lmodule, icall_name, call_sig);
3706 g_assert (builder && callee);
3708 return LLVMBuildCall (builder, callee, NULL, 0, icall_name);
3713 mono_llvm_emit_match_exception_call (EmitContext *ctx, LLVMBuilderRef builder, gint32 region_start, gint32 region_end)
3715 const char *icall_name = "mono_llvm_match_exception";
3717 ctx->builder = builder;
3719 const int num_args = 5;
3720 LLVMValueRef args [num_args];
3721 args [0] = convert (ctx, get_aotconst (ctx, MONO_PATCH_INFO_AOT_JIT_INFO, GINT_TO_POINTER (ctx->cfg->method_index)), IntPtrType ());
3722 args [1] = LLVMConstInt (LLVMInt32Type (), region_start, 0);
3723 args [2] = LLVMConstInt (LLVMInt32Type (), region_end, 0);
3724 if (ctx->cfg->rgctx_var) {
3725 LLVMValueRef rgctx_alloc = ctx->addresses [ctx->cfg->rgctx_var->dreg];
3726 g_assert (rgctx_alloc);
3727 args [3] = LLVMBuildLoad (builder, convert (ctx, rgctx_alloc, LLVMPointerType (IntPtrType (), 0)), "");
3729 args [3] = LLVMConstInt (IntPtrType (), 0, 0);
3732 args [4] = convert (ctx, ctx->this_arg, IntPtrType ());
3734 args [4] = LLVMConstInt (IntPtrType (), 0, 0);
3736 LLVMTypeRef match_sig = LLVMFunctionType5 (LLVMInt32Type (), IntPtrType (), LLVMInt32Type (), LLVMInt32Type (), IntPtrType (), IntPtrType (), FALSE);
3737 LLVMValueRef callee = ctx->module->match_exc;
3740 if (ctx->cfg->compile_aot) {
3741 ctx->builder = builder;
3742 // get_callee expects ctx->builder to be the emitting builder
3743 callee = get_callee (ctx, match_sig, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
3745 callee = ctx->module->match_exc = LLVMAddFunction (ctx->lmodule, icall_name, match_sig);
3746 LLVMAddGlobalMapping (ctx->module->ee, ctx->module->match_exc, resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name));
3747 ctx->module->match_exc = callee;
3748 mono_memory_barrier ();
3752 g_assert (builder && callee);
3754 g_assert (ctx->ex_var);
3756 return LLVMBuildCall (builder, callee, args, num_args, icall_name);
3759 // FIXME: This won't work because the code-finding makes this
3761 /*#define MONO_PERSONALITY_DEBUG*/
3763 #ifdef MONO_PERSONALITY_DEBUG
3764 static const gboolean use_debug_personality = TRUE;
3765 static const char *default_personality_name = "mono_debug_personality";
3767 static const gboolean use_debug_personality = FALSE;
3768 static const char *default_personality_name = "__gxx_personality_v0";
3772 default_cpp_lpad_exc_signature (void)
3774 static gboolean inited = FALSE;
3775 static LLVMTypeRef sig;
3778 LLVMTypeRef signature [2];
3779 signature [0] = LLVMPointerType (LLVMInt8Type (), 0);
3780 signature [1] = LLVMInt32Type ();
3781 sig = LLVMStructType (signature, 2, FALSE);
3789 get_mono_personality (EmitContext *ctx)
3791 LLVMValueRef personality = NULL;
3792 static gint32 mapping_inited = FALSE;
3793 LLVMTypeRef personality_type = LLVMFunctionType (LLVMInt32Type (), NULL, 0, TRUE);
3795 if (!use_debug_personality) {
3796 if (ctx->cfg->compile_aot) {
3797 personality = get_intrinsic (ctx, default_personality_name);
3798 } else if (InterlockedCompareExchange (&mapping_inited, 1, 0) == 0) {
3799 personality = LLVMAddFunction (ctx->lmodule, default_personality_name, personality_type);
3800 LLVMAddGlobalMapping (ctx->module->ee, personality, personality);
3803 if (ctx->cfg->compile_aot) {
3804 personality = get_callee (ctx, personality_type, MONO_PATCH_INFO_INTERNAL_METHOD, default_personality_name);
3806 personality = LLVMAddFunction (ctx->lmodule, default_personality_name, personality_type);
3807 LLVMAddGlobalMapping (ctx->module->ee, personality, resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, default_personality_name));
3808 mono_memory_barrier ();
3812 g_assert (personality);
3816 static LLVMBasicBlockRef
3817 emit_landing_pad (EmitContext *ctx, int group_index, int group_size)
3819 MonoCompile *cfg = ctx->cfg;
3820 LLVMBuilderRef old_builder = ctx->builder;
3821 MonoExceptionClause *group_start = cfg->header->clauses + group_index;
3823 LLVMBuilderRef lpadBuilder = create_builder (ctx);
3824 ctx->builder = lpadBuilder;
3826 MonoBasicBlock *handler_bb = cfg->cil_offset_to_bb [CLAUSE_START (group_start)];
3827 g_assert (handler_bb);
3829 // <resultval> = landingpad <somety> personality <type> <pers_fn> <clause>+
3830 LLVMValueRef personality = get_mono_personality (ctx);
3831 g_assert (personality);
3833 char *bb_name = g_strdup_printf ("LPAD%d_BB", group_index);
3834 LLVMBasicBlockRef lpad_bb = gen_bb (ctx, bb_name);
3836 LLVMPositionBuilderAtEnd (lpadBuilder, lpad_bb);
3837 LLVMValueRef landing_pad = LLVMBuildLandingPad (lpadBuilder, default_cpp_lpad_exc_signature (), personality, 0, "");
3838 g_assert (landing_pad);
3840 LLVMValueRef cast = LLVMBuildBitCast (lpadBuilder, ctx->module->sentinel_exception, LLVMPointerType (LLVMInt8Type (), 0), "int8TypeInfo");
3841 LLVMAddClause (landing_pad, cast);
3843 LLVMBasicBlockRef resume_bb = gen_bb (ctx, "RESUME_BB");
3844 LLVMBuilderRef resume_builder = create_builder (ctx);
3845 ctx->builder = resume_builder;
3846 LLVMPositionBuilderAtEnd (resume_builder, resume_bb);
3848 emit_resume_eh (ctx, handler_bb);
3851 ctx->builder = lpadBuilder;
3852 LLVMPositionBuilderAtEnd (lpadBuilder, lpad_bb);
3854 gboolean finally_only = TRUE;
3856 MonoExceptionClause *group_cursor = group_start;
3858 for (int i = 0; i < group_size; i ++) {
3859 if (!(group_cursor->flags & MONO_EXCEPTION_CLAUSE_FINALLY))
3860 finally_only = FALSE;
3866 // Handle landing pad inlining
3868 if (!finally_only) {
3869 // So at each level of the exception stack we will match the exception again.
3870 // During that match, we need to compare against the handler types for the current
3871 // protected region. We send the try start and end so that we can only check against
3872 // handlers for this lexical protected region.
3873 LLVMValueRef match = mono_llvm_emit_match_exception_call (ctx, lpadBuilder, group_start->try_offset, group_start->try_offset + group_start->try_len);
3875 // if returns -1, resume
3876 LLVMValueRef switch_ins = LLVMBuildSwitch (lpadBuilder, match, resume_bb, group_size);
3878 // else move to that target bb
3879 for (int i=0; i < group_size; i++) {
3880 MonoExceptionClause *clause = group_start + i;
3881 int clause_index = clause - cfg->header->clauses;
3882 MonoBasicBlock *handler_bb = (MonoBasicBlock*)g_hash_table_lookup (ctx->clause_to_handler, GINT_TO_POINTER (clause_index));
3883 g_assert (handler_bb);
3884 g_assert (ctx->bblocks [handler_bb->block_num].call_handler_target_bb);
3885 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), clause_index, FALSE), ctx->bblocks [handler_bb->block_num].call_handler_target_bb);
3888 int clause_index = group_start - cfg->header->clauses;
3889 MonoBasicBlock *finally_bb = (MonoBasicBlock*)g_hash_table_lookup (ctx->clause_to_handler, GINT_TO_POINTER (clause_index));
3890 g_assert (finally_bb);
3892 LLVMBuildBr (ctx->builder, ctx->bblocks [finally_bb->block_num].call_handler_target_bb);
3895 ctx->builder = old_builder;
3902 emit_llvmonly_handler_start (EmitContext *ctx, MonoBasicBlock *bb, LLVMBasicBlockRef cbb)
3904 int clause_index = MONO_REGION_CLAUSE_INDEX (bb->region);
3905 MonoExceptionClause *clause = &ctx->cfg->header->clauses [clause_index];
3907 // Make exception available to catch blocks
3908 if (!(clause->flags & MONO_EXCEPTION_CLAUSE_FINALLY)) {
3909 LLVMValueRef mono_exc = mono_llvm_emit_load_exception_call (ctx, ctx->builder);
3911 g_assert (ctx->ex_var);
3912 LLVMBuildStore (ctx->builder, LLVMBuildBitCast (ctx->builder, mono_exc, ObjRefType (), ""), ctx->ex_var);
3914 if (bb->in_scount == 1) {
3915 MonoInst *exvar = bb->in_stack [0];
3916 g_assert (!ctx->values [exvar->dreg]);
3917 g_assert (ctx->ex_var);
3918 ctx->values [exvar->dreg] = LLVMBuildLoad (ctx->builder, ctx->ex_var, "save_exception");
3919 emit_volatile_store (ctx, exvar->dreg);
3922 mono_llvm_emit_clear_exception_call (ctx, ctx->builder);
3925 LLVMBuilderRef handler_builder = create_builder (ctx);
3926 LLVMBasicBlockRef target_bb = ctx->bblocks [bb->block_num].call_handler_target_bb;
3927 LLVMPositionBuilderAtEnd (handler_builder, target_bb);
3929 // Make the handler code end with a jump to cbb
3930 LLVMBuildBr (handler_builder, cbb);
3934 emit_handler_start (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef builder)
3936 MonoCompile *cfg = ctx->cfg;
3937 LLVMValueRef *values = ctx->values;
3938 LLVMModuleRef lmodule = ctx->lmodule;
3939 BBInfo *bblocks = ctx->bblocks;
3941 LLVMValueRef personality;
3942 LLVMValueRef landing_pad;
3943 LLVMBasicBlockRef target_bb;
3945 static int ti_generator;
3947 LLVMValueRef type_info;
3951 // <resultval> = landingpad <somety> personality <type> <pers_fn> <clause>+
3953 if (cfg->compile_aot) {
3954 /* Use a dummy personality function */
3955 personality = LLVMGetNamedFunction (lmodule, "mono_personality");
3956 g_assert (personality);
3958 #if LLVM_API_VERSION > 100
3959 LLVMTypeRef personality_type = LLVMFunctionType (LLVMInt32Type (), NULL, 0, TRUE);
3960 personality = LLVMAddFunction (ctx->lmodule, "mono_personality", personality_type);
3961 LLVMAddFunctionAttr (personality, LLVMNoUnwindAttribute);
3962 LLVMBasicBlockRef entry_bb = LLVMAppendBasicBlock (personality, "ENTRY");
3963 LLVMBuilderRef builder2 = LLVMCreateBuilder ();
3964 LLVMPositionBuilderAtEnd (builder2, entry_bb);
3965 LLVMBuildRet (builder2, LLVMConstInt (LLVMInt32Type (), 0, FALSE));
3967 static gint32 mapping_inited;
3969 personality = LLVMGetNamedFunction (lmodule, "mono_personality");
3971 if (InterlockedCompareExchange (&mapping_inited, 1, 0) == 0)
3972 LLVMAddGlobalMapping (ctx->module->ee, personality, (gpointer)mono_personality);
3976 i8ptr = LLVMPointerType (LLVMInt8Type (), 0);
3978 clause_index = (mono_get_block_region_notry (cfg, bb->region) >> 8) - 1;
3981 * Create the type info
3983 sprintf (ti_name, "type_info_%d", ti_generator);
3986 if (cfg->compile_aot) {
3987 /* decode_eh_frame () in aot-runtime.c will decode this */
3988 type_info = LLVMAddGlobal (lmodule, LLVMInt32Type (), ti_name);
3989 LLVMSetInitializer (type_info, LLVMConstInt (LLVMInt32Type (), clause_index, FALSE));
3992 * These symbols are not really used, the clause_index is embedded into the EH tables generated by DwarfMonoException in LLVM.
3994 LLVMSetLinkage (type_info, LLVMInternalLinkage);
3996 #if LLVM_API_VERSION > 100
3997 type_info = LLVMAddGlobal (lmodule, LLVMInt32Type (), ti_name);
3998 LLVMSetInitializer (type_info, LLVMConstInt (LLVMInt32Type (), clause_index, FALSE));
4003 * After the cfg mempool is freed, the type info will point to stale memory,
4004 * but this is not a problem, since we decode it once in exception_cb during
4007 ti = (gint32*)mono_mempool_alloc (cfg->mempool, sizeof (gint32));
4008 *(gint32*)ti = clause_index;
4010 type_info = LLVMAddGlobal (lmodule, i8ptr, ti_name);
4012 LLVMAddGlobalMapping (ctx->module->ee, type_info, ti);
4017 LLVMTypeRef members [2], ret_type;
4019 members [0] = i8ptr;
4020 members [1] = LLVMInt32Type ();
4021 ret_type = LLVMStructType (members, 2, FALSE);
4023 landing_pad = LLVMBuildLandingPad (builder, ret_type, personality, 1, "");
4024 LLVMAddClause (landing_pad, type_info);
4026 /* Store the exception into the exvar */
4028 LLVMBuildStore (builder, convert (ctx, LLVMBuildExtractValue (builder, landing_pad, 0, "ex_obj"), ObjRefType ()), ctx->ex_var);
4032 * LLVM throw sites are associated with a one landing pad, and LLVM generated
4033 * code expects control to be transferred to this landing pad even in the
4034 * presence of nested clauses. The landing pad needs to branch to the landing
4035 * pads belonging to nested clauses based on the selector value returned by
4036 * the landing pad instruction, which is passed to the landing pad in a
4037 * register by the EH code.
4039 target_bb = bblocks [bb->block_num].call_handler_target_bb;
4040 g_assert (target_bb);
4043 * Branch to the correct landing pad
4045 LLVMValueRef ex_selector = LLVMBuildExtractValue (builder, landing_pad, 1, "ex_selector");
4046 LLVMValueRef switch_ins = LLVMBuildSwitch (builder, ex_selector, target_bb, 0);
4048 for (l = ctx->nested_in [clause_index]; l; l = l->next) {
4049 int nesting_clause_index = GPOINTER_TO_INT (l->data);
4050 MonoBasicBlock *handler_bb;
4052 handler_bb = (MonoBasicBlock*)g_hash_table_lookup (ctx->clause_to_handler, GINT_TO_POINTER (nesting_clause_index));
4053 g_assert (handler_bb);
4055 g_assert (ctx->bblocks [handler_bb->block_num].call_handler_target_bb);
4056 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), nesting_clause_index, FALSE), ctx->bblocks [handler_bb->block_num].call_handler_target_bb);
4059 /* Start a new bblock which CALL_HANDLER can branch to */
4060 target_bb = bblocks [bb->block_num].call_handler_target_bb;
4062 ctx->builder = builder = create_builder (ctx);
4063 LLVMPositionBuilderAtEnd (ctx->builder, target_bb);
4065 ctx->bblocks [bb->block_num].end_bblock = target_bb;
4067 /* Store the exception into the IL level exvar */
4068 if (bb->in_scount == 1) {
4069 g_assert (bb->in_scount == 1);
4070 exvar = bb->in_stack [0];
4072 // FIXME: This is shared with filter clauses ?
4073 g_assert (!values [exvar->dreg]);
4075 g_assert (ctx->ex_var);
4076 values [exvar->dreg] = LLVMBuildLoad (builder, ctx->ex_var, "");
4077 emit_volatile_store (ctx, exvar->dreg);
4083 process_bb (EmitContext *ctx, MonoBasicBlock *bb)
4085 MonoCompile *cfg = ctx->cfg;
4086 MonoMethodSignature *sig = ctx->sig;
4087 LLVMValueRef method = ctx->lmethod;
4088 LLVMValueRef *values = ctx->values;
4089 LLVMValueRef *addresses = ctx->addresses;
4090 LLVMCallInfo *linfo = ctx->linfo;
4091 BBInfo *bblocks = ctx->bblocks;
4093 LLVMBasicBlockRef cbb;
4094 LLVMBuilderRef builder, starting_builder;
4095 gboolean has_terminator;
4097 LLVMValueRef lhs, rhs;
4100 cbb = get_end_bb (ctx, bb);
4102 builder = create_builder (ctx);
4103 ctx->builder = builder;
4104 LLVMPositionBuilderAtEnd (builder, cbb);
4109 if (bb->flags & BB_EXCEPTION_HANDLER) {
4110 if (!ctx->llvm_only && !bblocks [bb->block_num].invoke_target) {
4111 set_failure (ctx, "handler without invokes");
4116 emit_llvmonly_handler_start (ctx, bb, cbb);
4118 emit_handler_start (ctx, bb, builder);
4121 builder = ctx->builder;
4124 has_terminator = FALSE;
4125 starting_builder = builder;
4126 for (ins = bb->code; ins; ins = ins->next) {
4127 const char *spec = LLVM_INS_INFO (ins->opcode);
4129 char dname_buf [128];
4131 emit_dbg_loc (ctx, builder, ins->cil_code);
4136 * Some steps in llc are non-linear in the size of basic blocks, see #5714.
4137 * Start a new bblock. If the llvm optimization passes merge these, we
4138 * can work around that by doing a volatile load + cond branch from
4139 * localloc-ed memory.
4141 //set_failure (ctx, "basic block too long");
4142 cbb = gen_bb (ctx, "CONT_LONG_BB");
4143 LLVMBuildBr (ctx->builder, cbb);
4144 ctx->builder = builder = create_builder (ctx);
4145 LLVMPositionBuilderAtEnd (builder, cbb);
4146 ctx->bblocks [bb->block_num].end_bblock = cbb;
4151 /* There could be instructions after a terminator, skip them */
4154 if (spec [MONO_INST_DEST] != ' ' && !MONO_IS_STORE_MEMBASE (ins)) {
4155 sprintf (dname_buf, "t%d", ins->dreg);
4159 if (spec [MONO_INST_SRC1] != ' ' && spec [MONO_INST_SRC1] != 'v') {
4160 MonoInst *var = get_vreg_to_inst (cfg, ins->sreg1);
4162 if (var && var->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT) && var->opcode != OP_GSHAREDVT_ARG_REGOFFSET) {
4163 lhs = emit_volatile_load (ctx, ins->sreg1);
4165 /* It is ok for SETRET to have an uninitialized argument */
4166 if (!values [ins->sreg1] && ins->opcode != OP_SETRET) {
4167 set_failure (ctx, "sreg1");
4170 lhs = values [ins->sreg1];
4176 if (spec [MONO_INST_SRC2] != ' ' && spec [MONO_INST_SRC2] != ' ') {
4177 MonoInst *var = get_vreg_to_inst (cfg, ins->sreg2);
4178 if (var && var->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT)) {
4179 rhs = emit_volatile_load (ctx, ins->sreg2);
4181 if (!values [ins->sreg2]) {
4182 set_failure (ctx, "sreg2");
4185 rhs = values [ins->sreg2];
4191 //mono_print_ins (ins);
4192 switch (ins->opcode) {
4195 case OP_LIVERANGE_START:
4196 case OP_LIVERANGE_END:
4199 values [ins->dreg] = LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE);
4202 #if SIZEOF_VOID_P == 4
4203 values [ins->dreg] = LLVMConstInt (LLVMInt64Type (), GET_LONG_IMM (ins), FALSE);
4205 values [ins->dreg] = LLVMConstInt (LLVMInt64Type (), (gint64)ins->inst_c0, FALSE);
4209 values [ins->dreg] = LLVMConstReal (LLVMDoubleType (), *(double*)ins->inst_p0);
4213 values [ins->dreg] = LLVMConstReal (LLVMFloatType (), *(float*)ins->inst_p0);
4215 values [ins->dreg] = LLVMConstFPExt (LLVMConstReal (LLVMFloatType (), *(float*)ins->inst_p0), LLVMDoubleType ());
4217 case OP_DUMMY_ICONST:
4218 values [ins->dreg] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
4220 case OP_DUMMY_I8CONST:
4221 values [ins->dreg] = LLVMConstInt (LLVMInt64Type (), 0, FALSE);
4223 case OP_DUMMY_R8CONST:
4224 values [ins->dreg] = LLVMConstReal (LLVMDoubleType (), 0.0f);
4227 LLVMBasicBlockRef target_bb = get_bb (ctx, ins->inst_target_bb);
4228 LLVMBuildBr (builder, target_bb);
4229 has_terminator = TRUE;
4236 LLVMBasicBlockRef new_bb;
4237 LLVMBuilderRef new_builder;
4239 // The default branch is already handled
4240 // FIXME: Handle it here
4242 /* Start new bblock */
4243 sprintf (bb_name, "SWITCH_DEFAULT_BB%d", ctx->default_index ++);
4244 new_bb = LLVMAppendBasicBlock (ctx->lmethod, bb_name);
4246 lhs = convert (ctx, lhs, LLVMInt32Type ());
4247 v = LLVMBuildSwitch (builder, lhs, new_bb, GPOINTER_TO_UINT (ins->klass));
4248 for (i = 0; i < GPOINTER_TO_UINT (ins->klass); ++i) {
4249 MonoBasicBlock *target_bb = ins->inst_many_bb [i];
4251 LLVMAddCase (v, LLVMConstInt (LLVMInt32Type (), i, FALSE), get_bb (ctx, target_bb));
4254 new_builder = create_builder (ctx);
4255 LLVMPositionBuilderAtEnd (new_builder, new_bb);
4256 LLVMBuildUnreachable (new_builder);
4258 has_terminator = TRUE;
4259 g_assert (!ins->next);
4265 switch (linfo->ret.storage) {
4266 case LLVMArgVtypeInReg: {
4267 LLVMTypeRef ret_type = LLVMGetReturnType (LLVMGetElementType (LLVMTypeOf (method)));
4268 LLVMValueRef val, addr, retval;
4271 retval = LLVMGetUndef (ret_type);
4273 if (!addresses [ins->sreg1]) {
4275 * The return type is an LLVM vector type, have to convert between it and the
4276 * real return type which is a struct type.
4278 g_assert (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (sig->ret)));
4279 /* Convert to 2xi64 first */
4280 val = LLVMBuildBitCast (builder, values [ins->sreg1], LLVMVectorType (IntPtrType (), 2), "");
4282 for (i = 0; i < 2; ++i) {
4283 if (linfo->ret.pair_storage [i] == LLVMArgInIReg) {
4284 retval = LLVMBuildInsertValue (builder, retval, LLVMBuildExtractElement (builder, val, LLVMConstInt (LLVMInt32Type (), i, FALSE), ""), i, "");
4286 g_assert (linfo->ret.pair_storage [i] == LLVMArgNone);
4290 addr = LLVMBuildBitCast (builder, addresses [ins->sreg1], LLVMPointerType (ret_type, 0), "");
4291 for (i = 0; i < 2; ++i) {
4292 if (linfo->ret.pair_storage [i] == LLVMArgInIReg) {
4293 LLVMValueRef indexes [2], part_addr;
4295 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
4296 indexes [1] = LLVMConstInt (LLVMInt32Type (), i, FALSE);
4297 part_addr = LLVMBuildGEP (builder, addr, indexes, 2, "");
4299 retval = LLVMBuildInsertValue (builder, retval, LLVMBuildLoad (builder, part_addr, ""), i, "");
4301 g_assert (linfo->ret.pair_storage [i] == LLVMArgNone);
4305 LLVMBuildRet (builder, retval);
4308 case LLVMArgVtypeAsScalar: {
4309 LLVMTypeRef ret_type = LLVMGetReturnType (LLVMGetElementType (LLVMTypeOf (method)));
4310 LLVMValueRef retval;
4312 g_assert (addresses [ins->sreg1]);
4314 retval = LLVMBuildLoad (builder, LLVMBuildBitCast (builder, addresses [ins->sreg1], LLVMPointerType (ret_type, 0), ""), "");
4315 LLVMBuildRet (builder, retval);
4318 case LLVMArgVtypeByVal: {
4319 LLVMValueRef retval;
4321 g_assert (addresses [ins->sreg1]);
4322 retval = LLVMBuildLoad (builder, addresses [ins->sreg1], "");
4323 LLVMBuildRet (builder, retval);
4326 case LLVMArgVtypeByRef: {
4327 LLVMBuildRetVoid (builder);
4330 case LLVMArgGsharedvtFixed: {
4331 LLVMTypeRef ret_type = type_to_llvm_type (ctx, sig->ret);
4332 /* The return value is in lhs, need to store to the vret argument */
4333 /* sreg1 might not be set */
4335 g_assert (cfg->vret_addr);
4336 g_assert (values [cfg->vret_addr->dreg]);
4337 LLVMBuildStore (builder, convert (ctx, lhs, ret_type), convert (ctx, values [cfg->vret_addr->dreg], LLVMPointerType (ret_type, 0)));
4339 LLVMBuildRetVoid (builder);
4342 case LLVMArgGsharedvtFixedVtype: {
4344 LLVMBuildRetVoid (builder);
4347 case LLVMArgGsharedvtVariable: {
4349 LLVMBuildRetVoid (builder);
4352 case LLVMArgVtypeRetAddr: {
4353 LLVMBuildRetVoid (builder);
4356 case LLVMArgFpStruct: {
4357 LLVMTypeRef ret_type = LLVMGetReturnType (LLVMGetElementType (LLVMTypeOf (method)));
4358 LLVMValueRef retval;
4360 g_assert (addresses [ins->sreg1]);
4361 retval = LLVMBuildLoad (builder, convert (ctx, addresses [ins->sreg1], LLVMPointerType (ret_type, 0)), "");
4362 LLVMBuildRet (builder, retval);
4366 case LLVMArgNormal: {
4367 if (!lhs || ctx->is_dead [ins->sreg1]) {
4369 * The method did not set its return value, probably because it
4370 * ends with a throw.
4373 LLVMBuildRetVoid (builder);
4375 LLVMBuildRet (builder, LLVMConstNull (type_to_llvm_type (ctx, sig->ret)));
4377 LLVMBuildRet (builder, convert (ctx, lhs, type_to_llvm_type (ctx, sig->ret)));
4379 has_terminator = TRUE;
4383 g_assert_not_reached ();
4392 case OP_ICOMPARE_IMM:
4393 case OP_LCOMPARE_IMM:
4394 case OP_COMPARE_IMM: {
4396 LLVMValueRef cmp, args [16];
4397 gboolean likely = (ins->flags & MONO_INST_LIKELY) != 0;
4399 if (ins->next->opcode == OP_NOP)
4402 if (ins->next->opcode == OP_BR)
4403 /* The comparison result is not needed */
4406 rel = mono_opcode_to_cond (ins->next->opcode);
4408 if (ins->opcode == OP_ICOMPARE_IMM) {
4409 lhs = convert (ctx, lhs, LLVMInt32Type ());
4410 rhs = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
4412 if (ins->opcode == OP_LCOMPARE_IMM) {
4413 lhs = convert (ctx, lhs, LLVMInt64Type ());
4414 rhs = LLVMConstInt (LLVMInt64Type (), GET_LONG_IMM (ins), FALSE);
4416 if (ins->opcode == OP_LCOMPARE) {
4417 lhs = convert (ctx, lhs, LLVMInt64Type ());
4418 rhs = convert (ctx, rhs, LLVMInt64Type ());
4420 if (ins->opcode == OP_ICOMPARE) {
4421 lhs = convert (ctx, lhs, LLVMInt32Type ());
4422 rhs = convert (ctx, rhs, LLVMInt32Type ());
4426 if (LLVMGetTypeKind (LLVMTypeOf (lhs)) == LLVMPointerTypeKind)
4427 rhs = convert (ctx, rhs, LLVMTypeOf (lhs));
4428 else if (LLVMGetTypeKind (LLVMTypeOf (rhs)) == LLVMPointerTypeKind)
4429 lhs = convert (ctx, lhs, LLVMTypeOf (rhs));
4432 /* We use COMPARE+SETcc/Bcc, llvm uses SETcc+br cond */
4433 if (ins->opcode == OP_FCOMPARE) {
4434 cmp = LLVMBuildFCmp (builder, fpcond_to_llvm_cond [rel], convert (ctx, lhs, LLVMDoubleType ()), convert (ctx, rhs, LLVMDoubleType ()), "");
4435 } else if (ins->opcode == OP_RCOMPARE) {
4436 cmp = LLVMBuildFCmp (builder, fpcond_to_llvm_cond [rel], convert (ctx, lhs, LLVMFloatType ()), convert (ctx, rhs, LLVMFloatType ()), "");
4437 } else if (ins->opcode == OP_COMPARE_IMM) {
4438 if (LLVMGetTypeKind (LLVMTypeOf (lhs)) == LLVMPointerTypeKind && ins->inst_imm == 0)
4439 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], lhs, LLVMConstNull (LLVMTypeOf (lhs)), "");
4441 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE), "");
4442 } else if (ins->opcode == OP_LCOMPARE_IMM) {
4443 if (SIZEOF_REGISTER == 4 && COMPILE_LLVM (cfg)) {
4444 /* The immediate is encoded in two fields */
4445 guint64 l = ((guint64)(guint32)ins->inst_offset << 32) | ((guint32)ins->inst_imm);
4446 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, LLVMInt64Type ()), LLVMConstInt (LLVMInt64Type (), l, FALSE), "");
4448 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, LLVMInt64Type ()), LLVMConstInt (LLVMInt64Type (), ins->inst_imm, FALSE), "");
4451 else if (ins->opcode == OP_COMPARE) {
4452 if (LLVMGetTypeKind (LLVMTypeOf (lhs)) == LLVMPointerTypeKind && LLVMTypeOf (lhs) == LLVMTypeOf (rhs))
4453 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], lhs, rhs, "");
4455 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, IntPtrType ()), convert (ctx, rhs, IntPtrType ()), "");
4457 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], lhs, rhs, "");
4461 args [1] = LLVMConstInt (LLVMInt1Type (), 1, FALSE);
4462 cmp = LLVMBuildCall (ctx->builder, get_intrinsic (ctx, "llvm.expect.i1"), args, 2, "");
4465 if (MONO_IS_COND_BRANCH_OP (ins->next)) {
4466 if (ins->next->inst_true_bb == ins->next->inst_false_bb) {
4468 * If the target bb contains PHI instructions, LLVM requires
4469 * two PHI entries for this bblock, while we only generate one.
4470 * So convert this to an unconditional bblock. (bxc #171).
4472 LLVMBuildBr (builder, get_bb (ctx, ins->next->inst_true_bb));
4474 LLVMBuildCondBr (builder, cmp, get_bb (ctx, ins->next->inst_true_bb), get_bb (ctx, ins->next->inst_false_bb));
4476 has_terminator = TRUE;
4477 } else if (MONO_IS_SETCC (ins->next)) {
4478 sprintf (dname_buf, "t%d", ins->next->dreg);
4480 values [ins->next->dreg] = LLVMBuildZExt (builder, cmp, LLVMInt32Type (), dname);
4482 /* Add stores for volatile variables */
4483 emit_volatile_store (ctx, ins->next->dreg);
4484 } else if (MONO_IS_COND_EXC (ins->next)) {
4485 emit_cond_system_exception (ctx, bb, (const char*)ins->next->inst_p1, cmp);
4488 builder = ctx->builder;
4490 set_failure (ctx, "next");
4508 rel = mono_opcode_to_cond (ins->opcode);
4510 cmp = LLVMBuildFCmp (builder, fpcond_to_llvm_cond [rel], convert (ctx, lhs, LLVMDoubleType ()), convert (ctx, rhs, LLVMDoubleType ()), "");
4511 values [ins->dreg] = LLVMBuildZExt (builder, cmp, LLVMInt32Type (), dname);
4522 rel = mono_opcode_to_cond (ins->opcode);
4524 cmp = LLVMBuildFCmp (builder, fpcond_to_llvm_cond [rel], convert (ctx, lhs, LLVMFloatType ()), convert (ctx, rhs, LLVMFloatType ()), "");
4525 values [ins->dreg] = LLVMBuildZExt (builder, cmp, LLVMInt32Type (), dname);
4533 gboolean empty = TRUE;
4535 /* Check that all input bblocks really branch to us */
4536 for (i = 0; i < bb->in_count; ++i) {
4537 if (bb->in_bb [i]->last_ins && bb->in_bb [i]->last_ins->opcode == OP_NOT_REACHED)
4538 ins->inst_phi_args [i + 1] = -1;
4544 /* LLVM doesn't like phi instructions with zero operands */
4545 ctx->is_dead [ins->dreg] = TRUE;
4549 /* Created earlier, insert it now */
4550 LLVMInsertIntoBuilder (builder, values [ins->dreg]);
4552 for (i = 0; i < ins->inst_phi_args [0]; i++) {
4553 int sreg1 = ins->inst_phi_args [i + 1];
4557 * Count the number of times the incoming bblock branches to us,
4558 * since llvm requires a separate entry for each.
4560 if (bb->in_bb [i]->last_ins && bb->in_bb [i]->last_ins->opcode == OP_SWITCH) {
4561 MonoInst *switch_ins = bb->in_bb [i]->last_ins;
4564 for (j = 0; j < GPOINTER_TO_UINT (switch_ins->klass); ++j) {
4565 if (switch_ins->inst_many_bb [j] == bb)
4572 /* Remember for later */
4573 for (j = 0; j < count; ++j) {
4574 PhiNode *node = (PhiNode*)mono_mempool_alloc0 (ctx->mempool, sizeof (PhiNode));
4577 node->in_bb = bb->in_bb [i];
4579 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);
4589 values [ins->dreg] = lhs;
4593 MonoInst *var = get_vreg_to_inst (cfg, ins->dreg);
4596 values [ins->dreg] = lhs;
4598 if (var && var->klass->byval_arg.type == MONO_TYPE_R4) {
4600 * This is added by the spilling pass in case of the JIT,
4601 * but we have to do it ourselves.
4603 values [ins->dreg] = convert (ctx, values [ins->dreg], LLVMFloatType ());
4607 case OP_MOVE_F_TO_I4: {
4608 values [ins->dreg] = LLVMBuildBitCast (builder, LLVMBuildFPTrunc (builder, lhs, LLVMFloatType (), ""), LLVMInt32Type (), "");
4611 case OP_MOVE_I4_TO_F: {
4612 values [ins->dreg] = LLVMBuildFPExt (builder, LLVMBuildBitCast (builder, lhs, LLVMFloatType (), ""), LLVMDoubleType (), "");
4615 case OP_MOVE_F_TO_I8: {
4616 values [ins->dreg] = LLVMBuildBitCast (builder, lhs, LLVMInt64Type (), "");
4619 case OP_MOVE_I8_TO_F: {
4620 values [ins->dreg] = LLVMBuildBitCast (builder, lhs, LLVMDoubleType (), "");
4653 lhs = convert (ctx, lhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
4654 rhs = convert (ctx, rhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
4656 emit_div_check (ctx, builder, bb, ins, lhs, rhs);
4659 builder = ctx->builder;
4661 switch (ins->opcode) {
4664 values [ins->dreg] = LLVMBuildAdd (builder, lhs, rhs, dname);
4668 values [ins->dreg] = LLVMBuildSub (builder, lhs, rhs, dname);
4672 values [ins->dreg] = LLVMBuildMul (builder, lhs, rhs, dname);
4676 values [ins->dreg] = LLVMBuildSRem (builder, lhs, rhs, dname);
4680 values [ins->dreg] = LLVMBuildURem (builder, lhs, rhs, dname);
4684 values [ins->dreg] = LLVMBuildSDiv (builder, lhs, rhs, dname);
4688 values [ins->dreg] = LLVMBuildUDiv (builder, lhs, rhs, dname);
4692 values [ins->dreg] = LLVMBuildFDiv (builder, lhs, rhs, dname);
4696 values [ins->dreg] = LLVMBuildAnd (builder, lhs, rhs, dname);
4700 values [ins->dreg] = LLVMBuildOr (builder, lhs, rhs, dname);
4704 values [ins->dreg] = LLVMBuildXor (builder, lhs, rhs, dname);
4708 values [ins->dreg] = LLVMBuildShl (builder, lhs, rhs, dname);
4712 values [ins->dreg] = LLVMBuildAShr (builder, lhs, rhs, dname);
4716 values [ins->dreg] = LLVMBuildLShr (builder, lhs, rhs, dname);
4720 values [ins->dreg] = LLVMBuildFAdd (builder, lhs, rhs, dname);
4723 values [ins->dreg] = LLVMBuildFSub (builder, lhs, rhs, dname);
4726 values [ins->dreg] = LLVMBuildFMul (builder, lhs, rhs, dname);
4730 g_assert_not_reached ();
4737 lhs = convert (ctx, lhs, LLVMFloatType ());
4738 rhs = convert (ctx, rhs, LLVMFloatType ());
4739 switch (ins->opcode) {
4741 values [ins->dreg] = LLVMBuildFAdd (builder, lhs, rhs, dname);
4744 values [ins->dreg] = LLVMBuildFSub (builder, lhs, rhs, dname);
4747 values [ins->dreg] = LLVMBuildFMul (builder, lhs, rhs, dname);
4750 values [ins->dreg] = LLVMBuildFDiv (builder, lhs, rhs, dname);
4753 g_assert_not_reached ();
4762 case OP_IREM_UN_IMM:
4764 case OP_IDIV_UN_IMM:
4770 case OP_ISHR_UN_IMM:
4780 case OP_LSHR_UN_IMM:
4786 case OP_SHR_UN_IMM: {
4789 if (spec [MONO_INST_SRC1] == 'l') {
4790 imm = LLVMConstInt (LLVMInt64Type (), GET_LONG_IMM (ins), FALSE);
4792 imm = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
4795 emit_div_check (ctx, builder, bb, ins, lhs, imm);
4798 builder = ctx->builder;
4800 #if SIZEOF_VOID_P == 4
4801 if (ins->opcode == OP_LSHL_IMM || ins->opcode == OP_LSHR_IMM || ins->opcode == OP_LSHR_UN_IMM)
4802 imm = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
4805 if (LLVMGetTypeKind (LLVMTypeOf (lhs)) == LLVMPointerTypeKind)
4806 lhs = convert (ctx, lhs, IntPtrType ());
4807 imm = convert (ctx, imm, LLVMTypeOf (lhs));
4808 switch (ins->opcode) {
4812 values [ins->dreg] = LLVMBuildAdd (builder, lhs, imm, dname);
4816 values [ins->dreg] = LLVMBuildSub (builder, lhs, imm, dname);
4821 values [ins->dreg] = LLVMBuildMul (builder, lhs, imm, dname);
4825 values [ins->dreg] = LLVMBuildSDiv (builder, lhs, imm, dname);
4827 case OP_IDIV_UN_IMM:
4828 case OP_LDIV_UN_IMM:
4829 values [ins->dreg] = LLVMBuildUDiv (builder, lhs, imm, dname);
4833 values [ins->dreg] = LLVMBuildSRem (builder, lhs, imm, dname);
4835 case OP_IREM_UN_IMM:
4836 values [ins->dreg] = LLVMBuildURem (builder, lhs, imm, dname);
4841 values [ins->dreg] = LLVMBuildAnd (builder, lhs, imm, dname);
4845 values [ins->dreg] = LLVMBuildOr (builder, lhs, imm, dname);
4849 values [ins->dreg] = LLVMBuildXor (builder, lhs, imm, dname);
4854 values [ins->dreg] = LLVMBuildShl (builder, lhs, imm, dname);
4859 values [ins->dreg] = LLVMBuildAShr (builder, lhs, imm, dname);
4861 case OP_ISHR_UN_IMM:
4862 /* This is used to implement conv.u4, so the lhs could be an i8 */
4863 lhs = convert (ctx, lhs, LLVMInt32Type ());
4864 imm = convert (ctx, imm, LLVMInt32Type ());
4865 values [ins->dreg] = LLVMBuildLShr (builder, lhs, imm, dname);
4867 case OP_LSHR_UN_IMM:
4869 values [ins->dreg] = LLVMBuildLShr (builder, lhs, imm, dname);
4872 g_assert_not_reached ();
4877 values [ins->dreg] = LLVMBuildSub (builder, LLVMConstInt (LLVMInt32Type (), 0, FALSE), convert (ctx, lhs, LLVMInt32Type ()), dname);
4880 values [ins->dreg] = LLVMBuildSub (builder, LLVMConstInt (LLVMInt64Type (), 0, FALSE), lhs, dname);
4883 lhs = convert (ctx, lhs, LLVMDoubleType ());
4884 values [ins->dreg] = LLVMBuildFSub (builder, LLVMConstReal (LLVMDoubleType (), 0.0), lhs, dname);
4887 lhs = convert (ctx, lhs, LLVMFloatType ());
4888 values [ins->dreg] = LLVMBuildFSub (builder, LLVMConstReal (LLVMFloatType (), 0.0), lhs, dname);
4891 guint32 v = 0xffffffff;
4892 values [ins->dreg] = LLVMBuildXor (builder, LLVMConstInt (LLVMInt32Type (), v, FALSE), convert (ctx, lhs, LLVMInt32Type ()), dname);
4896 guint64 v = 0xffffffffffffffffLL;
4897 values [ins->dreg] = LLVMBuildXor (builder, LLVMConstInt (LLVMInt64Type (), v, FALSE), lhs, dname);
4900 #if defined(TARGET_X86) || defined(TARGET_AMD64)
4902 LLVMValueRef v1, v2;
4904 v1 = LLVMBuildMul (builder, convert (ctx, rhs, IntPtrType ()), LLVMConstInt (IntPtrType (), (1 << ins->backend.shift_amount), FALSE), "");
4905 v2 = LLVMBuildAdd (builder, convert (ctx, lhs, IntPtrType ()), v1, "");
4906 values [ins->dreg] = LLVMBuildAdd (builder, v2, LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE), dname);
4911 case OP_ICONV_TO_I1:
4912 case OP_ICONV_TO_I2:
4913 case OP_ICONV_TO_I4:
4914 case OP_ICONV_TO_U1:
4915 case OP_ICONV_TO_U2:
4916 case OP_ICONV_TO_U4:
4917 case OP_LCONV_TO_I1:
4918 case OP_LCONV_TO_I2:
4919 case OP_LCONV_TO_U1:
4920 case OP_LCONV_TO_U2:
4921 case OP_LCONV_TO_U4: {
4924 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);
4926 /* Have to do two casts since our vregs have type int */
4927 v = LLVMBuildTrunc (builder, lhs, op_to_llvm_type (ins->opcode), "");
4929 values [ins->dreg] = LLVMBuildSExt (builder, v, LLVMInt32Type (), dname);
4931 values [ins->dreg] = LLVMBuildZExt (builder, v, LLVMInt32Type (), dname);
4934 case OP_ICONV_TO_I8:
4935 values [ins->dreg] = LLVMBuildSExt (builder, lhs, LLVMInt64Type (), dname);
4937 case OP_ICONV_TO_U8:
4938 values [ins->dreg] = LLVMBuildZExt (builder, lhs, LLVMInt64Type (), dname);
4940 case OP_FCONV_TO_I4:
4941 case OP_RCONV_TO_I4:
4942 values [ins->dreg] = LLVMBuildFPToSI (builder, lhs, LLVMInt32Type (), dname);
4944 case OP_FCONV_TO_I1:
4945 case OP_RCONV_TO_I1:
4946 values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildFPToSI (builder, lhs, LLVMInt8Type (), dname), LLVMInt32Type (), "");
4948 case OP_FCONV_TO_U1:
4949 case OP_RCONV_TO_U1:
4950 values [ins->dreg] = LLVMBuildZExt (builder, LLVMBuildTrunc (builder, LLVMBuildFPToUI (builder, lhs, IntPtrType (), dname), LLVMInt8Type (), ""), LLVMInt32Type (), "");
4952 case OP_FCONV_TO_I2:
4953 case OP_RCONV_TO_I2:
4954 values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildFPToSI (builder, lhs, LLVMInt16Type (), dname), LLVMInt32Type (), "");
4956 case OP_FCONV_TO_U2:
4957 case OP_RCONV_TO_U2:
4958 values [ins->dreg] = LLVMBuildZExt (builder, LLVMBuildFPToUI (builder, lhs, LLVMInt16Type (), dname), LLVMInt32Type (), "");
4960 case OP_RCONV_TO_U4:
4961 values [ins->dreg] = LLVMBuildFPToUI (builder, lhs, LLVMInt32Type (), dname);
4963 case OP_FCONV_TO_I8:
4964 case OP_RCONV_TO_I8:
4965 values [ins->dreg] = LLVMBuildFPToSI (builder, lhs, LLVMInt64Type (), dname);
4968 values [ins->dreg] = LLVMBuildFPToSI (builder, lhs, IntPtrType (), dname);
4970 case OP_ICONV_TO_R8:
4971 case OP_LCONV_TO_R8:
4972 values [ins->dreg] = LLVMBuildSIToFP (builder, lhs, LLVMDoubleType (), dname);
4974 case OP_ICONV_TO_R_UN:
4975 case OP_LCONV_TO_R_UN:
4976 values [ins->dreg] = LLVMBuildUIToFP (builder, lhs, LLVMDoubleType (), dname);
4978 #if SIZEOF_VOID_P == 4
4981 case OP_LCONV_TO_I4:
4982 values [ins->dreg] = LLVMBuildTrunc (builder, lhs, LLVMInt32Type (), dname);
4984 case OP_ICONV_TO_R4:
4985 case OP_LCONV_TO_R4:
4986 v = LLVMBuildSIToFP (builder, lhs, LLVMFloatType (), "");
4988 values [ins->dreg] = v;
4990 values [ins->dreg] = LLVMBuildFPExt (builder, v, LLVMDoubleType (), dname);
4992 case OP_FCONV_TO_R4:
4993 v = LLVMBuildFPTrunc (builder, lhs, LLVMFloatType (), "");
4995 values [ins->dreg] = v;
4997 values [ins->dreg] = LLVMBuildFPExt (builder, v, LLVMDoubleType (), dname);
4999 case OP_RCONV_TO_R8:
5000 values [ins->dreg] = LLVMBuildFPExt (builder, lhs, LLVMDoubleType (), dname);
5002 case OP_RCONV_TO_R4:
5003 values [ins->dreg] = lhs;
5006 values [ins->dreg] = LLVMBuildSExt (builder, convert (ctx, lhs, LLVMInt32Type ()), LLVMInt64Type (), dname);
5009 values [ins->dreg] = LLVMBuildZExt (builder, convert (ctx, lhs, LLVMInt32Type ()), LLVMInt64Type (), dname);
5012 values [ins->dreg] = LLVMBuildTrunc (builder, lhs, LLVMInt32Type (), dname);
5014 case OP_LOCALLOC_IMM: {
5017 guint32 size = ins->inst_imm;
5018 size = (size + (MONO_ARCH_FRAME_ALIGNMENT - 1)) & ~ (MONO_ARCH_FRAME_ALIGNMENT - 1);
5020 v = mono_llvm_build_alloca (builder, LLVMInt8Type (), LLVMConstInt (LLVMInt32Type (), size, FALSE), MONO_ARCH_FRAME_ALIGNMENT, "");
5022 if (ins->flags & MONO_INST_INIT) {
5023 LLVMValueRef args [5];
5026 args [1] = LLVMConstInt (LLVMInt8Type (), 0, FALSE);
5027 args [2] = LLVMConstInt (LLVMInt32Type (), size, FALSE);
5028 args [3] = LLVMConstInt (LLVMInt32Type (), MONO_ARCH_FRAME_ALIGNMENT, FALSE);
5029 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
5030 LLVMBuildCall (builder, get_intrinsic (ctx, "llvm.memset.p0i8.i32"), args, 5, "");
5033 values [ins->dreg] = v;
5037 LLVMValueRef v, size;
5039 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), "");
5041 v = mono_llvm_build_alloca (builder, LLVMInt8Type (), size, MONO_ARCH_FRAME_ALIGNMENT, "");
5043 if (ins->flags & MONO_INST_INIT) {
5044 LLVMValueRef args [5];
5047 args [1] = LLVMConstInt (LLVMInt8Type (), 0, FALSE);
5049 args [3] = LLVMConstInt (LLVMInt32Type (), MONO_ARCH_FRAME_ALIGNMENT, FALSE);
5050 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
5051 LLVMBuildCall (builder, get_intrinsic (ctx, "llvm.memset.p0i8.i32"), args, 5, "");
5053 values [ins->dreg] = v;
5057 case OP_LOADI1_MEMBASE:
5058 case OP_LOADU1_MEMBASE:
5059 case OP_LOADI2_MEMBASE:
5060 case OP_LOADU2_MEMBASE:
5061 case OP_LOADI4_MEMBASE:
5062 case OP_LOADU4_MEMBASE:
5063 case OP_LOADI8_MEMBASE:
5064 case OP_LOADR4_MEMBASE:
5065 case OP_LOADR8_MEMBASE:
5066 case OP_LOAD_MEMBASE:
5074 LLVMValueRef base, index, addr;
5076 gboolean sext = FALSE, zext = FALSE;
5077 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
5079 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
5084 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)) {
5085 addr = LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE);
5090 if (ins->inst_offset == 0) {
5092 } else if (ins->inst_offset % size != 0) {
5093 /* Unaligned load */
5094 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset, FALSE);
5095 addr = LLVMBuildGEP (builder, convert (ctx, base, LLVMPointerType (LLVMInt8Type (), 0)), &index, 1, "");
5097 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
5098 addr = LLVMBuildGEP (builder, convert (ctx, base, LLVMPointerType (t, 0)), &index, 1, "");
5102 addr = convert (ctx, addr, LLVMPointerType (t, 0));
5104 values [ins->dreg] = emit_load (ctx, bb, &builder, size, addr, dname, is_volatile);
5106 if (!is_volatile && (ins->flags & MONO_INST_INVARIANT_LOAD)) {
5108 * These will signal LLVM that these loads do not alias any stores, and
5109 * they can't fail, allowing them to be hoisted out of loops.
5111 set_invariant_load_flag (values [ins->dreg]);
5112 #if LLVM_API_VERSION < 100
5113 set_metadata_flag (values [ins->dreg], "mono.nofail.load");
5118 values [ins->dreg] = LLVMBuildSExt (builder, values [ins->dreg], LLVMInt32Type (), dname);
5120 values [ins->dreg] = LLVMBuildZExt (builder, values [ins->dreg], LLVMInt32Type (), dname);
5121 else if (!cfg->r4fp && ins->opcode == OP_LOADR4_MEMBASE)
5122 values [ins->dreg] = LLVMBuildFPExt (builder, values [ins->dreg], LLVMDoubleType (), dname);
5126 case OP_STOREI1_MEMBASE_REG:
5127 case OP_STOREI2_MEMBASE_REG:
5128 case OP_STOREI4_MEMBASE_REG:
5129 case OP_STOREI8_MEMBASE_REG:
5130 case OP_STORER4_MEMBASE_REG:
5131 case OP_STORER8_MEMBASE_REG:
5132 case OP_STORE_MEMBASE_REG: {
5134 LLVMValueRef index, addr;
5136 gboolean sext = FALSE, zext = FALSE;
5137 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
5139 if (!values [ins->inst_destbasereg]) {
5140 set_failure (ctx, "inst_destbasereg");
5144 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
5146 if (ins->inst_offset % size != 0) {
5147 /* Unaligned store */
5148 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset, FALSE);
5149 addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (LLVMInt8Type (), 0)), &index, 1, "");
5151 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
5152 addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (t, 0)), &index, 1, "");
5154 emit_store (ctx, bb, &builder, size, convert (ctx, values [ins->sreg1], t), convert (ctx, addr, LLVMPointerType (t, 0)), is_volatile);
5158 case OP_STOREI1_MEMBASE_IMM:
5159 case OP_STOREI2_MEMBASE_IMM:
5160 case OP_STOREI4_MEMBASE_IMM:
5161 case OP_STOREI8_MEMBASE_IMM:
5162 case OP_STORE_MEMBASE_IMM: {
5164 LLVMValueRef index, addr;
5166 gboolean sext = FALSE, zext = FALSE;
5167 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
5169 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
5171 if (ins->inst_offset % size != 0) {
5172 /* Unaligned store */
5173 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset, FALSE);
5174 addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (LLVMInt8Type (), 0)), &index, 1, "");
5176 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
5177 addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (t, 0)), &index, 1, "");
5179 emit_store (ctx, bb, &builder, size, convert (ctx, LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE), t), convert (ctx, addr, LLVMPointerType (t, 0)), is_volatile);
5184 emit_load (ctx, bb, &builder, sizeof (gpointer), convert (ctx, lhs, LLVMPointerType (IntPtrType (), 0)), "", TRUE);
5186 case OP_OUTARG_VTRETADDR:
5194 case OP_VOIDCALL_MEMBASE:
5195 case OP_CALL_MEMBASE:
5196 case OP_LCALL_MEMBASE:
5197 case OP_FCALL_MEMBASE:
5198 case OP_RCALL_MEMBASE:
5199 case OP_VCALL_MEMBASE:
5200 case OP_VOIDCALL_REG:
5205 case OP_VCALL_REG: {
5206 process_call (ctx, bb, &builder, ins);
5211 LLVMValueRef indexes [2];
5212 MonoJumpInfo *tmp_ji, *ji;
5213 LLVMValueRef got_entry_addr;
5217 * FIXME: Can't allocate from the cfg mempool since that is freed if
5218 * the LLVM compile fails.
5220 tmp_ji = g_new0 (MonoJumpInfo, 1);
5221 tmp_ji->type = (MonoJumpInfoType)ins->inst_c1;
5222 tmp_ji->data.target = ins->inst_p0;
5224 ji = mono_aot_patch_info_dup (tmp_ji);
5227 ji->next = cfg->patch_info;
5228 cfg->patch_info = ji;
5230 //mono_add_patch_info (cfg, 0, (MonoJumpInfoType)ins->inst_i1, ins->inst_p0);
5231 got_offset = mono_aot_get_got_offset (cfg->patch_info);
5232 ctx->module->max_got_offset = MAX (ctx->module->max_got_offset, got_offset);
5233 if (!mono_aot_is_shared_got_offset (got_offset)) {
5234 //mono_print_ji (ji);
5236 ctx->has_got_access = TRUE;
5239 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
5240 indexes [1] = LLVMConstInt (LLVMInt32Type (), (gssize)got_offset, FALSE);
5241 got_entry_addr = LLVMBuildGEP (builder, ctx->module->got_var, indexes, 2, "");
5243 name = get_aotconst_name (ji->type, ji->data.target, got_offset);
5244 values [ins->dreg] = LLVMBuildLoad (builder, got_entry_addr, name);
5246 /* Can't use this in llvmonly mode since the got slots are initialized by the methods themselves */
5247 if (!cfg->llvm_only)
5248 set_invariant_load_flag (values [ins->dreg]);
5251 case OP_NOT_REACHED:
5252 LLVMBuildUnreachable (builder);
5253 has_terminator = TRUE;
5254 g_assert (bb->block_num < cfg->max_block_num);
5255 ctx->unreachable [bb->block_num] = TRUE;
5256 /* Might have instructions after this */
5258 MonoInst *next = ins->next;
5260 * FIXME: If later code uses the regs defined by these instructions,
5261 * compilation will fail.
5263 MONO_DELETE_INS (bb, next);
5267 MonoInst *var = ins->inst_i0;
5269 if (var->opcode == OP_VTARG_ADDR) {
5270 /* The variable contains the vtype address */
5271 values [ins->dreg] = values [var->dreg];
5272 } else if (var->opcode == OP_GSHAREDVT_LOCAL) {
5273 values [ins->dreg] = emit_gsharedvt_ldaddr (ctx, var->dreg);
5275 values [ins->dreg] = addresses [var->dreg];
5280 LLVMValueRef args [1];
5282 args [0] = convert (ctx, lhs, LLVMDoubleType ());
5283 values [ins->dreg] = LLVMBuildCall (builder, get_intrinsic (ctx, "llvm.sin.f64"), args, 1, dname);
5287 LLVMValueRef args [1];
5289 args [0] = convert (ctx, lhs, LLVMDoubleType ());
5290 values [ins->dreg] = LLVMBuildCall (builder, get_intrinsic (ctx, "llvm.cos.f64"), args, 1, dname);
5294 LLVMValueRef args [1];
5296 args [0] = convert (ctx, lhs, LLVMDoubleType ());
5297 values [ins->dreg] = LLVMBuildCall (builder, get_intrinsic (ctx, "llvm.sqrt.f64"), args, 1, dname);
5301 LLVMValueRef args [1];
5303 args [0] = convert (ctx, lhs, LLVMDoubleType ());
5304 values [ins->dreg] = LLVMBuildCall (builder, get_intrinsic (ctx, "fabs"), args, 1, dname);
5318 lhs = convert (ctx, lhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
5319 rhs = convert (ctx, rhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
5321 switch (ins->opcode) {
5324 v = LLVMBuildICmp (builder, LLVMIntSLE, lhs, rhs, "");
5328 v = LLVMBuildICmp (builder, LLVMIntSGE, lhs, rhs, "");
5332 v = LLVMBuildICmp (builder, LLVMIntULE, lhs, rhs, "");
5336 v = LLVMBuildICmp (builder, LLVMIntUGE, lhs, rhs, "");
5339 g_assert_not_reached ();
5342 values [ins->dreg] = LLVMBuildSelect (builder, v, lhs, rhs, dname);
5345 case OP_ATOMIC_EXCHANGE_I4:
5346 case OP_ATOMIC_EXCHANGE_I8: {
5347 LLVMValueRef args [2];
5350 if (ins->opcode == OP_ATOMIC_EXCHANGE_I4)
5351 t = LLVMInt32Type ();
5353 t = LLVMInt64Type ();
5355 g_assert (ins->inst_offset == 0);
5357 args [0] = convert (ctx, lhs, LLVMPointerType (t, 0));
5358 args [1] = convert (ctx, rhs, t);
5360 values [ins->dreg] = mono_llvm_build_atomic_rmw (builder, LLVM_ATOMICRMW_OP_XCHG, args [0], args [1]);
5363 case OP_ATOMIC_ADD_I4:
5364 case OP_ATOMIC_ADD_I8: {
5365 LLVMValueRef args [2];
5368 if (ins->opcode == OP_ATOMIC_ADD_I4)
5369 t = LLVMInt32Type ();
5371 t = LLVMInt64Type ();
5373 g_assert (ins->inst_offset == 0);
5375 args [0] = convert (ctx, lhs, LLVMPointerType (t, 0));
5376 args [1] = convert (ctx, rhs, t);
5377 values [ins->dreg] = LLVMBuildAdd (builder, mono_llvm_build_atomic_rmw (builder, LLVM_ATOMICRMW_OP_ADD, args [0], args [1]), args [1], dname);
5380 case OP_ATOMIC_CAS_I4:
5381 case OP_ATOMIC_CAS_I8: {
5382 LLVMValueRef args [3], val;
5385 if (ins->opcode == OP_ATOMIC_CAS_I4)
5386 t = LLVMInt32Type ();
5388 t = LLVMInt64Type ();
5390 args [0] = convert (ctx, lhs, LLVMPointerType (t, 0));
5392 args [1] = convert (ctx, values [ins->sreg3], t);
5394 args [2] = convert (ctx, values [ins->sreg2], t);
5395 val = mono_llvm_build_cmpxchg (builder, args [0], args [1], args [2]);
5396 /* cmpxchg returns a pair */
5397 values [ins->dreg] = LLVMBuildExtractValue (builder, val, 0, "");
5400 case OP_MEMORY_BARRIER: {
5401 mono_llvm_build_fence (builder, (BarrierKind) ins->backend.memory_barrier_kind);
5404 case OP_ATOMIC_LOAD_I1:
5405 case OP_ATOMIC_LOAD_I2:
5406 case OP_ATOMIC_LOAD_I4:
5407 case OP_ATOMIC_LOAD_I8:
5408 case OP_ATOMIC_LOAD_U1:
5409 case OP_ATOMIC_LOAD_U2:
5410 case OP_ATOMIC_LOAD_U4:
5411 case OP_ATOMIC_LOAD_U8:
5412 case OP_ATOMIC_LOAD_R4:
5413 case OP_ATOMIC_LOAD_R8: {
5414 set_failure (ctx, "atomic mono.load intrinsic");
5418 gboolean sext, zext;
5420 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
5421 BarrierKind barrier = (BarrierKind) ins->backend.memory_barrier_kind;
5422 LLVMValueRef index, addr;
5424 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
5429 if (ins->inst_offset != 0) {
5430 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
5431 addr = LLVMBuildGEP (builder, convert (ctx, lhs, LLVMPointerType (t, 0)), &index, 1, "");
5436 addr = convert (ctx, addr, LLVMPointerType (t, 0));
5438 values [ins->dreg] = emit_load_general (ctx, bb, &builder, size, addr, dname, is_volatile, barrier);
5441 values [ins->dreg] = LLVMBuildSExt (builder, values [ins->dreg], LLVMInt32Type (), dname);
5443 values [ins->dreg] = LLVMBuildZExt (builder, values [ins->dreg], LLVMInt32Type (), dname);
5447 case OP_ATOMIC_STORE_I1:
5448 case OP_ATOMIC_STORE_I2:
5449 case OP_ATOMIC_STORE_I4:
5450 case OP_ATOMIC_STORE_I8:
5451 case OP_ATOMIC_STORE_U1:
5452 case OP_ATOMIC_STORE_U2:
5453 case OP_ATOMIC_STORE_U4:
5454 case OP_ATOMIC_STORE_U8:
5455 case OP_ATOMIC_STORE_R4:
5456 case OP_ATOMIC_STORE_R8: {
5457 set_failure (ctx, "atomic mono.store intrinsic");
5461 gboolean sext, zext;
5463 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
5464 BarrierKind barrier = (BarrierKind) ins->backend.memory_barrier_kind;
5465 LLVMValueRef index, addr, value;
5467 if (!values [ins->inst_destbasereg]) {
5468 set_failure (ctx, "inst_destbasereg");
5472 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
5474 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
5475 addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (t, 0)), &index, 1, "");
5476 value = convert (ctx, values [ins->sreg1], t);
5478 emit_store_general (ctx, bb, &builder, size, value, addr, is_volatile, barrier);
5482 case OP_RELAXED_NOP: {
5483 #if defined(TARGET_AMD64) || defined(TARGET_X86)
5484 emit_call (ctx, bb, &builder, get_intrinsic (ctx, "llvm.x86.sse2.pause"), NULL, 0);
5491 #if (defined(TARGET_AMD64) || defined(TARGET_X86)) && defined(__linux__)
5493 // 257 == FS segment register
5494 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 257);
5496 // 256 == GS segment register
5497 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 256);
5500 values [ins->dreg] = LLVMBuildLoad (builder, LLVMBuildIntToPtr (builder, LLVMConstInt (IntPtrType (), ins->inst_offset, TRUE), ptrtype, ""), "");
5501 #elif defined(TARGET_AMD64) && defined(TARGET_OSX)
5502 /* See mono_amd64_emit_tls_get () */
5503 int offset = mono_amd64_get_tls_gs_offset () + (ins->inst_offset * 8);
5505 // 256 == GS segment register
5506 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 256);
5507 values [ins->dreg] = LLVMBuildLoad (builder, LLVMBuildIntToPtr (builder, LLVMConstInt (IntPtrType (), offset, TRUE), ptrtype, ""), "");
5509 set_failure (ctx, "opcode tls-get");
5515 case OP_TLS_GET_REG: {
5516 #if defined(TARGET_AMD64) && defined(TARGET_OSX)
5517 /* See emit_tls_get_reg () */
5518 // 256 == GS segment register
5519 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 256);
5520 values [ins->dreg] = LLVMBuildLoad (builder, LLVMBuildIntToPtr (builder, convert (ctx, lhs, LLVMInt32Type ()), ptrtype, ""), "");
5522 set_failure (ctx, "opcode tls-get");
5528 case OP_TLS_SET_REG: {
5529 #if defined(TARGET_AMD64) && defined(TARGET_OSX)
5530 /* See emit_tls_get_reg () */
5531 // 256 == GS segment register
5532 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 256);
5533 LLVMBuildStore (builder, convert (ctx, lhs, IntPtrType ()), LLVMBuildIntToPtr (builder, convert (ctx, rhs, LLVMInt32Type ()), ptrtype, ""));
5535 set_failure (ctx, "opcode tls-set-reg");
5540 case OP_GC_SAFE_POINT: {
5541 LLVMValueRef val, cmp, callee;
5542 LLVMBasicBlockRef poll_bb, cont_bb;
5543 static LLVMTypeRef sig;
5544 const char *icall_name = "mono_threads_state_poll";
5547 sig = LLVMFunctionType0 (LLVMVoidType (), FALSE);
5551 * mono_threads_state_poll ();
5552 * FIXME: Use a preserveall wrapper
5554 val = mono_llvm_build_load (builder, convert (ctx, lhs, LLVMPointerType (IntPtrType (), 0)), "", TRUE, LLVM_BARRIER_NONE);
5555 cmp = LLVMBuildICmp (builder, LLVMIntEQ, val, LLVMConstNull (LLVMTypeOf (val)), "");
5556 poll_bb = gen_bb (ctx, "POLL_BB");
5557 cont_bb = gen_bb (ctx, "CONT_BB");
5558 LLVMBuildCondBr (builder, cmp, cont_bb, poll_bb);
5560 ctx->builder = builder = create_builder (ctx);
5561 LLVMPositionBuilderAtEnd (builder, poll_bb);
5563 if (ctx->cfg->compile_aot) {
5564 callee = get_callee (ctx, sig, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
5566 gpointer target = resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
5567 callee = emit_jit_callee (ctx, icall_name, sig, target);
5569 LLVMBuildCall (builder, callee, NULL, 0, "");
5570 LLVMBuildBr (builder, cont_bb);
5572 ctx->builder = builder = create_builder (ctx);
5573 LLVMPositionBuilderAtEnd (builder, cont_bb);
5574 ctx->bblocks [bb->block_num].end_bblock = cont_bb;
5582 case OP_IADD_OVF_UN:
5584 case OP_ISUB_OVF_UN:
5586 case OP_IMUL_OVF_UN:
5588 case OP_LADD_OVF_UN:
5590 case OP_LSUB_OVF_UN:
5592 case OP_LMUL_OVF_UN:
5594 LLVMValueRef args [2], val, ovf, func;
5596 args [0] = convert (ctx, lhs, op_to_llvm_type (ins->opcode));
5597 args [1] = convert (ctx, rhs, op_to_llvm_type (ins->opcode));
5598 func = get_intrinsic (ctx, ovf_op_to_intrins (ins->opcode));
5600 val = LLVMBuildCall (builder, func, args, 2, "");
5601 values [ins->dreg] = LLVMBuildExtractValue (builder, val, 0, dname);
5602 ovf = LLVMBuildExtractValue (builder, val, 1, "");
5603 emit_cond_system_exception (ctx, bb, "OverflowException", ovf);
5606 builder = ctx->builder;
5612 * We currently model them using arrays. Promotion to local vregs is
5613 * disabled for them in mono_handle_global_vregs () in the LLVM case,
5614 * so we always have an entry in cfg->varinfo for them.
5615 * FIXME: Is this needed ?
5618 MonoClass *klass = ins->klass;
5619 LLVMValueRef args [5];
5623 set_failure (ctx, "!klass");
5627 if (!addresses [ins->dreg])
5628 addresses [ins->dreg] = build_alloca (ctx, &klass->byval_arg);
5629 args [0] = LLVMBuildBitCast (builder, addresses [ins->dreg], LLVMPointerType (LLVMInt8Type (), 0), "");
5630 args [1] = LLVMConstInt (LLVMInt8Type (), 0, FALSE);
5631 args [2] = LLVMConstInt (LLVMInt32Type (), mono_class_value_size (klass, NULL), FALSE);
5633 args [3] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
5634 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
5635 LLVMBuildCall (builder, get_intrinsic (ctx, "llvm.memset.p0i8.i32"), args, 5, "");
5638 case OP_DUMMY_VZERO:
5641 case OP_STOREV_MEMBASE:
5642 case OP_LOADV_MEMBASE:
5644 MonoClass *klass = ins->klass;
5645 LLVMValueRef src = NULL, dst, args [5];
5646 gboolean done = FALSE;
5650 set_failure (ctx, "!klass");
5654 if (mini_is_gsharedvt_klass (klass)) {
5656 set_failure (ctx, "gsharedvt");
5660 switch (ins->opcode) {
5661 case OP_STOREV_MEMBASE:
5662 if (cfg->gen_write_barriers && klass->has_references && ins->inst_destbasereg != cfg->frame_reg &&
5663 LLVMGetInstructionOpcode (values [ins->inst_destbasereg]) != LLVMAlloca) {
5664 /* Decomposed earlier */
5665 g_assert_not_reached ();
5668 if (!addresses [ins->sreg1]) {
5670 g_assert (values [ins->sreg1]);
5671 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));
5672 LLVMBuildStore (builder, values [ins->sreg1], dst);
5675 src = LLVMBuildBitCast (builder, addresses [ins->sreg1], LLVMPointerType (LLVMInt8Type (), 0), "");
5676 dst = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_destbasereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (LLVMInt8Type (), 0));
5679 case OP_LOADV_MEMBASE:
5680 if (!addresses [ins->dreg])
5681 addresses [ins->dreg] = build_alloca (ctx, &klass->byval_arg);
5682 src = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_basereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (LLVMInt8Type (), 0));
5683 dst = LLVMBuildBitCast (builder, addresses [ins->dreg], LLVMPointerType (LLVMInt8Type (), 0), "");
5686 if (!addresses [ins->sreg1])
5687 addresses [ins->sreg1] = build_alloca (ctx, &klass->byval_arg);
5688 if (!addresses [ins->dreg])
5689 addresses [ins->dreg] = build_alloca (ctx, &klass->byval_arg);
5690 src = LLVMBuildBitCast (builder, addresses [ins->sreg1], LLVMPointerType (LLVMInt8Type (), 0), "");
5691 dst = LLVMBuildBitCast (builder, addresses [ins->dreg], LLVMPointerType (LLVMInt8Type (), 0), "");
5694 g_assert_not_reached ();
5704 args [2] = LLVMConstInt (LLVMInt32Type (), mono_class_value_size (klass, NULL), FALSE);
5705 args [3] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
5707 args [3] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
5708 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
5709 LLVMBuildCall (builder, get_intrinsic (ctx, "llvm.memcpy.p0i8.p0i8.i32"), args, 5, "");
5712 case OP_LLVM_OUTARG_VT: {
5713 LLVMArgInfo *ainfo = (LLVMArgInfo*)ins->inst_p0;
5714 MonoType *t = mini_get_underlying_type (ins->inst_vtype);
5716 if (ainfo->storage == LLVMArgGsharedvtVariable) {
5717 MonoInst *var = get_vreg_to_inst (cfg, ins->sreg1);
5719 if (var && var->opcode == OP_GSHAREDVT_LOCAL) {
5720 addresses [ins->dreg] = convert (ctx, emit_gsharedvt_ldaddr (ctx, var->dreg), LLVMPointerType (IntPtrType (), 0));
5722 g_assert (addresses [ins->sreg1]);
5723 addresses [ins->dreg] = addresses [ins->sreg1];
5725 } else if (ainfo->storage == LLVMArgGsharedvtFixed) {
5726 if (!addresses [ins->sreg1]) {
5727 addresses [ins->sreg1] = build_alloca (ctx, t);
5728 g_assert (values [ins->sreg1]);
5730 LLVMBuildStore (builder, convert (ctx, values [ins->sreg1], LLVMGetElementType (LLVMTypeOf (addresses [ins->sreg1]))), addresses [ins->sreg1]);
5731 addresses [ins->dreg] = addresses [ins->sreg1];
5733 if (!addresses [ins->sreg1]) {
5734 addresses [ins->sreg1] = build_alloca (ctx, t);
5735 g_assert (values [ins->sreg1]);
5736 LLVMBuildStore (builder, convert (ctx, values [ins->sreg1], type_to_llvm_type (ctx, t)), addresses [ins->sreg1]);
5738 addresses [ins->dreg] = addresses [ins->sreg1];
5746 #if defined(TARGET_X86) || defined(TARGET_AMD64)
5748 values [ins->dreg] = LLVMConstNull (type_to_llvm_type (ctx, &ins->klass->byval_arg));
5751 case OP_LOADX_MEMBASE: {
5752 LLVMTypeRef t = type_to_llvm_type (ctx, &ins->klass->byval_arg);
5755 src = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_basereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (t, 0));
5756 values [ins->dreg] = mono_llvm_build_aligned_load (builder, src, "", FALSE, 1);
5759 case OP_STOREX_MEMBASE: {
5760 LLVMTypeRef t = LLVMTypeOf (values [ins->sreg1]);
5763 dest = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_destbasereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (t, 0));
5764 mono_llvm_build_aligned_store (builder, values [ins->sreg1], dest, FALSE, 1);
5771 values [ins->dreg] = LLVMBuildAdd (builder, lhs, rhs, "");
5775 values [ins->dreg] = LLVMBuildFAdd (builder, lhs, rhs, "");
5781 values [ins->dreg] = LLVMBuildSub (builder, lhs, rhs, "");
5785 values [ins->dreg] = LLVMBuildFSub (builder, lhs, rhs, "");
5789 values [ins->dreg] = LLVMBuildFMul (builder, lhs, rhs, "");
5793 values [ins->dreg] = LLVMBuildFDiv (builder, lhs, rhs, "");
5796 values [ins->dreg] = LLVMBuildAnd (builder, lhs, rhs, "");
5799 values [ins->dreg] = LLVMBuildOr (builder, lhs, rhs, "");
5802 values [ins->dreg] = LLVMBuildXor (builder, lhs, rhs, "");
5806 values [ins->dreg] = LLVMBuildMul (builder, lhs, rhs, "");
5817 LLVMValueRef v = NULL;
5819 switch (ins->opcode) {
5824 t = LLVMVectorType (LLVMInt32Type (), 4);
5825 rt = LLVMVectorType (LLVMFloatType (), 4);
5831 t = LLVMVectorType (LLVMInt64Type (), 2);
5832 rt = LLVMVectorType (LLVMDoubleType (), 2);
5835 t = LLVMInt32Type ();
5836 rt = LLVMInt32Type ();
5837 g_assert_not_reached ();
5840 lhs = LLVMBuildBitCast (builder, lhs, t, "");
5841 rhs = LLVMBuildBitCast (builder, rhs, t, "");
5842 switch (ins->opcode) {
5845 v = LLVMBuildAnd (builder, lhs, rhs, "");
5849 v = LLVMBuildOr (builder, lhs, rhs, "");
5853 v = LLVMBuildXor (builder, lhs, rhs, "");
5857 v = LLVMBuildAnd (builder, rhs, LLVMBuildNot (builder, lhs, ""), "");
5860 values [ins->dreg] = LLVMBuildBitCast (builder, v, rt, "");
5884 case OP_PADDB_SAT_UN:
5885 case OP_PADDW_SAT_UN:
5886 case OP_PSUBB_SAT_UN:
5887 case OP_PSUBW_SAT_UN:
5895 case OP_PMULW_HIGH_UN: {
5896 LLVMValueRef args [2];
5901 values [ins->dreg] = LLVMBuildCall (builder, get_intrinsic (ctx, simd_op_to_intrins (ins->opcode)), args, 2, dname);
5908 values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildICmp (builder, LLVMIntEQ, lhs, rhs, ""), LLVMTypeOf (lhs), "");
5912 values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildICmp (builder, LLVMIntSGT, lhs, rhs, ""), LLVMTypeOf (lhs), "");
5920 case OP_EXTRACTX_U2:
5922 case OP_EXTRACT_U1: {
5924 gboolean zext = FALSE;
5926 t = simd_op_to_llvm_type (ins->opcode);
5928 switch (ins->opcode) {
5936 case OP_EXTRACTX_U2:
5941 t = LLVMInt32Type ();
5942 g_assert_not_reached ();
5945 lhs = LLVMBuildBitCast (builder, lhs, t, "");
5946 values [ins->dreg] = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), "");
5948 values [ins->dreg] = LLVMBuildZExt (builder, values [ins->dreg], LLVMInt32Type (), "");
5957 case OP_EXPAND_R8: {
5958 LLVMTypeRef t = simd_op_to_llvm_type (ins->opcode);
5959 LLVMValueRef mask [16], v;
5962 for (i = 0; i < 16; ++i)
5963 mask [i] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
5965 v = convert (ctx, values [ins->sreg1], LLVMGetElementType (t));
5967 values [ins->dreg] = LLVMBuildInsertElement (builder, LLVMConstNull (t), v, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
5968 values [ins->dreg] = LLVMBuildShuffleVector (builder, values [ins->dreg], LLVMGetUndef (t), LLVMConstVector (mask, LLVMGetVectorSize (t)), "");
5973 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt8Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
5976 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt16Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
5979 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt32Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
5982 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt64Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
5985 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMFloatType ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
5988 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMDoubleType ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
5999 case OP_EXTRACT_MASK:
6006 v = convert (ctx, values [ins->sreg1], simd_op_to_llvm_type (ins->opcode));
6008 values [ins->dreg] = LLVMBuildCall (builder, get_intrinsic (ctx, simd_op_to_intrins (ins->opcode)), &v, 1, dname);
6014 LLVMValueRef args [3];
6018 args [2] = LLVMConstInt (LLVMInt8Type (), ins->inst_c0, FALSE);
6020 values [ins->dreg] = LLVMBuildCall (builder, get_intrinsic (ctx, simd_op_to_intrins (ins->opcode)), args, 3, dname);
6025 /* This is only used for implementing shifts by non-immediate */
6026 values [ins->dreg] = lhs;
6037 LLVMValueRef args [3];
6040 args [1] = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
6042 values [ins->dreg] = LLVMBuildCall (builder, get_intrinsic (ctx, simd_op_to_intrins (ins->opcode)), args, 2, dname);
6053 case OP_PSHLQ_REG: {
6054 LLVMValueRef args [3];
6057 args [1] = values [ins->sreg2];
6059 values [ins->dreg] = LLVMBuildCall (builder, get_intrinsic (ctx, simd_op_to_intrins (ins->opcode)), args, 2, dname);
6066 case OP_PSHUFLEW_LOW:
6067 case OP_PSHUFLEW_HIGH: {
6069 LLVMValueRef v1 = NULL, v2 = NULL, mask_values [16];
6070 int i, mask_size = 0;
6071 int imask = ins->inst_c0;
6073 /* Convert the x86 shuffle mask to LLVM's */
6074 switch (ins->opcode) {
6077 mask [0] = ((imask >> 0) & 3);
6078 mask [1] = ((imask >> 2) & 3);
6079 mask [2] = ((imask >> 4) & 3) + 4;
6080 mask [3] = ((imask >> 6) & 3) + 4;
6081 v1 = values [ins->sreg1];
6082 v2 = values [ins->sreg2];
6086 mask [0] = ((imask >> 0) & 1);
6087 mask [1] = ((imask >> 1) & 1) + 2;
6088 v1 = values [ins->sreg1];
6089 v2 = values [ins->sreg2];
6091 case OP_PSHUFLEW_LOW:
6093 mask [0] = ((imask >> 0) & 3);
6094 mask [1] = ((imask >> 2) & 3);
6095 mask [2] = ((imask >> 4) & 3);
6096 mask [3] = ((imask >> 6) & 3);
6101 v1 = values [ins->sreg1];
6102 v2 = LLVMGetUndef (LLVMTypeOf (v1));
6104 case OP_PSHUFLEW_HIGH:
6110 mask [4] = 4 + ((imask >> 0) & 3);
6111 mask [5] = 4 + ((imask >> 2) & 3);
6112 mask [6] = 4 + ((imask >> 4) & 3);
6113 mask [7] = 4 + ((imask >> 6) & 3);
6114 v1 = values [ins->sreg1];
6115 v2 = LLVMGetUndef (LLVMTypeOf (v1));
6119 mask [0] = ((imask >> 0) & 3);
6120 mask [1] = ((imask >> 2) & 3);
6121 mask [2] = ((imask >> 4) & 3);
6122 mask [3] = ((imask >> 6) & 3);
6123 v1 = values [ins->sreg1];
6124 v2 = LLVMGetUndef (LLVMTypeOf (v1));
6127 g_assert_not_reached ();
6129 for (i = 0; i < mask_size; ++i)
6130 mask_values [i] = LLVMConstInt (LLVMInt32Type (), mask [i], FALSE);
6132 values [ins->dreg] =
6133 LLVMBuildShuffleVector (builder, v1, v2,
6134 LLVMConstVector (mask_values, mask_size), dname);
6138 case OP_UNPACK_LOWB:
6139 case OP_UNPACK_LOWW:
6140 case OP_UNPACK_LOWD:
6141 case OP_UNPACK_LOWQ:
6142 case OP_UNPACK_LOWPS:
6143 case OP_UNPACK_LOWPD:
6144 case OP_UNPACK_HIGHB:
6145 case OP_UNPACK_HIGHW:
6146 case OP_UNPACK_HIGHD:
6147 case OP_UNPACK_HIGHQ:
6148 case OP_UNPACK_HIGHPS:
6149 case OP_UNPACK_HIGHPD: {
6151 LLVMValueRef mask_values [16];
6152 int i, mask_size = 0;
6153 gboolean low = FALSE;
6155 switch (ins->opcode) {
6156 case OP_UNPACK_LOWB:
6160 case OP_UNPACK_LOWW:
6164 case OP_UNPACK_LOWD:
6165 case OP_UNPACK_LOWPS:
6169 case OP_UNPACK_LOWQ:
6170 case OP_UNPACK_LOWPD:
6174 case OP_UNPACK_HIGHB:
6177 case OP_UNPACK_HIGHW:
6180 case OP_UNPACK_HIGHD:
6181 case OP_UNPACK_HIGHPS:
6184 case OP_UNPACK_HIGHQ:
6185 case OP_UNPACK_HIGHPD:
6189 g_assert_not_reached ();
6193 for (i = 0; i < (mask_size / 2); ++i) {
6195 mask [(i * 2) + 1] = mask_size + i;
6198 for (i = 0; i < (mask_size / 2); ++i) {
6199 mask [(i * 2)] = (mask_size / 2) + i;
6200 mask [(i * 2) + 1] = mask_size + (mask_size / 2) + i;
6204 for (i = 0; i < mask_size; ++i)
6205 mask_values [i] = LLVMConstInt (LLVMInt32Type (), mask [i], FALSE);
6207 values [ins->dreg] =
6208 LLVMBuildShuffleVector (builder, values [ins->sreg1], values [ins->sreg2],
6209 LLVMConstVector (mask_values, mask_size), dname);
6214 LLVMTypeRef t = simd_op_to_llvm_type (ins->opcode);
6215 LLVMValueRef v, val;
6217 v = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
6218 val = LLVMConstNull (t);
6219 val = LLVMBuildInsertElement (builder, val, v, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
6220 val = LLVMBuildInsertElement (builder, val, v, LLVMConstInt (LLVMInt32Type (), 1, FALSE), dname);
6222 values [ins->dreg] = val;
6226 case OP_DUPPS_HIGH: {
6227 LLVMTypeRef t = simd_op_to_llvm_type (ins->opcode);
6228 LLVMValueRef v1, v2, val;
6231 if (ins->opcode == OP_DUPPS_LOW) {
6232 v1 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
6233 v2 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 2, FALSE), "");
6235 v1 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 1, FALSE), "");
6236 v2 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 3, FALSE), "");
6238 val = LLVMConstNull (t);
6239 val = LLVMBuildInsertElement (builder, val, v1, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
6240 val = LLVMBuildInsertElement (builder, val, v1, LLVMConstInt (LLVMInt32Type (), 1, FALSE), "");
6241 val = LLVMBuildInsertElement (builder, val, v2, LLVMConstInt (LLVMInt32Type (), 2, FALSE), "");
6242 val = LLVMBuildInsertElement (builder, val, v2, LLVMConstInt (LLVMInt32Type (), 3, FALSE), "");
6244 values [ins->dreg] = val;
6254 * EXCEPTION HANDLING
6256 case OP_IMPLICIT_EXCEPTION:
6257 /* This marks a place where an implicit exception can happen */
6258 if (bb->region != -1)
6259 set_failure (ctx, "implicit-exception");
6263 gboolean rethrow = (ins->opcode == OP_RETHROW);
6264 if (ctx->llvm_only) {
6265 emit_llvmonly_throw (ctx, bb, rethrow, lhs);
6266 has_terminator = TRUE;
6267 ctx->unreachable [bb->block_num] = TRUE;
6269 emit_throw (ctx, bb, rethrow, lhs);
6270 builder = ctx->builder;
6274 case OP_CALL_HANDLER: {
6276 * We don't 'call' handlers, but instead simply branch to them.
6277 * The code generated by ENDFINALLY will branch back to us.
6279 LLVMBasicBlockRef noex_bb;
6281 BBInfo *info = &bblocks [ins->inst_target_bb->block_num];
6283 bb_list = info->call_handler_return_bbs;
6286 * Set the indicator variable for the finally clause.
6288 lhs = info->finally_ind;
6290 LLVMBuildStore (builder, LLVMConstInt (LLVMInt32Type (), g_slist_length (bb_list) + 1, FALSE), lhs);
6292 /* Branch to the finally clause */
6293 LLVMBuildBr (builder, info->call_handler_target_bb);
6295 noex_bb = gen_bb (ctx, "CALL_HANDLER_CONT_BB");
6296 info->call_handler_return_bbs = g_slist_append_mempool (cfg->mempool, info->call_handler_return_bbs, noex_bb);
6298 builder = ctx->builder = create_builder (ctx);
6299 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
6301 bblocks [bb->block_num].end_bblock = noex_bb;
6304 case OP_START_HANDLER: {
6307 case OP_ENDFINALLY: {
6308 LLVMBasicBlockRef resume_bb;
6309 MonoBasicBlock *handler_bb;
6310 LLVMValueRef val, switch_ins, callee;
6314 handler_bb = (MonoBasicBlock*)g_hash_table_lookup (ctx->region_to_handler, GUINT_TO_POINTER (mono_get_block_region_notry (cfg, bb->region)));
6315 g_assert (handler_bb);
6316 info = &bblocks [handler_bb->block_num];
6317 lhs = info->finally_ind;
6320 bb_list = info->call_handler_return_bbs;
6322 resume_bb = gen_bb (ctx, "ENDFINALLY_RESUME_BB");
6324 /* Load the finally variable */
6325 val = LLVMBuildLoad (builder, lhs, "");
6327 /* Reset the variable */
6328 LLVMBuildStore (builder, LLVMConstInt (LLVMInt32Type (), 0, FALSE), lhs);
6330 /* Branch to either resume_bb, or to the bblocks in bb_list */
6331 switch_ins = LLVMBuildSwitch (builder, val, resume_bb, g_slist_length (bb_list));
6333 * The other targets are added at the end to handle OP_CALL_HANDLER
6334 * opcodes processed later.
6336 info->endfinally_switch_ins_list = g_slist_append_mempool (cfg->mempool, info->endfinally_switch_ins_list, switch_ins);
6338 builder = ctx->builder = create_builder (ctx);
6339 LLVMPositionBuilderAtEnd (ctx->builder, resume_bb);
6341 if (ctx->llvm_only) {
6342 emit_resume_eh (ctx, bb);
6344 if (ctx->cfg->compile_aot) {
6345 callee = get_callee (ctx, LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE), MONO_PATCH_INFO_INTERNAL_METHOD, "llvm_resume_unwind_trampoline");
6347 #if LLVM_API_VERSION > 100
6348 MonoJitICallInfo *info;
6350 info = mono_find_jit_icall_by_name ("llvm_resume_unwind_trampoline");
6352 gpointer target = (void*)info->func;
6353 LLVMTypeRef icall_sig = LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE);
6354 callee = emit_jit_callee (ctx, "llvm_resume_unwind_trampoline", icall_sig, target);
6356 callee = LLVMGetNamedFunction (ctx->lmodule, "llvm_resume_unwind_trampoline");
6359 LLVMBuildCall (builder, callee, NULL, 0, "");
6360 LLVMBuildUnreachable (builder);
6363 has_terminator = TRUE;
6366 case OP_IL_SEQ_POINT:
6371 sprintf (reason, "opcode %s", mono_inst_name (ins->opcode));
6372 set_failure (ctx, reason);
6380 /* Convert the value to the type required by phi nodes */
6381 if (spec [MONO_INST_DEST] != ' ' && !MONO_IS_STORE_MEMBASE (ins) && ctx->vreg_types [ins->dreg]) {
6382 if (!values [ins->dreg])
6384 values [ins->dreg] = addresses [ins->dreg];
6386 values [ins->dreg] = convert (ctx, values [ins->dreg], ctx->vreg_types [ins->dreg]);
6389 /* Add stores for volatile variables */
6390 if (spec [MONO_INST_DEST] != ' ' && spec [MONO_INST_DEST] != 'v' && !MONO_IS_STORE_MEMBASE (ins))
6391 emit_volatile_store (ctx, ins->dreg);
6397 if (!has_terminator && bb->next_bb && (bb == cfg->bb_entry || bb->in_count > 0)) {
6398 LLVMBuildBr (builder, get_bb (ctx, bb->next_bb));
6401 if (bb == cfg->bb_exit && sig->ret->type == MONO_TYPE_VOID) {
6402 emit_dbg_loc (ctx, builder, cfg->header->code + cfg->header->code_size - 1);
6403 LLVMBuildRetVoid (builder);
6406 if (bb == cfg->bb_entry)
6407 ctx->last_alloca = LLVMGetLastInstruction (get_bb (ctx, cfg->bb_entry));
6411 * mono_llvm_check_method_supported:
6413 * Do some quick checks to decide whenever cfg->method can be compiled by LLVM, to avoid
6414 * compiling a method twice.
6417 mono_llvm_check_method_supported (MonoCompile *cfg)
6424 if (cfg->method->save_lmf) {
6425 cfg->exception_message = g_strdup ("lmf");
6426 cfg->disable_llvm = TRUE;
6428 if (cfg->disable_llvm)
6432 * Nested clauses where one of the clauses is a finally clause is
6433 * not supported, because LLVM can't figure out the control flow,
6434 * probably because we resume exception handling by calling our
6435 * own function instead of using the 'resume' llvm instruction.
6437 for (i = 0; i < cfg->header->num_clauses; ++i) {
6438 for (j = 0; j < cfg->header->num_clauses; ++j) {
6439 MonoExceptionClause *clause1 = &cfg->header->clauses [i];
6440 MonoExceptionClause *clause2 = &cfg->header->clauses [j];
6442 // FIXME: Nested try clauses fail in some cases too, i.e. #37273
6443 if (i != j && clause1->try_offset >= clause2->try_offset && clause1->handler_offset <= clause2->handler_offset) {
6444 //(clause1->flags == MONO_EXCEPTION_CLAUSE_FINALLY || clause2->flags == MONO_EXCEPTION_CLAUSE_FINALLY)) {
6445 cfg->exception_message = g_strdup ("nested clauses");
6446 cfg->disable_llvm = TRUE;
6451 if (cfg->disable_llvm)
6455 if (cfg->method->dynamic) {
6456 cfg->exception_message = g_strdup ("dynamic.");
6457 cfg->disable_llvm = TRUE;
6459 if (cfg->disable_llvm)
6463 static LLVMCallInfo*
6464 get_llvm_call_info (MonoCompile *cfg, MonoMethodSignature *sig)
6466 LLVMCallInfo *linfo;
6469 if (cfg->gsharedvt && cfg->llvm_only && mini_is_gsharedvt_variable_signature (sig)) {
6473 * Gsharedvt methods have the following calling convention:
6474 * - all arguments are passed by ref, even non generic ones
6475 * - the return value is returned by ref too, using a vret
6476 * argument passed after 'this'.
6478 n = sig->param_count + sig->hasthis;
6479 linfo = (LLVMCallInfo*)mono_mempool_alloc0 (cfg->mempool, sizeof (LLVMCallInfo) + (sizeof (LLVMArgInfo) * n));
6483 linfo->args [pindex ++].storage = LLVMArgNormal;
6485 if (sig->ret->type != MONO_TYPE_VOID) {
6486 if (mini_is_gsharedvt_variable_type (sig->ret))
6487 linfo->ret.storage = LLVMArgGsharedvtVariable;
6488 else if (mini_type_is_vtype (sig->ret))
6489 linfo->ret.storage = LLVMArgGsharedvtFixedVtype;
6491 linfo->ret.storage = LLVMArgGsharedvtFixed;
6492 linfo->vret_arg_index = pindex;
6494 linfo->ret.storage = LLVMArgNone;
6497 for (i = 0; i < sig->param_count; ++i) {
6498 if (sig->params [i]->byref)
6499 linfo->args [pindex].storage = LLVMArgNormal;
6500 else if (mini_is_gsharedvt_variable_type (sig->params [i]))
6501 linfo->args [pindex].storage = LLVMArgGsharedvtVariable;
6502 else if (mini_type_is_vtype (sig->params [i]))
6503 linfo->args [pindex].storage = LLVMArgGsharedvtFixedVtype;
6505 linfo->args [pindex].storage = LLVMArgGsharedvtFixed;
6506 linfo->args [pindex].type = sig->params [i];
6513 linfo = mono_arch_get_llvm_call_info (cfg, sig);
6514 for (i = 0; i < sig->param_count; ++i)
6515 linfo->args [i + sig->hasthis].type = sig->params [i];
6521 emit_method_inner (EmitContext *ctx);
6524 free_ctx (EmitContext *ctx)
6528 g_free (ctx->values);
6529 g_free (ctx->addresses);
6530 g_free (ctx->vreg_types);
6531 g_free (ctx->vreg_cli_types);
6532 g_free (ctx->is_dead);
6533 g_free (ctx->unreachable);
6534 g_ptr_array_free (ctx->phi_values, TRUE);
6535 g_free (ctx->bblocks);
6536 g_hash_table_destroy (ctx->region_to_handler);
6537 g_hash_table_destroy (ctx->clause_to_handler);
6538 g_hash_table_destroy (ctx->jit_callees);
6539 g_free (ctx->method_name);
6540 g_ptr_array_free (ctx->bblock_list, TRUE);
6542 for (l = ctx->builders; l; l = l->next) {
6543 LLVMBuilderRef builder = (LLVMBuilderRef)l->data;
6544 LLVMDisposeBuilder (builder);
6551 * mono_llvm_emit_method:
6553 * Emit LLVM IL from the mono IL, and compile it to native code using LLVM.
6556 mono_llvm_emit_method (MonoCompile *cfg)
6560 gboolean is_linkonce = FALSE;
6563 /* The code below might acquire the loader lock, so use it for global locking */
6564 mono_loader_lock ();
6566 /* Used to communicate with the callbacks */
6567 mono_native_tls_set_value (current_cfg_tls_id, cfg);
6569 ctx = g_new0 (EmitContext, 1);
6571 ctx->mempool = cfg->mempool;
6574 * This maps vregs to the LLVM instruction defining them
6576 ctx->values = g_new0 (LLVMValueRef, cfg->next_vreg);
6578 * This maps vregs for volatile variables to the LLVM instruction defining their
6581 ctx->addresses = g_new0 (LLVMValueRef, cfg->next_vreg);
6582 ctx->vreg_types = g_new0 (LLVMTypeRef, cfg->next_vreg);
6583 ctx->vreg_cli_types = g_new0 (MonoType*, cfg->next_vreg);
6584 ctx->phi_values = g_ptr_array_sized_new (256);
6586 * This signals whenever the vreg was defined by a phi node with no input vars
6587 * (i.e. all its input bblocks end with NOT_REACHABLE).
6589 ctx->is_dead = g_new0 (gboolean, cfg->next_vreg);
6590 /* Whenever the bblock is unreachable */
6591 ctx->unreachable = g_new0 (gboolean, cfg->max_block_num);
6592 ctx->bblock_list = g_ptr_array_sized_new (256);
6594 ctx->region_to_handler = g_hash_table_new (NULL, NULL);
6595 ctx->clause_to_handler = g_hash_table_new (NULL, NULL);
6596 ctx->method_to_callers = g_hash_table_new (NULL, NULL);
6597 ctx->jit_callees = g_hash_table_new (NULL, NULL);
6598 if (cfg->compile_aot) {
6599 ctx->module = &aot_module;
6603 * Allow the linker to discard duplicate copies of wrappers, generic instances etc. by using the 'linkonce'
6604 * linkage for them. This requires the following:
6605 * - the method needs to have a unique mangled name
6606 * - llvmonly mode, since the code in aot-runtime.c would initialize got slots in the wrong aot image etc.
6608 is_linkonce = ctx->module->llvm_only && ctx->module->static_link && mono_aot_is_linkonce_method (cfg->method);
6610 method_name = mono_aot_get_mangled_method_name (cfg->method);
6612 is_linkonce = FALSE;
6615 printf ("%s %s\n", mono_method_full_name (cfg->method, 1), method_name);
6617 printf ("%s\n", mono_method_full_name (cfg->method, 1));
6621 method_name = mono_aot_get_method_name (cfg);
6622 cfg->llvm_method_name = g_strdup (method_name);
6624 init_jit_module (cfg->domain);
6625 ctx->module = (MonoLLVMModule*)domain_jit_info (cfg->domain)->llvm_module;
6626 method_name = mono_method_full_name (cfg->method, TRUE);
6628 ctx->method_name = method_name;
6629 ctx->is_linkonce = is_linkonce;
6631 #if LLVM_API_VERSION > 100
6632 ctx->lmodule = LLVMModuleCreateWithName ("jit-module");
6634 ctx->lmodule = ctx->module->lmodule;
6636 ctx->llvm_only = ctx->module->llvm_only;
6638 emit_method_inner (ctx);
6640 if (!ctx_ok (ctx)) {
6642 /* Need to add unused phi nodes as they can be referenced by other values */
6643 LLVMBasicBlockRef phi_bb = LLVMAppendBasicBlock (ctx->lmethod, "PHI_BB");
6644 LLVMBuilderRef builder;
6646 builder = create_builder (ctx);
6647 LLVMPositionBuilderAtEnd (builder, phi_bb);
6649 for (i = 0; i < ctx->phi_values->len; ++i) {
6650 LLVMValueRef v = (LLVMValueRef)g_ptr_array_index (ctx->phi_values, i);
6651 if (LLVMGetInstructionParent (v) == NULL)
6652 LLVMInsertIntoBuilder (builder, v);
6655 LLVMDeleteFunction (ctx->lmethod);
6661 mono_native_tls_set_value (current_cfg_tls_id, NULL);
6663 mono_loader_unlock ();
6667 emit_method_inner (EmitContext *ctx)
6669 MonoCompile *cfg = ctx->cfg;
6670 MonoMethodSignature *sig;
6672 LLVMTypeRef method_type;
6673 LLVMValueRef method = NULL;
6674 LLVMValueRef *values = ctx->values;
6675 int i, max_block_num, bb_index;
6676 gboolean last = FALSE;
6677 LLVMCallInfo *linfo;
6678 LLVMModuleRef lmodule = ctx->lmodule;
6680 GPtrArray *bblock_list = ctx->bblock_list;
6681 MonoMethodHeader *header;
6682 MonoExceptionClause *clause;
6685 if (cfg->gsharedvt && !cfg->llvm_only) {
6686 set_failure (ctx, "gsharedvt");
6692 static int count = 0;
6695 if (g_getenv ("LLVM_COUNT")) {
6696 if (count == atoi (g_getenv ("LLVM_COUNT"))) {
6697 printf ("LAST: %s\n", mono_method_full_name (cfg->method, TRUE));
6701 if (count > atoi (g_getenv ("LLVM_COUNT"))) {
6702 set_failure (ctx, "count");
6709 sig = mono_method_signature (cfg->method);
6712 linfo = get_llvm_call_info (cfg, sig);
6718 linfo->rgctx_arg = TRUE;
6719 ctx->method_type = method_type = sig_to_llvm_sig_full (ctx, sig, linfo);
6723 method = LLVMAddFunction (lmodule, ctx->method_name, method_type);
6724 ctx->lmethod = method;
6726 if (!cfg->llvm_only)
6727 LLVMSetFunctionCallConv (method, LLVMMono1CallConv);
6728 LLVMSetLinkage (method, LLVMPrivateLinkage);
6730 LLVMAddFunctionAttr (method, LLVMUWTable);
6732 if (cfg->compile_aot) {
6733 LLVMSetLinkage (method, LLVMInternalLinkage);
6734 if (ctx->module->external_symbols) {
6735 LLVMSetLinkage (method, LLVMExternalLinkage);
6736 LLVMSetVisibility (method, LLVMHiddenVisibility);
6738 if (ctx->is_linkonce) {
6739 LLVMSetLinkage (method, LLVMLinkOnceAnyLinkage);
6740 LLVMSetVisibility (method, LLVMDefaultVisibility);
6743 #if LLVM_API_VERSION > 100
6744 LLVMSetLinkage (method, LLVMExternalLinkage);
6746 LLVMSetLinkage (method, LLVMPrivateLinkage);
6750 if (cfg->method->save_lmf && !cfg->llvm_only) {
6751 set_failure (ctx, "lmf");
6755 if (sig->pinvoke && cfg->method->wrapper_type != MONO_WRAPPER_RUNTIME_INVOKE && !cfg->llvm_only) {
6756 set_failure (ctx, "pinvoke signature");
6760 header = cfg->header;
6761 for (i = 0; i < header->num_clauses; ++i) {
6762 clause = &header->clauses [i];
6763 if (clause->flags != MONO_EXCEPTION_CLAUSE_FINALLY && clause->flags != MONO_EXCEPTION_CLAUSE_NONE) {
6764 set_failure (ctx, "non-finally/catch clause.");
6768 if (header->num_clauses || (cfg->method->iflags & METHOD_IMPL_ATTRIBUTE_NOINLINING) || cfg->no_inline)
6769 /* We can't handle inlined methods with clauses */
6770 LLVMAddFunctionAttr (method, LLVMNoInlineAttribute);
6772 if (linfo->rgctx_arg) {
6773 ctx->rgctx_arg = LLVMGetParam (method, linfo->rgctx_arg_pindex);
6774 ctx->rgctx_arg_pindex = linfo->rgctx_arg_pindex;
6776 * We mark the rgctx parameter with the inreg attribute, which is mapped to
6777 * MONO_ARCH_RGCTX_REG in the Mono calling convention in llvm, i.e.
6778 * CC_X86_64_Mono in X86CallingConv.td.
6780 if (!ctx->llvm_only)
6781 LLVMAddAttribute (ctx->rgctx_arg, LLVMInRegAttribute);
6782 LLVMSetValueName (ctx->rgctx_arg, "rgctx");
6784 ctx->rgctx_arg_pindex = -1;
6786 if (cfg->vret_addr) {
6787 values [cfg->vret_addr->dreg] = LLVMGetParam (method, linfo->vret_arg_pindex);
6788 LLVMSetValueName (values [cfg->vret_addr->dreg], "vret");
6789 if (linfo->ret.storage == LLVMArgVtypeByRef) {
6790 LLVMAddAttribute (LLVMGetParam (method, linfo->vret_arg_pindex), LLVMStructRetAttribute);
6791 LLVMAddAttribute (LLVMGetParam (method, linfo->vret_arg_pindex), LLVMNoAliasAttribute);
6796 ctx->this_arg_pindex = linfo->this_arg_pindex;
6797 ctx->this_arg = LLVMGetParam (method, linfo->this_arg_pindex);
6798 values [cfg->args [0]->dreg] = ctx->this_arg;
6799 LLVMSetValueName (values [cfg->args [0]->dreg], "this");
6802 names = g_new (char *, sig->param_count);
6803 mono_method_get_param_names (cfg->method, (const char **) names);
6805 for (i = 0; i < sig->param_count; ++i) {
6806 LLVMArgInfo *ainfo = &linfo->args [i + sig->hasthis];
6808 int pindex = ainfo->pindex + ainfo->ndummy_fpargs;
6811 for (j = 0; j < ainfo->ndummy_fpargs; ++j) {
6812 name = g_strdup_printf ("dummy_%d_%d", i, j);
6813 LLVMSetValueName (LLVMGetParam (method, ainfo->pindex + j), name);
6817 values [cfg->args [i + sig->hasthis]->dreg] = LLVMGetParam (method, pindex);
6818 if (ainfo->storage == LLVMArgGsharedvtFixed || ainfo->storage == LLVMArgGsharedvtFixedVtype) {
6819 if (names [i] && names [i][0] != '\0')
6820 name = g_strdup_printf ("p_arg_%s", names [i]);
6822 name = g_strdup_printf ("p_arg_%d", i);
6824 if (names [i] && names [i][0] != '\0')
6825 name = g_strdup_printf ("arg_%s", names [i]);
6827 name = g_strdup_printf ("arg_%d", i);
6829 LLVMSetValueName (values [cfg->args [i + sig->hasthis]->dreg], name);
6831 if (ainfo->storage == LLVMArgVtypeByVal)
6832 LLVMAddAttribute (LLVMGetParam (method, pindex), LLVMByValAttribute);
6834 if (ainfo->storage == LLVMArgVtypeByRef) {
6836 cfg->args [i + sig->hasthis]->opcode = OP_VTARG_ADDR;
6841 if (ctx->module->emit_dwarf && cfg->compile_aot && mono_debug_enabled ()) {
6842 ctx->minfo = mono_debug_lookup_method (cfg->method);
6843 ctx->dbg_md = emit_dbg_subprogram (ctx, cfg, method, ctx->method_name);
6847 for (bb = cfg->bb_entry; bb; bb = bb->next_bb)
6848 max_block_num = MAX (max_block_num, bb->block_num);
6849 ctx->bblocks = bblocks = g_new0 (BBInfo, max_block_num + 1);
6851 /* Add branches between non-consecutive bblocks */
6852 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
6853 if (bb->last_ins && MONO_IS_COND_BRANCH_OP (bb->last_ins) &&
6854 bb->next_bb != bb->last_ins->inst_false_bb) {
6856 MonoInst *inst = (MonoInst*)mono_mempool_alloc0 (cfg->mempool, sizeof (MonoInst));
6857 inst->opcode = OP_BR;
6858 inst->inst_target_bb = bb->last_ins->inst_false_bb;
6859 mono_bblock_add_inst (bb, inst);
6864 * The INDIRECT flag added by OP_LDADDR inhibits optimizations, even if the LDADDR
6865 * was later optimized away, so clear these flags, and add them back for the still
6866 * present OP_LDADDR instructions.
6868 for (i = 0; i < cfg->next_vreg; ++i) {
6871 ins = get_vreg_to_inst (cfg, i);
6872 if (ins && ins != cfg->rgctx_var)
6873 ins->flags &= ~MONO_INST_INDIRECT;
6877 * Make a first pass over the code to precreate PHI nodes/set INDIRECT flags.
6879 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
6881 LLVMBuilderRef builder;
6883 char dname_buf[128];
6885 builder = create_builder (ctx);
6887 for (ins = bb->code; ins; ins = ins->next) {
6888 switch (ins->opcode) {
6893 LLVMTypeRef phi_type = llvm_type_to_stack_type (cfg, type_to_llvm_type (ctx, &ins->klass->byval_arg));
6898 if (ins->opcode == OP_VPHI) {
6899 /* Treat valuetype PHI nodes as operating on the address itself */
6900 g_assert (ins->klass);
6901 phi_type = LLVMPointerType (type_to_llvm_type (ctx, &ins->klass->byval_arg), 0);
6905 * Have to precreate these, as they can be referenced by
6906 * earlier instructions.
6908 sprintf (dname_buf, "t%d", ins->dreg);
6910 values [ins->dreg] = LLVMBuildPhi (builder, phi_type, dname);
6912 if (ins->opcode == OP_VPHI)
6913 ctx->addresses [ins->dreg] = values [ins->dreg];
6915 g_ptr_array_add (ctx->phi_values, values [ins->dreg]);
6918 * Set the expected type of the incoming arguments since these have
6919 * to have the same type.
6921 for (i = 0; i < ins->inst_phi_args [0]; i++) {
6922 int sreg1 = ins->inst_phi_args [i + 1];
6925 ctx->vreg_types [sreg1] = phi_type;
6930 ((MonoInst*)ins->inst_p0)->flags |= MONO_INST_INDIRECT;
6939 * Create an ordering for bblocks, use the depth first order first, then
6940 * put the exception handling bblocks last.
6942 for (bb_index = 0; bb_index < cfg->num_bblocks; ++bb_index) {
6943 bb = cfg->bblocks [bb_index];
6944 if (!(bb->region != -1 && !MONO_BBLOCK_IS_IN_REGION (bb, MONO_REGION_TRY))) {
6945 g_ptr_array_add (bblock_list, bb);
6946 bblocks [bb->block_num].added = TRUE;
6950 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
6951 if (!bblocks [bb->block_num].added)
6952 g_ptr_array_add (bblock_list, bb);
6956 * Second pass: generate code.
6959 LLVMBuilderRef entry_builder = create_builder (ctx);
6960 LLVMBasicBlockRef entry_bb = get_bb (ctx, cfg->bb_entry);
6961 LLVMPositionBuilderAtEnd (entry_builder, entry_bb);
6962 emit_entry_bb (ctx, entry_builder);
6964 // Make landing pads first
6965 ctx->exc_meta = g_hash_table_new_full (NULL, NULL, NULL, NULL);
6967 if (ctx->llvm_only) {
6968 size_t group_index = 0;
6969 while (group_index < cfg->header->num_clauses) {
6971 size_t cursor = group_index;
6972 while (cursor < cfg->header->num_clauses &&
6973 CLAUSE_START (&cfg->header->clauses [cursor]) == CLAUSE_START (&cfg->header->clauses [group_index]) &&
6974 CLAUSE_END (&cfg->header->clauses [cursor]) == CLAUSE_END (&cfg->header->clauses [group_index])) {
6979 LLVMBasicBlockRef lpad_bb = emit_landing_pad (ctx, group_index, count);
6980 intptr_t key = CLAUSE_END (&cfg->header->clauses [group_index]);
6981 g_hash_table_insert (ctx->exc_meta, (gpointer)key, lpad_bb);
6983 group_index = cursor;
6987 for (bb_index = 0; bb_index < bblock_list->len; ++bb_index) {
6988 bb = (MonoBasicBlock*)g_ptr_array_index (bblock_list, bb_index);
6990 // Prune unreachable mono BBs.
6991 if (!(bb == cfg->bb_entry || bb->in_count > 0))
6994 process_bb (ctx, bb);
6998 g_hash_table_destroy (ctx->exc_meta);
7000 mono_memory_barrier ();
7002 /* Add incoming phi values */
7003 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
7004 GSList *l, *ins_list;
7006 ins_list = bblocks [bb->block_num].phi_nodes;
7008 for (l = ins_list; l; l = l->next) {
7009 PhiNode *node = (PhiNode*)l->data;
7010 MonoInst *phi = node->phi;
7011 int sreg1 = node->sreg;
7012 LLVMBasicBlockRef in_bb;
7017 in_bb = get_end_bb (ctx, node->in_bb);
7019 if (ctx->unreachable [node->in_bb->block_num])
7022 if (!values [sreg1]) {
7023 /* Can happen with values in EH clauses */
7024 set_failure (ctx, "incoming phi sreg1");
7028 if (phi->opcode == OP_VPHI) {
7029 g_assert (LLVMTypeOf (ctx->addresses [sreg1]) == LLVMTypeOf (values [phi->dreg]));
7030 LLVMAddIncoming (values [phi->dreg], &ctx->addresses [sreg1], &in_bb, 1);
7032 if (LLVMTypeOf (values [sreg1]) != LLVMTypeOf (values [phi->dreg])) {
7033 set_failure (ctx, "incoming phi arg type mismatch");
7036 g_assert (LLVMTypeOf (values [sreg1]) == LLVMTypeOf (values [phi->dreg]));
7037 LLVMAddIncoming (values [phi->dreg], &values [sreg1], &in_bb, 1);
7042 /* Nullify empty phi instructions */
7043 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
7044 GSList *l, *ins_list;
7046 ins_list = bblocks [bb->block_num].phi_nodes;
7048 for (l = ins_list; l; l = l->next) {
7049 PhiNode *node = (PhiNode*)l->data;
7050 MonoInst *phi = node->phi;
7051 LLVMValueRef phi_ins = values [phi->dreg];
7054 /* Already removed */
7057 if (LLVMCountIncoming (phi_ins) == 0) {
7058 mono_llvm_replace_uses_of (phi_ins, LLVMConstNull (LLVMTypeOf (phi_ins)));
7059 LLVMInstructionEraseFromParent (phi_ins);
7060 values [phi->dreg] = NULL;
7065 /* Create the SWITCH statements for ENDFINALLY instructions */
7066 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
7067 BBInfo *info = &bblocks [bb->block_num];
7069 for (l = info->endfinally_switch_ins_list; l; l = l->next) {
7070 LLVMValueRef switch_ins = (LLVMValueRef)l->data;
7071 GSList *bb_list = info->call_handler_return_bbs;
7073 for (i = 0; i < g_slist_length (bb_list); ++i)
7074 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), i + 1, FALSE), (LLVMBasicBlockRef)(g_slist_nth (bb_list, i)->data));
7078 /* Initialize the method if needed */
7079 if (cfg->compile_aot && ctx->llvm_only) {
7080 // FIXME: Add more shared got entries
7081 ctx->builder = create_builder (ctx);
7082 LLVMPositionBuilderAtEnd (ctx->builder, ctx->init_bb);
7084 ctx->module->max_method_idx = MAX (ctx->module->max_method_idx, cfg->method_index);
7086 // FIXME: beforefieldinit
7087 if (ctx->has_got_access || mono_class_get_cctor (cfg->method->klass)) {
7088 emit_init_method (ctx);
7090 LLVMBuildBr (ctx->builder, ctx->inited_bb);
7094 if (cfg->llvm_only) {
7095 GHashTableIter iter;
7097 GSList *callers, *l, *l2;
7100 * Add the contents of ctx->method_to_callers to module->method_to_callers.
7101 * We can't do this earlier, as it contains llvm instructions which can be
7102 * freed if compilation fails.
7103 * FIXME: Get rid of this when all methods can be llvm compiled.
7105 g_hash_table_iter_init (&iter, ctx->method_to_callers);
7106 while (g_hash_table_iter_next (&iter, (void**)&method, (void**)&callers)) {
7107 for (l = callers; l; l = l->next) {
7108 l2 = (GSList*)g_hash_table_lookup (ctx->module->method_to_callers, method);
7109 l2 = g_slist_prepend (l2, l->data);
7110 g_hash_table_insert (ctx->module->method_to_callers, method, l2);
7115 if (cfg->verbose_level > 1)
7116 mono_llvm_dump_value (method);
7118 if (cfg->compile_aot && !cfg->llvm_only)
7119 mark_as_used (ctx->module, method);
7121 if (cfg->compile_aot && !cfg->llvm_only) {
7122 LLVMValueRef md_args [16];
7123 LLVMValueRef md_node;
7126 method_index = mono_aot_get_method_index (cfg->orig_method);
7127 md_args [0] = LLVMMDString (ctx->method_name, strlen (ctx->method_name));
7128 md_args [1] = LLVMConstInt (LLVMInt32Type (), method_index, FALSE);
7129 md_node = LLVMMDNode (md_args, 2);
7130 LLVMAddNamedMetadataOperand (lmodule, "mono.function_indexes", md_node);
7131 //LLVMSetMetadata (method, md_kind, LLVMMDNode (&md_arg, 1));
7134 if (cfg->compile_aot) {
7135 /* Don't generate native code, keep the LLVM IR */
7136 if (cfg->verbose_level)
7137 printf ("%s emitted as %s\n", mono_method_full_name (cfg->method, TRUE), ctx->method_name);
7139 #if LLVM_API_VERSION < 100
7140 /* VerifyFunction can't handle some of the debug info created by DIBuilder in llvm 3.9 */
7141 int err = LLVMVerifyFunction(ctx->lmethod, LLVMPrintMessageAction);
7142 g_assert (err == 0);
7145 //LLVMVerifyFunction(method, 0);
7146 #if LLVM_API_VERSION > 100
7147 MonoDomain *domain = mono_domain_get ();
7148 MonoJitDomainInfo *domain_info;
7149 int nvars = g_hash_table_size (ctx->jit_callees);
7150 LLVMValueRef *callee_vars = g_new0 (LLVMValueRef, nvars);
7151 gpointer *callee_addrs = g_new0 (gpointer, nvars);
7152 GHashTableIter iter;
7158 * Compute the addresses of the LLVM globals pointing to the
7159 * methods called by the current method. Pass it to the trampoline
7160 * code so it can update them after their corresponding method was
7163 g_hash_table_iter_init (&iter, ctx->jit_callees);
7165 while (g_hash_table_iter_next (&iter, NULL, (void**)&var))
7166 callee_vars [i ++] = var;
7168 cfg->native_code = mono_llvm_compile_method (ctx->module->mono_ee, ctx->lmethod, nvars, callee_vars, callee_addrs, &eh_frame);
7170 decode_llvm_eh_info (ctx, eh_frame);
7172 mono_domain_lock (domain);
7173 domain_info = domain_jit_info (domain);
7174 if (!domain_info->llvm_jit_callees)
7175 domain_info->llvm_jit_callees = g_hash_table_new (NULL, NULL);
7176 g_hash_table_iter_init (&iter, ctx->jit_callees);
7178 while (g_hash_table_iter_next (&iter, (void**)&callee, (void**)&var)) {
7179 GSList *addrs = g_hash_table_lookup (domain_info->llvm_jit_callees, callee);
7180 addrs = g_slist_prepend (addrs, callee_addrs [i]);
7181 g_hash_table_insert (domain_info->llvm_jit_callees, callee, addrs);
7184 mono_domain_unlock (domain);
7186 mono_llvm_optimize_method (ctx->module->mono_ee, ctx->lmethod);
7188 if (cfg->verbose_level > 1)
7189 mono_llvm_dump_value (ctx->lmethod);
7191 cfg->native_code = (unsigned char*)LLVMGetPointerToGlobal (ctx->module->ee, ctx->lmethod);
7193 /* Set by emit_cb */
7194 g_assert (cfg->code_len);
7198 if (ctx->module->method_to_lmethod)
7199 g_hash_table_insert (ctx->module->method_to_lmethod, cfg->method, ctx->lmethod);
7200 if (ctx->module->idx_to_lmethod)
7201 g_hash_table_insert (ctx->module->idx_to_lmethod, GINT_TO_POINTER (cfg->method_index), ctx->lmethod);
7203 if (ctx->llvm_only && cfg->orig_method->klass->valuetype && !(cfg->orig_method->flags & METHOD_ATTRIBUTE_STATIC))
7204 emit_unbox_tramp (ctx, ctx->method_name, ctx->method_type, ctx->lmethod, cfg->method_index);
7208 * mono_llvm_create_vars:
7210 * Same as mono_arch_create_vars () for LLVM.
7213 mono_llvm_create_vars (MonoCompile *cfg)
7215 MonoMethodSignature *sig;
7217 sig = mono_method_signature (cfg->method);
7218 if (cfg->gsharedvt && cfg->llvm_only) {
7219 if (mini_is_gsharedvt_variable_signature (sig) && sig->ret->type != MONO_TYPE_VOID) {
7220 cfg->vret_addr = mono_compile_create_var (cfg, &mono_get_intptr_class ()->byval_arg, OP_ARG);
7221 if (G_UNLIKELY (cfg->verbose_level > 1)) {
7222 printf ("vret_addr = ");
7223 mono_print_ins (cfg->vret_addr);
7227 mono_arch_create_vars (cfg);
7232 * mono_llvm_emit_call:
7234 * Same as mono_arch_emit_call () for LLVM.
7237 mono_llvm_emit_call (MonoCompile *cfg, MonoCallInst *call)
7240 MonoMethodSignature *sig;
7241 int i, n, stack_size;
7246 sig = call->signature;
7247 n = sig->param_count + sig->hasthis;
7249 call->cinfo = get_llvm_call_info (cfg, sig);
7251 if (cfg->disable_llvm)
7254 if (sig->call_convention == MONO_CALL_VARARG) {
7255 cfg->exception_message = g_strdup ("varargs");
7256 cfg->disable_llvm = TRUE;
7259 for (i = 0; i < n; ++i) {
7262 ainfo = call->cinfo->args + i;
7264 in = call->args [i];
7266 /* Simply remember the arguments */
7267 switch (ainfo->storage) {
7268 case LLVMArgNormal: {
7269 MonoType *t = (sig->hasthis && i == 0) ? &mono_get_intptr_class ()->byval_arg : ainfo->type;
7272 opcode = mono_type_to_regmove (cfg, t);
7273 if (opcode == OP_FMOVE) {
7274 MONO_INST_NEW (cfg, ins, OP_FMOVE);
7275 ins->dreg = mono_alloc_freg (cfg);
7276 } else if (opcode == OP_LMOVE) {
7277 MONO_INST_NEW (cfg, ins, OP_LMOVE);
7278 ins->dreg = mono_alloc_lreg (cfg);
7279 } else if (opcode == OP_RMOVE) {
7280 MONO_INST_NEW (cfg, ins, OP_RMOVE);
7281 ins->dreg = mono_alloc_freg (cfg);
7283 MONO_INST_NEW (cfg, ins, OP_MOVE);
7284 ins->dreg = mono_alloc_ireg (cfg);
7286 ins->sreg1 = in->dreg;
7289 case LLVMArgVtypeByVal:
7290 case LLVMArgVtypeByRef:
7291 case LLVMArgVtypeInReg:
7292 case LLVMArgVtypeAsScalar:
7293 case LLVMArgAsIArgs:
7294 case LLVMArgAsFpArgs:
7295 case LLVMArgGsharedvtVariable:
7296 case LLVMArgGsharedvtFixed:
7297 case LLVMArgGsharedvtFixedVtype:
7298 MONO_INST_NEW (cfg, ins, OP_LLVM_OUTARG_VT);
7299 ins->dreg = mono_alloc_ireg (cfg);
7300 ins->sreg1 = in->dreg;
7301 ins->inst_p0 = mono_mempool_alloc0 (cfg->mempool, sizeof (LLVMArgInfo));
7302 memcpy (ins->inst_p0, ainfo, sizeof (LLVMArgInfo));
7303 ins->inst_vtype = ainfo->type;
7304 ins->klass = mono_class_from_mono_type (ainfo->type);
7307 cfg->exception_message = g_strdup ("ainfo->storage");
7308 cfg->disable_llvm = TRUE;
7312 if (!cfg->disable_llvm) {
7313 MONO_ADD_INS (cfg->cbb, ins);
7314 mono_call_inst_add_outarg_reg (cfg, call, ins->dreg, 0, FALSE);
7319 static unsigned char*
7320 alloc_cb (LLVMValueRef function, int size)
7324 cfg = (MonoCompile*)mono_native_tls_get_value (current_cfg_tls_id);
7328 return (unsigned char*)mono_domain_code_reserve (cfg->domain, size);
7330 return (unsigned char*)mono_domain_code_reserve (mono_domain_get (), size);
7335 emitted_cb (LLVMValueRef function, void *start, void *end)
7339 cfg = (MonoCompile*)mono_native_tls_get_value (current_cfg_tls_id);
7341 cfg->code_len = (guint8*)end - (guint8*)start;
7345 exception_cb (void *data)
7348 MonoJitExceptionInfo *ei;
7349 guint32 ei_len, i, j, nested_len, nindex;
7350 gpointer *type_info;
7351 int this_reg, this_offset;
7353 cfg = (MonoCompile*)mono_native_tls_get_value (current_cfg_tls_id);
7357 * data points to a DWARF FDE structure, convert it to our unwind format and
7359 * An alternative would be to save it directly, and modify our unwinder to work
7362 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);
7363 if (cfg->verbose_level > 1)
7364 mono_print_unwind_info (cfg->encoded_unwind_ops, cfg->encoded_unwind_ops_len);
7366 /* Count nested clauses */
7368 for (i = 0; i < ei_len; ++i) {
7369 gint32 cindex1 = *(gint32*)type_info [i];
7370 MonoExceptionClause *clause1 = &cfg->header->clauses [cindex1];
7372 for (j = 0; j < cfg->header->num_clauses; ++j) {
7374 MonoExceptionClause *clause2 = &cfg->header->clauses [cindex2];
7376 if (cindex1 != cindex2 && clause1->try_offset >= clause2->try_offset && clause1->handler_offset <= clause2->handler_offset) {
7382 cfg->llvm_ex_info = (MonoJitExceptionInfo*)mono_mempool_alloc0 (cfg->mempool, (ei_len + nested_len) * sizeof (MonoJitExceptionInfo));
7383 cfg->llvm_ex_info_len = ei_len + nested_len;
7384 memcpy (cfg->llvm_ex_info, ei, ei_len * sizeof (MonoJitExceptionInfo));
7385 /* Fill the rest of the information from the type info */
7386 for (i = 0; i < ei_len; ++i) {
7387 gint32 clause_index = *(gint32*)type_info [i];
7388 MonoExceptionClause *clause = &cfg->header->clauses [clause_index];
7390 cfg->llvm_ex_info [i].flags = clause->flags;
7391 cfg->llvm_ex_info [i].data.catch_class = clause->data.catch_class;
7392 cfg->llvm_ex_info [i].clause_index = clause_index;
7396 * For nested clauses, the LLVM produced exception info associates the try interval with
7397 * the innermost handler, while mono expects it to be associated with all nesting clauses.
7398 * So add new clauses which use the IL info (catch class etc.) from the nesting clause,
7399 * and everything else from the nested clause.
7402 for (i = 0; i < ei_len; ++i) {
7403 gint32 cindex1 = *(gint32*)type_info [i];
7404 MonoExceptionClause *clause1 = &cfg->header->clauses [cindex1];
7406 for (j = 0; j < cfg->header->num_clauses; ++j) {
7408 MonoExceptionClause *clause2 = &cfg->header->clauses [cindex2];
7409 MonoJitExceptionInfo *nesting_ei, *nested_ei;
7411 if (cindex1 != cindex2 && clause1->try_offset >= clause2->try_offset && clause1->handler_offset <= clause2->handler_offset) {
7412 /* clause1 is the nested clause */
7413 nested_ei = &cfg->llvm_ex_info [i];
7414 nesting_ei = &cfg->llvm_ex_info [nindex];
7417 memcpy (nesting_ei, nested_ei, sizeof (MonoJitExceptionInfo));
7419 nesting_ei->flags = clause2->flags;
7420 nesting_ei->data.catch_class = clause2->data.catch_class;
7421 nesting_ei->clause_index = cindex2;
7425 g_assert (nindex == ei_len + nested_len);
7426 cfg->llvm_this_reg = this_reg;
7427 cfg->llvm_this_offset = this_offset;
7429 /* type_info [i] is cfg mempool allocated, no need to free it */
7435 #if LLVM_API_VERSION > 100
7437 * decode_llvm_eh_info:
7439 * Decode the EH table emitted by llvm in jit mode, and store
7440 * the result into cfg.
7443 decode_llvm_eh_info (EmitContext *ctx, gpointer eh_frame)
7445 MonoCompile *cfg = ctx->cfg;
7448 MonoLLVMFDEInfo info;
7449 MonoJitExceptionInfo *ei;
7450 guint8 *p = eh_frame;
7451 int version, fde_count, fde_offset;
7452 guint32 ei_len, i, nested_len;
7453 gpointer *type_info;
7457 * Decode the one element EH table emitted by the MonoException class
7461 /* Similar to decode_llvm_mono_eh_frame () in aot-runtime.c */
7464 g_assert (version == 3);
7467 p = (guint8 *)ALIGN_PTR_TO (p, 4);
7469 fde_count = *(guint32*)p;
7473 g_assert (fde_count == 1);
7475 /* The only table entry */
7476 fde_offset = table [1];
7479 cfg->code_len = table [0];
7480 fde_len = table [1] - fde_offset;
7483 fde = (guint8*)eh_frame + fde_offset;
7484 cie = (guint8*)table;
7486 mono_unwind_decode_llvm_mono_fde (fde, fde_len, cie, cfg->native_code, &info);
7488 cfg->encoded_unwind_ops = info.unw_info;
7489 cfg->encoded_unwind_ops_len = info.unw_info_len;
7490 if (cfg->verbose_level > 1)
7491 mono_print_unwind_info (cfg->encoded_unwind_ops, cfg->encoded_unwind_ops_len);
7492 if (info.this_reg != -1) {
7493 cfg->llvm_this_reg = info.this_reg;
7494 cfg->llvm_this_offset = info.this_offset;
7498 ei_len = info.ex_info_len;
7499 type_info = info.type_info;
7501 // Nested clauses are currently disabled
7504 cfg->llvm_ex_info = (MonoJitExceptionInfo*)mono_mempool_alloc0 (cfg->mempool, (ei_len + nested_len) * sizeof (MonoJitExceptionInfo));
7505 cfg->llvm_ex_info_len = ei_len + nested_len;
7506 memcpy (cfg->llvm_ex_info, ei, ei_len * sizeof (MonoJitExceptionInfo));
7507 /* Fill the rest of the information from the type info */
7508 for (i = 0; i < ei_len; ++i) {
7509 gint32 clause_index = *(gint32*)type_info [i];
7510 MonoExceptionClause *clause = &cfg->header->clauses [clause_index];
7512 cfg->llvm_ex_info [i].flags = clause->flags;
7513 cfg->llvm_ex_info [i].data.catch_class = clause->data.catch_class;
7514 cfg->llvm_ex_info [i].clause_index = clause_index;
7520 dlsym_cb (const char *name, void **symbol)
7526 if (!strcmp (name, "__bzero")) {
7527 *symbol = (void*)bzero;
7529 current = mono_dl_open (NULL, 0, NULL);
7532 err = mono_dl_symbol (current, name, symbol);
7534 mono_dl_close (current);
7536 #ifdef MONO_ARCH_HAVE_CREATE_LLVM_NATIVE_THUNK
7537 *symbol = (char*)mono_arch_create_llvm_native_thunk (mono_domain_get (), (guint8*)(*symbol));
7543 AddFunc (LLVMModuleRef module, const char *name, LLVMTypeRef ret_type, LLVMTypeRef *param_types, int nparams)
7545 LLVMAddFunction (module, name, LLVMFunctionType (ret_type, param_types, nparams, FALSE));
7549 AddFunc2 (LLVMModuleRef module, const char *name, LLVMTypeRef ret_type, LLVMTypeRef param_type1, LLVMTypeRef param_type2)
7551 LLVMTypeRef param_types [4];
7553 param_types [0] = param_type1;
7554 param_types [1] = param_type2;
7556 AddFunc (module, name, ret_type, param_types, 2);
7562 INTRINS_SADD_OVF_I32,
7563 INTRINS_UADD_OVF_I32,
7564 INTRINS_SSUB_OVF_I32,
7565 INTRINS_USUB_OVF_I32,
7566 INTRINS_SMUL_OVF_I32,
7567 INTRINS_UMUL_OVF_I32,
7568 INTRINS_SADD_OVF_I64,
7569 INTRINS_UADD_OVF_I64,
7570 INTRINS_SSUB_OVF_I64,
7571 INTRINS_USUB_OVF_I64,
7572 INTRINS_SMUL_OVF_I64,
7573 INTRINS_UMUL_OVF_I64,
7580 #if defined(TARGET_AMD64) || defined(TARGET_X86)
7581 INTRINS_SSE_PMOVMSKB,
7582 INTRINS_SSE_PSRLI_W,
7583 INTRINS_SSE_PSRAI_W,
7584 INTRINS_SSE_PSLLI_W,
7585 INTRINS_SSE_PSRLI_D,
7586 INTRINS_SSE_PSRAI_D,
7587 INTRINS_SSE_PSLLI_D,
7588 INTRINS_SSE_PSRLI_Q,
7589 INTRINS_SSE_PSLLI_Q,
7590 INTRINS_SSE_SQRT_PD,
7591 INTRINS_SSE_SQRT_PS,
7592 INTRINS_SSE_RSQRT_PS,
7594 INTRINS_SSE_CVTTPD2DQ,
7595 INTRINS_SSE_CVTTPS2DQ,
7596 INTRINS_SSE_CVTDQ2PD,
7597 INTRINS_SSE_CVTDQ2PS,
7598 INTRINS_SSE_CVTPD2DQ,
7599 INTRINS_SSE_CVTPS2DQ,
7600 INTRINS_SSE_CVTPD2PS,
7601 INTRINS_SSE_CVTPS2PD,
7604 INTRINS_SSE_PACKSSWB,
7605 INTRINS_SSE_PACKUSWB,
7606 INTRINS_SSE_PACKSSDW,
7607 INTRINS_SSE_PACKUSDW,
7612 INTRINS_SSE_ADDSUBPS,
7617 INTRINS_SSE_ADDSUBPD,
7625 INTRINS_SSE_PADDUSW,
7626 INTRINS_SSE_PSUBUSW,
7634 INTRINS_SSE_PADDUSB,
7635 INTRINS_SSE_PSUBUSB,
7647 static IntrinsicDesc intrinsics[] = {
7648 {INTRINS_MEMSET, "llvm.memset.p0i8.i32"},
7649 {INTRINS_MEMCPY, "llvm.memcpy.p0i8.p0i8.i32"},
7650 {INTRINS_SADD_OVF_I32, "llvm.sadd.with.overflow.i32"},
7651 {INTRINS_UADD_OVF_I32, "llvm.uadd.with.overflow.i32"},
7652 {INTRINS_SSUB_OVF_I32, "llvm.ssub.with.overflow.i32"},
7653 {INTRINS_USUB_OVF_I32, "llvm.usub.with.overflow.i32"},
7654 {INTRINS_SMUL_OVF_I32, "llvm.smul.with.overflow.i32"},
7655 {INTRINS_UMUL_OVF_I32, "llvm.umul.with.overflow.i32"},
7656 {INTRINS_SADD_OVF_I64, "llvm.sadd.with.overflow.i64"},
7657 {INTRINS_UADD_OVF_I64, "llvm.uadd.with.overflow.i64"},
7658 {INTRINS_SSUB_OVF_I64, "llvm.ssub.with.overflow.i64"},
7659 {INTRINS_USUB_OVF_I64, "llvm.usub.with.overflow.i64"},
7660 {INTRINS_SMUL_OVF_I64, "llvm.smul.with.overflow.i64"},
7661 {INTRINS_UMUL_OVF_I64, "llvm.umul.with.overflow.i64"},
7662 {INTRINS_SIN, "llvm.sin.f64"},
7663 {INTRINS_COS, "llvm.cos.f64"},
7664 {INTRINS_SQRT, "llvm.sqrt.f64"},
7665 /* This isn't an intrinsic, instead llvm seems to special case it by name */
7666 {INTRINS_FABS, "fabs"},
7667 {INTRINS_EXPECT_I8, "llvm.expect.i8"},
7668 {INTRINS_EXPECT_I1, "llvm.expect.i1"},
7669 #if defined(TARGET_AMD64) || defined(TARGET_X86)
7670 {INTRINS_SSE_PMOVMSKB, "llvm.x86.sse2.pmovmskb.128"},
7671 {INTRINS_SSE_PSRLI_W, "llvm.x86.sse2.psrli.w"},
7672 {INTRINS_SSE_PSRAI_W, "llvm.x86.sse2.psrai.w"},
7673 {INTRINS_SSE_PSLLI_W, "llvm.x86.sse2.pslli.w"},
7674 {INTRINS_SSE_PSRLI_D, "llvm.x86.sse2.psrli.d"},
7675 {INTRINS_SSE_PSRAI_D, "llvm.x86.sse2.psrai.d"},
7676 {INTRINS_SSE_PSLLI_D, "llvm.x86.sse2.pslli.d"},
7677 {INTRINS_SSE_PSRLI_Q, "llvm.x86.sse2.psrli.q"},
7678 {INTRINS_SSE_PSLLI_Q, "llvm.x86.sse2.pslli.q"},
7679 {INTRINS_SSE_SQRT_PD, "llvm.x86.sse2.sqrt.pd"},
7680 {INTRINS_SSE_SQRT_PS, "llvm.x86.sse.sqrt.ps"},
7681 {INTRINS_SSE_RSQRT_PS, "llvm.x86.sse.rsqrt.ps"},
7682 {INTRINS_SSE_RCP_PS, "llvm.x86.sse.rcp.ps"},
7683 {INTRINS_SSE_CVTTPD2DQ, "llvm.x86.sse2.cvttpd2dq"},
7684 {INTRINS_SSE_CVTTPS2DQ, "llvm.x86.sse2.cvttps2dq"},
7685 {INTRINS_SSE_CVTDQ2PD, "llvm.x86.sse2.cvtdq2pd"},
7686 {INTRINS_SSE_CVTDQ2PS, "llvm.x86.sse2.cvtdq2ps"},
7687 {INTRINS_SSE_CVTPD2DQ, "llvm.x86.sse2.cvtpd2dq"},
7688 {INTRINS_SSE_CVTPS2DQ, "llvm.x86.sse2.cvtps2dq"},
7689 {INTRINS_SSE_CVTPD2PS, "llvm.x86.sse2.cvtpd2ps"},
7690 {INTRINS_SSE_CVTPS2PD, "llvm.x86.sse2.cvtps2pd"},
7691 {INTRINS_SSE_CMPPD, "llvm.x86.sse2.cmp.pd"},
7692 {INTRINS_SSE_CMPPS, "llvm.x86.sse.cmp.ps"},
7693 {INTRINS_SSE_PACKSSWB, "llvm.x86.sse2.packsswb.128"},
7694 {INTRINS_SSE_PACKUSWB, "llvm.x86.sse2.packuswb.128"},
7695 {INTRINS_SSE_PACKSSDW, "llvm.x86.sse2.packssdw.128"},
7696 {INTRINS_SSE_PACKUSDW, "llvm.x86.sse41.packusdw"},
7697 {INTRINS_SSE_MINPS, "llvm.x86.sse.min.ps"},
7698 {INTRINS_SSE_MAXPS, "llvm.x86.sse.max.ps"},
7699 {INTRINS_SSE_HADDPS, "llvm.x86.sse3.hadd.ps"},
7700 {INTRINS_SSE_HSUBPS, "llvm.x86.sse3.hsub.ps"},
7701 {INTRINS_SSE_ADDSUBPS, "llvm.x86.sse3.addsub.ps"},
7702 {INTRINS_SSE_MINPD, "llvm.x86.sse2.min.pd"},
7703 {INTRINS_SSE_MAXPD, "llvm.x86.sse2.max.pd"},
7704 {INTRINS_SSE_HADDPD, "llvm.x86.sse3.hadd.pd"},
7705 {INTRINS_SSE_HSUBPD, "llvm.x86.sse3.hsub.pd"},
7706 {INTRINS_SSE_ADDSUBPD, "llvm.x86.sse3.addsub.pd"},
7707 {INTRINS_SSE_PMINUD, "llvm.x86.sse41.pminud"},
7708 {INTRINS_SSE_PMAXUD, "llvm.x86.sse41.pmaxud"},
7709 {INTRINS_SSE_PMINUW, "llvm.x86.sse41.pminuw"},
7710 {INTRINS_SSE_PMINSW, "llvm.x86.sse2.pmins.w"},
7711 {INTRINS_SSE_PMAXUW, "llvm.x86.sse41.pmaxuw"},
7712 {INTRINS_SSE_PADDSW, "llvm.x86.sse2.padds.w"},
7713 {INTRINS_SSE_PSUBSW, "llvm.x86.sse2.psubs.w"},
7714 {INTRINS_SSE_PADDUSW, "llvm.x86.sse2.paddus.w"},
7715 {INTRINS_SSE_PSUBUSW, "llvm.x86.sse2.psubus.w"},
7716 {INTRINS_SSE_PAVGW, "llvm.x86.sse2.pavg.w"},
7717 {INTRINS_SSE_PMULHW, "llvm.x86.sse2.pmulh.w"},
7718 {INTRINS_SSE_PMULHU, "llvm.x86.sse2.pmulhu.w"},
7719 {INTRINS_SSE_PMINUB, "llvm.x86.sse2.pminu.b"},
7720 {INTRINS_SSE_PMAXUB, "llvm.x86.sse2.pmaxu.b"},
7721 {INTRINS_SE_PADDSB, "llvm.x86.sse2.padds.b"},
7722 {INTRINS_SSE_PSUBSB, "llvm.x86.sse2.psubs.b"},
7723 {INTRINS_SSE_PADDUSB, "llvm.x86.sse2.paddus.b"},
7724 {INTRINS_SSE_PSUBUSB, "llvm.x86.sse2.psubus.b"},
7725 {INTRINS_SSE_PAVGB, "llvm.x86.sse2.pavg.b"},
7726 {INTRINS_SSE_PAUSE, "llvm.x86.sse2.pause"}
7731 add_sse_binary (LLVMModuleRef module, const char *name, int type)
7733 LLVMTypeRef ret_type = type_to_simd_type (type);
7734 AddFunc2 (module, name, ret_type, ret_type, ret_type);
7738 add_intrinsic (LLVMModuleRef module, int id)
7741 LLVMTypeRef ret_type, arg_types [16];
7743 name = g_hash_table_lookup (intrins_id_to_name, GINT_TO_POINTER (id));
7747 case INTRINS_MEMSET: {
7748 LLVMTypeRef params [] = { LLVMPointerType (LLVMInt8Type (), 0), LLVMInt8Type (), LLVMInt32Type (), LLVMInt32Type (), LLVMInt1Type () };
7750 AddFunc (module, name, LLVMVoidType (), params, 5);
7753 case INTRINS_MEMCPY: {
7754 LLVMTypeRef params [] = { LLVMPointerType (LLVMInt8Type (), 0), LLVMPointerType (LLVMInt8Type (), 0), LLVMInt32Type (), LLVMInt32Type (), LLVMInt1Type () };
7756 AddFunc (module, name, LLVMVoidType (), params, 5);
7759 case INTRINS_SADD_OVF_I32:
7760 case INTRINS_UADD_OVF_I32:
7761 case INTRINS_SSUB_OVF_I32:
7762 case INTRINS_USUB_OVF_I32:
7763 case INTRINS_SMUL_OVF_I32:
7764 case INTRINS_UMUL_OVF_I32: {
7765 LLVMTypeRef ovf_res_i32 [] = { LLVMInt32Type (), LLVMInt1Type () };
7766 LLVMTypeRef params [] = { LLVMInt32Type (), LLVMInt32Type () };
7767 LLVMTypeRef ret_type = LLVMStructType (ovf_res_i32, 2, FALSE);
7769 AddFunc (module, name, ret_type, params, 2);
7772 case INTRINS_SADD_OVF_I64:
7773 case INTRINS_UADD_OVF_I64:
7774 case INTRINS_SSUB_OVF_I64:
7775 case INTRINS_USUB_OVF_I64:
7776 case INTRINS_SMUL_OVF_I64:
7777 case INTRINS_UMUL_OVF_I64: {
7778 LLVMTypeRef ovf_res_i64 [] = { LLVMInt64Type (), LLVMInt1Type () };
7779 LLVMTypeRef params [] = { LLVMInt64Type (), LLVMInt64Type () };
7780 LLVMTypeRef ret_type = LLVMStructType (ovf_res_i64, 2, FALSE);
7782 AddFunc (module, name, ret_type, params, 2);
7788 case INTRINS_FABS: {
7789 LLVMTypeRef params [] = { LLVMDoubleType () };
7791 AddFunc (module, name, LLVMDoubleType (), params, 1);
7794 case INTRINS_EXPECT_I8:
7795 AddFunc2 (module, name, LLVMInt8Type (), LLVMInt8Type (), LLVMInt8Type ());
7797 case INTRINS_EXPECT_I1:
7798 AddFunc2 (module, name, LLVMInt1Type (), LLVMInt1Type (), LLVMInt1Type ());
7800 #if defined(TARGET_AMD64) || defined(TARGET_X86)
7801 case INTRINS_SSE_PMOVMSKB:
7803 ret_type = LLVMInt32Type ();
7804 arg_types [0] = type_to_simd_type (MONO_TYPE_I1);
7805 AddFunc (module, name, ret_type, arg_types, 1);
7807 case INTRINS_SSE_PSRLI_W:
7808 case INTRINS_SSE_PSRAI_W:
7809 case INTRINS_SSE_PSLLI_W:
7811 ret_type = type_to_simd_type (MONO_TYPE_I2);
7812 arg_types [0] = ret_type;
7813 arg_types [1] = LLVMInt32Type ();
7814 AddFunc (module, name, ret_type, arg_types, 2);
7816 case INTRINS_SSE_PSRLI_D:
7817 case INTRINS_SSE_PSRAI_D:
7818 case INTRINS_SSE_PSLLI_D:
7819 ret_type = type_to_simd_type (MONO_TYPE_I4);
7820 arg_types [0] = ret_type;
7821 arg_types [1] = LLVMInt32Type ();
7822 AddFunc (module, name, ret_type, arg_types, 2);
7824 case INTRINS_SSE_PSRLI_Q:
7825 case INTRINS_SSE_PSLLI_Q:
7826 ret_type = type_to_simd_type (MONO_TYPE_I8);
7827 arg_types [0] = ret_type;
7828 arg_types [1] = LLVMInt32Type ();
7829 AddFunc (module, name, ret_type, arg_types, 2);
7831 case INTRINS_SSE_SQRT_PD:
7833 ret_type = type_to_simd_type (MONO_TYPE_R8);
7834 arg_types [0] = ret_type;
7835 AddFunc (module, name, ret_type, arg_types, 1);
7837 case INTRINS_SSE_SQRT_PS:
7838 ret_type = type_to_simd_type (MONO_TYPE_R4);
7839 arg_types [0] = ret_type;
7840 AddFunc (module, name, ret_type, arg_types, 1);
7842 case INTRINS_SSE_RSQRT_PS:
7843 ret_type = type_to_simd_type (MONO_TYPE_R4);
7844 arg_types [0] = ret_type;
7845 AddFunc (module, name, ret_type, arg_types, 1);
7847 case INTRINS_SSE_RCP_PS:
7848 ret_type = type_to_simd_type (MONO_TYPE_R4);
7849 arg_types [0] = ret_type;
7850 AddFunc (module, name, ret_type, arg_types, 1);
7852 case INTRINS_SSE_CVTTPD2DQ:
7853 ret_type = type_to_simd_type (MONO_TYPE_I4);
7854 arg_types [0] = type_to_simd_type (MONO_TYPE_R8);
7855 AddFunc (module, name, ret_type, arg_types, 1);
7857 case INTRINS_SSE_CVTTPS2DQ:
7858 ret_type = type_to_simd_type (MONO_TYPE_I4);
7859 arg_types [0] = type_to_simd_type (MONO_TYPE_R4);
7860 AddFunc (module, name, ret_type, arg_types, 1);
7862 case INTRINS_SSE_CVTDQ2PD:
7863 /* Conversion ops */
7864 ret_type = type_to_simd_type (MONO_TYPE_R8);
7865 arg_types [0] = type_to_simd_type (MONO_TYPE_I4);
7866 AddFunc (module, name, ret_type, arg_types, 1);
7868 case INTRINS_SSE_CVTDQ2PS:
7869 ret_type = type_to_simd_type (MONO_TYPE_R4);
7870 arg_types [0] = type_to_simd_type (MONO_TYPE_I4);
7871 AddFunc (module, name, ret_type, arg_types, 1);
7873 case INTRINS_SSE_CVTPD2DQ:
7874 ret_type = type_to_simd_type (MONO_TYPE_I4);
7875 arg_types [0] = type_to_simd_type (MONO_TYPE_R8);
7876 AddFunc (module, name, ret_type, arg_types, 1);
7878 case INTRINS_SSE_CVTPS2DQ:
7879 ret_type = type_to_simd_type (MONO_TYPE_I4);
7880 arg_types [0] = type_to_simd_type (MONO_TYPE_R4);
7881 AddFunc (module, name, ret_type, arg_types, 1);
7883 case INTRINS_SSE_CVTPD2PS:
7884 ret_type = type_to_simd_type (MONO_TYPE_R4);
7885 arg_types [0] = type_to_simd_type (MONO_TYPE_R8);
7886 AddFunc (module, name, ret_type, arg_types, 1);
7888 case INTRINS_SSE_CVTPS2PD:
7889 ret_type = type_to_simd_type (MONO_TYPE_R8);
7890 arg_types [0] = type_to_simd_type (MONO_TYPE_R4);
7891 AddFunc (module, name, ret_type, arg_types, 1);
7893 case INTRINS_SSE_CMPPD:
7895 ret_type = type_to_simd_type (MONO_TYPE_R8);
7896 arg_types [0] = ret_type;
7897 arg_types [1] = ret_type;
7898 arg_types [2] = LLVMInt8Type ();
7899 AddFunc (module, name, ret_type, arg_types, 3);
7901 case INTRINS_SSE_CMPPS:
7902 ret_type = type_to_simd_type (MONO_TYPE_R4);
7903 arg_types [0] = ret_type;
7904 arg_types [1] = ret_type;
7905 arg_types [2] = LLVMInt8Type ();
7906 AddFunc (module, name, ret_type, arg_types, 3);
7908 case INTRINS_SSE_PACKSSWB:
7909 case INTRINS_SSE_PACKUSWB:
7910 case INTRINS_SSE_PACKSSDW:
7912 ret_type = type_to_simd_type (MONO_TYPE_I1);
7913 arg_types [0] = type_to_simd_type (MONO_TYPE_I2);
7914 arg_types [1] = type_to_simd_type (MONO_TYPE_I2);
7915 AddFunc (module, name, ret_type, arg_types, 2);
7917 case INTRINS_SSE_PACKUSDW:
7918 ret_type = type_to_simd_type (MONO_TYPE_I2);
7919 arg_types [0] = type_to_simd_type (MONO_TYPE_I4);
7920 arg_types [1] = type_to_simd_type (MONO_TYPE_I4);
7921 AddFunc (module, name, ret_type, arg_types, 2);
7923 /* SSE Binary ops */
7924 case INTRINS_SSE_PMINUD:
7925 case INTRINS_SSE_PMAXUD:
7926 add_sse_binary (module, name, MONO_TYPE_I4);
7928 case INTRINS_SSE_PMINUW:
7929 case INTRINS_SSE_PMINSW:
7930 case INTRINS_SSE_PMAXUW:
7931 case INTRINS_SSE_PADDSW:
7932 case INTRINS_SSE_PSUBSW:
7933 case INTRINS_SSE_PADDUSW:
7934 case INTRINS_SSE_PSUBUSW:
7935 case INTRINS_SSE_PAVGW:
7936 case INTRINS_SSE_PMULHW:
7937 case INTRINS_SSE_PMULHU:
7938 add_sse_binary (module, name, MONO_TYPE_I2);
7940 case INTRINS_SSE_MINPS:
7941 case INTRINS_SSE_MAXPS:
7942 case INTRINS_SSE_HADDPS:
7943 case INTRINS_SSE_HSUBPS:
7944 case INTRINS_SSE_ADDSUBPS:
7945 add_sse_binary (module, name, MONO_TYPE_R4);
7947 case INTRINS_SSE_MINPD:
7948 case INTRINS_SSE_MAXPD:
7949 case INTRINS_SSE_HADDPD:
7950 case INTRINS_SSE_HSUBPD:
7951 case INTRINS_SSE_ADDSUBPD:
7952 add_sse_binary (module, name, MONO_TYPE_R8);
7954 case INTRINS_SSE_PMINUB:
7955 case INTRINS_SSE_PMAXUB:
7956 case INTRINS_SE_PADDSB:
7957 case INTRINS_SSE_PSUBSB:
7958 case INTRINS_SSE_PADDUSB:
7959 case INTRINS_SSE_PSUBUSB:
7960 case INTRINS_SSE_PAVGB:
7961 add_sse_binary (module, name, MONO_TYPE_I1);
7963 case INTRINS_SSE_PAUSE:
7964 AddFunc (module, "llvm.x86.sse2.pause", LLVMVoidType (), NULL, 0);
7968 g_assert_not_reached ();
7974 get_intrinsic (EmitContext *ctx, const char *name)
7976 #if LLVM_API_VERSION > 100
7980 * Every method is emitted into its own module so
7981 * we can add intrinsics on demand.
7983 res = LLVMGetNamedFunction (ctx->lmodule, name);
7987 /* No locking needed */
7988 id = GPOINTER_TO_INT (g_hash_table_lookup (intrins_name_to_id, name));
7991 printf ("%s\n", name);
7992 g_assert (id != -1);
7993 add_intrinsic (ctx->lmodule, id);
7994 res = LLVMGetNamedFunction (ctx->lmodule, name);
8002 res = LLVMGetNamedFunction (ctx->lmodule, name);
8009 add_intrinsics (LLVMModuleRef module)
8013 /* Emit declarations of instrinsics */
8015 * It would be nicer to emit only the intrinsics actually used, but LLVM's Module
8016 * type doesn't seem to do any locking.
8018 for (i = 0; i < INTRINS_NUM; ++i)
8019 add_intrinsic (module, i);
8023 AddFunc (module, "mono_personality", LLVMVoidType (), NULL, 0);
8025 AddFunc (module, "llvm_resume_unwind_trampoline", LLVMVoidType (), NULL, 0);
8028 /* SSE intrinsics */
8029 #if defined(TARGET_X86) || defined(TARGET_AMD64)
8033 /* Load/Store intrinsics */
8035 LLVMTypeRef arg_types [5];
8039 for (i = 1; i <= 8; i *= 2) {
8040 arg_types [0] = LLVMPointerType (LLVMIntType (i * 8), 0);
8041 arg_types [1] = LLVMInt32Type ();
8042 arg_types [2] = LLVMInt1Type ();
8043 arg_types [3] = LLVMInt32Type ();
8044 sprintf (name, "llvm.mono.load.i%d.p0i%d", i * 8, i * 8);
8045 AddFunc (module, name, LLVMIntType (i * 8), arg_types, 4);
8047 arg_types [0] = LLVMIntType (i * 8);
8048 arg_types [1] = LLVMPointerType (LLVMIntType (i * 8), 0);
8049 arg_types [2] = LLVMInt32Type ();
8050 arg_types [3] = LLVMInt1Type ();
8051 arg_types [4] = LLVMInt32Type ();
8052 sprintf (name, "llvm.mono.store.i%d.p0i%d", i * 8, i * 8);
8053 AddFunc (module, name, LLVMVoidType (), arg_types, 5);
8059 add_types (MonoLLVMModule *module)
8061 module->ptr_type = LLVMPointerType (sizeof (gpointer) == 8 ? LLVMInt64Type () : LLVMInt32Type (), 0);
8065 mono_llvm_init (void)
8070 mono_native_tls_alloc (¤t_cfg_tls_id, NULL);
8072 h = g_hash_table_new (NULL, NULL);
8073 for (i = 0; i < INTRINS_NUM; ++i)
8074 g_hash_table_insert (h, GINT_TO_POINTER (intrinsics [i].id), (gpointer)intrinsics [i].name);
8075 intrins_id_to_name = h;
8077 h = g_hash_table_new (g_str_hash, g_str_equal);
8078 for (i = 0; i < INTRINS_NUM; ++i)
8079 g_hash_table_insert (h, (gpointer)intrinsics [i].name, GINT_TO_POINTER (intrinsics [i].id + 1));
8080 intrins_name_to_id = h;
8084 init_jit_module (MonoDomain *domain)
8086 MonoJitDomainInfo *dinfo;
8087 MonoLLVMModule *module;
8090 dinfo = domain_jit_info (domain);
8091 if (dinfo->llvm_module)
8094 mono_loader_lock ();
8096 if (dinfo->llvm_module) {
8097 mono_loader_unlock ();
8101 module = g_new0 (MonoLLVMModule, 1);
8103 name = g_strdup_printf ("mono-%s", domain->friendly_name);
8104 module->lmodule = LLVMModuleCreateWithName (name);
8105 module->context = LLVMGetGlobalContext ();
8107 module->mono_ee = (MonoEERef*)mono_llvm_create_ee (LLVMCreateModuleProviderForExistingModule (module->lmodule), alloc_cb, emitted_cb, exception_cb, dlsym_cb, &module->ee);
8109 add_intrinsics (module->lmodule);
8112 module->llvm_types = g_hash_table_new (NULL, NULL);
8114 #if LLVM_API_VERSION < 100
8115 MonoJitICallInfo *info;
8117 info = mono_find_jit_icall_by_name ("llvm_resume_unwind_trampoline");
8119 LLVMAddGlobalMapping (module->ee, LLVMGetNamedFunction (module->lmodule, "llvm_resume_unwind_trampoline"), (void*)info->func);
8122 mono_memory_barrier ();
8124 dinfo->llvm_module = module;
8126 mono_loader_unlock ();
8130 mono_llvm_cleanup (void)
8132 MonoLLVMModule *module = &aot_module;
8134 if (module->lmodule)
8135 LLVMDisposeModule (module->lmodule);
8137 if (module->context)
8138 LLVMContextDispose (module->context);
8142 mono_llvm_free_domain_info (MonoDomain *domain)
8144 MonoJitDomainInfo *info = domain_jit_info (domain);
8145 MonoLLVMModule *module = (MonoLLVMModule*)info->llvm_module;
8151 if (module->llvm_types)
8152 g_hash_table_destroy (module->llvm_types);
8154 mono_llvm_dispose_ee (module->mono_ee);
8156 if (module->bb_names) {
8157 for (i = 0; i < module->bb_names_len; ++i)
8158 g_free (module->bb_names [i]);
8159 g_free (module->bb_names);
8161 //LLVMDisposeModule (module->module);
8165 info->llvm_module = NULL;
8169 mono_llvm_create_aot_module (MonoAssembly *assembly, const char *global_prefix, gboolean emit_dwarf, gboolean static_link, gboolean llvm_only)
8171 MonoLLVMModule *module = &aot_module;
8173 /* Delete previous module */
8174 if (module->plt_entries)
8175 g_hash_table_destroy (module->plt_entries);
8176 if (module->lmodule)
8177 LLVMDisposeModule (module->lmodule);
8179 memset (module, 0, sizeof (aot_module));
8181 module->lmodule = LLVMModuleCreateWithName ("aot");
8182 module->assembly = assembly;
8183 module->global_prefix = g_strdup (global_prefix);
8184 module->got_symbol = g_strdup_printf ("%s_llvm_got", global_prefix);
8185 module->eh_frame_symbol = g_strdup_printf ("%s_eh_frame", global_prefix);
8186 module->get_method_symbol = g_strdup_printf ("%s_get_method", global_prefix);
8187 module->get_unbox_tramp_symbol = g_strdup_printf ("%s_get_unbox_tramp", global_prefix);
8188 module->external_symbols = TRUE;
8189 module->emit_dwarf = emit_dwarf;
8190 module->static_link = static_link;
8191 module->llvm_only = llvm_only;
8192 /* The first few entries are reserved */
8193 module->max_got_offset = 16;
8194 module->context = LLVMContextCreate ();
8197 /* clang ignores our debug info because it has an invalid version */
8198 module->emit_dwarf = FALSE;
8200 #if LLVM_API_VERSION > 100
8201 module->emit_dwarf = FALSE;
8204 add_intrinsics (module->lmodule);
8207 #if LLVM_API_VERSION > 100
8208 if (module->emit_dwarf) {
8209 char *dir, *build_info, *s, *cu_name;
8211 module->di_builder = mono_llvm_create_di_builder (module->lmodule);
8214 dir = g_strdup (".");
8215 build_info = mono_get_runtime_build_info ();
8216 s = g_strdup_printf ("Mono AOT Compiler %s (LLVM)", build_info);
8217 cu_name = g_path_get_basename (assembly->image->name);
8218 module->cu = mono_llvm_di_create_compile_unit (module->di_builder, cu_name, dir, s);
8220 g_free (build_info);
8227 * We couldn't compute the type of the LLVM global representing the got because
8228 * its size is only known after all the methods have been emitted. So create
8229 * a dummy variable, and replace all uses it with the real got variable when
8230 * its size is known in mono_llvm_emit_aot_module ().
8233 LLVMTypeRef got_type = LLVMArrayType (module->ptr_type, 0);
8235 module->got_var = LLVMAddGlobal (module->lmodule, got_type, "mono_dummy_got");
8236 LLVMSetInitializer (module->got_var, LLVMConstNull (got_type));
8239 /* Add initialization array */
8241 LLVMTypeRef inited_type = LLVMArrayType (LLVMInt8Type (), 0);
8243 module->inited_var = LLVMAddGlobal (aot_module.lmodule, inited_type, "mono_inited_tmp");
8244 LLVMSetInitializer (module->inited_var, LLVMConstNull (inited_type));
8248 emit_init_icall_wrappers (module);
8250 emit_llvm_code_start (module);
8252 /* Add a dummy personality function */
8253 if (!use_debug_personality) {
8254 LLVMValueRef personality = LLVMAddFunction (module->lmodule, default_personality_name, LLVMFunctionType (LLVMInt32Type (), NULL, 0, TRUE));
8255 LLVMSetLinkage (personality, LLVMExternalLinkage);
8256 mark_as_used (module, personality);
8259 /* Add a reference to the c++ exception we throw/catch */
8261 LLVMTypeRef exc = LLVMPointerType (LLVMInt8Type (), 0);
8262 module->sentinel_exception = LLVMAddGlobal (module->lmodule, exc, "_ZTIPi");
8263 LLVMSetLinkage (module->sentinel_exception, LLVMExternalLinkage);
8264 mono_llvm_set_is_constant (module->sentinel_exception);
8267 module->llvm_types = g_hash_table_new (NULL, NULL);
8268 module->plt_entries = g_hash_table_new (g_str_hash, g_str_equal);
8269 module->plt_entries_ji = g_hash_table_new (NULL, NULL);
8270 module->direct_callables = g_hash_table_new (g_str_hash, g_str_equal);
8271 module->method_to_lmethod = g_hash_table_new (NULL, NULL);
8272 module->idx_to_lmethod = g_hash_table_new (NULL, NULL);
8273 module->idx_to_unbox_tramp = g_hash_table_new (NULL, NULL);
8274 module->method_to_callers = g_hash_table_new (NULL, NULL);
8278 llvm_array_from_uints (LLVMTypeRef el_type, guint32 *values, int nvalues)
8281 LLVMValueRef res, *vals;
8283 vals = g_new0 (LLVMValueRef, nvalues);
8284 for (i = 0; i < nvalues; ++i)
8285 vals [i] = LLVMConstInt (LLVMInt32Type (), values [i], FALSE);
8286 res = LLVMConstArray (LLVMInt32Type (), vals, nvalues);
8292 * mono_llvm_emit_aot_file_info:
8294 * Emit the MonoAotFileInfo structure.
8295 * Same as emit_aot_file_info () in aot-compiler.c.
8298 mono_llvm_emit_aot_file_info (MonoAotFileInfo *info, gboolean has_jitted_code)
8300 MonoLLVMModule *module = &aot_module;
8302 /* Save these for later */
8303 memcpy (&module->aot_info, info, sizeof (MonoAotFileInfo));
8304 module->has_jitted_code = has_jitted_code;
8308 * mono_llvm_emit_aot_data:
8310 * Emit the binary data DATA pointed to by symbol SYMBOL.
8313 mono_llvm_emit_aot_data (const char *symbol, guint8 *data, int data_len)
8315 MonoLLVMModule *module = &aot_module;
8319 type = LLVMArrayType (LLVMInt8Type (), data_len);
8320 d = LLVMAddGlobal (module->lmodule, type, symbol);
8321 LLVMSetVisibility (d, LLVMHiddenVisibility);
8322 LLVMSetLinkage (d, LLVMInternalLinkage);
8323 LLVMSetInitializer (d, mono_llvm_create_constant_data_array (data, data_len));
8324 mono_llvm_set_is_constant (d);
8327 /* Add a reference to a global defined in JITted code */
8329 AddJitGlobal (MonoLLVMModule *module, LLVMTypeRef type, const char *name)
8334 s = g_strdup_printf ("%s%s", module->global_prefix, name);
8335 v = LLVMAddGlobal (module->lmodule, LLVMInt8Type (), s);
8341 emit_aot_file_info (MonoLLVMModule *module)
8343 LLVMTypeRef file_info_type;
8344 LLVMTypeRef *eltypes, eltype;
8345 LLVMValueRef info_var;
8346 LLVMValueRef *fields;
8347 int i, nfields, tindex;
8348 MonoAotFileInfo *info;
8349 LLVMModuleRef lmodule = module->lmodule;
8351 info = &module->aot_info;
8353 /* Create an LLVM type to represent MonoAotFileInfo */
8354 nfields = 2 + MONO_AOT_FILE_INFO_NUM_SYMBOLS + 15 + 5;
8355 eltypes = g_new (LLVMTypeRef, nfields);
8357 eltypes [tindex ++] = LLVMInt32Type ();
8358 eltypes [tindex ++] = LLVMInt32Type ();
8360 for (i = 0; i < MONO_AOT_FILE_INFO_NUM_SYMBOLS; ++i)
8361 eltypes [tindex ++] = LLVMPointerType (LLVMInt8Type (), 0);
8363 for (i = 0; i < 15; ++i)
8364 eltypes [tindex ++] = LLVMInt32Type ();
8366 eltypes [tindex ++] = LLVMArrayType (LLVMInt32Type (), MONO_AOT_TABLE_NUM);
8367 for (i = 0; i < 4; ++i)
8368 eltypes [tindex ++] = LLVMArrayType (LLVMInt32Type (), MONO_AOT_TRAMP_NUM);
8369 g_assert (tindex == nfields);
8370 file_info_type = LLVMStructCreateNamed (module->context, "MonoAotFileInfo");
8371 LLVMStructSetBody (file_info_type, eltypes, nfields, FALSE);
8373 info_var = LLVMAddGlobal (lmodule, file_info_type, "mono_aot_file_info");
8374 if (module->static_link) {
8375 LLVMSetVisibility (info_var, LLVMHiddenVisibility);
8376 LLVMSetLinkage (info_var, LLVMInternalLinkage);
8378 fields = g_new (LLVMValueRef, nfields);
8380 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->version, FALSE);
8381 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->dummy, FALSE);
8385 * We use LLVMGetNamedGlobal () for symbol which are defined in LLVM code, and LLVMAddGlobal ()
8386 * for symbols defined in the .s file emitted by the aot compiler.
8388 eltype = eltypes [tindex];
8389 if (module->llvm_only)
8390 fields [tindex ++] = LLVMConstNull (eltype);
8392 fields [tindex ++] = AddJitGlobal (module, eltype, "jit_got");
8393 fields [tindex ++] = module->got_var;
8394 /* llc defines this directly */
8395 if (!module->llvm_only) {
8396 fields [tindex ++] = LLVMAddGlobal (lmodule, eltype, module->eh_frame_symbol);
8397 fields [tindex ++] = LLVMConstNull (eltype);
8398 fields [tindex ++] = LLVMConstNull (eltype);
8400 fields [tindex ++] = LLVMConstNull (eltype);
8401 fields [tindex ++] = module->get_method;
8402 fields [tindex ++] = module->get_unbox_tramp;
8404 if (module->has_jitted_code) {
8405 fields [tindex ++] = AddJitGlobal (module, eltype, "jit_code_start");
8406 fields [tindex ++] = AddJitGlobal (module, eltype, "jit_code_end");
8408 fields [tindex ++] = LLVMConstNull (eltype);
8409 fields [tindex ++] = LLVMConstNull (eltype);
8411 if (!module->llvm_only)
8412 fields [tindex ++] = AddJitGlobal (module, eltype, "method_addresses");
8414 fields [tindex ++] = LLVMConstNull (eltype);
8415 if (info->flags & MONO_AOT_FILE_FLAG_SEPARATE_DATA) {
8416 for (i = 0; i < MONO_AOT_TABLE_NUM; ++i)
8417 fields [tindex ++] = LLVMConstNull (eltype);
8419 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "blob");
8420 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "class_name_table");
8421 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "class_info_offsets");
8422 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "method_info_offsets");
8423 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "ex_info_offsets");
8424 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "extra_method_info_offsets");
8425 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "extra_method_table");
8426 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "got_info_offsets");
8427 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "llvm_got_info_offsets");
8428 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "image_table");
8430 /* Not needed (mem_end) */
8431 fields [tindex ++] = LLVMConstNull (eltype);
8432 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "assembly_guid");
8433 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "runtime_version");
8434 if (info->trampoline_size [0]) {
8435 fields [tindex ++] = AddJitGlobal (module, eltype, "specific_trampolines");
8436 fields [tindex ++] = AddJitGlobal (module, eltype, "static_rgctx_trampolines");
8437 fields [tindex ++] = AddJitGlobal (module, eltype, "imt_thunks");
8438 fields [tindex ++] = AddJitGlobal (module, eltype, "gsharedvt_arg_trampolines");
8440 fields [tindex ++] = LLVMConstNull (eltype);
8441 fields [tindex ++] = LLVMConstNull (eltype);
8442 fields [tindex ++] = LLVMConstNull (eltype);
8443 fields [tindex ++] = LLVMConstNull (eltype);
8445 if (module->static_link && !module->llvm_only)
8446 fields [tindex ++] = AddJitGlobal (module, eltype, "globals");
8448 fields [tindex ++] = LLVMConstNull (eltype);
8449 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "assembly_name");
8450 if (!module->llvm_only) {
8451 fields [tindex ++] = AddJitGlobal (module, eltype, "plt");
8452 fields [tindex ++] = AddJitGlobal (module, eltype, "plt_end");
8453 fields [tindex ++] = AddJitGlobal (module, eltype, "unwind_info");
8454 fields [tindex ++] = AddJitGlobal (module, eltype, "unbox_trampolines");
8455 fields [tindex ++] = AddJitGlobal (module, eltype, "unbox_trampolines_end");
8456 fields [tindex ++] = AddJitGlobal (module, eltype, "unbox_trampoline_addresses");
8458 fields [tindex ++] = LLVMConstNull (eltype);
8459 fields [tindex ++] = LLVMConstNull (eltype);
8460 fields [tindex ++] = LLVMConstNull (eltype);
8461 fields [tindex ++] = LLVMConstNull (eltype);
8462 fields [tindex ++] = LLVMConstNull (eltype);
8463 fields [tindex ++] = LLVMConstNull (eltype);
8466 for (i = 0; i < MONO_AOT_FILE_INFO_NUM_SYMBOLS; ++i)
8467 fields [2 + i] = LLVMConstBitCast (fields [2 + i], eltype);
8470 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->plt_got_offset_base, FALSE);
8471 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->got_size, FALSE);
8472 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->plt_size, FALSE);
8473 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->nmethods, FALSE);
8474 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->flags, FALSE);
8475 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->opts, FALSE);
8476 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->simd_opts, FALSE);
8477 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->gc_name_index, FALSE);
8478 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->num_rgctx_fetch_trampolines, FALSE);
8479 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->double_align, FALSE);
8480 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->long_align, FALSE);
8481 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->generic_tramp_num, FALSE);
8482 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->tramp_page_size, FALSE);
8483 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->nshared_got_entries, FALSE);
8484 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->datafile_size, FALSE);
8486 fields [tindex ++] = llvm_array_from_uints (LLVMInt32Type (), info->table_offsets, MONO_AOT_TABLE_NUM);
8487 fields [tindex ++] = llvm_array_from_uints (LLVMInt32Type (), info->num_trampolines, MONO_AOT_TRAMP_NUM);
8488 fields [tindex ++] = llvm_array_from_uints (LLVMInt32Type (), info->trampoline_got_offset_base, MONO_AOT_TRAMP_NUM);
8489 fields [tindex ++] = llvm_array_from_uints (LLVMInt32Type (), info->trampoline_size, MONO_AOT_TRAMP_NUM);
8490 fields [tindex ++] = llvm_array_from_uints (LLVMInt32Type (), info->tramp_page_code_offsets, MONO_AOT_TRAMP_NUM);
8491 g_assert (tindex == nfields);
8493 LLVMSetInitializer (info_var, LLVMConstNamedStruct (file_info_type, fields, nfields));
8495 if (module->static_link) {
8499 s = g_strdup_printf ("mono_aot_module_%s_info", module->assembly->aname.name);
8500 /* Get rid of characters which cannot occur in symbols */
8502 for (p = s; *p; ++p) {
8503 if (!(isalnum (*p) || *p == '_'))
8506 var = LLVMAddGlobal (module->lmodule, LLVMPointerType (LLVMInt8Type (), 0), s);
8508 LLVMSetInitializer (var, LLVMConstBitCast (LLVMGetNamedGlobal (module->lmodule, "mono_aot_file_info"), LLVMPointerType (LLVMInt8Type (), 0)));
8509 LLVMSetLinkage (var, LLVMExternalLinkage);
8514 * Emit the aot module into the LLVM bitcode file FILENAME.
8517 mono_llvm_emit_aot_module (const char *filename, const char *cu_name)
8519 LLVMTypeRef got_type, inited_type;
8520 LLVMValueRef real_got, real_inited;
8521 MonoLLVMModule *module = &aot_module;
8523 emit_llvm_code_end (module);
8526 * Create the real got variable and replace all uses of the dummy variable with
8529 got_type = LLVMArrayType (module->ptr_type, module->max_got_offset + 1);
8530 real_got = LLVMAddGlobal (module->lmodule, got_type, module->got_symbol);
8531 LLVMSetInitializer (real_got, LLVMConstNull (got_type));
8532 if (module->external_symbols) {
8533 LLVMSetLinkage (real_got, LLVMExternalLinkage);
8534 LLVMSetVisibility (real_got, LLVMHiddenVisibility);
8536 LLVMSetLinkage (real_got, LLVMInternalLinkage);
8538 mono_llvm_replace_uses_of (module->got_var, real_got);
8540 mark_as_used (&aot_module, real_got);
8542 /* Delete the dummy got so it doesn't become a global */
8543 LLVMDeleteGlobal (module->got_var);
8544 module->got_var = real_got;
8547 * Same for the init_var
8549 if (module->llvm_only) {
8550 inited_type = LLVMArrayType (LLVMInt8Type (), module->max_inited_idx + 1);
8551 real_inited = LLVMAddGlobal (module->lmodule, inited_type, "mono_inited");
8552 LLVMSetInitializer (real_inited, LLVMConstNull (inited_type));
8553 LLVMSetLinkage (real_inited, LLVMInternalLinkage);
8554 mono_llvm_replace_uses_of (module->inited_var, real_inited);
8555 LLVMDeleteGlobal (module->inited_var);
8558 if (module->llvm_only) {
8559 emit_get_method (&aot_module);
8560 emit_get_unbox_tramp (&aot_module);
8563 emit_llvm_used (&aot_module);
8564 emit_dbg_info (&aot_module, filename, cu_name);
8565 emit_aot_file_info (&aot_module);
8568 * Replace GOT entries for directly callable methods with the methods themselves.
8569 * It would be easier to implement this by predefining all methods before compiling
8570 * their bodies, but that couldn't handle the case when a method fails to compile
8573 if (module->llvm_only) {
8574 GHashTableIter iter;
8576 GSList *callers, *l;
8578 g_hash_table_iter_init (&iter, module->method_to_callers);
8579 while (g_hash_table_iter_next (&iter, (void**)&method, (void**)&callers)) {
8580 LLVMValueRef lmethod;
8582 lmethod = (LLVMValueRef)g_hash_table_lookup (module->method_to_lmethod, method);
8584 for (l = callers; l; l = l->next) {
8585 LLVMValueRef caller = (LLVMValueRef)l->data;
8587 mono_llvm_replace_uses_of (caller, lmethod);
8593 /* Replace PLT entries for directly callable methods with the methods themselves */
8595 GHashTableIter iter;
8597 LLVMValueRef callee;
8599 g_hash_table_iter_init (&iter, module->plt_entries_ji);
8600 while (g_hash_table_iter_next (&iter, (void**)&ji, (void**)&callee)) {
8601 if (mono_aot_is_direct_callable (ji)) {
8602 LLVMValueRef lmethod;
8604 lmethod = (LLVMValueRef)g_hash_table_lookup (module->method_to_lmethod, ji->data.method);
8605 /* The types might not match because the caller might pass an rgctx */
8606 if (lmethod && LLVMTypeOf (callee) == LLVMTypeOf (lmethod)) {
8607 mono_llvm_replace_uses_of (callee, lmethod);
8608 mono_aot_mark_unused_llvm_plt_entry (ji);
8618 if (LLVMVerifyModule (module->lmodule, LLVMReturnStatusAction, &verifier_err)) {
8619 g_assert_not_reached ();
8624 LLVMWriteBitcodeToFile (module->lmodule, filename);
8629 md_string (const char *s)
8631 return LLVMMDString (s, strlen (s));
8634 /* Debugging support */
8637 emit_dbg_info (MonoLLVMModule *module, const char *filename, const char *cu_name)
8639 LLVMModuleRef lmodule = module->lmodule;
8640 LLVMValueRef args [16], ver;
8643 * This can only be enabled when LLVM code is emitted into a separate object
8644 * file, since the AOT compiler also emits dwarf info,
8645 * and the abbrev indexes will not be correct since llvm has added its own
8648 if (!module->emit_dwarf)
8651 #if LLVM_API_VERSION > 100
8652 mono_llvm_di_builder_finalize (module->di_builder);
8654 LLVMValueRef cu_args [16], cu;
8656 char *build_info, *s, *dir;
8659 * Emit dwarf info in the form of LLVM metadata. There is some
8660 * out-of-date documentation at:
8661 * http://llvm.org/docs/SourceLevelDebugging.html
8662 * but most of this was gathered from the llvm and
8667 cu_args [n_cuargs ++] = LLVMConstInt (LLVMInt32Type (), DW_TAG_compile_unit, FALSE);
8668 /* CU name/compilation dir */
8669 dir = g_path_get_dirname (filename);
8670 args [0] = LLVMMDString (cu_name, strlen (cu_name));
8671 args [1] = LLVMMDString (dir, strlen (dir));
8672 cu_args [n_cuargs ++] = LLVMMDNode (args, 2);
8675 cu_args [n_cuargs ++] = LLVMConstInt (LLVMInt32Type (), DW_LANG_C99, FALSE);
8677 build_info = mono_get_runtime_build_info ();
8678 s = g_strdup_printf ("Mono AOT Compiler %s (LLVM)", build_info);
8679 cu_args [n_cuargs ++] = LLVMMDString (s, strlen (s));
8680 g_free (build_info);
8682 cu_args [n_cuargs ++] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
8684 cu_args [n_cuargs ++] = LLVMMDString ("", strlen (""));
8685 /* Runtime version */
8686 cu_args [n_cuargs ++] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
8688 cu_args [n_cuargs ++] = LLVMMDNode (args, 0);
8689 cu_args [n_cuargs ++] = LLVMMDNode (args, 0);
8691 if (module->subprogram_mds) {
8695 mds = g_new0 (LLVMValueRef, module->subprogram_mds->len);
8696 for (i = 0; i < module->subprogram_mds->len; ++i)
8697 mds [i] = (LLVMValueRef)g_ptr_array_index (module->subprogram_mds, i);
8698 cu_args [n_cuargs ++] = LLVMMDNode (mds, module->subprogram_mds->len);
8700 cu_args [n_cuargs ++] = LLVMMDNode (args, 0);
8703 cu_args [n_cuargs ++] = LLVMMDNode (args, 0);
8704 /* Imported modules */
8705 cu_args [n_cuargs ++] = LLVMMDNode (args, 0);
8707 cu_args [n_cuargs ++] = LLVMMDString ("", strlen (""));
8708 /* DebugEmissionKind = FullDebug */
8709 cu_args [n_cuargs ++] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
8710 cu = LLVMMDNode (cu_args, n_cuargs);
8711 LLVMAddNamedMetadataOperand (lmodule, "llvm.dbg.cu", cu);
8714 #if LLVM_API_VERSION > 100
8715 args [0] = LLVMConstInt (LLVMInt32Type (), 2, FALSE);
8716 args [1] = LLVMMDString ("Dwarf Version", strlen ("Dwarf Version"));
8717 args [2] = LLVMConstInt (LLVMInt32Type (), 2, FALSE);
8718 ver = LLVMMDNode (args, 3);
8719 LLVMAddNamedMetadataOperand (lmodule, "llvm.module.flags", ver);
8721 args [0] = LLVMConstInt (LLVMInt32Type (), 2, FALSE);
8722 args [1] = LLVMMDString ("Debug Info Version", strlen ("Debug Info Version"));
8723 args [2] = LLVMConstInt (LLVMInt64Type (), 3, FALSE);
8724 ver = LLVMMDNode (args, 3);
8725 LLVMAddNamedMetadataOperand (lmodule, "llvm.module.flags", ver);
8727 args [0] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
8728 args [1] = LLVMMDString ("Dwarf Version", strlen ("Dwarf Version"));
8729 args [2] = LLVMConstInt (LLVMInt32Type (), 2, FALSE);
8730 ver = LLVMMDNode (args, 3);
8731 LLVMAddNamedMetadataOperand (lmodule, "llvm.module.flags", ver);
8733 args [0] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
8734 args [1] = LLVMMDString ("Debug Info Version", strlen ("Debug Info Version"));
8735 args [2] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
8736 ver = LLVMMDNode (args, 3);
8737 LLVMAddNamedMetadataOperand (lmodule, "llvm.module.flags", ver);
8742 emit_dbg_subprogram (EmitContext *ctx, MonoCompile *cfg, LLVMValueRef method, const char *name)
8744 MonoLLVMModule *module = ctx->module;
8745 MonoDebugMethodInfo *minfo = ctx->minfo;
8746 char *source_file, *dir, *filename;
8747 LLVMValueRef md, args [16], ctx_args [16], md_args [64], type_args [16], ctx_md, type_md;
8748 MonoSymSeqPoint *sym_seq_points;
8754 mono_debug_symfile_get_seq_points (minfo, &source_file, NULL, NULL, &sym_seq_points, &n_seq_points);
8756 source_file = g_strdup ("<unknown>");
8757 dir = g_path_get_dirname (source_file);
8758 filename = g_path_get_basename (source_file);
8760 #if LLVM_API_VERSION > 100
8761 return mono_llvm_di_create_function (module->di_builder, module->cu, cfg->method->name, name, dir, filename, n_seq_points ? sym_seq_points [0].line : 1);
8764 ctx_args [0] = LLVMConstInt (LLVMInt32Type (), 0x29, FALSE);
8765 args [0] = md_string (filename);
8766 args [1] = md_string (dir);
8767 ctx_args [1] = LLVMMDNode (args, 2);
8768 ctx_md = LLVMMDNode (ctx_args, 2);
8770 type_args [0] = LLVMConstInt (LLVMInt32Type (), DW_TAG_subroutine_type, FALSE);
8771 type_args [1] = NULL;
8772 type_args [2] = NULL;
8773 type_args [3] = LLVMMDString ("", 0);
8774 type_args [4] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
8775 type_args [5] = LLVMConstInt (LLVMInt64Type (), 0, FALSE);
8776 type_args [6] = LLVMConstInt (LLVMInt64Type (), 0, FALSE);
8777 type_args [7] = LLVMConstInt (LLVMInt64Type (), 0, FALSE);
8778 type_args [8] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
8779 type_args [9] = NULL;
8780 type_args [10] = NULL;
8781 type_args [11] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
8782 type_args [12] = NULL;
8783 type_args [13] = NULL;
8784 type_args [14] = NULL;
8785 type_md = LLVMMDNode (type_args, 14);
8787 /* http://llvm.org/docs/SourceLevelDebugging.html#subprogram-descriptors */
8788 md_args [0] = LLVMConstInt (LLVMInt32Type (), DW_TAG_subprogram, FALSE);
8789 /* Source directory + file pair */
8790 args [0] = md_string (filename);
8791 args [1] = md_string (dir);
8792 md_args [1] = LLVMMDNode (args ,2);
8793 md_args [2] = ctx_md;
8794 md_args [3] = md_string (cfg->method->name);
8795 md_args [4] = md_string (name);
8796 md_args [5] = md_string (name);
8799 md_args [6] = LLVMConstInt (LLVMInt32Type (), sym_seq_points [0].line, FALSE);
8801 md_args [6] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
8803 md_args [7] = type_md;
8805 md_args [8] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
8807 md_args [9] = LLVMConstInt (LLVMInt1Type (), 1, FALSE);
8809 md_args [10] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
8810 /* Index into a virtual function */
8811 md_args [11] = NULL;
8812 md_args [12] = NULL;
8814 md_args [13] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
8816 md_args [14] = LLVMConstInt (LLVMInt1Type (), 1, FALSE);
8817 /* Pointer to LLVM function */
8818 md_args [15] = method;
8819 /* Function template parameter */
8820 md_args [16] = NULL;
8821 /* Function declaration descriptor */
8822 md_args [17] = NULL;
8823 /* List of function variables */
8824 md_args [18] = LLVMMDNode (args, 0);
8826 md_args [19] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
8827 md = LLVMMDNode (md_args, 20);
8829 if (!module->subprogram_mds)
8830 module->subprogram_mds = g_ptr_array_new ();
8831 g_ptr_array_add (module->subprogram_mds, md);
8835 g_free (source_file);
8836 g_free (sym_seq_points);
8842 emit_dbg_loc (EmitContext *ctx, LLVMBuilderRef builder, const unsigned char *cil_code)
8844 MonoCompile *cfg = ctx->cfg;
8846 if (ctx->minfo && cil_code && cil_code >= cfg->header->code && cil_code < cfg->header->code + cfg->header->code_size) {
8847 MonoDebugSourceLocation *loc;
8848 LLVMValueRef loc_md;
8850 loc = mono_debug_symfile_lookup_location (ctx->minfo, cil_code - cfg->header->code);
8853 #if LLVM_API_VERSION > 100
8854 loc_md = mono_llvm_di_create_location (ctx->module->di_builder, ctx->dbg_md, loc->row, loc->column);
8855 mono_llvm_di_set_location (builder, loc_md);
8857 LLVMValueRef md_args [16];
8861 md_args [nmd_args ++] = LLVMConstInt (LLVMInt32Type (), loc->row, FALSE);
8862 md_args [nmd_args ++] = LLVMConstInt (LLVMInt32Type (), loc->column, FALSE);
8863 md_args [nmd_args ++] = ctx->dbg_md;
8864 md_args [nmd_args ++] = NULL;
8865 loc_md = LLVMMDNode (md_args, nmd_args);
8866 LLVMSetCurrentDebugLocation (builder, loc_md);
8868 mono_debug_symfile_free_location (loc);
8874 default_mono_llvm_unhandled_exception (void)
8876 MonoJitTlsData *jit_tls = mono_get_jit_tls ();
8877 MonoObject *target = mono_gchandle_get_target (jit_tls->thrown_exc);
8879 mono_unhandled_exception (target);
8880 exit (mono_environment_exitcode_get ());
8885 - Emit LLVM IR from the mono IR using the LLVM C API.
8886 - The original arch specific code remains, so we can fall back to it if we run
8887 into something we can't handle.
8891 A partial list of issues:
8892 - Handling of opcodes which can throw exceptions.
8894 In the mono JIT, these are implemented using code like this:
8901 push throw_pos - method
8902 call <exception trampoline>
8904 The problematic part is push throw_pos - method, which cannot be represented
8905 in the LLVM IR, since it does not support label values.
8906 -> this can be implemented in AOT mode using inline asm + labels, but cannot
8907 be implemented in JIT mode ?
8908 -> a possible but slower implementation would use the normal exception
8909 throwing code but it would need to control the placement of the throw code
8910 (it needs to be exactly after the compare+branch).
8911 -> perhaps add a PC offset intrinsics ?
8913 - efficient implementation of .ovf opcodes.
8915 These are currently implemented as:
8916 <ins which sets the condition codes>
8919 Some overflow opcodes are now supported by LLVM SVN.
8921 - exception handling, unwinding.
8922 - SSA is disabled for methods with exception handlers
8923 - How to obtain unwind info for LLVM compiled methods ?
8924 -> this is now solved by converting the unwind info generated by LLVM
8926 - LLVM uses the c++ exception handling framework, while we use our home grown
8927 code, and couldn't use the c++ one:
8928 - its not supported under VC++, other exotic platforms.
8929 - it might be impossible to support filter clauses with it.
8933 The trampolines need a predictable call sequence, since they need to disasm
8934 the calling code to obtain register numbers / offsets.
8936 LLVM currently generates this code in non-JIT mode:
8937 mov -0x98(%rax),%eax
8939 Here, the vtable pointer is lost.
8940 -> solution: use one vtable trampoline per class.
8942 - passing/receiving the IMT pointer/RGCTX.
8943 -> solution: pass them as normal arguments ?
8947 LLVM does not allow the specification of argument registers etc. This means
8948 that all calls are made according to the platform ABI.
8950 - passing/receiving vtypes.
8952 Vtypes passed/received in registers are handled by the front end by using
8953 a signature with scalar arguments, and loading the parts of the vtype into those
8956 Vtypes passed on the stack are handled using the 'byval' attribute.
8960 Supported though alloca, we need to emit the load/store code.
8964 The mono JIT uses pointer sized iregs/double fregs, while LLVM uses precisely
8965 typed registers, so we have to keep track of the precise LLVM type of each vreg.
8966 This is made easier because the IR is already in SSA form.
8967 An additional problem is that our IR is not consistent with types, i.e. i32/ia64
8968 types are frequently used incorrectly.
8973 Emit LLVM bytecode into a .bc file, compile it using llc into a .s file, then link
8974 it with the file containing the methods emitted by the JIT and the AOT data
8978 /* FIXME: Normalize some aspects of the mono IR to allow easier translation, like:
8979 * - each bblock should end with a branch
8980 * - setting the return value, making cfg->ret non-volatile
8981 * - avoid some transformations in the JIT which make it harder for us to generate
8983 * - use pointer types to help optimizations.