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 LLVMArgAsIArgs:
1286 ret_type = LLVMArrayType (IntPtrType (), cinfo->ret.nslots);
1288 case LLVMArgFpStruct: {
1289 /* Vtype returned as a fp struct */
1290 LLVMTypeRef members [16];
1292 /* Have to create our own structure since we don't map fp structures to LLVM fp structures yet */
1293 for (i = 0; i < cinfo->ret.nslots; ++i)
1294 members [i] = cinfo->ret.esize == 8 ? LLVMDoubleType () : LLVMFloatType ();
1295 ret_type = LLVMStructType (members, cinfo->ret.nslots, FALSE);
1298 case LLVMArgVtypeByRef:
1299 /* Vtype returned using a hidden argument */
1300 ret_type = LLVMVoidType ();
1302 case LLVMArgVtypeRetAddr:
1303 case LLVMArgGsharedvtFixed:
1304 case LLVMArgGsharedvtFixedVtype:
1305 case LLVMArgGsharedvtVariable:
1307 ret_type = LLVMVoidType ();
1313 param_types = g_new0 (LLVMTypeRef, (sig->param_count * 8) + 3);
1315 if (cinfo->ret.storage == LLVMArgVtypeByRef) {
1317 * Has to be the first argument because of the sret argument attribute
1318 * FIXME: This might conflict with passing 'this' as the first argument, but
1319 * this is only used on arm64 which has a dedicated struct return register.
1321 cinfo->vret_arg_pindex = pindex;
1322 param_types [pindex] = type_to_llvm_arg_type (ctx, sig->ret);
1323 if (!ctx_ok (ctx)) {
1324 g_free (param_types);
1327 param_types [pindex] = LLVMPointerType (param_types [pindex], 0);
1330 if (!ctx->llvm_only && cinfo->rgctx_arg) {
1331 cinfo->rgctx_arg_pindex = pindex;
1332 param_types [pindex] = ctx->module->ptr_type;
1335 if (cinfo->imt_arg) {
1336 cinfo->imt_arg_pindex = pindex;
1337 param_types [pindex] = ctx->module->ptr_type;
1341 /* Compute the index in the LLVM signature where the vret arg needs to be passed */
1342 vret_arg_pindex = pindex;
1343 if (cinfo->vret_arg_index == 1) {
1344 /* Add the slots consumed by the first argument */
1345 LLVMArgInfo *ainfo = &cinfo->args [0];
1346 switch (ainfo->storage) {
1347 case LLVMArgVtypeInReg:
1348 for (j = 0; j < 2; ++j) {
1349 if (ainfo->pair_storage [j] == LLVMArgInIReg)
1358 cinfo->vret_arg_pindex = vret_arg_pindex;
1361 if (vretaddr && vret_arg_pindex == pindex)
1362 param_types [pindex ++] = IntPtrType ();
1364 cinfo->this_arg_pindex = pindex;
1365 param_types [pindex ++] = ThisType ();
1366 cinfo->args [0].pindex = cinfo->this_arg_pindex;
1368 if (vretaddr && vret_arg_pindex == pindex)
1369 param_types [pindex ++] = IntPtrType ();
1370 for (i = 0; i < sig->param_count; ++i) {
1371 LLVMArgInfo *ainfo = &cinfo->args [i + sig->hasthis];
1373 if (vretaddr && vret_arg_pindex == pindex)
1374 param_types [pindex ++] = IntPtrType ();
1375 ainfo->pindex = pindex;
1377 switch (ainfo->storage) {
1378 case LLVMArgVtypeInReg:
1379 for (j = 0; j < 2; ++j) {
1380 switch (ainfo->pair_storage [j]) {
1382 param_types [pindex ++] = LLVMIntType (sizeof (gpointer) * 8);
1387 g_assert_not_reached ();
1391 case LLVMArgVtypeByVal:
1392 param_types [pindex] = type_to_llvm_arg_type (ctx, ainfo->type);
1395 param_types [pindex] = LLVMPointerType (param_types [pindex], 0);
1398 case LLVMArgAsIArgs:
1399 param_types [pindex] = LLVMArrayType (IntPtrType (), ainfo->nslots);
1402 case LLVMArgVtypeByRef:
1403 param_types [pindex] = type_to_llvm_arg_type (ctx, ainfo->type);
1406 param_types [pindex] = LLVMPointerType (param_types [pindex], 0);
1409 case LLVMArgAsFpArgs: {
1412 /* Emit dummy fp arguments if needed so the rest is passed on the stack */
1413 for (j = 0; j < ainfo->ndummy_fpargs; ++j)
1414 param_types [pindex ++] = LLVMDoubleType ();
1415 for (j = 0; j < ainfo->nslots; ++j)
1416 param_types [pindex ++] = ainfo->esize == 8 ? LLVMDoubleType () : LLVMFloatType ();
1419 case LLVMArgVtypeAsScalar:
1420 g_assert_not_reached ();
1422 case LLVMArgGsharedvtFixed:
1423 case LLVMArgGsharedvtFixedVtype:
1424 param_types [pindex ++] = LLVMPointerType (type_to_llvm_arg_type (ctx, ainfo->type), 0);
1426 case LLVMArgGsharedvtVariable:
1427 param_types [pindex ++] = LLVMPointerType (IntPtrType (), 0);
1430 param_types [pindex ++] = type_to_llvm_arg_type (ctx, ainfo->type);
1434 if (!ctx_ok (ctx)) {
1435 g_free (param_types);
1438 if (vretaddr && vret_arg_pindex == pindex)
1439 param_types [pindex ++] = IntPtrType ();
1440 if (ctx->llvm_only && cinfo->rgctx_arg) {
1441 /* Pass the rgctx as the last argument */
1442 cinfo->rgctx_arg_pindex = pindex;
1443 param_types [pindex] = ctx->module->ptr_type;
1447 res = LLVMFunctionType (ret_type, param_types, pindex, FALSE);
1448 g_free (param_types);
1454 sig_to_llvm_sig (EmitContext *ctx, MonoMethodSignature *sig)
1456 return sig_to_llvm_sig_full (ctx, sig, NULL);
1460 * LLVMFunctionType1:
1462 * Create an LLVM function type from the arguments.
1464 static G_GNUC_UNUSED LLVMTypeRef
1465 LLVMFunctionType0 (LLVMTypeRef ReturnType,
1468 return LLVMFunctionType (ReturnType, NULL, 0, IsVarArg);
1472 * LLVMFunctionType1:
1474 * Create an LLVM function type from the arguments.
1476 static G_GNUC_UNUSED LLVMTypeRef
1477 LLVMFunctionType1 (LLVMTypeRef ReturnType,
1478 LLVMTypeRef ParamType1,
1481 LLVMTypeRef param_types [1];
1483 param_types [0] = ParamType1;
1485 return LLVMFunctionType (ReturnType, param_types, 1, IsVarArg);
1489 * LLVMFunctionType2:
1491 * Create an LLVM function type from the arguments.
1493 static G_GNUC_UNUSED LLVMTypeRef
1494 LLVMFunctionType2 (LLVMTypeRef ReturnType,
1495 LLVMTypeRef ParamType1,
1496 LLVMTypeRef ParamType2,
1499 LLVMTypeRef param_types [2];
1501 param_types [0] = ParamType1;
1502 param_types [1] = ParamType2;
1504 return LLVMFunctionType (ReturnType, param_types, 2, IsVarArg);
1508 * LLVMFunctionType3:
1510 * Create an LLVM function type from the arguments.
1512 static G_GNUC_UNUSED LLVMTypeRef
1513 LLVMFunctionType3 (LLVMTypeRef ReturnType,
1514 LLVMTypeRef ParamType1,
1515 LLVMTypeRef ParamType2,
1516 LLVMTypeRef ParamType3,
1519 LLVMTypeRef param_types [3];
1521 param_types [0] = ParamType1;
1522 param_types [1] = ParamType2;
1523 param_types [2] = ParamType3;
1525 return LLVMFunctionType (ReturnType, param_types, 3, IsVarArg);
1528 static G_GNUC_UNUSED LLVMTypeRef
1529 LLVMFunctionType5 (LLVMTypeRef ReturnType,
1530 LLVMTypeRef ParamType1,
1531 LLVMTypeRef ParamType2,
1532 LLVMTypeRef ParamType3,
1533 LLVMTypeRef ParamType4,
1534 LLVMTypeRef ParamType5,
1537 LLVMTypeRef param_types [5];
1539 param_types [0] = ParamType1;
1540 param_types [1] = ParamType2;
1541 param_types [2] = ParamType3;
1542 param_types [3] = ParamType4;
1543 param_types [4] = ParamType5;
1545 return LLVMFunctionType (ReturnType, param_types, 5, IsVarArg);
1551 * Create an LLVM builder and remember it so it can be freed later.
1553 static LLVMBuilderRef
1554 create_builder (EmitContext *ctx)
1556 LLVMBuilderRef builder = LLVMCreateBuilder ();
1558 ctx->builders = g_slist_prepend_mempool (ctx->cfg->mempool, ctx->builders, builder);
1564 get_aotconst_name (MonoJumpInfoType type, gconstpointer data, int got_offset)
1569 case MONO_PATCH_INFO_INTERNAL_METHOD:
1570 name = g_strdup_printf ("jit_icall_%s", data);
1572 case MONO_PATCH_INFO_RGCTX_SLOT_INDEX: {
1573 MonoJumpInfoRgctxEntry *entry = (MonoJumpInfoRgctxEntry*)data;
1574 name = g_strdup_printf ("RGCTX_SLOT_INDEX_%s", mono_rgctx_info_type_to_str (entry->info_type));
1578 name = g_strdup_printf ("%s_%d", mono_ji_type_to_string (type), got_offset);
1586 get_aotconst_typed (EmitContext *ctx, MonoJumpInfoType type, gconstpointer data, LLVMTypeRef llvm_type)
1590 LLVMValueRef indexes [2];
1592 LLVMValueRef got_entry_addr, load;
1593 LLVMBuilderRef builder = ctx->builder;
1598 ji = g_new0 (MonoJumpInfo, 1);
1600 ji->data.target = data;
1602 ji = mono_aot_patch_info_dup (ji);
1604 ji->next = cfg->patch_info;
1605 cfg->patch_info = ji;
1607 got_offset = mono_aot_get_got_offset (cfg->patch_info);
1608 ctx->module->max_got_offset = MAX (ctx->module->max_got_offset, got_offset);
1610 * If the got slot is shared, it means its initialized when the aot image is loaded, so we don't need to
1611 * explicitly initialize it.
1613 if (!mono_aot_is_shared_got_offset (got_offset)) {
1614 //mono_print_ji (ji);
1616 ctx->has_got_access = TRUE;
1619 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
1620 indexes [1] = LLVMConstInt (LLVMInt32Type (), (gssize)got_offset, FALSE);
1621 got_entry_addr = LLVMBuildGEP (builder, ctx->module->got_var, indexes, 2, "");
1623 name = get_aotconst_name (type, data, got_offset);
1625 load = LLVMBuildLoad (builder, got_entry_addr, "");
1626 load = convert (ctx, load, llvm_type);
1627 LLVMSetValueName (load, name ? name : "");
1629 load = LLVMBuildLoad (builder, got_entry_addr, name ? name : "");
1632 //set_invariant_load_flag (load);
1638 get_aotconst (EmitContext *ctx, MonoJumpInfoType type, gconstpointer data)
1640 return get_aotconst_typed (ctx, type, data, NULL);
1644 get_callee (EmitContext *ctx, LLVMTypeRef llvm_sig, MonoJumpInfoType type, gconstpointer data)
1646 LLVMValueRef callee;
1648 if (ctx->llvm_only) {
1649 callee_name = mono_aot_get_direct_call_symbol (type, data);
1651 /* Directly callable */
1653 callee = (LLVMValueRef)g_hash_table_lookup (ctx->module->direct_callables, callee_name);
1655 callee = LLVMAddFunction (ctx->lmodule, callee_name, llvm_sig);
1657 LLVMSetVisibility (callee, LLVMHiddenVisibility);
1659 g_hash_table_insert (ctx->module->direct_callables, (char*)callee_name, callee);
1661 /* LLVMTypeRef's are uniqued */
1662 if (LLVMGetElementType (LLVMTypeOf (callee)) != llvm_sig)
1663 return LLVMConstBitCast (callee, LLVMPointerType (llvm_sig, 0));
1665 g_free (callee_name);
1671 * Calls are made through the GOT.
1673 return get_aotconst_typed (ctx, type, data, LLVMPointerType (llvm_sig, 0));
1675 MonoJumpInfo *ji = NULL;
1677 callee_name = mono_aot_get_plt_symbol (type, data);
1681 if (ctx->cfg->compile_aot)
1682 /* Add a patch so referenced wrappers can be compiled in full aot mode */
1683 mono_add_patch_info (ctx->cfg, 0, type, data);
1686 callee = (LLVMValueRef)g_hash_table_lookup (ctx->module->plt_entries, callee_name);
1688 callee = LLVMAddFunction (ctx->lmodule, callee_name, llvm_sig);
1690 LLVMSetVisibility (callee, LLVMHiddenVisibility);
1692 g_hash_table_insert (ctx->module->plt_entries, (char*)callee_name, callee);
1695 if (ctx->cfg->compile_aot) {
1696 ji = g_new0 (MonoJumpInfo, 1);
1698 ji->data.target = data;
1700 g_hash_table_insert (ctx->module->plt_entries_ji, ji, callee);
1708 emit_jit_callee (EmitContext *ctx, const char *name, LLVMTypeRef llvm_sig, gpointer target)
1710 #if LLVM_API_VERSION > 100
1711 LLVMValueRef tramp_var = LLVMAddGlobal (ctx->lmodule, LLVMPointerType (llvm_sig, 0), name);
1712 LLVMSetInitializer (tramp_var, LLVMConstIntToPtr (LLVMConstInt (LLVMInt64Type (), (guint64)(size_t)target, FALSE), LLVMPointerType (llvm_sig, 0)));
1713 LLVMSetLinkage (tramp_var, LLVMExternalLinkage);
1714 LLVMValueRef callee = LLVMBuildLoad (ctx->builder, tramp_var, "");
1717 LLVMValueRef callee = LLVMAddFunction (ctx->lmodule, "", llvm_sig);
1718 LLVMAddGlobalMapping (ctx->module->ee, callee, target);
1724 get_handler_clause (MonoCompile *cfg, MonoBasicBlock *bb)
1726 MonoMethodHeader *header = cfg->header;
1727 MonoExceptionClause *clause;
1731 if (bb->region != -1 && MONO_BBLOCK_IS_IN_REGION (bb, MONO_REGION_TRY))
1732 return (bb->region >> 8) - 1;
1735 for (i = 0; i < header->num_clauses; ++i) {
1736 clause = &header->clauses [i];
1738 if (MONO_OFFSET_IN_CLAUSE (clause, bb->real_offset) && clause->flags == MONO_EXCEPTION_CLAUSE_NONE)
1745 static MonoExceptionClause *
1746 get_most_deep_clause (MonoCompile *cfg, EmitContext *ctx, MonoBasicBlock *bb)
1748 // Since they're sorted by nesting we just need
1749 // the first one that the bb is a member of
1750 for (int i = 0; i < cfg->header->num_clauses; i++) {
1751 MonoExceptionClause *curr = &cfg->header->clauses [i];
1753 if (MONO_OFFSET_IN_CLAUSE (curr, bb->real_offset))
1761 set_metadata_flag (LLVMValueRef v, const char *flag_name)
1763 LLVMValueRef md_arg;
1766 md_kind = LLVMGetMDKindID (flag_name, strlen (flag_name));
1767 md_arg = LLVMMDString ("mono", 4);
1768 LLVMSetMetadata (v, md_kind, LLVMMDNode (&md_arg, 1));
1772 set_invariant_load_flag (LLVMValueRef v)
1774 LLVMValueRef md_arg;
1776 const char *flag_name;
1778 // FIXME: Cache this
1779 flag_name = "invariant.load";
1780 md_kind = LLVMGetMDKindID (flag_name, strlen (flag_name));
1781 md_arg = LLVMMDString ("<index>", strlen ("<index>"));
1782 LLVMSetMetadata (v, md_kind, LLVMMDNode (&md_arg, 1));
1788 * Emit an LLVM call or invoke instruction depending on whenever the call is inside
1792 emit_call (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, LLVMValueRef callee, LLVMValueRef *args, int pindex)
1794 MonoCompile *cfg = ctx->cfg;
1795 LLVMValueRef lcall = NULL;
1796 LLVMBuilderRef builder = *builder_ref;
1797 MonoExceptionClause *clause;
1799 if (ctx->llvm_only) {
1800 clause = get_most_deep_clause (cfg, ctx, bb);
1803 g_assert (clause->flags == MONO_EXCEPTION_CLAUSE_NONE || clause->flags == MONO_EXCEPTION_CLAUSE_FINALLY);
1806 * Have to use an invoke instead of a call, branching to the
1807 * handler bblock of the clause containing this bblock.
1809 intptr_t key = CLAUSE_END(clause);
1811 LLVMBasicBlockRef lpad_bb = (LLVMBasicBlockRef)g_hash_table_lookup (ctx->exc_meta, (gconstpointer)key);
1813 // FIXME: Find the one that has the lowest end bound for the right start address
1814 // FIXME: Finally + nesting
1817 LLVMBasicBlockRef noex_bb = gen_bb (ctx, "CALL_NOEX_BB");
1820 lcall = LLVMBuildInvoke (builder, callee, args, pindex, noex_bb, lpad_bb, "");
1822 builder = ctx->builder = create_builder (ctx);
1823 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
1825 ctx->bblocks [bb->block_num].end_bblock = noex_bb;
1829 int clause_index = get_handler_clause (cfg, bb);
1831 if (clause_index != -1) {
1832 MonoMethodHeader *header = cfg->header;
1833 MonoExceptionClause *ec = &header->clauses [clause_index];
1834 MonoBasicBlock *tblock;
1835 LLVMBasicBlockRef ex_bb, noex_bb;
1838 * Have to use an invoke instead of a call, branching to the
1839 * handler bblock of the clause containing this bblock.
1842 g_assert (ec->flags == MONO_EXCEPTION_CLAUSE_NONE || ec->flags == MONO_EXCEPTION_CLAUSE_FINALLY);
1844 tblock = cfg->cil_offset_to_bb [ec->handler_offset];
1847 ctx->bblocks [tblock->block_num].invoke_target = TRUE;
1849 ex_bb = get_bb (ctx, tblock);
1851 noex_bb = gen_bb (ctx, "NOEX_BB");
1854 lcall = LLVMBuildInvoke (builder, callee, args, pindex, noex_bb, ex_bb, "");
1856 builder = ctx->builder = create_builder (ctx);
1857 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
1859 ctx->bblocks [bb->block_num].end_bblock = noex_bb;
1864 lcall = LLVMBuildCall (builder, callee, args, pindex, "");
1865 ctx->builder = builder;
1869 *builder_ref = ctx->builder;
1875 emit_load_general (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, int size, LLVMValueRef addr, const char *name, gboolean is_faulting, BarrierKind barrier)
1877 const char *intrins_name;
1878 LLVMValueRef args [16], res;
1879 LLVMTypeRef addr_type;
1880 gboolean use_intrinsics = TRUE;
1882 #if LLVM_API_VERSION > 100
1883 if (is_faulting && bb->region != -1 && !ctx->cfg->llvm_only) {
1884 /* The llvm.mono.load/store intrinsics are not supported by this llvm version, emit an explicit null check instead */
1885 LLVMValueRef cmp = LLVMBuildICmp (*builder_ref, LLVMIntEQ, addr, LLVMConstNull (LLVMTypeOf (addr)), "");
1886 emit_cond_system_exception (ctx, bb, "NullReferenceException", cmp);
1887 *builder_ref = ctx->builder;
1888 use_intrinsics = FALSE;
1892 if (is_faulting && bb->region != -1 && !ctx->cfg->llvm_only && use_intrinsics) {
1893 LLVMAtomicOrdering ordering;
1896 case LLVM_BARRIER_NONE:
1897 ordering = LLVMAtomicOrderingNotAtomic;
1899 case LLVM_BARRIER_ACQ:
1900 ordering = LLVMAtomicOrderingAcquire;
1902 case LLVM_BARRIER_SEQ:
1903 ordering = LLVMAtomicOrderingSequentiallyConsistent;
1906 g_assert_not_reached ();
1911 * We handle loads which can fault by calling a mono specific intrinsic
1912 * using an invoke, so they are handled properly inside try blocks.
1913 * We can't use this outside clauses, since LLVM optimizes intrinsics which
1914 * are marked with IntrReadArgMem.
1918 intrins_name = "llvm.mono.load.i8.p0i8";
1921 intrins_name = "llvm.mono.load.i16.p0i16";
1924 intrins_name = "llvm.mono.load.i32.p0i32";
1927 intrins_name = "llvm.mono.load.i64.p0i64";
1930 g_assert_not_reached ();
1933 addr_type = LLVMTypeOf (addr);
1934 if (addr_type == LLVMPointerType (LLVMDoubleType (), 0) || addr_type == LLVMPointerType (LLVMFloatType (), 0))
1935 addr = LLVMBuildBitCast (*builder_ref, addr, LLVMPointerType (LLVMIntType (size * 8), 0), "");
1938 args [1] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
1939 args [2] = LLVMConstInt (LLVMInt1Type (), TRUE, FALSE);
1940 args [3] = LLVMConstInt (LLVMInt32Type (), ordering, FALSE);
1941 res = emit_call (ctx, bb, builder_ref, get_intrinsic (ctx, intrins_name), args, 4);
1943 if (addr_type == LLVMPointerType (LLVMDoubleType (), 0))
1944 res = LLVMBuildBitCast (*builder_ref, res, LLVMDoubleType (), "");
1945 else if (addr_type == LLVMPointerType (LLVMFloatType (), 0))
1946 res = LLVMBuildBitCast (*builder_ref, res, LLVMFloatType (), "");
1953 * We emit volatile loads for loads which can fault, because otherwise
1954 * LLVM will generate invalid code when encountering a load from a
1957 res = mono_llvm_build_load (*builder_ref, addr, name, is_faulting, barrier);
1959 /* Mark it with a custom metadata */
1962 set_metadata_flag (res, "mono.faulting.load");
1970 emit_load (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, int size, LLVMValueRef addr, const char *name, gboolean is_faulting)
1972 return emit_load_general (ctx, bb, builder_ref, size, addr, name, is_faulting, LLVM_BARRIER_NONE);
1976 emit_store_general (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, int size, LLVMValueRef value, LLVMValueRef addr, gboolean is_faulting, BarrierKind barrier)
1978 const char *intrins_name;
1979 LLVMValueRef args [16];
1980 gboolean use_intrinsics = TRUE;
1982 #if LLVM_API_VERSION > 100
1983 if (is_faulting && bb->region != -1 && !ctx->cfg->llvm_only) {
1984 /* The llvm.mono.load/store intrinsics are not supported by this llvm version, emit an explicit null check instead */
1985 LLVMValueRef cmp = LLVMBuildICmp (*builder_ref, LLVMIntEQ, addr, LLVMConstNull (LLVMTypeOf (addr)), "");
1986 emit_cond_system_exception (ctx, bb, "NullReferenceException", cmp);
1987 *builder_ref = ctx->builder;
1988 use_intrinsics = FALSE;
1992 if (is_faulting && bb->region != -1 && !ctx->cfg->llvm_only && use_intrinsics) {
1993 LLVMAtomicOrdering ordering;
1996 case LLVM_BARRIER_NONE:
1997 ordering = LLVMAtomicOrderingNotAtomic;
1999 case LLVM_BARRIER_REL:
2000 ordering = LLVMAtomicOrderingRelease;
2002 case LLVM_BARRIER_SEQ:
2003 ordering = LLVMAtomicOrderingSequentiallyConsistent;
2006 g_assert_not_reached ();
2012 intrins_name = "llvm.mono.store.i8.p0i8";
2015 intrins_name = "llvm.mono.store.i16.p0i16";
2018 intrins_name = "llvm.mono.store.i32.p0i32";
2021 intrins_name = "llvm.mono.store.i64.p0i64";
2024 g_assert_not_reached ();
2027 if (LLVMTypeOf (value) == LLVMDoubleType () || LLVMTypeOf (value) == LLVMFloatType ()) {
2028 value = LLVMBuildBitCast (*builder_ref, value, LLVMIntType (size * 8), "");
2029 addr = LLVMBuildBitCast (*builder_ref, addr, LLVMPointerType (LLVMIntType (size * 8), 0), "");
2034 args [2] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
2035 args [3] = LLVMConstInt (LLVMInt1Type (), TRUE, FALSE);
2036 args [4] = LLVMConstInt (LLVMInt32Type (), ordering, FALSE);
2037 emit_call (ctx, bb, builder_ref, get_intrinsic (ctx, intrins_name), args, 5);
2039 mono_llvm_build_store (*builder_ref, value, addr, is_faulting, barrier);
2044 emit_store (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, int size, LLVMValueRef value, LLVMValueRef addr, gboolean is_faulting)
2046 emit_store_general (ctx, bb, builder_ref, size, value, addr, is_faulting, LLVM_BARRIER_NONE);
2050 * emit_cond_system_exception:
2052 * Emit code to throw the exception EXC_TYPE if the condition CMP is false.
2053 * Might set the ctx exception.
2056 emit_cond_system_exception (EmitContext *ctx, MonoBasicBlock *bb, const char *exc_type, LLVMValueRef cmp)
2058 LLVMBasicBlockRef ex_bb, ex2_bb = NULL, noex_bb;
2059 LLVMBuilderRef builder;
2060 MonoClass *exc_class;
2061 LLVMValueRef args [2];
2062 LLVMValueRef callee;
2063 gboolean no_pc = FALSE;
2065 if (IS_TARGET_AMD64)
2066 /* Some platforms don't require the pc argument */
2069 ex_bb = gen_bb (ctx, "EX_BB");
2071 ex2_bb = gen_bb (ctx, "EX2_BB");
2072 noex_bb = gen_bb (ctx, "NOEX_BB");
2074 LLVMBuildCondBr (ctx->builder, cmp, ex_bb, noex_bb);
2076 exc_class = mono_class_load_from_name (mono_get_corlib (), "System", exc_type);
2078 /* Emit exception throwing code */
2079 ctx->builder = builder = create_builder (ctx);
2080 LLVMPositionBuilderAtEnd (builder, ex_bb);
2082 if (ctx->cfg->llvm_only) {
2083 static LLVMTypeRef sig;
2086 sig = LLVMFunctionType1 (LLVMVoidType (), LLVMInt32Type (), FALSE);
2087 callee = get_callee (ctx, sig, MONO_PATCH_INFO_JIT_ICALL_ADDR, "mono_llvm_throw_corlib_exception");
2089 LLVMBuildBr (builder, ex2_bb);
2091 ctx->builder = builder = create_builder (ctx);
2092 LLVMPositionBuilderAtEnd (ctx->builder, ex2_bb);
2094 args [0] = LLVMConstInt (LLVMInt32Type (), exc_class->type_token - MONO_TOKEN_TYPE_DEF, FALSE);
2095 emit_call (ctx, bb, &builder, callee, args, 1);
2096 LLVMBuildUnreachable (builder);
2098 ctx->builder = builder = create_builder (ctx);
2099 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
2101 ctx->bblocks [bb->block_num].end_bblock = noex_bb;
2107 callee = ctx->module->throw_corlib_exception;
2110 const char *icall_name;
2113 sig = LLVMFunctionType1 (LLVMVoidType (), LLVMInt32Type (), FALSE);
2115 sig = LLVMFunctionType2 (LLVMVoidType (), LLVMInt32Type (), LLVMPointerType (LLVMInt8Type (), 0), FALSE);
2116 icall_name = "llvm_throw_corlib_exception_abs_trampoline";
2118 if (ctx->cfg->compile_aot) {
2119 callee = get_callee (ctx, sig, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
2122 * Differences between the LLVM/non-LLVM throw corlib exception trampoline:
2123 * - On x86, LLVM generated code doesn't push the arguments
2124 * - The trampoline takes the throw address as an arguments, not a pc offset.
2126 gpointer target = resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
2127 callee = emit_jit_callee (ctx, "llvm_throw_corlib_exception_trampoline", sig, target);
2129 #if LLVM_API_VERSION > 100
2131 * Make sure that ex_bb starts with the invoke, so the block address points to it, and not to the load
2132 * added by emit_jit_callee ().
2134 ex2_bb = gen_bb (ctx, "EX2_BB");
2135 LLVMBuildBr (builder, ex2_bb);
2138 ctx->builder = builder = create_builder (ctx);
2139 LLVMPositionBuilderAtEnd (ctx->builder, ex2_bb);
2141 mono_memory_barrier ();
2142 ctx->module->throw_corlib_exception = callee;
2147 args [0] = LLVMConstInt (LLVMInt32Type (), exc_class->type_token - MONO_TOKEN_TYPE_DEF, FALSE);
2150 * The LLVM mono branch contains changes so a block address can be passed as an
2151 * argument to a call.
2154 emit_call (ctx, bb, &builder, callee, args, 1);
2156 args [1] = LLVMBlockAddress (ctx->lmethod, ex_bb);
2157 emit_call (ctx, bb, &builder, callee, args, 2);
2160 LLVMBuildUnreachable (builder);
2162 ctx->builder = builder = create_builder (ctx);
2163 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
2165 ctx->bblocks [bb->block_num].end_bblock = noex_bb;
2172 * emit_args_to_vtype:
2174 * Emit code to store the vtype in the arguments args to the address ADDRESS.
2177 emit_args_to_vtype (EmitContext *ctx, LLVMBuilderRef builder, MonoType *t, LLVMValueRef address, LLVMArgInfo *ainfo, LLVMValueRef *args)
2179 int j, size, nslots;
2181 size = mono_class_value_size (mono_class_from_mono_type (t), NULL);
2183 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (t))) {
2184 address = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (LLVMInt8Type (), 0), "");
2187 if (ainfo->storage == LLVMArgAsFpArgs)
2188 nslots = ainfo->nslots;
2192 for (j = 0; j < nslots; ++j) {
2193 LLVMValueRef index [2], addr, daddr;
2194 int part_size = size > sizeof (gpointer) ? sizeof (gpointer) : size;
2195 LLVMTypeRef part_type;
2197 while (part_size != 1 && part_size != 2 && part_size != 4 && part_size < 8)
2200 if (ainfo->pair_storage [j] == LLVMArgNone)
2203 switch (ainfo->pair_storage [j]) {
2204 case LLVMArgInIReg: {
2205 part_type = LLVMIntType (part_size * 8);
2206 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (t))) {
2207 index [0] = LLVMConstInt (LLVMInt32Type (), j * sizeof (gpointer), FALSE);
2208 addr = LLVMBuildGEP (builder, address, index, 1, "");
2210 daddr = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (IntPtrType (), 0), "");
2211 index [0] = LLVMConstInt (LLVMInt32Type (), j, FALSE);
2212 addr = LLVMBuildGEP (builder, daddr, index, 1, "");
2214 LLVMBuildStore (builder, convert (ctx, args [j], part_type), LLVMBuildBitCast (ctx->builder, addr, LLVMPointerType (part_type, 0), ""));
2217 case LLVMArgInFPReg: {
2218 LLVMTypeRef arg_type;
2220 if (ainfo->esize == 8)
2221 arg_type = LLVMDoubleType ();
2223 arg_type = LLVMFloatType ();
2225 index [0] = LLVMConstInt (LLVMInt32Type (), j, FALSE);
2226 daddr = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (arg_type, 0), "");
2227 addr = LLVMBuildGEP (builder, daddr, index, 1, "");
2228 LLVMBuildStore (builder, args [j], addr);
2234 g_assert_not_reached ();
2237 size -= sizeof (gpointer);
2242 * emit_vtype_to_args:
2244 * Emit code to load a vtype at address ADDRESS into scalar arguments. Store the arguments
2245 * into ARGS, and the number of arguments into NARGS.
2248 emit_vtype_to_args (EmitContext *ctx, LLVMBuilderRef builder, MonoType *t, LLVMValueRef address, LLVMArgInfo *ainfo, LLVMValueRef *args, guint32 *nargs)
2251 int j, size, nslots;
2252 LLVMTypeRef arg_type;
2254 size = get_vtype_size (t);
2256 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (t)))
2257 address = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (LLVMInt8Type (), 0), "");
2259 if (ainfo->storage == LLVMArgAsFpArgs)
2260 nslots = ainfo->nslots;
2263 for (j = 0; j < nslots; ++j) {
2264 LLVMValueRef index [2], addr, daddr;
2265 int partsize = size > sizeof (gpointer) ? sizeof (gpointer) : size;
2267 if (ainfo->pair_storage [j] == LLVMArgNone)
2270 switch (ainfo->pair_storage [j]) {
2272 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (t))) {
2273 index [0] = LLVMConstInt (LLVMInt32Type (), j * sizeof (gpointer), FALSE);
2274 addr = LLVMBuildGEP (builder, address, index, 1, "");
2276 daddr = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (IntPtrType (), 0), "");
2277 index [0] = LLVMConstInt (LLVMInt32Type (), j, FALSE);
2278 addr = LLVMBuildGEP (builder, daddr, index, 1, "");
2280 args [pindex ++] = convert (ctx, LLVMBuildLoad (builder, LLVMBuildBitCast (ctx->builder, addr, LLVMPointerType (LLVMIntType (partsize * 8), 0), ""), ""), IntPtrType ());
2282 case LLVMArgInFPReg:
2283 if (ainfo->esize == 8)
2284 arg_type = LLVMDoubleType ();
2286 arg_type = LLVMFloatType ();
2287 daddr = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (arg_type, 0), "");
2288 index [0] = LLVMConstInt (LLVMInt32Type (), j, FALSE);
2289 addr = LLVMBuildGEP (builder, daddr, index, 1, "");
2290 args [pindex ++] = LLVMBuildLoad (builder, addr, "");
2295 g_assert_not_reached ();
2297 size -= sizeof (gpointer);
2304 build_alloca_llvm_type_name (EmitContext *ctx, LLVMTypeRef t, int align, const char *name)
2307 * Have to place all alloca's at the end of the entry bb, since otherwise they would
2308 * get executed every time control reaches them.
2310 LLVMPositionBuilder (ctx->alloca_builder, get_bb (ctx, ctx->cfg->bb_entry), ctx->last_alloca);
2312 ctx->last_alloca = mono_llvm_build_alloca (ctx->alloca_builder, t, NULL, align, name);
2313 return ctx->last_alloca;
2317 build_alloca_llvm_type (EmitContext *ctx, LLVMTypeRef t, int align)
2319 return build_alloca_llvm_type_name (ctx, t, align, "");
2323 build_alloca (EmitContext *ctx, MonoType *t)
2325 MonoClass *k = mono_class_from_mono_type (t);
2328 g_assert (!mini_is_gsharedvt_variable_type (t));
2330 if (MONO_CLASS_IS_SIMD (ctx->cfg, k))
2333 align = mono_class_min_align (k);
2335 /* Sometimes align is not a power of 2 */
2336 while (mono_is_power_of_two (align) == -1)
2339 return build_alloca_llvm_type (ctx, type_to_llvm_type (ctx, t), align);
2343 emit_gsharedvt_ldaddr (EmitContext *ctx, int vreg)
2347 * Compute the address of the local as gsharedvt_locals_var + gsharedvt_info_var->locals_offsets [idx].
2349 MonoCompile *cfg = ctx->cfg;
2350 LLVMBuilderRef builder = ctx->builder;
2351 LLVMValueRef offset, offset_var;
2352 LLVMValueRef info_var = ctx->values [cfg->gsharedvt_info_var->dreg];
2353 LLVMValueRef locals_var = ctx->values [cfg->gsharedvt_locals_var->dreg];
2357 g_assert (info_var);
2358 g_assert (locals_var);
2360 int idx = cfg->gsharedvt_vreg_to_idx [vreg] - 1;
2362 offset = LLVMConstInt (LLVMInt32Type (), MONO_STRUCT_OFFSET (MonoGSharedVtMethodRuntimeInfo, entries) + (idx * sizeof (gpointer)), FALSE);
2363 ptr = LLVMBuildAdd (builder, convert (ctx, info_var, IntPtrType ()), convert (ctx, offset, IntPtrType ()), "");
2365 name = g_strdup_printf ("gsharedvt_local_%d_offset", vreg);
2366 offset_var = LLVMBuildLoad (builder, convert (ctx, ptr, LLVMPointerType (LLVMInt32Type (), 0)), name);
2368 return LLVMBuildAdd (builder, convert (ctx, locals_var, IntPtrType ()), convert (ctx, offset_var, IntPtrType ()), "");
2372 * Put the global into the 'llvm.used' array to prevent it from being optimized away.
2375 mark_as_used (MonoLLVMModule *module, LLVMValueRef global)
2378 module->used = g_ptr_array_sized_new (16);
2379 g_ptr_array_add (module->used, global);
2383 emit_llvm_used (MonoLLVMModule *module)
2385 LLVMModuleRef lmodule = module->lmodule;
2386 LLVMTypeRef used_type;
2387 LLVMValueRef used, *used_elem;
2393 used_type = LLVMArrayType (LLVMPointerType (LLVMInt8Type (), 0), module->used->len);
2394 used = LLVMAddGlobal (lmodule, used_type, "llvm.used");
2395 used_elem = g_new0 (LLVMValueRef, module->used->len);
2396 for (i = 0; i < module->used->len; ++i)
2397 used_elem [i] = LLVMConstBitCast ((LLVMValueRef)g_ptr_array_index (module->used, i), LLVMPointerType (LLVMInt8Type (), 0));
2398 LLVMSetInitializer (used, LLVMConstArray (LLVMPointerType (LLVMInt8Type (), 0), used_elem, module->used->len));
2399 LLVMSetLinkage (used, LLVMAppendingLinkage);
2400 LLVMSetSection (used, "llvm.metadata");
2406 * Emit a function mapping method indexes to their code
2409 emit_get_method (MonoLLVMModule *module)
2411 LLVMModuleRef lmodule = module->lmodule;
2412 LLVMValueRef func, switch_ins, m;
2413 LLVMBasicBlockRef entry_bb, fail_bb, bb, code_start_bb, code_end_bb;
2414 LLVMBasicBlockRef *bbs;
2416 LLVMBuilderRef builder;
2421 * Emit a switch statement. Emitting a table of function addresses is smaller/faster,
2422 * but generating code seems safer.
2424 rtype = LLVMPointerType (LLVMInt8Type (), 0);
2425 func = LLVMAddFunction (lmodule, module->get_method_symbol, LLVMFunctionType1 (rtype, LLVMInt32Type (), FALSE));
2426 LLVMSetLinkage (func, LLVMExternalLinkage);
2427 LLVMSetVisibility (func, LLVMHiddenVisibility);
2428 LLVMAddFunctionAttr (func, LLVMNoUnwindAttribute);
2429 module->get_method = func;
2431 entry_bb = LLVMAppendBasicBlock (func, "ENTRY");
2434 * Return llvm_code_start/llvm_code_end when called with -1/-2.
2435 * Hopefully, the toolchain doesn't reorder these functions. If it does,
2436 * then we will have to find another solution.
2439 name = g_strdup_printf ("BB_CODE_START");
2440 code_start_bb = LLVMAppendBasicBlock (func, name);
2442 builder = LLVMCreateBuilder ();
2443 LLVMPositionBuilderAtEnd (builder, code_start_bb);
2444 LLVMBuildRet (builder, LLVMBuildBitCast (builder, module->code_start, rtype, ""));
2446 name = g_strdup_printf ("BB_CODE_END");
2447 code_end_bb = LLVMAppendBasicBlock (func, name);
2449 builder = LLVMCreateBuilder ();
2450 LLVMPositionBuilderAtEnd (builder, code_end_bb);
2451 LLVMBuildRet (builder, LLVMBuildBitCast (builder, module->code_end, rtype, ""));
2453 bbs = g_new0 (LLVMBasicBlockRef, module->max_method_idx + 1);
2454 for (i = 0; i < module->max_method_idx + 1; ++i) {
2455 name = g_strdup_printf ("BB_%d", i);
2456 bb = LLVMAppendBasicBlock (func, name);
2460 builder = LLVMCreateBuilder ();
2461 LLVMPositionBuilderAtEnd (builder, bb);
2463 m = (LLVMValueRef)g_hash_table_lookup (module->idx_to_lmethod, GINT_TO_POINTER (i));
2465 LLVMBuildRet (builder, LLVMBuildBitCast (builder, m, rtype, ""));
2467 LLVMBuildRet (builder, LLVMConstNull (rtype));
2470 fail_bb = LLVMAppendBasicBlock (func, "FAIL");
2471 builder = LLVMCreateBuilder ();
2472 LLVMPositionBuilderAtEnd (builder, fail_bb);
2473 LLVMBuildRet (builder, LLVMConstNull (rtype));
2475 builder = LLVMCreateBuilder ();
2476 LLVMPositionBuilderAtEnd (builder, entry_bb);
2478 switch_ins = LLVMBuildSwitch (builder, LLVMGetParam (func, 0), fail_bb, 0);
2479 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), -1, FALSE), code_start_bb);
2480 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), -2, FALSE), code_end_bb);
2481 for (i = 0; i < module->max_method_idx + 1; ++i) {
2482 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), i, FALSE), bbs [i]);
2485 mark_as_used (module, func);
2489 * emit_get_unbox_tramp:
2491 * Emit a function mapping method indexes to their unbox trampoline
2494 emit_get_unbox_tramp (MonoLLVMModule *module)
2496 LLVMModuleRef lmodule = module->lmodule;
2497 LLVMValueRef func, switch_ins, m;
2498 LLVMBasicBlockRef entry_bb, fail_bb, bb;
2499 LLVMBasicBlockRef *bbs;
2501 LLVMBuilderRef builder;
2505 /* Similar to emit_get_method () */
2507 rtype = LLVMPointerType (LLVMInt8Type (), 0);
2508 func = LLVMAddFunction (lmodule, module->get_unbox_tramp_symbol, LLVMFunctionType1 (rtype, LLVMInt32Type (), FALSE));
2509 LLVMSetLinkage (func, LLVMExternalLinkage);
2510 LLVMSetVisibility (func, LLVMHiddenVisibility);
2511 LLVMAddFunctionAttr (func, LLVMNoUnwindAttribute);
2512 module->get_unbox_tramp = func;
2514 entry_bb = LLVMAppendBasicBlock (func, "ENTRY");
2516 bbs = g_new0 (LLVMBasicBlockRef, module->max_method_idx + 1);
2517 for (i = 0; i < module->max_method_idx + 1; ++i) {
2518 m = (LLVMValueRef)g_hash_table_lookup (module->idx_to_unbox_tramp, GINT_TO_POINTER (i));
2522 name = g_strdup_printf ("BB_%d", i);
2523 bb = LLVMAppendBasicBlock (func, name);
2527 builder = LLVMCreateBuilder ();
2528 LLVMPositionBuilderAtEnd (builder, bb);
2530 LLVMBuildRet (builder, LLVMBuildBitCast (builder, m, rtype, ""));
2533 fail_bb = LLVMAppendBasicBlock (func, "FAIL");
2534 builder = LLVMCreateBuilder ();
2535 LLVMPositionBuilderAtEnd (builder, fail_bb);
2536 LLVMBuildRet (builder, LLVMConstNull (rtype));
2538 builder = LLVMCreateBuilder ();
2539 LLVMPositionBuilderAtEnd (builder, entry_bb);
2541 switch_ins = LLVMBuildSwitch (builder, LLVMGetParam (func, 0), fail_bb, 0);
2542 for (i = 0; i < module->max_method_idx + 1; ++i) {
2543 m = (LLVMValueRef)g_hash_table_lookup (module->idx_to_unbox_tramp, GINT_TO_POINTER (i));
2547 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), i, FALSE), bbs [i]);
2550 mark_as_used (module, func);
2553 /* Add a function to mark the beginning of LLVM code */
2555 emit_llvm_code_start (MonoLLVMModule *module)
2557 LLVMModuleRef lmodule = module->lmodule;
2559 LLVMBasicBlockRef entry_bb;
2560 LLVMBuilderRef builder;
2562 func = LLVMAddFunction (lmodule, "llvm_code_start", LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE));
2563 LLVMSetLinkage (func, LLVMInternalLinkage);
2564 LLVMAddFunctionAttr (func, LLVMNoUnwindAttribute);
2565 module->code_start = func;
2566 entry_bb = LLVMAppendBasicBlock (func, "ENTRY");
2567 builder = LLVMCreateBuilder ();
2568 LLVMPositionBuilderAtEnd (builder, entry_bb);
2569 LLVMBuildRetVoid (builder);
2573 emit_init_icall_wrapper (MonoLLVMModule *module, const char *name, const char *icall_name, int subtype)
2575 LLVMModuleRef lmodule = module->lmodule;
2576 LLVMValueRef func, indexes [2], got_entry_addr, args [16], callee;
2577 LLVMBasicBlockRef entry_bb;
2578 LLVMBuilderRef builder;
2585 func = LLVMAddFunction (lmodule, name, LLVMFunctionType1 (LLVMVoidType (), LLVMInt32Type (), FALSE));
2586 sig = LLVMFunctionType2 (LLVMVoidType (), IntPtrType (), LLVMInt32Type (), FALSE);
2591 func = LLVMAddFunction (lmodule, name, LLVMFunctionType2 (LLVMVoidType (), LLVMInt32Type (), IntPtrType (), FALSE));
2592 sig = LLVMFunctionType3 (LLVMVoidType (), IntPtrType (), LLVMInt32Type (), IntPtrType (), FALSE);
2595 func = LLVMAddFunction (lmodule, name, LLVMFunctionType2 (LLVMVoidType (), LLVMInt32Type (), ObjRefType (), FALSE));
2596 sig = LLVMFunctionType3 (LLVMVoidType (), IntPtrType (), LLVMInt32Type (), ObjRefType (), FALSE);
2599 g_assert_not_reached ();
2601 LLVMSetLinkage (func, LLVMInternalLinkage);
2602 LLVMAddFunctionAttr (func, LLVMNoInlineAttribute);
2603 mono_llvm_set_preserveall_cc (func);
2604 entry_bb = LLVMAppendBasicBlock (func, "ENTRY");
2605 builder = LLVMCreateBuilder ();
2606 LLVMPositionBuilderAtEnd (builder, entry_bb);
2609 ji = g_new0 (MonoJumpInfo, 1);
2610 ji->type = MONO_PATCH_INFO_AOT_MODULE;
2611 ji = mono_aot_patch_info_dup (ji);
2612 got_offset = mono_aot_get_got_offset (ji);
2613 module->max_got_offset = MAX (module->max_got_offset, got_offset);
2614 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
2615 indexes [1] = LLVMConstInt (LLVMInt32Type (), got_offset, FALSE);
2616 got_entry_addr = LLVMBuildGEP (builder, module->got_var, indexes, 2, "");
2617 args [0] = LLVMBuildPtrToInt (builder, LLVMBuildLoad (builder, got_entry_addr, ""), IntPtrType (), "");
2618 args [1] = LLVMGetParam (func, 0);
2620 args [2] = LLVMGetParam (func, 1);
2622 ji = g_new0 (MonoJumpInfo, 1);
2623 ji->type = MONO_PATCH_INFO_INTERNAL_METHOD;
2624 ji->data.name = icall_name;
2625 ji = mono_aot_patch_info_dup (ji);
2626 got_offset = mono_aot_get_got_offset (ji);
2627 module->max_got_offset = MAX (module->max_got_offset, got_offset);
2628 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
2629 indexes [1] = LLVMConstInt (LLVMInt32Type (), got_offset, FALSE);
2630 got_entry_addr = LLVMBuildGEP (builder, module->got_var, indexes, 2, "");
2631 callee = LLVMBuildLoad (builder, got_entry_addr, "");
2632 callee = LLVMBuildBitCast (builder, callee, LLVMPointerType (sig, 0), "");
2633 LLVMBuildCall (builder, callee, args, LLVMCountParamTypes (sig), "");
2635 // Set the inited flag
2636 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
2637 indexes [1] = LLVMGetParam (func, 0);
2638 LLVMBuildStore (builder, LLVMConstInt (LLVMInt8Type (), 1, FALSE), LLVMBuildGEP (builder, module->inited_var, indexes, 2, ""));
2640 LLVMBuildRetVoid (builder);
2642 LLVMVerifyFunction(func, LLVMAbortProcessAction);
2647 * Emit wrappers around the C icalls used to initialize llvm methods, to
2648 * make the calling code smaller and to enable usage of the llvm
2649 * PreserveAll calling convention.
2652 emit_init_icall_wrappers (MonoLLVMModule *module)
2654 module->init_method = emit_init_icall_wrapper (module, "init_method", "mono_aot_init_llvm_method", 0);
2655 module->init_method_gshared_mrgctx = emit_init_icall_wrapper (module, "init_method_gshared_mrgctx", "mono_aot_init_gshared_method_mrgctx", 1);
2656 module->init_method_gshared_this = emit_init_icall_wrapper (module, "init_method_gshared_this", "mono_aot_init_gshared_method_this", 2);
2657 module->init_method_gshared_vtable = emit_init_icall_wrapper (module, "init_method_gshared_vtable", "mono_aot_init_gshared_method_vtable", 3);
2661 emit_llvm_code_end (MonoLLVMModule *module)
2663 LLVMModuleRef lmodule = module->lmodule;
2665 LLVMBasicBlockRef entry_bb;
2666 LLVMBuilderRef builder;
2668 func = LLVMAddFunction (lmodule, "llvm_code_end", LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE));
2669 LLVMSetLinkage (func, LLVMInternalLinkage);
2670 LLVMAddFunctionAttr (func, LLVMNoUnwindAttribute);
2671 module->code_end = func;
2672 entry_bb = LLVMAppendBasicBlock (func, "ENTRY");
2673 builder = LLVMCreateBuilder ();
2674 LLVMPositionBuilderAtEnd (builder, entry_bb);
2675 LLVMBuildRetVoid (builder);
2679 emit_div_check (EmitContext *ctx, LLVMBuilderRef builder, MonoBasicBlock *bb, MonoInst *ins, LLVMValueRef lhs, LLVMValueRef rhs)
2681 gboolean need_div_check = ctx->cfg->backend->need_div_check;
2684 /* LLVM doesn't know that these can throw an exception since they are not called through an intrinsic */
2685 need_div_check = TRUE;
2687 if (!need_div_check)
2690 switch (ins->opcode) {
2703 case OP_IDIV_UN_IMM:
2704 case OP_LDIV_UN_IMM:
2705 case OP_IREM_UN_IMM:
2706 case OP_LREM_UN_IMM: {
2708 gboolean is_signed = (ins->opcode == OP_IDIV || ins->opcode == OP_LDIV || ins->opcode == OP_IREM || ins->opcode == OP_LREM ||
2709 ins->opcode == OP_IDIV_IMM || ins->opcode == OP_LDIV_IMM || ins->opcode == OP_IREM_IMM || ins->opcode == OP_LREM_IMM);
2711 cmp = LLVMBuildICmp (builder, LLVMIntEQ, rhs, LLVMConstInt (LLVMTypeOf (rhs), 0, FALSE), "");
2712 emit_cond_system_exception (ctx, bb, "DivideByZeroException", cmp);
2715 builder = ctx->builder;
2717 /* b == -1 && a == 0x80000000 */
2719 LLVMValueRef c = (LLVMTypeOf (lhs) == LLVMInt32Type ()) ? LLVMConstInt (LLVMTypeOf (lhs), 0x80000000, FALSE) : LLVMConstInt (LLVMTypeOf (lhs), 0x8000000000000000LL, FALSE);
2720 LLVMValueRef cond1 = LLVMBuildICmp (builder, LLVMIntEQ, rhs, LLVMConstInt (LLVMTypeOf (rhs), -1, FALSE), "");
2721 LLVMValueRef cond2 = LLVMBuildICmp (builder, LLVMIntEQ, lhs, c, "");
2723 cmp = LLVMBuildICmp (builder, LLVMIntEQ, LLVMBuildAnd (builder, cond1, cond2, ""), LLVMConstInt (LLVMInt1Type (), 1, FALSE), "");
2724 emit_cond_system_exception (ctx, bb, "OverflowException", cmp);
2727 builder = ctx->builder;
2739 * Emit code to initialize the GOT slots used by the method.
2742 emit_init_method (EmitContext *ctx)
2744 LLVMValueRef indexes [16], args [16], callee;
2745 LLVMValueRef inited_var, cmp, call;
2746 LLVMBasicBlockRef inited_bb, notinited_bb;
2747 LLVMBuilderRef builder = ctx->builder;
2748 MonoCompile *cfg = ctx->cfg;
2750 ctx->module->max_inited_idx = MAX (ctx->module->max_inited_idx, cfg->method_index);
2752 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
2753 indexes [1] = LLVMConstInt (LLVMInt32Type (), cfg->method_index, FALSE);
2754 inited_var = LLVMBuildLoad (builder, LLVMBuildGEP (builder, ctx->module->inited_var, indexes, 2, ""), "is_inited");
2756 args [0] = inited_var;
2757 args [1] = LLVMConstInt (LLVMInt8Type (), 1, FALSE);
2758 inited_var = LLVMBuildCall (ctx->builder, get_intrinsic (ctx, "llvm.expect.i8"), args, 2, "");
2760 cmp = LLVMBuildICmp (builder, LLVMIntEQ, inited_var, LLVMConstInt (LLVMTypeOf (inited_var), 0, FALSE), "");
2762 inited_bb = ctx->inited_bb;
2763 notinited_bb = gen_bb (ctx, "NOTINITED_BB");
2765 LLVMBuildCondBr (ctx->builder, cmp, notinited_bb, inited_bb);
2767 builder = ctx->builder = create_builder (ctx);
2768 LLVMPositionBuilderAtEnd (ctx->builder, notinited_bb);
2771 if (ctx->rgctx_arg && cfg->method->is_inflated && mono_method_get_context (cfg->method)->method_inst) {
2772 args [0] = LLVMConstInt (LLVMInt32Type (), cfg->method_index, 0);
2773 args [1] = convert (ctx, ctx->rgctx_arg, IntPtrType ());
2774 callee = ctx->module->init_method_gshared_mrgctx;
2775 call = LLVMBuildCall (builder, callee, args, 2, "");
2776 } else if (ctx->rgctx_arg) {
2777 /* A vtable is passed as the rgctx argument */
2778 args [0] = LLVMConstInt (LLVMInt32Type (), cfg->method_index, 0);
2779 args [1] = convert (ctx, ctx->rgctx_arg, IntPtrType ());
2780 callee = ctx->module->init_method_gshared_vtable;
2781 call = LLVMBuildCall (builder, callee, args, 2, "");
2782 } else if (cfg->gshared) {
2783 args [0] = LLVMConstInt (LLVMInt32Type (), cfg->method_index, 0);
2784 args [1] = convert (ctx, ctx->this_arg, ObjRefType ());
2785 callee = ctx->module->init_method_gshared_this;
2786 call = LLVMBuildCall (builder, callee, args, 2, "");
2788 args [0] = LLVMConstInt (LLVMInt32Type (), cfg->method_index, 0);
2789 callee = ctx->module->init_method;
2790 call = LLVMBuildCall (builder, callee, args, 1, "");
2794 * This enables llvm to keep arguments in their original registers/
2795 * scratch registers, since the call will not clobber them.
2797 mono_llvm_set_call_preserveall_cc (call);
2799 LLVMBuildBr (builder, inited_bb);
2800 ctx->bblocks [cfg->bb_entry->block_num].end_bblock = inited_bb;
2802 builder = ctx->builder = create_builder (ctx);
2803 LLVMPositionBuilderAtEnd (ctx->builder, inited_bb);
2807 emit_unbox_tramp (EmitContext *ctx, const char *method_name, LLVMTypeRef method_type, LLVMValueRef method, int method_index)
2810 * Emit unbox trampoline using a tail call
2812 LLVMValueRef tramp, call, *args;
2813 LLVMBuilderRef builder;
2814 LLVMBasicBlockRef lbb;
2815 LLVMCallInfo *linfo;
2819 tramp_name = g_strdup_printf ("ut_%s", method_name);
2820 tramp = LLVMAddFunction (ctx->module->lmodule, tramp_name, method_type);
2821 LLVMSetLinkage (tramp, LLVMInternalLinkage);
2822 LLVMAddFunctionAttr (tramp, LLVMOptimizeForSizeAttribute);
2823 //LLVMAddFunctionAttr (tramp, LLVMNoUnwindAttribute);
2825 // FIXME: Reduce code duplication with mono_llvm_compile_method () etc.
2826 if (!ctx->llvm_only && ctx->rgctx_arg_pindex != -1)
2827 LLVMAddAttribute (LLVMGetParam (tramp, ctx->rgctx_arg_pindex), LLVMInRegAttribute);
2828 if (ctx->cfg->vret_addr) {
2829 LLVMSetValueName (LLVMGetParam (tramp, linfo->vret_arg_pindex), "vret");
2830 if (linfo->ret.storage == LLVMArgVtypeByRef) {
2831 LLVMAddAttribute (LLVMGetParam (tramp, linfo->vret_arg_pindex), LLVMStructRetAttribute);
2832 LLVMAddAttribute (LLVMGetParam (tramp, linfo->vret_arg_pindex), LLVMNoAliasAttribute);
2836 lbb = LLVMAppendBasicBlock (tramp, "");
2837 builder = LLVMCreateBuilder ();
2838 LLVMPositionBuilderAtEnd (builder, lbb);
2840 nargs = LLVMCountParamTypes (method_type);
2841 args = g_new0 (LLVMValueRef, nargs);
2842 for (i = 0; i < nargs; ++i) {
2843 args [i] = LLVMGetParam (tramp, i);
2844 if (i == ctx->this_arg_pindex) {
2845 LLVMTypeRef arg_type = LLVMTypeOf (args [i]);
2847 args [i] = LLVMBuildPtrToInt (builder, args [i], IntPtrType (), "");
2848 args [i] = LLVMBuildAdd (builder, args [i], LLVMConstInt (IntPtrType (), sizeof (MonoObject), FALSE), "");
2849 args [i] = LLVMBuildIntToPtr (builder, args [i], arg_type, "");
2852 call = LLVMBuildCall (builder, method, args, nargs, "");
2853 if (!ctx->llvm_only && ctx->rgctx_arg_pindex != -1)
2854 LLVMAddInstrAttribute (call, 1 + ctx->rgctx_arg_pindex, LLVMInRegAttribute);
2855 if (linfo->ret.storage == LLVMArgVtypeByRef)
2856 LLVMAddInstrAttribute (call, 1 + linfo->vret_arg_pindex, LLVMStructRetAttribute);
2858 // FIXME: This causes assertions in clang
2859 //mono_llvm_set_must_tail (call);
2860 if (LLVMGetReturnType (method_type) == LLVMVoidType ())
2861 LLVMBuildRetVoid (builder);
2863 LLVMBuildRet (builder, call);
2865 g_hash_table_insert (ctx->module->idx_to_unbox_tramp, GINT_TO_POINTER (method_index), tramp);
2871 * Emit code to load/convert arguments.
2874 emit_entry_bb (EmitContext *ctx, LLVMBuilderRef builder)
2877 MonoCompile *cfg = ctx->cfg;
2878 MonoMethodSignature *sig = ctx->sig;
2879 LLVMCallInfo *linfo = ctx->linfo;
2883 LLVMBuilderRef old_builder = ctx->builder;
2884 ctx->builder = builder;
2886 ctx->alloca_builder = create_builder (ctx);
2889 * Handle indirect/volatile variables by allocating memory for them
2890 * using 'alloca', and storing their address in a temporary.
2892 for (i = 0; i < cfg->num_varinfo; ++i) {
2893 MonoInst *var = cfg->varinfo [i];
2896 if (var->opcode == OP_GSHAREDVT_LOCAL || var->opcode == OP_GSHAREDVT_ARG_REGOFFSET) {
2897 } 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))) {
2898 vtype = type_to_llvm_type (ctx, var->inst_vtype);
2901 /* Could be already created by an OP_VPHI */
2902 if (!ctx->addresses [var->dreg]) {
2903 ctx->addresses [var->dreg] = build_alloca (ctx, var->inst_vtype);
2904 //LLVMSetValueName (ctx->addresses [var->dreg], g_strdup_printf ("vreg_loc_%d", var->dreg));
2906 ctx->vreg_cli_types [var->dreg] = var->inst_vtype;
2910 names = g_new (char *, sig->param_count);
2911 mono_method_get_param_names (cfg->method, (const char **) names);
2913 for (i = 0; i < sig->param_count; ++i) {
2914 LLVMArgInfo *ainfo = &linfo->args [i + sig->hasthis];
2915 int reg = cfg->args [i + sig->hasthis]->dreg;
2918 pindex = ainfo->pindex;
2920 switch (ainfo->storage) {
2921 case LLVMArgVtypeInReg:
2922 case LLVMArgAsFpArgs: {
2923 LLVMValueRef args [8];
2926 pindex += ainfo->ndummy_fpargs;
2928 /* The argument is received as a set of int/fp arguments, store them into the real argument */
2929 memset (args, 0, sizeof (args));
2930 if (ainfo->storage == LLVMArgVtypeInReg) {
2931 args [0] = LLVMGetParam (ctx->lmethod, pindex);
2932 if (ainfo->pair_storage [1] != LLVMArgNone)
2933 args [1] = LLVMGetParam (ctx->lmethod, pindex + 1);
2935 g_assert (ainfo->nslots <= 8);
2936 for (j = 0; j < ainfo->nslots; ++j)
2937 args [j] = LLVMGetParam (ctx->lmethod, pindex + j);
2939 ctx->addresses [reg] = build_alloca (ctx, ainfo->type);
2941 emit_args_to_vtype (ctx, builder, ainfo->type, ctx->addresses [reg], ainfo, args);
2943 if (ainfo->storage == LLVMArgVtypeInReg && MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (ainfo->type))) {
2944 /* Treat these as normal values */
2945 ctx->values [reg] = LLVMBuildLoad (builder, ctx->addresses [reg], "");
2949 case LLVMArgVtypeByVal: {
2950 ctx->addresses [reg] = LLVMGetParam (ctx->lmethod, pindex);
2952 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (ainfo->type))) {
2953 /* Treat these as normal values */
2954 ctx->values [reg] = LLVMBuildLoad (builder, ctx->addresses [reg], "");
2958 case LLVMArgVtypeByRef: {
2959 /* The argument is passed by ref */
2960 ctx->addresses [reg] = LLVMGetParam (ctx->lmethod, pindex);
2963 case LLVMArgAsIArgs: {
2964 LLVMValueRef arg = LLVMGetParam (ctx->lmethod, pindex);
2967 /* The argument is received as an array of ints, store it into the real argument */
2968 ctx->addresses [reg] = build_alloca (ctx, ainfo->type);
2970 size = mono_class_value_size (mono_class_from_mono_type (ainfo->type), NULL);
2971 if (size < SIZEOF_VOID_P) {
2972 /* The upper bits of the registers might not be valid */
2973 LLVMValueRef val = LLVMBuildExtractValue (builder, arg, 0, "");
2974 LLVMValueRef dest = convert (ctx, ctx->addresses [reg], LLVMPointerType (LLVMIntType (size * 8), 0));
2975 LLVMBuildStore (ctx->builder, LLVMBuildTrunc (builder, val, LLVMIntType (size * 8), ""), dest);
2977 LLVMBuildStore (ctx->builder, arg, convert (ctx, ctx->addresses [reg], LLVMPointerType (LLVMTypeOf (arg), 0)));
2981 case LLVMArgVtypeAsScalar:
2982 g_assert_not_reached ();
2984 case LLVMArgGsharedvtFixed: {
2985 /* These are non-gsharedvt arguments passed by ref, the rest of the IR treats them as scalars */
2986 LLVMValueRef arg = LLVMGetParam (ctx->lmethod, pindex);
2989 name = g_strdup_printf ("arg_%s", names [i]);
2991 name = g_strdup_printf ("arg_%d", i);
2993 ctx->values [reg] = LLVMBuildLoad (builder, convert (ctx, arg, LLVMPointerType (type_to_llvm_type (ctx, ainfo->type), 0)), name);
2996 case LLVMArgGsharedvtFixedVtype: {
2997 LLVMValueRef arg = LLVMGetParam (ctx->lmethod, pindex);
3000 name = g_strdup_printf ("vtype_arg_%s", names [i]);
3002 name = g_strdup_printf ("vtype_arg_%d", i);
3004 /* Non-gsharedvt vtype argument passed by ref, the rest of the IR treats it as a vtype */
3005 g_assert (ctx->addresses [reg]);
3006 LLVMSetValueName (ctx->addresses [reg], name);
3007 LLVMBuildStore (builder, LLVMBuildLoad (builder, convert (ctx, arg, LLVMPointerType (type_to_llvm_type (ctx, ainfo->type), 0)), ""), ctx->addresses [reg]);
3010 case LLVMArgGsharedvtVariable:
3011 /* The IR treats these as variables with addresses */
3012 ctx->addresses [reg] = LLVMGetParam (ctx->lmethod, pindex);
3015 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));
3022 emit_volatile_store (ctx, cfg->vret_addr->dreg);
3024 emit_volatile_store (ctx, cfg->args [0]->dreg);
3025 for (i = 0; i < sig->param_count; ++i)
3026 if (!mini_type_is_vtype (sig->params [i]))
3027 emit_volatile_store (ctx, cfg->args [i + sig->hasthis]->dreg);
3029 if (sig->hasthis && !cfg->rgctx_var && cfg->gshared) {
3030 LLVMValueRef this_alloc;
3033 * The exception handling code needs the location where the this argument was
3034 * stored for gshared methods. We create a separate alloca to hold it, and mark it
3035 * with the "mono.this" custom metadata to tell llvm that it needs to save its
3036 * location into the LSDA.
3038 this_alloc = mono_llvm_build_alloca (builder, ThisType (), LLVMConstInt (LLVMInt32Type (), 1, FALSE), 0, "");
3039 /* This volatile store will keep the alloca alive */
3040 mono_llvm_build_store (builder, ctx->values [cfg->args [0]->dreg], this_alloc, TRUE, LLVM_BARRIER_NONE);
3042 set_metadata_flag (this_alloc, "mono.this");
3045 if (cfg->rgctx_var) {
3046 LLVMValueRef rgctx_alloc, store;
3049 * We handle the rgctx arg similarly to the this pointer.
3051 g_assert (ctx->addresses [cfg->rgctx_var->dreg]);
3052 rgctx_alloc = ctx->addresses [cfg->rgctx_var->dreg];
3053 /* This volatile store will keep the alloca alive */
3054 store = mono_llvm_build_store (builder, convert (ctx, ctx->rgctx_arg, IntPtrType ()), rgctx_alloc, TRUE, LLVM_BARRIER_NONE);
3056 set_metadata_flag (rgctx_alloc, "mono.this");
3059 /* Initialize the method if needed */
3060 if (cfg->compile_aot && ctx->llvm_only) {
3061 /* Emit a location for the initialization code */
3062 ctx->init_bb = gen_bb (ctx, "INIT_BB");
3063 ctx->inited_bb = gen_bb (ctx, "INITED_BB");
3065 LLVMBuildBr (ctx->builder, ctx->init_bb);
3066 builder = ctx->builder = create_builder (ctx);
3067 LLVMPositionBuilderAtEnd (ctx->builder, ctx->inited_bb);
3068 ctx->bblocks [cfg->bb_entry->block_num].end_bblock = ctx->inited_bb;
3071 /* Compute nesting between clauses */
3072 ctx->nested_in = (GSList**)mono_mempool_alloc0 (cfg->mempool, sizeof (GSList*) * cfg->header->num_clauses);
3073 for (i = 0; i < cfg->header->num_clauses; ++i) {
3074 for (j = 0; j < cfg->header->num_clauses; ++j) {
3075 MonoExceptionClause *clause1 = &cfg->header->clauses [i];
3076 MonoExceptionClause *clause2 = &cfg->header->clauses [j];
3078 if (i != j && clause1->try_offset >= clause2->try_offset && clause1->handler_offset <= clause2->handler_offset)
3079 ctx->nested_in [i] = g_slist_prepend_mempool (cfg->mempool, ctx->nested_in [i], GINT_TO_POINTER (j));
3084 * For finally clauses, create an indicator variable telling OP_ENDFINALLY whenever
3085 * it needs to continue normally, or return back to the exception handling system.
3087 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
3091 if (!(bb->region != -1 && (bb->flags & BB_EXCEPTION_HANDLER)))
3094 clause_index = MONO_REGION_CLAUSE_INDEX (bb->region);
3095 g_hash_table_insert (ctx->region_to_handler, GUINT_TO_POINTER (mono_get_block_region_notry (cfg, bb->region)), bb);
3096 g_hash_table_insert (ctx->clause_to_handler, GINT_TO_POINTER (clause_index), bb);
3098 if (bb->in_scount == 0) {
3101 sprintf (name, "finally_ind_bb%d", bb->block_num);
3102 val = LLVMBuildAlloca (builder, LLVMInt32Type (), name);
3103 LLVMBuildStore (builder, LLVMConstInt (LLVMInt32Type (), 0, FALSE), val);
3105 ctx->bblocks [bb->block_num].finally_ind = val;
3107 /* Create a variable to hold the exception var */
3109 ctx->ex_var = LLVMBuildAlloca (builder, ObjRefType (), "exvar");
3113 * Create a new bblock which CALL_HANDLER/landing pads can branch to, because branching to the
3114 * LLVM bblock containing a landing pad causes problems for the
3115 * LLVM optimizer passes.
3117 sprintf (name, "BB%d_CALL_HANDLER_TARGET", bb->block_num);
3118 ctx->bblocks [bb->block_num].call_handler_target_bb = LLVMAppendBasicBlock (ctx->lmethod, name);
3120 ctx->builder = old_builder;
3124 process_call (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, MonoInst *ins)
3126 MonoCompile *cfg = ctx->cfg;
3127 LLVMValueRef *values = ctx->values;
3128 LLVMValueRef *addresses = ctx->addresses;
3129 MonoCallInst *call = (MonoCallInst*)ins;
3130 MonoMethodSignature *sig = call->signature;
3131 LLVMValueRef callee = NULL, lcall;
3133 LLVMCallInfo *cinfo;
3137 LLVMTypeRef llvm_sig;
3139 gboolean is_virtual, calli, preserveall;
3140 LLVMBuilderRef builder = *builder_ref;
3142 if ((call->signature->call_convention != MONO_CALL_DEFAULT) && !((call->signature->call_convention == MONO_CALL_C) && ctx->llvm_only)) {
3143 set_failure (ctx, "non-default callconv");
3147 cinfo = call->cinfo;
3149 if (call->rgctx_arg_reg)
3150 cinfo->rgctx_arg = TRUE;
3151 if (call->imt_arg_reg)
3152 cinfo->imt_arg = TRUE;
3154 vretaddr = (cinfo->ret.storage == LLVMArgVtypeRetAddr || cinfo->ret.storage == LLVMArgVtypeByRef || cinfo->ret.storage == LLVMArgGsharedvtFixed || cinfo->ret.storage == LLVMArgGsharedvtVariable || cinfo->ret.storage == LLVMArgGsharedvtFixedVtype);
3156 llvm_sig = sig_to_llvm_sig_full (ctx, sig, cinfo);
3160 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);
3161 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);
3163 preserveall = FALSE;
3165 /* FIXME: Avoid creating duplicate methods */
3167 if (ins->flags & MONO_INST_HAS_METHOD) {
3171 if (cfg->compile_aot) {
3172 callee = get_callee (ctx, llvm_sig, MONO_PATCH_INFO_METHOD, call->method);
3174 set_failure (ctx, "can't encode patch");
3177 if (cfg->llvm_only && call->method->klass->image->assembly == ctx->module->assembly) {
3179 * Collect instructions representing the callee into a hash so they can be replaced
3180 * by the llvm method for the callee if the callee turns out to be direct
3181 * callable. Currently this only requires it to not fail llvm compilation.
3183 GSList *l = (GSList*)g_hash_table_lookup (ctx->method_to_callers, call->method);
3184 l = g_slist_prepend (l, callee);
3185 g_hash_table_insert (ctx->method_to_callers, call->method, l);
3189 static int tramp_index;
3192 name = g_strdup_printf ("tramp_%d", tramp_index);
3195 #if LLVM_API_VERSION > 100
3197 * Use our trampoline infrastructure for lazy compilation instead of llvm's.
3198 * Make all calls through a global. The address of the global will be saved in
3199 * MonoJitDomainInfo.llvm_jit_callees and updated when the method it refers to is
3202 LLVMValueRef tramp_var = g_hash_table_lookup (ctx->jit_callees, call->method);
3205 mono_create_jit_trampoline (mono_domain_get (),
3206 call->method, &error);
3207 if (!is_ok (&error)) {
3208 set_failure (ctx, mono_error_get_message (&error));
3209 mono_error_cleanup (&error);
3213 tramp_var = LLVMAddGlobal (ctx->lmodule, LLVMPointerType (llvm_sig, 0), name);
3214 LLVMSetInitializer (tramp_var, LLVMConstIntToPtr (LLVMConstInt (LLVMInt64Type (), (guint64)(size_t)target, FALSE), LLVMPointerType (llvm_sig, 0)));
3215 LLVMSetLinkage (tramp_var, LLVMExternalLinkage);
3216 g_hash_table_insert (ctx->jit_callees, call->method, tramp_var);
3218 callee = LLVMBuildLoad (builder, tramp_var, "");
3221 mono_create_jit_trampoline (mono_domain_get (),
3222 call->method, &error);
3223 if (!is_ok (&error)) {
3225 set_failure (ctx, mono_error_get_message (&error));
3226 mono_error_cleanup (&error);
3230 callee = LLVMAddFunction (ctx->lmodule, name, llvm_sig);
3233 LLVMAddGlobalMapping (ctx->module->ee, callee, target);
3238 if (!cfg->llvm_only && call->method && strstr (call->method->klass->name, "AsyncVoidMethodBuilder")) {
3239 /* LLVM miscompiles async methods */
3240 set_failure (ctx, "#13734");
3245 MonoJitICallInfo *info = mono_find_jit_icall_by_addr (call->fptr);
3251 memset (&ji, 0, sizeof (ji));
3252 ji.type = MONO_PATCH_INFO_JIT_ICALL_ADDR;
3253 ji.data.target = info->name;
3255 target = mono_resolve_patch_target (cfg->method, cfg->domain, NULL, &ji, FALSE);
3257 if (cfg->compile_aot) {
3258 callee = get_callee (ctx, llvm_sig, MONO_PATCH_INFO_INTERNAL_METHOD, (char*)info->name);
3260 set_failure (ctx, "can't encode patch");
3264 target = (gpointer)mono_icall_get_wrapper (info);
3265 callee = emit_jit_callee (ctx, "", llvm_sig, target);
3268 if (cfg->compile_aot) {
3270 if (cfg->abs_patches) {
3271 MonoJumpInfo *abs_ji = (MonoJumpInfo*)g_hash_table_lookup (cfg->abs_patches, call->fptr);
3273 callee = get_callee (ctx, llvm_sig, abs_ji->type, abs_ji->data.target);
3275 set_failure (ctx, "can't encode patch");
3281 set_failure (ctx, "aot");
3285 #if LLVM_API_VERSION > 100
3286 if (cfg->abs_patches) {
3287 MonoJumpInfo *abs_ji = (MonoJumpInfo*)g_hash_table_lookup (cfg->abs_patches, call->fptr);
3291 target = mono_resolve_patch_target (cfg->method, cfg->domain, NULL, abs_ji, FALSE, &error);
3292 mono_error_assert_ok (&error);
3293 callee = emit_jit_callee (ctx, "", llvm_sig, target);
3295 g_assert_not_reached ();
3298 g_assert_not_reached ();
3301 callee = LLVMAddFunction (ctx->lmodule, "", llvm_sig);
3303 if (cfg->abs_patches) {
3304 MonoJumpInfo *abs_ji = (MonoJumpInfo*)g_hash_table_lookup (cfg->abs_patches, call->fptr);
3309 * FIXME: Some trampolines might have
3310 * their own calling convention on some platforms.
3312 target = mono_resolve_patch_target (cfg->method, cfg->domain, NULL, abs_ji, FALSE, &error);
3313 mono_error_assert_ok (&error);
3314 LLVMAddGlobalMapping (ctx->module->ee, callee, target);
3318 LLVMAddGlobalMapping (ctx->module->ee, callee, (gpointer)call->fptr);
3325 int size = sizeof (gpointer);
3328 g_assert (ins->inst_offset % size == 0);
3329 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
3331 callee = convert (ctx, LLVMBuildLoad (builder, LLVMBuildGEP (builder, convert (ctx, values [ins->inst_basereg], LLVMPointerType (LLVMPointerType (IntPtrType (), 0), 0)), &index, 1, ""), ""), LLVMPointerType (llvm_sig, 0));
3333 callee = convert (ctx, values [ins->sreg1], LLVMPointerType (llvm_sig, 0));
3335 if (ins->flags & MONO_INST_HAS_METHOD) {
3340 * Collect and convert arguments
3342 nargs = (sig->param_count * 16) + sig->hasthis + vretaddr + call->rgctx_reg + call->imt_arg_reg;
3343 len = sizeof (LLVMValueRef) * nargs;
3344 args = (LLVMValueRef*)alloca (len);
3345 memset (args, 0, len);
3346 l = call->out_ireg_args;
3348 if (call->rgctx_arg_reg) {
3349 g_assert (values [call->rgctx_arg_reg]);
3350 g_assert (cinfo->rgctx_arg_pindex < nargs);
3352 * On ARM, the imt/rgctx argument is passed in a caller save register, but some of our trampolines etc. clobber it, leading to
3353 * problems is LLVM moves the arg assignment earlier. To work around this, save the argument into a stack slot and load
3354 * it using a volatile load.
3357 if (!ctx->imt_rgctx_loc)
3358 ctx->imt_rgctx_loc = build_alloca_llvm_type (ctx, ctx->module->ptr_type, sizeof (gpointer));
3359 LLVMBuildStore (builder, convert (ctx, ctx->values [call->rgctx_arg_reg], ctx->module->ptr_type), ctx->imt_rgctx_loc);
3360 args [cinfo->rgctx_arg_pindex] = mono_llvm_build_load (builder, ctx->imt_rgctx_loc, "", TRUE, LLVM_BARRIER_NONE);
3362 args [cinfo->rgctx_arg_pindex] = convert (ctx, values [call->rgctx_arg_reg], ctx->module->ptr_type);
3365 if (call->imt_arg_reg) {
3366 g_assert (!ctx->llvm_only);
3367 g_assert (values [call->imt_arg_reg]);
3368 g_assert (cinfo->imt_arg_pindex < nargs);
3370 if (!ctx->imt_rgctx_loc)
3371 ctx->imt_rgctx_loc = build_alloca_llvm_type (ctx, ctx->module->ptr_type, sizeof (gpointer));
3372 LLVMBuildStore (builder, convert (ctx, ctx->values [call->imt_arg_reg], ctx->module->ptr_type), ctx->imt_rgctx_loc);
3373 args [cinfo->imt_arg_pindex] = mono_llvm_build_load (builder, ctx->imt_rgctx_loc, "", TRUE, LLVM_BARRIER_NONE);
3375 args [cinfo->imt_arg_pindex] = convert (ctx, values [call->imt_arg_reg], ctx->module->ptr_type);
3378 switch (cinfo->ret.storage) {
3379 case LLVMArgGsharedvtVariable: {
3380 MonoInst *var = get_vreg_to_inst (cfg, call->inst.dreg);
3382 if (var && var->opcode == OP_GSHAREDVT_LOCAL) {
3383 args [cinfo->vret_arg_pindex] = convert (ctx, emit_gsharedvt_ldaddr (ctx, var->dreg), IntPtrType ());
3385 g_assert (addresses [call->inst.dreg]);
3386 args [cinfo->vret_arg_pindex] = addresses [call->inst.dreg];
3392 if (!addresses [call->inst.dreg])
3393 addresses [call->inst.dreg] = build_alloca (ctx, sig->ret);
3394 g_assert (cinfo->vret_arg_pindex < nargs);
3395 if (cinfo->ret.storage == LLVMArgVtypeByRef)
3396 args [cinfo->vret_arg_pindex] = addresses [call->inst.dreg];
3398 args [cinfo->vret_arg_pindex] = LLVMBuildPtrToInt (builder, addresses [call->inst.dreg], IntPtrType (), "");
3404 * Sometimes the same method is called with two different signatures (i.e. with and without 'this'), so
3405 * use the real callee for argument type conversion.
3407 LLVMTypeRef callee_type = LLVMGetElementType (LLVMTypeOf (callee));
3408 LLVMTypeRef *param_types = (LLVMTypeRef*)g_alloca (sizeof (LLVMTypeRef) * LLVMCountParamTypes (callee_type));
3409 LLVMGetParamTypes (callee_type, param_types);
3411 for (i = 0; i < sig->param_count + sig->hasthis; ++i) {
3414 LLVMArgInfo *ainfo = &call->cinfo->args [i];
3416 pindex = ainfo->pindex;
3418 regpair = (guint32)(gssize)(l->data);
3419 reg = regpair & 0xffffff;
3420 args [pindex] = values [reg];
3421 switch (ainfo->storage) {
3422 case LLVMArgVtypeInReg:
3423 case LLVMArgAsFpArgs: {
3427 for (j = 0; j < ainfo->ndummy_fpargs; ++j)
3428 args [pindex + j] = LLVMConstNull (LLVMDoubleType ());
3429 pindex += ainfo->ndummy_fpargs;
3431 g_assert (addresses [reg]);
3432 emit_vtype_to_args (ctx, builder, ainfo->type, addresses [reg], ainfo, args + pindex, &nargs);
3436 // FIXME: Get rid of the VMOVE
3439 case LLVMArgVtypeByVal:
3440 g_assert (addresses [reg]);
3441 args [pindex] = addresses [reg];
3443 case LLVMArgVtypeByRef: {
3444 g_assert (addresses [reg]);
3445 args [pindex] = convert (ctx, addresses [reg], LLVMPointerType (type_to_llvm_arg_type (ctx, ainfo->type), 0));
3448 case LLVMArgAsIArgs:
3449 g_assert (addresses [reg]);
3450 args [pindex] = LLVMBuildLoad (ctx->builder, convert (ctx, addresses [reg], LLVMPointerType (LLVMArrayType (IntPtrType (), ainfo->nslots), 0)), "");
3452 case LLVMArgVtypeAsScalar:
3453 g_assert_not_reached ();
3455 case LLVMArgGsharedvtFixed:
3456 case LLVMArgGsharedvtFixedVtype:
3457 g_assert (addresses [reg]);
3458 args [pindex] = convert (ctx, addresses [reg], LLVMPointerType (type_to_llvm_arg_type (ctx, ainfo->type), 0));
3460 case LLVMArgGsharedvtVariable:
3461 g_assert (addresses [reg]);
3462 args [pindex] = convert (ctx, addresses [reg], LLVMPointerType (IntPtrType (), 0));
3465 g_assert (args [pindex]);
3466 if (i == 0 && sig->hasthis)
3467 args [pindex] = convert (ctx, args [pindex], param_types [pindex]);
3469 args [pindex] = convert (ctx, args [pindex], type_to_llvm_arg_type (ctx, ainfo->type));
3472 g_assert (pindex <= nargs);
3477 // FIXME: Align call sites
3483 lcall = emit_call (ctx, bb, &builder, callee, args, LLVMCountParamTypes (llvm_sig));
3486 * Modify cconv and parameter attributes to pass rgctx/imt correctly.
3488 #if defined(MONO_ARCH_IMT_REG) && defined(MONO_ARCH_RGCTX_REG)
3489 g_assert (MONO_ARCH_IMT_REG == MONO_ARCH_RGCTX_REG);
3491 /* The two can't be used together, so use only one LLVM calling conv to pass them */
3492 g_assert (!(call->rgctx_arg_reg && call->imt_arg_reg));
3493 if (!sig->pinvoke && !cfg->llvm_only)
3494 LLVMSetInstructionCallConv (lcall, LLVMMono1CallConv);
3496 mono_llvm_set_call_preserveall_cc (lcall);
3498 if (cinfo->ret.storage == LLVMArgVtypeByRef)
3499 LLVMAddInstrAttribute (lcall, 1 + cinfo->vret_arg_pindex, LLVMStructRetAttribute);
3500 if (!ctx->llvm_only && call->rgctx_arg_reg)
3501 LLVMAddInstrAttribute (lcall, 1 + cinfo->rgctx_arg_pindex, LLVMInRegAttribute);
3502 if (call->imt_arg_reg)
3503 LLVMAddInstrAttribute (lcall, 1 + cinfo->imt_arg_pindex, LLVMInRegAttribute);
3505 /* Add byval attributes if needed */
3506 for (i = 0; i < sig->param_count; ++i) {
3507 LLVMArgInfo *ainfo = &call->cinfo->args [i + sig->hasthis];
3509 if (ainfo && ainfo->storage == LLVMArgVtypeByVal)
3510 LLVMAddInstrAttribute (lcall, 1 + ainfo->pindex, LLVMByValAttribute);
3514 * Convert the result
3516 switch (cinfo->ret.storage) {
3517 case LLVMArgVtypeInReg: {
3518 LLVMValueRef regs [2];
3520 if (LLVMTypeOf (lcall) == LLVMVoidType ())
3524 if (!addresses [ins->dreg])
3525 addresses [ins->dreg] = build_alloca (ctx, sig->ret);
3527 regs [0] = LLVMBuildExtractValue (builder, lcall, 0, "");
3528 if (cinfo->ret.pair_storage [1] != LLVMArgNone)
3529 regs [1] = LLVMBuildExtractValue (builder, lcall, 1, "");
3530 emit_args_to_vtype (ctx, builder, sig->ret, addresses [ins->dreg], &cinfo->ret, regs);
3533 case LLVMArgVtypeByVal:
3534 if (!addresses [call->inst.dreg])
3535 addresses [call->inst.dreg] = build_alloca (ctx, sig->ret);
3536 LLVMBuildStore (builder, lcall, addresses [call->inst.dreg]);
3538 case LLVMArgAsIArgs:
3539 case LLVMArgFpStruct:
3540 if (!addresses [call->inst.dreg])
3541 addresses [call->inst.dreg] = build_alloca (ctx, sig->ret);
3542 LLVMBuildStore (builder, lcall, convert_full (ctx, addresses [call->inst.dreg], LLVMPointerType (LLVMTypeOf (lcall), 0), FALSE));
3544 case LLVMArgVtypeAsScalar:
3545 if (!addresses [call->inst.dreg])
3546 addresses [call->inst.dreg] = build_alloca (ctx, sig->ret);
3547 LLVMBuildStore (builder, lcall, convert_full (ctx, addresses [call->inst.dreg], LLVMPointerType (LLVMTypeOf (lcall), 0), FALSE));
3549 case LLVMArgVtypeRetAddr:
3550 case LLVMArgVtypeByRef:
3551 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (sig->ret))) {
3552 /* Some opcodes like STOREX_MEMBASE access these by value */
3553 g_assert (addresses [call->inst.dreg]);
3554 values [ins->dreg] = LLVMBuildLoad (builder, convert_full (ctx, addresses [call->inst.dreg], LLVMPointerType (type_to_llvm_type (ctx, sig->ret), 0), FALSE), "");
3557 case LLVMArgGsharedvtVariable:
3559 case LLVMArgGsharedvtFixed:
3560 case LLVMArgGsharedvtFixedVtype:
3561 values [ins->dreg] = LLVMBuildLoad (builder, convert_full (ctx, addresses [call->inst.dreg], LLVMPointerType (type_to_llvm_type (ctx, sig->ret), 0), FALSE), "");
3564 if (sig->ret->type != MONO_TYPE_VOID)
3565 /* If the method returns an unsigned value, need to zext it */
3566 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));
3570 *builder_ref = ctx->builder;
3574 emit_llvmonly_throw (EmitContext *ctx, MonoBasicBlock *bb, gboolean rethrow, LLVMValueRef exc)
3576 const char *icall_name = rethrow ? "mono_llvm_rethrow_exception" : "mono_llvm_throw_exception";
3577 LLVMValueRef callee = rethrow ? ctx->module->rethrow : ctx->module->throw_icall;
3579 LLVMTypeRef exc_type = type_to_llvm_type (ctx, &mono_get_exception_class ()->byval_arg);
3582 LLVMTypeRef fun_sig = LLVMFunctionType1 (LLVMVoidType (), exc_type, FALSE);
3584 if (ctx->cfg->compile_aot) {
3585 callee = get_callee (ctx, fun_sig, MONO_PATCH_INFO_JIT_ICALL_ADDR, icall_name);
3587 callee = LLVMAddFunction (ctx->lmodule, icall_name, fun_sig);
3588 LLVMAddGlobalMapping (ctx->module->ee, callee, resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name));
3589 mono_memory_barrier ();
3592 ctx->module->rethrow = callee;
3594 ctx->module->throw_icall = callee;
3598 LLVMValueRef args [2];
3600 args [0] = convert (ctx, exc, exc_type);
3601 emit_call (ctx, bb, &ctx->builder, callee, args, 1);
3603 LLVMBuildUnreachable (ctx->builder);
3605 ctx->builder = create_builder (ctx);
3609 emit_throw (EmitContext *ctx, MonoBasicBlock *bb, gboolean rethrow, LLVMValueRef exc)
3611 MonoMethodSignature *throw_sig;
3612 LLVMValueRef callee, arg;
3613 const char *icall_name;
3615 callee = rethrow ? ctx->module->rethrow : ctx->module->throw_icall;
3616 icall_name = rethrow ? "mono_arch_rethrow_exception" : "mono_arch_throw_exception";
3619 throw_sig = mono_metadata_signature_alloc (mono_get_corlib (), 1);
3620 throw_sig->ret = &mono_get_void_class ()->byval_arg;
3621 throw_sig->params [0] = &mono_get_object_class ()->byval_arg;
3622 if (ctx->cfg->compile_aot) {
3623 callee = get_callee (ctx, sig_to_llvm_sig (ctx, throw_sig), MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
3628 * LLVM doesn't push the exception argument, so we need a different
3631 target = resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, rethrow ? "llvm_rethrow_exception_trampoline" : "llvm_throw_exception_trampoline");
3633 target = resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
3635 callee = emit_jit_callee (ctx, icall_name, sig_to_llvm_sig (ctx, throw_sig), target);
3638 mono_memory_barrier ();
3639 #if LLVM_API_VERSION < 100
3641 ctx->module->rethrow = callee;
3643 ctx->module->throw_icall = callee;
3646 arg = convert (ctx, exc, type_to_llvm_type (ctx, &mono_get_object_class ()->byval_arg));
3647 emit_call (ctx, bb, &ctx->builder, callee, &arg, 1);
3651 emit_resume_eh (EmitContext *ctx, MonoBasicBlock *bb)
3653 const char *icall_name = "mono_llvm_resume_exception";
3654 LLVMValueRef callee = ctx->module->resume_eh;
3656 LLVMTypeRef fun_sig = LLVMFunctionType0 (LLVMVoidType (), FALSE);
3659 if (ctx->cfg->compile_aot) {
3660 callee = get_callee (ctx, fun_sig, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
3662 callee = LLVMAddFunction (ctx->lmodule, icall_name, fun_sig);
3663 LLVMAddGlobalMapping (ctx->module->ee, callee, resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name));
3664 mono_memory_barrier ();
3666 ctx->module->resume_eh = callee;
3670 emit_call (ctx, bb, &ctx->builder, callee, NULL, 0);
3672 LLVMBuildUnreachable (ctx->builder);
3674 ctx->builder = create_builder (ctx);
3678 mono_llvm_emit_clear_exception_call (EmitContext *ctx, LLVMBuilderRef builder)
3680 const char *icall_name = "mono_llvm_clear_exception";
3682 LLVMTypeRef call_sig = LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE);
3683 LLVMValueRef callee = NULL;
3686 if (ctx->cfg->compile_aot) {
3687 callee = get_callee (ctx, call_sig, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
3689 // FIXME: This is broken.
3690 callee = LLVMAddFunction (ctx->lmodule, icall_name, call_sig);
3694 g_assert (builder && callee);
3696 return LLVMBuildCall (builder, callee, NULL, 0, "");
3700 mono_llvm_emit_load_exception_call (EmitContext *ctx, LLVMBuilderRef builder)
3702 const char *icall_name = "mono_llvm_load_exception";
3704 LLVMTypeRef call_sig = LLVMFunctionType (ObjRefType (), NULL, 0, FALSE);
3705 LLVMValueRef callee = NULL;
3708 if (ctx->cfg->compile_aot) {
3709 callee = get_callee (ctx, call_sig, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
3711 // FIXME: This is broken.
3712 callee = LLVMAddFunction (ctx->lmodule, icall_name, call_sig);
3716 g_assert (builder && callee);
3718 return LLVMBuildCall (builder, callee, NULL, 0, icall_name);
3723 mono_llvm_emit_match_exception_call (EmitContext *ctx, LLVMBuilderRef builder, gint32 region_start, gint32 region_end)
3725 const char *icall_name = "mono_llvm_match_exception";
3727 ctx->builder = builder;
3729 const int num_args = 5;
3730 LLVMValueRef args [num_args];
3731 args [0] = convert (ctx, get_aotconst (ctx, MONO_PATCH_INFO_AOT_JIT_INFO, GINT_TO_POINTER (ctx->cfg->method_index)), IntPtrType ());
3732 args [1] = LLVMConstInt (LLVMInt32Type (), region_start, 0);
3733 args [2] = LLVMConstInt (LLVMInt32Type (), region_end, 0);
3734 if (ctx->cfg->rgctx_var) {
3735 LLVMValueRef rgctx_alloc = ctx->addresses [ctx->cfg->rgctx_var->dreg];
3736 g_assert (rgctx_alloc);
3737 args [3] = LLVMBuildLoad (builder, convert (ctx, rgctx_alloc, LLVMPointerType (IntPtrType (), 0)), "");
3739 args [3] = LLVMConstInt (IntPtrType (), 0, 0);
3742 args [4] = convert (ctx, ctx->this_arg, IntPtrType ());
3744 args [4] = LLVMConstInt (IntPtrType (), 0, 0);
3746 LLVMTypeRef match_sig = LLVMFunctionType5 (LLVMInt32Type (), IntPtrType (), LLVMInt32Type (), LLVMInt32Type (), IntPtrType (), IntPtrType (), FALSE);
3747 LLVMValueRef callee = ctx->module->match_exc;
3750 if (ctx->cfg->compile_aot) {
3751 ctx->builder = builder;
3752 // get_callee expects ctx->builder to be the emitting builder
3753 callee = get_callee (ctx, match_sig, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
3755 callee = ctx->module->match_exc = LLVMAddFunction (ctx->lmodule, icall_name, match_sig);
3756 LLVMAddGlobalMapping (ctx->module->ee, ctx->module->match_exc, resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name));
3757 ctx->module->match_exc = callee;
3758 mono_memory_barrier ();
3762 g_assert (builder && callee);
3764 g_assert (ctx->ex_var);
3766 return LLVMBuildCall (builder, callee, args, num_args, icall_name);
3769 // FIXME: This won't work because the code-finding makes this
3771 /*#define MONO_PERSONALITY_DEBUG*/
3773 #ifdef MONO_PERSONALITY_DEBUG
3774 static const gboolean use_debug_personality = TRUE;
3775 static const char *default_personality_name = "mono_debug_personality";
3777 static const gboolean use_debug_personality = FALSE;
3778 static const char *default_personality_name = "__gxx_personality_v0";
3782 default_cpp_lpad_exc_signature (void)
3784 static gboolean inited = FALSE;
3785 static LLVMTypeRef sig;
3788 LLVMTypeRef signature [2];
3789 signature [0] = LLVMPointerType (LLVMInt8Type (), 0);
3790 signature [1] = LLVMInt32Type ();
3791 sig = LLVMStructType (signature, 2, FALSE);
3799 get_mono_personality (EmitContext *ctx)
3801 LLVMValueRef personality = NULL;
3802 static gint32 mapping_inited = FALSE;
3803 LLVMTypeRef personality_type = LLVMFunctionType (LLVMInt32Type (), NULL, 0, TRUE);
3805 if (!use_debug_personality) {
3806 if (ctx->cfg->compile_aot) {
3807 personality = get_intrinsic (ctx, default_personality_name);
3808 } else if (InterlockedCompareExchange (&mapping_inited, 1, 0) == 0) {
3809 personality = LLVMAddFunction (ctx->lmodule, default_personality_name, personality_type);
3810 LLVMAddGlobalMapping (ctx->module->ee, personality, personality);
3813 if (ctx->cfg->compile_aot) {
3814 personality = get_callee (ctx, personality_type, MONO_PATCH_INFO_INTERNAL_METHOD, default_personality_name);
3816 personality = LLVMAddFunction (ctx->lmodule, default_personality_name, personality_type);
3817 LLVMAddGlobalMapping (ctx->module->ee, personality, resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, default_personality_name));
3818 mono_memory_barrier ();
3822 g_assert (personality);
3826 static LLVMBasicBlockRef
3827 emit_landing_pad (EmitContext *ctx, int group_index, int group_size)
3829 MonoCompile *cfg = ctx->cfg;
3830 LLVMBuilderRef old_builder = ctx->builder;
3831 MonoExceptionClause *group_start = cfg->header->clauses + group_index;
3833 LLVMBuilderRef lpadBuilder = create_builder (ctx);
3834 ctx->builder = lpadBuilder;
3836 MonoBasicBlock *handler_bb = cfg->cil_offset_to_bb [CLAUSE_START (group_start)];
3837 g_assert (handler_bb);
3839 // <resultval> = landingpad <somety> personality <type> <pers_fn> <clause>+
3840 LLVMValueRef personality = get_mono_personality (ctx);
3841 g_assert (personality);
3843 char *bb_name = g_strdup_printf ("LPAD%d_BB", group_index);
3844 LLVMBasicBlockRef lpad_bb = gen_bb (ctx, bb_name);
3846 LLVMPositionBuilderAtEnd (lpadBuilder, lpad_bb);
3847 LLVMValueRef landing_pad = LLVMBuildLandingPad (lpadBuilder, default_cpp_lpad_exc_signature (), personality, 0, "");
3848 g_assert (landing_pad);
3850 LLVMValueRef cast = LLVMBuildBitCast (lpadBuilder, ctx->module->sentinel_exception, LLVMPointerType (LLVMInt8Type (), 0), "int8TypeInfo");
3851 LLVMAddClause (landing_pad, cast);
3853 LLVMBasicBlockRef resume_bb = gen_bb (ctx, "RESUME_BB");
3854 LLVMBuilderRef resume_builder = create_builder (ctx);
3855 ctx->builder = resume_builder;
3856 LLVMPositionBuilderAtEnd (resume_builder, resume_bb);
3858 emit_resume_eh (ctx, handler_bb);
3861 ctx->builder = lpadBuilder;
3862 LLVMPositionBuilderAtEnd (lpadBuilder, lpad_bb);
3864 gboolean finally_only = TRUE;
3866 MonoExceptionClause *group_cursor = group_start;
3868 for (int i = 0; i < group_size; i ++) {
3869 if (!(group_cursor->flags & MONO_EXCEPTION_CLAUSE_FINALLY))
3870 finally_only = FALSE;
3876 // Handle landing pad inlining
3878 if (!finally_only) {
3879 // So at each level of the exception stack we will match the exception again.
3880 // During that match, we need to compare against the handler types for the current
3881 // protected region. We send the try start and end so that we can only check against
3882 // handlers for this lexical protected region.
3883 LLVMValueRef match = mono_llvm_emit_match_exception_call (ctx, lpadBuilder, group_start->try_offset, group_start->try_offset + group_start->try_len);
3885 // if returns -1, resume
3886 LLVMValueRef switch_ins = LLVMBuildSwitch (lpadBuilder, match, resume_bb, group_size);
3888 // else move to that target bb
3889 for (int i=0; i < group_size; i++) {
3890 MonoExceptionClause *clause = group_start + i;
3891 int clause_index = clause - cfg->header->clauses;
3892 MonoBasicBlock *handler_bb = (MonoBasicBlock*)g_hash_table_lookup (ctx->clause_to_handler, GINT_TO_POINTER (clause_index));
3893 g_assert (handler_bb);
3894 g_assert (ctx->bblocks [handler_bb->block_num].call_handler_target_bb);
3895 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), clause_index, FALSE), ctx->bblocks [handler_bb->block_num].call_handler_target_bb);
3898 int clause_index = group_start - cfg->header->clauses;
3899 MonoBasicBlock *finally_bb = (MonoBasicBlock*)g_hash_table_lookup (ctx->clause_to_handler, GINT_TO_POINTER (clause_index));
3900 g_assert (finally_bb);
3902 LLVMBuildBr (ctx->builder, ctx->bblocks [finally_bb->block_num].call_handler_target_bb);
3905 ctx->builder = old_builder;
3912 emit_llvmonly_handler_start (EmitContext *ctx, MonoBasicBlock *bb, LLVMBasicBlockRef cbb)
3914 int clause_index = MONO_REGION_CLAUSE_INDEX (bb->region);
3915 MonoExceptionClause *clause = &ctx->cfg->header->clauses [clause_index];
3917 // Make exception available to catch blocks
3918 if (!(clause->flags & MONO_EXCEPTION_CLAUSE_FINALLY)) {
3919 LLVMValueRef mono_exc = mono_llvm_emit_load_exception_call (ctx, ctx->builder);
3921 g_assert (ctx->ex_var);
3922 LLVMBuildStore (ctx->builder, LLVMBuildBitCast (ctx->builder, mono_exc, ObjRefType (), ""), ctx->ex_var);
3924 if (bb->in_scount == 1) {
3925 MonoInst *exvar = bb->in_stack [0];
3926 g_assert (!ctx->values [exvar->dreg]);
3927 g_assert (ctx->ex_var);
3928 ctx->values [exvar->dreg] = LLVMBuildLoad (ctx->builder, ctx->ex_var, "save_exception");
3929 emit_volatile_store (ctx, exvar->dreg);
3932 mono_llvm_emit_clear_exception_call (ctx, ctx->builder);
3935 LLVMBuilderRef handler_builder = create_builder (ctx);
3936 LLVMBasicBlockRef target_bb = ctx->bblocks [bb->block_num].call_handler_target_bb;
3937 LLVMPositionBuilderAtEnd (handler_builder, target_bb);
3939 // Make the handler code end with a jump to cbb
3940 LLVMBuildBr (handler_builder, cbb);
3944 emit_handler_start (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef builder)
3946 MonoCompile *cfg = ctx->cfg;
3947 LLVMValueRef *values = ctx->values;
3948 LLVMModuleRef lmodule = ctx->lmodule;
3949 BBInfo *bblocks = ctx->bblocks;
3951 LLVMValueRef personality;
3952 LLVMValueRef landing_pad;
3953 LLVMBasicBlockRef target_bb;
3955 static int ti_generator;
3957 LLVMValueRef type_info;
3961 // <resultval> = landingpad <somety> personality <type> <pers_fn> <clause>+
3963 if (cfg->compile_aot) {
3964 /* Use a dummy personality function */
3965 personality = LLVMGetNamedFunction (lmodule, "mono_personality");
3966 g_assert (personality);
3968 #if LLVM_API_VERSION > 100
3969 LLVMTypeRef personality_type = LLVMFunctionType (LLVMInt32Type (), NULL, 0, TRUE);
3970 personality = LLVMAddFunction (ctx->lmodule, "mono_personality", personality_type);
3971 LLVMAddFunctionAttr (personality, LLVMNoUnwindAttribute);
3972 LLVMBasicBlockRef entry_bb = LLVMAppendBasicBlock (personality, "ENTRY");
3973 LLVMBuilderRef builder2 = LLVMCreateBuilder ();
3974 LLVMPositionBuilderAtEnd (builder2, entry_bb);
3975 LLVMBuildRet (builder2, LLVMConstInt (LLVMInt32Type (), 0, FALSE));
3977 static gint32 mapping_inited;
3979 personality = LLVMGetNamedFunction (lmodule, "mono_personality");
3981 if (InterlockedCompareExchange (&mapping_inited, 1, 0) == 0)
3982 LLVMAddGlobalMapping (ctx->module->ee, personality, (gpointer)mono_personality);
3986 i8ptr = LLVMPointerType (LLVMInt8Type (), 0);
3988 clause_index = (mono_get_block_region_notry (cfg, bb->region) >> 8) - 1;
3991 * Create the type info
3993 sprintf (ti_name, "type_info_%d", ti_generator);
3996 if (cfg->compile_aot) {
3997 /* decode_eh_frame () in aot-runtime.c will decode this */
3998 type_info = LLVMAddGlobal (lmodule, LLVMInt32Type (), ti_name);
3999 LLVMSetInitializer (type_info, LLVMConstInt (LLVMInt32Type (), clause_index, FALSE));
4002 * These symbols are not really used, the clause_index is embedded into the EH tables generated by DwarfMonoException in LLVM.
4004 LLVMSetLinkage (type_info, LLVMInternalLinkage);
4006 #if LLVM_API_VERSION > 100
4007 type_info = LLVMAddGlobal (lmodule, LLVMInt32Type (), ti_name);
4008 LLVMSetInitializer (type_info, LLVMConstInt (LLVMInt32Type (), clause_index, FALSE));
4013 * After the cfg mempool is freed, the type info will point to stale memory,
4014 * but this is not a problem, since we decode it once in exception_cb during
4017 ti = (gint32*)mono_mempool_alloc (cfg->mempool, sizeof (gint32));
4018 *(gint32*)ti = clause_index;
4020 type_info = LLVMAddGlobal (lmodule, i8ptr, ti_name);
4022 LLVMAddGlobalMapping (ctx->module->ee, type_info, ti);
4027 LLVMTypeRef members [2], ret_type;
4029 members [0] = i8ptr;
4030 members [1] = LLVMInt32Type ();
4031 ret_type = LLVMStructType (members, 2, FALSE);
4033 landing_pad = LLVMBuildLandingPad (builder, ret_type, personality, 1, "");
4034 LLVMAddClause (landing_pad, type_info);
4036 /* Store the exception into the exvar */
4038 LLVMBuildStore (builder, convert (ctx, LLVMBuildExtractValue (builder, landing_pad, 0, "ex_obj"), ObjRefType ()), ctx->ex_var);
4042 * LLVM throw sites are associated with a one landing pad, and LLVM generated
4043 * code expects control to be transferred to this landing pad even in the
4044 * presence of nested clauses. The landing pad needs to branch to the landing
4045 * pads belonging to nested clauses based on the selector value returned by
4046 * the landing pad instruction, which is passed to the landing pad in a
4047 * register by the EH code.
4049 target_bb = bblocks [bb->block_num].call_handler_target_bb;
4050 g_assert (target_bb);
4053 * Branch to the correct landing pad
4055 LLVMValueRef ex_selector = LLVMBuildExtractValue (builder, landing_pad, 1, "ex_selector");
4056 LLVMValueRef switch_ins = LLVMBuildSwitch (builder, ex_selector, target_bb, 0);
4058 for (l = ctx->nested_in [clause_index]; l; l = l->next) {
4059 int nesting_clause_index = GPOINTER_TO_INT (l->data);
4060 MonoBasicBlock *handler_bb;
4062 handler_bb = (MonoBasicBlock*)g_hash_table_lookup (ctx->clause_to_handler, GINT_TO_POINTER (nesting_clause_index));
4063 g_assert (handler_bb);
4065 g_assert (ctx->bblocks [handler_bb->block_num].call_handler_target_bb);
4066 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), nesting_clause_index, FALSE), ctx->bblocks [handler_bb->block_num].call_handler_target_bb);
4069 /* Start a new bblock which CALL_HANDLER can branch to */
4070 target_bb = bblocks [bb->block_num].call_handler_target_bb;
4072 ctx->builder = builder = create_builder (ctx);
4073 LLVMPositionBuilderAtEnd (ctx->builder, target_bb);
4075 ctx->bblocks [bb->block_num].end_bblock = target_bb;
4077 /* Store the exception into the IL level exvar */
4078 if (bb->in_scount == 1) {
4079 g_assert (bb->in_scount == 1);
4080 exvar = bb->in_stack [0];
4082 // FIXME: This is shared with filter clauses ?
4083 g_assert (!values [exvar->dreg]);
4085 g_assert (ctx->ex_var);
4086 values [exvar->dreg] = LLVMBuildLoad (builder, ctx->ex_var, "");
4087 emit_volatile_store (ctx, exvar->dreg);
4093 process_bb (EmitContext *ctx, MonoBasicBlock *bb)
4095 MonoCompile *cfg = ctx->cfg;
4096 MonoMethodSignature *sig = ctx->sig;
4097 LLVMValueRef method = ctx->lmethod;
4098 LLVMValueRef *values = ctx->values;
4099 LLVMValueRef *addresses = ctx->addresses;
4100 LLVMCallInfo *linfo = ctx->linfo;
4101 BBInfo *bblocks = ctx->bblocks;
4103 LLVMBasicBlockRef cbb;
4104 LLVMBuilderRef builder, starting_builder;
4105 gboolean has_terminator;
4107 LLVMValueRef lhs, rhs;
4110 cbb = get_end_bb (ctx, bb);
4112 builder = create_builder (ctx);
4113 ctx->builder = builder;
4114 LLVMPositionBuilderAtEnd (builder, cbb);
4119 if (bb->flags & BB_EXCEPTION_HANDLER) {
4120 if (!ctx->llvm_only && !bblocks [bb->block_num].invoke_target) {
4121 set_failure (ctx, "handler without invokes");
4126 emit_llvmonly_handler_start (ctx, bb, cbb);
4128 emit_handler_start (ctx, bb, builder);
4131 builder = ctx->builder;
4134 has_terminator = FALSE;
4135 starting_builder = builder;
4136 for (ins = bb->code; ins; ins = ins->next) {
4137 const char *spec = LLVM_INS_INFO (ins->opcode);
4139 char dname_buf [128];
4141 emit_dbg_loc (ctx, builder, ins->cil_code);
4146 * Some steps in llc are non-linear in the size of basic blocks, see #5714.
4147 * Start a new bblock. If the llvm optimization passes merge these, we
4148 * can work around that by doing a volatile load + cond branch from
4149 * localloc-ed memory.
4151 //set_failure (ctx, "basic block too long");
4152 cbb = gen_bb (ctx, "CONT_LONG_BB");
4153 LLVMBuildBr (ctx->builder, cbb);
4154 ctx->builder = builder = create_builder (ctx);
4155 LLVMPositionBuilderAtEnd (builder, cbb);
4156 ctx->bblocks [bb->block_num].end_bblock = cbb;
4161 /* There could be instructions after a terminator, skip them */
4164 if (spec [MONO_INST_DEST] != ' ' && !MONO_IS_STORE_MEMBASE (ins)) {
4165 sprintf (dname_buf, "t%d", ins->dreg);
4169 if (spec [MONO_INST_SRC1] != ' ' && spec [MONO_INST_SRC1] != 'v') {
4170 MonoInst *var = get_vreg_to_inst (cfg, ins->sreg1);
4172 if (var && var->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT) && var->opcode != OP_GSHAREDVT_ARG_REGOFFSET) {
4173 lhs = emit_volatile_load (ctx, ins->sreg1);
4175 /* It is ok for SETRET to have an uninitialized argument */
4176 if (!values [ins->sreg1] && ins->opcode != OP_SETRET) {
4177 set_failure (ctx, "sreg1");
4180 lhs = values [ins->sreg1];
4186 if (spec [MONO_INST_SRC2] != ' ' && spec [MONO_INST_SRC2] != ' ') {
4187 MonoInst *var = get_vreg_to_inst (cfg, ins->sreg2);
4188 if (var && var->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT)) {
4189 rhs = emit_volatile_load (ctx, ins->sreg2);
4191 if (!values [ins->sreg2]) {
4192 set_failure (ctx, "sreg2");
4195 rhs = values [ins->sreg2];
4201 //mono_print_ins (ins);
4202 switch (ins->opcode) {
4205 case OP_LIVERANGE_START:
4206 case OP_LIVERANGE_END:
4209 values [ins->dreg] = LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE);
4212 #if SIZEOF_VOID_P == 4
4213 values [ins->dreg] = LLVMConstInt (LLVMInt64Type (), GET_LONG_IMM (ins), FALSE);
4215 values [ins->dreg] = LLVMConstInt (LLVMInt64Type (), (gint64)ins->inst_c0, FALSE);
4219 values [ins->dreg] = LLVMConstReal (LLVMDoubleType (), *(double*)ins->inst_p0);
4223 values [ins->dreg] = LLVMConstReal (LLVMFloatType (), *(float*)ins->inst_p0);
4225 values [ins->dreg] = LLVMConstFPExt (LLVMConstReal (LLVMFloatType (), *(float*)ins->inst_p0), LLVMDoubleType ());
4227 case OP_DUMMY_ICONST:
4228 values [ins->dreg] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
4230 case OP_DUMMY_I8CONST:
4231 values [ins->dreg] = LLVMConstInt (LLVMInt64Type (), 0, FALSE);
4233 case OP_DUMMY_R8CONST:
4234 values [ins->dreg] = LLVMConstReal (LLVMDoubleType (), 0.0f);
4237 LLVMBasicBlockRef target_bb = get_bb (ctx, ins->inst_target_bb);
4238 LLVMBuildBr (builder, target_bb);
4239 has_terminator = TRUE;
4246 LLVMBasicBlockRef new_bb;
4247 LLVMBuilderRef new_builder;
4249 // The default branch is already handled
4250 // FIXME: Handle it here
4252 /* Start new bblock */
4253 sprintf (bb_name, "SWITCH_DEFAULT_BB%d", ctx->default_index ++);
4254 new_bb = LLVMAppendBasicBlock (ctx->lmethod, bb_name);
4256 lhs = convert (ctx, lhs, LLVMInt32Type ());
4257 v = LLVMBuildSwitch (builder, lhs, new_bb, GPOINTER_TO_UINT (ins->klass));
4258 for (i = 0; i < GPOINTER_TO_UINT (ins->klass); ++i) {
4259 MonoBasicBlock *target_bb = ins->inst_many_bb [i];
4261 LLVMAddCase (v, LLVMConstInt (LLVMInt32Type (), i, FALSE), get_bb (ctx, target_bb));
4264 new_builder = create_builder (ctx);
4265 LLVMPositionBuilderAtEnd (new_builder, new_bb);
4266 LLVMBuildUnreachable (new_builder);
4268 has_terminator = TRUE;
4269 g_assert (!ins->next);
4275 switch (linfo->ret.storage) {
4276 case LLVMArgVtypeInReg: {
4277 LLVMTypeRef ret_type = LLVMGetReturnType (LLVMGetElementType (LLVMTypeOf (method)));
4278 LLVMValueRef val, addr, retval;
4281 retval = LLVMGetUndef (ret_type);
4283 if (!addresses [ins->sreg1]) {
4285 * The return type is an LLVM vector type, have to convert between it and the
4286 * real return type which is a struct type.
4288 g_assert (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (sig->ret)));
4289 /* Convert to 2xi64 first */
4290 val = LLVMBuildBitCast (builder, values [ins->sreg1], LLVMVectorType (IntPtrType (), 2), "");
4292 for (i = 0; i < 2; ++i) {
4293 if (linfo->ret.pair_storage [i] == LLVMArgInIReg) {
4294 retval = LLVMBuildInsertValue (builder, retval, LLVMBuildExtractElement (builder, val, LLVMConstInt (LLVMInt32Type (), i, FALSE), ""), i, "");
4296 g_assert (linfo->ret.pair_storage [i] == LLVMArgNone);
4300 addr = LLVMBuildBitCast (builder, addresses [ins->sreg1], LLVMPointerType (ret_type, 0), "");
4301 for (i = 0; i < 2; ++i) {
4302 if (linfo->ret.pair_storage [i] == LLVMArgInIReg) {
4303 LLVMValueRef indexes [2], part_addr;
4305 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
4306 indexes [1] = LLVMConstInt (LLVMInt32Type (), i, FALSE);
4307 part_addr = LLVMBuildGEP (builder, addr, indexes, 2, "");
4309 retval = LLVMBuildInsertValue (builder, retval, LLVMBuildLoad (builder, part_addr, ""), i, "");
4311 g_assert (linfo->ret.pair_storage [i] == LLVMArgNone);
4315 LLVMBuildRet (builder, retval);
4318 case LLVMArgVtypeAsScalar: {
4319 LLVMTypeRef ret_type = LLVMGetReturnType (LLVMGetElementType (LLVMTypeOf (method)));
4320 LLVMValueRef retval;
4322 g_assert (addresses [ins->sreg1]);
4324 retval = LLVMBuildLoad (builder, LLVMBuildBitCast (builder, addresses [ins->sreg1], LLVMPointerType (ret_type, 0), ""), "");
4325 LLVMBuildRet (builder, retval);
4328 case LLVMArgVtypeByVal: {
4329 LLVMValueRef retval;
4331 g_assert (addresses [ins->sreg1]);
4332 retval = LLVMBuildLoad (builder, addresses [ins->sreg1], "");
4333 LLVMBuildRet (builder, retval);
4336 case LLVMArgVtypeByRef: {
4337 LLVMBuildRetVoid (builder);
4340 case LLVMArgGsharedvtFixed: {
4341 LLVMTypeRef ret_type = type_to_llvm_type (ctx, sig->ret);
4342 /* The return value is in lhs, need to store to the vret argument */
4343 /* sreg1 might not be set */
4345 g_assert (cfg->vret_addr);
4346 g_assert (values [cfg->vret_addr->dreg]);
4347 LLVMBuildStore (builder, convert (ctx, lhs, ret_type), convert (ctx, values [cfg->vret_addr->dreg], LLVMPointerType (ret_type, 0)));
4349 LLVMBuildRetVoid (builder);
4352 case LLVMArgGsharedvtFixedVtype: {
4354 LLVMBuildRetVoid (builder);
4357 case LLVMArgGsharedvtVariable: {
4359 LLVMBuildRetVoid (builder);
4362 case LLVMArgVtypeRetAddr: {
4363 LLVMBuildRetVoid (builder);
4366 case LLVMArgAsIArgs:
4367 case LLVMArgFpStruct: {
4368 LLVMTypeRef ret_type = LLVMGetReturnType (LLVMGetElementType (LLVMTypeOf (method)));
4369 LLVMValueRef retval;
4371 g_assert (addresses [ins->sreg1]);
4372 retval = LLVMBuildLoad (builder, convert (ctx, addresses [ins->sreg1], LLVMPointerType (ret_type, 0)), "");
4373 LLVMBuildRet (builder, retval);
4377 case LLVMArgNormal: {
4378 if (!lhs || ctx->is_dead [ins->sreg1]) {
4380 * The method did not set its return value, probably because it
4381 * ends with a throw.
4384 LLVMBuildRetVoid (builder);
4386 LLVMBuildRet (builder, LLVMConstNull (type_to_llvm_type (ctx, sig->ret)));
4388 LLVMBuildRet (builder, convert (ctx, lhs, type_to_llvm_type (ctx, sig->ret)));
4390 has_terminator = TRUE;
4394 g_assert_not_reached ();
4403 case OP_ICOMPARE_IMM:
4404 case OP_LCOMPARE_IMM:
4405 case OP_COMPARE_IMM: {
4407 LLVMValueRef cmp, args [16];
4408 gboolean likely = (ins->flags & MONO_INST_LIKELY) != 0;
4410 if (ins->next->opcode == OP_NOP)
4413 if (ins->next->opcode == OP_BR)
4414 /* The comparison result is not needed */
4417 rel = mono_opcode_to_cond (ins->next->opcode);
4419 if (ins->opcode == OP_ICOMPARE_IMM) {
4420 lhs = convert (ctx, lhs, LLVMInt32Type ());
4421 rhs = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
4423 if (ins->opcode == OP_LCOMPARE_IMM) {
4424 lhs = convert (ctx, lhs, LLVMInt64Type ());
4425 rhs = LLVMConstInt (LLVMInt64Type (), GET_LONG_IMM (ins), FALSE);
4427 if (ins->opcode == OP_LCOMPARE) {
4428 lhs = convert (ctx, lhs, LLVMInt64Type ());
4429 rhs = convert (ctx, rhs, LLVMInt64Type ());
4431 if (ins->opcode == OP_ICOMPARE) {
4432 lhs = convert (ctx, lhs, LLVMInt32Type ());
4433 rhs = convert (ctx, rhs, LLVMInt32Type ());
4437 if (LLVMGetTypeKind (LLVMTypeOf (lhs)) == LLVMPointerTypeKind)
4438 rhs = convert (ctx, rhs, LLVMTypeOf (lhs));
4439 else if (LLVMGetTypeKind (LLVMTypeOf (rhs)) == LLVMPointerTypeKind)
4440 lhs = convert (ctx, lhs, LLVMTypeOf (rhs));
4443 /* We use COMPARE+SETcc/Bcc, llvm uses SETcc+br cond */
4444 if (ins->opcode == OP_FCOMPARE) {
4445 cmp = LLVMBuildFCmp (builder, fpcond_to_llvm_cond [rel], convert (ctx, lhs, LLVMDoubleType ()), convert (ctx, rhs, LLVMDoubleType ()), "");
4446 } else if (ins->opcode == OP_RCOMPARE) {
4447 cmp = LLVMBuildFCmp (builder, fpcond_to_llvm_cond [rel], convert (ctx, lhs, LLVMFloatType ()), convert (ctx, rhs, LLVMFloatType ()), "");
4448 } else if (ins->opcode == OP_COMPARE_IMM) {
4449 if (LLVMGetTypeKind (LLVMTypeOf (lhs)) == LLVMPointerTypeKind && ins->inst_imm == 0)
4450 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], lhs, LLVMConstNull (LLVMTypeOf (lhs)), "");
4452 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE), "");
4453 } else if (ins->opcode == OP_LCOMPARE_IMM) {
4454 if (SIZEOF_REGISTER == 4 && COMPILE_LLVM (cfg)) {
4455 /* The immediate is encoded in two fields */
4456 guint64 l = ((guint64)(guint32)ins->inst_offset << 32) | ((guint32)ins->inst_imm);
4457 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, LLVMInt64Type ()), LLVMConstInt (LLVMInt64Type (), l, FALSE), "");
4459 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, LLVMInt64Type ()), LLVMConstInt (LLVMInt64Type (), ins->inst_imm, FALSE), "");
4462 else if (ins->opcode == OP_COMPARE) {
4463 if (LLVMGetTypeKind (LLVMTypeOf (lhs)) == LLVMPointerTypeKind && LLVMTypeOf (lhs) == LLVMTypeOf (rhs))
4464 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], lhs, rhs, "");
4466 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, IntPtrType ()), convert (ctx, rhs, IntPtrType ()), "");
4468 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], lhs, rhs, "");
4472 args [1] = LLVMConstInt (LLVMInt1Type (), 1, FALSE);
4473 cmp = LLVMBuildCall (ctx->builder, get_intrinsic (ctx, "llvm.expect.i1"), args, 2, "");
4476 if (MONO_IS_COND_BRANCH_OP (ins->next)) {
4477 if (ins->next->inst_true_bb == ins->next->inst_false_bb) {
4479 * If the target bb contains PHI instructions, LLVM requires
4480 * two PHI entries for this bblock, while we only generate one.
4481 * So convert this to an unconditional bblock. (bxc #171).
4483 LLVMBuildBr (builder, get_bb (ctx, ins->next->inst_true_bb));
4485 LLVMBuildCondBr (builder, cmp, get_bb (ctx, ins->next->inst_true_bb), get_bb (ctx, ins->next->inst_false_bb));
4487 has_terminator = TRUE;
4488 } else if (MONO_IS_SETCC (ins->next)) {
4489 sprintf (dname_buf, "t%d", ins->next->dreg);
4491 values [ins->next->dreg] = LLVMBuildZExt (builder, cmp, LLVMInt32Type (), dname);
4493 /* Add stores for volatile variables */
4494 emit_volatile_store (ctx, ins->next->dreg);
4495 } else if (MONO_IS_COND_EXC (ins->next)) {
4496 emit_cond_system_exception (ctx, bb, (const char*)ins->next->inst_p1, cmp);
4499 builder = ctx->builder;
4501 set_failure (ctx, "next");
4519 rel = mono_opcode_to_cond (ins->opcode);
4521 cmp = LLVMBuildFCmp (builder, fpcond_to_llvm_cond [rel], convert (ctx, lhs, LLVMDoubleType ()), convert (ctx, rhs, LLVMDoubleType ()), "");
4522 values [ins->dreg] = LLVMBuildZExt (builder, cmp, LLVMInt32Type (), dname);
4533 rel = mono_opcode_to_cond (ins->opcode);
4535 cmp = LLVMBuildFCmp (builder, fpcond_to_llvm_cond [rel], convert (ctx, lhs, LLVMFloatType ()), convert (ctx, rhs, LLVMFloatType ()), "");
4536 values [ins->dreg] = LLVMBuildZExt (builder, cmp, LLVMInt32Type (), dname);
4544 gboolean empty = TRUE;
4546 /* Check that all input bblocks really branch to us */
4547 for (i = 0; i < bb->in_count; ++i) {
4548 if (bb->in_bb [i]->last_ins && bb->in_bb [i]->last_ins->opcode == OP_NOT_REACHED)
4549 ins->inst_phi_args [i + 1] = -1;
4555 /* LLVM doesn't like phi instructions with zero operands */
4556 ctx->is_dead [ins->dreg] = TRUE;
4560 /* Created earlier, insert it now */
4561 LLVMInsertIntoBuilder (builder, values [ins->dreg]);
4563 for (i = 0; i < ins->inst_phi_args [0]; i++) {
4564 int sreg1 = ins->inst_phi_args [i + 1];
4568 * Count the number of times the incoming bblock branches to us,
4569 * since llvm requires a separate entry for each.
4571 if (bb->in_bb [i]->last_ins && bb->in_bb [i]->last_ins->opcode == OP_SWITCH) {
4572 MonoInst *switch_ins = bb->in_bb [i]->last_ins;
4575 for (j = 0; j < GPOINTER_TO_UINT (switch_ins->klass); ++j) {
4576 if (switch_ins->inst_many_bb [j] == bb)
4583 /* Remember for later */
4584 for (j = 0; j < count; ++j) {
4585 PhiNode *node = (PhiNode*)mono_mempool_alloc0 (ctx->mempool, sizeof (PhiNode));
4588 node->in_bb = bb->in_bb [i];
4590 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);
4600 values [ins->dreg] = lhs;
4604 MonoInst *var = get_vreg_to_inst (cfg, ins->dreg);
4607 values [ins->dreg] = lhs;
4609 if (var && var->klass->byval_arg.type == MONO_TYPE_R4) {
4611 * This is added by the spilling pass in case of the JIT,
4612 * but we have to do it ourselves.
4614 values [ins->dreg] = convert (ctx, values [ins->dreg], LLVMFloatType ());
4618 case OP_MOVE_F_TO_I4: {
4619 values [ins->dreg] = LLVMBuildBitCast (builder, LLVMBuildFPTrunc (builder, lhs, LLVMFloatType (), ""), LLVMInt32Type (), "");
4622 case OP_MOVE_I4_TO_F: {
4623 values [ins->dreg] = LLVMBuildFPExt (builder, LLVMBuildBitCast (builder, lhs, LLVMFloatType (), ""), LLVMDoubleType (), "");
4626 case OP_MOVE_F_TO_I8: {
4627 values [ins->dreg] = LLVMBuildBitCast (builder, lhs, LLVMInt64Type (), "");
4630 case OP_MOVE_I8_TO_F: {
4631 values [ins->dreg] = LLVMBuildBitCast (builder, lhs, LLVMDoubleType (), "");
4664 lhs = convert (ctx, lhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
4665 rhs = convert (ctx, rhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
4667 emit_div_check (ctx, builder, bb, ins, lhs, rhs);
4670 builder = ctx->builder;
4672 switch (ins->opcode) {
4675 values [ins->dreg] = LLVMBuildAdd (builder, lhs, rhs, dname);
4679 values [ins->dreg] = LLVMBuildSub (builder, lhs, rhs, dname);
4683 values [ins->dreg] = LLVMBuildMul (builder, lhs, rhs, dname);
4687 values [ins->dreg] = LLVMBuildSRem (builder, lhs, rhs, dname);
4691 values [ins->dreg] = LLVMBuildURem (builder, lhs, rhs, dname);
4695 values [ins->dreg] = LLVMBuildSDiv (builder, lhs, rhs, dname);
4699 values [ins->dreg] = LLVMBuildUDiv (builder, lhs, rhs, dname);
4703 values [ins->dreg] = LLVMBuildFDiv (builder, lhs, rhs, dname);
4707 values [ins->dreg] = LLVMBuildAnd (builder, lhs, rhs, dname);
4711 values [ins->dreg] = LLVMBuildOr (builder, lhs, rhs, dname);
4715 values [ins->dreg] = LLVMBuildXor (builder, lhs, rhs, dname);
4719 values [ins->dreg] = LLVMBuildShl (builder, lhs, rhs, dname);
4723 values [ins->dreg] = LLVMBuildAShr (builder, lhs, rhs, dname);
4727 values [ins->dreg] = LLVMBuildLShr (builder, lhs, rhs, dname);
4731 values [ins->dreg] = LLVMBuildFAdd (builder, lhs, rhs, dname);
4734 values [ins->dreg] = LLVMBuildFSub (builder, lhs, rhs, dname);
4737 values [ins->dreg] = LLVMBuildFMul (builder, lhs, rhs, dname);
4741 g_assert_not_reached ();
4748 lhs = convert (ctx, lhs, LLVMFloatType ());
4749 rhs = convert (ctx, rhs, LLVMFloatType ());
4750 switch (ins->opcode) {
4752 values [ins->dreg] = LLVMBuildFAdd (builder, lhs, rhs, dname);
4755 values [ins->dreg] = LLVMBuildFSub (builder, lhs, rhs, dname);
4758 values [ins->dreg] = LLVMBuildFMul (builder, lhs, rhs, dname);
4761 values [ins->dreg] = LLVMBuildFDiv (builder, lhs, rhs, dname);
4764 g_assert_not_reached ();
4773 case OP_IREM_UN_IMM:
4775 case OP_IDIV_UN_IMM:
4781 case OP_ISHR_UN_IMM:
4791 case OP_LSHR_UN_IMM:
4797 case OP_SHR_UN_IMM: {
4800 if (spec [MONO_INST_SRC1] == 'l') {
4801 imm = LLVMConstInt (LLVMInt64Type (), GET_LONG_IMM (ins), FALSE);
4803 imm = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
4806 emit_div_check (ctx, builder, bb, ins, lhs, imm);
4809 builder = ctx->builder;
4811 #if SIZEOF_VOID_P == 4
4812 if (ins->opcode == OP_LSHL_IMM || ins->opcode == OP_LSHR_IMM || ins->opcode == OP_LSHR_UN_IMM)
4813 imm = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
4816 if (LLVMGetTypeKind (LLVMTypeOf (lhs)) == LLVMPointerTypeKind)
4817 lhs = convert (ctx, lhs, IntPtrType ());
4818 imm = convert (ctx, imm, LLVMTypeOf (lhs));
4819 switch (ins->opcode) {
4823 values [ins->dreg] = LLVMBuildAdd (builder, lhs, imm, dname);
4827 values [ins->dreg] = LLVMBuildSub (builder, lhs, imm, dname);
4832 values [ins->dreg] = LLVMBuildMul (builder, lhs, imm, dname);
4836 values [ins->dreg] = LLVMBuildSDiv (builder, lhs, imm, dname);
4838 case OP_IDIV_UN_IMM:
4839 case OP_LDIV_UN_IMM:
4840 values [ins->dreg] = LLVMBuildUDiv (builder, lhs, imm, dname);
4844 values [ins->dreg] = LLVMBuildSRem (builder, lhs, imm, dname);
4846 case OP_IREM_UN_IMM:
4847 values [ins->dreg] = LLVMBuildURem (builder, lhs, imm, dname);
4852 values [ins->dreg] = LLVMBuildAnd (builder, lhs, imm, dname);
4856 values [ins->dreg] = LLVMBuildOr (builder, lhs, imm, dname);
4860 values [ins->dreg] = LLVMBuildXor (builder, lhs, imm, dname);
4865 values [ins->dreg] = LLVMBuildShl (builder, lhs, imm, dname);
4870 values [ins->dreg] = LLVMBuildAShr (builder, lhs, imm, dname);
4872 case OP_ISHR_UN_IMM:
4873 /* This is used to implement conv.u4, so the lhs could be an i8 */
4874 lhs = convert (ctx, lhs, LLVMInt32Type ());
4875 imm = convert (ctx, imm, LLVMInt32Type ());
4876 values [ins->dreg] = LLVMBuildLShr (builder, lhs, imm, dname);
4878 case OP_LSHR_UN_IMM:
4880 values [ins->dreg] = LLVMBuildLShr (builder, lhs, imm, dname);
4883 g_assert_not_reached ();
4888 values [ins->dreg] = LLVMBuildSub (builder, LLVMConstInt (LLVMInt32Type (), 0, FALSE), convert (ctx, lhs, LLVMInt32Type ()), dname);
4891 values [ins->dreg] = LLVMBuildSub (builder, LLVMConstInt (LLVMInt64Type (), 0, FALSE), lhs, dname);
4894 lhs = convert (ctx, lhs, LLVMDoubleType ());
4895 values [ins->dreg] = LLVMBuildFSub (builder, LLVMConstReal (LLVMDoubleType (), 0.0), lhs, dname);
4898 lhs = convert (ctx, lhs, LLVMFloatType ());
4899 values [ins->dreg] = LLVMBuildFSub (builder, LLVMConstReal (LLVMFloatType (), 0.0), lhs, dname);
4902 guint32 v = 0xffffffff;
4903 values [ins->dreg] = LLVMBuildXor (builder, LLVMConstInt (LLVMInt32Type (), v, FALSE), convert (ctx, lhs, LLVMInt32Type ()), dname);
4907 guint64 v = 0xffffffffffffffffLL;
4908 values [ins->dreg] = LLVMBuildXor (builder, LLVMConstInt (LLVMInt64Type (), v, FALSE), lhs, dname);
4911 #if defined(TARGET_X86) || defined(TARGET_AMD64)
4913 LLVMValueRef v1, v2;
4915 v1 = LLVMBuildMul (builder, convert (ctx, rhs, IntPtrType ()), LLVMConstInt (IntPtrType (), (1 << ins->backend.shift_amount), FALSE), "");
4916 v2 = LLVMBuildAdd (builder, convert (ctx, lhs, IntPtrType ()), v1, "");
4917 values [ins->dreg] = LLVMBuildAdd (builder, v2, LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE), dname);
4922 case OP_ICONV_TO_I1:
4923 case OP_ICONV_TO_I2:
4924 case OP_ICONV_TO_I4:
4925 case OP_ICONV_TO_U1:
4926 case OP_ICONV_TO_U2:
4927 case OP_ICONV_TO_U4:
4928 case OP_LCONV_TO_I1:
4929 case OP_LCONV_TO_I2:
4930 case OP_LCONV_TO_U1:
4931 case OP_LCONV_TO_U2:
4932 case OP_LCONV_TO_U4: {
4935 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);
4937 /* Have to do two casts since our vregs have type int */
4938 v = LLVMBuildTrunc (builder, lhs, op_to_llvm_type (ins->opcode), "");
4940 values [ins->dreg] = LLVMBuildSExt (builder, v, LLVMInt32Type (), dname);
4942 values [ins->dreg] = LLVMBuildZExt (builder, v, LLVMInt32Type (), dname);
4945 case OP_ICONV_TO_I8:
4946 values [ins->dreg] = LLVMBuildSExt (builder, lhs, LLVMInt64Type (), dname);
4948 case OP_ICONV_TO_U8:
4949 values [ins->dreg] = LLVMBuildZExt (builder, lhs, LLVMInt64Type (), dname);
4951 case OP_FCONV_TO_I4:
4952 case OP_RCONV_TO_I4:
4953 values [ins->dreg] = LLVMBuildFPToSI (builder, lhs, LLVMInt32Type (), dname);
4955 case OP_FCONV_TO_I1:
4956 case OP_RCONV_TO_I1:
4957 values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildFPToSI (builder, lhs, LLVMInt8Type (), dname), LLVMInt32Type (), "");
4959 case OP_FCONV_TO_U1:
4960 case OP_RCONV_TO_U1:
4961 values [ins->dreg] = LLVMBuildZExt (builder, LLVMBuildTrunc (builder, LLVMBuildFPToUI (builder, lhs, IntPtrType (), dname), LLVMInt8Type (), ""), LLVMInt32Type (), "");
4963 case OP_FCONV_TO_I2:
4964 case OP_RCONV_TO_I2:
4965 values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildFPToSI (builder, lhs, LLVMInt16Type (), dname), LLVMInt32Type (), "");
4967 case OP_FCONV_TO_U2:
4968 case OP_RCONV_TO_U2:
4969 values [ins->dreg] = LLVMBuildZExt (builder, LLVMBuildFPToUI (builder, lhs, LLVMInt16Type (), dname), LLVMInt32Type (), "");
4971 case OP_RCONV_TO_U4:
4972 values [ins->dreg] = LLVMBuildFPToUI (builder, lhs, LLVMInt32Type (), dname);
4974 case OP_FCONV_TO_I8:
4975 case OP_RCONV_TO_I8:
4976 values [ins->dreg] = LLVMBuildFPToSI (builder, lhs, LLVMInt64Type (), dname);
4979 values [ins->dreg] = LLVMBuildFPToSI (builder, lhs, IntPtrType (), dname);
4981 case OP_ICONV_TO_R8:
4982 case OP_LCONV_TO_R8:
4983 values [ins->dreg] = LLVMBuildSIToFP (builder, lhs, LLVMDoubleType (), dname);
4985 case OP_ICONV_TO_R_UN:
4986 case OP_LCONV_TO_R_UN:
4987 values [ins->dreg] = LLVMBuildUIToFP (builder, lhs, LLVMDoubleType (), dname);
4989 #if SIZEOF_VOID_P == 4
4992 case OP_LCONV_TO_I4:
4993 values [ins->dreg] = LLVMBuildTrunc (builder, lhs, LLVMInt32Type (), dname);
4995 case OP_ICONV_TO_R4:
4996 case OP_LCONV_TO_R4:
4997 v = LLVMBuildSIToFP (builder, lhs, LLVMFloatType (), "");
4999 values [ins->dreg] = v;
5001 values [ins->dreg] = LLVMBuildFPExt (builder, v, LLVMDoubleType (), dname);
5003 case OP_FCONV_TO_R4:
5004 v = LLVMBuildFPTrunc (builder, lhs, LLVMFloatType (), "");
5006 values [ins->dreg] = v;
5008 values [ins->dreg] = LLVMBuildFPExt (builder, v, LLVMDoubleType (), dname);
5010 case OP_RCONV_TO_R8:
5011 values [ins->dreg] = LLVMBuildFPExt (builder, lhs, LLVMDoubleType (), dname);
5013 case OP_RCONV_TO_R4:
5014 values [ins->dreg] = lhs;
5017 values [ins->dreg] = LLVMBuildSExt (builder, convert (ctx, lhs, LLVMInt32Type ()), LLVMInt64Type (), dname);
5020 values [ins->dreg] = LLVMBuildZExt (builder, convert (ctx, lhs, LLVMInt32Type ()), LLVMInt64Type (), dname);
5023 values [ins->dreg] = LLVMBuildTrunc (builder, lhs, LLVMInt32Type (), dname);
5025 case OP_LOCALLOC_IMM: {
5028 guint32 size = ins->inst_imm;
5029 size = (size + (MONO_ARCH_FRAME_ALIGNMENT - 1)) & ~ (MONO_ARCH_FRAME_ALIGNMENT - 1);
5031 v = mono_llvm_build_alloca (builder, LLVMInt8Type (), LLVMConstInt (LLVMInt32Type (), size, FALSE), MONO_ARCH_FRAME_ALIGNMENT, "");
5033 if (ins->flags & MONO_INST_INIT) {
5034 LLVMValueRef args [5];
5037 args [1] = LLVMConstInt (LLVMInt8Type (), 0, FALSE);
5038 args [2] = LLVMConstInt (LLVMInt32Type (), size, FALSE);
5039 args [3] = LLVMConstInt (LLVMInt32Type (), MONO_ARCH_FRAME_ALIGNMENT, FALSE);
5040 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
5041 LLVMBuildCall (builder, get_intrinsic (ctx, "llvm.memset.p0i8.i32"), args, 5, "");
5044 values [ins->dreg] = v;
5048 LLVMValueRef v, size;
5050 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), "");
5052 v = mono_llvm_build_alloca (builder, LLVMInt8Type (), size, MONO_ARCH_FRAME_ALIGNMENT, "");
5054 if (ins->flags & MONO_INST_INIT) {
5055 LLVMValueRef args [5];
5058 args [1] = LLVMConstInt (LLVMInt8Type (), 0, FALSE);
5060 args [3] = LLVMConstInt (LLVMInt32Type (), MONO_ARCH_FRAME_ALIGNMENT, FALSE);
5061 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
5062 LLVMBuildCall (builder, get_intrinsic (ctx, "llvm.memset.p0i8.i32"), args, 5, "");
5064 values [ins->dreg] = v;
5068 case OP_LOADI1_MEMBASE:
5069 case OP_LOADU1_MEMBASE:
5070 case OP_LOADI2_MEMBASE:
5071 case OP_LOADU2_MEMBASE:
5072 case OP_LOADI4_MEMBASE:
5073 case OP_LOADU4_MEMBASE:
5074 case OP_LOADI8_MEMBASE:
5075 case OP_LOADR4_MEMBASE:
5076 case OP_LOADR8_MEMBASE:
5077 case OP_LOAD_MEMBASE:
5085 LLVMValueRef base, index, addr;
5087 gboolean sext = FALSE, zext = FALSE;
5088 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
5090 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
5095 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)) {
5096 addr = LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE);
5101 if (ins->inst_offset == 0) {
5103 } else if (ins->inst_offset % size != 0) {
5104 /* Unaligned load */
5105 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset, FALSE);
5106 addr = LLVMBuildGEP (builder, convert (ctx, base, LLVMPointerType (LLVMInt8Type (), 0)), &index, 1, "");
5108 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
5109 addr = LLVMBuildGEP (builder, convert (ctx, base, LLVMPointerType (t, 0)), &index, 1, "");
5113 addr = convert (ctx, addr, LLVMPointerType (t, 0));
5115 values [ins->dreg] = emit_load (ctx, bb, &builder, size, addr, dname, is_volatile);
5117 if (!is_volatile && (ins->flags & MONO_INST_INVARIANT_LOAD)) {
5119 * These will signal LLVM that these loads do not alias any stores, and
5120 * they can't fail, allowing them to be hoisted out of loops.
5122 set_invariant_load_flag (values [ins->dreg]);
5123 #if LLVM_API_VERSION < 100
5124 set_metadata_flag (values [ins->dreg], "mono.nofail.load");
5129 values [ins->dreg] = LLVMBuildSExt (builder, values [ins->dreg], LLVMInt32Type (), dname);
5131 values [ins->dreg] = LLVMBuildZExt (builder, values [ins->dreg], LLVMInt32Type (), dname);
5132 else if (!cfg->r4fp && ins->opcode == OP_LOADR4_MEMBASE)
5133 values [ins->dreg] = LLVMBuildFPExt (builder, values [ins->dreg], LLVMDoubleType (), dname);
5137 case OP_STOREI1_MEMBASE_REG:
5138 case OP_STOREI2_MEMBASE_REG:
5139 case OP_STOREI4_MEMBASE_REG:
5140 case OP_STOREI8_MEMBASE_REG:
5141 case OP_STORER4_MEMBASE_REG:
5142 case OP_STORER8_MEMBASE_REG:
5143 case OP_STORE_MEMBASE_REG: {
5145 LLVMValueRef index, addr;
5147 gboolean sext = FALSE, zext = FALSE;
5148 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
5150 if (!values [ins->inst_destbasereg]) {
5151 set_failure (ctx, "inst_destbasereg");
5155 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
5157 if (ins->inst_offset % size != 0) {
5158 /* Unaligned store */
5159 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset, FALSE);
5160 addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (LLVMInt8Type (), 0)), &index, 1, "");
5162 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
5163 addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (t, 0)), &index, 1, "");
5165 emit_store (ctx, bb, &builder, size, convert (ctx, values [ins->sreg1], t), convert (ctx, addr, LLVMPointerType (t, 0)), is_volatile);
5169 case OP_STOREI1_MEMBASE_IMM:
5170 case OP_STOREI2_MEMBASE_IMM:
5171 case OP_STOREI4_MEMBASE_IMM:
5172 case OP_STOREI8_MEMBASE_IMM:
5173 case OP_STORE_MEMBASE_IMM: {
5175 LLVMValueRef index, addr;
5177 gboolean sext = FALSE, zext = FALSE;
5178 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
5180 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
5182 if (ins->inst_offset % size != 0) {
5183 /* Unaligned store */
5184 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset, FALSE);
5185 addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (LLVMInt8Type (), 0)), &index, 1, "");
5187 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
5188 addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (t, 0)), &index, 1, "");
5190 emit_store (ctx, bb, &builder, size, convert (ctx, LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE), t), convert (ctx, addr, LLVMPointerType (t, 0)), is_volatile);
5195 emit_load (ctx, bb, &builder, sizeof (gpointer), convert (ctx, lhs, LLVMPointerType (IntPtrType (), 0)), "", TRUE);
5197 case OP_OUTARG_VTRETADDR:
5205 case OP_VOIDCALL_MEMBASE:
5206 case OP_CALL_MEMBASE:
5207 case OP_LCALL_MEMBASE:
5208 case OP_FCALL_MEMBASE:
5209 case OP_RCALL_MEMBASE:
5210 case OP_VCALL_MEMBASE:
5211 case OP_VOIDCALL_REG:
5216 case OP_VCALL_REG: {
5217 process_call (ctx, bb, &builder, ins);
5222 LLVMValueRef indexes [2];
5223 MonoJumpInfo *tmp_ji, *ji;
5224 LLVMValueRef got_entry_addr;
5228 * FIXME: Can't allocate from the cfg mempool since that is freed if
5229 * the LLVM compile fails.
5231 tmp_ji = g_new0 (MonoJumpInfo, 1);
5232 tmp_ji->type = (MonoJumpInfoType)ins->inst_c1;
5233 tmp_ji->data.target = ins->inst_p0;
5235 ji = mono_aot_patch_info_dup (tmp_ji);
5238 if (ji->type == MONO_PATCH_INFO_ICALL_ADDR) {
5239 char *symbol = mono_aot_get_direct_call_symbol (MONO_PATCH_INFO_ICALL_ADDR_CALL, ji->data.target);
5242 * Avoid emitting a got entry for these since the method is directly called, and it might not be
5243 * resolvable at runtime using dlsym ().
5246 values [ins->dreg] = LLVMConstInt (IntPtrType (), 0, FALSE);
5251 ji->next = cfg->patch_info;
5252 cfg->patch_info = ji;
5254 //mono_add_patch_info (cfg, 0, (MonoJumpInfoType)ins->inst_i1, ins->inst_p0);
5255 got_offset = mono_aot_get_got_offset (cfg->patch_info);
5256 ctx->module->max_got_offset = MAX (ctx->module->max_got_offset, got_offset);
5257 if (!mono_aot_is_shared_got_offset (got_offset)) {
5258 //mono_print_ji (ji);
5260 ctx->has_got_access = TRUE;
5263 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
5264 indexes [1] = LLVMConstInt (LLVMInt32Type (), (gssize)got_offset, FALSE);
5265 got_entry_addr = LLVMBuildGEP (builder, ctx->module->got_var, indexes, 2, "");
5267 name = get_aotconst_name (ji->type, ji->data.target, got_offset);
5268 values [ins->dreg] = LLVMBuildLoad (builder, got_entry_addr, name);
5270 /* Can't use this in llvmonly mode since the got slots are initialized by the methods themselves */
5271 if (!cfg->llvm_only)
5272 set_invariant_load_flag (values [ins->dreg]);
5275 case OP_NOT_REACHED:
5276 LLVMBuildUnreachable (builder);
5277 has_terminator = TRUE;
5278 g_assert (bb->block_num < cfg->max_block_num);
5279 ctx->unreachable [bb->block_num] = TRUE;
5280 /* Might have instructions after this */
5282 MonoInst *next = ins->next;
5284 * FIXME: If later code uses the regs defined by these instructions,
5285 * compilation will fail.
5287 MONO_DELETE_INS (bb, next);
5291 MonoInst *var = ins->inst_i0;
5293 if (var->opcode == OP_VTARG_ADDR) {
5294 /* The variable contains the vtype address */
5295 values [ins->dreg] = values [var->dreg];
5296 } else if (var->opcode == OP_GSHAREDVT_LOCAL) {
5297 values [ins->dreg] = emit_gsharedvt_ldaddr (ctx, var->dreg);
5299 values [ins->dreg] = addresses [var->dreg];
5304 LLVMValueRef args [1];
5306 args [0] = convert (ctx, lhs, LLVMDoubleType ());
5307 values [ins->dreg] = LLVMBuildCall (builder, get_intrinsic (ctx, "llvm.sin.f64"), args, 1, dname);
5311 LLVMValueRef args [1];
5313 args [0] = convert (ctx, lhs, LLVMDoubleType ());
5314 values [ins->dreg] = LLVMBuildCall (builder, get_intrinsic (ctx, "llvm.cos.f64"), args, 1, dname);
5318 LLVMValueRef args [1];
5320 args [0] = convert (ctx, lhs, LLVMDoubleType ());
5321 values [ins->dreg] = LLVMBuildCall (builder, get_intrinsic (ctx, "llvm.sqrt.f64"), args, 1, dname);
5325 LLVMValueRef args [1];
5327 args [0] = convert (ctx, lhs, LLVMDoubleType ());
5328 values [ins->dreg] = LLVMBuildCall (builder, get_intrinsic (ctx, "fabs"), args, 1, dname);
5342 lhs = convert (ctx, lhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
5343 rhs = convert (ctx, rhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
5345 switch (ins->opcode) {
5348 v = LLVMBuildICmp (builder, LLVMIntSLE, lhs, rhs, "");
5352 v = LLVMBuildICmp (builder, LLVMIntSGE, lhs, rhs, "");
5356 v = LLVMBuildICmp (builder, LLVMIntULE, lhs, rhs, "");
5360 v = LLVMBuildICmp (builder, LLVMIntUGE, lhs, rhs, "");
5363 g_assert_not_reached ();
5366 values [ins->dreg] = LLVMBuildSelect (builder, v, lhs, rhs, dname);
5369 case OP_ATOMIC_EXCHANGE_I4:
5370 case OP_ATOMIC_EXCHANGE_I8: {
5371 LLVMValueRef args [2];
5374 if (ins->opcode == OP_ATOMIC_EXCHANGE_I4)
5375 t = LLVMInt32Type ();
5377 t = LLVMInt64Type ();
5379 g_assert (ins->inst_offset == 0);
5381 args [0] = convert (ctx, lhs, LLVMPointerType (t, 0));
5382 args [1] = convert (ctx, rhs, t);
5384 values [ins->dreg] = mono_llvm_build_atomic_rmw (builder, LLVM_ATOMICRMW_OP_XCHG, args [0], args [1]);
5387 case OP_ATOMIC_ADD_I4:
5388 case OP_ATOMIC_ADD_I8: {
5389 LLVMValueRef args [2];
5392 if (ins->opcode == OP_ATOMIC_ADD_I4)
5393 t = LLVMInt32Type ();
5395 t = LLVMInt64Type ();
5397 g_assert (ins->inst_offset == 0);
5399 args [0] = convert (ctx, lhs, LLVMPointerType (t, 0));
5400 args [1] = convert (ctx, rhs, t);
5401 values [ins->dreg] = LLVMBuildAdd (builder, mono_llvm_build_atomic_rmw (builder, LLVM_ATOMICRMW_OP_ADD, args [0], args [1]), args [1], dname);
5404 case OP_ATOMIC_CAS_I4:
5405 case OP_ATOMIC_CAS_I8: {
5406 LLVMValueRef args [3], val;
5409 if (ins->opcode == OP_ATOMIC_CAS_I4)
5410 t = LLVMInt32Type ();
5412 t = LLVMInt64Type ();
5414 args [0] = convert (ctx, lhs, LLVMPointerType (t, 0));
5416 args [1] = convert (ctx, values [ins->sreg3], t);
5418 args [2] = convert (ctx, values [ins->sreg2], t);
5419 val = mono_llvm_build_cmpxchg (builder, args [0], args [1], args [2]);
5420 /* cmpxchg returns a pair */
5421 values [ins->dreg] = LLVMBuildExtractValue (builder, val, 0, "");
5424 case OP_MEMORY_BARRIER: {
5425 mono_llvm_build_fence (builder, (BarrierKind) ins->backend.memory_barrier_kind);
5428 case OP_ATOMIC_LOAD_I1:
5429 case OP_ATOMIC_LOAD_I2:
5430 case OP_ATOMIC_LOAD_I4:
5431 case OP_ATOMIC_LOAD_I8:
5432 case OP_ATOMIC_LOAD_U1:
5433 case OP_ATOMIC_LOAD_U2:
5434 case OP_ATOMIC_LOAD_U4:
5435 case OP_ATOMIC_LOAD_U8:
5436 case OP_ATOMIC_LOAD_R4:
5437 case OP_ATOMIC_LOAD_R8: {
5438 set_failure (ctx, "atomic mono.load intrinsic");
5442 gboolean sext, zext;
5444 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
5445 BarrierKind barrier = (BarrierKind) ins->backend.memory_barrier_kind;
5446 LLVMValueRef index, addr;
5448 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
5453 if (ins->inst_offset != 0) {
5454 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
5455 addr = LLVMBuildGEP (builder, convert (ctx, lhs, LLVMPointerType (t, 0)), &index, 1, "");
5460 addr = convert (ctx, addr, LLVMPointerType (t, 0));
5462 values [ins->dreg] = emit_load_general (ctx, bb, &builder, size, addr, dname, is_volatile, barrier);
5465 values [ins->dreg] = LLVMBuildSExt (builder, values [ins->dreg], LLVMInt32Type (), dname);
5467 values [ins->dreg] = LLVMBuildZExt (builder, values [ins->dreg], LLVMInt32Type (), dname);
5471 case OP_ATOMIC_STORE_I1:
5472 case OP_ATOMIC_STORE_I2:
5473 case OP_ATOMIC_STORE_I4:
5474 case OP_ATOMIC_STORE_I8:
5475 case OP_ATOMIC_STORE_U1:
5476 case OP_ATOMIC_STORE_U2:
5477 case OP_ATOMIC_STORE_U4:
5478 case OP_ATOMIC_STORE_U8:
5479 case OP_ATOMIC_STORE_R4:
5480 case OP_ATOMIC_STORE_R8: {
5481 set_failure (ctx, "atomic mono.store intrinsic");
5485 gboolean sext, zext;
5487 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
5488 BarrierKind barrier = (BarrierKind) ins->backend.memory_barrier_kind;
5489 LLVMValueRef index, addr, value;
5491 if (!values [ins->inst_destbasereg]) {
5492 set_failure (ctx, "inst_destbasereg");
5496 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
5498 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
5499 addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (t, 0)), &index, 1, "");
5500 value = convert (ctx, values [ins->sreg1], t);
5502 emit_store_general (ctx, bb, &builder, size, value, addr, is_volatile, barrier);
5506 case OP_RELAXED_NOP: {
5507 #if defined(TARGET_AMD64) || defined(TARGET_X86)
5508 emit_call (ctx, bb, &builder, get_intrinsic (ctx, "llvm.x86.sse2.pause"), NULL, 0);
5515 #if (defined(TARGET_AMD64) || defined(TARGET_X86)) && defined(__linux__)
5517 // 257 == FS segment register
5518 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 257);
5520 // 256 == GS segment register
5521 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 256);
5524 values [ins->dreg] = LLVMBuildLoad (builder, LLVMBuildIntToPtr (builder, LLVMConstInt (IntPtrType (), ins->inst_offset, TRUE), ptrtype, ""), "");
5525 #elif defined(TARGET_AMD64) && defined(TARGET_OSX)
5526 /* See mono_amd64_emit_tls_get () */
5527 int offset = mono_amd64_get_tls_gs_offset () + (ins->inst_offset * 8);
5529 // 256 == GS segment register
5530 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 256);
5531 values [ins->dreg] = LLVMBuildLoad (builder, LLVMBuildIntToPtr (builder, LLVMConstInt (IntPtrType (), offset, TRUE), ptrtype, ""), "");
5533 set_failure (ctx, "opcode tls-get");
5539 case OP_TLS_GET_REG: {
5540 #if defined(TARGET_AMD64) && defined(TARGET_OSX)
5541 /* See emit_tls_get_reg () */
5542 // 256 == GS segment register
5543 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 256);
5544 values [ins->dreg] = LLVMBuildLoad (builder, LLVMBuildIntToPtr (builder, convert (ctx, lhs, LLVMInt32Type ()), ptrtype, ""), "");
5546 set_failure (ctx, "opcode tls-get");
5552 case OP_TLS_SET_REG: {
5553 #if defined(TARGET_AMD64) && defined(TARGET_OSX)
5554 /* See emit_tls_get_reg () */
5555 // 256 == GS segment register
5556 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 256);
5557 LLVMBuildStore (builder, convert (ctx, lhs, IntPtrType ()), LLVMBuildIntToPtr (builder, convert (ctx, rhs, LLVMInt32Type ()), ptrtype, ""));
5559 set_failure (ctx, "opcode tls-set-reg");
5564 case OP_GC_SAFE_POINT: {
5565 LLVMValueRef val, cmp, callee;
5566 LLVMBasicBlockRef poll_bb, cont_bb;
5567 static LLVMTypeRef sig;
5568 const char *icall_name = "mono_threads_state_poll";
5571 sig = LLVMFunctionType0 (LLVMVoidType (), FALSE);
5575 * mono_threads_state_poll ();
5576 * FIXME: Use a preserveall wrapper
5578 val = mono_llvm_build_load (builder, convert (ctx, lhs, LLVMPointerType (IntPtrType (), 0)), "", TRUE, LLVM_BARRIER_NONE);
5579 cmp = LLVMBuildICmp (builder, LLVMIntEQ, val, LLVMConstNull (LLVMTypeOf (val)), "");
5580 poll_bb = gen_bb (ctx, "POLL_BB");
5581 cont_bb = gen_bb (ctx, "CONT_BB");
5582 LLVMBuildCondBr (builder, cmp, cont_bb, poll_bb);
5584 ctx->builder = builder = create_builder (ctx);
5585 LLVMPositionBuilderAtEnd (builder, poll_bb);
5587 if (ctx->cfg->compile_aot) {
5588 callee = get_callee (ctx, sig, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
5590 gpointer target = resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
5591 callee = emit_jit_callee (ctx, icall_name, sig, target);
5593 LLVMBuildCall (builder, callee, NULL, 0, "");
5594 LLVMBuildBr (builder, cont_bb);
5596 ctx->builder = builder = create_builder (ctx);
5597 LLVMPositionBuilderAtEnd (builder, cont_bb);
5598 ctx->bblocks [bb->block_num].end_bblock = cont_bb;
5606 case OP_IADD_OVF_UN:
5608 case OP_ISUB_OVF_UN:
5610 case OP_IMUL_OVF_UN:
5612 case OP_LADD_OVF_UN:
5614 case OP_LSUB_OVF_UN:
5616 case OP_LMUL_OVF_UN:
5618 LLVMValueRef args [2], val, ovf, func;
5620 args [0] = convert (ctx, lhs, op_to_llvm_type (ins->opcode));
5621 args [1] = convert (ctx, rhs, op_to_llvm_type (ins->opcode));
5622 func = get_intrinsic (ctx, ovf_op_to_intrins (ins->opcode));
5624 val = LLVMBuildCall (builder, func, args, 2, "");
5625 values [ins->dreg] = LLVMBuildExtractValue (builder, val, 0, dname);
5626 ovf = LLVMBuildExtractValue (builder, val, 1, "");
5627 emit_cond_system_exception (ctx, bb, "OverflowException", ovf);
5630 builder = ctx->builder;
5636 * We currently model them using arrays. Promotion to local vregs is
5637 * disabled for them in mono_handle_global_vregs () in the LLVM case,
5638 * so we always have an entry in cfg->varinfo for them.
5639 * FIXME: Is this needed ?
5642 MonoClass *klass = ins->klass;
5643 LLVMValueRef args [5];
5647 set_failure (ctx, "!klass");
5651 if (!addresses [ins->dreg])
5652 addresses [ins->dreg] = build_alloca (ctx, &klass->byval_arg);
5653 args [0] = LLVMBuildBitCast (builder, addresses [ins->dreg], LLVMPointerType (LLVMInt8Type (), 0), "");
5654 args [1] = LLVMConstInt (LLVMInt8Type (), 0, FALSE);
5655 args [2] = LLVMConstInt (LLVMInt32Type (), mono_class_value_size (klass, NULL), FALSE);
5657 args [3] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
5658 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
5659 LLVMBuildCall (builder, get_intrinsic (ctx, "llvm.memset.p0i8.i32"), args, 5, "");
5662 case OP_DUMMY_VZERO:
5665 case OP_STOREV_MEMBASE:
5666 case OP_LOADV_MEMBASE:
5668 MonoClass *klass = ins->klass;
5669 LLVMValueRef src = NULL, dst, args [5];
5670 gboolean done = FALSE;
5674 set_failure (ctx, "!klass");
5678 if (mini_is_gsharedvt_klass (klass)) {
5680 set_failure (ctx, "gsharedvt");
5684 switch (ins->opcode) {
5685 case OP_STOREV_MEMBASE:
5686 if (cfg->gen_write_barriers && klass->has_references && ins->inst_destbasereg != cfg->frame_reg &&
5687 LLVMGetInstructionOpcode (values [ins->inst_destbasereg]) != LLVMAlloca) {
5688 /* Decomposed earlier */
5689 g_assert_not_reached ();
5692 if (!addresses [ins->sreg1]) {
5694 g_assert (values [ins->sreg1]);
5695 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));
5696 LLVMBuildStore (builder, values [ins->sreg1], dst);
5699 src = LLVMBuildBitCast (builder, addresses [ins->sreg1], LLVMPointerType (LLVMInt8Type (), 0), "");
5700 dst = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_destbasereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (LLVMInt8Type (), 0));
5703 case OP_LOADV_MEMBASE:
5704 if (!addresses [ins->dreg])
5705 addresses [ins->dreg] = build_alloca (ctx, &klass->byval_arg);
5706 src = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_basereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (LLVMInt8Type (), 0));
5707 dst = LLVMBuildBitCast (builder, addresses [ins->dreg], LLVMPointerType (LLVMInt8Type (), 0), "");
5710 if (!addresses [ins->sreg1])
5711 addresses [ins->sreg1] = build_alloca (ctx, &klass->byval_arg);
5712 if (!addresses [ins->dreg])
5713 addresses [ins->dreg] = build_alloca (ctx, &klass->byval_arg);
5714 src = LLVMBuildBitCast (builder, addresses [ins->sreg1], LLVMPointerType (LLVMInt8Type (), 0), "");
5715 dst = LLVMBuildBitCast (builder, addresses [ins->dreg], LLVMPointerType (LLVMInt8Type (), 0), "");
5718 g_assert_not_reached ();
5728 args [2] = LLVMConstInt (LLVMInt32Type (), mono_class_value_size (klass, NULL), FALSE);
5729 args [3] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
5731 args [3] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
5732 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
5733 LLVMBuildCall (builder, get_intrinsic (ctx, "llvm.memcpy.p0i8.p0i8.i32"), args, 5, "");
5736 case OP_LLVM_OUTARG_VT: {
5737 LLVMArgInfo *ainfo = (LLVMArgInfo*)ins->inst_p0;
5738 MonoType *t = mini_get_underlying_type (ins->inst_vtype);
5740 if (ainfo->storage == LLVMArgGsharedvtVariable) {
5741 MonoInst *var = get_vreg_to_inst (cfg, ins->sreg1);
5743 if (var && var->opcode == OP_GSHAREDVT_LOCAL) {
5744 addresses [ins->dreg] = convert (ctx, emit_gsharedvt_ldaddr (ctx, var->dreg), LLVMPointerType (IntPtrType (), 0));
5746 g_assert (addresses [ins->sreg1]);
5747 addresses [ins->dreg] = addresses [ins->sreg1];
5749 } else if (ainfo->storage == LLVMArgGsharedvtFixed) {
5750 if (!addresses [ins->sreg1]) {
5751 addresses [ins->sreg1] = build_alloca (ctx, t);
5752 g_assert (values [ins->sreg1]);
5754 LLVMBuildStore (builder, convert (ctx, values [ins->sreg1], LLVMGetElementType (LLVMTypeOf (addresses [ins->sreg1]))), addresses [ins->sreg1]);
5755 addresses [ins->dreg] = addresses [ins->sreg1];
5757 if (!addresses [ins->sreg1]) {
5758 addresses [ins->sreg1] = build_alloca (ctx, t);
5759 g_assert (values [ins->sreg1]);
5760 LLVMBuildStore (builder, convert (ctx, values [ins->sreg1], type_to_llvm_type (ctx, t)), addresses [ins->sreg1]);
5762 addresses [ins->dreg] = addresses [ins->sreg1];
5770 #if defined(TARGET_X86) || defined(TARGET_AMD64)
5772 values [ins->dreg] = LLVMConstNull (type_to_llvm_type (ctx, &ins->klass->byval_arg));
5775 case OP_LOADX_MEMBASE: {
5776 LLVMTypeRef t = type_to_llvm_type (ctx, &ins->klass->byval_arg);
5779 src = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_basereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (t, 0));
5780 values [ins->dreg] = mono_llvm_build_aligned_load (builder, src, "", FALSE, 1);
5783 case OP_STOREX_MEMBASE: {
5784 LLVMTypeRef t = LLVMTypeOf (values [ins->sreg1]);
5787 dest = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_destbasereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (t, 0));
5788 mono_llvm_build_aligned_store (builder, values [ins->sreg1], dest, FALSE, 1);
5795 values [ins->dreg] = LLVMBuildAdd (builder, lhs, rhs, "");
5799 values [ins->dreg] = LLVMBuildFAdd (builder, lhs, rhs, "");
5805 values [ins->dreg] = LLVMBuildSub (builder, lhs, rhs, "");
5809 values [ins->dreg] = LLVMBuildFSub (builder, lhs, rhs, "");
5813 values [ins->dreg] = LLVMBuildFMul (builder, lhs, rhs, "");
5817 values [ins->dreg] = LLVMBuildFDiv (builder, lhs, rhs, "");
5820 values [ins->dreg] = LLVMBuildAnd (builder, lhs, rhs, "");
5823 values [ins->dreg] = LLVMBuildOr (builder, lhs, rhs, "");
5826 values [ins->dreg] = LLVMBuildXor (builder, lhs, rhs, "");
5830 values [ins->dreg] = LLVMBuildMul (builder, lhs, rhs, "");
5841 LLVMValueRef v = NULL;
5843 switch (ins->opcode) {
5848 t = LLVMVectorType (LLVMInt32Type (), 4);
5849 rt = LLVMVectorType (LLVMFloatType (), 4);
5855 t = LLVMVectorType (LLVMInt64Type (), 2);
5856 rt = LLVMVectorType (LLVMDoubleType (), 2);
5859 t = LLVMInt32Type ();
5860 rt = LLVMInt32Type ();
5861 g_assert_not_reached ();
5864 lhs = LLVMBuildBitCast (builder, lhs, t, "");
5865 rhs = LLVMBuildBitCast (builder, rhs, t, "");
5866 switch (ins->opcode) {
5869 v = LLVMBuildAnd (builder, lhs, rhs, "");
5873 v = LLVMBuildOr (builder, lhs, rhs, "");
5877 v = LLVMBuildXor (builder, lhs, rhs, "");
5881 v = LLVMBuildAnd (builder, rhs, LLVMBuildNot (builder, lhs, ""), "");
5884 values [ins->dreg] = LLVMBuildBitCast (builder, v, rt, "");
5908 case OP_PADDB_SAT_UN:
5909 case OP_PADDW_SAT_UN:
5910 case OP_PSUBB_SAT_UN:
5911 case OP_PSUBW_SAT_UN:
5919 case OP_PMULW_HIGH_UN: {
5920 LLVMValueRef args [2];
5925 values [ins->dreg] = LLVMBuildCall (builder, get_intrinsic (ctx, simd_op_to_intrins (ins->opcode)), args, 2, dname);
5932 values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildICmp (builder, LLVMIntEQ, lhs, rhs, ""), LLVMTypeOf (lhs), "");
5936 values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildICmp (builder, LLVMIntSGT, lhs, rhs, ""), LLVMTypeOf (lhs), "");
5944 case OP_EXTRACTX_U2:
5946 case OP_EXTRACT_U1: {
5948 gboolean zext = FALSE;
5950 t = simd_op_to_llvm_type (ins->opcode);
5952 switch (ins->opcode) {
5960 case OP_EXTRACTX_U2:
5965 t = LLVMInt32Type ();
5966 g_assert_not_reached ();
5969 lhs = LLVMBuildBitCast (builder, lhs, t, "");
5970 values [ins->dreg] = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), "");
5972 values [ins->dreg] = LLVMBuildZExt (builder, values [ins->dreg], LLVMInt32Type (), "");
5981 case OP_EXPAND_R8: {
5982 LLVMTypeRef t = simd_op_to_llvm_type (ins->opcode);
5983 LLVMValueRef mask [16], v;
5986 for (i = 0; i < 16; ++i)
5987 mask [i] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
5989 v = convert (ctx, values [ins->sreg1], LLVMGetElementType (t));
5991 values [ins->dreg] = LLVMBuildInsertElement (builder, LLVMConstNull (t), v, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
5992 values [ins->dreg] = LLVMBuildShuffleVector (builder, values [ins->dreg], LLVMGetUndef (t), LLVMConstVector (mask, LLVMGetVectorSize (t)), "");
5997 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt8Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
6000 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt16Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
6003 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt32Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
6006 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt64Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
6009 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMFloatType ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
6012 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMDoubleType ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
6023 case OP_EXTRACT_MASK:
6030 v = convert (ctx, values [ins->sreg1], simd_op_to_llvm_type (ins->opcode));
6032 values [ins->dreg] = LLVMBuildCall (builder, get_intrinsic (ctx, simd_op_to_intrins (ins->opcode)), &v, 1, dname);
6038 LLVMValueRef args [3];
6042 args [2] = LLVMConstInt (LLVMInt8Type (), ins->inst_c0, FALSE);
6044 values [ins->dreg] = LLVMBuildCall (builder, get_intrinsic (ctx, simd_op_to_intrins (ins->opcode)), args, 3, dname);
6049 /* This is only used for implementing shifts by non-immediate */
6050 values [ins->dreg] = lhs;
6061 LLVMValueRef args [3];
6064 args [1] = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
6066 values [ins->dreg] = LLVMBuildCall (builder, get_intrinsic (ctx, simd_op_to_intrins (ins->opcode)), args, 2, dname);
6077 case OP_PSHLQ_REG: {
6078 LLVMValueRef args [3];
6081 args [1] = values [ins->sreg2];
6083 values [ins->dreg] = LLVMBuildCall (builder, get_intrinsic (ctx, simd_op_to_intrins (ins->opcode)), args, 2, dname);
6090 case OP_PSHUFLEW_LOW:
6091 case OP_PSHUFLEW_HIGH: {
6093 LLVMValueRef v1 = NULL, v2 = NULL, mask_values [16];
6094 int i, mask_size = 0;
6095 int imask = ins->inst_c0;
6097 /* Convert the x86 shuffle mask to LLVM's */
6098 switch (ins->opcode) {
6101 mask [0] = ((imask >> 0) & 3);
6102 mask [1] = ((imask >> 2) & 3);
6103 mask [2] = ((imask >> 4) & 3) + 4;
6104 mask [3] = ((imask >> 6) & 3) + 4;
6105 v1 = values [ins->sreg1];
6106 v2 = values [ins->sreg2];
6110 mask [0] = ((imask >> 0) & 1);
6111 mask [1] = ((imask >> 1) & 1) + 2;
6112 v1 = values [ins->sreg1];
6113 v2 = values [ins->sreg2];
6115 case OP_PSHUFLEW_LOW:
6117 mask [0] = ((imask >> 0) & 3);
6118 mask [1] = ((imask >> 2) & 3);
6119 mask [2] = ((imask >> 4) & 3);
6120 mask [3] = ((imask >> 6) & 3);
6125 v1 = values [ins->sreg1];
6126 v2 = LLVMGetUndef (LLVMTypeOf (v1));
6128 case OP_PSHUFLEW_HIGH:
6134 mask [4] = 4 + ((imask >> 0) & 3);
6135 mask [5] = 4 + ((imask >> 2) & 3);
6136 mask [6] = 4 + ((imask >> 4) & 3);
6137 mask [7] = 4 + ((imask >> 6) & 3);
6138 v1 = values [ins->sreg1];
6139 v2 = LLVMGetUndef (LLVMTypeOf (v1));
6143 mask [0] = ((imask >> 0) & 3);
6144 mask [1] = ((imask >> 2) & 3);
6145 mask [2] = ((imask >> 4) & 3);
6146 mask [3] = ((imask >> 6) & 3);
6147 v1 = values [ins->sreg1];
6148 v2 = LLVMGetUndef (LLVMTypeOf (v1));
6151 g_assert_not_reached ();
6153 for (i = 0; i < mask_size; ++i)
6154 mask_values [i] = LLVMConstInt (LLVMInt32Type (), mask [i], FALSE);
6156 values [ins->dreg] =
6157 LLVMBuildShuffleVector (builder, v1, v2,
6158 LLVMConstVector (mask_values, mask_size), dname);
6162 case OP_UNPACK_LOWB:
6163 case OP_UNPACK_LOWW:
6164 case OP_UNPACK_LOWD:
6165 case OP_UNPACK_LOWQ:
6166 case OP_UNPACK_LOWPS:
6167 case OP_UNPACK_LOWPD:
6168 case OP_UNPACK_HIGHB:
6169 case OP_UNPACK_HIGHW:
6170 case OP_UNPACK_HIGHD:
6171 case OP_UNPACK_HIGHQ:
6172 case OP_UNPACK_HIGHPS:
6173 case OP_UNPACK_HIGHPD: {
6175 LLVMValueRef mask_values [16];
6176 int i, mask_size = 0;
6177 gboolean low = FALSE;
6179 switch (ins->opcode) {
6180 case OP_UNPACK_LOWB:
6184 case OP_UNPACK_LOWW:
6188 case OP_UNPACK_LOWD:
6189 case OP_UNPACK_LOWPS:
6193 case OP_UNPACK_LOWQ:
6194 case OP_UNPACK_LOWPD:
6198 case OP_UNPACK_HIGHB:
6201 case OP_UNPACK_HIGHW:
6204 case OP_UNPACK_HIGHD:
6205 case OP_UNPACK_HIGHPS:
6208 case OP_UNPACK_HIGHQ:
6209 case OP_UNPACK_HIGHPD:
6213 g_assert_not_reached ();
6217 for (i = 0; i < (mask_size / 2); ++i) {
6219 mask [(i * 2) + 1] = mask_size + i;
6222 for (i = 0; i < (mask_size / 2); ++i) {
6223 mask [(i * 2)] = (mask_size / 2) + i;
6224 mask [(i * 2) + 1] = mask_size + (mask_size / 2) + i;
6228 for (i = 0; i < mask_size; ++i)
6229 mask_values [i] = LLVMConstInt (LLVMInt32Type (), mask [i], FALSE);
6231 values [ins->dreg] =
6232 LLVMBuildShuffleVector (builder, values [ins->sreg1], values [ins->sreg2],
6233 LLVMConstVector (mask_values, mask_size), dname);
6238 LLVMTypeRef t = simd_op_to_llvm_type (ins->opcode);
6239 LLVMValueRef v, val;
6241 v = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
6242 val = LLVMConstNull (t);
6243 val = LLVMBuildInsertElement (builder, val, v, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
6244 val = LLVMBuildInsertElement (builder, val, v, LLVMConstInt (LLVMInt32Type (), 1, FALSE), dname);
6246 values [ins->dreg] = val;
6250 case OP_DUPPS_HIGH: {
6251 LLVMTypeRef t = simd_op_to_llvm_type (ins->opcode);
6252 LLVMValueRef v1, v2, val;
6255 if (ins->opcode == OP_DUPPS_LOW) {
6256 v1 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
6257 v2 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 2, FALSE), "");
6259 v1 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 1, FALSE), "");
6260 v2 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 3, FALSE), "");
6262 val = LLVMConstNull (t);
6263 val = LLVMBuildInsertElement (builder, val, v1, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
6264 val = LLVMBuildInsertElement (builder, val, v1, LLVMConstInt (LLVMInt32Type (), 1, FALSE), "");
6265 val = LLVMBuildInsertElement (builder, val, v2, LLVMConstInt (LLVMInt32Type (), 2, FALSE), "");
6266 val = LLVMBuildInsertElement (builder, val, v2, LLVMConstInt (LLVMInt32Type (), 3, FALSE), "");
6268 values [ins->dreg] = val;
6278 * EXCEPTION HANDLING
6280 case OP_IMPLICIT_EXCEPTION:
6281 /* This marks a place where an implicit exception can happen */
6282 if (bb->region != -1)
6283 set_failure (ctx, "implicit-exception");
6287 gboolean rethrow = (ins->opcode == OP_RETHROW);
6288 if (ctx->llvm_only) {
6289 emit_llvmonly_throw (ctx, bb, rethrow, lhs);
6290 has_terminator = TRUE;
6291 ctx->unreachable [bb->block_num] = TRUE;
6293 emit_throw (ctx, bb, rethrow, lhs);
6294 builder = ctx->builder;
6298 case OP_CALL_HANDLER: {
6300 * We don't 'call' handlers, but instead simply branch to them.
6301 * The code generated by ENDFINALLY will branch back to us.
6303 LLVMBasicBlockRef noex_bb;
6305 BBInfo *info = &bblocks [ins->inst_target_bb->block_num];
6307 bb_list = info->call_handler_return_bbs;
6310 * Set the indicator variable for the finally clause.
6312 lhs = info->finally_ind;
6314 LLVMBuildStore (builder, LLVMConstInt (LLVMInt32Type (), g_slist_length (bb_list) + 1, FALSE), lhs);
6316 /* Branch to the finally clause */
6317 LLVMBuildBr (builder, info->call_handler_target_bb);
6319 noex_bb = gen_bb (ctx, "CALL_HANDLER_CONT_BB");
6320 info->call_handler_return_bbs = g_slist_append_mempool (cfg->mempool, info->call_handler_return_bbs, noex_bb);
6322 builder = ctx->builder = create_builder (ctx);
6323 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
6325 bblocks [bb->block_num].end_bblock = noex_bb;
6328 case OP_START_HANDLER: {
6331 case OP_ENDFINALLY: {
6332 LLVMBasicBlockRef resume_bb;
6333 MonoBasicBlock *handler_bb;
6334 LLVMValueRef val, switch_ins, callee;
6338 handler_bb = (MonoBasicBlock*)g_hash_table_lookup (ctx->region_to_handler, GUINT_TO_POINTER (mono_get_block_region_notry (cfg, bb->region)));
6339 g_assert (handler_bb);
6340 info = &bblocks [handler_bb->block_num];
6341 lhs = info->finally_ind;
6344 bb_list = info->call_handler_return_bbs;
6346 resume_bb = gen_bb (ctx, "ENDFINALLY_RESUME_BB");
6348 /* Load the finally variable */
6349 val = LLVMBuildLoad (builder, lhs, "");
6351 /* Reset the variable */
6352 LLVMBuildStore (builder, LLVMConstInt (LLVMInt32Type (), 0, FALSE), lhs);
6354 /* Branch to either resume_bb, or to the bblocks in bb_list */
6355 switch_ins = LLVMBuildSwitch (builder, val, resume_bb, g_slist_length (bb_list));
6357 * The other targets are added at the end to handle OP_CALL_HANDLER
6358 * opcodes processed later.
6360 info->endfinally_switch_ins_list = g_slist_append_mempool (cfg->mempool, info->endfinally_switch_ins_list, switch_ins);
6362 builder = ctx->builder = create_builder (ctx);
6363 LLVMPositionBuilderAtEnd (ctx->builder, resume_bb);
6365 if (ctx->llvm_only) {
6366 emit_resume_eh (ctx, bb);
6368 if (ctx->cfg->compile_aot) {
6369 callee = get_callee (ctx, LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE), MONO_PATCH_INFO_INTERNAL_METHOD, "llvm_resume_unwind_trampoline");
6371 #if LLVM_API_VERSION > 100
6372 MonoJitICallInfo *info;
6374 info = mono_find_jit_icall_by_name ("llvm_resume_unwind_trampoline");
6376 gpointer target = (void*)info->func;
6377 LLVMTypeRef icall_sig = LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE);
6378 callee = emit_jit_callee (ctx, "llvm_resume_unwind_trampoline", icall_sig, target);
6380 callee = LLVMGetNamedFunction (ctx->lmodule, "llvm_resume_unwind_trampoline");
6383 LLVMBuildCall (builder, callee, NULL, 0, "");
6384 LLVMBuildUnreachable (builder);
6387 has_terminator = TRUE;
6390 case OP_IL_SEQ_POINT:
6395 sprintf (reason, "opcode %s", mono_inst_name (ins->opcode));
6396 set_failure (ctx, reason);
6404 /* Convert the value to the type required by phi nodes */
6405 if (spec [MONO_INST_DEST] != ' ' && !MONO_IS_STORE_MEMBASE (ins) && ctx->vreg_types [ins->dreg]) {
6406 if (!values [ins->dreg])
6408 values [ins->dreg] = addresses [ins->dreg];
6410 values [ins->dreg] = convert (ctx, values [ins->dreg], ctx->vreg_types [ins->dreg]);
6413 /* Add stores for volatile variables */
6414 if (spec [MONO_INST_DEST] != ' ' && spec [MONO_INST_DEST] != 'v' && !MONO_IS_STORE_MEMBASE (ins))
6415 emit_volatile_store (ctx, ins->dreg);
6421 if (!has_terminator && bb->next_bb && (bb == cfg->bb_entry || bb->in_count > 0)) {
6422 LLVMBuildBr (builder, get_bb (ctx, bb->next_bb));
6425 if (bb == cfg->bb_exit && sig->ret->type == MONO_TYPE_VOID) {
6426 emit_dbg_loc (ctx, builder, cfg->header->code + cfg->header->code_size - 1);
6427 LLVMBuildRetVoid (builder);
6430 if (bb == cfg->bb_entry)
6431 ctx->last_alloca = LLVMGetLastInstruction (get_bb (ctx, cfg->bb_entry));
6435 * mono_llvm_check_method_supported:
6437 * Do some quick checks to decide whenever cfg->method can be compiled by LLVM, to avoid
6438 * compiling a method twice.
6441 mono_llvm_check_method_supported (MonoCompile *cfg)
6448 if (cfg->method->save_lmf) {
6449 cfg->exception_message = g_strdup ("lmf");
6450 cfg->disable_llvm = TRUE;
6452 if (cfg->disable_llvm)
6456 * Nested clauses where one of the clauses is a finally clause is
6457 * not supported, because LLVM can't figure out the control flow,
6458 * probably because we resume exception handling by calling our
6459 * own function instead of using the 'resume' llvm instruction.
6461 for (i = 0; i < cfg->header->num_clauses; ++i) {
6462 for (j = 0; j < cfg->header->num_clauses; ++j) {
6463 MonoExceptionClause *clause1 = &cfg->header->clauses [i];
6464 MonoExceptionClause *clause2 = &cfg->header->clauses [j];
6466 // FIXME: Nested try clauses fail in some cases too, i.e. #37273
6467 if (i != j && clause1->try_offset >= clause2->try_offset && clause1->handler_offset <= clause2->handler_offset) {
6468 //(clause1->flags == MONO_EXCEPTION_CLAUSE_FINALLY || clause2->flags == MONO_EXCEPTION_CLAUSE_FINALLY)) {
6469 cfg->exception_message = g_strdup ("nested clauses");
6470 cfg->disable_llvm = TRUE;
6475 if (cfg->disable_llvm)
6479 if (cfg->method->dynamic) {
6480 cfg->exception_message = g_strdup ("dynamic.");
6481 cfg->disable_llvm = TRUE;
6483 if (cfg->disable_llvm)
6487 static LLVMCallInfo*
6488 get_llvm_call_info (MonoCompile *cfg, MonoMethodSignature *sig)
6490 LLVMCallInfo *linfo;
6493 if (cfg->gsharedvt && cfg->llvm_only && mini_is_gsharedvt_variable_signature (sig)) {
6497 * Gsharedvt methods have the following calling convention:
6498 * - all arguments are passed by ref, even non generic ones
6499 * - the return value is returned by ref too, using a vret
6500 * argument passed after 'this'.
6502 n = sig->param_count + sig->hasthis;
6503 linfo = (LLVMCallInfo*)mono_mempool_alloc0 (cfg->mempool, sizeof (LLVMCallInfo) + (sizeof (LLVMArgInfo) * n));
6507 linfo->args [pindex ++].storage = LLVMArgNormal;
6509 if (sig->ret->type != MONO_TYPE_VOID) {
6510 if (mini_is_gsharedvt_variable_type (sig->ret))
6511 linfo->ret.storage = LLVMArgGsharedvtVariable;
6512 else if (mini_type_is_vtype (sig->ret))
6513 linfo->ret.storage = LLVMArgGsharedvtFixedVtype;
6515 linfo->ret.storage = LLVMArgGsharedvtFixed;
6516 linfo->vret_arg_index = pindex;
6518 linfo->ret.storage = LLVMArgNone;
6521 for (i = 0; i < sig->param_count; ++i) {
6522 if (sig->params [i]->byref)
6523 linfo->args [pindex].storage = LLVMArgNormal;
6524 else if (mini_is_gsharedvt_variable_type (sig->params [i]))
6525 linfo->args [pindex].storage = LLVMArgGsharedvtVariable;
6526 else if (mini_type_is_vtype (sig->params [i]))
6527 linfo->args [pindex].storage = LLVMArgGsharedvtFixedVtype;
6529 linfo->args [pindex].storage = LLVMArgGsharedvtFixed;
6530 linfo->args [pindex].type = sig->params [i];
6537 linfo = mono_arch_get_llvm_call_info (cfg, sig);
6538 for (i = 0; i < sig->param_count; ++i)
6539 linfo->args [i + sig->hasthis].type = sig->params [i];
6545 emit_method_inner (EmitContext *ctx);
6548 free_ctx (EmitContext *ctx)
6552 g_free (ctx->values);
6553 g_free (ctx->addresses);
6554 g_free (ctx->vreg_types);
6555 g_free (ctx->vreg_cli_types);
6556 g_free (ctx->is_dead);
6557 g_free (ctx->unreachable);
6558 g_ptr_array_free (ctx->phi_values, TRUE);
6559 g_free (ctx->bblocks);
6560 g_hash_table_destroy (ctx->region_to_handler);
6561 g_hash_table_destroy (ctx->clause_to_handler);
6562 g_hash_table_destroy (ctx->jit_callees);
6563 g_free (ctx->method_name);
6564 g_ptr_array_free (ctx->bblock_list, TRUE);
6566 for (l = ctx->builders; l; l = l->next) {
6567 LLVMBuilderRef builder = (LLVMBuilderRef)l->data;
6568 LLVMDisposeBuilder (builder);
6575 * mono_llvm_emit_method:
6577 * Emit LLVM IL from the mono IL, and compile it to native code using LLVM.
6580 mono_llvm_emit_method (MonoCompile *cfg)
6584 gboolean is_linkonce = FALSE;
6587 /* The code below might acquire the loader lock, so use it for global locking */
6588 mono_loader_lock ();
6590 /* Used to communicate with the callbacks */
6591 mono_native_tls_set_value (current_cfg_tls_id, cfg);
6593 ctx = g_new0 (EmitContext, 1);
6595 ctx->mempool = cfg->mempool;
6598 * This maps vregs to the LLVM instruction defining them
6600 ctx->values = g_new0 (LLVMValueRef, cfg->next_vreg);
6602 * This maps vregs for volatile variables to the LLVM instruction defining their
6605 ctx->addresses = g_new0 (LLVMValueRef, cfg->next_vreg);
6606 ctx->vreg_types = g_new0 (LLVMTypeRef, cfg->next_vreg);
6607 ctx->vreg_cli_types = g_new0 (MonoType*, cfg->next_vreg);
6608 ctx->phi_values = g_ptr_array_sized_new (256);
6610 * This signals whenever the vreg was defined by a phi node with no input vars
6611 * (i.e. all its input bblocks end with NOT_REACHABLE).
6613 ctx->is_dead = g_new0 (gboolean, cfg->next_vreg);
6614 /* Whenever the bblock is unreachable */
6615 ctx->unreachable = g_new0 (gboolean, cfg->max_block_num);
6616 ctx->bblock_list = g_ptr_array_sized_new (256);
6618 ctx->region_to_handler = g_hash_table_new (NULL, NULL);
6619 ctx->clause_to_handler = g_hash_table_new (NULL, NULL);
6620 ctx->method_to_callers = g_hash_table_new (NULL, NULL);
6621 ctx->jit_callees = g_hash_table_new (NULL, NULL);
6622 if (cfg->compile_aot) {
6623 ctx->module = &aot_module;
6627 * Allow the linker to discard duplicate copies of wrappers, generic instances etc. by using the 'linkonce'
6628 * linkage for them. This requires the following:
6629 * - the method needs to have a unique mangled name
6630 * - llvmonly mode, since the code in aot-runtime.c would initialize got slots in the wrong aot image etc.
6632 is_linkonce = ctx->module->llvm_only && ctx->module->static_link && mono_aot_is_linkonce_method (cfg->method);
6634 method_name = mono_aot_get_mangled_method_name (cfg->method);
6636 is_linkonce = FALSE;
6639 printf ("%s %s\n", mono_method_full_name (cfg->method, 1), method_name);
6641 printf ("%s\n", mono_method_full_name (cfg->method, 1));
6645 method_name = mono_aot_get_method_name (cfg);
6646 cfg->llvm_method_name = g_strdup (method_name);
6648 init_jit_module (cfg->domain);
6649 ctx->module = (MonoLLVMModule*)domain_jit_info (cfg->domain)->llvm_module;
6650 method_name = mono_method_full_name (cfg->method, TRUE);
6652 ctx->method_name = method_name;
6653 ctx->is_linkonce = is_linkonce;
6655 #if LLVM_API_VERSION > 100
6656 ctx->lmodule = LLVMModuleCreateWithName ("jit-module");
6658 ctx->lmodule = ctx->module->lmodule;
6660 ctx->llvm_only = ctx->module->llvm_only;
6662 emit_method_inner (ctx);
6664 if (!ctx_ok (ctx)) {
6666 /* Need to add unused phi nodes as they can be referenced by other values */
6667 LLVMBasicBlockRef phi_bb = LLVMAppendBasicBlock (ctx->lmethod, "PHI_BB");
6668 LLVMBuilderRef builder;
6670 builder = create_builder (ctx);
6671 LLVMPositionBuilderAtEnd (builder, phi_bb);
6673 for (i = 0; i < ctx->phi_values->len; ++i) {
6674 LLVMValueRef v = (LLVMValueRef)g_ptr_array_index (ctx->phi_values, i);
6675 if (LLVMGetInstructionParent (v) == NULL)
6676 LLVMInsertIntoBuilder (builder, v);
6679 LLVMDeleteFunction (ctx->lmethod);
6685 mono_native_tls_set_value (current_cfg_tls_id, NULL);
6687 mono_loader_unlock ();
6691 emit_method_inner (EmitContext *ctx)
6693 MonoCompile *cfg = ctx->cfg;
6694 MonoMethodSignature *sig;
6696 LLVMTypeRef method_type;
6697 LLVMValueRef method = NULL;
6698 LLVMValueRef *values = ctx->values;
6699 int i, max_block_num, bb_index;
6700 gboolean last = FALSE;
6701 LLVMCallInfo *linfo;
6702 LLVMModuleRef lmodule = ctx->lmodule;
6704 GPtrArray *bblock_list = ctx->bblock_list;
6705 MonoMethodHeader *header;
6706 MonoExceptionClause *clause;
6709 if (cfg->gsharedvt && !cfg->llvm_only) {
6710 set_failure (ctx, "gsharedvt");
6716 static int count = 0;
6719 if (g_getenv ("LLVM_COUNT")) {
6720 if (count == atoi (g_getenv ("LLVM_COUNT"))) {
6721 printf ("LAST: %s\n", mono_method_full_name (cfg->method, TRUE));
6725 if (count > atoi (g_getenv ("LLVM_COUNT"))) {
6726 set_failure (ctx, "count");
6733 sig = mono_method_signature (cfg->method);
6736 linfo = get_llvm_call_info (cfg, sig);
6742 linfo->rgctx_arg = TRUE;
6743 ctx->method_type = method_type = sig_to_llvm_sig_full (ctx, sig, linfo);
6747 method = LLVMAddFunction (lmodule, ctx->method_name, method_type);
6748 ctx->lmethod = method;
6750 if (!cfg->llvm_only)
6751 LLVMSetFunctionCallConv (method, LLVMMono1CallConv);
6752 LLVMSetLinkage (method, LLVMPrivateLinkage);
6754 LLVMAddFunctionAttr (method, LLVMUWTable);
6756 if (cfg->compile_aot) {
6757 LLVMSetLinkage (method, LLVMInternalLinkage);
6758 if (ctx->module->external_symbols) {
6759 LLVMSetLinkage (method, LLVMExternalLinkage);
6760 LLVMSetVisibility (method, LLVMHiddenVisibility);
6762 if (ctx->is_linkonce) {
6763 LLVMSetLinkage (method, LLVMLinkOnceAnyLinkage);
6764 LLVMSetVisibility (method, LLVMDefaultVisibility);
6767 #if LLVM_API_VERSION > 100
6768 LLVMSetLinkage (method, LLVMExternalLinkage);
6770 LLVMSetLinkage (method, LLVMPrivateLinkage);
6774 if (cfg->method->save_lmf && !cfg->llvm_only) {
6775 set_failure (ctx, "lmf");
6779 if (sig->pinvoke && cfg->method->wrapper_type != MONO_WRAPPER_RUNTIME_INVOKE && !cfg->llvm_only) {
6780 set_failure (ctx, "pinvoke signature");
6784 header = cfg->header;
6785 for (i = 0; i < header->num_clauses; ++i) {
6786 clause = &header->clauses [i];
6787 if (clause->flags != MONO_EXCEPTION_CLAUSE_FINALLY && clause->flags != MONO_EXCEPTION_CLAUSE_NONE) {
6788 set_failure (ctx, "non-finally/catch clause.");
6792 if (header->num_clauses || (cfg->method->iflags & METHOD_IMPL_ATTRIBUTE_NOINLINING) || cfg->no_inline)
6793 /* We can't handle inlined methods with clauses */
6794 LLVMAddFunctionAttr (method, LLVMNoInlineAttribute);
6796 if (linfo->rgctx_arg) {
6797 ctx->rgctx_arg = LLVMGetParam (method, linfo->rgctx_arg_pindex);
6798 ctx->rgctx_arg_pindex = linfo->rgctx_arg_pindex;
6800 * We mark the rgctx parameter with the inreg attribute, which is mapped to
6801 * MONO_ARCH_RGCTX_REG in the Mono calling convention in llvm, i.e.
6802 * CC_X86_64_Mono in X86CallingConv.td.
6804 if (!ctx->llvm_only)
6805 LLVMAddAttribute (ctx->rgctx_arg, LLVMInRegAttribute);
6806 LLVMSetValueName (ctx->rgctx_arg, "rgctx");
6808 ctx->rgctx_arg_pindex = -1;
6810 if (cfg->vret_addr) {
6811 values [cfg->vret_addr->dreg] = LLVMGetParam (method, linfo->vret_arg_pindex);
6812 LLVMSetValueName (values [cfg->vret_addr->dreg], "vret");
6813 if (linfo->ret.storage == LLVMArgVtypeByRef) {
6814 LLVMAddAttribute (LLVMGetParam (method, linfo->vret_arg_pindex), LLVMStructRetAttribute);
6815 LLVMAddAttribute (LLVMGetParam (method, linfo->vret_arg_pindex), LLVMNoAliasAttribute);
6820 ctx->this_arg_pindex = linfo->this_arg_pindex;
6821 ctx->this_arg = LLVMGetParam (method, linfo->this_arg_pindex);
6822 values [cfg->args [0]->dreg] = ctx->this_arg;
6823 LLVMSetValueName (values [cfg->args [0]->dreg], "this");
6826 names = g_new (char *, sig->param_count);
6827 mono_method_get_param_names (cfg->method, (const char **) names);
6829 for (i = 0; i < sig->param_count; ++i) {
6830 LLVMArgInfo *ainfo = &linfo->args [i + sig->hasthis];
6832 int pindex = ainfo->pindex + ainfo->ndummy_fpargs;
6835 for (j = 0; j < ainfo->ndummy_fpargs; ++j) {
6836 name = g_strdup_printf ("dummy_%d_%d", i, j);
6837 LLVMSetValueName (LLVMGetParam (method, ainfo->pindex + j), name);
6841 values [cfg->args [i + sig->hasthis]->dreg] = LLVMGetParam (method, pindex);
6842 if (ainfo->storage == LLVMArgGsharedvtFixed || ainfo->storage == LLVMArgGsharedvtFixedVtype) {
6843 if (names [i] && names [i][0] != '\0')
6844 name = g_strdup_printf ("p_arg_%s", names [i]);
6846 name = g_strdup_printf ("p_arg_%d", i);
6848 if (names [i] && names [i][0] != '\0')
6849 name = g_strdup_printf ("arg_%s", names [i]);
6851 name = g_strdup_printf ("arg_%d", i);
6853 LLVMSetValueName (values [cfg->args [i + sig->hasthis]->dreg], name);
6855 if (ainfo->storage == LLVMArgVtypeByVal)
6856 LLVMAddAttribute (LLVMGetParam (method, pindex), LLVMByValAttribute);
6858 if (ainfo->storage == LLVMArgVtypeByRef) {
6860 cfg->args [i + sig->hasthis]->opcode = OP_VTARG_ADDR;
6865 if (ctx->module->emit_dwarf && cfg->compile_aot && mono_debug_enabled ()) {
6866 ctx->minfo = mono_debug_lookup_method (cfg->method);
6867 ctx->dbg_md = emit_dbg_subprogram (ctx, cfg, method, ctx->method_name);
6871 for (bb = cfg->bb_entry; bb; bb = bb->next_bb)
6872 max_block_num = MAX (max_block_num, bb->block_num);
6873 ctx->bblocks = bblocks = g_new0 (BBInfo, max_block_num + 1);
6875 /* Add branches between non-consecutive bblocks */
6876 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
6877 if (bb->last_ins && MONO_IS_COND_BRANCH_OP (bb->last_ins) &&
6878 bb->next_bb != bb->last_ins->inst_false_bb) {
6880 MonoInst *inst = (MonoInst*)mono_mempool_alloc0 (cfg->mempool, sizeof (MonoInst));
6881 inst->opcode = OP_BR;
6882 inst->inst_target_bb = bb->last_ins->inst_false_bb;
6883 mono_bblock_add_inst (bb, inst);
6888 * The INDIRECT flag added by OP_LDADDR inhibits optimizations, even if the LDADDR
6889 * was later optimized away, so clear these flags, and add them back for the still
6890 * present OP_LDADDR instructions.
6892 for (i = 0; i < cfg->next_vreg; ++i) {
6895 ins = get_vreg_to_inst (cfg, i);
6896 if (ins && ins != cfg->rgctx_var)
6897 ins->flags &= ~MONO_INST_INDIRECT;
6901 * Make a first pass over the code to precreate PHI nodes/set INDIRECT flags.
6903 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
6905 LLVMBuilderRef builder;
6907 char dname_buf[128];
6909 builder = create_builder (ctx);
6911 for (ins = bb->code; ins; ins = ins->next) {
6912 switch (ins->opcode) {
6917 LLVMTypeRef phi_type = llvm_type_to_stack_type (cfg, type_to_llvm_type (ctx, &ins->klass->byval_arg));
6922 if (ins->opcode == OP_VPHI) {
6923 /* Treat valuetype PHI nodes as operating on the address itself */
6924 g_assert (ins->klass);
6925 phi_type = LLVMPointerType (type_to_llvm_type (ctx, &ins->klass->byval_arg), 0);
6929 * Have to precreate these, as they can be referenced by
6930 * earlier instructions.
6932 sprintf (dname_buf, "t%d", ins->dreg);
6934 values [ins->dreg] = LLVMBuildPhi (builder, phi_type, dname);
6936 if (ins->opcode == OP_VPHI)
6937 ctx->addresses [ins->dreg] = values [ins->dreg];
6939 g_ptr_array_add (ctx->phi_values, values [ins->dreg]);
6942 * Set the expected type of the incoming arguments since these have
6943 * to have the same type.
6945 for (i = 0; i < ins->inst_phi_args [0]; i++) {
6946 int sreg1 = ins->inst_phi_args [i + 1];
6949 ctx->vreg_types [sreg1] = phi_type;
6954 ((MonoInst*)ins->inst_p0)->flags |= MONO_INST_INDIRECT;
6963 * Create an ordering for bblocks, use the depth first order first, then
6964 * put the exception handling bblocks last.
6966 for (bb_index = 0; bb_index < cfg->num_bblocks; ++bb_index) {
6967 bb = cfg->bblocks [bb_index];
6968 if (!(bb->region != -1 && !MONO_BBLOCK_IS_IN_REGION (bb, MONO_REGION_TRY))) {
6969 g_ptr_array_add (bblock_list, bb);
6970 bblocks [bb->block_num].added = TRUE;
6974 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
6975 if (!bblocks [bb->block_num].added)
6976 g_ptr_array_add (bblock_list, bb);
6980 * Second pass: generate code.
6983 LLVMBuilderRef entry_builder = create_builder (ctx);
6984 LLVMBasicBlockRef entry_bb = get_bb (ctx, cfg->bb_entry);
6985 LLVMPositionBuilderAtEnd (entry_builder, entry_bb);
6986 emit_entry_bb (ctx, entry_builder);
6988 // Make landing pads first
6989 ctx->exc_meta = g_hash_table_new_full (NULL, NULL, NULL, NULL);
6991 if (ctx->llvm_only) {
6992 size_t group_index = 0;
6993 while (group_index < cfg->header->num_clauses) {
6995 size_t cursor = group_index;
6996 while (cursor < cfg->header->num_clauses &&
6997 CLAUSE_START (&cfg->header->clauses [cursor]) == CLAUSE_START (&cfg->header->clauses [group_index]) &&
6998 CLAUSE_END (&cfg->header->clauses [cursor]) == CLAUSE_END (&cfg->header->clauses [group_index])) {
7003 LLVMBasicBlockRef lpad_bb = emit_landing_pad (ctx, group_index, count);
7004 intptr_t key = CLAUSE_END (&cfg->header->clauses [group_index]);
7005 g_hash_table_insert (ctx->exc_meta, (gpointer)key, lpad_bb);
7007 group_index = cursor;
7011 for (bb_index = 0; bb_index < bblock_list->len; ++bb_index) {
7012 bb = (MonoBasicBlock*)g_ptr_array_index (bblock_list, bb_index);
7014 // Prune unreachable mono BBs.
7015 if (!(bb == cfg->bb_entry || bb->in_count > 0))
7018 process_bb (ctx, bb);
7022 g_hash_table_destroy (ctx->exc_meta);
7024 mono_memory_barrier ();
7026 /* Add incoming phi values */
7027 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
7028 GSList *l, *ins_list;
7030 ins_list = bblocks [bb->block_num].phi_nodes;
7032 for (l = ins_list; l; l = l->next) {
7033 PhiNode *node = (PhiNode*)l->data;
7034 MonoInst *phi = node->phi;
7035 int sreg1 = node->sreg;
7036 LLVMBasicBlockRef in_bb;
7041 in_bb = get_end_bb (ctx, node->in_bb);
7043 if (ctx->unreachable [node->in_bb->block_num])
7046 if (!values [sreg1]) {
7047 /* Can happen with values in EH clauses */
7048 set_failure (ctx, "incoming phi sreg1");
7052 if (phi->opcode == OP_VPHI) {
7053 g_assert (LLVMTypeOf (ctx->addresses [sreg1]) == LLVMTypeOf (values [phi->dreg]));
7054 LLVMAddIncoming (values [phi->dreg], &ctx->addresses [sreg1], &in_bb, 1);
7056 if (LLVMTypeOf (values [sreg1]) != LLVMTypeOf (values [phi->dreg])) {
7057 set_failure (ctx, "incoming phi arg type mismatch");
7060 g_assert (LLVMTypeOf (values [sreg1]) == LLVMTypeOf (values [phi->dreg]));
7061 LLVMAddIncoming (values [phi->dreg], &values [sreg1], &in_bb, 1);
7066 /* Nullify empty phi instructions */
7067 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
7068 GSList *l, *ins_list;
7070 ins_list = bblocks [bb->block_num].phi_nodes;
7072 for (l = ins_list; l; l = l->next) {
7073 PhiNode *node = (PhiNode*)l->data;
7074 MonoInst *phi = node->phi;
7075 LLVMValueRef phi_ins = values [phi->dreg];
7078 /* Already removed */
7081 if (LLVMCountIncoming (phi_ins) == 0) {
7082 mono_llvm_replace_uses_of (phi_ins, LLVMConstNull (LLVMTypeOf (phi_ins)));
7083 LLVMInstructionEraseFromParent (phi_ins);
7084 values [phi->dreg] = NULL;
7089 /* Create the SWITCH statements for ENDFINALLY instructions */
7090 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
7091 BBInfo *info = &bblocks [bb->block_num];
7093 for (l = info->endfinally_switch_ins_list; l; l = l->next) {
7094 LLVMValueRef switch_ins = (LLVMValueRef)l->data;
7095 GSList *bb_list = info->call_handler_return_bbs;
7097 for (i = 0; i < g_slist_length (bb_list); ++i)
7098 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), i + 1, FALSE), (LLVMBasicBlockRef)(g_slist_nth (bb_list, i)->data));
7102 /* Initialize the method if needed */
7103 if (cfg->compile_aot && ctx->llvm_only) {
7104 // FIXME: Add more shared got entries
7105 ctx->builder = create_builder (ctx);
7106 LLVMPositionBuilderAtEnd (ctx->builder, ctx->init_bb);
7108 ctx->module->max_method_idx = MAX (ctx->module->max_method_idx, cfg->method_index);
7110 // FIXME: beforefieldinit
7111 if (ctx->has_got_access || mono_class_get_cctor (cfg->method->klass)) {
7113 * linkonce methods shouldn't have initialization,
7114 * because they might belong to assemblies which
7115 * haven't been loaded yet.
7117 g_assert (!ctx->is_linkonce);
7118 emit_init_method (ctx);
7120 LLVMBuildBr (ctx->builder, ctx->inited_bb);
7124 if (cfg->llvm_only) {
7125 GHashTableIter iter;
7127 GSList *callers, *l, *l2;
7130 * Add the contents of ctx->method_to_callers to module->method_to_callers.
7131 * We can't do this earlier, as it contains llvm instructions which can be
7132 * freed if compilation fails.
7133 * FIXME: Get rid of this when all methods can be llvm compiled.
7135 g_hash_table_iter_init (&iter, ctx->method_to_callers);
7136 while (g_hash_table_iter_next (&iter, (void**)&method, (void**)&callers)) {
7137 for (l = callers; l; l = l->next) {
7138 l2 = (GSList*)g_hash_table_lookup (ctx->module->method_to_callers, method);
7139 l2 = g_slist_prepend (l2, l->data);
7140 g_hash_table_insert (ctx->module->method_to_callers, method, l2);
7145 if (cfg->verbose_level > 1)
7146 mono_llvm_dump_value (method);
7148 if (cfg->compile_aot && !cfg->llvm_only)
7149 mark_as_used (ctx->module, method);
7151 if (cfg->compile_aot && !cfg->llvm_only) {
7152 LLVMValueRef md_args [16];
7153 LLVMValueRef md_node;
7156 method_index = mono_aot_get_method_index (cfg->orig_method);
7157 md_args [0] = LLVMMDString (ctx->method_name, strlen (ctx->method_name));
7158 md_args [1] = LLVMConstInt (LLVMInt32Type (), method_index, FALSE);
7159 md_node = LLVMMDNode (md_args, 2);
7160 LLVMAddNamedMetadataOperand (lmodule, "mono.function_indexes", md_node);
7161 //LLVMSetMetadata (method, md_kind, LLVMMDNode (&md_arg, 1));
7164 if (cfg->compile_aot) {
7165 /* Don't generate native code, keep the LLVM IR */
7166 if (cfg->verbose_level)
7167 printf ("%s emitted as %s\n", mono_method_full_name (cfg->method, TRUE), ctx->method_name);
7169 #if LLVM_API_VERSION < 100
7170 /* VerifyFunction can't handle some of the debug info created by DIBuilder in llvm 3.9 */
7171 int err = LLVMVerifyFunction(ctx->lmethod, LLVMPrintMessageAction);
7172 g_assert (err == 0);
7175 //LLVMVerifyFunction(method, 0);
7176 #if LLVM_API_VERSION > 100
7177 MonoDomain *domain = mono_domain_get ();
7178 MonoJitDomainInfo *domain_info;
7179 int nvars = g_hash_table_size (ctx->jit_callees);
7180 LLVMValueRef *callee_vars = g_new0 (LLVMValueRef, nvars);
7181 gpointer *callee_addrs = g_new0 (gpointer, nvars);
7182 GHashTableIter iter;
7188 * Compute the addresses of the LLVM globals pointing to the
7189 * methods called by the current method. Pass it to the trampoline
7190 * code so it can update them after their corresponding method was
7193 g_hash_table_iter_init (&iter, ctx->jit_callees);
7195 while (g_hash_table_iter_next (&iter, NULL, (void**)&var))
7196 callee_vars [i ++] = var;
7198 cfg->native_code = mono_llvm_compile_method (ctx->module->mono_ee, ctx->lmethod, nvars, callee_vars, callee_addrs, &eh_frame);
7200 decode_llvm_eh_info (ctx, eh_frame);
7202 mono_domain_lock (domain);
7203 domain_info = domain_jit_info (domain);
7204 if (!domain_info->llvm_jit_callees)
7205 domain_info->llvm_jit_callees = g_hash_table_new (NULL, NULL);
7206 g_hash_table_iter_init (&iter, ctx->jit_callees);
7208 while (g_hash_table_iter_next (&iter, (void**)&callee, (void**)&var)) {
7209 GSList *addrs = g_hash_table_lookup (domain_info->llvm_jit_callees, callee);
7210 addrs = g_slist_prepend (addrs, callee_addrs [i]);
7211 g_hash_table_insert (domain_info->llvm_jit_callees, callee, addrs);
7214 mono_domain_unlock (domain);
7216 mono_llvm_optimize_method (ctx->module->mono_ee, ctx->lmethod);
7218 if (cfg->verbose_level > 1)
7219 mono_llvm_dump_value (ctx->lmethod);
7221 cfg->native_code = (unsigned char*)LLVMGetPointerToGlobal (ctx->module->ee, ctx->lmethod);
7223 /* Set by emit_cb */
7224 g_assert (cfg->code_len);
7228 if (ctx->module->method_to_lmethod)
7229 g_hash_table_insert (ctx->module->method_to_lmethod, cfg->method, ctx->lmethod);
7230 if (ctx->module->idx_to_lmethod)
7231 g_hash_table_insert (ctx->module->idx_to_lmethod, GINT_TO_POINTER (cfg->method_index), ctx->lmethod);
7233 if (ctx->llvm_only && cfg->orig_method->klass->valuetype && !(cfg->orig_method->flags & METHOD_ATTRIBUTE_STATIC))
7234 emit_unbox_tramp (ctx, ctx->method_name, ctx->method_type, ctx->lmethod, cfg->method_index);
7238 * mono_llvm_create_vars:
7240 * Same as mono_arch_create_vars () for LLVM.
7243 mono_llvm_create_vars (MonoCompile *cfg)
7245 MonoMethodSignature *sig;
7247 sig = mono_method_signature (cfg->method);
7248 if (cfg->gsharedvt && cfg->llvm_only) {
7249 if (mini_is_gsharedvt_variable_signature (sig) && sig->ret->type != MONO_TYPE_VOID) {
7250 cfg->vret_addr = mono_compile_create_var (cfg, &mono_get_intptr_class ()->byval_arg, OP_ARG);
7251 if (G_UNLIKELY (cfg->verbose_level > 1)) {
7252 printf ("vret_addr = ");
7253 mono_print_ins (cfg->vret_addr);
7257 mono_arch_create_vars (cfg);
7262 * mono_llvm_emit_call:
7264 * Same as mono_arch_emit_call () for LLVM.
7267 mono_llvm_emit_call (MonoCompile *cfg, MonoCallInst *call)
7270 MonoMethodSignature *sig;
7271 int i, n, stack_size;
7276 sig = call->signature;
7277 n = sig->param_count + sig->hasthis;
7279 call->cinfo = get_llvm_call_info (cfg, sig);
7281 if (cfg->disable_llvm)
7284 if (sig->call_convention == MONO_CALL_VARARG) {
7285 cfg->exception_message = g_strdup ("varargs");
7286 cfg->disable_llvm = TRUE;
7289 for (i = 0; i < n; ++i) {
7292 ainfo = call->cinfo->args + i;
7294 in = call->args [i];
7296 /* Simply remember the arguments */
7297 switch (ainfo->storage) {
7298 case LLVMArgNormal: {
7299 MonoType *t = (sig->hasthis && i == 0) ? &mono_get_intptr_class ()->byval_arg : ainfo->type;
7302 opcode = mono_type_to_regmove (cfg, t);
7303 if (opcode == OP_FMOVE) {
7304 MONO_INST_NEW (cfg, ins, OP_FMOVE);
7305 ins->dreg = mono_alloc_freg (cfg);
7306 } else if (opcode == OP_LMOVE) {
7307 MONO_INST_NEW (cfg, ins, OP_LMOVE);
7308 ins->dreg = mono_alloc_lreg (cfg);
7309 } else if (opcode == OP_RMOVE) {
7310 MONO_INST_NEW (cfg, ins, OP_RMOVE);
7311 ins->dreg = mono_alloc_freg (cfg);
7313 MONO_INST_NEW (cfg, ins, OP_MOVE);
7314 ins->dreg = mono_alloc_ireg (cfg);
7316 ins->sreg1 = in->dreg;
7319 case LLVMArgVtypeByVal:
7320 case LLVMArgVtypeByRef:
7321 case LLVMArgVtypeInReg:
7322 case LLVMArgVtypeAsScalar:
7323 case LLVMArgAsIArgs:
7324 case LLVMArgAsFpArgs:
7325 case LLVMArgGsharedvtVariable:
7326 case LLVMArgGsharedvtFixed:
7327 case LLVMArgGsharedvtFixedVtype:
7328 MONO_INST_NEW (cfg, ins, OP_LLVM_OUTARG_VT);
7329 ins->dreg = mono_alloc_ireg (cfg);
7330 ins->sreg1 = in->dreg;
7331 ins->inst_p0 = mono_mempool_alloc0 (cfg->mempool, sizeof (LLVMArgInfo));
7332 memcpy (ins->inst_p0, ainfo, sizeof (LLVMArgInfo));
7333 ins->inst_vtype = ainfo->type;
7334 ins->klass = mono_class_from_mono_type (ainfo->type);
7337 cfg->exception_message = g_strdup ("ainfo->storage");
7338 cfg->disable_llvm = TRUE;
7342 if (!cfg->disable_llvm) {
7343 MONO_ADD_INS (cfg->cbb, ins);
7344 mono_call_inst_add_outarg_reg (cfg, call, ins->dreg, 0, FALSE);
7349 static unsigned char*
7350 alloc_cb (LLVMValueRef function, int size)
7354 cfg = (MonoCompile*)mono_native_tls_get_value (current_cfg_tls_id);
7358 return (unsigned char*)mono_domain_code_reserve (cfg->domain, size);
7360 return (unsigned char*)mono_domain_code_reserve (mono_domain_get (), size);
7365 emitted_cb (LLVMValueRef function, void *start, void *end)
7369 cfg = (MonoCompile*)mono_native_tls_get_value (current_cfg_tls_id);
7371 cfg->code_len = (guint8*)end - (guint8*)start;
7375 exception_cb (void *data)
7378 MonoJitExceptionInfo *ei;
7379 guint32 ei_len, i, j, nested_len, nindex;
7380 gpointer *type_info;
7381 int this_reg, this_offset;
7383 cfg = (MonoCompile*)mono_native_tls_get_value (current_cfg_tls_id);
7387 * data points to a DWARF FDE structure, convert it to our unwind format and
7389 * An alternative would be to save it directly, and modify our unwinder to work
7392 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);
7393 if (cfg->verbose_level > 1)
7394 mono_print_unwind_info (cfg->encoded_unwind_ops, cfg->encoded_unwind_ops_len);
7396 /* Count nested clauses */
7398 for (i = 0; i < ei_len; ++i) {
7399 gint32 cindex1 = *(gint32*)type_info [i];
7400 MonoExceptionClause *clause1 = &cfg->header->clauses [cindex1];
7402 for (j = 0; j < cfg->header->num_clauses; ++j) {
7404 MonoExceptionClause *clause2 = &cfg->header->clauses [cindex2];
7406 if (cindex1 != cindex2 && clause1->try_offset >= clause2->try_offset && clause1->handler_offset <= clause2->handler_offset) {
7412 cfg->llvm_ex_info = (MonoJitExceptionInfo*)mono_mempool_alloc0 (cfg->mempool, (ei_len + nested_len) * sizeof (MonoJitExceptionInfo));
7413 cfg->llvm_ex_info_len = ei_len + nested_len;
7414 memcpy (cfg->llvm_ex_info, ei, ei_len * sizeof (MonoJitExceptionInfo));
7415 /* Fill the rest of the information from the type info */
7416 for (i = 0; i < ei_len; ++i) {
7417 gint32 clause_index = *(gint32*)type_info [i];
7418 MonoExceptionClause *clause = &cfg->header->clauses [clause_index];
7420 cfg->llvm_ex_info [i].flags = clause->flags;
7421 cfg->llvm_ex_info [i].data.catch_class = clause->data.catch_class;
7422 cfg->llvm_ex_info [i].clause_index = clause_index;
7426 * For nested clauses, the LLVM produced exception info associates the try interval with
7427 * the innermost handler, while mono expects it to be associated with all nesting clauses.
7428 * So add new clauses which use the IL info (catch class etc.) from the nesting clause,
7429 * and everything else from the nested clause.
7432 for (i = 0; i < ei_len; ++i) {
7433 gint32 cindex1 = *(gint32*)type_info [i];
7434 MonoExceptionClause *clause1 = &cfg->header->clauses [cindex1];
7436 for (j = 0; j < cfg->header->num_clauses; ++j) {
7438 MonoExceptionClause *clause2 = &cfg->header->clauses [cindex2];
7439 MonoJitExceptionInfo *nesting_ei, *nested_ei;
7441 if (cindex1 != cindex2 && clause1->try_offset >= clause2->try_offset && clause1->handler_offset <= clause2->handler_offset) {
7442 /* clause1 is the nested clause */
7443 nested_ei = &cfg->llvm_ex_info [i];
7444 nesting_ei = &cfg->llvm_ex_info [nindex];
7447 memcpy (nesting_ei, nested_ei, sizeof (MonoJitExceptionInfo));
7449 nesting_ei->flags = clause2->flags;
7450 nesting_ei->data.catch_class = clause2->data.catch_class;
7451 nesting_ei->clause_index = cindex2;
7455 g_assert (nindex == ei_len + nested_len);
7456 cfg->llvm_this_reg = this_reg;
7457 cfg->llvm_this_offset = this_offset;
7459 /* type_info [i] is cfg mempool allocated, no need to free it */
7465 #if LLVM_API_VERSION > 100
7467 * decode_llvm_eh_info:
7469 * Decode the EH table emitted by llvm in jit mode, and store
7470 * the result into cfg.
7473 decode_llvm_eh_info (EmitContext *ctx, gpointer eh_frame)
7475 MonoCompile *cfg = ctx->cfg;
7478 MonoLLVMFDEInfo info;
7479 MonoJitExceptionInfo *ei;
7480 guint8 *p = eh_frame;
7481 int version, fde_count, fde_offset;
7482 guint32 ei_len, i, nested_len;
7483 gpointer *type_info;
7487 * Decode the one element EH table emitted by the MonoException class
7491 /* Similar to decode_llvm_mono_eh_frame () in aot-runtime.c */
7494 g_assert (version == 3);
7497 p = (guint8 *)ALIGN_PTR_TO (p, 4);
7499 fde_count = *(guint32*)p;
7503 g_assert (fde_count == 1);
7505 /* The only table entry */
7506 fde_offset = table [1];
7509 cfg->code_len = table [0];
7510 fde_len = table [1] - fde_offset;
7513 fde = (guint8*)eh_frame + fde_offset;
7514 cie = (guint8*)table;
7516 mono_unwind_decode_llvm_mono_fde (fde, fde_len, cie, cfg->native_code, &info);
7518 cfg->encoded_unwind_ops = info.unw_info;
7519 cfg->encoded_unwind_ops_len = info.unw_info_len;
7520 if (cfg->verbose_level > 1)
7521 mono_print_unwind_info (cfg->encoded_unwind_ops, cfg->encoded_unwind_ops_len);
7522 if (info.this_reg != -1) {
7523 cfg->llvm_this_reg = info.this_reg;
7524 cfg->llvm_this_offset = info.this_offset;
7528 ei_len = info.ex_info_len;
7529 type_info = info.type_info;
7531 // Nested clauses are currently disabled
7534 cfg->llvm_ex_info = (MonoJitExceptionInfo*)mono_mempool_alloc0 (cfg->mempool, (ei_len + nested_len) * sizeof (MonoJitExceptionInfo));
7535 cfg->llvm_ex_info_len = ei_len + nested_len;
7536 memcpy (cfg->llvm_ex_info, ei, ei_len * sizeof (MonoJitExceptionInfo));
7537 /* Fill the rest of the information from the type info */
7538 for (i = 0; i < ei_len; ++i) {
7539 gint32 clause_index = *(gint32*)type_info [i];
7540 MonoExceptionClause *clause = &cfg->header->clauses [clause_index];
7542 cfg->llvm_ex_info [i].flags = clause->flags;
7543 cfg->llvm_ex_info [i].data.catch_class = clause->data.catch_class;
7544 cfg->llvm_ex_info [i].clause_index = clause_index;
7550 dlsym_cb (const char *name, void **symbol)
7556 if (!strcmp (name, "__bzero")) {
7557 *symbol = (void*)bzero;
7559 current = mono_dl_open (NULL, 0, NULL);
7562 err = mono_dl_symbol (current, name, symbol);
7564 mono_dl_close (current);
7566 #ifdef MONO_ARCH_HAVE_CREATE_LLVM_NATIVE_THUNK
7567 *symbol = (char*)mono_arch_create_llvm_native_thunk (mono_domain_get (), (guint8*)(*symbol));
7573 AddFunc (LLVMModuleRef module, const char *name, LLVMTypeRef ret_type, LLVMTypeRef *param_types, int nparams)
7575 LLVMAddFunction (module, name, LLVMFunctionType (ret_type, param_types, nparams, FALSE));
7579 AddFunc2 (LLVMModuleRef module, const char *name, LLVMTypeRef ret_type, LLVMTypeRef param_type1, LLVMTypeRef param_type2)
7581 LLVMTypeRef param_types [4];
7583 param_types [0] = param_type1;
7584 param_types [1] = param_type2;
7586 AddFunc (module, name, ret_type, param_types, 2);
7592 INTRINS_SADD_OVF_I32,
7593 INTRINS_UADD_OVF_I32,
7594 INTRINS_SSUB_OVF_I32,
7595 INTRINS_USUB_OVF_I32,
7596 INTRINS_SMUL_OVF_I32,
7597 INTRINS_UMUL_OVF_I32,
7598 INTRINS_SADD_OVF_I64,
7599 INTRINS_UADD_OVF_I64,
7600 INTRINS_SSUB_OVF_I64,
7601 INTRINS_USUB_OVF_I64,
7602 INTRINS_SMUL_OVF_I64,
7603 INTRINS_UMUL_OVF_I64,
7610 #if defined(TARGET_AMD64) || defined(TARGET_X86)
7611 INTRINS_SSE_PMOVMSKB,
7612 INTRINS_SSE_PSRLI_W,
7613 INTRINS_SSE_PSRAI_W,
7614 INTRINS_SSE_PSLLI_W,
7615 INTRINS_SSE_PSRLI_D,
7616 INTRINS_SSE_PSRAI_D,
7617 INTRINS_SSE_PSLLI_D,
7618 INTRINS_SSE_PSRLI_Q,
7619 INTRINS_SSE_PSLLI_Q,
7620 INTRINS_SSE_SQRT_PD,
7621 INTRINS_SSE_SQRT_PS,
7622 INTRINS_SSE_RSQRT_PS,
7624 INTRINS_SSE_CVTTPD2DQ,
7625 INTRINS_SSE_CVTTPS2DQ,
7626 INTRINS_SSE_CVTDQ2PD,
7627 INTRINS_SSE_CVTDQ2PS,
7628 INTRINS_SSE_CVTPD2DQ,
7629 INTRINS_SSE_CVTPS2DQ,
7630 INTRINS_SSE_CVTPD2PS,
7631 INTRINS_SSE_CVTPS2PD,
7634 INTRINS_SSE_PACKSSWB,
7635 INTRINS_SSE_PACKUSWB,
7636 INTRINS_SSE_PACKSSDW,
7637 INTRINS_SSE_PACKUSDW,
7642 INTRINS_SSE_ADDSUBPS,
7647 INTRINS_SSE_ADDSUBPD,
7655 INTRINS_SSE_PADDUSW,
7656 INTRINS_SSE_PSUBUSW,
7664 INTRINS_SSE_PADDUSB,
7665 INTRINS_SSE_PSUBUSB,
7677 static IntrinsicDesc intrinsics[] = {
7678 {INTRINS_MEMSET, "llvm.memset.p0i8.i32"},
7679 {INTRINS_MEMCPY, "llvm.memcpy.p0i8.p0i8.i32"},
7680 {INTRINS_SADD_OVF_I32, "llvm.sadd.with.overflow.i32"},
7681 {INTRINS_UADD_OVF_I32, "llvm.uadd.with.overflow.i32"},
7682 {INTRINS_SSUB_OVF_I32, "llvm.ssub.with.overflow.i32"},
7683 {INTRINS_USUB_OVF_I32, "llvm.usub.with.overflow.i32"},
7684 {INTRINS_SMUL_OVF_I32, "llvm.smul.with.overflow.i32"},
7685 {INTRINS_UMUL_OVF_I32, "llvm.umul.with.overflow.i32"},
7686 {INTRINS_SADD_OVF_I64, "llvm.sadd.with.overflow.i64"},
7687 {INTRINS_UADD_OVF_I64, "llvm.uadd.with.overflow.i64"},
7688 {INTRINS_SSUB_OVF_I64, "llvm.ssub.with.overflow.i64"},
7689 {INTRINS_USUB_OVF_I64, "llvm.usub.with.overflow.i64"},
7690 {INTRINS_SMUL_OVF_I64, "llvm.smul.with.overflow.i64"},
7691 {INTRINS_UMUL_OVF_I64, "llvm.umul.with.overflow.i64"},
7692 {INTRINS_SIN, "llvm.sin.f64"},
7693 {INTRINS_COS, "llvm.cos.f64"},
7694 {INTRINS_SQRT, "llvm.sqrt.f64"},
7695 /* This isn't an intrinsic, instead llvm seems to special case it by name */
7696 {INTRINS_FABS, "fabs"},
7697 {INTRINS_EXPECT_I8, "llvm.expect.i8"},
7698 {INTRINS_EXPECT_I1, "llvm.expect.i1"},
7699 #if defined(TARGET_AMD64) || defined(TARGET_X86)
7700 {INTRINS_SSE_PMOVMSKB, "llvm.x86.sse2.pmovmskb.128"},
7701 {INTRINS_SSE_PSRLI_W, "llvm.x86.sse2.psrli.w"},
7702 {INTRINS_SSE_PSRAI_W, "llvm.x86.sse2.psrai.w"},
7703 {INTRINS_SSE_PSLLI_W, "llvm.x86.sse2.pslli.w"},
7704 {INTRINS_SSE_PSRLI_D, "llvm.x86.sse2.psrli.d"},
7705 {INTRINS_SSE_PSRAI_D, "llvm.x86.sse2.psrai.d"},
7706 {INTRINS_SSE_PSLLI_D, "llvm.x86.sse2.pslli.d"},
7707 {INTRINS_SSE_PSRLI_Q, "llvm.x86.sse2.psrli.q"},
7708 {INTRINS_SSE_PSLLI_Q, "llvm.x86.sse2.pslli.q"},
7709 {INTRINS_SSE_SQRT_PD, "llvm.x86.sse2.sqrt.pd"},
7710 {INTRINS_SSE_SQRT_PS, "llvm.x86.sse.sqrt.ps"},
7711 {INTRINS_SSE_RSQRT_PS, "llvm.x86.sse.rsqrt.ps"},
7712 {INTRINS_SSE_RCP_PS, "llvm.x86.sse.rcp.ps"},
7713 {INTRINS_SSE_CVTTPD2DQ, "llvm.x86.sse2.cvttpd2dq"},
7714 {INTRINS_SSE_CVTTPS2DQ, "llvm.x86.sse2.cvttps2dq"},
7715 {INTRINS_SSE_CVTDQ2PD, "llvm.x86.sse2.cvtdq2pd"},
7716 {INTRINS_SSE_CVTDQ2PS, "llvm.x86.sse2.cvtdq2ps"},
7717 {INTRINS_SSE_CVTPD2DQ, "llvm.x86.sse2.cvtpd2dq"},
7718 {INTRINS_SSE_CVTPS2DQ, "llvm.x86.sse2.cvtps2dq"},
7719 {INTRINS_SSE_CVTPD2PS, "llvm.x86.sse2.cvtpd2ps"},
7720 {INTRINS_SSE_CVTPS2PD, "llvm.x86.sse2.cvtps2pd"},
7721 {INTRINS_SSE_CMPPD, "llvm.x86.sse2.cmp.pd"},
7722 {INTRINS_SSE_CMPPS, "llvm.x86.sse.cmp.ps"},
7723 {INTRINS_SSE_PACKSSWB, "llvm.x86.sse2.packsswb.128"},
7724 {INTRINS_SSE_PACKUSWB, "llvm.x86.sse2.packuswb.128"},
7725 {INTRINS_SSE_PACKSSDW, "llvm.x86.sse2.packssdw.128"},
7726 {INTRINS_SSE_PACKUSDW, "llvm.x86.sse41.packusdw"},
7727 {INTRINS_SSE_MINPS, "llvm.x86.sse.min.ps"},
7728 {INTRINS_SSE_MAXPS, "llvm.x86.sse.max.ps"},
7729 {INTRINS_SSE_HADDPS, "llvm.x86.sse3.hadd.ps"},
7730 {INTRINS_SSE_HSUBPS, "llvm.x86.sse3.hsub.ps"},
7731 {INTRINS_SSE_ADDSUBPS, "llvm.x86.sse3.addsub.ps"},
7732 {INTRINS_SSE_MINPD, "llvm.x86.sse2.min.pd"},
7733 {INTRINS_SSE_MAXPD, "llvm.x86.sse2.max.pd"},
7734 {INTRINS_SSE_HADDPD, "llvm.x86.sse3.hadd.pd"},
7735 {INTRINS_SSE_HSUBPD, "llvm.x86.sse3.hsub.pd"},
7736 {INTRINS_SSE_ADDSUBPD, "llvm.x86.sse3.addsub.pd"},
7737 {INTRINS_SSE_PMINUD, "llvm.x86.sse41.pminud"},
7738 {INTRINS_SSE_PMAXUD, "llvm.x86.sse41.pmaxud"},
7739 {INTRINS_SSE_PMINUW, "llvm.x86.sse41.pminuw"},
7740 {INTRINS_SSE_PMINSW, "llvm.x86.sse2.pmins.w"},
7741 {INTRINS_SSE_PMAXUW, "llvm.x86.sse41.pmaxuw"},
7742 {INTRINS_SSE_PADDSW, "llvm.x86.sse2.padds.w"},
7743 {INTRINS_SSE_PSUBSW, "llvm.x86.sse2.psubs.w"},
7744 {INTRINS_SSE_PADDUSW, "llvm.x86.sse2.paddus.w"},
7745 {INTRINS_SSE_PSUBUSW, "llvm.x86.sse2.psubus.w"},
7746 {INTRINS_SSE_PAVGW, "llvm.x86.sse2.pavg.w"},
7747 {INTRINS_SSE_PMULHW, "llvm.x86.sse2.pmulh.w"},
7748 {INTRINS_SSE_PMULHU, "llvm.x86.sse2.pmulhu.w"},
7749 {INTRINS_SSE_PMINUB, "llvm.x86.sse2.pminu.b"},
7750 {INTRINS_SSE_PMAXUB, "llvm.x86.sse2.pmaxu.b"},
7751 {INTRINS_SE_PADDSB, "llvm.x86.sse2.padds.b"},
7752 {INTRINS_SSE_PSUBSB, "llvm.x86.sse2.psubs.b"},
7753 {INTRINS_SSE_PADDUSB, "llvm.x86.sse2.paddus.b"},
7754 {INTRINS_SSE_PSUBUSB, "llvm.x86.sse2.psubus.b"},
7755 {INTRINS_SSE_PAVGB, "llvm.x86.sse2.pavg.b"},
7756 {INTRINS_SSE_PAUSE, "llvm.x86.sse2.pause"}
7761 add_sse_binary (LLVMModuleRef module, const char *name, int type)
7763 LLVMTypeRef ret_type = type_to_simd_type (type);
7764 AddFunc2 (module, name, ret_type, ret_type, ret_type);
7768 add_intrinsic (LLVMModuleRef module, int id)
7771 #if defined(TARGET_AMD64) || defined(TARGET_X86)
7772 LLVMTypeRef ret_type, arg_types [16];
7775 name = g_hash_table_lookup (intrins_id_to_name, GINT_TO_POINTER (id));
7779 case INTRINS_MEMSET: {
7780 LLVMTypeRef params [] = { LLVMPointerType (LLVMInt8Type (), 0), LLVMInt8Type (), LLVMInt32Type (), LLVMInt32Type (), LLVMInt1Type () };
7782 AddFunc (module, name, LLVMVoidType (), params, 5);
7785 case INTRINS_MEMCPY: {
7786 LLVMTypeRef params [] = { LLVMPointerType (LLVMInt8Type (), 0), LLVMPointerType (LLVMInt8Type (), 0), LLVMInt32Type (), LLVMInt32Type (), LLVMInt1Type () };
7788 AddFunc (module, name, LLVMVoidType (), params, 5);
7791 case INTRINS_SADD_OVF_I32:
7792 case INTRINS_UADD_OVF_I32:
7793 case INTRINS_SSUB_OVF_I32:
7794 case INTRINS_USUB_OVF_I32:
7795 case INTRINS_SMUL_OVF_I32:
7796 case INTRINS_UMUL_OVF_I32: {
7797 LLVMTypeRef ovf_res_i32 [] = { LLVMInt32Type (), LLVMInt1Type () };
7798 LLVMTypeRef params [] = { LLVMInt32Type (), LLVMInt32Type () };
7799 LLVMTypeRef ret_type = LLVMStructType (ovf_res_i32, 2, FALSE);
7801 AddFunc (module, name, ret_type, params, 2);
7804 case INTRINS_SADD_OVF_I64:
7805 case INTRINS_UADD_OVF_I64:
7806 case INTRINS_SSUB_OVF_I64:
7807 case INTRINS_USUB_OVF_I64:
7808 case INTRINS_SMUL_OVF_I64:
7809 case INTRINS_UMUL_OVF_I64: {
7810 LLVMTypeRef ovf_res_i64 [] = { LLVMInt64Type (), LLVMInt1Type () };
7811 LLVMTypeRef params [] = { LLVMInt64Type (), LLVMInt64Type () };
7812 LLVMTypeRef ret_type = LLVMStructType (ovf_res_i64, 2, FALSE);
7814 AddFunc (module, name, ret_type, params, 2);
7820 case INTRINS_FABS: {
7821 LLVMTypeRef params [] = { LLVMDoubleType () };
7823 AddFunc (module, name, LLVMDoubleType (), params, 1);
7826 case INTRINS_EXPECT_I8:
7827 AddFunc2 (module, name, LLVMInt8Type (), LLVMInt8Type (), LLVMInt8Type ());
7829 case INTRINS_EXPECT_I1:
7830 AddFunc2 (module, name, LLVMInt1Type (), LLVMInt1Type (), LLVMInt1Type ());
7832 #if defined(TARGET_AMD64) || defined(TARGET_X86)
7833 case INTRINS_SSE_PMOVMSKB:
7835 ret_type = LLVMInt32Type ();
7836 arg_types [0] = type_to_simd_type (MONO_TYPE_I1);
7837 AddFunc (module, name, ret_type, arg_types, 1);
7839 case INTRINS_SSE_PSRLI_W:
7840 case INTRINS_SSE_PSRAI_W:
7841 case INTRINS_SSE_PSLLI_W:
7843 ret_type = type_to_simd_type (MONO_TYPE_I2);
7844 arg_types [0] = ret_type;
7845 arg_types [1] = LLVMInt32Type ();
7846 AddFunc (module, name, ret_type, arg_types, 2);
7848 case INTRINS_SSE_PSRLI_D:
7849 case INTRINS_SSE_PSRAI_D:
7850 case INTRINS_SSE_PSLLI_D:
7851 ret_type = type_to_simd_type (MONO_TYPE_I4);
7852 arg_types [0] = ret_type;
7853 arg_types [1] = LLVMInt32Type ();
7854 AddFunc (module, name, ret_type, arg_types, 2);
7856 case INTRINS_SSE_PSRLI_Q:
7857 case INTRINS_SSE_PSLLI_Q:
7858 ret_type = type_to_simd_type (MONO_TYPE_I8);
7859 arg_types [0] = ret_type;
7860 arg_types [1] = LLVMInt32Type ();
7861 AddFunc (module, name, ret_type, arg_types, 2);
7863 case INTRINS_SSE_SQRT_PD:
7865 ret_type = type_to_simd_type (MONO_TYPE_R8);
7866 arg_types [0] = ret_type;
7867 AddFunc (module, name, ret_type, arg_types, 1);
7869 case INTRINS_SSE_SQRT_PS:
7870 ret_type = type_to_simd_type (MONO_TYPE_R4);
7871 arg_types [0] = ret_type;
7872 AddFunc (module, name, ret_type, arg_types, 1);
7874 case INTRINS_SSE_RSQRT_PS:
7875 ret_type = type_to_simd_type (MONO_TYPE_R4);
7876 arg_types [0] = ret_type;
7877 AddFunc (module, name, ret_type, arg_types, 1);
7879 case INTRINS_SSE_RCP_PS:
7880 ret_type = type_to_simd_type (MONO_TYPE_R4);
7881 arg_types [0] = ret_type;
7882 AddFunc (module, name, ret_type, arg_types, 1);
7884 case INTRINS_SSE_CVTTPD2DQ:
7885 ret_type = type_to_simd_type (MONO_TYPE_I4);
7886 arg_types [0] = type_to_simd_type (MONO_TYPE_R8);
7887 AddFunc (module, name, ret_type, arg_types, 1);
7889 case INTRINS_SSE_CVTTPS2DQ:
7890 ret_type = type_to_simd_type (MONO_TYPE_I4);
7891 arg_types [0] = type_to_simd_type (MONO_TYPE_R4);
7892 AddFunc (module, name, ret_type, arg_types, 1);
7894 case INTRINS_SSE_CVTDQ2PD:
7895 /* Conversion ops */
7896 ret_type = type_to_simd_type (MONO_TYPE_R8);
7897 arg_types [0] = type_to_simd_type (MONO_TYPE_I4);
7898 AddFunc (module, name, ret_type, arg_types, 1);
7900 case INTRINS_SSE_CVTDQ2PS:
7901 ret_type = type_to_simd_type (MONO_TYPE_R4);
7902 arg_types [0] = type_to_simd_type (MONO_TYPE_I4);
7903 AddFunc (module, name, ret_type, arg_types, 1);
7905 case INTRINS_SSE_CVTPD2DQ:
7906 ret_type = type_to_simd_type (MONO_TYPE_I4);
7907 arg_types [0] = type_to_simd_type (MONO_TYPE_R8);
7908 AddFunc (module, name, ret_type, arg_types, 1);
7910 case INTRINS_SSE_CVTPS2DQ:
7911 ret_type = type_to_simd_type (MONO_TYPE_I4);
7912 arg_types [0] = type_to_simd_type (MONO_TYPE_R4);
7913 AddFunc (module, name, ret_type, arg_types, 1);
7915 case INTRINS_SSE_CVTPD2PS:
7916 ret_type = type_to_simd_type (MONO_TYPE_R4);
7917 arg_types [0] = type_to_simd_type (MONO_TYPE_R8);
7918 AddFunc (module, name, ret_type, arg_types, 1);
7920 case INTRINS_SSE_CVTPS2PD:
7921 ret_type = type_to_simd_type (MONO_TYPE_R8);
7922 arg_types [0] = type_to_simd_type (MONO_TYPE_R4);
7923 AddFunc (module, name, ret_type, arg_types, 1);
7925 case INTRINS_SSE_CMPPD:
7927 ret_type = type_to_simd_type (MONO_TYPE_R8);
7928 arg_types [0] = ret_type;
7929 arg_types [1] = ret_type;
7930 arg_types [2] = LLVMInt8Type ();
7931 AddFunc (module, name, ret_type, arg_types, 3);
7933 case INTRINS_SSE_CMPPS:
7934 ret_type = type_to_simd_type (MONO_TYPE_R4);
7935 arg_types [0] = ret_type;
7936 arg_types [1] = ret_type;
7937 arg_types [2] = LLVMInt8Type ();
7938 AddFunc (module, name, ret_type, arg_types, 3);
7940 case INTRINS_SSE_PACKSSWB:
7941 case INTRINS_SSE_PACKUSWB:
7942 case INTRINS_SSE_PACKSSDW:
7944 ret_type = type_to_simd_type (MONO_TYPE_I1);
7945 arg_types [0] = type_to_simd_type (MONO_TYPE_I2);
7946 arg_types [1] = type_to_simd_type (MONO_TYPE_I2);
7947 AddFunc (module, name, ret_type, arg_types, 2);
7949 case INTRINS_SSE_PACKUSDW:
7950 ret_type = type_to_simd_type (MONO_TYPE_I2);
7951 arg_types [0] = type_to_simd_type (MONO_TYPE_I4);
7952 arg_types [1] = type_to_simd_type (MONO_TYPE_I4);
7953 AddFunc (module, name, ret_type, arg_types, 2);
7955 /* SSE Binary ops */
7956 case INTRINS_SSE_PMINUD:
7957 case INTRINS_SSE_PMAXUD:
7958 add_sse_binary (module, name, MONO_TYPE_I4);
7960 case INTRINS_SSE_PMINUW:
7961 case INTRINS_SSE_PMINSW:
7962 case INTRINS_SSE_PMAXUW:
7963 case INTRINS_SSE_PADDSW:
7964 case INTRINS_SSE_PSUBSW:
7965 case INTRINS_SSE_PADDUSW:
7966 case INTRINS_SSE_PSUBUSW:
7967 case INTRINS_SSE_PAVGW:
7968 case INTRINS_SSE_PMULHW:
7969 case INTRINS_SSE_PMULHU:
7970 add_sse_binary (module, name, MONO_TYPE_I2);
7972 case INTRINS_SSE_MINPS:
7973 case INTRINS_SSE_MAXPS:
7974 case INTRINS_SSE_HADDPS:
7975 case INTRINS_SSE_HSUBPS:
7976 case INTRINS_SSE_ADDSUBPS:
7977 add_sse_binary (module, name, MONO_TYPE_R4);
7979 case INTRINS_SSE_MINPD:
7980 case INTRINS_SSE_MAXPD:
7981 case INTRINS_SSE_HADDPD:
7982 case INTRINS_SSE_HSUBPD:
7983 case INTRINS_SSE_ADDSUBPD:
7984 add_sse_binary (module, name, MONO_TYPE_R8);
7986 case INTRINS_SSE_PMINUB:
7987 case INTRINS_SSE_PMAXUB:
7988 case INTRINS_SE_PADDSB:
7989 case INTRINS_SSE_PSUBSB:
7990 case INTRINS_SSE_PADDUSB:
7991 case INTRINS_SSE_PSUBUSB:
7992 case INTRINS_SSE_PAVGB:
7993 add_sse_binary (module, name, MONO_TYPE_I1);
7995 case INTRINS_SSE_PAUSE:
7996 AddFunc (module, "llvm.x86.sse2.pause", LLVMVoidType (), NULL, 0);
8000 g_assert_not_reached ();
8006 get_intrinsic (EmitContext *ctx, const char *name)
8008 #if LLVM_API_VERSION > 100
8012 * Every method is emitted into its own module so
8013 * we can add intrinsics on demand.
8015 res = LLVMGetNamedFunction (ctx->lmodule, name);
8019 /* No locking needed */
8020 id = GPOINTER_TO_INT (g_hash_table_lookup (intrins_name_to_id, name));
8023 printf ("%s\n", name);
8024 g_assert (id != -1);
8025 add_intrinsic (ctx->lmodule, id);
8026 res = LLVMGetNamedFunction (ctx->lmodule, name);
8034 res = LLVMGetNamedFunction (ctx->lmodule, name);
8041 add_intrinsics (LLVMModuleRef module)
8045 /* Emit declarations of instrinsics */
8047 * It would be nicer to emit only the intrinsics actually used, but LLVM's Module
8048 * type doesn't seem to do any locking.
8050 for (i = 0; i < INTRINS_NUM; ++i)
8051 add_intrinsic (module, i);
8055 AddFunc (module, "mono_personality", LLVMVoidType (), NULL, 0);
8057 AddFunc (module, "llvm_resume_unwind_trampoline", LLVMVoidType (), NULL, 0);
8060 /* SSE intrinsics */
8061 #if defined(TARGET_X86) || defined(TARGET_AMD64)
8065 /* Load/Store intrinsics */
8067 LLVMTypeRef arg_types [5];
8071 for (i = 1; i <= 8; i *= 2) {
8072 arg_types [0] = LLVMPointerType (LLVMIntType (i * 8), 0);
8073 arg_types [1] = LLVMInt32Type ();
8074 arg_types [2] = LLVMInt1Type ();
8075 arg_types [3] = LLVMInt32Type ();
8076 sprintf (name, "llvm.mono.load.i%d.p0i%d", i * 8, i * 8);
8077 AddFunc (module, name, LLVMIntType (i * 8), arg_types, 4);
8079 arg_types [0] = LLVMIntType (i * 8);
8080 arg_types [1] = LLVMPointerType (LLVMIntType (i * 8), 0);
8081 arg_types [2] = LLVMInt32Type ();
8082 arg_types [3] = LLVMInt1Type ();
8083 arg_types [4] = LLVMInt32Type ();
8084 sprintf (name, "llvm.mono.store.i%d.p0i%d", i * 8, i * 8);
8085 AddFunc (module, name, LLVMVoidType (), arg_types, 5);
8091 add_types (MonoLLVMModule *module)
8093 module->ptr_type = LLVMPointerType (sizeof (gpointer) == 8 ? LLVMInt64Type () : LLVMInt32Type (), 0);
8097 mono_llvm_init (void)
8102 mono_native_tls_alloc (¤t_cfg_tls_id, NULL);
8104 h = g_hash_table_new (NULL, NULL);
8105 for (i = 0; i < INTRINS_NUM; ++i)
8106 g_hash_table_insert (h, GINT_TO_POINTER (intrinsics [i].id), (gpointer)intrinsics [i].name);
8107 intrins_id_to_name = h;
8109 h = g_hash_table_new (g_str_hash, g_str_equal);
8110 for (i = 0; i < INTRINS_NUM; ++i)
8111 g_hash_table_insert (h, (gpointer)intrinsics [i].name, GINT_TO_POINTER (intrinsics [i].id + 1));
8112 intrins_name_to_id = h;
8116 init_jit_module (MonoDomain *domain)
8118 MonoJitDomainInfo *dinfo;
8119 MonoLLVMModule *module;
8122 dinfo = domain_jit_info (domain);
8123 if (dinfo->llvm_module)
8126 mono_loader_lock ();
8128 if (dinfo->llvm_module) {
8129 mono_loader_unlock ();
8133 module = g_new0 (MonoLLVMModule, 1);
8135 name = g_strdup_printf ("mono-%s", domain->friendly_name);
8136 module->lmodule = LLVMModuleCreateWithName (name);
8137 module->context = LLVMGetGlobalContext ();
8139 module->mono_ee = (MonoEERef*)mono_llvm_create_ee (LLVMCreateModuleProviderForExistingModule (module->lmodule), alloc_cb, emitted_cb, exception_cb, dlsym_cb, &module->ee);
8141 add_intrinsics (module->lmodule);
8144 module->llvm_types = g_hash_table_new (NULL, NULL);
8146 #if LLVM_API_VERSION < 100
8147 MonoJitICallInfo *info;
8149 info = mono_find_jit_icall_by_name ("llvm_resume_unwind_trampoline");
8151 LLVMAddGlobalMapping (module->ee, LLVMGetNamedFunction (module->lmodule, "llvm_resume_unwind_trampoline"), (void*)info->func);
8154 mono_memory_barrier ();
8156 dinfo->llvm_module = module;
8158 mono_loader_unlock ();
8162 mono_llvm_cleanup (void)
8164 MonoLLVMModule *module = &aot_module;
8166 if (module->lmodule)
8167 LLVMDisposeModule (module->lmodule);
8169 if (module->context)
8170 LLVMContextDispose (module->context);
8174 mono_llvm_free_domain_info (MonoDomain *domain)
8176 MonoJitDomainInfo *info = domain_jit_info (domain);
8177 MonoLLVMModule *module = (MonoLLVMModule*)info->llvm_module;
8183 if (module->llvm_types)
8184 g_hash_table_destroy (module->llvm_types);
8186 mono_llvm_dispose_ee (module->mono_ee);
8188 if (module->bb_names) {
8189 for (i = 0; i < module->bb_names_len; ++i)
8190 g_free (module->bb_names [i]);
8191 g_free (module->bb_names);
8193 //LLVMDisposeModule (module->module);
8197 info->llvm_module = NULL;
8201 mono_llvm_create_aot_module (MonoAssembly *assembly, const char *global_prefix, gboolean emit_dwarf, gboolean static_link, gboolean llvm_only)
8203 MonoLLVMModule *module = &aot_module;
8205 /* Delete previous module */
8206 if (module->plt_entries)
8207 g_hash_table_destroy (module->plt_entries);
8208 if (module->lmodule)
8209 LLVMDisposeModule (module->lmodule);
8211 memset (module, 0, sizeof (aot_module));
8213 module->lmodule = LLVMModuleCreateWithName ("aot");
8214 module->assembly = assembly;
8215 module->global_prefix = g_strdup (global_prefix);
8216 module->got_symbol = g_strdup_printf ("%s_llvm_got", global_prefix);
8217 module->eh_frame_symbol = g_strdup_printf ("%s_eh_frame", global_prefix);
8218 module->get_method_symbol = g_strdup_printf ("%s_get_method", global_prefix);
8219 module->get_unbox_tramp_symbol = g_strdup_printf ("%s_get_unbox_tramp", global_prefix);
8220 module->external_symbols = TRUE;
8221 module->emit_dwarf = emit_dwarf;
8222 module->static_link = static_link;
8223 module->llvm_only = llvm_only;
8224 /* The first few entries are reserved */
8225 module->max_got_offset = 16;
8226 module->context = LLVMContextCreate ();
8229 /* clang ignores our debug info because it has an invalid version */
8230 module->emit_dwarf = FALSE;
8232 #if LLVM_API_VERSION > 100
8233 module->emit_dwarf = FALSE;
8236 add_intrinsics (module->lmodule);
8239 #if LLVM_API_VERSION > 100
8240 if (module->emit_dwarf) {
8241 char *dir, *build_info, *s, *cu_name;
8243 module->di_builder = mono_llvm_create_di_builder (module->lmodule);
8246 dir = g_strdup (".");
8247 build_info = mono_get_runtime_build_info ();
8248 s = g_strdup_printf ("Mono AOT Compiler %s (LLVM)", build_info);
8249 cu_name = g_path_get_basename (assembly->image->name);
8250 module->cu = mono_llvm_di_create_compile_unit (module->di_builder, cu_name, dir, s);
8252 g_free (build_info);
8259 * We couldn't compute the type of the LLVM global representing the got because
8260 * its size is only known after all the methods have been emitted. So create
8261 * a dummy variable, and replace all uses it with the real got variable when
8262 * its size is known in mono_llvm_emit_aot_module ().
8265 LLVMTypeRef got_type = LLVMArrayType (module->ptr_type, 0);
8267 module->got_var = LLVMAddGlobal (module->lmodule, got_type, "mono_dummy_got");
8268 LLVMSetInitializer (module->got_var, LLVMConstNull (got_type));
8271 /* Add initialization array */
8273 LLVMTypeRef inited_type = LLVMArrayType (LLVMInt8Type (), 0);
8275 module->inited_var = LLVMAddGlobal (aot_module.lmodule, inited_type, "mono_inited_tmp");
8276 LLVMSetInitializer (module->inited_var, LLVMConstNull (inited_type));
8280 emit_init_icall_wrappers (module);
8282 emit_llvm_code_start (module);
8284 /* Add a dummy personality function */
8285 if (!use_debug_personality) {
8286 LLVMValueRef personality = LLVMAddFunction (module->lmodule, default_personality_name, LLVMFunctionType (LLVMInt32Type (), NULL, 0, TRUE));
8287 LLVMSetLinkage (personality, LLVMExternalLinkage);
8288 mark_as_used (module, personality);
8291 /* Add a reference to the c++ exception we throw/catch */
8293 LLVMTypeRef exc = LLVMPointerType (LLVMInt8Type (), 0);
8294 module->sentinel_exception = LLVMAddGlobal (module->lmodule, exc, "_ZTIPi");
8295 LLVMSetLinkage (module->sentinel_exception, LLVMExternalLinkage);
8296 mono_llvm_set_is_constant (module->sentinel_exception);
8299 module->llvm_types = g_hash_table_new (NULL, NULL);
8300 module->plt_entries = g_hash_table_new (g_str_hash, g_str_equal);
8301 module->plt_entries_ji = g_hash_table_new (NULL, NULL);
8302 module->direct_callables = g_hash_table_new (g_str_hash, g_str_equal);
8303 module->method_to_lmethod = g_hash_table_new (NULL, NULL);
8304 module->idx_to_lmethod = g_hash_table_new (NULL, NULL);
8305 module->idx_to_unbox_tramp = g_hash_table_new (NULL, NULL);
8306 module->method_to_callers = g_hash_table_new (NULL, NULL);
8310 llvm_array_from_uints (LLVMTypeRef el_type, guint32 *values, int nvalues)
8313 LLVMValueRef res, *vals;
8315 vals = g_new0 (LLVMValueRef, nvalues);
8316 for (i = 0; i < nvalues; ++i)
8317 vals [i] = LLVMConstInt (LLVMInt32Type (), values [i], FALSE);
8318 res = LLVMConstArray (LLVMInt32Type (), vals, nvalues);
8324 * mono_llvm_emit_aot_file_info:
8326 * Emit the MonoAotFileInfo structure.
8327 * Same as emit_aot_file_info () in aot-compiler.c.
8330 mono_llvm_emit_aot_file_info (MonoAotFileInfo *info, gboolean has_jitted_code)
8332 MonoLLVMModule *module = &aot_module;
8334 /* Save these for later */
8335 memcpy (&module->aot_info, info, sizeof (MonoAotFileInfo));
8336 module->has_jitted_code = has_jitted_code;
8340 * mono_llvm_emit_aot_data:
8342 * Emit the binary data DATA pointed to by symbol SYMBOL.
8345 mono_llvm_emit_aot_data (const char *symbol, guint8 *data, int data_len)
8347 MonoLLVMModule *module = &aot_module;
8351 type = LLVMArrayType (LLVMInt8Type (), data_len);
8352 d = LLVMAddGlobal (module->lmodule, type, symbol);
8353 LLVMSetVisibility (d, LLVMHiddenVisibility);
8354 LLVMSetLinkage (d, LLVMInternalLinkage);
8355 LLVMSetInitializer (d, mono_llvm_create_constant_data_array (data, data_len));
8356 mono_llvm_set_is_constant (d);
8359 /* Add a reference to a global defined in JITted code */
8361 AddJitGlobal (MonoLLVMModule *module, LLVMTypeRef type, const char *name)
8366 s = g_strdup_printf ("%s%s", module->global_prefix, name);
8367 v = LLVMAddGlobal (module->lmodule, LLVMInt8Type (), s);
8373 emit_aot_file_info (MonoLLVMModule *module)
8375 LLVMTypeRef file_info_type;
8376 LLVMTypeRef *eltypes, eltype;
8377 LLVMValueRef info_var;
8378 LLVMValueRef *fields;
8379 int i, nfields, tindex;
8380 MonoAotFileInfo *info;
8381 LLVMModuleRef lmodule = module->lmodule;
8383 info = &module->aot_info;
8385 /* Create an LLVM type to represent MonoAotFileInfo */
8386 nfields = 2 + MONO_AOT_FILE_INFO_NUM_SYMBOLS + 15 + 5;
8387 eltypes = g_new (LLVMTypeRef, nfields);
8389 eltypes [tindex ++] = LLVMInt32Type ();
8390 eltypes [tindex ++] = LLVMInt32Type ();
8392 for (i = 0; i < MONO_AOT_FILE_INFO_NUM_SYMBOLS; ++i)
8393 eltypes [tindex ++] = LLVMPointerType (LLVMInt8Type (), 0);
8395 for (i = 0; i < 15; ++i)
8396 eltypes [tindex ++] = LLVMInt32Type ();
8398 eltypes [tindex ++] = LLVMArrayType (LLVMInt32Type (), MONO_AOT_TABLE_NUM);
8399 for (i = 0; i < 4; ++i)
8400 eltypes [tindex ++] = LLVMArrayType (LLVMInt32Type (), MONO_AOT_TRAMP_NUM);
8401 g_assert (tindex == nfields);
8402 file_info_type = LLVMStructCreateNamed (module->context, "MonoAotFileInfo");
8403 LLVMStructSetBody (file_info_type, eltypes, nfields, FALSE);
8405 info_var = LLVMAddGlobal (lmodule, file_info_type, "mono_aot_file_info");
8406 if (module->static_link) {
8407 LLVMSetVisibility (info_var, LLVMHiddenVisibility);
8408 LLVMSetLinkage (info_var, LLVMInternalLinkage);
8410 fields = g_new (LLVMValueRef, nfields);
8412 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->version, FALSE);
8413 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->dummy, FALSE);
8417 * We use LLVMGetNamedGlobal () for symbol which are defined in LLVM code, and LLVMAddGlobal ()
8418 * for symbols defined in the .s file emitted by the aot compiler.
8420 eltype = eltypes [tindex];
8421 if (module->llvm_only)
8422 fields [tindex ++] = LLVMConstNull (eltype);
8424 fields [tindex ++] = AddJitGlobal (module, eltype, "jit_got");
8425 fields [tindex ++] = module->got_var;
8426 /* llc defines this directly */
8427 if (!module->llvm_only) {
8428 fields [tindex ++] = LLVMAddGlobal (lmodule, eltype, module->eh_frame_symbol);
8429 fields [tindex ++] = LLVMConstNull (eltype);
8430 fields [tindex ++] = LLVMConstNull (eltype);
8432 fields [tindex ++] = LLVMConstNull (eltype);
8433 fields [tindex ++] = module->get_method;
8434 fields [tindex ++] = module->get_unbox_tramp;
8436 if (module->has_jitted_code) {
8437 fields [tindex ++] = AddJitGlobal (module, eltype, "jit_code_start");
8438 fields [tindex ++] = AddJitGlobal (module, eltype, "jit_code_end");
8440 fields [tindex ++] = LLVMConstNull (eltype);
8441 fields [tindex ++] = LLVMConstNull (eltype);
8443 if (!module->llvm_only)
8444 fields [tindex ++] = AddJitGlobal (module, eltype, "method_addresses");
8446 fields [tindex ++] = LLVMConstNull (eltype);
8447 if (info->flags & MONO_AOT_FILE_FLAG_SEPARATE_DATA) {
8448 for (i = 0; i < MONO_AOT_TABLE_NUM; ++i)
8449 fields [tindex ++] = LLVMConstNull (eltype);
8451 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "blob");
8452 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "class_name_table");
8453 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "class_info_offsets");
8454 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "method_info_offsets");
8455 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "ex_info_offsets");
8456 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "extra_method_info_offsets");
8457 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "extra_method_table");
8458 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "got_info_offsets");
8459 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "llvm_got_info_offsets");
8460 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "image_table");
8462 /* Not needed (mem_end) */
8463 fields [tindex ++] = LLVMConstNull (eltype);
8464 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "assembly_guid");
8465 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "runtime_version");
8466 if (info->trampoline_size [0]) {
8467 fields [tindex ++] = AddJitGlobal (module, eltype, "specific_trampolines");
8468 fields [tindex ++] = AddJitGlobal (module, eltype, "static_rgctx_trampolines");
8469 fields [tindex ++] = AddJitGlobal (module, eltype, "imt_thunks");
8470 fields [tindex ++] = AddJitGlobal (module, eltype, "gsharedvt_arg_trampolines");
8472 fields [tindex ++] = LLVMConstNull (eltype);
8473 fields [tindex ++] = LLVMConstNull (eltype);
8474 fields [tindex ++] = LLVMConstNull (eltype);
8475 fields [tindex ++] = LLVMConstNull (eltype);
8477 if (module->static_link && !module->llvm_only)
8478 fields [tindex ++] = AddJitGlobal (module, eltype, "globals");
8480 fields [tindex ++] = LLVMConstNull (eltype);
8481 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "assembly_name");
8482 if (!module->llvm_only) {
8483 fields [tindex ++] = AddJitGlobal (module, eltype, "plt");
8484 fields [tindex ++] = AddJitGlobal (module, eltype, "plt_end");
8485 fields [tindex ++] = AddJitGlobal (module, eltype, "unwind_info");
8486 fields [tindex ++] = AddJitGlobal (module, eltype, "unbox_trampolines");
8487 fields [tindex ++] = AddJitGlobal (module, eltype, "unbox_trampolines_end");
8488 fields [tindex ++] = AddJitGlobal (module, eltype, "unbox_trampoline_addresses");
8490 fields [tindex ++] = LLVMConstNull (eltype);
8491 fields [tindex ++] = LLVMConstNull (eltype);
8492 fields [tindex ++] = LLVMConstNull (eltype);
8493 fields [tindex ++] = LLVMConstNull (eltype);
8494 fields [tindex ++] = LLVMConstNull (eltype);
8495 fields [tindex ++] = LLVMConstNull (eltype);
8498 for (i = 0; i < MONO_AOT_FILE_INFO_NUM_SYMBOLS; ++i)
8499 fields [2 + i] = LLVMConstBitCast (fields [2 + i], eltype);
8502 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->plt_got_offset_base, FALSE);
8503 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->got_size, FALSE);
8504 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->plt_size, FALSE);
8505 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->nmethods, FALSE);
8506 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->flags, FALSE);
8507 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->opts, FALSE);
8508 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->simd_opts, FALSE);
8509 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->gc_name_index, FALSE);
8510 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->num_rgctx_fetch_trampolines, FALSE);
8511 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->double_align, FALSE);
8512 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->long_align, FALSE);
8513 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->generic_tramp_num, FALSE);
8514 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->tramp_page_size, FALSE);
8515 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->nshared_got_entries, FALSE);
8516 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->datafile_size, FALSE);
8518 fields [tindex ++] = llvm_array_from_uints (LLVMInt32Type (), info->table_offsets, MONO_AOT_TABLE_NUM);
8519 fields [tindex ++] = llvm_array_from_uints (LLVMInt32Type (), info->num_trampolines, MONO_AOT_TRAMP_NUM);
8520 fields [tindex ++] = llvm_array_from_uints (LLVMInt32Type (), info->trampoline_got_offset_base, MONO_AOT_TRAMP_NUM);
8521 fields [tindex ++] = llvm_array_from_uints (LLVMInt32Type (), info->trampoline_size, MONO_AOT_TRAMP_NUM);
8522 fields [tindex ++] = llvm_array_from_uints (LLVMInt32Type (), info->tramp_page_code_offsets, MONO_AOT_TRAMP_NUM);
8523 g_assert (tindex == nfields);
8525 LLVMSetInitializer (info_var, LLVMConstNamedStruct (file_info_type, fields, nfields));
8527 if (module->static_link) {
8531 s = g_strdup_printf ("mono_aot_module_%s_info", module->assembly->aname.name);
8532 /* Get rid of characters which cannot occur in symbols */
8534 for (p = s; *p; ++p) {
8535 if (!(isalnum (*p) || *p == '_'))
8538 var = LLVMAddGlobal (module->lmodule, LLVMPointerType (LLVMInt8Type (), 0), s);
8540 LLVMSetInitializer (var, LLVMConstBitCast (LLVMGetNamedGlobal (module->lmodule, "mono_aot_file_info"), LLVMPointerType (LLVMInt8Type (), 0)));
8541 LLVMSetLinkage (var, LLVMExternalLinkage);
8546 * Emit the aot module into the LLVM bitcode file FILENAME.
8549 mono_llvm_emit_aot_module (const char *filename, const char *cu_name)
8551 LLVMTypeRef got_type, inited_type;
8552 LLVMValueRef real_got, real_inited;
8553 MonoLLVMModule *module = &aot_module;
8555 emit_llvm_code_end (module);
8558 * Create the real got variable and replace all uses of the dummy variable with
8561 got_type = LLVMArrayType (module->ptr_type, module->max_got_offset + 1);
8562 real_got = LLVMAddGlobal (module->lmodule, got_type, module->got_symbol);
8563 LLVMSetInitializer (real_got, LLVMConstNull (got_type));
8564 if (module->external_symbols) {
8565 LLVMSetLinkage (real_got, LLVMExternalLinkage);
8566 LLVMSetVisibility (real_got, LLVMHiddenVisibility);
8568 LLVMSetLinkage (real_got, LLVMInternalLinkage);
8570 mono_llvm_replace_uses_of (module->got_var, real_got);
8572 mark_as_used (&aot_module, real_got);
8574 /* Delete the dummy got so it doesn't become a global */
8575 LLVMDeleteGlobal (module->got_var);
8576 module->got_var = real_got;
8579 * Same for the init_var
8581 if (module->llvm_only) {
8582 inited_type = LLVMArrayType (LLVMInt8Type (), module->max_inited_idx + 1);
8583 real_inited = LLVMAddGlobal (module->lmodule, inited_type, "mono_inited");
8584 LLVMSetInitializer (real_inited, LLVMConstNull (inited_type));
8585 LLVMSetLinkage (real_inited, LLVMInternalLinkage);
8586 mono_llvm_replace_uses_of (module->inited_var, real_inited);
8587 LLVMDeleteGlobal (module->inited_var);
8590 if (module->llvm_only) {
8591 emit_get_method (&aot_module);
8592 emit_get_unbox_tramp (&aot_module);
8595 emit_llvm_used (&aot_module);
8596 emit_dbg_info (&aot_module, filename, cu_name);
8597 emit_aot_file_info (&aot_module);
8600 * Replace GOT entries for directly callable methods with the methods themselves.
8601 * It would be easier to implement this by predefining all methods before compiling
8602 * their bodies, but that couldn't handle the case when a method fails to compile
8605 if (module->llvm_only) {
8606 GHashTableIter iter;
8608 GSList *callers, *l;
8610 g_hash_table_iter_init (&iter, module->method_to_callers);
8611 while (g_hash_table_iter_next (&iter, (void**)&method, (void**)&callers)) {
8612 LLVMValueRef lmethod;
8614 lmethod = (LLVMValueRef)g_hash_table_lookup (module->method_to_lmethod, method);
8616 for (l = callers; l; l = l->next) {
8617 LLVMValueRef caller = (LLVMValueRef)l->data;
8619 mono_llvm_replace_uses_of (caller, lmethod);
8625 /* Replace PLT entries for directly callable methods with the methods themselves */
8627 GHashTableIter iter;
8629 LLVMValueRef callee;
8631 g_hash_table_iter_init (&iter, module->plt_entries_ji);
8632 while (g_hash_table_iter_next (&iter, (void**)&ji, (void**)&callee)) {
8633 if (mono_aot_is_direct_callable (ji)) {
8634 LLVMValueRef lmethod;
8636 lmethod = (LLVMValueRef)g_hash_table_lookup (module->method_to_lmethod, ji->data.method);
8637 /* The types might not match because the caller might pass an rgctx */
8638 if (lmethod && LLVMTypeOf (callee) == LLVMTypeOf (lmethod)) {
8639 mono_llvm_replace_uses_of (callee, lmethod);
8640 mono_aot_mark_unused_llvm_plt_entry (ji);
8650 if (LLVMVerifyModule (module->lmodule, LLVMReturnStatusAction, &verifier_err)) {
8651 g_assert_not_reached ();
8656 LLVMWriteBitcodeToFile (module->lmodule, filename);
8661 md_string (const char *s)
8663 return LLVMMDString (s, strlen (s));
8666 /* Debugging support */
8669 emit_dbg_info (MonoLLVMModule *module, const char *filename, const char *cu_name)
8671 LLVMModuleRef lmodule = module->lmodule;
8672 LLVMValueRef args [16], ver;
8675 * This can only be enabled when LLVM code is emitted into a separate object
8676 * file, since the AOT compiler also emits dwarf info,
8677 * and the abbrev indexes will not be correct since llvm has added its own
8680 if (!module->emit_dwarf)
8683 #if LLVM_API_VERSION > 100
8684 mono_llvm_di_builder_finalize (module->di_builder);
8686 LLVMValueRef cu_args [16], cu;
8688 char *build_info, *s, *dir;
8691 * Emit dwarf info in the form of LLVM metadata. There is some
8692 * out-of-date documentation at:
8693 * http://llvm.org/docs/SourceLevelDebugging.html
8694 * but most of this was gathered from the llvm and
8699 cu_args [n_cuargs ++] = LLVMConstInt (LLVMInt32Type (), DW_TAG_compile_unit, FALSE);
8700 /* CU name/compilation dir */
8701 dir = g_path_get_dirname (filename);
8702 args [0] = LLVMMDString (cu_name, strlen (cu_name));
8703 args [1] = LLVMMDString (dir, strlen (dir));
8704 cu_args [n_cuargs ++] = LLVMMDNode (args, 2);
8707 cu_args [n_cuargs ++] = LLVMConstInt (LLVMInt32Type (), DW_LANG_C99, FALSE);
8709 build_info = mono_get_runtime_build_info ();
8710 s = g_strdup_printf ("Mono AOT Compiler %s (LLVM)", build_info);
8711 cu_args [n_cuargs ++] = LLVMMDString (s, strlen (s));
8712 g_free (build_info);
8714 cu_args [n_cuargs ++] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
8716 cu_args [n_cuargs ++] = LLVMMDString ("", strlen (""));
8717 /* Runtime version */
8718 cu_args [n_cuargs ++] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
8720 cu_args [n_cuargs ++] = LLVMMDNode (args, 0);
8721 cu_args [n_cuargs ++] = LLVMMDNode (args, 0);
8723 if (module->subprogram_mds) {
8727 mds = g_new0 (LLVMValueRef, module->subprogram_mds->len);
8728 for (i = 0; i < module->subprogram_mds->len; ++i)
8729 mds [i] = (LLVMValueRef)g_ptr_array_index (module->subprogram_mds, i);
8730 cu_args [n_cuargs ++] = LLVMMDNode (mds, module->subprogram_mds->len);
8732 cu_args [n_cuargs ++] = LLVMMDNode (args, 0);
8735 cu_args [n_cuargs ++] = LLVMMDNode (args, 0);
8736 /* Imported modules */
8737 cu_args [n_cuargs ++] = LLVMMDNode (args, 0);
8739 cu_args [n_cuargs ++] = LLVMMDString ("", strlen (""));
8740 /* DebugEmissionKind = FullDebug */
8741 cu_args [n_cuargs ++] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
8742 cu = LLVMMDNode (cu_args, n_cuargs);
8743 LLVMAddNamedMetadataOperand (lmodule, "llvm.dbg.cu", cu);
8746 #if LLVM_API_VERSION > 100
8747 args [0] = LLVMConstInt (LLVMInt32Type (), 2, FALSE);
8748 args [1] = LLVMMDString ("Dwarf Version", strlen ("Dwarf Version"));
8749 args [2] = LLVMConstInt (LLVMInt32Type (), 2, FALSE);
8750 ver = LLVMMDNode (args, 3);
8751 LLVMAddNamedMetadataOperand (lmodule, "llvm.module.flags", ver);
8753 args [0] = LLVMConstInt (LLVMInt32Type (), 2, FALSE);
8754 args [1] = LLVMMDString ("Debug Info Version", strlen ("Debug Info Version"));
8755 args [2] = LLVMConstInt (LLVMInt64Type (), 3, FALSE);
8756 ver = LLVMMDNode (args, 3);
8757 LLVMAddNamedMetadataOperand (lmodule, "llvm.module.flags", ver);
8759 args [0] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
8760 args [1] = LLVMMDString ("Dwarf Version", strlen ("Dwarf Version"));
8761 args [2] = LLVMConstInt (LLVMInt32Type (), 2, FALSE);
8762 ver = LLVMMDNode (args, 3);
8763 LLVMAddNamedMetadataOperand (lmodule, "llvm.module.flags", ver);
8765 args [0] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
8766 args [1] = LLVMMDString ("Debug Info Version", strlen ("Debug Info Version"));
8767 args [2] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
8768 ver = LLVMMDNode (args, 3);
8769 LLVMAddNamedMetadataOperand (lmodule, "llvm.module.flags", ver);
8774 emit_dbg_subprogram (EmitContext *ctx, MonoCompile *cfg, LLVMValueRef method, const char *name)
8776 MonoLLVMModule *module = ctx->module;
8777 MonoDebugMethodInfo *minfo = ctx->minfo;
8778 char *source_file, *dir, *filename;
8779 LLVMValueRef md, args [16], ctx_args [16], md_args [64], type_args [16], ctx_md, type_md;
8780 MonoSymSeqPoint *sym_seq_points;
8786 mono_debug_symfile_get_seq_points (minfo, &source_file, NULL, NULL, &sym_seq_points, &n_seq_points);
8788 source_file = g_strdup ("<unknown>");
8789 dir = g_path_get_dirname (source_file);
8790 filename = g_path_get_basename (source_file);
8792 #if LLVM_API_VERSION > 100
8793 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);
8796 ctx_args [0] = LLVMConstInt (LLVMInt32Type (), 0x29, FALSE);
8797 args [0] = md_string (filename);
8798 args [1] = md_string (dir);
8799 ctx_args [1] = LLVMMDNode (args, 2);
8800 ctx_md = LLVMMDNode (ctx_args, 2);
8802 type_args [0] = LLVMConstInt (LLVMInt32Type (), DW_TAG_subroutine_type, FALSE);
8803 type_args [1] = NULL;
8804 type_args [2] = NULL;
8805 type_args [3] = LLVMMDString ("", 0);
8806 type_args [4] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
8807 type_args [5] = LLVMConstInt (LLVMInt64Type (), 0, FALSE);
8808 type_args [6] = LLVMConstInt (LLVMInt64Type (), 0, FALSE);
8809 type_args [7] = LLVMConstInt (LLVMInt64Type (), 0, FALSE);
8810 type_args [8] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
8811 type_args [9] = NULL;
8812 type_args [10] = NULL;
8813 type_args [11] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
8814 type_args [12] = NULL;
8815 type_args [13] = NULL;
8816 type_args [14] = NULL;
8817 type_md = LLVMMDNode (type_args, 14);
8819 /* http://llvm.org/docs/SourceLevelDebugging.html#subprogram-descriptors */
8820 md_args [0] = LLVMConstInt (LLVMInt32Type (), DW_TAG_subprogram, FALSE);
8821 /* Source directory + file pair */
8822 args [0] = md_string (filename);
8823 args [1] = md_string (dir);
8824 md_args [1] = LLVMMDNode (args ,2);
8825 md_args [2] = ctx_md;
8826 md_args [3] = md_string (cfg->method->name);
8827 md_args [4] = md_string (name);
8828 md_args [5] = md_string (name);
8831 md_args [6] = LLVMConstInt (LLVMInt32Type (), sym_seq_points [0].line, FALSE);
8833 md_args [6] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
8835 md_args [7] = type_md;
8837 md_args [8] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
8839 md_args [9] = LLVMConstInt (LLVMInt1Type (), 1, FALSE);
8841 md_args [10] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
8842 /* Index into a virtual function */
8843 md_args [11] = NULL;
8844 md_args [12] = NULL;
8846 md_args [13] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
8848 md_args [14] = LLVMConstInt (LLVMInt1Type (), 1, FALSE);
8849 /* Pointer to LLVM function */
8850 md_args [15] = method;
8851 /* Function template parameter */
8852 md_args [16] = NULL;
8853 /* Function declaration descriptor */
8854 md_args [17] = NULL;
8855 /* List of function variables */
8856 md_args [18] = LLVMMDNode (args, 0);
8858 md_args [19] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
8859 md = LLVMMDNode (md_args, 20);
8861 if (!module->subprogram_mds)
8862 module->subprogram_mds = g_ptr_array_new ();
8863 g_ptr_array_add (module->subprogram_mds, md);
8867 g_free (source_file);
8868 g_free (sym_seq_points);
8874 emit_dbg_loc (EmitContext *ctx, LLVMBuilderRef builder, const unsigned char *cil_code)
8876 MonoCompile *cfg = ctx->cfg;
8878 if (ctx->minfo && cil_code && cil_code >= cfg->header->code && cil_code < cfg->header->code + cfg->header->code_size) {
8879 MonoDebugSourceLocation *loc;
8880 LLVMValueRef loc_md;
8882 loc = mono_debug_symfile_lookup_location (ctx->minfo, cil_code - cfg->header->code);
8885 #if LLVM_API_VERSION > 100
8886 loc_md = mono_llvm_di_create_location (ctx->module->di_builder, ctx->dbg_md, loc->row, loc->column);
8887 mono_llvm_di_set_location (builder, loc_md);
8889 LLVMValueRef md_args [16];
8893 md_args [nmd_args ++] = LLVMConstInt (LLVMInt32Type (), loc->row, FALSE);
8894 md_args [nmd_args ++] = LLVMConstInt (LLVMInt32Type (), loc->column, FALSE);
8895 md_args [nmd_args ++] = ctx->dbg_md;
8896 md_args [nmd_args ++] = NULL;
8897 loc_md = LLVMMDNode (md_args, nmd_args);
8898 LLVMSetCurrentDebugLocation (builder, loc_md);
8900 mono_debug_symfile_free_location (loc);
8906 default_mono_llvm_unhandled_exception (void)
8908 MonoJitTlsData *jit_tls = mono_get_jit_tls ();
8909 MonoObject *target = mono_gchandle_get_target (jit_tls->thrown_exc);
8911 mono_unhandled_exception (target);
8912 exit (mono_environment_exitcode_get ());
8917 - Emit LLVM IR from the mono IR using the LLVM C API.
8918 - The original arch specific code remains, so we can fall back to it if we run
8919 into something we can't handle.
8923 A partial list of issues:
8924 - Handling of opcodes which can throw exceptions.
8926 In the mono JIT, these are implemented using code like this:
8933 push throw_pos - method
8934 call <exception trampoline>
8936 The problematic part is push throw_pos - method, which cannot be represented
8937 in the LLVM IR, since it does not support label values.
8938 -> this can be implemented in AOT mode using inline asm + labels, but cannot
8939 be implemented in JIT mode ?
8940 -> a possible but slower implementation would use the normal exception
8941 throwing code but it would need to control the placement of the throw code
8942 (it needs to be exactly after the compare+branch).
8943 -> perhaps add a PC offset intrinsics ?
8945 - efficient implementation of .ovf opcodes.
8947 These are currently implemented as:
8948 <ins which sets the condition codes>
8951 Some overflow opcodes are now supported by LLVM SVN.
8953 - exception handling, unwinding.
8954 - SSA is disabled for methods with exception handlers
8955 - How to obtain unwind info for LLVM compiled methods ?
8956 -> this is now solved by converting the unwind info generated by LLVM
8958 - LLVM uses the c++ exception handling framework, while we use our home grown
8959 code, and couldn't use the c++ one:
8960 - its not supported under VC++, other exotic platforms.
8961 - it might be impossible to support filter clauses with it.
8965 The trampolines need a predictable call sequence, since they need to disasm
8966 the calling code to obtain register numbers / offsets.
8968 LLVM currently generates this code in non-JIT mode:
8969 mov -0x98(%rax),%eax
8971 Here, the vtable pointer is lost.
8972 -> solution: use one vtable trampoline per class.
8974 - passing/receiving the IMT pointer/RGCTX.
8975 -> solution: pass them as normal arguments ?
8979 LLVM does not allow the specification of argument registers etc. This means
8980 that all calls are made according to the platform ABI.
8982 - passing/receiving vtypes.
8984 Vtypes passed/received in registers are handled by the front end by using
8985 a signature with scalar arguments, and loading the parts of the vtype into those
8988 Vtypes passed on the stack are handled using the 'byval' attribute.
8992 Supported though alloca, we need to emit the load/store code.
8996 The mono JIT uses pointer sized iregs/double fregs, while LLVM uses precisely
8997 typed registers, so we have to keep track of the precise LLVM type of each vreg.
8998 This is made easier because the IR is already in SSA form.
8999 An additional problem is that our IR is not consistent with types, i.e. i32/ia64
9000 types are frequently used incorrectly.
9005 Emit LLVM bytecode into a .bc file, compile it using llc into a .s file, then link
9006 it with the file containing the methods emitted by the JIT and the AOT data
9010 /* FIXME: Normalize some aspects of the mono IR to allow easier translation, like:
9011 * - each bblock should end with a branch
9012 * - setting the return value, making cfg->ret non-volatile
9013 * - avoid some transformations in the JIT which make it harder for us to generate
9015 * - use pointer types to help optimizations.