2 * mini-llvm.c: llvm "Backend" for the mono JIT
4 * Copyright 2009-2011 Novell Inc (http://www.novell.com)
5 * Copyright 2011 Xamarin Inc (http://www.xamarin.com)
6 * Licensed under the MIT license. See LICENSE file in the project root for full license information.
10 #include <mono/metadata/debug-helpers.h>
11 #include <mono/metadata/debug-mono-symfile.h>
12 #include <mono/metadata/mempool-internals.h>
13 #include <mono/metadata/environment.h>
14 #include <mono/metadata/object-internals.h>
15 #include <mono/metadata/abi-details.h>
16 #include <mono/utils/mono-tls.h>
17 #include <mono/utils/mono-dl.h>
18 #include <mono/utils/mono-time.h>
19 #include <mono/utils/freebsd-dwarf.h>
21 #ifndef __STDC_LIMIT_MACROS
22 #define __STDC_LIMIT_MACROS
24 #ifndef __STDC_CONSTANT_MACROS
25 #define __STDC_CONSTANT_MACROS
28 #include "llvm-c/BitWriter.h"
29 #include "llvm-c/Analysis.h"
31 #include "mini-llvm-cpp.h"
33 #include "aot-compiler.h"
34 #include "mini-llvm.h"
39 extern void *memset(void *, int, size_t);
40 void bzero (void *to, size_t count) { memset (to, 0, count); }
44 #if LLVM_API_VERSION < 4
45 #error "The version of the mono llvm repository is too old."
48 #define ALIGN_PTR_TO(ptr,align) (gpointer)((((gssize)(ptr)) + (align - 1)) & (~(align - 1)))
51 * Information associated by mono with LLVM modules.
54 LLVMModuleRef lmodule;
55 LLVMValueRef throw_icall, rethrow, match_exc, throw_corlib_exception, resume_eh;
56 GHashTable *llvm_types;
58 const char *got_symbol;
59 const char *get_method_symbol;
60 const char *get_unbox_tramp_symbol;
61 GHashTable *plt_entries;
62 GHashTable *plt_entries_ji;
63 GHashTable *method_to_lmethod;
64 GHashTable *direct_callables;
69 GPtrArray *subprogram_mds;
71 LLVMExecutionEngineRef ee;
72 gboolean external_symbols;
77 MonoAssembly *assembly;
79 MonoAotFileInfo aot_info;
80 const char *jit_got_symbol;
81 const char *eh_frame_symbol;
82 LLVMValueRef get_method, get_unbox_tramp;
83 LLVMValueRef init_method, init_method_gshared_mrgctx, init_method_gshared_this, init_method_gshared_vtable;
84 LLVMValueRef code_start, code_end;
85 LLVMValueRef inited_var;
86 int max_inited_idx, max_method_idx;
87 gboolean has_jitted_code;
90 GHashTable *idx_to_lmethod;
91 GHashTable *idx_to_unbox_tramp;
92 /* Maps a MonoMethod to LLVM instructions representing it */
93 GHashTable *method_to_callers;
94 LLVMContextRef context;
95 LLVMValueRef sentinel_exception;
96 void *di_builder, *cu;
100 * Information associated by the backend with mono basic blocks.
103 LLVMBasicBlockRef bblock, end_bblock;
104 LLVMValueRef finally_ind;
105 gboolean added, invoke_target;
107 * If this bblock is the start of a finally clause, this is a list of bblocks it
108 * needs to branch to in ENDFINALLY.
110 GSList *call_handler_return_bbs;
112 * If this bblock is the start of a finally clause, this is the bblock that
113 * CALL_HANDLER needs to branch to.
115 LLVMBasicBlockRef call_handler_target_bb;
116 /* The list of switch statements generated by ENDFINALLY instructions */
117 GSList *endfinally_switch_ins_list;
122 * Structure containing emit state
125 MonoMemPool *mempool;
127 /* Maps method names to the corresponding LLVMValueRef */
128 GHashTable *emitted_method_decls;
131 LLVMValueRef lmethod;
132 MonoLLVMModule *module;
133 LLVMModuleRef lmodule;
135 int sindex, default_index, ex_index;
136 LLVMBuilderRef builder;
137 LLVMValueRef *values, *addresses;
138 MonoType **vreg_cli_types;
140 MonoMethodSignature *sig;
142 GHashTable *region_to_handler;
143 GHashTable *clause_to_handler;
144 LLVMBuilderRef alloca_builder;
145 LLVMValueRef last_alloca;
146 LLVMValueRef rgctx_arg;
147 LLVMValueRef this_arg;
148 LLVMTypeRef *vreg_types;
149 LLVMTypeRef method_type;
150 LLVMBasicBlockRef init_bb, inited_bb;
152 gboolean *unreachable;
154 gboolean has_got_access;
155 gboolean is_linkonce;
156 int this_arg_pindex, rgctx_arg_pindex;
157 LLVMValueRef imt_rgctx_loc;
158 GHashTable *llvm_types;
160 MonoDebugMethodInfo *minfo;
162 /* For every clause, the clauses it is nested in */
165 GHashTable *exc_meta;
166 GHashTable *method_to_callers;
167 GPtrArray *phi_values;
168 GPtrArray *bblock_list;
170 GHashTable *jit_callees;
176 MonoBasicBlock *in_bb;
181 * Instruction metadata
182 * This is the same as ins_info, but LREG != IREG.
190 #define MINI_OP(a,b,dest,src1,src2) dest, src1, src2, ' ',
191 #define MINI_OP3(a,b,dest,src1,src2,src3) dest, src1, src2, src3,
198 /* keep in sync with the enum in mini.h */
201 #include "mini-ops.h"
206 #if SIZEOF_VOID_P == 4
207 #define GET_LONG_IMM(ins) (((guint64)(ins)->inst_ms_word << 32) | (guint64)(guint32)(ins)->inst_ls_word)
209 #define GET_LONG_IMM(ins) ((ins)->inst_imm)
212 #define LLVM_INS_INFO(opcode) (&llvm_ins_info [((opcode) - OP_START - 1) * 4])
215 #define TRACE_FAILURE(msg) do { printf ("%s\n", msg); } while (0)
217 #define TRACE_FAILURE(msg)
221 #define IS_TARGET_X86 1
223 #define IS_TARGET_X86 0
227 #define IS_TARGET_AMD64 1
229 #define IS_TARGET_AMD64 0
232 #define ctx_ok(ctx) (!(ctx)->cfg->disable_llvm)
234 static LLVMIntPredicate cond_to_llvm_cond [] = {
247 static LLVMRealPredicate fpcond_to_llvm_cond [] = {
260 static MonoNativeTlsKey current_cfg_tls_id;
262 static MonoLLVMModule aot_module;
264 static GHashTable *intrins_id_to_name;
265 static GHashTable *intrins_name_to_id;
267 static void init_jit_module (MonoDomain *domain);
269 static void emit_dbg_loc (EmitContext *ctx, LLVMBuilderRef builder, const unsigned char *cil_code);
270 static LLVMValueRef emit_dbg_subprogram (EmitContext *ctx, MonoCompile *cfg, LLVMValueRef method, const char *name);
271 static void emit_dbg_info (MonoLLVMModule *module, const char *filename, const char *cu_name);
272 static void emit_cond_system_exception (EmitContext *ctx, MonoBasicBlock *bb, const char *exc_type, LLVMValueRef cmp);
273 static LLVMValueRef get_intrinsic (EmitContext *ctx, const char *name);
274 static void decode_llvm_eh_info (EmitContext *ctx, gpointer eh_frame);
277 set_failure (EmitContext *ctx, const char *message)
279 TRACE_FAILURE (reason);
280 ctx->cfg->exception_message = g_strdup (message);
281 ctx->cfg->disable_llvm = TRUE;
287 * The LLVM type with width == sizeof (gpointer)
292 return sizeof (gpointer) == 8 ? LLVMInt64Type () : LLVMInt32Type ();
298 return sizeof (gpointer) == 8 ? LLVMPointerType (LLVMInt64Type (), 0) : LLVMPointerType (LLVMInt32Type (), 0);
304 return sizeof (gpointer) == 8 ? LLVMPointerType (LLVMInt64Type (), 0) : LLVMPointerType (LLVMInt32Type (), 0);
310 * Return the size of the LLVM representation of the vtype T.
313 get_vtype_size (MonoType *t)
317 size = mono_class_value_size (mono_class_from_mono_type (t), NULL);
319 /* LLVMArgAsIArgs depends on this since it stores whole words */
320 while (size < 2 * sizeof (gpointer) && mono_is_power_of_two (size) == -1)
327 * simd_class_to_llvm_type:
329 * Return the LLVM type corresponding to the Mono.SIMD class KLASS
332 simd_class_to_llvm_type (EmitContext *ctx, MonoClass *klass)
334 if (!strcmp (klass->name, "Vector2d")) {
335 return LLVMVectorType (LLVMDoubleType (), 2);
336 } else if (!strcmp (klass->name, "Vector2l")) {
337 return LLVMVectorType (LLVMInt64Type (), 2);
338 } else if (!strcmp (klass->name, "Vector2ul")) {
339 return LLVMVectorType (LLVMInt64Type (), 2);
340 } else if (!strcmp (klass->name, "Vector4i")) {
341 return LLVMVectorType (LLVMInt32Type (), 4);
342 } else if (!strcmp (klass->name, "Vector4ui")) {
343 return LLVMVectorType (LLVMInt32Type (), 4);
344 } else if (!strcmp (klass->name, "Vector4f")) {
345 return LLVMVectorType (LLVMFloatType (), 4);
346 } else if (!strcmp (klass->name, "Vector8s")) {
347 return LLVMVectorType (LLVMInt16Type (), 8);
348 } else if (!strcmp (klass->name, "Vector8us")) {
349 return LLVMVectorType (LLVMInt16Type (), 8);
350 } else if (!strcmp (klass->name, "Vector16sb")) {
351 return LLVMVectorType (LLVMInt8Type (), 16);
352 } else if (!strcmp (klass->name, "Vector16b")) {
353 return LLVMVectorType (LLVMInt8Type (), 16);
355 printf ("%s\n", klass->name);
361 /* Return the 128 bit SIMD type corresponding to the mono type TYPE */
362 static inline G_GNUC_UNUSED LLVMTypeRef
363 type_to_simd_type (int type)
367 return LLVMVectorType (LLVMInt8Type (), 16);
369 return LLVMVectorType (LLVMInt16Type (), 8);
371 return LLVMVectorType (LLVMInt32Type (), 4);
373 return LLVMVectorType (LLVMInt64Type (), 2);
375 return LLVMVectorType (LLVMDoubleType (), 2);
377 return LLVMVectorType (LLVMFloatType (), 4);
379 g_assert_not_reached ();
385 create_llvm_type_for_type (MonoLLVMModule *module, MonoClass *klass)
387 int i, size, nfields, esize;
388 LLVMTypeRef *eltypes;
393 t = &klass->byval_arg;
395 if (mini_type_is_hfa (t, &nfields, &esize)) {
397 * This is needed on arm64 where HFAs are returned in
401 eltypes = g_new (LLVMTypeRef, size);
402 for (i = 0; i < size; ++i)
403 eltypes [i] = esize == 4 ? LLVMFloatType () : LLVMDoubleType ();
405 size = get_vtype_size (t);
407 eltypes = g_new (LLVMTypeRef, size);
408 for (i = 0; i < size; ++i)
409 eltypes [i] = LLVMInt8Type ();
412 name = mono_type_full_name (&klass->byval_arg);
413 ltype = LLVMStructCreateNamed (module->context, name);
414 LLVMStructSetBody (ltype, eltypes, size, FALSE);
424 * Return the LLVM type corresponding to T.
427 type_to_llvm_type (EmitContext *ctx, MonoType *t)
429 t = mini_get_underlying_type (t);
433 return LLVMVoidType ();
435 return LLVMInt8Type ();
437 return LLVMInt16Type ();
439 return LLVMInt32Type ();
441 return LLVMInt8Type ();
443 return LLVMInt16Type ();
445 return LLVMInt32Type ();
446 case MONO_TYPE_BOOLEAN:
447 return LLVMInt8Type ();
450 return LLVMInt64Type ();
452 return LLVMInt16Type ();
454 return LLVMFloatType ();
456 return LLVMDoubleType ();
459 return IntPtrType ();
460 case MONO_TYPE_OBJECT:
461 case MONO_TYPE_CLASS:
462 case MONO_TYPE_ARRAY:
463 case MONO_TYPE_SZARRAY:
464 case MONO_TYPE_STRING:
466 return ObjRefType ();
469 /* Because of generic sharing */
470 return ObjRefType ();
471 case MONO_TYPE_GENERICINST:
472 if (!mono_type_generic_inst_is_valuetype (t))
473 return ObjRefType ();
475 case MONO_TYPE_VALUETYPE:
476 case MONO_TYPE_TYPEDBYREF: {
480 klass = mono_class_from_mono_type (t);
482 if (MONO_CLASS_IS_SIMD (ctx->cfg, klass))
483 return simd_class_to_llvm_type (ctx, klass);
486 return type_to_llvm_type (ctx, mono_class_enum_basetype (klass));
488 ltype = (LLVMTypeRef)g_hash_table_lookup (ctx->module->llvm_types, klass);
490 ltype = create_llvm_type_for_type (ctx->module, klass);
491 g_hash_table_insert (ctx->module->llvm_types, klass, ltype);
497 printf ("X: %d\n", t->type);
498 ctx->cfg->exception_message = g_strdup_printf ("type %s", mono_type_full_name (t));
499 ctx->cfg->disable_llvm = TRUE;
507 * Return whenever T is an unsigned int type.
510 type_is_unsigned (EmitContext *ctx, MonoType *t)
512 t = mini_get_underlying_type (t);
528 * type_to_llvm_arg_type:
530 * Same as type_to_llvm_type, but treat i8/i16 as i32.
533 type_to_llvm_arg_type (EmitContext *ctx, MonoType *t)
535 LLVMTypeRef ptype = type_to_llvm_type (ctx, t);
537 if (ctx->cfg->llvm_only)
541 * This works on all abis except arm64/ios which passes multiple
542 * arguments in one stack slot.
545 if (ptype == LLVMInt8Type () || ptype == LLVMInt16Type ()) {
547 * LLVM generates code which only sets the lower bits, while JITted
548 * code expects all the bits to be set.
550 ptype = LLVMInt32Type ();
558 * llvm_type_to_stack_type:
560 * Return the LLVM type which needs to be used when a value of type TYPE is pushed
563 static G_GNUC_UNUSED LLVMTypeRef
564 llvm_type_to_stack_type (MonoCompile *cfg, LLVMTypeRef type)
568 if (type == LLVMInt8Type ())
569 return LLVMInt32Type ();
570 else if (type == LLVMInt16Type ())
571 return LLVMInt32Type ();
572 else if (!cfg->r4fp && type == LLVMFloatType ())
573 return LLVMDoubleType ();
579 * regtype_to_llvm_type:
581 * Return the LLVM type corresponding to the regtype C used in instruction
585 regtype_to_llvm_type (char c)
589 return LLVMInt32Type ();
591 return LLVMInt64Type ();
593 return LLVMDoubleType ();
602 * Return the LLVM type corresponding to the unary/binary opcode OPCODE.
605 op_to_llvm_type (int opcode)
610 return LLVMInt8Type ();
613 return LLVMInt8Type ();
616 return LLVMInt16Type ();
619 return LLVMInt16Type ();
622 return LLVMInt32Type ();
625 return LLVMInt32Type ();
627 return LLVMInt64Type ();
629 return LLVMFloatType ();
631 return LLVMDoubleType ();
633 return LLVMInt64Type ();
635 return LLVMInt32Type ();
637 return LLVMInt64Type ();
642 return LLVMInt8Type ();
647 return LLVMInt16Type ();
649 return LLVMInt32Type ();
652 return sizeof (gpointer) == 8 ? LLVMInt64Type () : LLVMInt32Type ();
659 return LLVMInt32Type ();
666 return LLVMInt64Type ();
668 printf ("%s\n", mono_inst_name (opcode));
669 g_assert_not_reached ();
674 #define CLAUSE_START(clause) ((clause)->try_offset)
675 #define CLAUSE_END(clause) (((clause))->try_offset + ((clause))->try_len)
678 * load_store_to_llvm_type:
680 * Return the size/sign/zero extension corresponding to the load/store opcode
684 load_store_to_llvm_type (int opcode, int *size, gboolean *sext, gboolean *zext)
690 case OP_LOADI1_MEMBASE:
691 case OP_STOREI1_MEMBASE_REG:
692 case OP_STOREI1_MEMBASE_IMM:
693 case OP_ATOMIC_LOAD_I1:
694 case OP_ATOMIC_STORE_I1:
697 return LLVMInt8Type ();
698 case OP_LOADU1_MEMBASE:
700 case OP_ATOMIC_LOAD_U1:
701 case OP_ATOMIC_STORE_U1:
704 return LLVMInt8Type ();
705 case OP_LOADI2_MEMBASE:
706 case OP_STOREI2_MEMBASE_REG:
707 case OP_STOREI2_MEMBASE_IMM:
708 case OP_ATOMIC_LOAD_I2:
709 case OP_ATOMIC_STORE_I2:
712 return LLVMInt16Type ();
713 case OP_LOADU2_MEMBASE:
715 case OP_ATOMIC_LOAD_U2:
716 case OP_ATOMIC_STORE_U2:
719 return LLVMInt16Type ();
720 case OP_LOADI4_MEMBASE:
721 case OP_LOADU4_MEMBASE:
724 case OP_STOREI4_MEMBASE_REG:
725 case OP_STOREI4_MEMBASE_IMM:
726 case OP_ATOMIC_LOAD_I4:
727 case OP_ATOMIC_STORE_I4:
728 case OP_ATOMIC_LOAD_U4:
729 case OP_ATOMIC_STORE_U4:
731 return LLVMInt32Type ();
732 case OP_LOADI8_MEMBASE:
734 case OP_STOREI8_MEMBASE_REG:
735 case OP_STOREI8_MEMBASE_IMM:
736 case OP_ATOMIC_LOAD_I8:
737 case OP_ATOMIC_STORE_I8:
738 case OP_ATOMIC_LOAD_U8:
739 case OP_ATOMIC_STORE_U8:
741 return LLVMInt64Type ();
742 case OP_LOADR4_MEMBASE:
743 case OP_STORER4_MEMBASE_REG:
744 case OP_ATOMIC_LOAD_R4:
745 case OP_ATOMIC_STORE_R4:
747 return LLVMFloatType ();
748 case OP_LOADR8_MEMBASE:
749 case OP_STORER8_MEMBASE_REG:
750 case OP_ATOMIC_LOAD_R8:
751 case OP_ATOMIC_STORE_R8:
753 return LLVMDoubleType ();
754 case OP_LOAD_MEMBASE:
756 case OP_STORE_MEMBASE_REG:
757 case OP_STORE_MEMBASE_IMM:
758 *size = sizeof (gpointer);
759 return IntPtrType ();
761 g_assert_not_reached ();
769 * Return the LLVM intrinsics corresponding to the overflow opcode OPCODE.
772 ovf_op_to_intrins (int opcode)
776 return "llvm.sadd.with.overflow.i32";
778 return "llvm.uadd.with.overflow.i32";
780 return "llvm.ssub.with.overflow.i32";
782 return "llvm.usub.with.overflow.i32";
784 return "llvm.smul.with.overflow.i32";
786 return "llvm.umul.with.overflow.i32";
788 return "llvm.sadd.with.overflow.i64";
790 return "llvm.uadd.with.overflow.i64";
792 return "llvm.ssub.with.overflow.i64";
794 return "llvm.usub.with.overflow.i64";
796 return "llvm.smul.with.overflow.i64";
798 return "llvm.umul.with.overflow.i64";
800 g_assert_not_reached ();
806 simd_op_to_intrins (int opcode)
809 #if defined(TARGET_X86) || defined(TARGET_AMD64)
811 return "llvm.x86.sse2.min.pd";
813 return "llvm.x86.sse.min.ps";
815 return "llvm.x86.sse41.pminud";
817 return "llvm.x86.sse41.pminuw";
819 return "llvm.x86.sse2.pminu.b";
821 return "llvm.x86.sse2.pmins.w";
823 return "llvm.x86.sse2.max.pd";
825 return "llvm.x86.sse.max.ps";
827 return "llvm.x86.sse3.hadd.pd";
829 return "llvm.x86.sse3.hadd.ps";
831 return "llvm.x86.sse3.hsub.pd";
833 return "llvm.x86.sse3.hsub.ps";
835 return "llvm.x86.sse41.pmaxud";
837 return "llvm.x86.sse41.pmaxuw";
839 return "llvm.x86.sse2.pmaxu.b";
841 return "llvm.x86.sse3.addsub.ps";
843 return "llvm.x86.sse3.addsub.pd";
844 case OP_EXTRACT_MASK:
845 return "llvm.x86.sse2.pmovmskb.128";
848 return "llvm.x86.sse2.psrli.w";
851 return "llvm.x86.sse2.psrli.d";
854 return "llvm.x86.sse2.psrli.q";
857 return "llvm.x86.sse2.pslli.w";
860 return "llvm.x86.sse2.pslli.d";
863 return "llvm.x86.sse2.pslli.q";
866 return "llvm.x86.sse2.psrai.w";
869 return "llvm.x86.sse2.psrai.d";
871 return "llvm.x86.sse2.padds.b";
873 return "llvm.x86.sse2.padds.w";
875 return "llvm.x86.sse2.psubs.b";
877 return "llvm.x86.sse2.psubs.w";
878 case OP_PADDB_SAT_UN:
879 return "llvm.x86.sse2.paddus.b";
880 case OP_PADDW_SAT_UN:
881 return "llvm.x86.sse2.paddus.w";
882 case OP_PSUBB_SAT_UN:
883 return "llvm.x86.sse2.psubus.b";
884 case OP_PSUBW_SAT_UN:
885 return "llvm.x86.sse2.psubus.w";
887 return "llvm.x86.sse2.pavg.b";
889 return "llvm.x86.sse2.pavg.w";
891 return "llvm.x86.sse.sqrt.ps";
893 return "llvm.x86.sse2.sqrt.pd";
895 return "llvm.x86.sse.rsqrt.ps";
897 return "llvm.x86.sse.rcp.ps";
899 return "llvm.x86.sse2.cvtdq2pd";
901 return "llvm.x86.sse2.cvtdq2ps";
903 return "llvm.x86.sse2.cvtpd2dq";
905 return "llvm.x86.sse2.cvtps2dq";
907 return "llvm.x86.sse2.cvtpd2ps";
909 return "llvm.x86.sse2.cvtps2pd";
911 return "llvm.x86.sse2.cvttpd2dq";
913 return "llvm.x86.sse2.cvttps2dq";
915 return "llvm.x86.sse.cmp.ps";
917 return "llvm.x86.sse2.cmp.pd";
919 return "llvm.x86.sse2.packsswb.128";
921 return "llvm.x86.sse2.packssdw.128";
923 return "llvm.x86.sse2.packuswb.128";
925 return "llvm.x86.sse41.packusdw";
927 return "llvm.x86.sse2.pmulh.w";
928 case OP_PMULW_HIGH_UN:
929 return "llvm.x86.sse2.pmulhu.w";
932 g_assert_not_reached ();
938 simd_op_to_llvm_type (int opcode)
940 #if defined(TARGET_X86) || defined(TARGET_AMD64)
944 return type_to_simd_type (MONO_TYPE_R8);
947 return type_to_simd_type (MONO_TYPE_I8);
950 return type_to_simd_type (MONO_TYPE_I4);
955 return type_to_simd_type (MONO_TYPE_I2);
959 return type_to_simd_type (MONO_TYPE_I1);
961 return type_to_simd_type (MONO_TYPE_R4);
964 return type_to_simd_type (MONO_TYPE_I4);
968 return type_to_simd_type (MONO_TYPE_R8);
972 return type_to_simd_type (MONO_TYPE_R4);
973 case OP_EXTRACT_MASK:
974 return type_to_simd_type (MONO_TYPE_I1);
980 return type_to_simd_type (MONO_TYPE_R4);
983 return type_to_simd_type (MONO_TYPE_R8);
985 g_assert_not_reached ();
996 * Return the LLVM basic block corresponding to BB.
998 static LLVMBasicBlockRef
999 get_bb (EmitContext *ctx, MonoBasicBlock *bb)
1001 char bb_name_buf [128];
1004 if (ctx->bblocks [bb->block_num].bblock == NULL) {
1005 if (bb->flags & BB_EXCEPTION_HANDLER) {
1006 int clause_index = (mono_get_block_region_notry (ctx->cfg, bb->region) >> 8) - 1;
1007 sprintf (bb_name_buf, "EH_CLAUSE%d_BB%d", clause_index, bb->block_num);
1008 bb_name = bb_name_buf;
1009 } else if (bb->block_num < 256) {
1010 if (!ctx->module->bb_names) {
1011 ctx->module->bb_names_len = 256;
1012 ctx->module->bb_names = g_new0 (char*, ctx->module->bb_names_len);
1014 if (!ctx->module->bb_names [bb->block_num]) {
1017 n = g_strdup_printf ("BB%d", bb->block_num);
1018 mono_memory_barrier ();
1019 ctx->module->bb_names [bb->block_num] = n;
1021 bb_name = ctx->module->bb_names [bb->block_num];
1023 sprintf (bb_name_buf, "BB%d", bb->block_num);
1024 bb_name = bb_name_buf;
1027 ctx->bblocks [bb->block_num].bblock = LLVMAppendBasicBlock (ctx->lmethod, bb_name);
1028 ctx->bblocks [bb->block_num].end_bblock = ctx->bblocks [bb->block_num].bblock;
1031 return ctx->bblocks [bb->block_num].bblock;
1037 * Return the last LLVM bblock corresponding to BB.
1038 * This might not be equal to the bb returned by get_bb () since we need to generate
1039 * multiple LLVM bblocks for a mono bblock to handle throwing exceptions.
1041 static LLVMBasicBlockRef
1042 get_end_bb (EmitContext *ctx, MonoBasicBlock *bb)
1045 return ctx->bblocks [bb->block_num].end_bblock;
1048 static LLVMBasicBlockRef
1049 gen_bb (EmitContext *ctx, const char *prefix)
1053 sprintf (bb_name, "%s%d", prefix, ++ ctx->ex_index);
1054 return LLVMAppendBasicBlock (ctx->lmethod, bb_name);
1060 * Return the target of the patch identified by TYPE and TARGET.
1063 resolve_patch (MonoCompile *cfg, MonoJumpInfoType type, gconstpointer target)
1069 memset (&ji, 0, sizeof (ji));
1071 ji.data.target = target;
1073 res = mono_resolve_patch_target (cfg->method, cfg->domain, NULL, &ji, FALSE, &error);
1074 mono_error_assert_ok (&error);
1082 * Emit code to convert the LLVM value V to DTYPE.
1085 convert_full (EmitContext *ctx, LLVMValueRef v, LLVMTypeRef dtype, gboolean is_unsigned)
1087 LLVMTypeRef stype = LLVMTypeOf (v);
1089 if (stype != dtype) {
1090 gboolean ext = FALSE;
1093 if (dtype == LLVMInt64Type () && (stype == LLVMInt32Type () || stype == LLVMInt16Type () || stype == LLVMInt8Type ()))
1095 else if (dtype == LLVMInt32Type () && (stype == LLVMInt16Type () || stype == LLVMInt8Type ()))
1097 else if (dtype == LLVMInt16Type () && (stype == LLVMInt8Type ()))
1101 return is_unsigned ? LLVMBuildZExt (ctx->builder, v, dtype, "") : LLVMBuildSExt (ctx->builder, v, dtype, "");
1103 if (dtype == LLVMDoubleType () && stype == LLVMFloatType ())
1104 return LLVMBuildFPExt (ctx->builder, v, dtype, "");
1107 if (stype == LLVMInt64Type () && (dtype == LLVMInt32Type () || dtype == LLVMInt16Type () || dtype == LLVMInt8Type ()))
1108 return LLVMBuildTrunc (ctx->builder, v, dtype, "");
1109 if (stype == LLVMInt32Type () && (dtype == LLVMInt16Type () || dtype == LLVMInt8Type ()))
1110 return LLVMBuildTrunc (ctx->builder, v, dtype, "");
1111 if (stype == LLVMInt16Type () && dtype == LLVMInt8Type ())
1112 return LLVMBuildTrunc (ctx->builder, v, dtype, "");
1113 if (stype == LLVMDoubleType () && dtype == LLVMFloatType ())
1114 return LLVMBuildFPTrunc (ctx->builder, v, dtype, "");
1116 if (LLVMGetTypeKind (stype) == LLVMPointerTypeKind && LLVMGetTypeKind (dtype) == LLVMPointerTypeKind)
1117 return LLVMBuildBitCast (ctx->builder, v, dtype, "");
1118 if (LLVMGetTypeKind (dtype) == LLVMPointerTypeKind)
1119 return LLVMBuildIntToPtr (ctx->builder, v, dtype, "");
1120 if (LLVMGetTypeKind (stype) == LLVMPointerTypeKind)
1121 return LLVMBuildPtrToInt (ctx->builder, v, dtype, "");
1123 if (mono_arch_is_soft_float ()) {
1124 if (stype == LLVMInt32Type () && dtype == LLVMFloatType ())
1125 return LLVMBuildBitCast (ctx->builder, v, dtype, "");
1126 if (stype == LLVMInt32Type () && dtype == LLVMDoubleType ())
1127 return LLVMBuildBitCast (ctx->builder, LLVMBuildZExt (ctx->builder, v, LLVMInt64Type (), ""), dtype, "");
1130 if (LLVMGetTypeKind (stype) == LLVMVectorTypeKind && LLVMGetTypeKind (dtype) == LLVMVectorTypeKind)
1131 return LLVMBuildBitCast (ctx->builder, v, dtype, "");
1134 LLVMDumpValue (LLVMConstNull (dtype));
1135 g_assert_not_reached ();
1143 convert (EmitContext *ctx, LLVMValueRef v, LLVMTypeRef dtype)
1145 return convert_full (ctx, v, dtype, FALSE);
1149 * emit_volatile_load:
1151 * If vreg is volatile, emit a load from its address.
1154 emit_volatile_load (EmitContext *ctx, int vreg)
1158 LLVMValueRef v = LLVMBuildLoad (ctx->builder, ctx->addresses [vreg], "");
1159 t = ctx->vreg_cli_types [vreg];
1160 if (t && !t->byref) {
1162 * Might have to zero extend since llvm doesn't have
1165 if (t->type == MONO_TYPE_U1 || t->type == MONO_TYPE_U2 || t->type == MONO_TYPE_CHAR || t->type == MONO_TYPE_BOOLEAN)
1166 v = LLVMBuildZExt (ctx->builder, v, LLVMInt32Type (), "");
1167 else if (t->type == MONO_TYPE_I1 || t->type == MONO_TYPE_I2)
1168 v = LLVMBuildSExt (ctx->builder, v, LLVMInt32Type (), "");
1169 else if (t->type == MONO_TYPE_U8)
1170 v = LLVMBuildZExt (ctx->builder, v, LLVMInt64Type (), "");
1177 * emit_volatile_store:
1179 * If VREG is volatile, emit a store from its value to its address.
1182 emit_volatile_store (EmitContext *ctx, int vreg)
1184 MonoInst *var = get_vreg_to_inst (ctx->cfg, vreg);
1186 if (var && var->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT)) {
1187 g_assert (ctx->addresses [vreg]);
1188 LLVMBuildStore (ctx->builder, convert (ctx, ctx->values [vreg], type_to_llvm_type (ctx, var->inst_vtype)), ctx->addresses [vreg]);
1193 sig_to_llvm_sig_no_cinfo (EmitContext *ctx, MonoMethodSignature *sig)
1195 LLVMTypeRef ret_type;
1196 LLVMTypeRef *param_types = NULL;
1201 rtype = mini_get_underlying_type (sig->ret);
1202 ret_type = type_to_llvm_type (ctx, rtype);
1206 param_types = g_new0 (LLVMTypeRef, (sig->param_count * 8) + 3);
1210 param_types [pindex ++] = ThisType ();
1211 for (i = 0; i < sig->param_count; ++i)
1212 param_types [pindex ++] = type_to_llvm_arg_type (ctx, sig->params [i]);
1214 if (!ctx_ok (ctx)) {
1215 g_free (param_types);
1219 res = LLVMFunctionType (ret_type, param_types, pindex, FALSE);
1220 g_free (param_types);
1226 * sig_to_llvm_sig_full:
1228 * Return the LLVM signature corresponding to the mono signature SIG using the
1229 * calling convention information in CINFO. Fill out the parameter mapping information in CINFO.
1232 sig_to_llvm_sig_full (EmitContext *ctx, MonoMethodSignature *sig, LLVMCallInfo *cinfo)
1234 LLVMTypeRef ret_type;
1235 LLVMTypeRef *param_types = NULL;
1237 int i, j, pindex, vret_arg_pindex = 0;
1238 gboolean vretaddr = FALSE;
1242 return sig_to_llvm_sig_no_cinfo (ctx, sig);
1244 rtype = mini_get_underlying_type (sig->ret);
1245 ret_type = type_to_llvm_type (ctx, rtype);
1249 switch (cinfo->ret.storage) {
1250 case LLVMArgVtypeInReg:
1251 /* LLVM models this by returning an aggregate value */
1252 if (cinfo->ret.pair_storage [0] == LLVMArgInIReg && cinfo->ret.pair_storage [1] == LLVMArgNone) {
1253 LLVMTypeRef members [2];
1255 members [0] = IntPtrType ();
1256 ret_type = LLVMStructType (members, 1, FALSE);
1257 } else if (cinfo->ret.pair_storage [0] == LLVMArgNone && cinfo->ret.pair_storage [1] == LLVMArgNone) {
1259 ret_type = LLVMVoidType ();
1260 } else if (cinfo->ret.pair_storage [0] == LLVMArgInIReg && cinfo->ret.pair_storage [1] == LLVMArgInIReg) {
1261 LLVMTypeRef members [2];
1263 members [0] = IntPtrType ();
1264 members [1] = IntPtrType ();
1265 ret_type = LLVMStructType (members, 2, FALSE);
1267 g_assert_not_reached ();
1270 case LLVMArgVtypeByVal:
1271 /* Vtype returned normally by val */
1273 case LLVMArgVtypeAsScalar: {
1274 int size = mono_class_value_size (mono_class_from_mono_type (rtype), NULL);
1275 /* LLVM models this by returning an int */
1276 if (size < SIZEOF_VOID_P) {
1277 g_assert (cinfo->ret.nslots == 1);
1278 ret_type = LLVMIntType (size * 8);
1280 g_assert (cinfo->ret.nslots == 1 || cinfo->ret.nslots == 2);
1281 ret_type = LLVMIntType (cinfo->ret.nslots * sizeof (mgreg_t) * 8);
1285 case LLVMArgFpStruct: {
1286 /* Vtype returned as a fp struct */
1287 LLVMTypeRef members [16];
1289 /* Have to create our own structure since we don't map fp structures to LLVM fp structures yet */
1290 for (i = 0; i < cinfo->ret.nslots; ++i)
1291 members [i] = cinfo->ret.esize == 8 ? LLVMDoubleType () : LLVMFloatType ();
1292 ret_type = LLVMStructType (members, cinfo->ret.nslots, FALSE);
1295 case LLVMArgVtypeByRef:
1296 /* Vtype returned using a hidden argument */
1297 ret_type = LLVMVoidType ();
1299 case LLVMArgVtypeRetAddr:
1300 case LLVMArgGsharedvtFixed:
1301 case LLVMArgGsharedvtFixedVtype:
1302 case LLVMArgGsharedvtVariable:
1304 ret_type = LLVMVoidType ();
1310 param_types = g_new0 (LLVMTypeRef, (sig->param_count * 8) + 3);
1312 if (cinfo->ret.storage == LLVMArgVtypeByRef) {
1314 * Has to be the first argument because of the sret argument attribute
1315 * FIXME: This might conflict with passing 'this' as the first argument, but
1316 * this is only used on arm64 which has a dedicated struct return register.
1318 cinfo->vret_arg_pindex = pindex;
1319 param_types [pindex] = type_to_llvm_arg_type (ctx, sig->ret);
1320 if (!ctx_ok (ctx)) {
1321 g_free (param_types);
1324 param_types [pindex] = LLVMPointerType (param_types [pindex], 0);
1327 if (!ctx->llvm_only && cinfo->rgctx_arg) {
1328 cinfo->rgctx_arg_pindex = pindex;
1329 param_types [pindex] = ctx->module->ptr_type;
1332 if (cinfo->imt_arg) {
1333 cinfo->imt_arg_pindex = pindex;
1334 param_types [pindex] = ctx->module->ptr_type;
1338 /* Compute the index in the LLVM signature where the vret arg needs to be passed */
1339 vret_arg_pindex = pindex;
1340 if (cinfo->vret_arg_index == 1) {
1341 /* Add the slots consumed by the first argument */
1342 LLVMArgInfo *ainfo = &cinfo->args [0];
1343 switch (ainfo->storage) {
1344 case LLVMArgVtypeInReg:
1345 for (j = 0; j < 2; ++j) {
1346 if (ainfo->pair_storage [j] == LLVMArgInIReg)
1355 cinfo->vret_arg_pindex = vret_arg_pindex;
1358 if (vretaddr && vret_arg_pindex == pindex)
1359 param_types [pindex ++] = IntPtrType ();
1361 cinfo->this_arg_pindex = pindex;
1362 param_types [pindex ++] = ThisType ();
1363 cinfo->args [0].pindex = cinfo->this_arg_pindex;
1365 if (vretaddr && vret_arg_pindex == pindex)
1366 param_types [pindex ++] = IntPtrType ();
1367 for (i = 0; i < sig->param_count; ++i) {
1368 LLVMArgInfo *ainfo = &cinfo->args [i + sig->hasthis];
1370 if (vretaddr && vret_arg_pindex == pindex)
1371 param_types [pindex ++] = IntPtrType ();
1372 ainfo->pindex = pindex;
1374 switch (ainfo->storage) {
1375 case LLVMArgVtypeInReg:
1376 for (j = 0; j < 2; ++j) {
1377 switch (ainfo->pair_storage [j]) {
1379 param_types [pindex ++] = LLVMIntType (sizeof (gpointer) * 8);
1384 g_assert_not_reached ();
1388 case LLVMArgVtypeByVal:
1389 param_types [pindex] = type_to_llvm_arg_type (ctx, ainfo->type);
1392 param_types [pindex] = LLVMPointerType (param_types [pindex], 0);
1395 case LLVMArgAsIArgs:
1396 param_types [pindex] = LLVMArrayType (IntPtrType (), ainfo->nslots);
1399 case LLVMArgVtypeByRef:
1400 param_types [pindex] = type_to_llvm_arg_type (ctx, ainfo->type);
1403 param_types [pindex] = LLVMPointerType (param_types [pindex], 0);
1406 case LLVMArgAsFpArgs: {
1409 /* Emit dummy fp arguments if needed so the rest is passed on the stack */
1410 for (j = 0; j < ainfo->ndummy_fpargs; ++j)
1411 param_types [pindex ++] = LLVMDoubleType ();
1412 for (j = 0; j < ainfo->nslots; ++j)
1413 param_types [pindex ++] = ainfo->esize == 8 ? LLVMDoubleType () : LLVMFloatType ();
1416 case LLVMArgVtypeAsScalar:
1417 g_assert_not_reached ();
1419 case LLVMArgGsharedvtFixed:
1420 case LLVMArgGsharedvtFixedVtype:
1421 param_types [pindex ++] = LLVMPointerType (type_to_llvm_arg_type (ctx, ainfo->type), 0);
1423 case LLVMArgGsharedvtVariable:
1424 param_types [pindex ++] = LLVMPointerType (IntPtrType (), 0);
1427 param_types [pindex ++] = type_to_llvm_arg_type (ctx, ainfo->type);
1431 if (!ctx_ok (ctx)) {
1432 g_free (param_types);
1435 if (vretaddr && vret_arg_pindex == pindex)
1436 param_types [pindex ++] = IntPtrType ();
1437 if (ctx->llvm_only && cinfo->rgctx_arg) {
1438 /* Pass the rgctx as the last argument */
1439 cinfo->rgctx_arg_pindex = pindex;
1440 param_types [pindex] = ctx->module->ptr_type;
1444 res = LLVMFunctionType (ret_type, param_types, pindex, FALSE);
1445 g_free (param_types);
1451 sig_to_llvm_sig (EmitContext *ctx, MonoMethodSignature *sig)
1453 return sig_to_llvm_sig_full (ctx, sig, NULL);
1457 * LLVMFunctionType1:
1459 * Create an LLVM function type from the arguments.
1461 static G_GNUC_UNUSED LLVMTypeRef
1462 LLVMFunctionType0 (LLVMTypeRef ReturnType,
1465 return LLVMFunctionType (ReturnType, NULL, 0, IsVarArg);
1469 * LLVMFunctionType1:
1471 * Create an LLVM function type from the arguments.
1473 static G_GNUC_UNUSED LLVMTypeRef
1474 LLVMFunctionType1 (LLVMTypeRef ReturnType,
1475 LLVMTypeRef ParamType1,
1478 LLVMTypeRef param_types [1];
1480 param_types [0] = ParamType1;
1482 return LLVMFunctionType (ReturnType, param_types, 1, IsVarArg);
1486 * LLVMFunctionType2:
1488 * Create an LLVM function type from the arguments.
1490 static G_GNUC_UNUSED LLVMTypeRef
1491 LLVMFunctionType2 (LLVMTypeRef ReturnType,
1492 LLVMTypeRef ParamType1,
1493 LLVMTypeRef ParamType2,
1496 LLVMTypeRef param_types [2];
1498 param_types [0] = ParamType1;
1499 param_types [1] = ParamType2;
1501 return LLVMFunctionType (ReturnType, param_types, 2, IsVarArg);
1505 * LLVMFunctionType3:
1507 * Create an LLVM function type from the arguments.
1509 static G_GNUC_UNUSED LLVMTypeRef
1510 LLVMFunctionType3 (LLVMTypeRef ReturnType,
1511 LLVMTypeRef ParamType1,
1512 LLVMTypeRef ParamType2,
1513 LLVMTypeRef ParamType3,
1516 LLVMTypeRef param_types [3];
1518 param_types [0] = ParamType1;
1519 param_types [1] = ParamType2;
1520 param_types [2] = ParamType3;
1522 return LLVMFunctionType (ReturnType, param_types, 3, IsVarArg);
1525 static G_GNUC_UNUSED LLVMTypeRef
1526 LLVMFunctionType5 (LLVMTypeRef ReturnType,
1527 LLVMTypeRef ParamType1,
1528 LLVMTypeRef ParamType2,
1529 LLVMTypeRef ParamType3,
1530 LLVMTypeRef ParamType4,
1531 LLVMTypeRef ParamType5,
1534 LLVMTypeRef param_types [5];
1536 param_types [0] = ParamType1;
1537 param_types [1] = ParamType2;
1538 param_types [2] = ParamType3;
1539 param_types [3] = ParamType4;
1540 param_types [4] = ParamType5;
1542 return LLVMFunctionType (ReturnType, param_types, 5, IsVarArg);
1548 * Create an LLVM builder and remember it so it can be freed later.
1550 static LLVMBuilderRef
1551 create_builder (EmitContext *ctx)
1553 LLVMBuilderRef builder = LLVMCreateBuilder ();
1555 ctx->builders = g_slist_prepend_mempool (ctx->cfg->mempool, ctx->builders, builder);
1561 get_aotconst_name (MonoJumpInfoType type, gconstpointer data, int got_offset)
1566 case MONO_PATCH_INFO_INTERNAL_METHOD:
1567 name = g_strdup_printf ("jit_icall_%s", data);
1569 case MONO_PATCH_INFO_RGCTX_SLOT_INDEX: {
1570 MonoJumpInfoRgctxEntry *entry = (MonoJumpInfoRgctxEntry*)data;
1571 name = g_strdup_printf ("RGCTX_SLOT_INDEX_%s", mono_rgctx_info_type_to_str (entry->info_type));
1575 name = g_strdup_printf ("%s_%d", mono_ji_type_to_string (type), got_offset);
1583 get_aotconst_typed (EmitContext *ctx, MonoJumpInfoType type, gconstpointer data, LLVMTypeRef llvm_type)
1587 LLVMValueRef indexes [2];
1589 LLVMValueRef got_entry_addr, load;
1590 LLVMBuilderRef builder = ctx->builder;
1595 ji = g_new0 (MonoJumpInfo, 1);
1597 ji->data.target = data;
1599 ji = mono_aot_patch_info_dup (ji);
1601 ji->next = cfg->patch_info;
1602 cfg->patch_info = ji;
1604 got_offset = mono_aot_get_got_offset (cfg->patch_info);
1605 ctx->module->max_got_offset = MAX (ctx->module->max_got_offset, got_offset);
1607 * If the got slot is shared, it means its initialized when the aot image is loaded, so we don't need to
1608 * explicitly initialize it.
1610 if (!mono_aot_is_shared_got_offset (got_offset)) {
1611 //mono_print_ji (ji);
1613 ctx->has_got_access = TRUE;
1616 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
1617 indexes [1] = LLVMConstInt (LLVMInt32Type (), (gssize)got_offset, FALSE);
1618 got_entry_addr = LLVMBuildGEP (builder, ctx->module->got_var, indexes, 2, "");
1620 name = get_aotconst_name (type, data, got_offset);
1622 load = LLVMBuildLoad (builder, got_entry_addr, "");
1623 load = convert (ctx, load, llvm_type);
1624 LLVMSetValueName (load, name ? name : "");
1626 load = LLVMBuildLoad (builder, got_entry_addr, name ? name : "");
1629 //set_invariant_load_flag (load);
1635 get_aotconst (EmitContext *ctx, MonoJumpInfoType type, gconstpointer data)
1637 return get_aotconst_typed (ctx, type, data, NULL);
1641 get_callee (EmitContext *ctx, LLVMTypeRef llvm_sig, MonoJumpInfoType type, gconstpointer data)
1643 LLVMValueRef callee;
1645 if (ctx->llvm_only) {
1646 callee_name = mono_aot_get_direct_call_symbol (type, data);
1648 /* Directly callable */
1650 callee = (LLVMValueRef)g_hash_table_lookup (ctx->module->direct_callables, callee_name);
1652 callee = LLVMAddFunction (ctx->lmodule, callee_name, llvm_sig);
1654 LLVMSetVisibility (callee, LLVMHiddenVisibility);
1656 g_hash_table_insert (ctx->module->direct_callables, (char*)callee_name, callee);
1658 /* LLVMTypeRef's are uniqued */
1659 if (LLVMGetElementType (LLVMTypeOf (callee)) != llvm_sig)
1660 return LLVMConstBitCast (callee, LLVMPointerType (llvm_sig, 0));
1662 g_free (callee_name);
1668 * Calls are made through the GOT.
1670 return get_aotconst_typed (ctx, type, data, LLVMPointerType (llvm_sig, 0));
1672 MonoJumpInfo *ji = NULL;
1674 callee_name = mono_aot_get_plt_symbol (type, data);
1678 if (ctx->cfg->compile_aot)
1679 /* Add a patch so referenced wrappers can be compiled in full aot mode */
1680 mono_add_patch_info (ctx->cfg, 0, type, data);
1683 callee = (LLVMValueRef)g_hash_table_lookup (ctx->module->plt_entries, callee_name);
1685 callee = LLVMAddFunction (ctx->lmodule, callee_name, llvm_sig);
1687 LLVMSetVisibility (callee, LLVMHiddenVisibility);
1689 g_hash_table_insert (ctx->module->plt_entries, (char*)callee_name, callee);
1692 if (ctx->cfg->compile_aot) {
1693 ji = g_new0 (MonoJumpInfo, 1);
1695 ji->data.target = data;
1697 g_hash_table_insert (ctx->module->plt_entries_ji, ji, callee);
1705 emit_jit_callee (EmitContext *ctx, const char *name, LLVMTypeRef llvm_sig, gpointer target)
1707 #if LLVM_API_VERSION > 100
1708 LLVMValueRef tramp_var = LLVMAddGlobal (ctx->lmodule, LLVMPointerType (llvm_sig, 0), name);
1709 LLVMSetInitializer (tramp_var, LLVMConstIntToPtr (LLVMConstInt (LLVMInt64Type (), (guint64)(size_t)target, FALSE), LLVMPointerType (llvm_sig, 0)));
1710 LLVMSetLinkage (tramp_var, LLVMExternalLinkage);
1711 LLVMValueRef callee = LLVMBuildLoad (ctx->builder, tramp_var, "");
1714 LLVMValueRef callee = LLVMAddFunction (ctx->lmodule, "", llvm_sig);
1715 LLVMAddGlobalMapping (ctx->module->ee, callee, target);
1721 get_handler_clause (MonoCompile *cfg, MonoBasicBlock *bb)
1723 MonoMethodHeader *header = cfg->header;
1724 MonoExceptionClause *clause;
1728 if (bb->region != -1 && MONO_BBLOCK_IS_IN_REGION (bb, MONO_REGION_TRY))
1729 return (bb->region >> 8) - 1;
1732 for (i = 0; i < header->num_clauses; ++i) {
1733 clause = &header->clauses [i];
1735 if (MONO_OFFSET_IN_CLAUSE (clause, bb->real_offset) && clause->flags == MONO_EXCEPTION_CLAUSE_NONE)
1742 static MonoExceptionClause *
1743 get_most_deep_clause (MonoCompile *cfg, EmitContext *ctx, MonoBasicBlock *bb)
1745 // Since they're sorted by nesting we just need
1746 // the first one that the bb is a member of
1747 for (int i = 0; i < cfg->header->num_clauses; i++) {
1748 MonoExceptionClause *curr = &cfg->header->clauses [i];
1750 if (MONO_OFFSET_IN_CLAUSE (curr, bb->real_offset))
1758 set_metadata_flag (LLVMValueRef v, const char *flag_name)
1760 LLVMValueRef md_arg;
1763 md_kind = LLVMGetMDKindID (flag_name, strlen (flag_name));
1764 md_arg = LLVMMDString ("mono", 4);
1765 LLVMSetMetadata (v, md_kind, LLVMMDNode (&md_arg, 1));
1769 set_invariant_load_flag (LLVMValueRef v)
1771 LLVMValueRef md_arg;
1773 const char *flag_name;
1775 // FIXME: Cache this
1776 flag_name = "invariant.load";
1777 md_kind = LLVMGetMDKindID (flag_name, strlen (flag_name));
1778 md_arg = LLVMMDString ("<index>", strlen ("<index>"));
1779 LLVMSetMetadata (v, md_kind, LLVMMDNode (&md_arg, 1));
1785 * Emit an LLVM call or invoke instruction depending on whenever the call is inside
1789 emit_call (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, LLVMValueRef callee, LLVMValueRef *args, int pindex)
1791 MonoCompile *cfg = ctx->cfg;
1792 LLVMValueRef lcall = NULL;
1793 LLVMBuilderRef builder = *builder_ref;
1794 MonoExceptionClause *clause;
1796 if (ctx->llvm_only) {
1797 clause = get_most_deep_clause (cfg, ctx, bb);
1800 g_assert (clause->flags == MONO_EXCEPTION_CLAUSE_NONE || clause->flags == MONO_EXCEPTION_CLAUSE_FINALLY);
1803 * Have to use an invoke instead of a call, branching to the
1804 * handler bblock of the clause containing this bblock.
1806 intptr_t key = CLAUSE_END(clause);
1808 LLVMBasicBlockRef lpad_bb = (LLVMBasicBlockRef)g_hash_table_lookup (ctx->exc_meta, (gconstpointer)key);
1810 // FIXME: Find the one that has the lowest end bound for the right start address
1811 // FIXME: Finally + nesting
1814 LLVMBasicBlockRef noex_bb = gen_bb (ctx, "CALL_NOEX_BB");
1817 lcall = LLVMBuildInvoke (builder, callee, args, pindex, noex_bb, lpad_bb, "");
1819 builder = ctx->builder = create_builder (ctx);
1820 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
1822 ctx->bblocks [bb->block_num].end_bblock = noex_bb;
1826 int clause_index = get_handler_clause (cfg, bb);
1828 if (clause_index != -1) {
1829 MonoMethodHeader *header = cfg->header;
1830 MonoExceptionClause *ec = &header->clauses [clause_index];
1831 MonoBasicBlock *tblock;
1832 LLVMBasicBlockRef ex_bb, noex_bb;
1835 * Have to use an invoke instead of a call, branching to the
1836 * handler bblock of the clause containing this bblock.
1839 g_assert (ec->flags == MONO_EXCEPTION_CLAUSE_NONE || ec->flags == MONO_EXCEPTION_CLAUSE_FINALLY);
1841 tblock = cfg->cil_offset_to_bb [ec->handler_offset];
1844 ctx->bblocks [tblock->block_num].invoke_target = TRUE;
1846 ex_bb = get_bb (ctx, tblock);
1848 noex_bb = gen_bb (ctx, "NOEX_BB");
1851 lcall = LLVMBuildInvoke (builder, callee, args, pindex, noex_bb, ex_bb, "");
1853 builder = ctx->builder = create_builder (ctx);
1854 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
1856 ctx->bblocks [bb->block_num].end_bblock = noex_bb;
1861 lcall = LLVMBuildCall (builder, callee, args, pindex, "");
1862 ctx->builder = builder;
1866 *builder_ref = ctx->builder;
1872 emit_load_general (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, int size, LLVMValueRef addr, const char *name, gboolean is_faulting, BarrierKind barrier)
1874 const char *intrins_name;
1875 LLVMValueRef args [16], res;
1876 LLVMTypeRef addr_type;
1877 gboolean use_intrinsics = TRUE;
1879 #if LLVM_API_VERSION > 100
1880 if (is_faulting && bb->region != -1 && !ctx->cfg->llvm_only) {
1881 /* The llvm.mono.load/store intrinsics are not supported by this llvm version, emit an explicit null check instead */
1882 LLVMValueRef cmp = LLVMBuildICmp (*builder_ref, LLVMIntEQ, addr, LLVMConstNull (LLVMTypeOf (addr)), "");
1883 emit_cond_system_exception (ctx, bb, "NullReferenceException", cmp);
1884 *builder_ref = ctx->builder;
1885 use_intrinsics = FALSE;
1889 if (is_faulting && bb->region != -1 && !ctx->cfg->llvm_only && use_intrinsics) {
1890 LLVMAtomicOrdering ordering;
1893 case LLVM_BARRIER_NONE:
1894 ordering = LLVMAtomicOrderingNotAtomic;
1896 case LLVM_BARRIER_ACQ:
1897 ordering = LLVMAtomicOrderingAcquire;
1899 case LLVM_BARRIER_SEQ:
1900 ordering = LLVMAtomicOrderingSequentiallyConsistent;
1903 g_assert_not_reached ();
1908 * We handle loads which can fault by calling a mono specific intrinsic
1909 * using an invoke, so they are handled properly inside try blocks.
1910 * We can't use this outside clauses, since LLVM optimizes intrinsics which
1911 * are marked with IntrReadArgMem.
1915 intrins_name = "llvm.mono.load.i8.p0i8";
1918 intrins_name = "llvm.mono.load.i16.p0i16";
1921 intrins_name = "llvm.mono.load.i32.p0i32";
1924 intrins_name = "llvm.mono.load.i64.p0i64";
1927 g_assert_not_reached ();
1930 addr_type = LLVMTypeOf (addr);
1931 if (addr_type == LLVMPointerType (LLVMDoubleType (), 0) || addr_type == LLVMPointerType (LLVMFloatType (), 0))
1932 addr = LLVMBuildBitCast (*builder_ref, addr, LLVMPointerType (LLVMIntType (size * 8), 0), "");
1935 args [1] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
1936 args [2] = LLVMConstInt (LLVMInt1Type (), TRUE, FALSE);
1937 args [3] = LLVMConstInt (LLVMInt32Type (), ordering, FALSE);
1938 res = emit_call (ctx, bb, builder_ref, get_intrinsic (ctx, intrins_name), args, 4);
1940 if (addr_type == LLVMPointerType (LLVMDoubleType (), 0))
1941 res = LLVMBuildBitCast (*builder_ref, res, LLVMDoubleType (), "");
1942 else if (addr_type == LLVMPointerType (LLVMFloatType (), 0))
1943 res = LLVMBuildBitCast (*builder_ref, res, LLVMFloatType (), "");
1950 * We emit volatile loads for loads which can fault, because otherwise
1951 * LLVM will generate invalid code when encountering a load from a
1954 res = mono_llvm_build_load (*builder_ref, addr, name, is_faulting, barrier);
1956 /* Mark it with a custom metadata */
1959 set_metadata_flag (res, "mono.faulting.load");
1967 emit_load (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, int size, LLVMValueRef addr, const char *name, gboolean is_faulting)
1969 return emit_load_general (ctx, bb, builder_ref, size, addr, name, is_faulting, LLVM_BARRIER_NONE);
1973 emit_store_general (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, int size, LLVMValueRef value, LLVMValueRef addr, gboolean is_faulting, BarrierKind barrier)
1975 const char *intrins_name;
1976 LLVMValueRef args [16];
1977 gboolean use_intrinsics = TRUE;
1979 #if LLVM_API_VERSION > 100
1980 if (is_faulting && bb->region != -1 && !ctx->cfg->llvm_only) {
1981 /* The llvm.mono.load/store intrinsics are not supported by this llvm version, emit an explicit null check instead */
1982 LLVMValueRef cmp = LLVMBuildICmp (*builder_ref, LLVMIntEQ, addr, LLVMConstNull (LLVMTypeOf (addr)), "");
1983 emit_cond_system_exception (ctx, bb, "NullReferenceException", cmp);
1984 *builder_ref = ctx->builder;
1985 use_intrinsics = FALSE;
1989 if (is_faulting && bb->region != -1 && !ctx->cfg->llvm_only && use_intrinsics) {
1990 LLVMAtomicOrdering ordering;
1993 case LLVM_BARRIER_NONE:
1994 ordering = LLVMAtomicOrderingNotAtomic;
1996 case LLVM_BARRIER_REL:
1997 ordering = LLVMAtomicOrderingRelease;
1999 case LLVM_BARRIER_SEQ:
2000 ordering = LLVMAtomicOrderingSequentiallyConsistent;
2003 g_assert_not_reached ();
2009 intrins_name = "llvm.mono.store.i8.p0i8";
2012 intrins_name = "llvm.mono.store.i16.p0i16";
2015 intrins_name = "llvm.mono.store.i32.p0i32";
2018 intrins_name = "llvm.mono.store.i64.p0i64";
2021 g_assert_not_reached ();
2024 if (LLVMTypeOf (value) == LLVMDoubleType () || LLVMTypeOf (value) == LLVMFloatType ()) {
2025 value = LLVMBuildBitCast (*builder_ref, value, LLVMIntType (size * 8), "");
2026 addr = LLVMBuildBitCast (*builder_ref, addr, LLVMPointerType (LLVMIntType (size * 8), 0), "");
2031 args [2] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
2032 args [3] = LLVMConstInt (LLVMInt1Type (), TRUE, FALSE);
2033 args [4] = LLVMConstInt (LLVMInt32Type (), ordering, FALSE);
2034 emit_call (ctx, bb, builder_ref, get_intrinsic (ctx, intrins_name), args, 5);
2036 mono_llvm_build_store (*builder_ref, value, addr, is_faulting, barrier);
2041 emit_store (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, int size, LLVMValueRef value, LLVMValueRef addr, gboolean is_faulting)
2043 emit_store_general (ctx, bb, builder_ref, size, value, addr, is_faulting, LLVM_BARRIER_NONE);
2047 * emit_cond_system_exception:
2049 * Emit code to throw the exception EXC_TYPE if the condition CMP is false.
2050 * Might set the ctx exception.
2053 emit_cond_system_exception (EmitContext *ctx, MonoBasicBlock *bb, const char *exc_type, LLVMValueRef cmp)
2055 LLVMBasicBlockRef ex_bb, ex2_bb = NULL, noex_bb;
2056 LLVMBuilderRef builder;
2057 MonoClass *exc_class;
2058 LLVMValueRef args [2];
2059 LLVMValueRef callee;
2060 gboolean no_pc = FALSE;
2062 if (IS_TARGET_AMD64)
2063 /* Some platforms don't require the pc argument */
2066 ex_bb = gen_bb (ctx, "EX_BB");
2068 ex2_bb = gen_bb (ctx, "EX2_BB");
2069 noex_bb = gen_bb (ctx, "NOEX_BB");
2071 LLVMBuildCondBr (ctx->builder, cmp, ex_bb, noex_bb);
2073 exc_class = mono_class_load_from_name (mono_get_corlib (), "System", exc_type);
2075 /* Emit exception throwing code */
2076 ctx->builder = builder = create_builder (ctx);
2077 LLVMPositionBuilderAtEnd (builder, ex_bb);
2079 if (ctx->cfg->llvm_only) {
2080 static LLVMTypeRef sig;
2083 sig = LLVMFunctionType1 (LLVMVoidType (), LLVMInt32Type (), FALSE);
2084 callee = get_callee (ctx, sig, MONO_PATCH_INFO_JIT_ICALL_ADDR, "mono_llvm_throw_corlib_exception");
2086 LLVMBuildBr (builder, ex2_bb);
2088 ctx->builder = builder = create_builder (ctx);
2089 LLVMPositionBuilderAtEnd (ctx->builder, ex2_bb);
2091 args [0] = LLVMConstInt (LLVMInt32Type (), exc_class->type_token - MONO_TOKEN_TYPE_DEF, FALSE);
2092 emit_call (ctx, bb, &builder, callee, args, 1);
2093 LLVMBuildUnreachable (builder);
2095 ctx->builder = builder = create_builder (ctx);
2096 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
2098 ctx->bblocks [bb->block_num].end_bblock = noex_bb;
2104 callee = ctx->module->throw_corlib_exception;
2107 const char *icall_name;
2110 sig = LLVMFunctionType1 (LLVMVoidType (), LLVMInt32Type (), FALSE);
2112 sig = LLVMFunctionType2 (LLVMVoidType (), LLVMInt32Type (), LLVMPointerType (LLVMInt8Type (), 0), FALSE);
2113 icall_name = "llvm_throw_corlib_exception_abs_trampoline";
2115 if (ctx->cfg->compile_aot) {
2116 callee = get_callee (ctx, sig, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
2119 * Differences between the LLVM/non-LLVM throw corlib exception trampoline:
2120 * - On x86, LLVM generated code doesn't push the arguments
2121 * - The trampoline takes the throw address as an arguments, not a pc offset.
2123 gpointer target = resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
2124 callee = emit_jit_callee (ctx, "llvm_throw_corlib_exception_trampoline", sig, target);
2126 #if LLVM_API_VERSION > 100
2128 * Make sure that ex_bb starts with the invoke, so the block address points to it, and not to the load
2129 * added by emit_jit_callee ().
2131 ex2_bb = gen_bb (ctx, "EX2_BB");
2132 LLVMBuildBr (builder, ex2_bb);
2135 ctx->builder = builder = create_builder (ctx);
2136 LLVMPositionBuilderAtEnd (ctx->builder, ex2_bb);
2138 mono_memory_barrier ();
2139 ctx->module->throw_corlib_exception = callee;
2144 args [0] = LLVMConstInt (LLVMInt32Type (), exc_class->type_token - MONO_TOKEN_TYPE_DEF, FALSE);
2147 * The LLVM mono branch contains changes so a block address can be passed as an
2148 * argument to a call.
2151 emit_call (ctx, bb, &builder, callee, args, 1);
2153 args [1] = LLVMBlockAddress (ctx->lmethod, ex_bb);
2154 emit_call (ctx, bb, &builder, callee, args, 2);
2157 LLVMBuildUnreachable (builder);
2159 ctx->builder = builder = create_builder (ctx);
2160 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
2162 ctx->bblocks [bb->block_num].end_bblock = noex_bb;
2169 * emit_args_to_vtype:
2171 * Emit code to store the vtype in the arguments args to the address ADDRESS.
2174 emit_args_to_vtype (EmitContext *ctx, LLVMBuilderRef builder, MonoType *t, LLVMValueRef address, LLVMArgInfo *ainfo, LLVMValueRef *args)
2176 int j, size, nslots;
2178 size = mono_class_value_size (mono_class_from_mono_type (t), NULL);
2180 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (t))) {
2181 address = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (LLVMInt8Type (), 0), "");
2184 if (ainfo->storage == LLVMArgAsFpArgs)
2185 nslots = ainfo->nslots;
2189 for (j = 0; j < nslots; ++j) {
2190 LLVMValueRef index [2], addr, daddr;
2191 int part_size = size > sizeof (gpointer) ? sizeof (gpointer) : size;
2192 LLVMTypeRef part_type;
2194 while (part_size != 1 && part_size != 2 && part_size != 4 && part_size < 8)
2197 if (ainfo->pair_storage [j] == LLVMArgNone)
2200 switch (ainfo->pair_storage [j]) {
2201 case LLVMArgInIReg: {
2202 part_type = LLVMIntType (part_size * 8);
2203 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (t))) {
2204 index [0] = LLVMConstInt (LLVMInt32Type (), j * sizeof (gpointer), FALSE);
2205 addr = LLVMBuildGEP (builder, address, index, 1, "");
2207 daddr = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (IntPtrType (), 0), "");
2208 index [0] = LLVMConstInt (LLVMInt32Type (), j, FALSE);
2209 addr = LLVMBuildGEP (builder, daddr, index, 1, "");
2211 LLVMBuildStore (builder, convert (ctx, args [j], part_type), LLVMBuildBitCast (ctx->builder, addr, LLVMPointerType (part_type, 0), ""));
2214 case LLVMArgInFPReg: {
2215 LLVMTypeRef arg_type;
2217 if (ainfo->esize == 8)
2218 arg_type = LLVMDoubleType ();
2220 arg_type = LLVMFloatType ();
2222 index [0] = LLVMConstInt (LLVMInt32Type (), j, FALSE);
2223 daddr = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (arg_type, 0), "");
2224 addr = LLVMBuildGEP (builder, daddr, index, 1, "");
2225 LLVMBuildStore (builder, args [j], addr);
2231 g_assert_not_reached ();
2234 size -= sizeof (gpointer);
2239 * emit_vtype_to_args:
2241 * Emit code to load a vtype at address ADDRESS into scalar arguments. Store the arguments
2242 * into ARGS, and the number of arguments into NARGS.
2245 emit_vtype_to_args (EmitContext *ctx, LLVMBuilderRef builder, MonoType *t, LLVMValueRef address, LLVMArgInfo *ainfo, LLVMValueRef *args, guint32 *nargs)
2248 int j, size, nslots;
2249 LLVMTypeRef arg_type;
2251 size = get_vtype_size (t);
2253 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (t)))
2254 address = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (LLVMInt8Type (), 0), "");
2256 if (ainfo->storage == LLVMArgAsFpArgs)
2257 nslots = ainfo->nslots;
2260 for (j = 0; j < nslots; ++j) {
2261 LLVMValueRef index [2], addr, daddr;
2262 int partsize = size > sizeof (gpointer) ? sizeof (gpointer) : size;
2264 if (ainfo->pair_storage [j] == LLVMArgNone)
2267 switch (ainfo->pair_storage [j]) {
2269 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (t))) {
2270 index [0] = LLVMConstInt (LLVMInt32Type (), j * sizeof (gpointer), FALSE);
2271 addr = LLVMBuildGEP (builder, address, index, 1, "");
2273 daddr = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (IntPtrType (), 0), "");
2274 index [0] = LLVMConstInt (LLVMInt32Type (), j, FALSE);
2275 addr = LLVMBuildGEP (builder, daddr, index, 1, "");
2277 args [pindex ++] = convert (ctx, LLVMBuildLoad (builder, LLVMBuildBitCast (ctx->builder, addr, LLVMPointerType (LLVMIntType (partsize * 8), 0), ""), ""), IntPtrType ());
2279 case LLVMArgInFPReg:
2280 if (ainfo->esize == 8)
2281 arg_type = LLVMDoubleType ();
2283 arg_type = LLVMFloatType ();
2284 daddr = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (arg_type, 0), "");
2285 index [0] = LLVMConstInt (LLVMInt32Type (), j, FALSE);
2286 addr = LLVMBuildGEP (builder, daddr, index, 1, "");
2287 args [pindex ++] = LLVMBuildLoad (builder, addr, "");
2292 g_assert_not_reached ();
2294 size -= sizeof (gpointer);
2301 build_alloca_llvm_type_name (EmitContext *ctx, LLVMTypeRef t, int align, const char *name)
2304 * Have to place all alloca's at the end of the entry bb, since otherwise they would
2305 * get executed every time control reaches them.
2307 LLVMPositionBuilder (ctx->alloca_builder, get_bb (ctx, ctx->cfg->bb_entry), ctx->last_alloca);
2309 ctx->last_alloca = mono_llvm_build_alloca (ctx->alloca_builder, t, NULL, align, name);
2310 return ctx->last_alloca;
2314 build_alloca_llvm_type (EmitContext *ctx, LLVMTypeRef t, int align)
2316 return build_alloca_llvm_type_name (ctx, t, align, "");
2320 build_alloca (EmitContext *ctx, MonoType *t)
2322 MonoClass *k = mono_class_from_mono_type (t);
2325 g_assert (!mini_is_gsharedvt_variable_type (t));
2327 if (MONO_CLASS_IS_SIMD (ctx->cfg, k))
2330 align = mono_class_min_align (k);
2332 /* Sometimes align is not a power of 2 */
2333 while (mono_is_power_of_two (align) == -1)
2336 return build_alloca_llvm_type (ctx, type_to_llvm_type (ctx, t), align);
2340 emit_gsharedvt_ldaddr (EmitContext *ctx, int vreg)
2344 * Compute the address of the local as gsharedvt_locals_var + gsharedvt_info_var->locals_offsets [idx].
2346 MonoCompile *cfg = ctx->cfg;
2347 LLVMBuilderRef builder = ctx->builder;
2348 LLVMValueRef offset, offset_var;
2349 LLVMValueRef info_var = ctx->values [cfg->gsharedvt_info_var->dreg];
2350 LLVMValueRef locals_var = ctx->values [cfg->gsharedvt_locals_var->dreg];
2354 g_assert (info_var);
2355 g_assert (locals_var);
2357 int idx = cfg->gsharedvt_vreg_to_idx [vreg] - 1;
2359 offset = LLVMConstInt (LLVMInt32Type (), MONO_STRUCT_OFFSET (MonoGSharedVtMethodRuntimeInfo, entries) + (idx * sizeof (gpointer)), FALSE);
2360 ptr = LLVMBuildAdd (builder, convert (ctx, info_var, IntPtrType ()), convert (ctx, offset, IntPtrType ()), "");
2362 name = g_strdup_printf ("gsharedvt_local_%d_offset", vreg);
2363 offset_var = LLVMBuildLoad (builder, convert (ctx, ptr, LLVMPointerType (LLVMInt32Type (), 0)), name);
2365 return LLVMBuildAdd (builder, convert (ctx, locals_var, IntPtrType ()), convert (ctx, offset_var, IntPtrType ()), "");
2369 * Put the global into the 'llvm.used' array to prevent it from being optimized away.
2372 mark_as_used (MonoLLVMModule *module, LLVMValueRef global)
2375 module->used = g_ptr_array_sized_new (16);
2376 g_ptr_array_add (module->used, global);
2380 emit_llvm_used (MonoLLVMModule *module)
2382 LLVMModuleRef lmodule = module->lmodule;
2383 LLVMTypeRef used_type;
2384 LLVMValueRef used, *used_elem;
2390 used_type = LLVMArrayType (LLVMPointerType (LLVMInt8Type (), 0), module->used->len);
2391 used = LLVMAddGlobal (lmodule, used_type, "llvm.used");
2392 used_elem = g_new0 (LLVMValueRef, module->used->len);
2393 for (i = 0; i < module->used->len; ++i)
2394 used_elem [i] = LLVMConstBitCast ((LLVMValueRef)g_ptr_array_index (module->used, i), LLVMPointerType (LLVMInt8Type (), 0));
2395 LLVMSetInitializer (used, LLVMConstArray (LLVMPointerType (LLVMInt8Type (), 0), used_elem, module->used->len));
2396 LLVMSetLinkage (used, LLVMAppendingLinkage);
2397 LLVMSetSection (used, "llvm.metadata");
2403 * Emit a function mapping method indexes to their code
2406 emit_get_method (MonoLLVMModule *module)
2408 LLVMModuleRef lmodule = module->lmodule;
2409 LLVMValueRef func, switch_ins, m;
2410 LLVMBasicBlockRef entry_bb, fail_bb, bb, code_start_bb, code_end_bb;
2411 LLVMBasicBlockRef *bbs;
2413 LLVMBuilderRef builder;
2418 * Emit a switch statement. Emitting a table of function addresses is smaller/faster,
2419 * but generating code seems safer.
2421 rtype = LLVMPointerType (LLVMInt8Type (), 0);
2422 func = LLVMAddFunction (lmodule, module->get_method_symbol, LLVMFunctionType1 (rtype, LLVMInt32Type (), FALSE));
2423 LLVMSetLinkage (func, LLVMExternalLinkage);
2424 LLVMSetVisibility (func, LLVMHiddenVisibility);
2425 LLVMAddFunctionAttr (func, LLVMNoUnwindAttribute);
2426 module->get_method = func;
2428 entry_bb = LLVMAppendBasicBlock (func, "ENTRY");
2431 * Return llvm_code_start/llvm_code_end when called with -1/-2.
2432 * Hopefully, the toolchain doesn't reorder these functions. If it does,
2433 * then we will have to find another solution.
2436 name = g_strdup_printf ("BB_CODE_START");
2437 code_start_bb = LLVMAppendBasicBlock (func, name);
2439 builder = LLVMCreateBuilder ();
2440 LLVMPositionBuilderAtEnd (builder, code_start_bb);
2441 LLVMBuildRet (builder, LLVMBuildBitCast (builder, module->code_start, rtype, ""));
2443 name = g_strdup_printf ("BB_CODE_END");
2444 code_end_bb = LLVMAppendBasicBlock (func, name);
2446 builder = LLVMCreateBuilder ();
2447 LLVMPositionBuilderAtEnd (builder, code_end_bb);
2448 LLVMBuildRet (builder, LLVMBuildBitCast (builder, module->code_end, rtype, ""));
2450 bbs = g_new0 (LLVMBasicBlockRef, module->max_method_idx + 1);
2451 for (i = 0; i < module->max_method_idx + 1; ++i) {
2452 name = g_strdup_printf ("BB_%d", i);
2453 bb = LLVMAppendBasicBlock (func, name);
2457 builder = LLVMCreateBuilder ();
2458 LLVMPositionBuilderAtEnd (builder, bb);
2460 m = (LLVMValueRef)g_hash_table_lookup (module->idx_to_lmethod, GINT_TO_POINTER (i));
2462 LLVMBuildRet (builder, LLVMBuildBitCast (builder, m, rtype, ""));
2464 LLVMBuildRet (builder, LLVMConstNull (rtype));
2467 fail_bb = LLVMAppendBasicBlock (func, "FAIL");
2468 builder = LLVMCreateBuilder ();
2469 LLVMPositionBuilderAtEnd (builder, fail_bb);
2470 LLVMBuildRet (builder, LLVMConstNull (rtype));
2472 builder = LLVMCreateBuilder ();
2473 LLVMPositionBuilderAtEnd (builder, entry_bb);
2475 switch_ins = LLVMBuildSwitch (builder, LLVMGetParam (func, 0), fail_bb, 0);
2476 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), -1, FALSE), code_start_bb);
2477 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), -2, FALSE), code_end_bb);
2478 for (i = 0; i < module->max_method_idx + 1; ++i) {
2479 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), i, FALSE), bbs [i]);
2482 mark_as_used (module, func);
2486 * emit_get_unbox_tramp:
2488 * Emit a function mapping method indexes to their unbox trampoline
2491 emit_get_unbox_tramp (MonoLLVMModule *module)
2493 LLVMModuleRef lmodule = module->lmodule;
2494 LLVMValueRef func, switch_ins, m;
2495 LLVMBasicBlockRef entry_bb, fail_bb, bb;
2496 LLVMBasicBlockRef *bbs;
2498 LLVMBuilderRef builder;
2502 /* Similar to emit_get_method () */
2504 rtype = LLVMPointerType (LLVMInt8Type (), 0);
2505 func = LLVMAddFunction (lmodule, module->get_unbox_tramp_symbol, LLVMFunctionType1 (rtype, LLVMInt32Type (), FALSE));
2506 LLVMSetLinkage (func, LLVMExternalLinkage);
2507 LLVMSetVisibility (func, LLVMHiddenVisibility);
2508 LLVMAddFunctionAttr (func, LLVMNoUnwindAttribute);
2509 module->get_unbox_tramp = func;
2511 entry_bb = LLVMAppendBasicBlock (func, "ENTRY");
2513 bbs = g_new0 (LLVMBasicBlockRef, module->max_method_idx + 1);
2514 for (i = 0; i < module->max_method_idx + 1; ++i) {
2515 m = (LLVMValueRef)g_hash_table_lookup (module->idx_to_unbox_tramp, GINT_TO_POINTER (i));
2519 name = g_strdup_printf ("BB_%d", i);
2520 bb = LLVMAppendBasicBlock (func, name);
2524 builder = LLVMCreateBuilder ();
2525 LLVMPositionBuilderAtEnd (builder, bb);
2527 LLVMBuildRet (builder, LLVMBuildBitCast (builder, m, rtype, ""));
2530 fail_bb = LLVMAppendBasicBlock (func, "FAIL");
2531 builder = LLVMCreateBuilder ();
2532 LLVMPositionBuilderAtEnd (builder, fail_bb);
2533 LLVMBuildRet (builder, LLVMConstNull (rtype));
2535 builder = LLVMCreateBuilder ();
2536 LLVMPositionBuilderAtEnd (builder, entry_bb);
2538 switch_ins = LLVMBuildSwitch (builder, LLVMGetParam (func, 0), fail_bb, 0);
2539 for (i = 0; i < module->max_method_idx + 1; ++i) {
2540 m = (LLVMValueRef)g_hash_table_lookup (module->idx_to_unbox_tramp, GINT_TO_POINTER (i));
2544 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), i, FALSE), bbs [i]);
2547 mark_as_used (module, func);
2550 /* Add a function to mark the beginning of LLVM code */
2552 emit_llvm_code_start (MonoLLVMModule *module)
2554 LLVMModuleRef lmodule = module->lmodule;
2556 LLVMBasicBlockRef entry_bb;
2557 LLVMBuilderRef builder;
2559 func = LLVMAddFunction (lmodule, "llvm_code_start", LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE));
2560 LLVMSetLinkage (func, LLVMInternalLinkage);
2561 LLVMAddFunctionAttr (func, LLVMNoUnwindAttribute);
2562 module->code_start = func;
2563 entry_bb = LLVMAppendBasicBlock (func, "ENTRY");
2564 builder = LLVMCreateBuilder ();
2565 LLVMPositionBuilderAtEnd (builder, entry_bb);
2566 LLVMBuildRetVoid (builder);
2570 emit_init_icall_wrapper (MonoLLVMModule *module, const char *name, const char *icall_name, int subtype)
2572 LLVMModuleRef lmodule = module->lmodule;
2573 LLVMValueRef func, indexes [2], got_entry_addr, args [16], callee;
2574 LLVMBasicBlockRef entry_bb;
2575 LLVMBuilderRef builder;
2582 func = LLVMAddFunction (lmodule, name, LLVMFunctionType1 (LLVMVoidType (), LLVMInt32Type (), FALSE));
2583 sig = LLVMFunctionType2 (LLVMVoidType (), IntPtrType (), LLVMInt32Type (), FALSE);
2588 func = LLVMAddFunction (lmodule, name, LLVMFunctionType2 (LLVMVoidType (), LLVMInt32Type (), IntPtrType (), FALSE));
2589 sig = LLVMFunctionType3 (LLVMVoidType (), IntPtrType (), LLVMInt32Type (), IntPtrType (), FALSE);
2592 func = LLVMAddFunction (lmodule, name, LLVMFunctionType2 (LLVMVoidType (), LLVMInt32Type (), ObjRefType (), FALSE));
2593 sig = LLVMFunctionType3 (LLVMVoidType (), IntPtrType (), LLVMInt32Type (), ObjRefType (), FALSE);
2596 g_assert_not_reached ();
2598 LLVMSetLinkage (func, LLVMInternalLinkage);
2599 LLVMAddFunctionAttr (func, LLVMNoInlineAttribute);
2600 mono_llvm_set_preserveall_cc (func);
2601 entry_bb = LLVMAppendBasicBlock (func, "ENTRY");
2602 builder = LLVMCreateBuilder ();
2603 LLVMPositionBuilderAtEnd (builder, entry_bb);
2606 ji = g_new0 (MonoJumpInfo, 1);
2607 ji->type = MONO_PATCH_INFO_AOT_MODULE;
2608 ji = mono_aot_patch_info_dup (ji);
2609 got_offset = mono_aot_get_got_offset (ji);
2610 module->max_got_offset = MAX (module->max_got_offset, got_offset);
2611 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
2612 indexes [1] = LLVMConstInt (LLVMInt32Type (), got_offset, FALSE);
2613 got_entry_addr = LLVMBuildGEP (builder, module->got_var, indexes, 2, "");
2614 args [0] = LLVMBuildPtrToInt (builder, LLVMBuildLoad (builder, got_entry_addr, ""), IntPtrType (), "");
2615 args [1] = LLVMGetParam (func, 0);
2617 args [2] = LLVMGetParam (func, 1);
2619 ji = g_new0 (MonoJumpInfo, 1);
2620 ji->type = MONO_PATCH_INFO_INTERNAL_METHOD;
2621 ji->data.name = icall_name;
2622 ji = mono_aot_patch_info_dup (ji);
2623 got_offset = mono_aot_get_got_offset (ji);
2624 module->max_got_offset = MAX (module->max_got_offset, got_offset);
2625 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
2626 indexes [1] = LLVMConstInt (LLVMInt32Type (), got_offset, FALSE);
2627 got_entry_addr = LLVMBuildGEP (builder, module->got_var, indexes, 2, "");
2628 callee = LLVMBuildLoad (builder, got_entry_addr, "");
2629 callee = LLVMBuildBitCast (builder, callee, LLVMPointerType (sig, 0), "");
2630 LLVMBuildCall (builder, callee, args, LLVMCountParamTypes (sig), "");
2632 // Set the inited flag
2633 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
2634 indexes [1] = LLVMGetParam (func, 0);
2635 LLVMBuildStore (builder, LLVMConstInt (LLVMInt8Type (), 1, FALSE), LLVMBuildGEP (builder, module->inited_var, indexes, 2, ""));
2637 LLVMBuildRetVoid (builder);
2639 LLVMVerifyFunction(func, LLVMAbortProcessAction);
2644 * Emit wrappers around the C icalls used to initialize llvm methods, to
2645 * make the calling code smaller and to enable usage of the llvm
2646 * PreserveAll calling convention.
2649 emit_init_icall_wrappers (MonoLLVMModule *module)
2651 module->init_method = emit_init_icall_wrapper (module, "init_method", "mono_aot_init_llvm_method", 0);
2652 module->init_method_gshared_mrgctx = emit_init_icall_wrapper (module, "init_method_gshared_mrgctx", "mono_aot_init_gshared_method_mrgctx", 1);
2653 module->init_method_gshared_this = emit_init_icall_wrapper (module, "init_method_gshared_this", "mono_aot_init_gshared_method_this", 2);
2654 module->init_method_gshared_vtable = emit_init_icall_wrapper (module, "init_method_gshared_vtable", "mono_aot_init_gshared_method_vtable", 3);
2658 emit_llvm_code_end (MonoLLVMModule *module)
2660 LLVMModuleRef lmodule = module->lmodule;
2662 LLVMBasicBlockRef entry_bb;
2663 LLVMBuilderRef builder;
2665 func = LLVMAddFunction (lmodule, "llvm_code_end", LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE));
2666 LLVMSetLinkage (func, LLVMInternalLinkage);
2667 LLVMAddFunctionAttr (func, LLVMNoUnwindAttribute);
2668 module->code_end = func;
2669 entry_bb = LLVMAppendBasicBlock (func, "ENTRY");
2670 builder = LLVMCreateBuilder ();
2671 LLVMPositionBuilderAtEnd (builder, entry_bb);
2672 LLVMBuildRetVoid (builder);
2676 emit_div_check (EmitContext *ctx, LLVMBuilderRef builder, MonoBasicBlock *bb, MonoInst *ins, LLVMValueRef lhs, LLVMValueRef rhs)
2678 gboolean need_div_check = ctx->cfg->backend->need_div_check;
2681 /* LLVM doesn't know that these can throw an exception since they are not called through an intrinsic */
2682 need_div_check = TRUE;
2684 if (!need_div_check)
2687 switch (ins->opcode) {
2700 case OP_IDIV_UN_IMM:
2701 case OP_LDIV_UN_IMM:
2702 case OP_IREM_UN_IMM:
2703 case OP_LREM_UN_IMM: {
2705 gboolean is_signed = (ins->opcode == OP_IDIV || ins->opcode == OP_LDIV || ins->opcode == OP_IREM || ins->opcode == OP_LREM ||
2706 ins->opcode == OP_IDIV_IMM || ins->opcode == OP_LDIV_IMM || ins->opcode == OP_IREM_IMM || ins->opcode == OP_LREM_IMM);
2708 cmp = LLVMBuildICmp (builder, LLVMIntEQ, rhs, LLVMConstInt (LLVMTypeOf (rhs), 0, FALSE), "");
2709 emit_cond_system_exception (ctx, bb, "DivideByZeroException", cmp);
2712 builder = ctx->builder;
2714 /* b == -1 && a == 0x80000000 */
2716 LLVMValueRef c = (LLVMTypeOf (lhs) == LLVMInt32Type ()) ? LLVMConstInt (LLVMTypeOf (lhs), 0x80000000, FALSE) : LLVMConstInt (LLVMTypeOf (lhs), 0x8000000000000000LL, FALSE);
2717 LLVMValueRef cond1 = LLVMBuildICmp (builder, LLVMIntEQ, rhs, LLVMConstInt (LLVMTypeOf (rhs), -1, FALSE), "");
2718 LLVMValueRef cond2 = LLVMBuildICmp (builder, LLVMIntEQ, lhs, c, "");
2720 cmp = LLVMBuildICmp (builder, LLVMIntEQ, LLVMBuildAnd (builder, cond1, cond2, ""), LLVMConstInt (LLVMInt1Type (), 1, FALSE), "");
2721 emit_cond_system_exception (ctx, bb, "OverflowException", cmp);
2724 builder = ctx->builder;
2736 * Emit code to initialize the GOT slots used by the method.
2739 emit_init_method (EmitContext *ctx)
2741 LLVMValueRef indexes [16], args [16], callee;
2742 LLVMValueRef inited_var, cmp, call;
2743 LLVMBasicBlockRef inited_bb, notinited_bb;
2744 LLVMBuilderRef builder = ctx->builder;
2745 MonoCompile *cfg = ctx->cfg;
2747 ctx->module->max_inited_idx = MAX (ctx->module->max_inited_idx, cfg->method_index);
2749 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
2750 indexes [1] = LLVMConstInt (LLVMInt32Type (), cfg->method_index, FALSE);
2751 inited_var = LLVMBuildLoad (builder, LLVMBuildGEP (builder, ctx->module->inited_var, indexes, 2, ""), "is_inited");
2753 args [0] = inited_var;
2754 args [1] = LLVMConstInt (LLVMInt8Type (), 1, FALSE);
2755 inited_var = LLVMBuildCall (ctx->builder, get_intrinsic (ctx, "llvm.expect.i8"), args, 2, "");
2757 cmp = LLVMBuildICmp (builder, LLVMIntEQ, inited_var, LLVMConstInt (LLVMTypeOf (inited_var), 0, FALSE), "");
2759 inited_bb = ctx->inited_bb;
2760 notinited_bb = gen_bb (ctx, "NOTINITED_BB");
2762 LLVMBuildCondBr (ctx->builder, cmp, notinited_bb, inited_bb);
2764 builder = ctx->builder = create_builder (ctx);
2765 LLVMPositionBuilderAtEnd (ctx->builder, notinited_bb);
2768 if (ctx->rgctx_arg && cfg->method->is_inflated && mono_method_get_context (cfg->method)->method_inst) {
2769 args [0] = LLVMConstInt (LLVMInt32Type (), cfg->method_index, 0);
2770 args [1] = convert (ctx, ctx->rgctx_arg, IntPtrType ());
2771 callee = ctx->module->init_method_gshared_mrgctx;
2772 call = LLVMBuildCall (builder, callee, args, 2, "");
2773 } else if (ctx->rgctx_arg) {
2774 /* A vtable is passed as the rgctx argument */
2775 args [0] = LLVMConstInt (LLVMInt32Type (), cfg->method_index, 0);
2776 args [1] = convert (ctx, ctx->rgctx_arg, IntPtrType ());
2777 callee = ctx->module->init_method_gshared_vtable;
2778 call = LLVMBuildCall (builder, callee, args, 2, "");
2779 } else if (cfg->gshared) {
2780 args [0] = LLVMConstInt (LLVMInt32Type (), cfg->method_index, 0);
2781 args [1] = convert (ctx, ctx->this_arg, ObjRefType ());
2782 callee = ctx->module->init_method_gshared_this;
2783 call = LLVMBuildCall (builder, callee, args, 2, "");
2785 args [0] = LLVMConstInt (LLVMInt32Type (), cfg->method_index, 0);
2786 callee = ctx->module->init_method;
2787 call = LLVMBuildCall (builder, callee, args, 1, "");
2791 * This enables llvm to keep arguments in their original registers/
2792 * scratch registers, since the call will not clobber them.
2794 mono_llvm_set_call_preserveall_cc (call);
2796 LLVMBuildBr (builder, inited_bb);
2797 ctx->bblocks [cfg->bb_entry->block_num].end_bblock = inited_bb;
2799 builder = ctx->builder = create_builder (ctx);
2800 LLVMPositionBuilderAtEnd (ctx->builder, inited_bb);
2804 emit_unbox_tramp (EmitContext *ctx, const char *method_name, LLVMTypeRef method_type, LLVMValueRef method, int method_index)
2807 * Emit unbox trampoline using a tail call
2809 LLVMValueRef tramp, call, *args;
2810 LLVMBuilderRef builder;
2811 LLVMBasicBlockRef lbb;
2812 LLVMCallInfo *linfo;
2816 tramp_name = g_strdup_printf ("ut_%s", method_name);
2817 tramp = LLVMAddFunction (ctx->module->lmodule, tramp_name, method_type);
2818 LLVMSetLinkage (tramp, LLVMInternalLinkage);
2819 LLVMAddFunctionAttr (tramp, LLVMOptimizeForSizeAttribute);
2820 //LLVMAddFunctionAttr (tramp, LLVMNoUnwindAttribute);
2822 // FIXME: Reduce code duplication with mono_llvm_compile_method () etc.
2823 if (!ctx->llvm_only && ctx->rgctx_arg_pindex != -1)
2824 LLVMAddAttribute (LLVMGetParam (tramp, ctx->rgctx_arg_pindex), LLVMInRegAttribute);
2825 if (ctx->cfg->vret_addr) {
2826 LLVMSetValueName (LLVMGetParam (tramp, linfo->vret_arg_pindex), "vret");
2827 if (linfo->ret.storage == LLVMArgVtypeByRef) {
2828 LLVMAddAttribute (LLVMGetParam (tramp, linfo->vret_arg_pindex), LLVMStructRetAttribute);
2829 LLVMAddAttribute (LLVMGetParam (tramp, linfo->vret_arg_pindex), LLVMNoAliasAttribute);
2833 lbb = LLVMAppendBasicBlock (tramp, "");
2834 builder = LLVMCreateBuilder ();
2835 LLVMPositionBuilderAtEnd (builder, lbb);
2837 nargs = LLVMCountParamTypes (method_type);
2838 args = g_new0 (LLVMValueRef, nargs);
2839 for (i = 0; i < nargs; ++i) {
2840 args [i] = LLVMGetParam (tramp, i);
2841 if (i == ctx->this_arg_pindex) {
2842 LLVMTypeRef arg_type = LLVMTypeOf (args [i]);
2844 args [i] = LLVMBuildPtrToInt (builder, args [i], IntPtrType (), "");
2845 args [i] = LLVMBuildAdd (builder, args [i], LLVMConstInt (IntPtrType (), sizeof (MonoObject), FALSE), "");
2846 args [i] = LLVMBuildIntToPtr (builder, args [i], arg_type, "");
2849 call = LLVMBuildCall (builder, method, args, nargs, "");
2850 if (!ctx->llvm_only && ctx->rgctx_arg_pindex != -1)
2851 LLVMAddInstrAttribute (call, 1 + ctx->rgctx_arg_pindex, LLVMInRegAttribute);
2852 if (linfo->ret.storage == LLVMArgVtypeByRef)
2853 LLVMAddInstrAttribute (call, 1 + linfo->vret_arg_pindex, LLVMStructRetAttribute);
2855 // FIXME: This causes assertions in clang
2856 //mono_llvm_set_must_tail (call);
2857 if (LLVMGetReturnType (method_type) == LLVMVoidType ())
2858 LLVMBuildRetVoid (builder);
2860 LLVMBuildRet (builder, call);
2862 g_hash_table_insert (ctx->module->idx_to_unbox_tramp, GINT_TO_POINTER (method_index), tramp);
2868 * Emit code to load/convert arguments.
2871 emit_entry_bb (EmitContext *ctx, LLVMBuilderRef builder)
2874 MonoCompile *cfg = ctx->cfg;
2875 MonoMethodSignature *sig = ctx->sig;
2876 LLVMCallInfo *linfo = ctx->linfo;
2880 LLVMBuilderRef old_builder = ctx->builder;
2881 ctx->builder = builder;
2883 ctx->alloca_builder = create_builder (ctx);
2886 * Handle indirect/volatile variables by allocating memory for them
2887 * using 'alloca', and storing their address in a temporary.
2889 for (i = 0; i < cfg->num_varinfo; ++i) {
2890 MonoInst *var = cfg->varinfo [i];
2893 if (var->opcode == OP_GSHAREDVT_LOCAL || var->opcode == OP_GSHAREDVT_ARG_REGOFFSET) {
2894 } else if (var->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT) || (mini_type_is_vtype (var->inst_vtype) && !MONO_CLASS_IS_SIMD (ctx->cfg, var->klass))) {
2895 vtype = type_to_llvm_type (ctx, var->inst_vtype);
2898 /* Could be already created by an OP_VPHI */
2899 if (!ctx->addresses [var->dreg]) {
2900 ctx->addresses [var->dreg] = build_alloca (ctx, var->inst_vtype);
2901 //LLVMSetValueName (ctx->addresses [var->dreg], g_strdup_printf ("vreg_loc_%d", var->dreg));
2903 ctx->vreg_cli_types [var->dreg] = var->inst_vtype;
2907 names = g_new (char *, sig->param_count);
2908 mono_method_get_param_names (cfg->method, (const char **) names);
2910 for (i = 0; i < sig->param_count; ++i) {
2911 LLVMArgInfo *ainfo = &linfo->args [i + sig->hasthis];
2912 int reg = cfg->args [i + sig->hasthis]->dreg;
2915 pindex = ainfo->pindex;
2917 switch (ainfo->storage) {
2918 case LLVMArgVtypeInReg:
2919 case LLVMArgAsFpArgs: {
2920 LLVMValueRef args [8];
2923 pindex += ainfo->ndummy_fpargs;
2925 /* The argument is received as a set of int/fp arguments, store them into the real argument */
2926 memset (args, 0, sizeof (args));
2927 if (ainfo->storage == LLVMArgVtypeInReg) {
2928 args [0] = LLVMGetParam (ctx->lmethod, pindex);
2929 if (ainfo->pair_storage [1] != LLVMArgNone)
2930 args [1] = LLVMGetParam (ctx->lmethod, pindex + 1);
2932 g_assert (ainfo->nslots <= 8);
2933 for (j = 0; j < ainfo->nslots; ++j)
2934 args [j] = LLVMGetParam (ctx->lmethod, pindex + j);
2936 ctx->addresses [reg] = build_alloca (ctx, ainfo->type);
2938 emit_args_to_vtype (ctx, builder, ainfo->type, ctx->addresses [reg], ainfo, args);
2940 if (ainfo->storage == LLVMArgVtypeInReg && MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (ainfo->type))) {
2941 /* Treat these as normal values */
2942 ctx->values [reg] = LLVMBuildLoad (builder, ctx->addresses [reg], "");
2946 case LLVMArgVtypeByVal: {
2947 ctx->addresses [reg] = LLVMGetParam (ctx->lmethod, pindex);
2949 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (ainfo->type))) {
2950 /* Treat these as normal values */
2951 ctx->values [reg] = LLVMBuildLoad (builder, ctx->addresses [reg], "");
2955 case LLVMArgVtypeByRef: {
2956 /* The argument is passed by ref */
2957 ctx->addresses [reg] = LLVMGetParam (ctx->lmethod, pindex);
2960 case LLVMArgAsIArgs: {
2961 LLVMValueRef arg = LLVMGetParam (ctx->lmethod, pindex);
2964 /* The argument is received as an array of ints, store it into the real argument */
2965 ctx->addresses [reg] = build_alloca (ctx, ainfo->type);
2967 size = mono_class_value_size (mono_class_from_mono_type (ainfo->type), NULL);
2968 if (size < SIZEOF_VOID_P) {
2969 /* The upper bits of the registers might not be valid */
2970 LLVMValueRef val = LLVMBuildExtractValue (builder, arg, 0, "");
2971 LLVMValueRef dest = convert (ctx, ctx->addresses [reg], LLVMPointerType (LLVMIntType (size * 8), 0));
2972 LLVMBuildStore (ctx->builder, LLVMBuildTrunc (builder, val, LLVMIntType (size * 8), ""), dest);
2974 LLVMBuildStore (ctx->builder, arg, convert (ctx, ctx->addresses [reg], LLVMPointerType (LLVMTypeOf (arg), 0)));
2978 case LLVMArgVtypeAsScalar:
2979 g_assert_not_reached ();
2981 case LLVMArgGsharedvtFixed: {
2982 /* These are non-gsharedvt arguments passed by ref, the rest of the IR treats them as scalars */
2983 LLVMValueRef arg = LLVMGetParam (ctx->lmethod, pindex);
2986 name = g_strdup_printf ("arg_%s", names [i]);
2988 name = g_strdup_printf ("arg_%d", i);
2990 ctx->values [reg] = LLVMBuildLoad (builder, convert (ctx, arg, LLVMPointerType (type_to_llvm_type (ctx, ainfo->type), 0)), name);
2993 case LLVMArgGsharedvtFixedVtype: {
2994 LLVMValueRef arg = LLVMGetParam (ctx->lmethod, pindex);
2997 name = g_strdup_printf ("vtype_arg_%s", names [i]);
2999 name = g_strdup_printf ("vtype_arg_%d", i);
3001 /* Non-gsharedvt vtype argument passed by ref, the rest of the IR treats it as a vtype */
3002 g_assert (ctx->addresses [reg]);
3003 LLVMSetValueName (ctx->addresses [reg], name);
3004 LLVMBuildStore (builder, LLVMBuildLoad (builder, convert (ctx, arg, LLVMPointerType (type_to_llvm_type (ctx, ainfo->type), 0)), ""), ctx->addresses [reg]);
3007 case LLVMArgGsharedvtVariable:
3008 /* The IR treats these as variables with addresses */
3009 ctx->addresses [reg] = LLVMGetParam (ctx->lmethod, pindex);
3012 ctx->values [reg] = convert_full (ctx, ctx->values [reg], llvm_type_to_stack_type (cfg, type_to_llvm_type (ctx, ainfo->type)), type_is_unsigned (ctx, ainfo->type));
3019 emit_volatile_store (ctx, cfg->vret_addr->dreg);
3021 emit_volatile_store (ctx, cfg->args [0]->dreg);
3022 for (i = 0; i < sig->param_count; ++i)
3023 if (!mini_type_is_vtype (sig->params [i]))
3024 emit_volatile_store (ctx, cfg->args [i + sig->hasthis]->dreg);
3026 if (sig->hasthis && !cfg->rgctx_var && cfg->gshared) {
3027 LLVMValueRef this_alloc;
3030 * The exception handling code needs the location where the this argument was
3031 * stored for gshared methods. We create a separate alloca to hold it, and mark it
3032 * with the "mono.this" custom metadata to tell llvm that it needs to save its
3033 * location into the LSDA.
3035 this_alloc = mono_llvm_build_alloca (builder, ThisType (), LLVMConstInt (LLVMInt32Type (), 1, FALSE), 0, "");
3036 /* This volatile store will keep the alloca alive */
3037 mono_llvm_build_store (builder, ctx->values [cfg->args [0]->dreg], this_alloc, TRUE, LLVM_BARRIER_NONE);
3039 set_metadata_flag (this_alloc, "mono.this");
3042 if (cfg->rgctx_var) {
3043 LLVMValueRef rgctx_alloc, store;
3046 * We handle the rgctx arg similarly to the this pointer.
3048 g_assert (ctx->addresses [cfg->rgctx_var->dreg]);
3049 rgctx_alloc = ctx->addresses [cfg->rgctx_var->dreg];
3050 /* This volatile store will keep the alloca alive */
3051 store = mono_llvm_build_store (builder, convert (ctx, ctx->rgctx_arg, IntPtrType ()), rgctx_alloc, TRUE, LLVM_BARRIER_NONE);
3053 set_metadata_flag (rgctx_alloc, "mono.this");
3056 /* Initialize the method if needed */
3057 if (cfg->compile_aot && ctx->llvm_only) {
3058 /* Emit a location for the initialization code */
3059 ctx->init_bb = gen_bb (ctx, "INIT_BB");
3060 ctx->inited_bb = gen_bb (ctx, "INITED_BB");
3062 LLVMBuildBr (ctx->builder, ctx->init_bb);
3063 builder = ctx->builder = create_builder (ctx);
3064 LLVMPositionBuilderAtEnd (ctx->builder, ctx->inited_bb);
3065 ctx->bblocks [cfg->bb_entry->block_num].end_bblock = ctx->inited_bb;
3068 /* Compute nesting between clauses */
3069 ctx->nested_in = (GSList**)mono_mempool_alloc0 (cfg->mempool, sizeof (GSList*) * cfg->header->num_clauses);
3070 for (i = 0; i < cfg->header->num_clauses; ++i) {
3071 for (j = 0; j < cfg->header->num_clauses; ++j) {
3072 MonoExceptionClause *clause1 = &cfg->header->clauses [i];
3073 MonoExceptionClause *clause2 = &cfg->header->clauses [j];
3075 if (i != j && clause1->try_offset >= clause2->try_offset && clause1->handler_offset <= clause2->handler_offset)
3076 ctx->nested_in [i] = g_slist_prepend_mempool (cfg->mempool, ctx->nested_in [i], GINT_TO_POINTER (j));
3081 * For finally clauses, create an indicator variable telling OP_ENDFINALLY whenever
3082 * it needs to continue normally, or return back to the exception handling system.
3084 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
3088 if (!(bb->region != -1 && (bb->flags & BB_EXCEPTION_HANDLER)))
3091 clause_index = MONO_REGION_CLAUSE_INDEX (bb->region);
3092 g_hash_table_insert (ctx->region_to_handler, GUINT_TO_POINTER (mono_get_block_region_notry (cfg, bb->region)), bb);
3093 g_hash_table_insert (ctx->clause_to_handler, GINT_TO_POINTER (clause_index), bb);
3095 if (bb->in_scount == 0) {
3098 sprintf (name, "finally_ind_bb%d", bb->block_num);
3099 val = LLVMBuildAlloca (builder, LLVMInt32Type (), name);
3100 LLVMBuildStore (builder, LLVMConstInt (LLVMInt32Type (), 0, FALSE), val);
3102 ctx->bblocks [bb->block_num].finally_ind = val;
3104 /* Create a variable to hold the exception var */
3106 ctx->ex_var = LLVMBuildAlloca (builder, ObjRefType (), "exvar");
3110 * Create a new bblock which CALL_HANDLER/landing pads can branch to, because branching to the
3111 * LLVM bblock containing a landing pad causes problems for the
3112 * LLVM optimizer passes.
3114 sprintf (name, "BB%d_CALL_HANDLER_TARGET", bb->block_num);
3115 ctx->bblocks [bb->block_num].call_handler_target_bb = LLVMAppendBasicBlock (ctx->lmethod, name);
3117 ctx->builder = old_builder;
3121 process_call (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, MonoInst *ins)
3123 MonoCompile *cfg = ctx->cfg;
3124 LLVMValueRef *values = ctx->values;
3125 LLVMValueRef *addresses = ctx->addresses;
3126 MonoCallInst *call = (MonoCallInst*)ins;
3127 MonoMethodSignature *sig = call->signature;
3128 LLVMValueRef callee = NULL, lcall;
3130 LLVMCallInfo *cinfo;
3134 LLVMTypeRef llvm_sig;
3136 gboolean is_virtual, calli, preserveall;
3137 LLVMBuilderRef builder = *builder_ref;
3139 if ((call->signature->call_convention != MONO_CALL_DEFAULT) && !((call->signature->call_convention == MONO_CALL_C) && ctx->llvm_only)) {
3140 set_failure (ctx, "non-default callconv");
3144 cinfo = call->cinfo;
3146 if (call->rgctx_arg_reg)
3147 cinfo->rgctx_arg = TRUE;
3148 if (call->imt_arg_reg)
3149 cinfo->imt_arg = TRUE;
3151 vretaddr = (cinfo->ret.storage == LLVMArgVtypeRetAddr || cinfo->ret.storage == LLVMArgVtypeByRef || cinfo->ret.storage == LLVMArgGsharedvtFixed || cinfo->ret.storage == LLVMArgGsharedvtVariable || cinfo->ret.storage == LLVMArgGsharedvtFixedVtype);
3153 llvm_sig = sig_to_llvm_sig_full (ctx, sig, cinfo);
3157 is_virtual = (ins->opcode == OP_VOIDCALL_MEMBASE || ins->opcode == OP_CALL_MEMBASE || ins->opcode == OP_VCALL_MEMBASE || ins->opcode == OP_LCALL_MEMBASE || ins->opcode == OP_FCALL_MEMBASE || ins->opcode == OP_RCALL_MEMBASE);
3158 calli = !call->fptr_is_patch && (ins->opcode == OP_VOIDCALL_REG || ins->opcode == OP_CALL_REG || ins->opcode == OP_VCALL_REG || ins->opcode == OP_LCALL_REG || ins->opcode == OP_FCALL_REG || ins->opcode == OP_RCALL_REG);
3160 preserveall = FALSE;
3162 /* FIXME: Avoid creating duplicate methods */
3164 if (ins->flags & MONO_INST_HAS_METHOD) {
3168 if (cfg->compile_aot) {
3169 callee = get_callee (ctx, llvm_sig, MONO_PATCH_INFO_METHOD, call->method);
3171 set_failure (ctx, "can't encode patch");
3174 if (cfg->llvm_only && call->method->klass->image->assembly == ctx->module->assembly) {
3176 * Collect instructions representing the callee into a hash so they can be replaced
3177 * by the llvm method for the callee if the callee turns out to be direct
3178 * callable. Currently this only requires it to not fail llvm compilation.
3180 GSList *l = (GSList*)g_hash_table_lookup (ctx->method_to_callers, call->method);
3181 l = g_slist_prepend (l, callee);
3182 g_hash_table_insert (ctx->method_to_callers, call->method, l);
3186 static int tramp_index;
3189 name = g_strdup_printf ("tramp_%d", tramp_index);
3192 #if LLVM_API_VERSION > 100
3194 * Use our trampoline infrastructure for lazy compilation instead of llvm's.
3195 * Make all calls through a global. The address of the global will be saved in
3196 * MonoJitDomainInfo.llvm_jit_callees and updated when the method it refers to is
3199 LLVMValueRef tramp_var = g_hash_table_lookup (ctx->jit_callees, call->method);
3202 mono_create_jit_trampoline (mono_domain_get (),
3203 call->method, &error);
3204 if (!is_ok (&error)) {
3205 set_failure (ctx, mono_error_get_message (&error));
3206 mono_error_cleanup (&error);
3210 tramp_var = LLVMAddGlobal (ctx->lmodule, LLVMPointerType (llvm_sig, 0), name);
3211 LLVMSetInitializer (tramp_var, LLVMConstIntToPtr (LLVMConstInt (LLVMInt64Type (), (guint64)(size_t)target, FALSE), LLVMPointerType (llvm_sig, 0)));
3212 LLVMSetLinkage (tramp_var, LLVMExternalLinkage);
3213 g_hash_table_insert (ctx->jit_callees, call->method, tramp_var);
3215 callee = LLVMBuildLoad (builder, tramp_var, "");
3218 mono_create_jit_trampoline (mono_domain_get (),
3219 call->method, &error);
3220 if (!is_ok (&error)) {
3222 set_failure (ctx, mono_error_get_message (&error));
3223 mono_error_cleanup (&error);
3227 callee = LLVMAddFunction (ctx->lmodule, name, llvm_sig);
3230 LLVMAddGlobalMapping (ctx->module->ee, callee, target);
3235 if (!cfg->llvm_only && call->method && strstr (call->method->klass->name, "AsyncVoidMethodBuilder")) {
3236 /* LLVM miscompiles async methods */
3237 set_failure (ctx, "#13734");
3242 MonoJitICallInfo *info = mono_find_jit_icall_by_addr (call->fptr);
3248 memset (&ji, 0, sizeof (ji));
3249 ji.type = MONO_PATCH_INFO_JIT_ICALL_ADDR;
3250 ji.data.target = info->name;
3252 target = mono_resolve_patch_target (cfg->method, cfg->domain, NULL, &ji, FALSE);
3254 if (cfg->compile_aot) {
3255 callee = get_callee (ctx, llvm_sig, MONO_PATCH_INFO_INTERNAL_METHOD, (char*)info->name);
3257 set_failure (ctx, "can't encode patch");
3261 target = (gpointer)mono_icall_get_wrapper (info);
3262 callee = emit_jit_callee (ctx, "", llvm_sig, target);
3265 if (cfg->compile_aot) {
3267 if (cfg->abs_patches) {
3268 MonoJumpInfo *abs_ji = (MonoJumpInfo*)g_hash_table_lookup (cfg->abs_patches, call->fptr);
3270 callee = get_callee (ctx, llvm_sig, abs_ji->type, abs_ji->data.target);
3272 set_failure (ctx, "can't encode patch");
3278 set_failure (ctx, "aot");
3282 #if LLVM_API_VERSION > 100
3283 if (cfg->abs_patches) {
3284 MonoJumpInfo *abs_ji = (MonoJumpInfo*)g_hash_table_lookup (cfg->abs_patches, call->fptr);
3288 target = mono_resolve_patch_target (cfg->method, cfg->domain, NULL, abs_ji, FALSE, &error);
3289 mono_error_assert_ok (&error);
3290 callee = emit_jit_callee (ctx, "", llvm_sig, target);
3292 g_assert_not_reached ();
3295 g_assert_not_reached ();
3298 callee = LLVMAddFunction (ctx->lmodule, "", llvm_sig);
3300 if (cfg->abs_patches) {
3301 MonoJumpInfo *abs_ji = (MonoJumpInfo*)g_hash_table_lookup (cfg->abs_patches, call->fptr);
3306 * FIXME: Some trampolines might have
3307 * their own calling convention on some platforms.
3309 target = mono_resolve_patch_target (cfg->method, cfg->domain, NULL, abs_ji, FALSE, &error);
3310 mono_error_assert_ok (&error);
3311 LLVMAddGlobalMapping (ctx->module->ee, callee, target);
3315 LLVMAddGlobalMapping (ctx->module->ee, callee, (gpointer)call->fptr);
3322 int size = sizeof (gpointer);
3325 g_assert (ins->inst_offset % size == 0);
3326 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
3328 callee = convert (ctx, LLVMBuildLoad (builder, LLVMBuildGEP (builder, convert (ctx, values [ins->inst_basereg], LLVMPointerType (LLVMPointerType (IntPtrType (), 0), 0)), &index, 1, ""), ""), LLVMPointerType (llvm_sig, 0));
3330 callee = convert (ctx, values [ins->sreg1], LLVMPointerType (llvm_sig, 0));
3332 if (ins->flags & MONO_INST_HAS_METHOD) {
3337 * Collect and convert arguments
3339 nargs = (sig->param_count * 16) + sig->hasthis + vretaddr + call->rgctx_reg + call->imt_arg_reg;
3340 len = sizeof (LLVMValueRef) * nargs;
3341 args = (LLVMValueRef*)alloca (len);
3342 memset (args, 0, len);
3343 l = call->out_ireg_args;
3345 if (call->rgctx_arg_reg) {
3346 g_assert (values [call->rgctx_arg_reg]);
3347 g_assert (cinfo->rgctx_arg_pindex < nargs);
3349 * On ARM, the imt/rgctx argument is passed in a caller save register, but some of our trampolines etc. clobber it, leading to
3350 * problems is LLVM moves the arg assignment earlier. To work around this, save the argument into a stack slot and load
3351 * it using a volatile load.
3354 if (!ctx->imt_rgctx_loc)
3355 ctx->imt_rgctx_loc = build_alloca_llvm_type (ctx, ctx->module->ptr_type, sizeof (gpointer));
3356 LLVMBuildStore (builder, convert (ctx, ctx->values [call->rgctx_arg_reg], ctx->module->ptr_type), ctx->imt_rgctx_loc);
3357 args [cinfo->rgctx_arg_pindex] = mono_llvm_build_load (builder, ctx->imt_rgctx_loc, "", TRUE, LLVM_BARRIER_NONE);
3359 args [cinfo->rgctx_arg_pindex] = convert (ctx, values [call->rgctx_arg_reg], ctx->module->ptr_type);
3362 if (call->imt_arg_reg) {
3363 g_assert (!ctx->llvm_only);
3364 g_assert (values [call->imt_arg_reg]);
3365 g_assert (cinfo->imt_arg_pindex < nargs);
3367 if (!ctx->imt_rgctx_loc)
3368 ctx->imt_rgctx_loc = build_alloca_llvm_type (ctx, ctx->module->ptr_type, sizeof (gpointer));
3369 LLVMBuildStore (builder, convert (ctx, ctx->values [call->imt_arg_reg], ctx->module->ptr_type), ctx->imt_rgctx_loc);
3370 args [cinfo->imt_arg_pindex] = mono_llvm_build_load (builder, ctx->imt_rgctx_loc, "", TRUE, LLVM_BARRIER_NONE);
3372 args [cinfo->imt_arg_pindex] = convert (ctx, values [call->imt_arg_reg], ctx->module->ptr_type);
3375 switch (cinfo->ret.storage) {
3376 case LLVMArgGsharedvtVariable: {
3377 MonoInst *var = get_vreg_to_inst (cfg, call->inst.dreg);
3379 if (var && var->opcode == OP_GSHAREDVT_LOCAL) {
3380 args [cinfo->vret_arg_pindex] = convert (ctx, emit_gsharedvt_ldaddr (ctx, var->dreg), IntPtrType ());
3382 g_assert (addresses [call->inst.dreg]);
3383 args [cinfo->vret_arg_pindex] = addresses [call->inst.dreg];
3389 if (!addresses [call->inst.dreg])
3390 addresses [call->inst.dreg] = build_alloca (ctx, sig->ret);
3391 g_assert (cinfo->vret_arg_pindex < nargs);
3392 if (cinfo->ret.storage == LLVMArgVtypeByRef)
3393 args [cinfo->vret_arg_pindex] = addresses [call->inst.dreg];
3395 args [cinfo->vret_arg_pindex] = LLVMBuildPtrToInt (builder, addresses [call->inst.dreg], IntPtrType (), "");
3401 * Sometimes the same method is called with two different signatures (i.e. with and without 'this'), so
3402 * use the real callee for argument type conversion.
3404 LLVMTypeRef callee_type = LLVMGetElementType (LLVMTypeOf (callee));
3405 LLVMTypeRef *param_types = (LLVMTypeRef*)g_alloca (sizeof (LLVMTypeRef) * LLVMCountParamTypes (callee_type));
3406 LLVMGetParamTypes (callee_type, param_types);
3408 for (i = 0; i < sig->param_count + sig->hasthis; ++i) {
3411 LLVMArgInfo *ainfo = &call->cinfo->args [i];
3413 pindex = ainfo->pindex;
3415 regpair = (guint32)(gssize)(l->data);
3416 reg = regpair & 0xffffff;
3417 args [pindex] = values [reg];
3418 switch (ainfo->storage) {
3419 case LLVMArgVtypeInReg:
3420 case LLVMArgAsFpArgs: {
3424 for (j = 0; j < ainfo->ndummy_fpargs; ++j)
3425 args [pindex + j] = LLVMConstNull (LLVMDoubleType ());
3426 pindex += ainfo->ndummy_fpargs;
3428 g_assert (addresses [reg]);
3429 emit_vtype_to_args (ctx, builder, ainfo->type, addresses [reg], ainfo, args + pindex, &nargs);
3433 // FIXME: Get rid of the VMOVE
3436 case LLVMArgVtypeByVal:
3437 g_assert (addresses [reg]);
3438 args [pindex] = addresses [reg];
3440 case LLVMArgVtypeByRef: {
3441 g_assert (addresses [reg]);
3442 args [pindex] = convert (ctx, addresses [reg], LLVMPointerType (type_to_llvm_arg_type (ctx, ainfo->type), 0));
3445 case LLVMArgAsIArgs:
3446 g_assert (addresses [reg]);
3447 args [pindex] = LLVMBuildLoad (ctx->builder, convert (ctx, addresses [reg], LLVMPointerType (LLVMArrayType (IntPtrType (), ainfo->nslots), 0)), "");
3449 case LLVMArgVtypeAsScalar:
3450 g_assert_not_reached ();
3452 case LLVMArgGsharedvtFixed:
3453 case LLVMArgGsharedvtFixedVtype:
3454 g_assert (addresses [reg]);
3455 args [pindex] = convert (ctx, addresses [reg], LLVMPointerType (type_to_llvm_arg_type (ctx, ainfo->type), 0));
3457 case LLVMArgGsharedvtVariable:
3458 g_assert (addresses [reg]);
3459 args [pindex] = convert (ctx, addresses [reg], LLVMPointerType (IntPtrType (), 0));
3462 g_assert (args [pindex]);
3463 if (i == 0 && sig->hasthis)
3464 args [pindex] = convert (ctx, args [pindex], param_types [pindex]);
3466 args [pindex] = convert (ctx, args [pindex], type_to_llvm_arg_type (ctx, ainfo->type));
3469 g_assert (pindex <= nargs);
3474 // FIXME: Align call sites
3480 lcall = emit_call (ctx, bb, &builder, callee, args, LLVMCountParamTypes (llvm_sig));
3483 * Modify cconv and parameter attributes to pass rgctx/imt correctly.
3485 #if defined(MONO_ARCH_IMT_REG) && defined(MONO_ARCH_RGCTX_REG)
3486 g_assert (MONO_ARCH_IMT_REG == MONO_ARCH_RGCTX_REG);
3488 /* The two can't be used together, so use only one LLVM calling conv to pass them */
3489 g_assert (!(call->rgctx_arg_reg && call->imt_arg_reg));
3490 if (!sig->pinvoke && !cfg->llvm_only)
3491 LLVMSetInstructionCallConv (lcall, LLVMMono1CallConv);
3493 mono_llvm_set_call_preserveall_cc (lcall);
3495 if (cinfo->ret.storage == LLVMArgVtypeByRef)
3496 LLVMAddInstrAttribute (lcall, 1 + cinfo->vret_arg_pindex, LLVMStructRetAttribute);
3497 if (!ctx->llvm_only && call->rgctx_arg_reg)
3498 LLVMAddInstrAttribute (lcall, 1 + cinfo->rgctx_arg_pindex, LLVMInRegAttribute);
3499 if (call->imt_arg_reg)
3500 LLVMAddInstrAttribute (lcall, 1 + cinfo->imt_arg_pindex, LLVMInRegAttribute);
3502 /* Add byval attributes if needed */
3503 for (i = 0; i < sig->param_count; ++i) {
3504 LLVMArgInfo *ainfo = &call->cinfo->args [i + sig->hasthis];
3506 if (ainfo && ainfo->storage == LLVMArgVtypeByVal)
3507 LLVMAddInstrAttribute (lcall, 1 + ainfo->pindex, LLVMByValAttribute);
3511 * Convert the result
3513 switch (cinfo->ret.storage) {
3514 case LLVMArgVtypeInReg: {
3515 LLVMValueRef regs [2];
3517 if (LLVMTypeOf (lcall) == LLVMVoidType ())
3521 if (!addresses [ins->dreg])
3522 addresses [ins->dreg] = build_alloca (ctx, sig->ret);
3524 regs [0] = LLVMBuildExtractValue (builder, lcall, 0, "");
3525 if (cinfo->ret.pair_storage [1] != LLVMArgNone)
3526 regs [1] = LLVMBuildExtractValue (builder, lcall, 1, "");
3527 emit_args_to_vtype (ctx, builder, sig->ret, addresses [ins->dreg], &cinfo->ret, regs);
3530 case LLVMArgVtypeByVal:
3531 if (!addresses [call->inst.dreg])
3532 addresses [call->inst.dreg] = build_alloca (ctx, sig->ret);
3533 LLVMBuildStore (builder, lcall, addresses [call->inst.dreg]);
3535 case LLVMArgFpStruct:
3536 if (!addresses [call->inst.dreg])
3537 addresses [call->inst.dreg] = build_alloca (ctx, sig->ret);
3538 LLVMBuildStore (builder, lcall, convert_full (ctx, addresses [call->inst.dreg], LLVMPointerType (LLVMTypeOf (lcall), 0), FALSE));
3540 case LLVMArgVtypeAsScalar:
3541 if (!addresses [call->inst.dreg])
3542 addresses [call->inst.dreg] = build_alloca (ctx, sig->ret);
3543 LLVMBuildStore (builder, lcall, convert_full (ctx, addresses [call->inst.dreg], LLVMPointerType (LLVMTypeOf (lcall), 0), FALSE));
3545 case LLVMArgVtypeRetAddr:
3546 case LLVMArgVtypeByRef:
3547 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (sig->ret))) {
3548 /* Some opcodes like STOREX_MEMBASE access these by value */
3549 g_assert (addresses [call->inst.dreg]);
3550 values [ins->dreg] = LLVMBuildLoad (builder, convert_full (ctx, addresses [call->inst.dreg], LLVMPointerType (type_to_llvm_type (ctx, sig->ret), 0), FALSE), "");
3553 case LLVMArgGsharedvtVariable:
3555 case LLVMArgGsharedvtFixed:
3556 case LLVMArgGsharedvtFixedVtype:
3557 values [ins->dreg] = LLVMBuildLoad (builder, convert_full (ctx, addresses [call->inst.dreg], LLVMPointerType (type_to_llvm_type (ctx, sig->ret), 0), FALSE), "");
3560 if (sig->ret->type != MONO_TYPE_VOID)
3561 /* If the method returns an unsigned value, need to zext it */
3562 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));
3566 *builder_ref = ctx->builder;
3570 emit_llvmonly_throw (EmitContext *ctx, MonoBasicBlock *bb, gboolean rethrow, LLVMValueRef exc)
3572 const char *icall_name = rethrow ? "mono_llvm_rethrow_exception" : "mono_llvm_throw_exception";
3573 LLVMValueRef callee = rethrow ? ctx->module->rethrow : ctx->module->throw_icall;
3575 LLVMTypeRef exc_type = type_to_llvm_type (ctx, &mono_get_exception_class ()->byval_arg);
3578 LLVMTypeRef fun_sig = LLVMFunctionType1 (LLVMVoidType (), exc_type, FALSE);
3580 if (ctx->cfg->compile_aot) {
3581 callee = get_callee (ctx, fun_sig, MONO_PATCH_INFO_JIT_ICALL_ADDR, icall_name);
3583 callee = LLVMAddFunction (ctx->lmodule, icall_name, fun_sig);
3584 LLVMAddGlobalMapping (ctx->module->ee, callee, resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name));
3585 mono_memory_barrier ();
3588 ctx->module->rethrow = callee;
3590 ctx->module->throw_icall = callee;
3594 LLVMValueRef args [2];
3596 args [0] = convert (ctx, exc, exc_type);
3597 emit_call (ctx, bb, &ctx->builder, callee, args, 1);
3599 LLVMBuildUnreachable (ctx->builder);
3601 ctx->builder = create_builder (ctx);
3605 emit_throw (EmitContext *ctx, MonoBasicBlock *bb, gboolean rethrow, LLVMValueRef exc)
3607 MonoMethodSignature *throw_sig;
3608 LLVMValueRef callee, arg;
3609 const char *icall_name;
3611 callee = rethrow ? ctx->module->rethrow : ctx->module->throw_icall;
3612 icall_name = rethrow ? "mono_arch_rethrow_exception" : "mono_arch_throw_exception";
3615 throw_sig = mono_metadata_signature_alloc (mono_get_corlib (), 1);
3616 throw_sig->ret = &mono_get_void_class ()->byval_arg;
3617 throw_sig->params [0] = &mono_get_object_class ()->byval_arg;
3618 if (ctx->cfg->compile_aot) {
3619 callee = get_callee (ctx, sig_to_llvm_sig (ctx, throw_sig), MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
3624 * LLVM doesn't push the exception argument, so we need a different
3627 target = resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, rethrow ? "llvm_rethrow_exception_trampoline" : "llvm_throw_exception_trampoline");
3629 target = resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
3631 callee = emit_jit_callee (ctx, icall_name, sig_to_llvm_sig (ctx, throw_sig), target);
3634 mono_memory_barrier ();
3635 #if LLVM_API_VERSION < 100
3637 ctx->module->rethrow = callee;
3639 ctx->module->throw_icall = callee;
3642 arg = convert (ctx, exc, type_to_llvm_type (ctx, &mono_get_object_class ()->byval_arg));
3643 emit_call (ctx, bb, &ctx->builder, callee, &arg, 1);
3647 emit_resume_eh (EmitContext *ctx, MonoBasicBlock *bb)
3649 const char *icall_name = "mono_llvm_resume_exception";
3650 LLVMValueRef callee = ctx->module->resume_eh;
3652 LLVMTypeRef fun_sig = LLVMFunctionType0 (LLVMVoidType (), FALSE);
3655 if (ctx->cfg->compile_aot) {
3656 callee = get_callee (ctx, fun_sig, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
3658 callee = LLVMAddFunction (ctx->lmodule, icall_name, fun_sig);
3659 LLVMAddGlobalMapping (ctx->module->ee, callee, resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name));
3660 mono_memory_barrier ();
3662 ctx->module->resume_eh = callee;
3666 emit_call (ctx, bb, &ctx->builder, callee, NULL, 0);
3668 LLVMBuildUnreachable (ctx->builder);
3670 ctx->builder = create_builder (ctx);
3674 mono_llvm_emit_clear_exception_call (EmitContext *ctx, LLVMBuilderRef builder)
3676 const char *icall_name = "mono_llvm_clear_exception";
3678 LLVMTypeRef call_sig = LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE);
3679 LLVMValueRef callee = NULL;
3682 if (ctx->cfg->compile_aot) {
3683 callee = get_callee (ctx, call_sig, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
3685 // FIXME: This is broken.
3686 callee = LLVMAddFunction (ctx->lmodule, icall_name, call_sig);
3690 g_assert (builder && callee);
3692 return LLVMBuildCall (builder, callee, NULL, 0, "");
3696 mono_llvm_emit_load_exception_call (EmitContext *ctx, LLVMBuilderRef builder)
3698 const char *icall_name = "mono_llvm_load_exception";
3700 LLVMTypeRef call_sig = LLVMFunctionType (ObjRefType (), NULL, 0, FALSE);
3701 LLVMValueRef callee = NULL;
3704 if (ctx->cfg->compile_aot) {
3705 callee = get_callee (ctx, call_sig, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
3707 // FIXME: This is broken.
3708 callee = LLVMAddFunction (ctx->lmodule, icall_name, call_sig);
3712 g_assert (builder && callee);
3714 return LLVMBuildCall (builder, callee, NULL, 0, icall_name);
3719 mono_llvm_emit_match_exception_call (EmitContext *ctx, LLVMBuilderRef builder, gint32 region_start, gint32 region_end)
3721 const char *icall_name = "mono_llvm_match_exception";
3723 ctx->builder = builder;
3725 const int num_args = 5;
3726 LLVMValueRef args [num_args];
3727 args [0] = convert (ctx, get_aotconst (ctx, MONO_PATCH_INFO_AOT_JIT_INFO, GINT_TO_POINTER (ctx->cfg->method_index)), IntPtrType ());
3728 args [1] = LLVMConstInt (LLVMInt32Type (), region_start, 0);
3729 args [2] = LLVMConstInt (LLVMInt32Type (), region_end, 0);
3730 if (ctx->cfg->rgctx_var) {
3731 LLVMValueRef rgctx_alloc = ctx->addresses [ctx->cfg->rgctx_var->dreg];
3732 g_assert (rgctx_alloc);
3733 args [3] = LLVMBuildLoad (builder, convert (ctx, rgctx_alloc, LLVMPointerType (IntPtrType (), 0)), "");
3735 args [3] = LLVMConstInt (IntPtrType (), 0, 0);
3738 args [4] = convert (ctx, ctx->this_arg, IntPtrType ());
3740 args [4] = LLVMConstInt (IntPtrType (), 0, 0);
3742 LLVMTypeRef match_sig = LLVMFunctionType5 (LLVMInt32Type (), IntPtrType (), LLVMInt32Type (), LLVMInt32Type (), IntPtrType (), IntPtrType (), FALSE);
3743 LLVMValueRef callee = ctx->module->match_exc;
3746 if (ctx->cfg->compile_aot) {
3747 ctx->builder = builder;
3748 // get_callee expects ctx->builder to be the emitting builder
3749 callee = get_callee (ctx, match_sig, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
3751 callee = ctx->module->match_exc = LLVMAddFunction (ctx->lmodule, icall_name, match_sig);
3752 LLVMAddGlobalMapping (ctx->module->ee, ctx->module->match_exc, resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name));
3753 ctx->module->match_exc = callee;
3754 mono_memory_barrier ();
3758 g_assert (builder && callee);
3760 g_assert (ctx->ex_var);
3762 return LLVMBuildCall (builder, callee, args, num_args, icall_name);
3765 // FIXME: This won't work because the code-finding makes this
3767 /*#define MONO_PERSONALITY_DEBUG*/
3769 #ifdef MONO_PERSONALITY_DEBUG
3770 static const gboolean use_debug_personality = TRUE;
3771 static const char *default_personality_name = "mono_debug_personality";
3773 static const gboolean use_debug_personality = FALSE;
3774 static const char *default_personality_name = "__gxx_personality_v0";
3778 default_cpp_lpad_exc_signature (void)
3780 static gboolean inited = FALSE;
3781 static LLVMTypeRef sig;
3784 LLVMTypeRef signature [2];
3785 signature [0] = LLVMPointerType (LLVMInt8Type (), 0);
3786 signature [1] = LLVMInt32Type ();
3787 sig = LLVMStructType (signature, 2, FALSE);
3795 get_mono_personality (EmitContext *ctx)
3797 LLVMValueRef personality = NULL;
3798 static gint32 mapping_inited = FALSE;
3799 LLVMTypeRef personality_type = LLVMFunctionType (LLVMInt32Type (), NULL, 0, TRUE);
3801 if (!use_debug_personality) {
3802 if (ctx->cfg->compile_aot) {
3803 personality = get_intrinsic (ctx, default_personality_name);
3804 } else if (InterlockedCompareExchange (&mapping_inited, 1, 0) == 0) {
3805 personality = LLVMAddFunction (ctx->lmodule, default_personality_name, personality_type);
3806 LLVMAddGlobalMapping (ctx->module->ee, personality, personality);
3809 if (ctx->cfg->compile_aot) {
3810 personality = get_callee (ctx, personality_type, MONO_PATCH_INFO_INTERNAL_METHOD, default_personality_name);
3812 personality = LLVMAddFunction (ctx->lmodule, default_personality_name, personality_type);
3813 LLVMAddGlobalMapping (ctx->module->ee, personality, resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, default_personality_name));
3814 mono_memory_barrier ();
3818 g_assert (personality);
3822 static LLVMBasicBlockRef
3823 emit_landing_pad (EmitContext *ctx, int group_index, int group_size)
3825 MonoCompile *cfg = ctx->cfg;
3826 LLVMBuilderRef old_builder = ctx->builder;
3827 MonoExceptionClause *group_start = cfg->header->clauses + group_index;
3829 LLVMBuilderRef lpadBuilder = create_builder (ctx);
3830 ctx->builder = lpadBuilder;
3832 MonoBasicBlock *handler_bb = cfg->cil_offset_to_bb [CLAUSE_START (group_start)];
3833 g_assert (handler_bb);
3835 // <resultval> = landingpad <somety> personality <type> <pers_fn> <clause>+
3836 LLVMValueRef personality = get_mono_personality (ctx);
3837 g_assert (personality);
3839 char *bb_name = g_strdup_printf ("LPAD%d_BB", group_index);
3840 LLVMBasicBlockRef lpad_bb = gen_bb (ctx, bb_name);
3842 LLVMPositionBuilderAtEnd (lpadBuilder, lpad_bb);
3843 LLVMValueRef landing_pad = LLVMBuildLandingPad (lpadBuilder, default_cpp_lpad_exc_signature (), personality, 0, "");
3844 g_assert (landing_pad);
3846 LLVMValueRef cast = LLVMBuildBitCast (lpadBuilder, ctx->module->sentinel_exception, LLVMPointerType (LLVMInt8Type (), 0), "int8TypeInfo");
3847 LLVMAddClause (landing_pad, cast);
3849 LLVMBasicBlockRef resume_bb = gen_bb (ctx, "RESUME_BB");
3850 LLVMBuilderRef resume_builder = create_builder (ctx);
3851 ctx->builder = resume_builder;
3852 LLVMPositionBuilderAtEnd (resume_builder, resume_bb);
3854 emit_resume_eh (ctx, handler_bb);
3857 ctx->builder = lpadBuilder;
3858 LLVMPositionBuilderAtEnd (lpadBuilder, lpad_bb);
3860 gboolean finally_only = TRUE;
3862 MonoExceptionClause *group_cursor = group_start;
3864 for (int i = 0; i < group_size; i ++) {
3865 if (!(group_cursor->flags & MONO_EXCEPTION_CLAUSE_FINALLY))
3866 finally_only = FALSE;
3872 // Handle landing pad inlining
3874 if (!finally_only) {
3875 // So at each level of the exception stack we will match the exception again.
3876 // During that match, we need to compare against the handler types for the current
3877 // protected region. We send the try start and end so that we can only check against
3878 // handlers for this lexical protected region.
3879 LLVMValueRef match = mono_llvm_emit_match_exception_call (ctx, lpadBuilder, group_start->try_offset, group_start->try_offset + group_start->try_len);
3881 // if returns -1, resume
3882 LLVMValueRef switch_ins = LLVMBuildSwitch (lpadBuilder, match, resume_bb, group_size);
3884 // else move to that target bb
3885 for (int i=0; i < group_size; i++) {
3886 MonoExceptionClause *clause = group_start + i;
3887 int clause_index = clause - cfg->header->clauses;
3888 MonoBasicBlock *handler_bb = (MonoBasicBlock*)g_hash_table_lookup (ctx->clause_to_handler, GINT_TO_POINTER (clause_index));
3889 g_assert (handler_bb);
3890 g_assert (ctx->bblocks [handler_bb->block_num].call_handler_target_bb);
3891 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), clause_index, FALSE), ctx->bblocks [handler_bb->block_num].call_handler_target_bb);
3894 int clause_index = group_start - cfg->header->clauses;
3895 MonoBasicBlock *finally_bb = (MonoBasicBlock*)g_hash_table_lookup (ctx->clause_to_handler, GINT_TO_POINTER (clause_index));
3896 g_assert (finally_bb);
3898 LLVMBuildBr (ctx->builder, ctx->bblocks [finally_bb->block_num].call_handler_target_bb);
3901 ctx->builder = old_builder;
3908 emit_llvmonly_handler_start (EmitContext *ctx, MonoBasicBlock *bb, LLVMBasicBlockRef cbb)
3910 int clause_index = MONO_REGION_CLAUSE_INDEX (bb->region);
3911 MonoExceptionClause *clause = &ctx->cfg->header->clauses [clause_index];
3913 // Make exception available to catch blocks
3914 if (!(clause->flags & MONO_EXCEPTION_CLAUSE_FINALLY)) {
3915 LLVMValueRef mono_exc = mono_llvm_emit_load_exception_call (ctx, ctx->builder);
3917 g_assert (ctx->ex_var);
3918 LLVMBuildStore (ctx->builder, LLVMBuildBitCast (ctx->builder, mono_exc, ObjRefType (), ""), ctx->ex_var);
3920 if (bb->in_scount == 1) {
3921 MonoInst *exvar = bb->in_stack [0];
3922 g_assert (!ctx->values [exvar->dreg]);
3923 g_assert (ctx->ex_var);
3924 ctx->values [exvar->dreg] = LLVMBuildLoad (ctx->builder, ctx->ex_var, "save_exception");
3925 emit_volatile_store (ctx, exvar->dreg);
3928 mono_llvm_emit_clear_exception_call (ctx, ctx->builder);
3931 LLVMBuilderRef handler_builder = create_builder (ctx);
3932 LLVMBasicBlockRef target_bb = ctx->bblocks [bb->block_num].call_handler_target_bb;
3933 LLVMPositionBuilderAtEnd (handler_builder, target_bb);
3935 // Make the handler code end with a jump to cbb
3936 LLVMBuildBr (handler_builder, cbb);
3940 emit_handler_start (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef builder)
3942 MonoCompile *cfg = ctx->cfg;
3943 LLVMValueRef *values = ctx->values;
3944 LLVMModuleRef lmodule = ctx->lmodule;
3945 BBInfo *bblocks = ctx->bblocks;
3947 LLVMValueRef personality;
3948 LLVMValueRef landing_pad;
3949 LLVMBasicBlockRef target_bb;
3951 static int ti_generator;
3953 LLVMValueRef type_info;
3957 // <resultval> = landingpad <somety> personality <type> <pers_fn> <clause>+
3959 if (cfg->compile_aot) {
3960 /* Use a dummy personality function */
3961 personality = LLVMGetNamedFunction (lmodule, "mono_personality");
3962 g_assert (personality);
3964 #if LLVM_API_VERSION > 100
3965 LLVMTypeRef personality_type = LLVMFunctionType (LLVMInt32Type (), NULL, 0, TRUE);
3966 personality = LLVMAddFunction (ctx->lmodule, "mono_personality", personality_type);
3967 LLVMAddFunctionAttr (personality, LLVMNoUnwindAttribute);
3968 LLVMBasicBlockRef entry_bb = LLVMAppendBasicBlock (personality, "ENTRY");
3969 LLVMBuilderRef builder2 = LLVMCreateBuilder ();
3970 LLVMPositionBuilderAtEnd (builder2, entry_bb);
3971 LLVMBuildRet (builder2, LLVMConstInt (LLVMInt32Type (), 0, FALSE));
3973 static gint32 mapping_inited;
3975 personality = LLVMGetNamedFunction (lmodule, "mono_personality");
3977 if (InterlockedCompareExchange (&mapping_inited, 1, 0) == 0)
3978 LLVMAddGlobalMapping (ctx->module->ee, personality, (gpointer)mono_personality);
3982 i8ptr = LLVMPointerType (LLVMInt8Type (), 0);
3984 clause_index = (mono_get_block_region_notry (cfg, bb->region) >> 8) - 1;
3987 * Create the type info
3989 sprintf (ti_name, "type_info_%d", ti_generator);
3992 if (cfg->compile_aot) {
3993 /* decode_eh_frame () in aot-runtime.c will decode this */
3994 type_info = LLVMAddGlobal (lmodule, LLVMInt32Type (), ti_name);
3995 LLVMSetInitializer (type_info, LLVMConstInt (LLVMInt32Type (), clause_index, FALSE));
3998 * These symbols are not really used, the clause_index is embedded into the EH tables generated by DwarfMonoException in LLVM.
4000 LLVMSetLinkage (type_info, LLVMInternalLinkage);
4002 #if LLVM_API_VERSION > 100
4003 type_info = LLVMAddGlobal (lmodule, LLVMInt32Type (), ti_name);
4004 LLVMSetInitializer (type_info, LLVMConstInt (LLVMInt32Type (), clause_index, FALSE));
4009 * After the cfg mempool is freed, the type info will point to stale memory,
4010 * but this is not a problem, since we decode it once in exception_cb during
4013 ti = (gint32*)mono_mempool_alloc (cfg->mempool, sizeof (gint32));
4014 *(gint32*)ti = clause_index;
4016 type_info = LLVMAddGlobal (lmodule, i8ptr, ti_name);
4018 LLVMAddGlobalMapping (ctx->module->ee, type_info, ti);
4023 LLVMTypeRef members [2], ret_type;
4025 members [0] = i8ptr;
4026 members [1] = LLVMInt32Type ();
4027 ret_type = LLVMStructType (members, 2, FALSE);
4029 landing_pad = LLVMBuildLandingPad (builder, ret_type, personality, 1, "");
4030 LLVMAddClause (landing_pad, type_info);
4032 /* Store the exception into the exvar */
4034 LLVMBuildStore (builder, convert (ctx, LLVMBuildExtractValue (builder, landing_pad, 0, "ex_obj"), ObjRefType ()), ctx->ex_var);
4038 * LLVM throw sites are associated with a one landing pad, and LLVM generated
4039 * code expects control to be transferred to this landing pad even in the
4040 * presence of nested clauses. The landing pad needs to branch to the landing
4041 * pads belonging to nested clauses based on the selector value returned by
4042 * the landing pad instruction, which is passed to the landing pad in a
4043 * register by the EH code.
4045 target_bb = bblocks [bb->block_num].call_handler_target_bb;
4046 g_assert (target_bb);
4049 * Branch to the correct landing pad
4051 LLVMValueRef ex_selector = LLVMBuildExtractValue (builder, landing_pad, 1, "ex_selector");
4052 LLVMValueRef switch_ins = LLVMBuildSwitch (builder, ex_selector, target_bb, 0);
4054 for (l = ctx->nested_in [clause_index]; l; l = l->next) {
4055 int nesting_clause_index = GPOINTER_TO_INT (l->data);
4056 MonoBasicBlock *handler_bb;
4058 handler_bb = (MonoBasicBlock*)g_hash_table_lookup (ctx->clause_to_handler, GINT_TO_POINTER (nesting_clause_index));
4059 g_assert (handler_bb);
4061 g_assert (ctx->bblocks [handler_bb->block_num].call_handler_target_bb);
4062 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), nesting_clause_index, FALSE), ctx->bblocks [handler_bb->block_num].call_handler_target_bb);
4065 /* Start a new bblock which CALL_HANDLER can branch to */
4066 target_bb = bblocks [bb->block_num].call_handler_target_bb;
4068 ctx->builder = builder = create_builder (ctx);
4069 LLVMPositionBuilderAtEnd (ctx->builder, target_bb);
4071 ctx->bblocks [bb->block_num].end_bblock = target_bb;
4073 /* Store the exception into the IL level exvar */
4074 if (bb->in_scount == 1) {
4075 g_assert (bb->in_scount == 1);
4076 exvar = bb->in_stack [0];
4078 // FIXME: This is shared with filter clauses ?
4079 g_assert (!values [exvar->dreg]);
4081 g_assert (ctx->ex_var);
4082 values [exvar->dreg] = LLVMBuildLoad (builder, ctx->ex_var, "");
4083 emit_volatile_store (ctx, exvar->dreg);
4089 process_bb (EmitContext *ctx, MonoBasicBlock *bb)
4091 MonoCompile *cfg = ctx->cfg;
4092 MonoMethodSignature *sig = ctx->sig;
4093 LLVMValueRef method = ctx->lmethod;
4094 LLVMValueRef *values = ctx->values;
4095 LLVMValueRef *addresses = ctx->addresses;
4096 LLVMCallInfo *linfo = ctx->linfo;
4097 BBInfo *bblocks = ctx->bblocks;
4099 LLVMBasicBlockRef cbb;
4100 LLVMBuilderRef builder, starting_builder;
4101 gboolean has_terminator;
4103 LLVMValueRef lhs, rhs;
4106 cbb = get_end_bb (ctx, bb);
4108 builder = create_builder (ctx);
4109 ctx->builder = builder;
4110 LLVMPositionBuilderAtEnd (builder, cbb);
4115 if (bb->flags & BB_EXCEPTION_HANDLER) {
4116 if (!ctx->llvm_only && !bblocks [bb->block_num].invoke_target) {
4117 set_failure (ctx, "handler without invokes");
4122 emit_llvmonly_handler_start (ctx, bb, cbb);
4124 emit_handler_start (ctx, bb, builder);
4127 builder = ctx->builder;
4130 has_terminator = FALSE;
4131 starting_builder = builder;
4132 for (ins = bb->code; ins; ins = ins->next) {
4133 const char *spec = LLVM_INS_INFO (ins->opcode);
4135 char dname_buf [128];
4137 emit_dbg_loc (ctx, builder, ins->cil_code);
4142 * Some steps in llc are non-linear in the size of basic blocks, see #5714.
4143 * Start a new bblock. If the llvm optimization passes merge these, we
4144 * can work around that by doing a volatile load + cond branch from
4145 * localloc-ed memory.
4147 //set_failure (ctx, "basic block too long");
4148 cbb = gen_bb (ctx, "CONT_LONG_BB");
4149 LLVMBuildBr (ctx->builder, cbb);
4150 ctx->builder = builder = create_builder (ctx);
4151 LLVMPositionBuilderAtEnd (builder, cbb);
4152 ctx->bblocks [bb->block_num].end_bblock = cbb;
4157 /* There could be instructions after a terminator, skip them */
4160 if (spec [MONO_INST_DEST] != ' ' && !MONO_IS_STORE_MEMBASE (ins)) {
4161 sprintf (dname_buf, "t%d", ins->dreg);
4165 if (spec [MONO_INST_SRC1] != ' ' && spec [MONO_INST_SRC1] != 'v') {
4166 MonoInst *var = get_vreg_to_inst (cfg, ins->sreg1);
4168 if (var && var->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT) && var->opcode != OP_GSHAREDVT_ARG_REGOFFSET) {
4169 lhs = emit_volatile_load (ctx, ins->sreg1);
4171 /* It is ok for SETRET to have an uninitialized argument */
4172 if (!values [ins->sreg1] && ins->opcode != OP_SETRET) {
4173 set_failure (ctx, "sreg1");
4176 lhs = values [ins->sreg1];
4182 if (spec [MONO_INST_SRC2] != ' ' && spec [MONO_INST_SRC2] != ' ') {
4183 MonoInst *var = get_vreg_to_inst (cfg, ins->sreg2);
4184 if (var && var->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT)) {
4185 rhs = emit_volatile_load (ctx, ins->sreg2);
4187 if (!values [ins->sreg2]) {
4188 set_failure (ctx, "sreg2");
4191 rhs = values [ins->sreg2];
4197 //mono_print_ins (ins);
4198 switch (ins->opcode) {
4201 case OP_LIVERANGE_START:
4202 case OP_LIVERANGE_END:
4205 values [ins->dreg] = LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE);
4208 #if SIZEOF_VOID_P == 4
4209 values [ins->dreg] = LLVMConstInt (LLVMInt64Type (), GET_LONG_IMM (ins), FALSE);
4211 values [ins->dreg] = LLVMConstInt (LLVMInt64Type (), (gint64)ins->inst_c0, FALSE);
4215 values [ins->dreg] = LLVMConstReal (LLVMDoubleType (), *(double*)ins->inst_p0);
4219 values [ins->dreg] = LLVMConstReal (LLVMFloatType (), *(float*)ins->inst_p0);
4221 values [ins->dreg] = LLVMConstFPExt (LLVMConstReal (LLVMFloatType (), *(float*)ins->inst_p0), LLVMDoubleType ());
4223 case OP_DUMMY_ICONST:
4224 values [ins->dreg] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
4226 case OP_DUMMY_I8CONST:
4227 values [ins->dreg] = LLVMConstInt (LLVMInt64Type (), 0, FALSE);
4229 case OP_DUMMY_R8CONST:
4230 values [ins->dreg] = LLVMConstReal (LLVMDoubleType (), 0.0f);
4233 LLVMBasicBlockRef target_bb = get_bb (ctx, ins->inst_target_bb);
4234 LLVMBuildBr (builder, target_bb);
4235 has_terminator = TRUE;
4242 LLVMBasicBlockRef new_bb;
4243 LLVMBuilderRef new_builder;
4245 // The default branch is already handled
4246 // FIXME: Handle it here
4248 /* Start new bblock */
4249 sprintf (bb_name, "SWITCH_DEFAULT_BB%d", ctx->default_index ++);
4250 new_bb = LLVMAppendBasicBlock (ctx->lmethod, bb_name);
4252 lhs = convert (ctx, lhs, LLVMInt32Type ());
4253 v = LLVMBuildSwitch (builder, lhs, new_bb, GPOINTER_TO_UINT (ins->klass));
4254 for (i = 0; i < GPOINTER_TO_UINT (ins->klass); ++i) {
4255 MonoBasicBlock *target_bb = ins->inst_many_bb [i];
4257 LLVMAddCase (v, LLVMConstInt (LLVMInt32Type (), i, FALSE), get_bb (ctx, target_bb));
4260 new_builder = create_builder (ctx);
4261 LLVMPositionBuilderAtEnd (new_builder, new_bb);
4262 LLVMBuildUnreachable (new_builder);
4264 has_terminator = TRUE;
4265 g_assert (!ins->next);
4271 switch (linfo->ret.storage) {
4272 case LLVMArgVtypeInReg: {
4273 LLVMTypeRef ret_type = LLVMGetReturnType (LLVMGetElementType (LLVMTypeOf (method)));
4274 LLVMValueRef val, addr, retval;
4277 retval = LLVMGetUndef (ret_type);
4279 if (!addresses [ins->sreg1]) {
4281 * The return type is an LLVM vector type, have to convert between it and the
4282 * real return type which is a struct type.
4284 g_assert (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (sig->ret)));
4285 /* Convert to 2xi64 first */
4286 val = LLVMBuildBitCast (builder, values [ins->sreg1], LLVMVectorType (IntPtrType (), 2), "");
4288 for (i = 0; i < 2; ++i) {
4289 if (linfo->ret.pair_storage [i] == LLVMArgInIReg) {
4290 retval = LLVMBuildInsertValue (builder, retval, LLVMBuildExtractElement (builder, val, LLVMConstInt (LLVMInt32Type (), i, FALSE), ""), i, "");
4292 g_assert (linfo->ret.pair_storage [i] == LLVMArgNone);
4296 addr = LLVMBuildBitCast (builder, addresses [ins->sreg1], LLVMPointerType (ret_type, 0), "");
4297 for (i = 0; i < 2; ++i) {
4298 if (linfo->ret.pair_storage [i] == LLVMArgInIReg) {
4299 LLVMValueRef indexes [2], part_addr;
4301 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
4302 indexes [1] = LLVMConstInt (LLVMInt32Type (), i, FALSE);
4303 part_addr = LLVMBuildGEP (builder, addr, indexes, 2, "");
4305 retval = LLVMBuildInsertValue (builder, retval, LLVMBuildLoad (builder, part_addr, ""), i, "");
4307 g_assert (linfo->ret.pair_storage [i] == LLVMArgNone);
4311 LLVMBuildRet (builder, retval);
4314 case LLVMArgVtypeAsScalar: {
4315 LLVMTypeRef ret_type = LLVMGetReturnType (LLVMGetElementType (LLVMTypeOf (method)));
4316 LLVMValueRef retval;
4318 g_assert (addresses [ins->sreg1]);
4320 retval = LLVMBuildLoad (builder, LLVMBuildBitCast (builder, addresses [ins->sreg1], LLVMPointerType (ret_type, 0), ""), "");
4321 LLVMBuildRet (builder, retval);
4324 case LLVMArgVtypeByVal: {
4325 LLVMValueRef retval;
4327 g_assert (addresses [ins->sreg1]);
4328 retval = LLVMBuildLoad (builder, addresses [ins->sreg1], "");
4329 LLVMBuildRet (builder, retval);
4332 case LLVMArgVtypeByRef: {
4333 LLVMBuildRetVoid (builder);
4336 case LLVMArgGsharedvtFixed: {
4337 LLVMTypeRef ret_type = type_to_llvm_type (ctx, sig->ret);
4338 /* The return value is in lhs, need to store to the vret argument */
4339 /* sreg1 might not be set */
4341 g_assert (cfg->vret_addr);
4342 g_assert (values [cfg->vret_addr->dreg]);
4343 LLVMBuildStore (builder, convert (ctx, lhs, ret_type), convert (ctx, values [cfg->vret_addr->dreg], LLVMPointerType (ret_type, 0)));
4345 LLVMBuildRetVoid (builder);
4348 case LLVMArgGsharedvtFixedVtype: {
4350 LLVMBuildRetVoid (builder);
4353 case LLVMArgGsharedvtVariable: {
4355 LLVMBuildRetVoid (builder);
4358 case LLVMArgVtypeRetAddr: {
4359 LLVMBuildRetVoid (builder);
4362 case LLVMArgFpStruct: {
4363 LLVMTypeRef ret_type = LLVMGetReturnType (LLVMGetElementType (LLVMTypeOf (method)));
4364 LLVMValueRef retval;
4366 g_assert (addresses [ins->sreg1]);
4367 retval = LLVMBuildLoad (builder, convert (ctx, addresses [ins->sreg1], LLVMPointerType (ret_type, 0)), "");
4368 LLVMBuildRet (builder, retval);
4372 case LLVMArgNormal: {
4373 if (!lhs || ctx->is_dead [ins->sreg1]) {
4375 * The method did not set its return value, probably because it
4376 * ends with a throw.
4379 LLVMBuildRetVoid (builder);
4381 LLVMBuildRet (builder, LLVMConstNull (type_to_llvm_type (ctx, sig->ret)));
4383 LLVMBuildRet (builder, convert (ctx, lhs, type_to_llvm_type (ctx, sig->ret)));
4385 has_terminator = TRUE;
4389 g_assert_not_reached ();
4398 case OP_ICOMPARE_IMM:
4399 case OP_LCOMPARE_IMM:
4400 case OP_COMPARE_IMM: {
4402 LLVMValueRef cmp, args [16];
4403 gboolean likely = (ins->flags & MONO_INST_LIKELY) != 0;
4405 if (ins->next->opcode == OP_NOP)
4408 if (ins->next->opcode == OP_BR)
4409 /* The comparison result is not needed */
4412 rel = mono_opcode_to_cond (ins->next->opcode);
4414 if (ins->opcode == OP_ICOMPARE_IMM) {
4415 lhs = convert (ctx, lhs, LLVMInt32Type ());
4416 rhs = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
4418 if (ins->opcode == OP_LCOMPARE_IMM) {
4419 lhs = convert (ctx, lhs, LLVMInt64Type ());
4420 rhs = LLVMConstInt (LLVMInt64Type (), GET_LONG_IMM (ins), FALSE);
4422 if (ins->opcode == OP_LCOMPARE) {
4423 lhs = convert (ctx, lhs, LLVMInt64Type ());
4424 rhs = convert (ctx, rhs, LLVMInt64Type ());
4426 if (ins->opcode == OP_ICOMPARE) {
4427 lhs = convert (ctx, lhs, LLVMInt32Type ());
4428 rhs = convert (ctx, rhs, LLVMInt32Type ());
4432 if (LLVMGetTypeKind (LLVMTypeOf (lhs)) == LLVMPointerTypeKind)
4433 rhs = convert (ctx, rhs, LLVMTypeOf (lhs));
4434 else if (LLVMGetTypeKind (LLVMTypeOf (rhs)) == LLVMPointerTypeKind)
4435 lhs = convert (ctx, lhs, LLVMTypeOf (rhs));
4438 /* We use COMPARE+SETcc/Bcc, llvm uses SETcc+br cond */
4439 if (ins->opcode == OP_FCOMPARE) {
4440 cmp = LLVMBuildFCmp (builder, fpcond_to_llvm_cond [rel], convert (ctx, lhs, LLVMDoubleType ()), convert (ctx, rhs, LLVMDoubleType ()), "");
4441 } else if (ins->opcode == OP_RCOMPARE) {
4442 cmp = LLVMBuildFCmp (builder, fpcond_to_llvm_cond [rel], convert (ctx, lhs, LLVMFloatType ()), convert (ctx, rhs, LLVMFloatType ()), "");
4443 } else if (ins->opcode == OP_COMPARE_IMM) {
4444 if (LLVMGetTypeKind (LLVMTypeOf (lhs)) == LLVMPointerTypeKind && ins->inst_imm == 0)
4445 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], lhs, LLVMConstNull (LLVMTypeOf (lhs)), "");
4447 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE), "");
4448 } else if (ins->opcode == OP_LCOMPARE_IMM) {
4449 if (SIZEOF_REGISTER == 4 && COMPILE_LLVM (cfg)) {
4450 /* The immediate is encoded in two fields */
4451 guint64 l = ((guint64)(guint32)ins->inst_offset << 32) | ((guint32)ins->inst_imm);
4452 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, LLVMInt64Type ()), LLVMConstInt (LLVMInt64Type (), l, FALSE), "");
4454 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, LLVMInt64Type ()), LLVMConstInt (LLVMInt64Type (), ins->inst_imm, FALSE), "");
4457 else if (ins->opcode == OP_COMPARE) {
4458 if (LLVMGetTypeKind (LLVMTypeOf (lhs)) == LLVMPointerTypeKind && LLVMTypeOf (lhs) == LLVMTypeOf (rhs))
4459 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], lhs, rhs, "");
4461 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, IntPtrType ()), convert (ctx, rhs, IntPtrType ()), "");
4463 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], lhs, rhs, "");
4467 args [1] = LLVMConstInt (LLVMInt1Type (), 1, FALSE);
4468 cmp = LLVMBuildCall (ctx->builder, get_intrinsic (ctx, "llvm.expect.i1"), args, 2, "");
4471 if (MONO_IS_COND_BRANCH_OP (ins->next)) {
4472 if (ins->next->inst_true_bb == ins->next->inst_false_bb) {
4474 * If the target bb contains PHI instructions, LLVM requires
4475 * two PHI entries for this bblock, while we only generate one.
4476 * So convert this to an unconditional bblock. (bxc #171).
4478 LLVMBuildBr (builder, get_bb (ctx, ins->next->inst_true_bb));
4480 LLVMBuildCondBr (builder, cmp, get_bb (ctx, ins->next->inst_true_bb), get_bb (ctx, ins->next->inst_false_bb));
4482 has_terminator = TRUE;
4483 } else if (MONO_IS_SETCC (ins->next)) {
4484 sprintf (dname_buf, "t%d", ins->next->dreg);
4486 values [ins->next->dreg] = LLVMBuildZExt (builder, cmp, LLVMInt32Type (), dname);
4488 /* Add stores for volatile variables */
4489 emit_volatile_store (ctx, ins->next->dreg);
4490 } else if (MONO_IS_COND_EXC (ins->next)) {
4491 emit_cond_system_exception (ctx, bb, (const char*)ins->next->inst_p1, cmp);
4494 builder = ctx->builder;
4496 set_failure (ctx, "next");
4514 rel = mono_opcode_to_cond (ins->opcode);
4516 cmp = LLVMBuildFCmp (builder, fpcond_to_llvm_cond [rel], convert (ctx, lhs, LLVMDoubleType ()), convert (ctx, rhs, LLVMDoubleType ()), "");
4517 values [ins->dreg] = LLVMBuildZExt (builder, cmp, LLVMInt32Type (), dname);
4528 rel = mono_opcode_to_cond (ins->opcode);
4530 cmp = LLVMBuildFCmp (builder, fpcond_to_llvm_cond [rel], convert (ctx, lhs, LLVMFloatType ()), convert (ctx, rhs, LLVMFloatType ()), "");
4531 values [ins->dreg] = LLVMBuildZExt (builder, cmp, LLVMInt32Type (), dname);
4539 gboolean empty = TRUE;
4541 /* Check that all input bblocks really branch to us */
4542 for (i = 0; i < bb->in_count; ++i) {
4543 if (bb->in_bb [i]->last_ins && bb->in_bb [i]->last_ins->opcode == OP_NOT_REACHED)
4544 ins->inst_phi_args [i + 1] = -1;
4550 /* LLVM doesn't like phi instructions with zero operands */
4551 ctx->is_dead [ins->dreg] = TRUE;
4555 /* Created earlier, insert it now */
4556 LLVMInsertIntoBuilder (builder, values [ins->dreg]);
4558 for (i = 0; i < ins->inst_phi_args [0]; i++) {
4559 int sreg1 = ins->inst_phi_args [i + 1];
4563 * Count the number of times the incoming bblock branches to us,
4564 * since llvm requires a separate entry for each.
4566 if (bb->in_bb [i]->last_ins && bb->in_bb [i]->last_ins->opcode == OP_SWITCH) {
4567 MonoInst *switch_ins = bb->in_bb [i]->last_ins;
4570 for (j = 0; j < GPOINTER_TO_UINT (switch_ins->klass); ++j) {
4571 if (switch_ins->inst_many_bb [j] == bb)
4578 /* Remember for later */
4579 for (j = 0; j < count; ++j) {
4580 PhiNode *node = (PhiNode*)mono_mempool_alloc0 (ctx->mempool, sizeof (PhiNode));
4583 node->in_bb = bb->in_bb [i];
4585 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);
4595 values [ins->dreg] = lhs;
4599 MonoInst *var = get_vreg_to_inst (cfg, ins->dreg);
4602 values [ins->dreg] = lhs;
4604 if (var && var->klass->byval_arg.type == MONO_TYPE_R4) {
4606 * This is added by the spilling pass in case of the JIT,
4607 * but we have to do it ourselves.
4609 values [ins->dreg] = convert (ctx, values [ins->dreg], LLVMFloatType ());
4613 case OP_MOVE_F_TO_I4: {
4614 values [ins->dreg] = LLVMBuildBitCast (builder, LLVMBuildFPTrunc (builder, lhs, LLVMFloatType (), ""), LLVMInt32Type (), "");
4617 case OP_MOVE_I4_TO_F: {
4618 values [ins->dreg] = LLVMBuildFPExt (builder, LLVMBuildBitCast (builder, lhs, LLVMFloatType (), ""), LLVMDoubleType (), "");
4621 case OP_MOVE_F_TO_I8: {
4622 values [ins->dreg] = LLVMBuildBitCast (builder, lhs, LLVMInt64Type (), "");
4625 case OP_MOVE_I8_TO_F: {
4626 values [ins->dreg] = LLVMBuildBitCast (builder, lhs, LLVMDoubleType (), "");
4659 lhs = convert (ctx, lhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
4660 rhs = convert (ctx, rhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
4662 emit_div_check (ctx, builder, bb, ins, lhs, rhs);
4665 builder = ctx->builder;
4667 switch (ins->opcode) {
4670 values [ins->dreg] = LLVMBuildAdd (builder, lhs, rhs, dname);
4674 values [ins->dreg] = LLVMBuildSub (builder, lhs, rhs, dname);
4678 values [ins->dreg] = LLVMBuildMul (builder, lhs, rhs, dname);
4682 values [ins->dreg] = LLVMBuildSRem (builder, lhs, rhs, dname);
4686 values [ins->dreg] = LLVMBuildURem (builder, lhs, rhs, dname);
4690 values [ins->dreg] = LLVMBuildSDiv (builder, lhs, rhs, dname);
4694 values [ins->dreg] = LLVMBuildUDiv (builder, lhs, rhs, dname);
4698 values [ins->dreg] = LLVMBuildFDiv (builder, lhs, rhs, dname);
4702 values [ins->dreg] = LLVMBuildAnd (builder, lhs, rhs, dname);
4706 values [ins->dreg] = LLVMBuildOr (builder, lhs, rhs, dname);
4710 values [ins->dreg] = LLVMBuildXor (builder, lhs, rhs, dname);
4714 values [ins->dreg] = LLVMBuildShl (builder, lhs, rhs, dname);
4718 values [ins->dreg] = LLVMBuildAShr (builder, lhs, rhs, dname);
4722 values [ins->dreg] = LLVMBuildLShr (builder, lhs, rhs, dname);
4726 values [ins->dreg] = LLVMBuildFAdd (builder, lhs, rhs, dname);
4729 values [ins->dreg] = LLVMBuildFSub (builder, lhs, rhs, dname);
4732 values [ins->dreg] = LLVMBuildFMul (builder, lhs, rhs, dname);
4736 g_assert_not_reached ();
4743 lhs = convert (ctx, lhs, LLVMFloatType ());
4744 rhs = convert (ctx, rhs, LLVMFloatType ());
4745 switch (ins->opcode) {
4747 values [ins->dreg] = LLVMBuildFAdd (builder, lhs, rhs, dname);
4750 values [ins->dreg] = LLVMBuildFSub (builder, lhs, rhs, dname);
4753 values [ins->dreg] = LLVMBuildFMul (builder, lhs, rhs, dname);
4756 values [ins->dreg] = LLVMBuildFDiv (builder, lhs, rhs, dname);
4759 g_assert_not_reached ();
4768 case OP_IREM_UN_IMM:
4770 case OP_IDIV_UN_IMM:
4776 case OP_ISHR_UN_IMM:
4786 case OP_LSHR_UN_IMM:
4792 case OP_SHR_UN_IMM: {
4795 if (spec [MONO_INST_SRC1] == 'l') {
4796 imm = LLVMConstInt (LLVMInt64Type (), GET_LONG_IMM (ins), FALSE);
4798 imm = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
4801 emit_div_check (ctx, builder, bb, ins, lhs, imm);
4804 builder = ctx->builder;
4806 #if SIZEOF_VOID_P == 4
4807 if (ins->opcode == OP_LSHL_IMM || ins->opcode == OP_LSHR_IMM || ins->opcode == OP_LSHR_UN_IMM)
4808 imm = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
4811 if (LLVMGetTypeKind (LLVMTypeOf (lhs)) == LLVMPointerTypeKind)
4812 lhs = convert (ctx, lhs, IntPtrType ());
4813 imm = convert (ctx, imm, LLVMTypeOf (lhs));
4814 switch (ins->opcode) {
4818 values [ins->dreg] = LLVMBuildAdd (builder, lhs, imm, dname);
4822 values [ins->dreg] = LLVMBuildSub (builder, lhs, imm, dname);
4827 values [ins->dreg] = LLVMBuildMul (builder, lhs, imm, dname);
4831 values [ins->dreg] = LLVMBuildSDiv (builder, lhs, imm, dname);
4833 case OP_IDIV_UN_IMM:
4834 case OP_LDIV_UN_IMM:
4835 values [ins->dreg] = LLVMBuildUDiv (builder, lhs, imm, dname);
4839 values [ins->dreg] = LLVMBuildSRem (builder, lhs, imm, dname);
4841 case OP_IREM_UN_IMM:
4842 values [ins->dreg] = LLVMBuildURem (builder, lhs, imm, dname);
4847 values [ins->dreg] = LLVMBuildAnd (builder, lhs, imm, dname);
4851 values [ins->dreg] = LLVMBuildOr (builder, lhs, imm, dname);
4855 values [ins->dreg] = LLVMBuildXor (builder, lhs, imm, dname);
4860 values [ins->dreg] = LLVMBuildShl (builder, lhs, imm, dname);
4865 values [ins->dreg] = LLVMBuildAShr (builder, lhs, imm, dname);
4867 case OP_ISHR_UN_IMM:
4868 /* This is used to implement conv.u4, so the lhs could be an i8 */
4869 lhs = convert (ctx, lhs, LLVMInt32Type ());
4870 imm = convert (ctx, imm, LLVMInt32Type ());
4871 values [ins->dreg] = LLVMBuildLShr (builder, lhs, imm, dname);
4873 case OP_LSHR_UN_IMM:
4875 values [ins->dreg] = LLVMBuildLShr (builder, lhs, imm, dname);
4878 g_assert_not_reached ();
4883 values [ins->dreg] = LLVMBuildSub (builder, LLVMConstInt (LLVMInt32Type (), 0, FALSE), convert (ctx, lhs, LLVMInt32Type ()), dname);
4886 values [ins->dreg] = LLVMBuildSub (builder, LLVMConstInt (LLVMInt64Type (), 0, FALSE), lhs, dname);
4889 lhs = convert (ctx, lhs, LLVMDoubleType ());
4890 values [ins->dreg] = LLVMBuildFSub (builder, LLVMConstReal (LLVMDoubleType (), 0.0), lhs, dname);
4893 lhs = convert (ctx, lhs, LLVMFloatType ());
4894 values [ins->dreg] = LLVMBuildFSub (builder, LLVMConstReal (LLVMFloatType (), 0.0), lhs, dname);
4897 guint32 v = 0xffffffff;
4898 values [ins->dreg] = LLVMBuildXor (builder, LLVMConstInt (LLVMInt32Type (), v, FALSE), convert (ctx, lhs, LLVMInt32Type ()), dname);
4902 guint64 v = 0xffffffffffffffffLL;
4903 values [ins->dreg] = LLVMBuildXor (builder, LLVMConstInt (LLVMInt64Type (), v, FALSE), lhs, dname);
4906 #if defined(TARGET_X86) || defined(TARGET_AMD64)
4908 LLVMValueRef v1, v2;
4910 v1 = LLVMBuildMul (builder, convert (ctx, rhs, IntPtrType ()), LLVMConstInt (IntPtrType (), (1 << ins->backend.shift_amount), FALSE), "");
4911 v2 = LLVMBuildAdd (builder, convert (ctx, lhs, IntPtrType ()), v1, "");
4912 values [ins->dreg] = LLVMBuildAdd (builder, v2, LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE), dname);
4917 case OP_ICONV_TO_I1:
4918 case OP_ICONV_TO_I2:
4919 case OP_ICONV_TO_I4:
4920 case OP_ICONV_TO_U1:
4921 case OP_ICONV_TO_U2:
4922 case OP_ICONV_TO_U4:
4923 case OP_LCONV_TO_I1:
4924 case OP_LCONV_TO_I2:
4925 case OP_LCONV_TO_U1:
4926 case OP_LCONV_TO_U2:
4927 case OP_LCONV_TO_U4: {
4930 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);
4932 /* Have to do two casts since our vregs have type int */
4933 v = LLVMBuildTrunc (builder, lhs, op_to_llvm_type (ins->opcode), "");
4935 values [ins->dreg] = LLVMBuildSExt (builder, v, LLVMInt32Type (), dname);
4937 values [ins->dreg] = LLVMBuildZExt (builder, v, LLVMInt32Type (), dname);
4940 case OP_ICONV_TO_I8:
4941 values [ins->dreg] = LLVMBuildSExt (builder, lhs, LLVMInt64Type (), dname);
4943 case OP_ICONV_TO_U8:
4944 values [ins->dreg] = LLVMBuildZExt (builder, lhs, LLVMInt64Type (), dname);
4946 case OP_FCONV_TO_I4:
4947 case OP_RCONV_TO_I4:
4948 values [ins->dreg] = LLVMBuildFPToSI (builder, lhs, LLVMInt32Type (), dname);
4950 case OP_FCONV_TO_I1:
4951 case OP_RCONV_TO_I1:
4952 values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildFPToSI (builder, lhs, LLVMInt8Type (), dname), LLVMInt32Type (), "");
4954 case OP_FCONV_TO_U1:
4955 case OP_RCONV_TO_U1:
4956 values [ins->dreg] = LLVMBuildZExt (builder, LLVMBuildTrunc (builder, LLVMBuildFPToUI (builder, lhs, IntPtrType (), dname), LLVMInt8Type (), ""), LLVMInt32Type (), "");
4958 case OP_FCONV_TO_I2:
4959 case OP_RCONV_TO_I2:
4960 values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildFPToSI (builder, lhs, LLVMInt16Type (), dname), LLVMInt32Type (), "");
4962 case OP_FCONV_TO_U2:
4963 case OP_RCONV_TO_U2:
4964 values [ins->dreg] = LLVMBuildZExt (builder, LLVMBuildFPToUI (builder, lhs, LLVMInt16Type (), dname), LLVMInt32Type (), "");
4966 case OP_RCONV_TO_U4:
4967 values [ins->dreg] = LLVMBuildFPToUI (builder, lhs, LLVMInt32Type (), dname);
4969 case OP_FCONV_TO_I8:
4970 case OP_RCONV_TO_I8:
4971 values [ins->dreg] = LLVMBuildFPToSI (builder, lhs, LLVMInt64Type (), dname);
4974 values [ins->dreg] = LLVMBuildFPToSI (builder, lhs, IntPtrType (), dname);
4976 case OP_ICONV_TO_R8:
4977 case OP_LCONV_TO_R8:
4978 values [ins->dreg] = LLVMBuildSIToFP (builder, lhs, LLVMDoubleType (), dname);
4980 case OP_ICONV_TO_R_UN:
4981 case OP_LCONV_TO_R_UN:
4982 values [ins->dreg] = LLVMBuildUIToFP (builder, lhs, LLVMDoubleType (), dname);
4984 #if SIZEOF_VOID_P == 4
4987 case OP_LCONV_TO_I4:
4988 values [ins->dreg] = LLVMBuildTrunc (builder, lhs, LLVMInt32Type (), dname);
4990 case OP_ICONV_TO_R4:
4991 case OP_LCONV_TO_R4:
4992 v = LLVMBuildSIToFP (builder, lhs, LLVMFloatType (), "");
4994 values [ins->dreg] = v;
4996 values [ins->dreg] = LLVMBuildFPExt (builder, v, LLVMDoubleType (), dname);
4998 case OP_FCONV_TO_R4:
4999 v = LLVMBuildFPTrunc (builder, lhs, LLVMFloatType (), "");
5001 values [ins->dreg] = v;
5003 values [ins->dreg] = LLVMBuildFPExt (builder, v, LLVMDoubleType (), dname);
5005 case OP_RCONV_TO_R8:
5006 values [ins->dreg] = LLVMBuildFPExt (builder, lhs, LLVMDoubleType (), dname);
5008 case OP_RCONV_TO_R4:
5009 values [ins->dreg] = lhs;
5012 values [ins->dreg] = LLVMBuildSExt (builder, convert (ctx, lhs, LLVMInt32Type ()), LLVMInt64Type (), dname);
5015 values [ins->dreg] = LLVMBuildZExt (builder, convert (ctx, lhs, LLVMInt32Type ()), LLVMInt64Type (), dname);
5018 values [ins->dreg] = LLVMBuildTrunc (builder, lhs, LLVMInt32Type (), dname);
5020 case OP_LOCALLOC_IMM: {
5023 guint32 size = ins->inst_imm;
5024 size = (size + (MONO_ARCH_FRAME_ALIGNMENT - 1)) & ~ (MONO_ARCH_FRAME_ALIGNMENT - 1);
5026 v = mono_llvm_build_alloca (builder, LLVMInt8Type (), LLVMConstInt (LLVMInt32Type (), size, FALSE), MONO_ARCH_FRAME_ALIGNMENT, "");
5028 if (ins->flags & MONO_INST_INIT) {
5029 LLVMValueRef args [5];
5032 args [1] = LLVMConstInt (LLVMInt8Type (), 0, FALSE);
5033 args [2] = LLVMConstInt (LLVMInt32Type (), size, FALSE);
5034 args [3] = LLVMConstInt (LLVMInt32Type (), MONO_ARCH_FRAME_ALIGNMENT, FALSE);
5035 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
5036 LLVMBuildCall (builder, get_intrinsic (ctx, "llvm.memset.p0i8.i32"), args, 5, "");
5039 values [ins->dreg] = v;
5043 LLVMValueRef v, size;
5045 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), "");
5047 v = mono_llvm_build_alloca (builder, LLVMInt8Type (), size, MONO_ARCH_FRAME_ALIGNMENT, "");
5049 if (ins->flags & MONO_INST_INIT) {
5050 LLVMValueRef args [5];
5053 args [1] = LLVMConstInt (LLVMInt8Type (), 0, FALSE);
5055 args [3] = LLVMConstInt (LLVMInt32Type (), MONO_ARCH_FRAME_ALIGNMENT, FALSE);
5056 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
5057 LLVMBuildCall (builder, get_intrinsic (ctx, "llvm.memset.p0i8.i32"), args, 5, "");
5059 values [ins->dreg] = v;
5063 case OP_LOADI1_MEMBASE:
5064 case OP_LOADU1_MEMBASE:
5065 case OP_LOADI2_MEMBASE:
5066 case OP_LOADU2_MEMBASE:
5067 case OP_LOADI4_MEMBASE:
5068 case OP_LOADU4_MEMBASE:
5069 case OP_LOADI8_MEMBASE:
5070 case OP_LOADR4_MEMBASE:
5071 case OP_LOADR8_MEMBASE:
5072 case OP_LOAD_MEMBASE:
5080 LLVMValueRef base, index, addr;
5082 gboolean sext = FALSE, zext = FALSE;
5083 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
5085 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
5090 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)) {
5091 addr = LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE);
5096 if (ins->inst_offset == 0) {
5098 } else if (ins->inst_offset % size != 0) {
5099 /* Unaligned load */
5100 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset, FALSE);
5101 addr = LLVMBuildGEP (builder, convert (ctx, base, LLVMPointerType (LLVMInt8Type (), 0)), &index, 1, "");
5103 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
5104 addr = LLVMBuildGEP (builder, convert (ctx, base, LLVMPointerType (t, 0)), &index, 1, "");
5108 addr = convert (ctx, addr, LLVMPointerType (t, 0));
5110 values [ins->dreg] = emit_load (ctx, bb, &builder, size, addr, dname, is_volatile);
5112 if (!is_volatile && (ins->flags & MONO_INST_INVARIANT_LOAD)) {
5114 * These will signal LLVM that these loads do not alias any stores, and
5115 * they can't fail, allowing them to be hoisted out of loops.
5117 set_invariant_load_flag (values [ins->dreg]);
5118 #if LLVM_API_VERSION < 100
5119 set_metadata_flag (values [ins->dreg], "mono.nofail.load");
5124 values [ins->dreg] = LLVMBuildSExt (builder, values [ins->dreg], LLVMInt32Type (), dname);
5126 values [ins->dreg] = LLVMBuildZExt (builder, values [ins->dreg], LLVMInt32Type (), dname);
5127 else if (!cfg->r4fp && ins->opcode == OP_LOADR4_MEMBASE)
5128 values [ins->dreg] = LLVMBuildFPExt (builder, values [ins->dreg], LLVMDoubleType (), dname);
5132 case OP_STOREI1_MEMBASE_REG:
5133 case OP_STOREI2_MEMBASE_REG:
5134 case OP_STOREI4_MEMBASE_REG:
5135 case OP_STOREI8_MEMBASE_REG:
5136 case OP_STORER4_MEMBASE_REG:
5137 case OP_STORER8_MEMBASE_REG:
5138 case OP_STORE_MEMBASE_REG: {
5140 LLVMValueRef index, addr;
5142 gboolean sext = FALSE, zext = FALSE;
5143 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
5145 if (!values [ins->inst_destbasereg]) {
5146 set_failure (ctx, "inst_destbasereg");
5150 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
5152 if (ins->inst_offset % size != 0) {
5153 /* Unaligned store */
5154 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset, FALSE);
5155 addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (LLVMInt8Type (), 0)), &index, 1, "");
5157 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
5158 addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (t, 0)), &index, 1, "");
5160 emit_store (ctx, bb, &builder, size, convert (ctx, values [ins->sreg1], t), convert (ctx, addr, LLVMPointerType (t, 0)), is_volatile);
5164 case OP_STOREI1_MEMBASE_IMM:
5165 case OP_STOREI2_MEMBASE_IMM:
5166 case OP_STOREI4_MEMBASE_IMM:
5167 case OP_STOREI8_MEMBASE_IMM:
5168 case OP_STORE_MEMBASE_IMM: {
5170 LLVMValueRef index, addr;
5172 gboolean sext = FALSE, zext = FALSE;
5173 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
5175 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
5177 if (ins->inst_offset % size != 0) {
5178 /* Unaligned store */
5179 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset, FALSE);
5180 addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (LLVMInt8Type (), 0)), &index, 1, "");
5182 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
5183 addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (t, 0)), &index, 1, "");
5185 emit_store (ctx, bb, &builder, size, convert (ctx, LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE), t), convert (ctx, addr, LLVMPointerType (t, 0)), is_volatile);
5190 emit_load (ctx, bb, &builder, sizeof (gpointer), convert (ctx, lhs, LLVMPointerType (IntPtrType (), 0)), "", TRUE);
5192 case OP_OUTARG_VTRETADDR:
5200 case OP_VOIDCALL_MEMBASE:
5201 case OP_CALL_MEMBASE:
5202 case OP_LCALL_MEMBASE:
5203 case OP_FCALL_MEMBASE:
5204 case OP_RCALL_MEMBASE:
5205 case OP_VCALL_MEMBASE:
5206 case OP_VOIDCALL_REG:
5211 case OP_VCALL_REG: {
5212 process_call (ctx, bb, &builder, ins);
5217 LLVMValueRef indexes [2];
5218 MonoJumpInfo *tmp_ji, *ji;
5219 LLVMValueRef got_entry_addr;
5223 * FIXME: Can't allocate from the cfg mempool since that is freed if
5224 * the LLVM compile fails.
5226 tmp_ji = g_new0 (MonoJumpInfo, 1);
5227 tmp_ji->type = (MonoJumpInfoType)ins->inst_c1;
5228 tmp_ji->data.target = ins->inst_p0;
5230 ji = mono_aot_patch_info_dup (tmp_ji);
5233 if (ji->type == MONO_PATCH_INFO_ICALL_ADDR) {
5234 char *symbol = mono_aot_get_direct_call_symbol (MONO_PATCH_INFO_ICALL_ADDR_CALL, ji->data.target);
5237 * Avoid emitting a got entry for these since the method is directly called, and it might not be
5238 * resolvable at runtime using dlsym ().
5241 values [ins->dreg] = LLVMConstInt (IntPtrType (), 0, FALSE);
5246 ji->next = cfg->patch_info;
5247 cfg->patch_info = ji;
5249 //mono_add_patch_info (cfg, 0, (MonoJumpInfoType)ins->inst_i1, ins->inst_p0);
5250 got_offset = mono_aot_get_got_offset (cfg->patch_info);
5251 ctx->module->max_got_offset = MAX (ctx->module->max_got_offset, got_offset);
5252 if (!mono_aot_is_shared_got_offset (got_offset)) {
5253 //mono_print_ji (ji);
5255 ctx->has_got_access = TRUE;
5258 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
5259 indexes [1] = LLVMConstInt (LLVMInt32Type (), (gssize)got_offset, FALSE);
5260 got_entry_addr = LLVMBuildGEP (builder, ctx->module->got_var, indexes, 2, "");
5262 name = get_aotconst_name (ji->type, ji->data.target, got_offset);
5263 values [ins->dreg] = LLVMBuildLoad (builder, got_entry_addr, name);
5265 /* Can't use this in llvmonly mode since the got slots are initialized by the methods themselves */
5266 if (!cfg->llvm_only)
5267 set_invariant_load_flag (values [ins->dreg]);
5270 case OP_NOT_REACHED:
5271 LLVMBuildUnreachable (builder);
5272 has_terminator = TRUE;
5273 g_assert (bb->block_num < cfg->max_block_num);
5274 ctx->unreachable [bb->block_num] = TRUE;
5275 /* Might have instructions after this */
5277 MonoInst *next = ins->next;
5279 * FIXME: If later code uses the regs defined by these instructions,
5280 * compilation will fail.
5282 MONO_DELETE_INS (bb, next);
5286 MonoInst *var = ins->inst_i0;
5288 if (var->opcode == OP_VTARG_ADDR) {
5289 /* The variable contains the vtype address */
5290 values [ins->dreg] = values [var->dreg];
5291 } else if (var->opcode == OP_GSHAREDVT_LOCAL) {
5292 values [ins->dreg] = emit_gsharedvt_ldaddr (ctx, var->dreg);
5294 values [ins->dreg] = addresses [var->dreg];
5299 LLVMValueRef args [1];
5301 args [0] = convert (ctx, lhs, LLVMDoubleType ());
5302 values [ins->dreg] = LLVMBuildCall (builder, get_intrinsic (ctx, "llvm.sin.f64"), args, 1, dname);
5306 LLVMValueRef args [1];
5308 args [0] = convert (ctx, lhs, LLVMDoubleType ());
5309 values [ins->dreg] = LLVMBuildCall (builder, get_intrinsic (ctx, "llvm.cos.f64"), args, 1, dname);
5313 LLVMValueRef args [1];
5315 args [0] = convert (ctx, lhs, LLVMDoubleType ());
5316 values [ins->dreg] = LLVMBuildCall (builder, get_intrinsic (ctx, "llvm.sqrt.f64"), args, 1, dname);
5320 LLVMValueRef args [1];
5322 args [0] = convert (ctx, lhs, LLVMDoubleType ());
5323 values [ins->dreg] = LLVMBuildCall (builder, get_intrinsic (ctx, "fabs"), args, 1, dname);
5337 lhs = convert (ctx, lhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
5338 rhs = convert (ctx, rhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
5340 switch (ins->opcode) {
5343 v = LLVMBuildICmp (builder, LLVMIntSLE, lhs, rhs, "");
5347 v = LLVMBuildICmp (builder, LLVMIntSGE, lhs, rhs, "");
5351 v = LLVMBuildICmp (builder, LLVMIntULE, lhs, rhs, "");
5355 v = LLVMBuildICmp (builder, LLVMIntUGE, lhs, rhs, "");
5358 g_assert_not_reached ();
5361 values [ins->dreg] = LLVMBuildSelect (builder, v, lhs, rhs, dname);
5364 case OP_ATOMIC_EXCHANGE_I4:
5365 case OP_ATOMIC_EXCHANGE_I8: {
5366 LLVMValueRef args [2];
5369 if (ins->opcode == OP_ATOMIC_EXCHANGE_I4)
5370 t = LLVMInt32Type ();
5372 t = LLVMInt64Type ();
5374 g_assert (ins->inst_offset == 0);
5376 args [0] = convert (ctx, lhs, LLVMPointerType (t, 0));
5377 args [1] = convert (ctx, rhs, t);
5379 values [ins->dreg] = mono_llvm_build_atomic_rmw (builder, LLVM_ATOMICRMW_OP_XCHG, args [0], args [1]);
5382 case OP_ATOMIC_ADD_I4:
5383 case OP_ATOMIC_ADD_I8: {
5384 LLVMValueRef args [2];
5387 if (ins->opcode == OP_ATOMIC_ADD_I4)
5388 t = LLVMInt32Type ();
5390 t = LLVMInt64Type ();
5392 g_assert (ins->inst_offset == 0);
5394 args [0] = convert (ctx, lhs, LLVMPointerType (t, 0));
5395 args [1] = convert (ctx, rhs, t);
5396 values [ins->dreg] = LLVMBuildAdd (builder, mono_llvm_build_atomic_rmw (builder, LLVM_ATOMICRMW_OP_ADD, args [0], args [1]), args [1], dname);
5399 case OP_ATOMIC_CAS_I4:
5400 case OP_ATOMIC_CAS_I8: {
5401 LLVMValueRef args [3], val;
5404 if (ins->opcode == OP_ATOMIC_CAS_I4)
5405 t = LLVMInt32Type ();
5407 t = LLVMInt64Type ();
5409 args [0] = convert (ctx, lhs, LLVMPointerType (t, 0));
5411 args [1] = convert (ctx, values [ins->sreg3], t);
5413 args [2] = convert (ctx, values [ins->sreg2], t);
5414 val = mono_llvm_build_cmpxchg (builder, args [0], args [1], args [2]);
5415 /* cmpxchg returns a pair */
5416 values [ins->dreg] = LLVMBuildExtractValue (builder, val, 0, "");
5419 case OP_MEMORY_BARRIER: {
5420 mono_llvm_build_fence (builder, (BarrierKind) ins->backend.memory_barrier_kind);
5423 case OP_ATOMIC_LOAD_I1:
5424 case OP_ATOMIC_LOAD_I2:
5425 case OP_ATOMIC_LOAD_I4:
5426 case OP_ATOMIC_LOAD_I8:
5427 case OP_ATOMIC_LOAD_U1:
5428 case OP_ATOMIC_LOAD_U2:
5429 case OP_ATOMIC_LOAD_U4:
5430 case OP_ATOMIC_LOAD_U8:
5431 case OP_ATOMIC_LOAD_R4:
5432 case OP_ATOMIC_LOAD_R8: {
5433 set_failure (ctx, "atomic mono.load intrinsic");
5437 gboolean sext, zext;
5439 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
5440 BarrierKind barrier = (BarrierKind) ins->backend.memory_barrier_kind;
5441 LLVMValueRef index, addr;
5443 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
5448 if (ins->inst_offset != 0) {
5449 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
5450 addr = LLVMBuildGEP (builder, convert (ctx, lhs, LLVMPointerType (t, 0)), &index, 1, "");
5455 addr = convert (ctx, addr, LLVMPointerType (t, 0));
5457 values [ins->dreg] = emit_load_general (ctx, bb, &builder, size, addr, dname, is_volatile, barrier);
5460 values [ins->dreg] = LLVMBuildSExt (builder, values [ins->dreg], LLVMInt32Type (), dname);
5462 values [ins->dreg] = LLVMBuildZExt (builder, values [ins->dreg], LLVMInt32Type (), dname);
5466 case OP_ATOMIC_STORE_I1:
5467 case OP_ATOMIC_STORE_I2:
5468 case OP_ATOMIC_STORE_I4:
5469 case OP_ATOMIC_STORE_I8:
5470 case OP_ATOMIC_STORE_U1:
5471 case OP_ATOMIC_STORE_U2:
5472 case OP_ATOMIC_STORE_U4:
5473 case OP_ATOMIC_STORE_U8:
5474 case OP_ATOMIC_STORE_R4:
5475 case OP_ATOMIC_STORE_R8: {
5476 set_failure (ctx, "atomic mono.store intrinsic");
5480 gboolean sext, zext;
5482 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
5483 BarrierKind barrier = (BarrierKind) ins->backend.memory_barrier_kind;
5484 LLVMValueRef index, addr, value;
5486 if (!values [ins->inst_destbasereg]) {
5487 set_failure (ctx, "inst_destbasereg");
5491 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
5493 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
5494 addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (t, 0)), &index, 1, "");
5495 value = convert (ctx, values [ins->sreg1], t);
5497 emit_store_general (ctx, bb, &builder, size, value, addr, is_volatile, barrier);
5501 case OP_RELAXED_NOP: {
5502 #if defined(TARGET_AMD64) || defined(TARGET_X86)
5503 emit_call (ctx, bb, &builder, get_intrinsic (ctx, "llvm.x86.sse2.pause"), NULL, 0);
5510 #if (defined(TARGET_AMD64) || defined(TARGET_X86)) && defined(__linux__)
5512 // 257 == FS segment register
5513 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 257);
5515 // 256 == GS segment register
5516 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 256);
5519 values [ins->dreg] = LLVMBuildLoad (builder, LLVMBuildIntToPtr (builder, LLVMConstInt (IntPtrType (), ins->inst_offset, TRUE), ptrtype, ""), "");
5520 #elif defined(TARGET_AMD64) && defined(TARGET_OSX)
5521 /* See mono_amd64_emit_tls_get () */
5522 int offset = mono_amd64_get_tls_gs_offset () + (ins->inst_offset * 8);
5524 // 256 == GS segment register
5525 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 256);
5526 values [ins->dreg] = LLVMBuildLoad (builder, LLVMBuildIntToPtr (builder, LLVMConstInt (IntPtrType (), offset, TRUE), ptrtype, ""), "");
5528 set_failure (ctx, "opcode tls-get");
5534 case OP_TLS_GET_REG: {
5535 #if defined(TARGET_AMD64) && defined(TARGET_OSX)
5536 /* See emit_tls_get_reg () */
5537 // 256 == GS segment register
5538 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 256);
5539 values [ins->dreg] = LLVMBuildLoad (builder, LLVMBuildIntToPtr (builder, convert (ctx, lhs, LLVMInt32Type ()), ptrtype, ""), "");
5541 set_failure (ctx, "opcode tls-get");
5547 case OP_TLS_SET_REG: {
5548 #if defined(TARGET_AMD64) && defined(TARGET_OSX)
5549 /* See emit_tls_get_reg () */
5550 // 256 == GS segment register
5551 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 256);
5552 LLVMBuildStore (builder, convert (ctx, lhs, IntPtrType ()), LLVMBuildIntToPtr (builder, convert (ctx, rhs, LLVMInt32Type ()), ptrtype, ""));
5554 set_failure (ctx, "opcode tls-set-reg");
5559 case OP_GC_SAFE_POINT: {
5560 LLVMValueRef val, cmp, callee;
5561 LLVMBasicBlockRef poll_bb, cont_bb;
5562 static LLVMTypeRef sig;
5563 const char *icall_name = "mono_threads_state_poll";
5566 sig = LLVMFunctionType0 (LLVMVoidType (), FALSE);
5570 * mono_threads_state_poll ();
5571 * FIXME: Use a preserveall wrapper
5573 val = mono_llvm_build_load (builder, convert (ctx, lhs, LLVMPointerType (IntPtrType (), 0)), "", TRUE, LLVM_BARRIER_NONE);
5574 cmp = LLVMBuildICmp (builder, LLVMIntEQ, val, LLVMConstNull (LLVMTypeOf (val)), "");
5575 poll_bb = gen_bb (ctx, "POLL_BB");
5576 cont_bb = gen_bb (ctx, "CONT_BB");
5577 LLVMBuildCondBr (builder, cmp, cont_bb, poll_bb);
5579 ctx->builder = builder = create_builder (ctx);
5580 LLVMPositionBuilderAtEnd (builder, poll_bb);
5582 if (ctx->cfg->compile_aot) {
5583 callee = get_callee (ctx, sig, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
5585 gpointer target = resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
5586 callee = emit_jit_callee (ctx, icall_name, sig, target);
5588 LLVMBuildCall (builder, callee, NULL, 0, "");
5589 LLVMBuildBr (builder, cont_bb);
5591 ctx->builder = builder = create_builder (ctx);
5592 LLVMPositionBuilderAtEnd (builder, cont_bb);
5593 ctx->bblocks [bb->block_num].end_bblock = cont_bb;
5601 case OP_IADD_OVF_UN:
5603 case OP_ISUB_OVF_UN:
5605 case OP_IMUL_OVF_UN:
5607 case OP_LADD_OVF_UN:
5609 case OP_LSUB_OVF_UN:
5611 case OP_LMUL_OVF_UN:
5613 LLVMValueRef args [2], val, ovf, func;
5615 args [0] = convert (ctx, lhs, op_to_llvm_type (ins->opcode));
5616 args [1] = convert (ctx, rhs, op_to_llvm_type (ins->opcode));
5617 func = get_intrinsic (ctx, ovf_op_to_intrins (ins->opcode));
5619 val = LLVMBuildCall (builder, func, args, 2, "");
5620 values [ins->dreg] = LLVMBuildExtractValue (builder, val, 0, dname);
5621 ovf = LLVMBuildExtractValue (builder, val, 1, "");
5622 emit_cond_system_exception (ctx, bb, "OverflowException", ovf);
5625 builder = ctx->builder;
5631 * We currently model them using arrays. Promotion to local vregs is
5632 * disabled for them in mono_handle_global_vregs () in the LLVM case,
5633 * so we always have an entry in cfg->varinfo for them.
5634 * FIXME: Is this needed ?
5637 MonoClass *klass = ins->klass;
5638 LLVMValueRef args [5];
5642 set_failure (ctx, "!klass");
5646 if (!addresses [ins->dreg])
5647 addresses [ins->dreg] = build_alloca (ctx, &klass->byval_arg);
5648 args [0] = LLVMBuildBitCast (builder, addresses [ins->dreg], LLVMPointerType (LLVMInt8Type (), 0), "");
5649 args [1] = LLVMConstInt (LLVMInt8Type (), 0, FALSE);
5650 args [2] = LLVMConstInt (LLVMInt32Type (), mono_class_value_size (klass, NULL), FALSE);
5652 args [3] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
5653 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
5654 LLVMBuildCall (builder, get_intrinsic (ctx, "llvm.memset.p0i8.i32"), args, 5, "");
5657 case OP_DUMMY_VZERO:
5660 case OP_STOREV_MEMBASE:
5661 case OP_LOADV_MEMBASE:
5663 MonoClass *klass = ins->klass;
5664 LLVMValueRef src = NULL, dst, args [5];
5665 gboolean done = FALSE;
5669 set_failure (ctx, "!klass");
5673 if (mini_is_gsharedvt_klass (klass)) {
5675 set_failure (ctx, "gsharedvt");
5679 switch (ins->opcode) {
5680 case OP_STOREV_MEMBASE:
5681 if (cfg->gen_write_barriers && klass->has_references && ins->inst_destbasereg != cfg->frame_reg &&
5682 LLVMGetInstructionOpcode (values [ins->inst_destbasereg]) != LLVMAlloca) {
5683 /* Decomposed earlier */
5684 g_assert_not_reached ();
5687 if (!addresses [ins->sreg1]) {
5689 g_assert (values [ins->sreg1]);
5690 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));
5691 LLVMBuildStore (builder, values [ins->sreg1], dst);
5694 src = LLVMBuildBitCast (builder, addresses [ins->sreg1], LLVMPointerType (LLVMInt8Type (), 0), "");
5695 dst = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_destbasereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (LLVMInt8Type (), 0));
5698 case OP_LOADV_MEMBASE:
5699 if (!addresses [ins->dreg])
5700 addresses [ins->dreg] = build_alloca (ctx, &klass->byval_arg);
5701 src = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_basereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (LLVMInt8Type (), 0));
5702 dst = LLVMBuildBitCast (builder, addresses [ins->dreg], LLVMPointerType (LLVMInt8Type (), 0), "");
5705 if (!addresses [ins->sreg1])
5706 addresses [ins->sreg1] = build_alloca (ctx, &klass->byval_arg);
5707 if (!addresses [ins->dreg])
5708 addresses [ins->dreg] = build_alloca (ctx, &klass->byval_arg);
5709 src = LLVMBuildBitCast (builder, addresses [ins->sreg1], LLVMPointerType (LLVMInt8Type (), 0), "");
5710 dst = LLVMBuildBitCast (builder, addresses [ins->dreg], LLVMPointerType (LLVMInt8Type (), 0), "");
5713 g_assert_not_reached ();
5723 args [2] = LLVMConstInt (LLVMInt32Type (), mono_class_value_size (klass, NULL), FALSE);
5724 args [3] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
5726 args [3] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
5727 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
5728 LLVMBuildCall (builder, get_intrinsic (ctx, "llvm.memcpy.p0i8.p0i8.i32"), args, 5, "");
5731 case OP_LLVM_OUTARG_VT: {
5732 LLVMArgInfo *ainfo = (LLVMArgInfo*)ins->inst_p0;
5733 MonoType *t = mini_get_underlying_type (ins->inst_vtype);
5735 if (ainfo->storage == LLVMArgGsharedvtVariable) {
5736 MonoInst *var = get_vreg_to_inst (cfg, ins->sreg1);
5738 if (var && var->opcode == OP_GSHAREDVT_LOCAL) {
5739 addresses [ins->dreg] = convert (ctx, emit_gsharedvt_ldaddr (ctx, var->dreg), LLVMPointerType (IntPtrType (), 0));
5741 g_assert (addresses [ins->sreg1]);
5742 addresses [ins->dreg] = addresses [ins->sreg1];
5744 } else if (ainfo->storage == LLVMArgGsharedvtFixed) {
5745 if (!addresses [ins->sreg1]) {
5746 addresses [ins->sreg1] = build_alloca (ctx, t);
5747 g_assert (values [ins->sreg1]);
5749 LLVMBuildStore (builder, convert (ctx, values [ins->sreg1], LLVMGetElementType (LLVMTypeOf (addresses [ins->sreg1]))), addresses [ins->sreg1]);
5750 addresses [ins->dreg] = addresses [ins->sreg1];
5752 if (!addresses [ins->sreg1]) {
5753 addresses [ins->sreg1] = build_alloca (ctx, t);
5754 g_assert (values [ins->sreg1]);
5755 LLVMBuildStore (builder, convert (ctx, values [ins->sreg1], type_to_llvm_type (ctx, t)), addresses [ins->sreg1]);
5757 addresses [ins->dreg] = addresses [ins->sreg1];
5765 #if defined(TARGET_X86) || defined(TARGET_AMD64)
5767 values [ins->dreg] = LLVMConstNull (type_to_llvm_type (ctx, &ins->klass->byval_arg));
5770 case OP_LOADX_MEMBASE: {
5771 LLVMTypeRef t = type_to_llvm_type (ctx, &ins->klass->byval_arg);
5774 src = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_basereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (t, 0));
5775 values [ins->dreg] = mono_llvm_build_aligned_load (builder, src, "", FALSE, 1);
5778 case OP_STOREX_MEMBASE: {
5779 LLVMTypeRef t = LLVMTypeOf (values [ins->sreg1]);
5782 dest = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_destbasereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (t, 0));
5783 mono_llvm_build_aligned_store (builder, values [ins->sreg1], dest, FALSE, 1);
5790 values [ins->dreg] = LLVMBuildAdd (builder, lhs, rhs, "");
5794 values [ins->dreg] = LLVMBuildFAdd (builder, lhs, rhs, "");
5800 values [ins->dreg] = LLVMBuildSub (builder, lhs, rhs, "");
5804 values [ins->dreg] = LLVMBuildFSub (builder, lhs, rhs, "");
5808 values [ins->dreg] = LLVMBuildFMul (builder, lhs, rhs, "");
5812 values [ins->dreg] = LLVMBuildFDiv (builder, lhs, rhs, "");
5815 values [ins->dreg] = LLVMBuildAnd (builder, lhs, rhs, "");
5818 values [ins->dreg] = LLVMBuildOr (builder, lhs, rhs, "");
5821 values [ins->dreg] = LLVMBuildXor (builder, lhs, rhs, "");
5825 values [ins->dreg] = LLVMBuildMul (builder, lhs, rhs, "");
5836 LLVMValueRef v = NULL;
5838 switch (ins->opcode) {
5843 t = LLVMVectorType (LLVMInt32Type (), 4);
5844 rt = LLVMVectorType (LLVMFloatType (), 4);
5850 t = LLVMVectorType (LLVMInt64Type (), 2);
5851 rt = LLVMVectorType (LLVMDoubleType (), 2);
5854 t = LLVMInt32Type ();
5855 rt = LLVMInt32Type ();
5856 g_assert_not_reached ();
5859 lhs = LLVMBuildBitCast (builder, lhs, t, "");
5860 rhs = LLVMBuildBitCast (builder, rhs, t, "");
5861 switch (ins->opcode) {
5864 v = LLVMBuildAnd (builder, lhs, rhs, "");
5868 v = LLVMBuildOr (builder, lhs, rhs, "");
5872 v = LLVMBuildXor (builder, lhs, rhs, "");
5876 v = LLVMBuildAnd (builder, rhs, LLVMBuildNot (builder, lhs, ""), "");
5879 values [ins->dreg] = LLVMBuildBitCast (builder, v, rt, "");
5903 case OP_PADDB_SAT_UN:
5904 case OP_PADDW_SAT_UN:
5905 case OP_PSUBB_SAT_UN:
5906 case OP_PSUBW_SAT_UN:
5914 case OP_PMULW_HIGH_UN: {
5915 LLVMValueRef args [2];
5920 values [ins->dreg] = LLVMBuildCall (builder, get_intrinsic (ctx, simd_op_to_intrins (ins->opcode)), args, 2, dname);
5927 values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildICmp (builder, LLVMIntEQ, lhs, rhs, ""), LLVMTypeOf (lhs), "");
5931 values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildICmp (builder, LLVMIntSGT, lhs, rhs, ""), LLVMTypeOf (lhs), "");
5939 case OP_EXTRACTX_U2:
5941 case OP_EXTRACT_U1: {
5943 gboolean zext = FALSE;
5945 t = simd_op_to_llvm_type (ins->opcode);
5947 switch (ins->opcode) {
5955 case OP_EXTRACTX_U2:
5960 t = LLVMInt32Type ();
5961 g_assert_not_reached ();
5964 lhs = LLVMBuildBitCast (builder, lhs, t, "");
5965 values [ins->dreg] = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), "");
5967 values [ins->dreg] = LLVMBuildZExt (builder, values [ins->dreg], LLVMInt32Type (), "");
5976 case OP_EXPAND_R8: {
5977 LLVMTypeRef t = simd_op_to_llvm_type (ins->opcode);
5978 LLVMValueRef mask [16], v;
5981 for (i = 0; i < 16; ++i)
5982 mask [i] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
5984 v = convert (ctx, values [ins->sreg1], LLVMGetElementType (t));
5986 values [ins->dreg] = LLVMBuildInsertElement (builder, LLVMConstNull (t), v, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
5987 values [ins->dreg] = LLVMBuildShuffleVector (builder, values [ins->dreg], LLVMGetUndef (t), LLVMConstVector (mask, LLVMGetVectorSize (t)), "");
5992 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt8Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
5995 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt16Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
5998 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt32Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
6001 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt64Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
6004 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMFloatType ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
6007 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMDoubleType ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
6018 case OP_EXTRACT_MASK:
6025 v = convert (ctx, values [ins->sreg1], simd_op_to_llvm_type (ins->opcode));
6027 values [ins->dreg] = LLVMBuildCall (builder, get_intrinsic (ctx, simd_op_to_intrins (ins->opcode)), &v, 1, dname);
6033 LLVMValueRef args [3];
6037 args [2] = LLVMConstInt (LLVMInt8Type (), ins->inst_c0, FALSE);
6039 values [ins->dreg] = LLVMBuildCall (builder, get_intrinsic (ctx, simd_op_to_intrins (ins->opcode)), args, 3, dname);
6044 /* This is only used for implementing shifts by non-immediate */
6045 values [ins->dreg] = lhs;
6056 LLVMValueRef args [3];
6059 args [1] = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
6061 values [ins->dreg] = LLVMBuildCall (builder, get_intrinsic (ctx, simd_op_to_intrins (ins->opcode)), args, 2, dname);
6072 case OP_PSHLQ_REG: {
6073 LLVMValueRef args [3];
6076 args [1] = values [ins->sreg2];
6078 values [ins->dreg] = LLVMBuildCall (builder, get_intrinsic (ctx, simd_op_to_intrins (ins->opcode)), args, 2, dname);
6085 case OP_PSHUFLEW_LOW:
6086 case OP_PSHUFLEW_HIGH: {
6088 LLVMValueRef v1 = NULL, v2 = NULL, mask_values [16];
6089 int i, mask_size = 0;
6090 int imask = ins->inst_c0;
6092 /* Convert the x86 shuffle mask to LLVM's */
6093 switch (ins->opcode) {
6096 mask [0] = ((imask >> 0) & 3);
6097 mask [1] = ((imask >> 2) & 3);
6098 mask [2] = ((imask >> 4) & 3) + 4;
6099 mask [3] = ((imask >> 6) & 3) + 4;
6100 v1 = values [ins->sreg1];
6101 v2 = values [ins->sreg2];
6105 mask [0] = ((imask >> 0) & 1);
6106 mask [1] = ((imask >> 1) & 1) + 2;
6107 v1 = values [ins->sreg1];
6108 v2 = values [ins->sreg2];
6110 case OP_PSHUFLEW_LOW:
6112 mask [0] = ((imask >> 0) & 3);
6113 mask [1] = ((imask >> 2) & 3);
6114 mask [2] = ((imask >> 4) & 3);
6115 mask [3] = ((imask >> 6) & 3);
6120 v1 = values [ins->sreg1];
6121 v2 = LLVMGetUndef (LLVMTypeOf (v1));
6123 case OP_PSHUFLEW_HIGH:
6129 mask [4] = 4 + ((imask >> 0) & 3);
6130 mask [5] = 4 + ((imask >> 2) & 3);
6131 mask [6] = 4 + ((imask >> 4) & 3);
6132 mask [7] = 4 + ((imask >> 6) & 3);
6133 v1 = values [ins->sreg1];
6134 v2 = LLVMGetUndef (LLVMTypeOf (v1));
6138 mask [0] = ((imask >> 0) & 3);
6139 mask [1] = ((imask >> 2) & 3);
6140 mask [2] = ((imask >> 4) & 3);
6141 mask [3] = ((imask >> 6) & 3);
6142 v1 = values [ins->sreg1];
6143 v2 = LLVMGetUndef (LLVMTypeOf (v1));
6146 g_assert_not_reached ();
6148 for (i = 0; i < mask_size; ++i)
6149 mask_values [i] = LLVMConstInt (LLVMInt32Type (), mask [i], FALSE);
6151 values [ins->dreg] =
6152 LLVMBuildShuffleVector (builder, v1, v2,
6153 LLVMConstVector (mask_values, mask_size), dname);
6157 case OP_UNPACK_LOWB:
6158 case OP_UNPACK_LOWW:
6159 case OP_UNPACK_LOWD:
6160 case OP_UNPACK_LOWQ:
6161 case OP_UNPACK_LOWPS:
6162 case OP_UNPACK_LOWPD:
6163 case OP_UNPACK_HIGHB:
6164 case OP_UNPACK_HIGHW:
6165 case OP_UNPACK_HIGHD:
6166 case OP_UNPACK_HIGHQ:
6167 case OP_UNPACK_HIGHPS:
6168 case OP_UNPACK_HIGHPD: {
6170 LLVMValueRef mask_values [16];
6171 int i, mask_size = 0;
6172 gboolean low = FALSE;
6174 switch (ins->opcode) {
6175 case OP_UNPACK_LOWB:
6179 case OP_UNPACK_LOWW:
6183 case OP_UNPACK_LOWD:
6184 case OP_UNPACK_LOWPS:
6188 case OP_UNPACK_LOWQ:
6189 case OP_UNPACK_LOWPD:
6193 case OP_UNPACK_HIGHB:
6196 case OP_UNPACK_HIGHW:
6199 case OP_UNPACK_HIGHD:
6200 case OP_UNPACK_HIGHPS:
6203 case OP_UNPACK_HIGHQ:
6204 case OP_UNPACK_HIGHPD:
6208 g_assert_not_reached ();
6212 for (i = 0; i < (mask_size / 2); ++i) {
6214 mask [(i * 2) + 1] = mask_size + i;
6217 for (i = 0; i < (mask_size / 2); ++i) {
6218 mask [(i * 2)] = (mask_size / 2) + i;
6219 mask [(i * 2) + 1] = mask_size + (mask_size / 2) + i;
6223 for (i = 0; i < mask_size; ++i)
6224 mask_values [i] = LLVMConstInt (LLVMInt32Type (), mask [i], FALSE);
6226 values [ins->dreg] =
6227 LLVMBuildShuffleVector (builder, values [ins->sreg1], values [ins->sreg2],
6228 LLVMConstVector (mask_values, mask_size), dname);
6233 LLVMTypeRef t = simd_op_to_llvm_type (ins->opcode);
6234 LLVMValueRef v, val;
6236 v = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
6237 val = LLVMConstNull (t);
6238 val = LLVMBuildInsertElement (builder, val, v, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
6239 val = LLVMBuildInsertElement (builder, val, v, LLVMConstInt (LLVMInt32Type (), 1, FALSE), dname);
6241 values [ins->dreg] = val;
6245 case OP_DUPPS_HIGH: {
6246 LLVMTypeRef t = simd_op_to_llvm_type (ins->opcode);
6247 LLVMValueRef v1, v2, val;
6250 if (ins->opcode == OP_DUPPS_LOW) {
6251 v1 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
6252 v2 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 2, FALSE), "");
6254 v1 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 1, FALSE), "");
6255 v2 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 3, FALSE), "");
6257 val = LLVMConstNull (t);
6258 val = LLVMBuildInsertElement (builder, val, v1, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
6259 val = LLVMBuildInsertElement (builder, val, v1, LLVMConstInt (LLVMInt32Type (), 1, FALSE), "");
6260 val = LLVMBuildInsertElement (builder, val, v2, LLVMConstInt (LLVMInt32Type (), 2, FALSE), "");
6261 val = LLVMBuildInsertElement (builder, val, v2, LLVMConstInt (LLVMInt32Type (), 3, FALSE), "");
6263 values [ins->dreg] = val;
6273 * EXCEPTION HANDLING
6275 case OP_IMPLICIT_EXCEPTION:
6276 /* This marks a place where an implicit exception can happen */
6277 if (bb->region != -1)
6278 set_failure (ctx, "implicit-exception");
6282 gboolean rethrow = (ins->opcode == OP_RETHROW);
6283 if (ctx->llvm_only) {
6284 emit_llvmonly_throw (ctx, bb, rethrow, lhs);
6285 has_terminator = TRUE;
6286 ctx->unreachable [bb->block_num] = TRUE;
6288 emit_throw (ctx, bb, rethrow, lhs);
6289 builder = ctx->builder;
6293 case OP_CALL_HANDLER: {
6295 * We don't 'call' handlers, but instead simply branch to them.
6296 * The code generated by ENDFINALLY will branch back to us.
6298 LLVMBasicBlockRef noex_bb;
6300 BBInfo *info = &bblocks [ins->inst_target_bb->block_num];
6302 bb_list = info->call_handler_return_bbs;
6305 * Set the indicator variable for the finally clause.
6307 lhs = info->finally_ind;
6309 LLVMBuildStore (builder, LLVMConstInt (LLVMInt32Type (), g_slist_length (bb_list) + 1, FALSE), lhs);
6311 /* Branch to the finally clause */
6312 LLVMBuildBr (builder, info->call_handler_target_bb);
6314 noex_bb = gen_bb (ctx, "CALL_HANDLER_CONT_BB");
6315 info->call_handler_return_bbs = g_slist_append_mempool (cfg->mempool, info->call_handler_return_bbs, noex_bb);
6317 builder = ctx->builder = create_builder (ctx);
6318 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
6320 bblocks [bb->block_num].end_bblock = noex_bb;
6323 case OP_START_HANDLER: {
6326 case OP_ENDFINALLY: {
6327 LLVMBasicBlockRef resume_bb;
6328 MonoBasicBlock *handler_bb;
6329 LLVMValueRef val, switch_ins, callee;
6333 handler_bb = (MonoBasicBlock*)g_hash_table_lookup (ctx->region_to_handler, GUINT_TO_POINTER (mono_get_block_region_notry (cfg, bb->region)));
6334 g_assert (handler_bb);
6335 info = &bblocks [handler_bb->block_num];
6336 lhs = info->finally_ind;
6339 bb_list = info->call_handler_return_bbs;
6341 resume_bb = gen_bb (ctx, "ENDFINALLY_RESUME_BB");
6343 /* Load the finally variable */
6344 val = LLVMBuildLoad (builder, lhs, "");
6346 /* Reset the variable */
6347 LLVMBuildStore (builder, LLVMConstInt (LLVMInt32Type (), 0, FALSE), lhs);
6349 /* Branch to either resume_bb, or to the bblocks in bb_list */
6350 switch_ins = LLVMBuildSwitch (builder, val, resume_bb, g_slist_length (bb_list));
6352 * The other targets are added at the end to handle OP_CALL_HANDLER
6353 * opcodes processed later.
6355 info->endfinally_switch_ins_list = g_slist_append_mempool (cfg->mempool, info->endfinally_switch_ins_list, switch_ins);
6357 builder = ctx->builder = create_builder (ctx);
6358 LLVMPositionBuilderAtEnd (ctx->builder, resume_bb);
6360 if (ctx->llvm_only) {
6361 emit_resume_eh (ctx, bb);
6363 if (ctx->cfg->compile_aot) {
6364 callee = get_callee (ctx, LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE), MONO_PATCH_INFO_INTERNAL_METHOD, "llvm_resume_unwind_trampoline");
6366 #if LLVM_API_VERSION > 100
6367 MonoJitICallInfo *info;
6369 info = mono_find_jit_icall_by_name ("llvm_resume_unwind_trampoline");
6371 gpointer target = (void*)info->func;
6372 LLVMTypeRef icall_sig = LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE);
6373 callee = emit_jit_callee (ctx, "llvm_resume_unwind_trampoline", icall_sig, target);
6375 callee = LLVMGetNamedFunction (ctx->lmodule, "llvm_resume_unwind_trampoline");
6378 LLVMBuildCall (builder, callee, NULL, 0, "");
6379 LLVMBuildUnreachable (builder);
6382 has_terminator = TRUE;
6385 case OP_IL_SEQ_POINT:
6390 sprintf (reason, "opcode %s", mono_inst_name (ins->opcode));
6391 set_failure (ctx, reason);
6399 /* Convert the value to the type required by phi nodes */
6400 if (spec [MONO_INST_DEST] != ' ' && !MONO_IS_STORE_MEMBASE (ins) && ctx->vreg_types [ins->dreg]) {
6401 if (!values [ins->dreg])
6403 values [ins->dreg] = addresses [ins->dreg];
6405 values [ins->dreg] = convert (ctx, values [ins->dreg], ctx->vreg_types [ins->dreg]);
6408 /* Add stores for volatile variables */
6409 if (spec [MONO_INST_DEST] != ' ' && spec [MONO_INST_DEST] != 'v' && !MONO_IS_STORE_MEMBASE (ins))
6410 emit_volatile_store (ctx, ins->dreg);
6416 if (!has_terminator && bb->next_bb && (bb == cfg->bb_entry || bb->in_count > 0)) {
6417 LLVMBuildBr (builder, get_bb (ctx, bb->next_bb));
6420 if (bb == cfg->bb_exit && sig->ret->type == MONO_TYPE_VOID) {
6421 emit_dbg_loc (ctx, builder, cfg->header->code + cfg->header->code_size - 1);
6422 LLVMBuildRetVoid (builder);
6425 if (bb == cfg->bb_entry)
6426 ctx->last_alloca = LLVMGetLastInstruction (get_bb (ctx, cfg->bb_entry));
6430 * mono_llvm_check_method_supported:
6432 * Do some quick checks to decide whenever cfg->method can be compiled by LLVM, to avoid
6433 * compiling a method twice.
6436 mono_llvm_check_method_supported (MonoCompile *cfg)
6443 if (cfg->method->save_lmf) {
6444 cfg->exception_message = g_strdup ("lmf");
6445 cfg->disable_llvm = TRUE;
6447 if (cfg->disable_llvm)
6451 * Nested clauses where one of the clauses is a finally clause is
6452 * not supported, because LLVM can't figure out the control flow,
6453 * probably because we resume exception handling by calling our
6454 * own function instead of using the 'resume' llvm instruction.
6456 for (i = 0; i < cfg->header->num_clauses; ++i) {
6457 for (j = 0; j < cfg->header->num_clauses; ++j) {
6458 MonoExceptionClause *clause1 = &cfg->header->clauses [i];
6459 MonoExceptionClause *clause2 = &cfg->header->clauses [j];
6461 // FIXME: Nested try clauses fail in some cases too, i.e. #37273
6462 if (i != j && clause1->try_offset >= clause2->try_offset && clause1->handler_offset <= clause2->handler_offset) {
6463 //(clause1->flags == MONO_EXCEPTION_CLAUSE_FINALLY || clause2->flags == MONO_EXCEPTION_CLAUSE_FINALLY)) {
6464 cfg->exception_message = g_strdup ("nested clauses");
6465 cfg->disable_llvm = TRUE;
6470 if (cfg->disable_llvm)
6474 if (cfg->method->dynamic) {
6475 cfg->exception_message = g_strdup ("dynamic.");
6476 cfg->disable_llvm = TRUE;
6478 if (cfg->disable_llvm)
6482 static LLVMCallInfo*
6483 get_llvm_call_info (MonoCompile *cfg, MonoMethodSignature *sig)
6485 LLVMCallInfo *linfo;
6488 if (cfg->gsharedvt && cfg->llvm_only && mini_is_gsharedvt_variable_signature (sig)) {
6492 * Gsharedvt methods have the following calling convention:
6493 * - all arguments are passed by ref, even non generic ones
6494 * - the return value is returned by ref too, using a vret
6495 * argument passed after 'this'.
6497 n = sig->param_count + sig->hasthis;
6498 linfo = (LLVMCallInfo*)mono_mempool_alloc0 (cfg->mempool, sizeof (LLVMCallInfo) + (sizeof (LLVMArgInfo) * n));
6502 linfo->args [pindex ++].storage = LLVMArgNormal;
6504 if (sig->ret->type != MONO_TYPE_VOID) {
6505 if (mini_is_gsharedvt_variable_type (sig->ret))
6506 linfo->ret.storage = LLVMArgGsharedvtVariable;
6507 else if (mini_type_is_vtype (sig->ret))
6508 linfo->ret.storage = LLVMArgGsharedvtFixedVtype;
6510 linfo->ret.storage = LLVMArgGsharedvtFixed;
6511 linfo->vret_arg_index = pindex;
6513 linfo->ret.storage = LLVMArgNone;
6516 for (i = 0; i < sig->param_count; ++i) {
6517 if (sig->params [i]->byref)
6518 linfo->args [pindex].storage = LLVMArgNormal;
6519 else if (mini_is_gsharedvt_variable_type (sig->params [i]))
6520 linfo->args [pindex].storage = LLVMArgGsharedvtVariable;
6521 else if (mini_type_is_vtype (sig->params [i]))
6522 linfo->args [pindex].storage = LLVMArgGsharedvtFixedVtype;
6524 linfo->args [pindex].storage = LLVMArgGsharedvtFixed;
6525 linfo->args [pindex].type = sig->params [i];
6532 linfo = mono_arch_get_llvm_call_info (cfg, sig);
6533 for (i = 0; i < sig->param_count; ++i)
6534 linfo->args [i + sig->hasthis].type = sig->params [i];
6540 emit_method_inner (EmitContext *ctx);
6543 free_ctx (EmitContext *ctx)
6547 g_free (ctx->values);
6548 g_free (ctx->addresses);
6549 g_free (ctx->vreg_types);
6550 g_free (ctx->vreg_cli_types);
6551 g_free (ctx->is_dead);
6552 g_free (ctx->unreachable);
6553 g_ptr_array_free (ctx->phi_values, TRUE);
6554 g_free (ctx->bblocks);
6555 g_hash_table_destroy (ctx->region_to_handler);
6556 g_hash_table_destroy (ctx->clause_to_handler);
6557 g_hash_table_destroy (ctx->jit_callees);
6558 g_free (ctx->method_name);
6559 g_ptr_array_free (ctx->bblock_list, TRUE);
6561 for (l = ctx->builders; l; l = l->next) {
6562 LLVMBuilderRef builder = (LLVMBuilderRef)l->data;
6563 LLVMDisposeBuilder (builder);
6570 * mono_llvm_emit_method:
6572 * Emit LLVM IL from the mono IL, and compile it to native code using LLVM.
6575 mono_llvm_emit_method (MonoCompile *cfg)
6579 gboolean is_linkonce = FALSE;
6582 /* The code below might acquire the loader lock, so use it for global locking */
6583 mono_loader_lock ();
6585 /* Used to communicate with the callbacks */
6586 mono_native_tls_set_value (current_cfg_tls_id, cfg);
6588 ctx = g_new0 (EmitContext, 1);
6590 ctx->mempool = cfg->mempool;
6593 * This maps vregs to the LLVM instruction defining them
6595 ctx->values = g_new0 (LLVMValueRef, cfg->next_vreg);
6597 * This maps vregs for volatile variables to the LLVM instruction defining their
6600 ctx->addresses = g_new0 (LLVMValueRef, cfg->next_vreg);
6601 ctx->vreg_types = g_new0 (LLVMTypeRef, cfg->next_vreg);
6602 ctx->vreg_cli_types = g_new0 (MonoType*, cfg->next_vreg);
6603 ctx->phi_values = g_ptr_array_sized_new (256);
6605 * This signals whenever the vreg was defined by a phi node with no input vars
6606 * (i.e. all its input bblocks end with NOT_REACHABLE).
6608 ctx->is_dead = g_new0 (gboolean, cfg->next_vreg);
6609 /* Whenever the bblock is unreachable */
6610 ctx->unreachable = g_new0 (gboolean, cfg->max_block_num);
6611 ctx->bblock_list = g_ptr_array_sized_new (256);
6613 ctx->region_to_handler = g_hash_table_new (NULL, NULL);
6614 ctx->clause_to_handler = g_hash_table_new (NULL, NULL);
6615 ctx->method_to_callers = g_hash_table_new (NULL, NULL);
6616 ctx->jit_callees = g_hash_table_new (NULL, NULL);
6617 if (cfg->compile_aot) {
6618 ctx->module = &aot_module;
6622 * Allow the linker to discard duplicate copies of wrappers, generic instances etc. by using the 'linkonce'
6623 * linkage for them. This requires the following:
6624 * - the method needs to have a unique mangled name
6625 * - llvmonly mode, since the code in aot-runtime.c would initialize got slots in the wrong aot image etc.
6627 is_linkonce = ctx->module->llvm_only && ctx->module->static_link && mono_aot_is_linkonce_method (cfg->method);
6629 method_name = mono_aot_get_mangled_method_name (cfg->method);
6631 is_linkonce = FALSE;
6634 printf ("%s %s\n", mono_method_full_name (cfg->method, 1), method_name);
6636 printf ("%s\n", mono_method_full_name (cfg->method, 1));
6640 method_name = mono_aot_get_method_name (cfg);
6641 cfg->llvm_method_name = g_strdup (method_name);
6643 init_jit_module (cfg->domain);
6644 ctx->module = (MonoLLVMModule*)domain_jit_info (cfg->domain)->llvm_module;
6645 method_name = mono_method_full_name (cfg->method, TRUE);
6647 ctx->method_name = method_name;
6648 ctx->is_linkonce = is_linkonce;
6650 #if LLVM_API_VERSION > 100
6651 ctx->lmodule = LLVMModuleCreateWithName ("jit-module");
6653 ctx->lmodule = ctx->module->lmodule;
6655 ctx->llvm_only = ctx->module->llvm_only;
6657 emit_method_inner (ctx);
6659 if (!ctx_ok (ctx)) {
6661 /* Need to add unused phi nodes as they can be referenced by other values */
6662 LLVMBasicBlockRef phi_bb = LLVMAppendBasicBlock (ctx->lmethod, "PHI_BB");
6663 LLVMBuilderRef builder;
6665 builder = create_builder (ctx);
6666 LLVMPositionBuilderAtEnd (builder, phi_bb);
6668 for (i = 0; i < ctx->phi_values->len; ++i) {
6669 LLVMValueRef v = (LLVMValueRef)g_ptr_array_index (ctx->phi_values, i);
6670 if (LLVMGetInstructionParent (v) == NULL)
6671 LLVMInsertIntoBuilder (builder, v);
6674 LLVMDeleteFunction (ctx->lmethod);
6680 mono_native_tls_set_value (current_cfg_tls_id, NULL);
6682 mono_loader_unlock ();
6686 emit_method_inner (EmitContext *ctx)
6688 MonoCompile *cfg = ctx->cfg;
6689 MonoMethodSignature *sig;
6691 LLVMTypeRef method_type;
6692 LLVMValueRef method = NULL;
6693 LLVMValueRef *values = ctx->values;
6694 int i, max_block_num, bb_index;
6695 gboolean last = FALSE;
6696 LLVMCallInfo *linfo;
6697 LLVMModuleRef lmodule = ctx->lmodule;
6699 GPtrArray *bblock_list = ctx->bblock_list;
6700 MonoMethodHeader *header;
6701 MonoExceptionClause *clause;
6704 if (cfg->gsharedvt && !cfg->llvm_only) {
6705 set_failure (ctx, "gsharedvt");
6711 static int count = 0;
6714 if (g_getenv ("LLVM_COUNT")) {
6715 if (count == atoi (g_getenv ("LLVM_COUNT"))) {
6716 printf ("LAST: %s\n", mono_method_full_name (cfg->method, TRUE));
6720 if (count > atoi (g_getenv ("LLVM_COUNT"))) {
6721 set_failure (ctx, "count");
6728 sig = mono_method_signature (cfg->method);
6731 linfo = get_llvm_call_info (cfg, sig);
6737 linfo->rgctx_arg = TRUE;
6738 ctx->method_type = method_type = sig_to_llvm_sig_full (ctx, sig, linfo);
6742 method = LLVMAddFunction (lmodule, ctx->method_name, method_type);
6743 ctx->lmethod = method;
6745 if (!cfg->llvm_only)
6746 LLVMSetFunctionCallConv (method, LLVMMono1CallConv);
6747 LLVMSetLinkage (method, LLVMPrivateLinkage);
6749 LLVMAddFunctionAttr (method, LLVMUWTable);
6751 if (cfg->compile_aot) {
6752 LLVMSetLinkage (method, LLVMInternalLinkage);
6753 if (ctx->module->external_symbols) {
6754 LLVMSetLinkage (method, LLVMExternalLinkage);
6755 LLVMSetVisibility (method, LLVMHiddenVisibility);
6757 if (ctx->is_linkonce) {
6758 LLVMSetLinkage (method, LLVMLinkOnceAnyLinkage);
6759 LLVMSetVisibility (method, LLVMDefaultVisibility);
6762 #if LLVM_API_VERSION > 100
6763 LLVMSetLinkage (method, LLVMExternalLinkage);
6765 LLVMSetLinkage (method, LLVMPrivateLinkage);
6769 if (cfg->method->save_lmf && !cfg->llvm_only) {
6770 set_failure (ctx, "lmf");
6774 if (sig->pinvoke && cfg->method->wrapper_type != MONO_WRAPPER_RUNTIME_INVOKE && !cfg->llvm_only) {
6775 set_failure (ctx, "pinvoke signature");
6779 header = cfg->header;
6780 for (i = 0; i < header->num_clauses; ++i) {
6781 clause = &header->clauses [i];
6782 if (clause->flags != MONO_EXCEPTION_CLAUSE_FINALLY && clause->flags != MONO_EXCEPTION_CLAUSE_NONE) {
6783 set_failure (ctx, "non-finally/catch clause.");
6787 if (header->num_clauses || (cfg->method->iflags & METHOD_IMPL_ATTRIBUTE_NOINLINING) || cfg->no_inline)
6788 /* We can't handle inlined methods with clauses */
6789 LLVMAddFunctionAttr (method, LLVMNoInlineAttribute);
6791 if (linfo->rgctx_arg) {
6792 ctx->rgctx_arg = LLVMGetParam (method, linfo->rgctx_arg_pindex);
6793 ctx->rgctx_arg_pindex = linfo->rgctx_arg_pindex;
6795 * We mark the rgctx parameter with the inreg attribute, which is mapped to
6796 * MONO_ARCH_RGCTX_REG in the Mono calling convention in llvm, i.e.
6797 * CC_X86_64_Mono in X86CallingConv.td.
6799 if (!ctx->llvm_only)
6800 LLVMAddAttribute (ctx->rgctx_arg, LLVMInRegAttribute);
6801 LLVMSetValueName (ctx->rgctx_arg, "rgctx");
6803 ctx->rgctx_arg_pindex = -1;
6805 if (cfg->vret_addr) {
6806 values [cfg->vret_addr->dreg] = LLVMGetParam (method, linfo->vret_arg_pindex);
6807 LLVMSetValueName (values [cfg->vret_addr->dreg], "vret");
6808 if (linfo->ret.storage == LLVMArgVtypeByRef) {
6809 LLVMAddAttribute (LLVMGetParam (method, linfo->vret_arg_pindex), LLVMStructRetAttribute);
6810 LLVMAddAttribute (LLVMGetParam (method, linfo->vret_arg_pindex), LLVMNoAliasAttribute);
6815 ctx->this_arg_pindex = linfo->this_arg_pindex;
6816 ctx->this_arg = LLVMGetParam (method, linfo->this_arg_pindex);
6817 values [cfg->args [0]->dreg] = ctx->this_arg;
6818 LLVMSetValueName (values [cfg->args [0]->dreg], "this");
6821 names = g_new (char *, sig->param_count);
6822 mono_method_get_param_names (cfg->method, (const char **) names);
6824 for (i = 0; i < sig->param_count; ++i) {
6825 LLVMArgInfo *ainfo = &linfo->args [i + sig->hasthis];
6827 int pindex = ainfo->pindex + ainfo->ndummy_fpargs;
6830 for (j = 0; j < ainfo->ndummy_fpargs; ++j) {
6831 name = g_strdup_printf ("dummy_%d_%d", i, j);
6832 LLVMSetValueName (LLVMGetParam (method, ainfo->pindex + j), name);
6836 values [cfg->args [i + sig->hasthis]->dreg] = LLVMGetParam (method, pindex);
6837 if (ainfo->storage == LLVMArgGsharedvtFixed || ainfo->storage == LLVMArgGsharedvtFixedVtype) {
6838 if (names [i] && names [i][0] != '\0')
6839 name = g_strdup_printf ("p_arg_%s", names [i]);
6841 name = g_strdup_printf ("p_arg_%d", i);
6843 if (names [i] && names [i][0] != '\0')
6844 name = g_strdup_printf ("arg_%s", names [i]);
6846 name = g_strdup_printf ("arg_%d", i);
6848 LLVMSetValueName (values [cfg->args [i + sig->hasthis]->dreg], name);
6850 if (ainfo->storage == LLVMArgVtypeByVal)
6851 LLVMAddAttribute (LLVMGetParam (method, pindex), LLVMByValAttribute);
6853 if (ainfo->storage == LLVMArgVtypeByRef) {
6855 cfg->args [i + sig->hasthis]->opcode = OP_VTARG_ADDR;
6860 if (ctx->module->emit_dwarf && cfg->compile_aot && mono_debug_enabled ()) {
6861 ctx->minfo = mono_debug_lookup_method (cfg->method);
6862 ctx->dbg_md = emit_dbg_subprogram (ctx, cfg, method, ctx->method_name);
6866 for (bb = cfg->bb_entry; bb; bb = bb->next_bb)
6867 max_block_num = MAX (max_block_num, bb->block_num);
6868 ctx->bblocks = bblocks = g_new0 (BBInfo, max_block_num + 1);
6870 /* Add branches between non-consecutive bblocks */
6871 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
6872 if (bb->last_ins && MONO_IS_COND_BRANCH_OP (bb->last_ins) &&
6873 bb->next_bb != bb->last_ins->inst_false_bb) {
6875 MonoInst *inst = (MonoInst*)mono_mempool_alloc0 (cfg->mempool, sizeof (MonoInst));
6876 inst->opcode = OP_BR;
6877 inst->inst_target_bb = bb->last_ins->inst_false_bb;
6878 mono_bblock_add_inst (bb, inst);
6883 * The INDIRECT flag added by OP_LDADDR inhibits optimizations, even if the LDADDR
6884 * was later optimized away, so clear these flags, and add them back for the still
6885 * present OP_LDADDR instructions.
6887 for (i = 0; i < cfg->next_vreg; ++i) {
6890 ins = get_vreg_to_inst (cfg, i);
6891 if (ins && ins != cfg->rgctx_var)
6892 ins->flags &= ~MONO_INST_INDIRECT;
6896 * Make a first pass over the code to precreate PHI nodes/set INDIRECT flags.
6898 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
6900 LLVMBuilderRef builder;
6902 char dname_buf[128];
6904 builder = create_builder (ctx);
6906 for (ins = bb->code; ins; ins = ins->next) {
6907 switch (ins->opcode) {
6912 LLVMTypeRef phi_type = llvm_type_to_stack_type (cfg, type_to_llvm_type (ctx, &ins->klass->byval_arg));
6917 if (ins->opcode == OP_VPHI) {
6918 /* Treat valuetype PHI nodes as operating on the address itself */
6919 g_assert (ins->klass);
6920 phi_type = LLVMPointerType (type_to_llvm_type (ctx, &ins->klass->byval_arg), 0);
6924 * Have to precreate these, as they can be referenced by
6925 * earlier instructions.
6927 sprintf (dname_buf, "t%d", ins->dreg);
6929 values [ins->dreg] = LLVMBuildPhi (builder, phi_type, dname);
6931 if (ins->opcode == OP_VPHI)
6932 ctx->addresses [ins->dreg] = values [ins->dreg];
6934 g_ptr_array_add (ctx->phi_values, values [ins->dreg]);
6937 * Set the expected type of the incoming arguments since these have
6938 * to have the same type.
6940 for (i = 0; i < ins->inst_phi_args [0]; i++) {
6941 int sreg1 = ins->inst_phi_args [i + 1];
6944 ctx->vreg_types [sreg1] = phi_type;
6949 ((MonoInst*)ins->inst_p0)->flags |= MONO_INST_INDIRECT;
6958 * Create an ordering for bblocks, use the depth first order first, then
6959 * put the exception handling bblocks last.
6961 for (bb_index = 0; bb_index < cfg->num_bblocks; ++bb_index) {
6962 bb = cfg->bblocks [bb_index];
6963 if (!(bb->region != -1 && !MONO_BBLOCK_IS_IN_REGION (bb, MONO_REGION_TRY))) {
6964 g_ptr_array_add (bblock_list, bb);
6965 bblocks [bb->block_num].added = TRUE;
6969 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
6970 if (!bblocks [bb->block_num].added)
6971 g_ptr_array_add (bblock_list, bb);
6975 * Second pass: generate code.
6978 LLVMBuilderRef entry_builder = create_builder (ctx);
6979 LLVMBasicBlockRef entry_bb = get_bb (ctx, cfg->bb_entry);
6980 LLVMPositionBuilderAtEnd (entry_builder, entry_bb);
6981 emit_entry_bb (ctx, entry_builder);
6983 // Make landing pads first
6984 ctx->exc_meta = g_hash_table_new_full (NULL, NULL, NULL, NULL);
6986 if (ctx->llvm_only) {
6987 size_t group_index = 0;
6988 while (group_index < cfg->header->num_clauses) {
6990 size_t cursor = group_index;
6991 while (cursor < cfg->header->num_clauses &&
6992 CLAUSE_START (&cfg->header->clauses [cursor]) == CLAUSE_START (&cfg->header->clauses [group_index]) &&
6993 CLAUSE_END (&cfg->header->clauses [cursor]) == CLAUSE_END (&cfg->header->clauses [group_index])) {
6998 LLVMBasicBlockRef lpad_bb = emit_landing_pad (ctx, group_index, count);
6999 intptr_t key = CLAUSE_END (&cfg->header->clauses [group_index]);
7000 g_hash_table_insert (ctx->exc_meta, (gpointer)key, lpad_bb);
7002 group_index = cursor;
7006 for (bb_index = 0; bb_index < bblock_list->len; ++bb_index) {
7007 bb = (MonoBasicBlock*)g_ptr_array_index (bblock_list, bb_index);
7009 // Prune unreachable mono BBs.
7010 if (!(bb == cfg->bb_entry || bb->in_count > 0))
7013 process_bb (ctx, bb);
7017 g_hash_table_destroy (ctx->exc_meta);
7019 mono_memory_barrier ();
7021 /* Add incoming phi values */
7022 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
7023 GSList *l, *ins_list;
7025 ins_list = bblocks [bb->block_num].phi_nodes;
7027 for (l = ins_list; l; l = l->next) {
7028 PhiNode *node = (PhiNode*)l->data;
7029 MonoInst *phi = node->phi;
7030 int sreg1 = node->sreg;
7031 LLVMBasicBlockRef in_bb;
7036 in_bb = get_end_bb (ctx, node->in_bb);
7038 if (ctx->unreachable [node->in_bb->block_num])
7041 if (!values [sreg1]) {
7042 /* Can happen with values in EH clauses */
7043 set_failure (ctx, "incoming phi sreg1");
7047 if (phi->opcode == OP_VPHI) {
7048 g_assert (LLVMTypeOf (ctx->addresses [sreg1]) == LLVMTypeOf (values [phi->dreg]));
7049 LLVMAddIncoming (values [phi->dreg], &ctx->addresses [sreg1], &in_bb, 1);
7051 if (LLVMTypeOf (values [sreg1]) != LLVMTypeOf (values [phi->dreg])) {
7052 set_failure (ctx, "incoming phi arg type mismatch");
7055 g_assert (LLVMTypeOf (values [sreg1]) == LLVMTypeOf (values [phi->dreg]));
7056 LLVMAddIncoming (values [phi->dreg], &values [sreg1], &in_bb, 1);
7061 /* Nullify empty phi instructions */
7062 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
7063 GSList *l, *ins_list;
7065 ins_list = bblocks [bb->block_num].phi_nodes;
7067 for (l = ins_list; l; l = l->next) {
7068 PhiNode *node = (PhiNode*)l->data;
7069 MonoInst *phi = node->phi;
7070 LLVMValueRef phi_ins = values [phi->dreg];
7073 /* Already removed */
7076 if (LLVMCountIncoming (phi_ins) == 0) {
7077 mono_llvm_replace_uses_of (phi_ins, LLVMConstNull (LLVMTypeOf (phi_ins)));
7078 LLVMInstructionEraseFromParent (phi_ins);
7079 values [phi->dreg] = NULL;
7084 /* Create the SWITCH statements for ENDFINALLY instructions */
7085 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
7086 BBInfo *info = &bblocks [bb->block_num];
7088 for (l = info->endfinally_switch_ins_list; l; l = l->next) {
7089 LLVMValueRef switch_ins = (LLVMValueRef)l->data;
7090 GSList *bb_list = info->call_handler_return_bbs;
7092 for (i = 0; i < g_slist_length (bb_list); ++i)
7093 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), i + 1, FALSE), (LLVMBasicBlockRef)(g_slist_nth (bb_list, i)->data));
7097 /* Initialize the method if needed */
7098 if (cfg->compile_aot && ctx->llvm_only) {
7099 // FIXME: Add more shared got entries
7100 ctx->builder = create_builder (ctx);
7101 LLVMPositionBuilderAtEnd (ctx->builder, ctx->init_bb);
7103 ctx->module->max_method_idx = MAX (ctx->module->max_method_idx, cfg->method_index);
7105 // FIXME: beforefieldinit
7106 if (ctx->has_got_access || mono_class_get_cctor (cfg->method->klass)) {
7108 * linkonce methods shouldn't have initialization,
7109 * because they might belong to assemblies which
7110 * haven't been loaded yet.
7112 g_assert (!ctx->is_linkonce);
7113 emit_init_method (ctx);
7115 LLVMBuildBr (ctx->builder, ctx->inited_bb);
7119 if (cfg->llvm_only) {
7120 GHashTableIter iter;
7122 GSList *callers, *l, *l2;
7125 * Add the contents of ctx->method_to_callers to module->method_to_callers.
7126 * We can't do this earlier, as it contains llvm instructions which can be
7127 * freed if compilation fails.
7128 * FIXME: Get rid of this when all methods can be llvm compiled.
7130 g_hash_table_iter_init (&iter, ctx->method_to_callers);
7131 while (g_hash_table_iter_next (&iter, (void**)&method, (void**)&callers)) {
7132 for (l = callers; l; l = l->next) {
7133 l2 = (GSList*)g_hash_table_lookup (ctx->module->method_to_callers, method);
7134 l2 = g_slist_prepend (l2, l->data);
7135 g_hash_table_insert (ctx->module->method_to_callers, method, l2);
7140 if (cfg->verbose_level > 1)
7141 mono_llvm_dump_value (method);
7143 if (cfg->compile_aot && !cfg->llvm_only)
7144 mark_as_used (ctx->module, method);
7146 if (cfg->compile_aot && !cfg->llvm_only) {
7147 LLVMValueRef md_args [16];
7148 LLVMValueRef md_node;
7151 method_index = mono_aot_get_method_index (cfg->orig_method);
7152 md_args [0] = LLVMMDString (ctx->method_name, strlen (ctx->method_name));
7153 md_args [1] = LLVMConstInt (LLVMInt32Type (), method_index, FALSE);
7154 md_node = LLVMMDNode (md_args, 2);
7155 LLVMAddNamedMetadataOperand (lmodule, "mono.function_indexes", md_node);
7156 //LLVMSetMetadata (method, md_kind, LLVMMDNode (&md_arg, 1));
7159 if (cfg->compile_aot) {
7160 /* Don't generate native code, keep the LLVM IR */
7161 if (cfg->verbose_level)
7162 printf ("%s emitted as %s\n", mono_method_full_name (cfg->method, TRUE), ctx->method_name);
7164 #if LLVM_API_VERSION < 100
7165 /* VerifyFunction can't handle some of the debug info created by DIBuilder in llvm 3.9 */
7166 int err = LLVMVerifyFunction(ctx->lmethod, LLVMPrintMessageAction);
7167 g_assert (err == 0);
7170 //LLVMVerifyFunction(method, 0);
7171 #if LLVM_API_VERSION > 100
7172 MonoDomain *domain = mono_domain_get ();
7173 MonoJitDomainInfo *domain_info;
7174 int nvars = g_hash_table_size (ctx->jit_callees);
7175 LLVMValueRef *callee_vars = g_new0 (LLVMValueRef, nvars);
7176 gpointer *callee_addrs = g_new0 (gpointer, nvars);
7177 GHashTableIter iter;
7183 * Compute the addresses of the LLVM globals pointing to the
7184 * methods called by the current method. Pass it to the trampoline
7185 * code so it can update them after their corresponding method was
7188 g_hash_table_iter_init (&iter, ctx->jit_callees);
7190 while (g_hash_table_iter_next (&iter, NULL, (void**)&var))
7191 callee_vars [i ++] = var;
7193 cfg->native_code = mono_llvm_compile_method (ctx->module->mono_ee, ctx->lmethod, nvars, callee_vars, callee_addrs, &eh_frame);
7195 decode_llvm_eh_info (ctx, eh_frame);
7197 mono_domain_lock (domain);
7198 domain_info = domain_jit_info (domain);
7199 if (!domain_info->llvm_jit_callees)
7200 domain_info->llvm_jit_callees = g_hash_table_new (NULL, NULL);
7201 g_hash_table_iter_init (&iter, ctx->jit_callees);
7203 while (g_hash_table_iter_next (&iter, (void**)&callee, (void**)&var)) {
7204 GSList *addrs = g_hash_table_lookup (domain_info->llvm_jit_callees, callee);
7205 addrs = g_slist_prepend (addrs, callee_addrs [i]);
7206 g_hash_table_insert (domain_info->llvm_jit_callees, callee, addrs);
7209 mono_domain_unlock (domain);
7211 mono_llvm_optimize_method (ctx->module->mono_ee, ctx->lmethod);
7213 if (cfg->verbose_level > 1)
7214 mono_llvm_dump_value (ctx->lmethod);
7216 cfg->native_code = (unsigned char*)LLVMGetPointerToGlobal (ctx->module->ee, ctx->lmethod);
7218 /* Set by emit_cb */
7219 g_assert (cfg->code_len);
7223 if (ctx->module->method_to_lmethod)
7224 g_hash_table_insert (ctx->module->method_to_lmethod, cfg->method, ctx->lmethod);
7225 if (ctx->module->idx_to_lmethod)
7226 g_hash_table_insert (ctx->module->idx_to_lmethod, GINT_TO_POINTER (cfg->method_index), ctx->lmethod);
7228 if (ctx->llvm_only && cfg->orig_method->klass->valuetype && !(cfg->orig_method->flags & METHOD_ATTRIBUTE_STATIC))
7229 emit_unbox_tramp (ctx, ctx->method_name, ctx->method_type, ctx->lmethod, cfg->method_index);
7233 * mono_llvm_create_vars:
7235 * Same as mono_arch_create_vars () for LLVM.
7238 mono_llvm_create_vars (MonoCompile *cfg)
7240 MonoMethodSignature *sig;
7242 sig = mono_method_signature (cfg->method);
7243 if (cfg->gsharedvt && cfg->llvm_only) {
7244 if (mini_is_gsharedvt_variable_signature (sig) && sig->ret->type != MONO_TYPE_VOID) {
7245 cfg->vret_addr = mono_compile_create_var (cfg, &mono_get_intptr_class ()->byval_arg, OP_ARG);
7246 if (G_UNLIKELY (cfg->verbose_level > 1)) {
7247 printf ("vret_addr = ");
7248 mono_print_ins (cfg->vret_addr);
7252 mono_arch_create_vars (cfg);
7257 * mono_llvm_emit_call:
7259 * Same as mono_arch_emit_call () for LLVM.
7262 mono_llvm_emit_call (MonoCompile *cfg, MonoCallInst *call)
7265 MonoMethodSignature *sig;
7266 int i, n, stack_size;
7271 sig = call->signature;
7272 n = sig->param_count + sig->hasthis;
7274 call->cinfo = get_llvm_call_info (cfg, sig);
7276 if (cfg->disable_llvm)
7279 if (sig->call_convention == MONO_CALL_VARARG) {
7280 cfg->exception_message = g_strdup ("varargs");
7281 cfg->disable_llvm = TRUE;
7284 for (i = 0; i < n; ++i) {
7287 ainfo = call->cinfo->args + i;
7289 in = call->args [i];
7291 /* Simply remember the arguments */
7292 switch (ainfo->storage) {
7293 case LLVMArgNormal: {
7294 MonoType *t = (sig->hasthis && i == 0) ? &mono_get_intptr_class ()->byval_arg : ainfo->type;
7297 opcode = mono_type_to_regmove (cfg, t);
7298 if (opcode == OP_FMOVE) {
7299 MONO_INST_NEW (cfg, ins, OP_FMOVE);
7300 ins->dreg = mono_alloc_freg (cfg);
7301 } else if (opcode == OP_LMOVE) {
7302 MONO_INST_NEW (cfg, ins, OP_LMOVE);
7303 ins->dreg = mono_alloc_lreg (cfg);
7304 } else if (opcode == OP_RMOVE) {
7305 MONO_INST_NEW (cfg, ins, OP_RMOVE);
7306 ins->dreg = mono_alloc_freg (cfg);
7308 MONO_INST_NEW (cfg, ins, OP_MOVE);
7309 ins->dreg = mono_alloc_ireg (cfg);
7311 ins->sreg1 = in->dreg;
7314 case LLVMArgVtypeByVal:
7315 case LLVMArgVtypeByRef:
7316 case LLVMArgVtypeInReg:
7317 case LLVMArgVtypeAsScalar:
7318 case LLVMArgAsIArgs:
7319 case LLVMArgAsFpArgs:
7320 case LLVMArgGsharedvtVariable:
7321 case LLVMArgGsharedvtFixed:
7322 case LLVMArgGsharedvtFixedVtype:
7323 MONO_INST_NEW (cfg, ins, OP_LLVM_OUTARG_VT);
7324 ins->dreg = mono_alloc_ireg (cfg);
7325 ins->sreg1 = in->dreg;
7326 ins->inst_p0 = mono_mempool_alloc0 (cfg->mempool, sizeof (LLVMArgInfo));
7327 memcpy (ins->inst_p0, ainfo, sizeof (LLVMArgInfo));
7328 ins->inst_vtype = ainfo->type;
7329 ins->klass = mono_class_from_mono_type (ainfo->type);
7332 cfg->exception_message = g_strdup ("ainfo->storage");
7333 cfg->disable_llvm = TRUE;
7337 if (!cfg->disable_llvm) {
7338 MONO_ADD_INS (cfg->cbb, ins);
7339 mono_call_inst_add_outarg_reg (cfg, call, ins->dreg, 0, FALSE);
7344 static unsigned char*
7345 alloc_cb (LLVMValueRef function, int size)
7349 cfg = (MonoCompile*)mono_native_tls_get_value (current_cfg_tls_id);
7353 return (unsigned char*)mono_domain_code_reserve (cfg->domain, size);
7355 return (unsigned char*)mono_domain_code_reserve (mono_domain_get (), size);
7360 emitted_cb (LLVMValueRef function, void *start, void *end)
7364 cfg = (MonoCompile*)mono_native_tls_get_value (current_cfg_tls_id);
7366 cfg->code_len = (guint8*)end - (guint8*)start;
7370 exception_cb (void *data)
7373 MonoJitExceptionInfo *ei;
7374 guint32 ei_len, i, j, nested_len, nindex;
7375 gpointer *type_info;
7376 int this_reg, this_offset;
7378 cfg = (MonoCompile*)mono_native_tls_get_value (current_cfg_tls_id);
7382 * data points to a DWARF FDE structure, convert it to our unwind format and
7384 * An alternative would be to save it directly, and modify our unwinder to work
7387 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);
7388 if (cfg->verbose_level > 1)
7389 mono_print_unwind_info (cfg->encoded_unwind_ops, cfg->encoded_unwind_ops_len);
7391 /* Count nested clauses */
7393 for (i = 0; i < ei_len; ++i) {
7394 gint32 cindex1 = *(gint32*)type_info [i];
7395 MonoExceptionClause *clause1 = &cfg->header->clauses [cindex1];
7397 for (j = 0; j < cfg->header->num_clauses; ++j) {
7399 MonoExceptionClause *clause2 = &cfg->header->clauses [cindex2];
7401 if (cindex1 != cindex2 && clause1->try_offset >= clause2->try_offset && clause1->handler_offset <= clause2->handler_offset) {
7407 cfg->llvm_ex_info = (MonoJitExceptionInfo*)mono_mempool_alloc0 (cfg->mempool, (ei_len + nested_len) * sizeof (MonoJitExceptionInfo));
7408 cfg->llvm_ex_info_len = ei_len + nested_len;
7409 memcpy (cfg->llvm_ex_info, ei, ei_len * sizeof (MonoJitExceptionInfo));
7410 /* Fill the rest of the information from the type info */
7411 for (i = 0; i < ei_len; ++i) {
7412 gint32 clause_index = *(gint32*)type_info [i];
7413 MonoExceptionClause *clause = &cfg->header->clauses [clause_index];
7415 cfg->llvm_ex_info [i].flags = clause->flags;
7416 cfg->llvm_ex_info [i].data.catch_class = clause->data.catch_class;
7417 cfg->llvm_ex_info [i].clause_index = clause_index;
7421 * For nested clauses, the LLVM produced exception info associates the try interval with
7422 * the innermost handler, while mono expects it to be associated with all nesting clauses.
7423 * So add new clauses which use the IL info (catch class etc.) from the nesting clause,
7424 * and everything else from the nested clause.
7427 for (i = 0; i < ei_len; ++i) {
7428 gint32 cindex1 = *(gint32*)type_info [i];
7429 MonoExceptionClause *clause1 = &cfg->header->clauses [cindex1];
7431 for (j = 0; j < cfg->header->num_clauses; ++j) {
7433 MonoExceptionClause *clause2 = &cfg->header->clauses [cindex2];
7434 MonoJitExceptionInfo *nesting_ei, *nested_ei;
7436 if (cindex1 != cindex2 && clause1->try_offset >= clause2->try_offset && clause1->handler_offset <= clause2->handler_offset) {
7437 /* clause1 is the nested clause */
7438 nested_ei = &cfg->llvm_ex_info [i];
7439 nesting_ei = &cfg->llvm_ex_info [nindex];
7442 memcpy (nesting_ei, nested_ei, sizeof (MonoJitExceptionInfo));
7444 nesting_ei->flags = clause2->flags;
7445 nesting_ei->data.catch_class = clause2->data.catch_class;
7446 nesting_ei->clause_index = cindex2;
7450 g_assert (nindex == ei_len + nested_len);
7451 cfg->llvm_this_reg = this_reg;
7452 cfg->llvm_this_offset = this_offset;
7454 /* type_info [i] is cfg mempool allocated, no need to free it */
7460 #if LLVM_API_VERSION > 100
7462 * decode_llvm_eh_info:
7464 * Decode the EH table emitted by llvm in jit mode, and store
7465 * the result into cfg.
7468 decode_llvm_eh_info (EmitContext *ctx, gpointer eh_frame)
7470 MonoCompile *cfg = ctx->cfg;
7473 MonoLLVMFDEInfo info;
7474 MonoJitExceptionInfo *ei;
7475 guint8 *p = eh_frame;
7476 int version, fde_count, fde_offset;
7477 guint32 ei_len, i, nested_len;
7478 gpointer *type_info;
7482 * Decode the one element EH table emitted by the MonoException class
7486 /* Similar to decode_llvm_mono_eh_frame () in aot-runtime.c */
7489 g_assert (version == 3);
7492 p = (guint8 *)ALIGN_PTR_TO (p, 4);
7494 fde_count = *(guint32*)p;
7498 g_assert (fde_count == 1);
7500 /* The only table entry */
7501 fde_offset = table [1];
7504 cfg->code_len = table [0];
7505 fde_len = table [1] - fde_offset;
7508 fde = (guint8*)eh_frame + fde_offset;
7509 cie = (guint8*)table;
7511 mono_unwind_decode_llvm_mono_fde (fde, fde_len, cie, cfg->native_code, &info);
7513 cfg->encoded_unwind_ops = info.unw_info;
7514 cfg->encoded_unwind_ops_len = info.unw_info_len;
7515 if (cfg->verbose_level > 1)
7516 mono_print_unwind_info (cfg->encoded_unwind_ops, cfg->encoded_unwind_ops_len);
7517 if (info.this_reg != -1) {
7518 cfg->llvm_this_reg = info.this_reg;
7519 cfg->llvm_this_offset = info.this_offset;
7523 ei_len = info.ex_info_len;
7524 type_info = info.type_info;
7526 // Nested clauses are currently disabled
7529 cfg->llvm_ex_info = (MonoJitExceptionInfo*)mono_mempool_alloc0 (cfg->mempool, (ei_len + nested_len) * sizeof (MonoJitExceptionInfo));
7530 cfg->llvm_ex_info_len = ei_len + nested_len;
7531 memcpy (cfg->llvm_ex_info, ei, ei_len * sizeof (MonoJitExceptionInfo));
7532 /* Fill the rest of the information from the type info */
7533 for (i = 0; i < ei_len; ++i) {
7534 gint32 clause_index = *(gint32*)type_info [i];
7535 MonoExceptionClause *clause = &cfg->header->clauses [clause_index];
7537 cfg->llvm_ex_info [i].flags = clause->flags;
7538 cfg->llvm_ex_info [i].data.catch_class = clause->data.catch_class;
7539 cfg->llvm_ex_info [i].clause_index = clause_index;
7545 dlsym_cb (const char *name, void **symbol)
7551 if (!strcmp (name, "__bzero")) {
7552 *symbol = (void*)bzero;
7554 current = mono_dl_open (NULL, 0, NULL);
7557 err = mono_dl_symbol (current, name, symbol);
7559 mono_dl_close (current);
7561 #ifdef MONO_ARCH_HAVE_CREATE_LLVM_NATIVE_THUNK
7562 *symbol = (char*)mono_arch_create_llvm_native_thunk (mono_domain_get (), (guint8*)(*symbol));
7568 AddFunc (LLVMModuleRef module, const char *name, LLVMTypeRef ret_type, LLVMTypeRef *param_types, int nparams)
7570 LLVMAddFunction (module, name, LLVMFunctionType (ret_type, param_types, nparams, FALSE));
7574 AddFunc2 (LLVMModuleRef module, const char *name, LLVMTypeRef ret_type, LLVMTypeRef param_type1, LLVMTypeRef param_type2)
7576 LLVMTypeRef param_types [4];
7578 param_types [0] = param_type1;
7579 param_types [1] = param_type2;
7581 AddFunc (module, name, ret_type, param_types, 2);
7587 INTRINS_SADD_OVF_I32,
7588 INTRINS_UADD_OVF_I32,
7589 INTRINS_SSUB_OVF_I32,
7590 INTRINS_USUB_OVF_I32,
7591 INTRINS_SMUL_OVF_I32,
7592 INTRINS_UMUL_OVF_I32,
7593 INTRINS_SADD_OVF_I64,
7594 INTRINS_UADD_OVF_I64,
7595 INTRINS_SSUB_OVF_I64,
7596 INTRINS_USUB_OVF_I64,
7597 INTRINS_SMUL_OVF_I64,
7598 INTRINS_UMUL_OVF_I64,
7605 #if defined(TARGET_AMD64) || defined(TARGET_X86)
7606 INTRINS_SSE_PMOVMSKB,
7607 INTRINS_SSE_PSRLI_W,
7608 INTRINS_SSE_PSRAI_W,
7609 INTRINS_SSE_PSLLI_W,
7610 INTRINS_SSE_PSRLI_D,
7611 INTRINS_SSE_PSRAI_D,
7612 INTRINS_SSE_PSLLI_D,
7613 INTRINS_SSE_PSRLI_Q,
7614 INTRINS_SSE_PSLLI_Q,
7615 INTRINS_SSE_SQRT_PD,
7616 INTRINS_SSE_SQRT_PS,
7617 INTRINS_SSE_RSQRT_PS,
7619 INTRINS_SSE_CVTTPD2DQ,
7620 INTRINS_SSE_CVTTPS2DQ,
7621 INTRINS_SSE_CVTDQ2PD,
7622 INTRINS_SSE_CVTDQ2PS,
7623 INTRINS_SSE_CVTPD2DQ,
7624 INTRINS_SSE_CVTPS2DQ,
7625 INTRINS_SSE_CVTPD2PS,
7626 INTRINS_SSE_CVTPS2PD,
7629 INTRINS_SSE_PACKSSWB,
7630 INTRINS_SSE_PACKUSWB,
7631 INTRINS_SSE_PACKSSDW,
7632 INTRINS_SSE_PACKUSDW,
7637 INTRINS_SSE_ADDSUBPS,
7642 INTRINS_SSE_ADDSUBPD,
7650 INTRINS_SSE_PADDUSW,
7651 INTRINS_SSE_PSUBUSW,
7659 INTRINS_SSE_PADDUSB,
7660 INTRINS_SSE_PSUBUSB,
7672 static IntrinsicDesc intrinsics[] = {
7673 {INTRINS_MEMSET, "llvm.memset.p0i8.i32"},
7674 {INTRINS_MEMCPY, "llvm.memcpy.p0i8.p0i8.i32"},
7675 {INTRINS_SADD_OVF_I32, "llvm.sadd.with.overflow.i32"},
7676 {INTRINS_UADD_OVF_I32, "llvm.uadd.with.overflow.i32"},
7677 {INTRINS_SSUB_OVF_I32, "llvm.ssub.with.overflow.i32"},
7678 {INTRINS_USUB_OVF_I32, "llvm.usub.with.overflow.i32"},
7679 {INTRINS_SMUL_OVF_I32, "llvm.smul.with.overflow.i32"},
7680 {INTRINS_UMUL_OVF_I32, "llvm.umul.with.overflow.i32"},
7681 {INTRINS_SADD_OVF_I64, "llvm.sadd.with.overflow.i64"},
7682 {INTRINS_UADD_OVF_I64, "llvm.uadd.with.overflow.i64"},
7683 {INTRINS_SSUB_OVF_I64, "llvm.ssub.with.overflow.i64"},
7684 {INTRINS_USUB_OVF_I64, "llvm.usub.with.overflow.i64"},
7685 {INTRINS_SMUL_OVF_I64, "llvm.smul.with.overflow.i64"},
7686 {INTRINS_UMUL_OVF_I64, "llvm.umul.with.overflow.i64"},
7687 {INTRINS_SIN, "llvm.sin.f64"},
7688 {INTRINS_COS, "llvm.cos.f64"},
7689 {INTRINS_SQRT, "llvm.sqrt.f64"},
7690 /* This isn't an intrinsic, instead llvm seems to special case it by name */
7691 {INTRINS_FABS, "fabs"},
7692 {INTRINS_EXPECT_I8, "llvm.expect.i8"},
7693 {INTRINS_EXPECT_I1, "llvm.expect.i1"},
7694 #if defined(TARGET_AMD64) || defined(TARGET_X86)
7695 {INTRINS_SSE_PMOVMSKB, "llvm.x86.sse2.pmovmskb.128"},
7696 {INTRINS_SSE_PSRLI_W, "llvm.x86.sse2.psrli.w"},
7697 {INTRINS_SSE_PSRAI_W, "llvm.x86.sse2.psrai.w"},
7698 {INTRINS_SSE_PSLLI_W, "llvm.x86.sse2.pslli.w"},
7699 {INTRINS_SSE_PSRLI_D, "llvm.x86.sse2.psrli.d"},
7700 {INTRINS_SSE_PSRAI_D, "llvm.x86.sse2.psrai.d"},
7701 {INTRINS_SSE_PSLLI_D, "llvm.x86.sse2.pslli.d"},
7702 {INTRINS_SSE_PSRLI_Q, "llvm.x86.sse2.psrli.q"},
7703 {INTRINS_SSE_PSLLI_Q, "llvm.x86.sse2.pslli.q"},
7704 {INTRINS_SSE_SQRT_PD, "llvm.x86.sse2.sqrt.pd"},
7705 {INTRINS_SSE_SQRT_PS, "llvm.x86.sse.sqrt.ps"},
7706 {INTRINS_SSE_RSQRT_PS, "llvm.x86.sse.rsqrt.ps"},
7707 {INTRINS_SSE_RCP_PS, "llvm.x86.sse.rcp.ps"},
7708 {INTRINS_SSE_CVTTPD2DQ, "llvm.x86.sse2.cvttpd2dq"},
7709 {INTRINS_SSE_CVTTPS2DQ, "llvm.x86.sse2.cvttps2dq"},
7710 {INTRINS_SSE_CVTDQ2PD, "llvm.x86.sse2.cvtdq2pd"},
7711 {INTRINS_SSE_CVTDQ2PS, "llvm.x86.sse2.cvtdq2ps"},
7712 {INTRINS_SSE_CVTPD2DQ, "llvm.x86.sse2.cvtpd2dq"},
7713 {INTRINS_SSE_CVTPS2DQ, "llvm.x86.sse2.cvtps2dq"},
7714 {INTRINS_SSE_CVTPD2PS, "llvm.x86.sse2.cvtpd2ps"},
7715 {INTRINS_SSE_CVTPS2PD, "llvm.x86.sse2.cvtps2pd"},
7716 {INTRINS_SSE_CMPPD, "llvm.x86.sse2.cmp.pd"},
7717 {INTRINS_SSE_CMPPS, "llvm.x86.sse.cmp.ps"},
7718 {INTRINS_SSE_PACKSSWB, "llvm.x86.sse2.packsswb.128"},
7719 {INTRINS_SSE_PACKUSWB, "llvm.x86.sse2.packuswb.128"},
7720 {INTRINS_SSE_PACKSSDW, "llvm.x86.sse2.packssdw.128"},
7721 {INTRINS_SSE_PACKUSDW, "llvm.x86.sse41.packusdw"},
7722 {INTRINS_SSE_MINPS, "llvm.x86.sse.min.ps"},
7723 {INTRINS_SSE_MAXPS, "llvm.x86.sse.max.ps"},
7724 {INTRINS_SSE_HADDPS, "llvm.x86.sse3.hadd.ps"},
7725 {INTRINS_SSE_HSUBPS, "llvm.x86.sse3.hsub.ps"},
7726 {INTRINS_SSE_ADDSUBPS, "llvm.x86.sse3.addsub.ps"},
7727 {INTRINS_SSE_MINPD, "llvm.x86.sse2.min.pd"},
7728 {INTRINS_SSE_MAXPD, "llvm.x86.sse2.max.pd"},
7729 {INTRINS_SSE_HADDPD, "llvm.x86.sse3.hadd.pd"},
7730 {INTRINS_SSE_HSUBPD, "llvm.x86.sse3.hsub.pd"},
7731 {INTRINS_SSE_ADDSUBPD, "llvm.x86.sse3.addsub.pd"},
7732 {INTRINS_SSE_PMINUD, "llvm.x86.sse41.pminud"},
7733 {INTRINS_SSE_PMAXUD, "llvm.x86.sse41.pmaxud"},
7734 {INTRINS_SSE_PMINUW, "llvm.x86.sse41.pminuw"},
7735 {INTRINS_SSE_PMINSW, "llvm.x86.sse2.pmins.w"},
7736 {INTRINS_SSE_PMAXUW, "llvm.x86.sse41.pmaxuw"},
7737 {INTRINS_SSE_PADDSW, "llvm.x86.sse2.padds.w"},
7738 {INTRINS_SSE_PSUBSW, "llvm.x86.sse2.psubs.w"},
7739 {INTRINS_SSE_PADDUSW, "llvm.x86.sse2.paddus.w"},
7740 {INTRINS_SSE_PSUBUSW, "llvm.x86.sse2.psubus.w"},
7741 {INTRINS_SSE_PAVGW, "llvm.x86.sse2.pavg.w"},
7742 {INTRINS_SSE_PMULHW, "llvm.x86.sse2.pmulh.w"},
7743 {INTRINS_SSE_PMULHU, "llvm.x86.sse2.pmulhu.w"},
7744 {INTRINS_SSE_PMINUB, "llvm.x86.sse2.pminu.b"},
7745 {INTRINS_SSE_PMAXUB, "llvm.x86.sse2.pmaxu.b"},
7746 {INTRINS_SE_PADDSB, "llvm.x86.sse2.padds.b"},
7747 {INTRINS_SSE_PSUBSB, "llvm.x86.sse2.psubs.b"},
7748 {INTRINS_SSE_PADDUSB, "llvm.x86.sse2.paddus.b"},
7749 {INTRINS_SSE_PSUBUSB, "llvm.x86.sse2.psubus.b"},
7750 {INTRINS_SSE_PAVGB, "llvm.x86.sse2.pavg.b"},
7751 {INTRINS_SSE_PAUSE, "llvm.x86.sse2.pause"}
7756 add_sse_binary (LLVMModuleRef module, const char *name, int type)
7758 LLVMTypeRef ret_type = type_to_simd_type (type);
7759 AddFunc2 (module, name, ret_type, ret_type, ret_type);
7763 add_intrinsic (LLVMModuleRef module, int id)
7766 #if defined(TARGET_AMD64) || defined(TARGET_X86)
7767 LLVMTypeRef ret_type, arg_types [16];
7770 name = g_hash_table_lookup (intrins_id_to_name, GINT_TO_POINTER (id));
7774 case INTRINS_MEMSET: {
7775 LLVMTypeRef params [] = { LLVMPointerType (LLVMInt8Type (), 0), LLVMInt8Type (), LLVMInt32Type (), LLVMInt32Type (), LLVMInt1Type () };
7777 AddFunc (module, name, LLVMVoidType (), params, 5);
7780 case INTRINS_MEMCPY: {
7781 LLVMTypeRef params [] = { LLVMPointerType (LLVMInt8Type (), 0), LLVMPointerType (LLVMInt8Type (), 0), LLVMInt32Type (), LLVMInt32Type (), LLVMInt1Type () };
7783 AddFunc (module, name, LLVMVoidType (), params, 5);
7786 case INTRINS_SADD_OVF_I32:
7787 case INTRINS_UADD_OVF_I32:
7788 case INTRINS_SSUB_OVF_I32:
7789 case INTRINS_USUB_OVF_I32:
7790 case INTRINS_SMUL_OVF_I32:
7791 case INTRINS_UMUL_OVF_I32: {
7792 LLVMTypeRef ovf_res_i32 [] = { LLVMInt32Type (), LLVMInt1Type () };
7793 LLVMTypeRef params [] = { LLVMInt32Type (), LLVMInt32Type () };
7794 LLVMTypeRef ret_type = LLVMStructType (ovf_res_i32, 2, FALSE);
7796 AddFunc (module, name, ret_type, params, 2);
7799 case INTRINS_SADD_OVF_I64:
7800 case INTRINS_UADD_OVF_I64:
7801 case INTRINS_SSUB_OVF_I64:
7802 case INTRINS_USUB_OVF_I64:
7803 case INTRINS_SMUL_OVF_I64:
7804 case INTRINS_UMUL_OVF_I64: {
7805 LLVMTypeRef ovf_res_i64 [] = { LLVMInt64Type (), LLVMInt1Type () };
7806 LLVMTypeRef params [] = { LLVMInt64Type (), LLVMInt64Type () };
7807 LLVMTypeRef ret_type = LLVMStructType (ovf_res_i64, 2, FALSE);
7809 AddFunc (module, name, ret_type, params, 2);
7815 case INTRINS_FABS: {
7816 LLVMTypeRef params [] = { LLVMDoubleType () };
7818 AddFunc (module, name, LLVMDoubleType (), params, 1);
7821 case INTRINS_EXPECT_I8:
7822 AddFunc2 (module, name, LLVMInt8Type (), LLVMInt8Type (), LLVMInt8Type ());
7824 case INTRINS_EXPECT_I1:
7825 AddFunc2 (module, name, LLVMInt1Type (), LLVMInt1Type (), LLVMInt1Type ());
7827 #if defined(TARGET_AMD64) || defined(TARGET_X86)
7828 case INTRINS_SSE_PMOVMSKB:
7830 ret_type = LLVMInt32Type ();
7831 arg_types [0] = type_to_simd_type (MONO_TYPE_I1);
7832 AddFunc (module, name, ret_type, arg_types, 1);
7834 case INTRINS_SSE_PSRLI_W:
7835 case INTRINS_SSE_PSRAI_W:
7836 case INTRINS_SSE_PSLLI_W:
7838 ret_type = type_to_simd_type (MONO_TYPE_I2);
7839 arg_types [0] = ret_type;
7840 arg_types [1] = LLVMInt32Type ();
7841 AddFunc (module, name, ret_type, arg_types, 2);
7843 case INTRINS_SSE_PSRLI_D:
7844 case INTRINS_SSE_PSRAI_D:
7845 case INTRINS_SSE_PSLLI_D:
7846 ret_type = type_to_simd_type (MONO_TYPE_I4);
7847 arg_types [0] = ret_type;
7848 arg_types [1] = LLVMInt32Type ();
7849 AddFunc (module, name, ret_type, arg_types, 2);
7851 case INTRINS_SSE_PSRLI_Q:
7852 case INTRINS_SSE_PSLLI_Q:
7853 ret_type = type_to_simd_type (MONO_TYPE_I8);
7854 arg_types [0] = ret_type;
7855 arg_types [1] = LLVMInt32Type ();
7856 AddFunc (module, name, ret_type, arg_types, 2);
7858 case INTRINS_SSE_SQRT_PD:
7860 ret_type = type_to_simd_type (MONO_TYPE_R8);
7861 arg_types [0] = ret_type;
7862 AddFunc (module, name, ret_type, arg_types, 1);
7864 case INTRINS_SSE_SQRT_PS:
7865 ret_type = type_to_simd_type (MONO_TYPE_R4);
7866 arg_types [0] = ret_type;
7867 AddFunc (module, name, ret_type, arg_types, 1);
7869 case INTRINS_SSE_RSQRT_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_RCP_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_CVTTPD2DQ:
7880 ret_type = type_to_simd_type (MONO_TYPE_I4);
7881 arg_types [0] = type_to_simd_type (MONO_TYPE_R8);
7882 AddFunc (module, name, ret_type, arg_types, 1);
7884 case INTRINS_SSE_CVTTPS2DQ:
7885 ret_type = type_to_simd_type (MONO_TYPE_I4);
7886 arg_types [0] = type_to_simd_type (MONO_TYPE_R4);
7887 AddFunc (module, name, ret_type, arg_types, 1);
7889 case INTRINS_SSE_CVTDQ2PD:
7890 /* Conversion ops */
7891 ret_type = type_to_simd_type (MONO_TYPE_R8);
7892 arg_types [0] = type_to_simd_type (MONO_TYPE_I4);
7893 AddFunc (module, name, ret_type, arg_types, 1);
7895 case INTRINS_SSE_CVTDQ2PS:
7896 ret_type = type_to_simd_type (MONO_TYPE_R4);
7897 arg_types [0] = type_to_simd_type (MONO_TYPE_I4);
7898 AddFunc (module, name, ret_type, arg_types, 1);
7900 case INTRINS_SSE_CVTPD2DQ:
7901 ret_type = type_to_simd_type (MONO_TYPE_I4);
7902 arg_types [0] = type_to_simd_type (MONO_TYPE_R8);
7903 AddFunc (module, name, ret_type, arg_types, 1);
7905 case INTRINS_SSE_CVTPS2DQ:
7906 ret_type = type_to_simd_type (MONO_TYPE_I4);
7907 arg_types [0] = type_to_simd_type (MONO_TYPE_R4);
7908 AddFunc (module, name, ret_type, arg_types, 1);
7910 case INTRINS_SSE_CVTPD2PS:
7911 ret_type = type_to_simd_type (MONO_TYPE_R4);
7912 arg_types [0] = type_to_simd_type (MONO_TYPE_R8);
7913 AddFunc (module, name, ret_type, arg_types, 1);
7915 case INTRINS_SSE_CVTPS2PD:
7916 ret_type = type_to_simd_type (MONO_TYPE_R8);
7917 arg_types [0] = type_to_simd_type (MONO_TYPE_R4);
7918 AddFunc (module, name, ret_type, arg_types, 1);
7920 case INTRINS_SSE_CMPPD:
7922 ret_type = type_to_simd_type (MONO_TYPE_R8);
7923 arg_types [0] = ret_type;
7924 arg_types [1] = ret_type;
7925 arg_types [2] = LLVMInt8Type ();
7926 AddFunc (module, name, ret_type, arg_types, 3);
7928 case INTRINS_SSE_CMPPS:
7929 ret_type = type_to_simd_type (MONO_TYPE_R4);
7930 arg_types [0] = ret_type;
7931 arg_types [1] = ret_type;
7932 arg_types [2] = LLVMInt8Type ();
7933 AddFunc (module, name, ret_type, arg_types, 3);
7935 case INTRINS_SSE_PACKSSWB:
7936 case INTRINS_SSE_PACKUSWB:
7937 case INTRINS_SSE_PACKSSDW:
7939 ret_type = type_to_simd_type (MONO_TYPE_I1);
7940 arg_types [0] = type_to_simd_type (MONO_TYPE_I2);
7941 arg_types [1] = type_to_simd_type (MONO_TYPE_I2);
7942 AddFunc (module, name, ret_type, arg_types, 2);
7944 case INTRINS_SSE_PACKUSDW:
7945 ret_type = type_to_simd_type (MONO_TYPE_I2);
7946 arg_types [0] = type_to_simd_type (MONO_TYPE_I4);
7947 arg_types [1] = type_to_simd_type (MONO_TYPE_I4);
7948 AddFunc (module, name, ret_type, arg_types, 2);
7950 /* SSE Binary ops */
7951 case INTRINS_SSE_PMINUD:
7952 case INTRINS_SSE_PMAXUD:
7953 add_sse_binary (module, name, MONO_TYPE_I4);
7955 case INTRINS_SSE_PMINUW:
7956 case INTRINS_SSE_PMINSW:
7957 case INTRINS_SSE_PMAXUW:
7958 case INTRINS_SSE_PADDSW:
7959 case INTRINS_SSE_PSUBSW:
7960 case INTRINS_SSE_PADDUSW:
7961 case INTRINS_SSE_PSUBUSW:
7962 case INTRINS_SSE_PAVGW:
7963 case INTRINS_SSE_PMULHW:
7964 case INTRINS_SSE_PMULHU:
7965 add_sse_binary (module, name, MONO_TYPE_I2);
7967 case INTRINS_SSE_MINPS:
7968 case INTRINS_SSE_MAXPS:
7969 case INTRINS_SSE_HADDPS:
7970 case INTRINS_SSE_HSUBPS:
7971 case INTRINS_SSE_ADDSUBPS:
7972 add_sse_binary (module, name, MONO_TYPE_R4);
7974 case INTRINS_SSE_MINPD:
7975 case INTRINS_SSE_MAXPD:
7976 case INTRINS_SSE_HADDPD:
7977 case INTRINS_SSE_HSUBPD:
7978 case INTRINS_SSE_ADDSUBPD:
7979 add_sse_binary (module, name, MONO_TYPE_R8);
7981 case INTRINS_SSE_PMINUB:
7982 case INTRINS_SSE_PMAXUB:
7983 case INTRINS_SE_PADDSB:
7984 case INTRINS_SSE_PSUBSB:
7985 case INTRINS_SSE_PADDUSB:
7986 case INTRINS_SSE_PSUBUSB:
7987 case INTRINS_SSE_PAVGB:
7988 add_sse_binary (module, name, MONO_TYPE_I1);
7990 case INTRINS_SSE_PAUSE:
7991 AddFunc (module, "llvm.x86.sse2.pause", LLVMVoidType (), NULL, 0);
7995 g_assert_not_reached ();
8001 get_intrinsic (EmitContext *ctx, const char *name)
8003 #if LLVM_API_VERSION > 100
8007 * Every method is emitted into its own module so
8008 * we can add intrinsics on demand.
8010 res = LLVMGetNamedFunction (ctx->lmodule, name);
8014 /* No locking needed */
8015 id = GPOINTER_TO_INT (g_hash_table_lookup (intrins_name_to_id, name));
8018 printf ("%s\n", name);
8019 g_assert (id != -1);
8020 add_intrinsic (ctx->lmodule, id);
8021 res = LLVMGetNamedFunction (ctx->lmodule, name);
8029 res = LLVMGetNamedFunction (ctx->lmodule, name);
8036 add_intrinsics (LLVMModuleRef module)
8040 /* Emit declarations of instrinsics */
8042 * It would be nicer to emit only the intrinsics actually used, but LLVM's Module
8043 * type doesn't seem to do any locking.
8045 for (i = 0; i < INTRINS_NUM; ++i)
8046 add_intrinsic (module, i);
8050 AddFunc (module, "mono_personality", LLVMVoidType (), NULL, 0);
8052 AddFunc (module, "llvm_resume_unwind_trampoline", LLVMVoidType (), NULL, 0);
8055 /* SSE intrinsics */
8056 #if defined(TARGET_X86) || defined(TARGET_AMD64)
8060 /* Load/Store intrinsics */
8062 LLVMTypeRef arg_types [5];
8066 for (i = 1; i <= 8; i *= 2) {
8067 arg_types [0] = LLVMPointerType (LLVMIntType (i * 8), 0);
8068 arg_types [1] = LLVMInt32Type ();
8069 arg_types [2] = LLVMInt1Type ();
8070 arg_types [3] = LLVMInt32Type ();
8071 sprintf (name, "llvm.mono.load.i%d.p0i%d", i * 8, i * 8);
8072 AddFunc (module, name, LLVMIntType (i * 8), arg_types, 4);
8074 arg_types [0] = LLVMIntType (i * 8);
8075 arg_types [1] = LLVMPointerType (LLVMIntType (i * 8), 0);
8076 arg_types [2] = LLVMInt32Type ();
8077 arg_types [3] = LLVMInt1Type ();
8078 arg_types [4] = LLVMInt32Type ();
8079 sprintf (name, "llvm.mono.store.i%d.p0i%d", i * 8, i * 8);
8080 AddFunc (module, name, LLVMVoidType (), arg_types, 5);
8086 add_types (MonoLLVMModule *module)
8088 module->ptr_type = LLVMPointerType (sizeof (gpointer) == 8 ? LLVMInt64Type () : LLVMInt32Type (), 0);
8092 mono_llvm_init (void)
8097 mono_native_tls_alloc (¤t_cfg_tls_id, NULL);
8099 h = g_hash_table_new (NULL, NULL);
8100 for (i = 0; i < INTRINS_NUM; ++i)
8101 g_hash_table_insert (h, GINT_TO_POINTER (intrinsics [i].id), (gpointer)intrinsics [i].name);
8102 intrins_id_to_name = h;
8104 h = g_hash_table_new (g_str_hash, g_str_equal);
8105 for (i = 0; i < INTRINS_NUM; ++i)
8106 g_hash_table_insert (h, (gpointer)intrinsics [i].name, GINT_TO_POINTER (intrinsics [i].id + 1));
8107 intrins_name_to_id = h;
8111 init_jit_module (MonoDomain *domain)
8113 MonoJitDomainInfo *dinfo;
8114 MonoLLVMModule *module;
8117 dinfo = domain_jit_info (domain);
8118 if (dinfo->llvm_module)
8121 mono_loader_lock ();
8123 if (dinfo->llvm_module) {
8124 mono_loader_unlock ();
8128 module = g_new0 (MonoLLVMModule, 1);
8130 name = g_strdup_printf ("mono-%s", domain->friendly_name);
8131 module->lmodule = LLVMModuleCreateWithName (name);
8132 module->context = LLVMGetGlobalContext ();
8134 module->mono_ee = (MonoEERef*)mono_llvm_create_ee (LLVMCreateModuleProviderForExistingModule (module->lmodule), alloc_cb, emitted_cb, exception_cb, dlsym_cb, &module->ee);
8136 add_intrinsics (module->lmodule);
8139 module->llvm_types = g_hash_table_new (NULL, NULL);
8141 #if LLVM_API_VERSION < 100
8142 MonoJitICallInfo *info;
8144 info = mono_find_jit_icall_by_name ("llvm_resume_unwind_trampoline");
8146 LLVMAddGlobalMapping (module->ee, LLVMGetNamedFunction (module->lmodule, "llvm_resume_unwind_trampoline"), (void*)info->func);
8149 mono_memory_barrier ();
8151 dinfo->llvm_module = module;
8153 mono_loader_unlock ();
8157 mono_llvm_cleanup (void)
8159 MonoLLVMModule *module = &aot_module;
8161 if (module->lmodule)
8162 LLVMDisposeModule (module->lmodule);
8164 if (module->context)
8165 LLVMContextDispose (module->context);
8169 mono_llvm_free_domain_info (MonoDomain *domain)
8171 MonoJitDomainInfo *info = domain_jit_info (domain);
8172 MonoLLVMModule *module = (MonoLLVMModule*)info->llvm_module;
8178 if (module->llvm_types)
8179 g_hash_table_destroy (module->llvm_types);
8181 mono_llvm_dispose_ee (module->mono_ee);
8183 if (module->bb_names) {
8184 for (i = 0; i < module->bb_names_len; ++i)
8185 g_free (module->bb_names [i]);
8186 g_free (module->bb_names);
8188 //LLVMDisposeModule (module->module);
8192 info->llvm_module = NULL;
8196 mono_llvm_create_aot_module (MonoAssembly *assembly, const char *global_prefix, gboolean emit_dwarf, gboolean static_link, gboolean llvm_only)
8198 MonoLLVMModule *module = &aot_module;
8200 /* Delete previous module */
8201 if (module->plt_entries)
8202 g_hash_table_destroy (module->plt_entries);
8203 if (module->lmodule)
8204 LLVMDisposeModule (module->lmodule);
8206 memset (module, 0, sizeof (aot_module));
8208 module->lmodule = LLVMModuleCreateWithName ("aot");
8209 module->assembly = assembly;
8210 module->global_prefix = g_strdup (global_prefix);
8211 module->got_symbol = g_strdup_printf ("%s_llvm_got", global_prefix);
8212 module->eh_frame_symbol = g_strdup_printf ("%s_eh_frame", global_prefix);
8213 module->get_method_symbol = g_strdup_printf ("%s_get_method", global_prefix);
8214 module->get_unbox_tramp_symbol = g_strdup_printf ("%s_get_unbox_tramp", global_prefix);
8215 module->external_symbols = TRUE;
8216 module->emit_dwarf = emit_dwarf;
8217 module->static_link = static_link;
8218 module->llvm_only = llvm_only;
8219 /* The first few entries are reserved */
8220 module->max_got_offset = 16;
8221 module->context = LLVMContextCreate ();
8224 /* clang ignores our debug info because it has an invalid version */
8225 module->emit_dwarf = FALSE;
8227 #if LLVM_API_VERSION > 100
8228 module->emit_dwarf = FALSE;
8231 add_intrinsics (module->lmodule);
8234 #if LLVM_API_VERSION > 100
8235 if (module->emit_dwarf) {
8236 char *dir, *build_info, *s, *cu_name;
8238 module->di_builder = mono_llvm_create_di_builder (module->lmodule);
8241 dir = g_strdup (".");
8242 build_info = mono_get_runtime_build_info ();
8243 s = g_strdup_printf ("Mono AOT Compiler %s (LLVM)", build_info);
8244 cu_name = g_path_get_basename (assembly->image->name);
8245 module->cu = mono_llvm_di_create_compile_unit (module->di_builder, cu_name, dir, s);
8247 g_free (build_info);
8254 * We couldn't compute the type of the LLVM global representing the got because
8255 * its size is only known after all the methods have been emitted. So create
8256 * a dummy variable, and replace all uses it with the real got variable when
8257 * its size is known in mono_llvm_emit_aot_module ().
8260 LLVMTypeRef got_type = LLVMArrayType (module->ptr_type, 0);
8262 module->got_var = LLVMAddGlobal (module->lmodule, got_type, "mono_dummy_got");
8263 LLVMSetInitializer (module->got_var, LLVMConstNull (got_type));
8266 /* Add initialization array */
8268 LLVMTypeRef inited_type = LLVMArrayType (LLVMInt8Type (), 0);
8270 module->inited_var = LLVMAddGlobal (aot_module.lmodule, inited_type, "mono_inited_tmp");
8271 LLVMSetInitializer (module->inited_var, LLVMConstNull (inited_type));
8275 emit_init_icall_wrappers (module);
8277 emit_llvm_code_start (module);
8279 /* Add a dummy personality function */
8280 if (!use_debug_personality) {
8281 LLVMValueRef personality = LLVMAddFunction (module->lmodule, default_personality_name, LLVMFunctionType (LLVMInt32Type (), NULL, 0, TRUE));
8282 LLVMSetLinkage (personality, LLVMExternalLinkage);
8283 mark_as_used (module, personality);
8286 /* Add a reference to the c++ exception we throw/catch */
8288 LLVMTypeRef exc = LLVMPointerType (LLVMInt8Type (), 0);
8289 module->sentinel_exception = LLVMAddGlobal (module->lmodule, exc, "_ZTIPi");
8290 LLVMSetLinkage (module->sentinel_exception, LLVMExternalLinkage);
8291 mono_llvm_set_is_constant (module->sentinel_exception);
8294 module->llvm_types = g_hash_table_new (NULL, NULL);
8295 module->plt_entries = g_hash_table_new (g_str_hash, g_str_equal);
8296 module->plt_entries_ji = g_hash_table_new (NULL, NULL);
8297 module->direct_callables = g_hash_table_new (g_str_hash, g_str_equal);
8298 module->method_to_lmethod = g_hash_table_new (NULL, NULL);
8299 module->idx_to_lmethod = g_hash_table_new (NULL, NULL);
8300 module->idx_to_unbox_tramp = g_hash_table_new (NULL, NULL);
8301 module->method_to_callers = g_hash_table_new (NULL, NULL);
8305 llvm_array_from_uints (LLVMTypeRef el_type, guint32 *values, int nvalues)
8308 LLVMValueRef res, *vals;
8310 vals = g_new0 (LLVMValueRef, nvalues);
8311 for (i = 0; i < nvalues; ++i)
8312 vals [i] = LLVMConstInt (LLVMInt32Type (), values [i], FALSE);
8313 res = LLVMConstArray (LLVMInt32Type (), vals, nvalues);
8319 * mono_llvm_emit_aot_file_info:
8321 * Emit the MonoAotFileInfo structure.
8322 * Same as emit_aot_file_info () in aot-compiler.c.
8325 mono_llvm_emit_aot_file_info (MonoAotFileInfo *info, gboolean has_jitted_code)
8327 MonoLLVMModule *module = &aot_module;
8329 /* Save these for later */
8330 memcpy (&module->aot_info, info, sizeof (MonoAotFileInfo));
8331 module->has_jitted_code = has_jitted_code;
8335 * mono_llvm_emit_aot_data:
8337 * Emit the binary data DATA pointed to by symbol SYMBOL.
8340 mono_llvm_emit_aot_data (const char *symbol, guint8 *data, int data_len)
8342 MonoLLVMModule *module = &aot_module;
8346 type = LLVMArrayType (LLVMInt8Type (), data_len);
8347 d = LLVMAddGlobal (module->lmodule, type, symbol);
8348 LLVMSetVisibility (d, LLVMHiddenVisibility);
8349 LLVMSetLinkage (d, LLVMInternalLinkage);
8350 LLVMSetInitializer (d, mono_llvm_create_constant_data_array (data, data_len));
8351 mono_llvm_set_is_constant (d);
8354 /* Add a reference to a global defined in JITted code */
8356 AddJitGlobal (MonoLLVMModule *module, LLVMTypeRef type, const char *name)
8361 s = g_strdup_printf ("%s%s", module->global_prefix, name);
8362 v = LLVMAddGlobal (module->lmodule, LLVMInt8Type (), s);
8368 emit_aot_file_info (MonoLLVMModule *module)
8370 LLVMTypeRef file_info_type;
8371 LLVMTypeRef *eltypes, eltype;
8372 LLVMValueRef info_var;
8373 LLVMValueRef *fields;
8374 int i, nfields, tindex;
8375 MonoAotFileInfo *info;
8376 LLVMModuleRef lmodule = module->lmodule;
8378 info = &module->aot_info;
8380 /* Create an LLVM type to represent MonoAotFileInfo */
8381 nfields = 2 + MONO_AOT_FILE_INFO_NUM_SYMBOLS + 15 + 5;
8382 eltypes = g_new (LLVMTypeRef, nfields);
8384 eltypes [tindex ++] = LLVMInt32Type ();
8385 eltypes [tindex ++] = LLVMInt32Type ();
8387 for (i = 0; i < MONO_AOT_FILE_INFO_NUM_SYMBOLS; ++i)
8388 eltypes [tindex ++] = LLVMPointerType (LLVMInt8Type (), 0);
8390 for (i = 0; i < 15; ++i)
8391 eltypes [tindex ++] = LLVMInt32Type ();
8393 eltypes [tindex ++] = LLVMArrayType (LLVMInt32Type (), MONO_AOT_TABLE_NUM);
8394 for (i = 0; i < 4; ++i)
8395 eltypes [tindex ++] = LLVMArrayType (LLVMInt32Type (), MONO_AOT_TRAMP_NUM);
8396 g_assert (tindex == nfields);
8397 file_info_type = LLVMStructCreateNamed (module->context, "MonoAotFileInfo");
8398 LLVMStructSetBody (file_info_type, eltypes, nfields, FALSE);
8400 info_var = LLVMAddGlobal (lmodule, file_info_type, "mono_aot_file_info");
8401 if (module->static_link) {
8402 LLVMSetVisibility (info_var, LLVMHiddenVisibility);
8403 LLVMSetLinkage (info_var, LLVMInternalLinkage);
8405 fields = g_new (LLVMValueRef, nfields);
8407 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->version, FALSE);
8408 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->dummy, FALSE);
8412 * We use LLVMGetNamedGlobal () for symbol which are defined in LLVM code, and LLVMAddGlobal ()
8413 * for symbols defined in the .s file emitted by the aot compiler.
8415 eltype = eltypes [tindex];
8416 if (module->llvm_only)
8417 fields [tindex ++] = LLVMConstNull (eltype);
8419 fields [tindex ++] = AddJitGlobal (module, eltype, "jit_got");
8420 fields [tindex ++] = module->got_var;
8421 /* llc defines this directly */
8422 if (!module->llvm_only) {
8423 fields [tindex ++] = LLVMAddGlobal (lmodule, eltype, module->eh_frame_symbol);
8424 fields [tindex ++] = LLVMConstNull (eltype);
8425 fields [tindex ++] = LLVMConstNull (eltype);
8427 fields [tindex ++] = LLVMConstNull (eltype);
8428 fields [tindex ++] = module->get_method;
8429 fields [tindex ++] = module->get_unbox_tramp;
8431 if (module->has_jitted_code) {
8432 fields [tindex ++] = AddJitGlobal (module, eltype, "jit_code_start");
8433 fields [tindex ++] = AddJitGlobal (module, eltype, "jit_code_end");
8435 fields [tindex ++] = LLVMConstNull (eltype);
8436 fields [tindex ++] = LLVMConstNull (eltype);
8438 if (!module->llvm_only)
8439 fields [tindex ++] = AddJitGlobal (module, eltype, "method_addresses");
8441 fields [tindex ++] = LLVMConstNull (eltype);
8442 if (info->flags & MONO_AOT_FILE_FLAG_SEPARATE_DATA) {
8443 for (i = 0; i < MONO_AOT_TABLE_NUM; ++i)
8444 fields [tindex ++] = LLVMConstNull (eltype);
8446 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "blob");
8447 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "class_name_table");
8448 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "class_info_offsets");
8449 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "method_info_offsets");
8450 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "ex_info_offsets");
8451 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "extra_method_info_offsets");
8452 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "extra_method_table");
8453 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "got_info_offsets");
8454 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "llvm_got_info_offsets");
8455 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "image_table");
8457 /* Not needed (mem_end) */
8458 fields [tindex ++] = LLVMConstNull (eltype);
8459 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "assembly_guid");
8460 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "runtime_version");
8461 if (info->trampoline_size [0]) {
8462 fields [tindex ++] = AddJitGlobal (module, eltype, "specific_trampolines");
8463 fields [tindex ++] = AddJitGlobal (module, eltype, "static_rgctx_trampolines");
8464 fields [tindex ++] = AddJitGlobal (module, eltype, "imt_thunks");
8465 fields [tindex ++] = AddJitGlobal (module, eltype, "gsharedvt_arg_trampolines");
8467 fields [tindex ++] = LLVMConstNull (eltype);
8468 fields [tindex ++] = LLVMConstNull (eltype);
8469 fields [tindex ++] = LLVMConstNull (eltype);
8470 fields [tindex ++] = LLVMConstNull (eltype);
8472 if (module->static_link && !module->llvm_only)
8473 fields [tindex ++] = AddJitGlobal (module, eltype, "globals");
8475 fields [tindex ++] = LLVMConstNull (eltype);
8476 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "assembly_name");
8477 if (!module->llvm_only) {
8478 fields [tindex ++] = AddJitGlobal (module, eltype, "plt");
8479 fields [tindex ++] = AddJitGlobal (module, eltype, "plt_end");
8480 fields [tindex ++] = AddJitGlobal (module, eltype, "unwind_info");
8481 fields [tindex ++] = AddJitGlobal (module, eltype, "unbox_trampolines");
8482 fields [tindex ++] = AddJitGlobal (module, eltype, "unbox_trampolines_end");
8483 fields [tindex ++] = AddJitGlobal (module, eltype, "unbox_trampoline_addresses");
8485 fields [tindex ++] = LLVMConstNull (eltype);
8486 fields [tindex ++] = LLVMConstNull (eltype);
8487 fields [tindex ++] = LLVMConstNull (eltype);
8488 fields [tindex ++] = LLVMConstNull (eltype);
8489 fields [tindex ++] = LLVMConstNull (eltype);
8490 fields [tindex ++] = LLVMConstNull (eltype);
8493 for (i = 0; i < MONO_AOT_FILE_INFO_NUM_SYMBOLS; ++i)
8494 fields [2 + i] = LLVMConstBitCast (fields [2 + i], eltype);
8497 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->plt_got_offset_base, FALSE);
8498 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->got_size, FALSE);
8499 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->plt_size, FALSE);
8500 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->nmethods, FALSE);
8501 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->flags, FALSE);
8502 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->opts, FALSE);
8503 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->simd_opts, FALSE);
8504 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->gc_name_index, FALSE);
8505 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->num_rgctx_fetch_trampolines, FALSE);
8506 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->double_align, FALSE);
8507 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->long_align, FALSE);
8508 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->generic_tramp_num, FALSE);
8509 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->tramp_page_size, FALSE);
8510 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->nshared_got_entries, FALSE);
8511 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->datafile_size, FALSE);
8513 fields [tindex ++] = llvm_array_from_uints (LLVMInt32Type (), info->table_offsets, MONO_AOT_TABLE_NUM);
8514 fields [tindex ++] = llvm_array_from_uints (LLVMInt32Type (), info->num_trampolines, MONO_AOT_TRAMP_NUM);
8515 fields [tindex ++] = llvm_array_from_uints (LLVMInt32Type (), info->trampoline_got_offset_base, MONO_AOT_TRAMP_NUM);
8516 fields [tindex ++] = llvm_array_from_uints (LLVMInt32Type (), info->trampoline_size, MONO_AOT_TRAMP_NUM);
8517 fields [tindex ++] = llvm_array_from_uints (LLVMInt32Type (), info->tramp_page_code_offsets, MONO_AOT_TRAMP_NUM);
8518 g_assert (tindex == nfields);
8520 LLVMSetInitializer (info_var, LLVMConstNamedStruct (file_info_type, fields, nfields));
8522 if (module->static_link) {
8526 s = g_strdup_printf ("mono_aot_module_%s_info", module->assembly->aname.name);
8527 /* Get rid of characters which cannot occur in symbols */
8529 for (p = s; *p; ++p) {
8530 if (!(isalnum (*p) || *p == '_'))
8533 var = LLVMAddGlobal (module->lmodule, LLVMPointerType (LLVMInt8Type (), 0), s);
8535 LLVMSetInitializer (var, LLVMConstBitCast (LLVMGetNamedGlobal (module->lmodule, "mono_aot_file_info"), LLVMPointerType (LLVMInt8Type (), 0)));
8536 LLVMSetLinkage (var, LLVMExternalLinkage);
8541 * Emit the aot module into the LLVM bitcode file FILENAME.
8544 mono_llvm_emit_aot_module (const char *filename, const char *cu_name)
8546 LLVMTypeRef got_type, inited_type;
8547 LLVMValueRef real_got, real_inited;
8548 MonoLLVMModule *module = &aot_module;
8550 emit_llvm_code_end (module);
8553 * Create the real got variable and replace all uses of the dummy variable with
8556 got_type = LLVMArrayType (module->ptr_type, module->max_got_offset + 1);
8557 real_got = LLVMAddGlobal (module->lmodule, got_type, module->got_symbol);
8558 LLVMSetInitializer (real_got, LLVMConstNull (got_type));
8559 if (module->external_symbols) {
8560 LLVMSetLinkage (real_got, LLVMExternalLinkage);
8561 LLVMSetVisibility (real_got, LLVMHiddenVisibility);
8563 LLVMSetLinkage (real_got, LLVMInternalLinkage);
8565 mono_llvm_replace_uses_of (module->got_var, real_got);
8567 mark_as_used (&aot_module, real_got);
8569 /* Delete the dummy got so it doesn't become a global */
8570 LLVMDeleteGlobal (module->got_var);
8571 module->got_var = real_got;
8574 * Same for the init_var
8576 if (module->llvm_only) {
8577 inited_type = LLVMArrayType (LLVMInt8Type (), module->max_inited_idx + 1);
8578 real_inited = LLVMAddGlobal (module->lmodule, inited_type, "mono_inited");
8579 LLVMSetInitializer (real_inited, LLVMConstNull (inited_type));
8580 LLVMSetLinkage (real_inited, LLVMInternalLinkage);
8581 mono_llvm_replace_uses_of (module->inited_var, real_inited);
8582 LLVMDeleteGlobal (module->inited_var);
8585 if (module->llvm_only) {
8586 emit_get_method (&aot_module);
8587 emit_get_unbox_tramp (&aot_module);
8590 emit_llvm_used (&aot_module);
8591 emit_dbg_info (&aot_module, filename, cu_name);
8592 emit_aot_file_info (&aot_module);
8595 * Replace GOT entries for directly callable methods with the methods themselves.
8596 * It would be easier to implement this by predefining all methods before compiling
8597 * their bodies, but that couldn't handle the case when a method fails to compile
8600 if (module->llvm_only) {
8601 GHashTableIter iter;
8603 GSList *callers, *l;
8605 g_hash_table_iter_init (&iter, module->method_to_callers);
8606 while (g_hash_table_iter_next (&iter, (void**)&method, (void**)&callers)) {
8607 LLVMValueRef lmethod;
8609 lmethod = (LLVMValueRef)g_hash_table_lookup (module->method_to_lmethod, method);
8611 for (l = callers; l; l = l->next) {
8612 LLVMValueRef caller = (LLVMValueRef)l->data;
8614 mono_llvm_replace_uses_of (caller, lmethod);
8620 /* Replace PLT entries for directly callable methods with the methods themselves */
8622 GHashTableIter iter;
8624 LLVMValueRef callee;
8626 g_hash_table_iter_init (&iter, module->plt_entries_ji);
8627 while (g_hash_table_iter_next (&iter, (void**)&ji, (void**)&callee)) {
8628 if (mono_aot_is_direct_callable (ji)) {
8629 LLVMValueRef lmethod;
8631 lmethod = (LLVMValueRef)g_hash_table_lookup (module->method_to_lmethod, ji->data.method);
8632 /* The types might not match because the caller might pass an rgctx */
8633 if (lmethod && LLVMTypeOf (callee) == LLVMTypeOf (lmethod)) {
8634 mono_llvm_replace_uses_of (callee, lmethod);
8635 mono_aot_mark_unused_llvm_plt_entry (ji);
8645 if (LLVMVerifyModule (module->lmodule, LLVMReturnStatusAction, &verifier_err)) {
8646 g_assert_not_reached ();
8651 LLVMWriteBitcodeToFile (module->lmodule, filename);
8656 md_string (const char *s)
8658 return LLVMMDString (s, strlen (s));
8661 /* Debugging support */
8664 emit_dbg_info (MonoLLVMModule *module, const char *filename, const char *cu_name)
8666 LLVMModuleRef lmodule = module->lmodule;
8667 LLVMValueRef args [16], ver;
8670 * This can only be enabled when LLVM code is emitted into a separate object
8671 * file, since the AOT compiler also emits dwarf info,
8672 * and the abbrev indexes will not be correct since llvm has added its own
8675 if (!module->emit_dwarf)
8678 #if LLVM_API_VERSION > 100
8679 mono_llvm_di_builder_finalize (module->di_builder);
8681 LLVMValueRef cu_args [16], cu;
8683 char *build_info, *s, *dir;
8686 * Emit dwarf info in the form of LLVM metadata. There is some
8687 * out-of-date documentation at:
8688 * http://llvm.org/docs/SourceLevelDebugging.html
8689 * but most of this was gathered from the llvm and
8694 cu_args [n_cuargs ++] = LLVMConstInt (LLVMInt32Type (), DW_TAG_compile_unit, FALSE);
8695 /* CU name/compilation dir */
8696 dir = g_path_get_dirname (filename);
8697 args [0] = LLVMMDString (cu_name, strlen (cu_name));
8698 args [1] = LLVMMDString (dir, strlen (dir));
8699 cu_args [n_cuargs ++] = LLVMMDNode (args, 2);
8702 cu_args [n_cuargs ++] = LLVMConstInt (LLVMInt32Type (), DW_LANG_C99, FALSE);
8704 build_info = mono_get_runtime_build_info ();
8705 s = g_strdup_printf ("Mono AOT Compiler %s (LLVM)", build_info);
8706 cu_args [n_cuargs ++] = LLVMMDString (s, strlen (s));
8707 g_free (build_info);
8709 cu_args [n_cuargs ++] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
8711 cu_args [n_cuargs ++] = LLVMMDString ("", strlen (""));
8712 /* Runtime version */
8713 cu_args [n_cuargs ++] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
8715 cu_args [n_cuargs ++] = LLVMMDNode (args, 0);
8716 cu_args [n_cuargs ++] = LLVMMDNode (args, 0);
8718 if (module->subprogram_mds) {
8722 mds = g_new0 (LLVMValueRef, module->subprogram_mds->len);
8723 for (i = 0; i < module->subprogram_mds->len; ++i)
8724 mds [i] = (LLVMValueRef)g_ptr_array_index (module->subprogram_mds, i);
8725 cu_args [n_cuargs ++] = LLVMMDNode (mds, module->subprogram_mds->len);
8727 cu_args [n_cuargs ++] = LLVMMDNode (args, 0);
8730 cu_args [n_cuargs ++] = LLVMMDNode (args, 0);
8731 /* Imported modules */
8732 cu_args [n_cuargs ++] = LLVMMDNode (args, 0);
8734 cu_args [n_cuargs ++] = LLVMMDString ("", strlen (""));
8735 /* DebugEmissionKind = FullDebug */
8736 cu_args [n_cuargs ++] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
8737 cu = LLVMMDNode (cu_args, n_cuargs);
8738 LLVMAddNamedMetadataOperand (lmodule, "llvm.dbg.cu", cu);
8741 #if LLVM_API_VERSION > 100
8742 args [0] = LLVMConstInt (LLVMInt32Type (), 2, FALSE);
8743 args [1] = LLVMMDString ("Dwarf Version", strlen ("Dwarf Version"));
8744 args [2] = LLVMConstInt (LLVMInt32Type (), 2, FALSE);
8745 ver = LLVMMDNode (args, 3);
8746 LLVMAddNamedMetadataOperand (lmodule, "llvm.module.flags", ver);
8748 args [0] = LLVMConstInt (LLVMInt32Type (), 2, FALSE);
8749 args [1] = LLVMMDString ("Debug Info Version", strlen ("Debug Info Version"));
8750 args [2] = LLVMConstInt (LLVMInt64Type (), 3, FALSE);
8751 ver = LLVMMDNode (args, 3);
8752 LLVMAddNamedMetadataOperand (lmodule, "llvm.module.flags", ver);
8754 args [0] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
8755 args [1] = LLVMMDString ("Dwarf Version", strlen ("Dwarf Version"));
8756 args [2] = LLVMConstInt (LLVMInt32Type (), 2, FALSE);
8757 ver = LLVMMDNode (args, 3);
8758 LLVMAddNamedMetadataOperand (lmodule, "llvm.module.flags", ver);
8760 args [0] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
8761 args [1] = LLVMMDString ("Debug Info Version", strlen ("Debug Info Version"));
8762 args [2] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
8763 ver = LLVMMDNode (args, 3);
8764 LLVMAddNamedMetadataOperand (lmodule, "llvm.module.flags", ver);
8769 emit_dbg_subprogram (EmitContext *ctx, MonoCompile *cfg, LLVMValueRef method, const char *name)
8771 MonoLLVMModule *module = ctx->module;
8772 MonoDebugMethodInfo *minfo = ctx->minfo;
8773 char *source_file, *dir, *filename;
8774 LLVMValueRef md, args [16], ctx_args [16], md_args [64], type_args [16], ctx_md, type_md;
8775 MonoSymSeqPoint *sym_seq_points;
8781 mono_debug_symfile_get_seq_points (minfo, &source_file, NULL, NULL, &sym_seq_points, &n_seq_points);
8783 source_file = g_strdup ("<unknown>");
8784 dir = g_path_get_dirname (source_file);
8785 filename = g_path_get_basename (source_file);
8787 #if LLVM_API_VERSION > 100
8788 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);
8791 ctx_args [0] = LLVMConstInt (LLVMInt32Type (), 0x29, FALSE);
8792 args [0] = md_string (filename);
8793 args [1] = md_string (dir);
8794 ctx_args [1] = LLVMMDNode (args, 2);
8795 ctx_md = LLVMMDNode (ctx_args, 2);
8797 type_args [0] = LLVMConstInt (LLVMInt32Type (), DW_TAG_subroutine_type, FALSE);
8798 type_args [1] = NULL;
8799 type_args [2] = NULL;
8800 type_args [3] = LLVMMDString ("", 0);
8801 type_args [4] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
8802 type_args [5] = LLVMConstInt (LLVMInt64Type (), 0, FALSE);
8803 type_args [6] = LLVMConstInt (LLVMInt64Type (), 0, FALSE);
8804 type_args [7] = LLVMConstInt (LLVMInt64Type (), 0, FALSE);
8805 type_args [8] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
8806 type_args [9] = NULL;
8807 type_args [10] = NULL;
8808 type_args [11] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
8809 type_args [12] = NULL;
8810 type_args [13] = NULL;
8811 type_args [14] = NULL;
8812 type_md = LLVMMDNode (type_args, 14);
8814 /* http://llvm.org/docs/SourceLevelDebugging.html#subprogram-descriptors */
8815 md_args [0] = LLVMConstInt (LLVMInt32Type (), DW_TAG_subprogram, FALSE);
8816 /* Source directory + file pair */
8817 args [0] = md_string (filename);
8818 args [1] = md_string (dir);
8819 md_args [1] = LLVMMDNode (args ,2);
8820 md_args [2] = ctx_md;
8821 md_args [3] = md_string (cfg->method->name);
8822 md_args [4] = md_string (name);
8823 md_args [5] = md_string (name);
8826 md_args [6] = LLVMConstInt (LLVMInt32Type (), sym_seq_points [0].line, FALSE);
8828 md_args [6] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
8830 md_args [7] = type_md;
8832 md_args [8] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
8834 md_args [9] = LLVMConstInt (LLVMInt1Type (), 1, FALSE);
8836 md_args [10] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
8837 /* Index into a virtual function */
8838 md_args [11] = NULL;
8839 md_args [12] = NULL;
8841 md_args [13] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
8843 md_args [14] = LLVMConstInt (LLVMInt1Type (), 1, FALSE);
8844 /* Pointer to LLVM function */
8845 md_args [15] = method;
8846 /* Function template parameter */
8847 md_args [16] = NULL;
8848 /* Function declaration descriptor */
8849 md_args [17] = NULL;
8850 /* List of function variables */
8851 md_args [18] = LLVMMDNode (args, 0);
8853 md_args [19] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
8854 md = LLVMMDNode (md_args, 20);
8856 if (!module->subprogram_mds)
8857 module->subprogram_mds = g_ptr_array_new ();
8858 g_ptr_array_add (module->subprogram_mds, md);
8862 g_free (source_file);
8863 g_free (sym_seq_points);
8869 emit_dbg_loc (EmitContext *ctx, LLVMBuilderRef builder, const unsigned char *cil_code)
8871 MonoCompile *cfg = ctx->cfg;
8873 if (ctx->minfo && cil_code && cil_code >= cfg->header->code && cil_code < cfg->header->code + cfg->header->code_size) {
8874 MonoDebugSourceLocation *loc;
8875 LLVMValueRef loc_md;
8877 loc = mono_debug_symfile_lookup_location (ctx->minfo, cil_code - cfg->header->code);
8880 #if LLVM_API_VERSION > 100
8881 loc_md = mono_llvm_di_create_location (ctx->module->di_builder, ctx->dbg_md, loc->row, loc->column);
8882 mono_llvm_di_set_location (builder, loc_md);
8884 LLVMValueRef md_args [16];
8888 md_args [nmd_args ++] = LLVMConstInt (LLVMInt32Type (), loc->row, FALSE);
8889 md_args [nmd_args ++] = LLVMConstInt (LLVMInt32Type (), loc->column, FALSE);
8890 md_args [nmd_args ++] = ctx->dbg_md;
8891 md_args [nmd_args ++] = NULL;
8892 loc_md = LLVMMDNode (md_args, nmd_args);
8893 LLVMSetCurrentDebugLocation (builder, loc_md);
8895 mono_debug_symfile_free_location (loc);
8901 default_mono_llvm_unhandled_exception (void)
8903 MonoJitTlsData *jit_tls = mono_get_jit_tls ();
8904 MonoObject *target = mono_gchandle_get_target (jit_tls->thrown_exc);
8906 mono_unhandled_exception (target);
8907 exit (mono_environment_exitcode_get ());
8912 - Emit LLVM IR from the mono IR using the LLVM C API.
8913 - The original arch specific code remains, so we can fall back to it if we run
8914 into something we can't handle.
8918 A partial list of issues:
8919 - Handling of opcodes which can throw exceptions.
8921 In the mono JIT, these are implemented using code like this:
8928 push throw_pos - method
8929 call <exception trampoline>
8931 The problematic part is push throw_pos - method, which cannot be represented
8932 in the LLVM IR, since it does not support label values.
8933 -> this can be implemented in AOT mode using inline asm + labels, but cannot
8934 be implemented in JIT mode ?
8935 -> a possible but slower implementation would use the normal exception
8936 throwing code but it would need to control the placement of the throw code
8937 (it needs to be exactly after the compare+branch).
8938 -> perhaps add a PC offset intrinsics ?
8940 - efficient implementation of .ovf opcodes.
8942 These are currently implemented as:
8943 <ins which sets the condition codes>
8946 Some overflow opcodes are now supported by LLVM SVN.
8948 - exception handling, unwinding.
8949 - SSA is disabled for methods with exception handlers
8950 - How to obtain unwind info for LLVM compiled methods ?
8951 -> this is now solved by converting the unwind info generated by LLVM
8953 - LLVM uses the c++ exception handling framework, while we use our home grown
8954 code, and couldn't use the c++ one:
8955 - its not supported under VC++, other exotic platforms.
8956 - it might be impossible to support filter clauses with it.
8960 The trampolines need a predictable call sequence, since they need to disasm
8961 the calling code to obtain register numbers / offsets.
8963 LLVM currently generates this code in non-JIT mode:
8964 mov -0x98(%rax),%eax
8966 Here, the vtable pointer is lost.
8967 -> solution: use one vtable trampoline per class.
8969 - passing/receiving the IMT pointer/RGCTX.
8970 -> solution: pass them as normal arguments ?
8974 LLVM does not allow the specification of argument registers etc. This means
8975 that all calls are made according to the platform ABI.
8977 - passing/receiving vtypes.
8979 Vtypes passed/received in registers are handled by the front end by using
8980 a signature with scalar arguments, and loading the parts of the vtype into those
8983 Vtypes passed on the stack are handled using the 'byval' attribute.
8987 Supported though alloca, we need to emit the load/store code.
8991 The mono JIT uses pointer sized iregs/double fregs, while LLVM uses precisely
8992 typed registers, so we have to keep track of the precise LLVM type of each vreg.
8993 This is made easier because the IR is already in SSA form.
8994 An additional problem is that our IR is not consistent with types, i.e. i32/ia64
8995 types are frequently used incorrectly.
9000 Emit LLVM bytecode into a .bc file, compile it using llc into a .s file, then link
9001 it with the file containing the methods emitted by the JIT and the AOT data
9005 /* FIXME: Normalize some aspects of the mono IR to allow easier translation, like:
9006 * - each bblock should end with a branch
9007 * - setting the return value, making cfg->ret non-volatile
9008 * - avoid some transformations in the JIT which make it harder for us to generate
9010 * - use pointer types to help optimizations.