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 MonoExceptionClause *last = NULL;
1749 for (int i = 0; i < cfg->header->num_clauses; i++) {
1750 MonoExceptionClause *curr = &cfg->header->clauses [i];
1752 if (MONO_OFFSET_IN_CLAUSE (curr, bb->real_offset))
1755 if (MONO_OFFSET_IN_CLAUSE (curr, bb->real_offset)) {
1756 if (last && CLAUSE_END(last) > CLAUSE_END(curr))
1770 set_metadata_flag (LLVMValueRef v, const char *flag_name)
1772 LLVMValueRef md_arg;
1775 md_kind = LLVMGetMDKindID (flag_name, strlen (flag_name));
1776 md_arg = LLVMMDString ("mono", 4);
1777 LLVMSetMetadata (v, md_kind, LLVMMDNode (&md_arg, 1));
1781 set_invariant_load_flag (LLVMValueRef v)
1783 LLVMValueRef md_arg;
1785 const char *flag_name;
1787 // FIXME: Cache this
1788 flag_name = "invariant.load";
1789 md_kind = LLVMGetMDKindID (flag_name, strlen (flag_name));
1790 md_arg = LLVMMDString ("<index>", strlen ("<index>"));
1791 LLVMSetMetadata (v, md_kind, LLVMMDNode (&md_arg, 1));
1797 * Emit an LLVM call or invoke instruction depending on whenever the call is inside
1801 emit_call (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, LLVMValueRef callee, LLVMValueRef *args, int pindex)
1803 MonoCompile *cfg = ctx->cfg;
1804 LLVMValueRef lcall = NULL;
1805 LLVMBuilderRef builder = *builder_ref;
1806 MonoExceptionClause *clause;
1808 if (ctx->llvm_only) {
1809 clause = get_most_deep_clause (cfg, ctx, bb);
1812 g_assert (clause->flags == MONO_EXCEPTION_CLAUSE_NONE || clause->flags == MONO_EXCEPTION_CLAUSE_FINALLY);
1815 * Have to use an invoke instead of a call, branching to the
1816 * handler bblock of the clause containing this bblock.
1818 intptr_t key = CLAUSE_END(clause);
1820 LLVMBasicBlockRef lpad_bb = (LLVMBasicBlockRef)g_hash_table_lookup (ctx->exc_meta, (gconstpointer)key);
1822 // FIXME: Find the one that has the lowest end bound for the right start address
1823 // FIXME: Finally + nesting
1826 LLVMBasicBlockRef noex_bb = gen_bb (ctx, "CALL_NOEX_BB");
1829 lcall = LLVMBuildInvoke (builder, callee, args, pindex, noex_bb, lpad_bb, "");
1831 builder = ctx->builder = create_builder (ctx);
1832 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
1834 ctx->bblocks [bb->block_num].end_bblock = noex_bb;
1838 int clause_index = get_handler_clause (cfg, bb);
1840 if (clause_index != -1) {
1841 MonoMethodHeader *header = cfg->header;
1842 MonoExceptionClause *ec = &header->clauses [clause_index];
1843 MonoBasicBlock *tblock;
1844 LLVMBasicBlockRef ex_bb, noex_bb;
1847 * Have to use an invoke instead of a call, branching to the
1848 * handler bblock of the clause containing this bblock.
1851 g_assert (ec->flags == MONO_EXCEPTION_CLAUSE_NONE || ec->flags == MONO_EXCEPTION_CLAUSE_FINALLY);
1853 tblock = cfg->cil_offset_to_bb [ec->handler_offset];
1856 ctx->bblocks [tblock->block_num].invoke_target = TRUE;
1858 ex_bb = get_bb (ctx, tblock);
1860 noex_bb = gen_bb (ctx, "NOEX_BB");
1863 lcall = LLVMBuildInvoke (builder, callee, args, pindex, noex_bb, ex_bb, "");
1865 builder = ctx->builder = create_builder (ctx);
1866 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
1868 ctx->bblocks [bb->block_num].end_bblock = noex_bb;
1873 lcall = LLVMBuildCall (builder, callee, args, pindex, "");
1874 ctx->builder = builder;
1878 *builder_ref = ctx->builder;
1884 emit_load_general (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, int size, LLVMValueRef addr, const char *name, gboolean is_faulting, BarrierKind barrier)
1886 const char *intrins_name;
1887 LLVMValueRef args [16], res;
1888 LLVMTypeRef addr_type;
1889 gboolean use_intrinsics = TRUE;
1891 #if LLVM_API_VERSION > 100
1892 if (is_faulting && bb->region != -1 && !ctx->cfg->llvm_only) {
1893 /* The llvm.mono.load/store intrinsics are not supported by this llvm version, emit an explicit null check instead */
1894 LLVMValueRef cmp = LLVMBuildICmp (*builder_ref, LLVMIntEQ, addr, LLVMConstNull (LLVMTypeOf (addr)), "");
1895 emit_cond_system_exception (ctx, bb, "NullReferenceException", cmp);
1896 *builder_ref = ctx->builder;
1897 use_intrinsics = FALSE;
1901 if (is_faulting && bb->region != -1 && !ctx->cfg->llvm_only && use_intrinsics) {
1902 LLVMAtomicOrdering ordering;
1905 case LLVM_BARRIER_NONE:
1906 ordering = LLVMAtomicOrderingNotAtomic;
1908 case LLVM_BARRIER_ACQ:
1909 ordering = LLVMAtomicOrderingAcquire;
1911 case LLVM_BARRIER_SEQ:
1912 ordering = LLVMAtomicOrderingSequentiallyConsistent;
1915 g_assert_not_reached ();
1920 * We handle loads which can fault by calling a mono specific intrinsic
1921 * using an invoke, so they are handled properly inside try blocks.
1922 * We can't use this outside clauses, since LLVM optimizes intrinsics which
1923 * are marked with IntrReadArgMem.
1927 intrins_name = "llvm.mono.load.i8.p0i8";
1930 intrins_name = "llvm.mono.load.i16.p0i16";
1933 intrins_name = "llvm.mono.load.i32.p0i32";
1936 intrins_name = "llvm.mono.load.i64.p0i64";
1939 g_assert_not_reached ();
1942 addr_type = LLVMTypeOf (addr);
1943 if (addr_type == LLVMPointerType (LLVMDoubleType (), 0) || addr_type == LLVMPointerType (LLVMFloatType (), 0))
1944 addr = LLVMBuildBitCast (*builder_ref, addr, LLVMPointerType (LLVMIntType (size * 8), 0), "");
1947 args [1] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
1948 args [2] = LLVMConstInt (LLVMInt1Type (), TRUE, FALSE);
1949 args [3] = LLVMConstInt (LLVMInt32Type (), ordering, FALSE);
1950 res = emit_call (ctx, bb, builder_ref, get_intrinsic (ctx, intrins_name), args, 4);
1952 if (addr_type == LLVMPointerType (LLVMDoubleType (), 0))
1953 res = LLVMBuildBitCast (*builder_ref, res, LLVMDoubleType (), "");
1954 else if (addr_type == LLVMPointerType (LLVMFloatType (), 0))
1955 res = LLVMBuildBitCast (*builder_ref, res, LLVMFloatType (), "");
1962 * We emit volatile loads for loads which can fault, because otherwise
1963 * LLVM will generate invalid code when encountering a load from a
1966 res = mono_llvm_build_load (*builder_ref, addr, name, is_faulting, barrier);
1968 /* Mark it with a custom metadata */
1971 set_metadata_flag (res, "mono.faulting.load");
1979 emit_load (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, int size, LLVMValueRef addr, const char *name, gboolean is_faulting)
1981 return emit_load_general (ctx, bb, builder_ref, size, addr, name, is_faulting, LLVM_BARRIER_NONE);
1985 emit_store_general (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, int size, LLVMValueRef value, LLVMValueRef addr, gboolean is_faulting, BarrierKind barrier)
1987 const char *intrins_name;
1988 LLVMValueRef args [16];
1989 gboolean use_intrinsics = TRUE;
1991 #if LLVM_API_VERSION > 100
1992 if (is_faulting && bb->region != -1 && !ctx->cfg->llvm_only) {
1993 /* The llvm.mono.load/store intrinsics are not supported by this llvm version, emit an explicit null check instead */
1994 LLVMValueRef cmp = LLVMBuildICmp (*builder_ref, LLVMIntEQ, addr, LLVMConstNull (LLVMTypeOf (addr)), "");
1995 emit_cond_system_exception (ctx, bb, "NullReferenceException", cmp);
1996 *builder_ref = ctx->builder;
1997 use_intrinsics = FALSE;
2001 if (is_faulting && bb->region != -1 && !ctx->cfg->llvm_only && use_intrinsics) {
2002 LLVMAtomicOrdering ordering;
2005 case LLVM_BARRIER_NONE:
2006 ordering = LLVMAtomicOrderingNotAtomic;
2008 case LLVM_BARRIER_REL:
2009 ordering = LLVMAtomicOrderingRelease;
2011 case LLVM_BARRIER_SEQ:
2012 ordering = LLVMAtomicOrderingSequentiallyConsistent;
2015 g_assert_not_reached ();
2021 intrins_name = "llvm.mono.store.i8.p0i8";
2024 intrins_name = "llvm.mono.store.i16.p0i16";
2027 intrins_name = "llvm.mono.store.i32.p0i32";
2030 intrins_name = "llvm.mono.store.i64.p0i64";
2033 g_assert_not_reached ();
2036 if (LLVMTypeOf (value) == LLVMDoubleType () || LLVMTypeOf (value) == LLVMFloatType ()) {
2037 value = LLVMBuildBitCast (*builder_ref, value, LLVMIntType (size * 8), "");
2038 addr = LLVMBuildBitCast (*builder_ref, addr, LLVMPointerType (LLVMIntType (size * 8), 0), "");
2043 args [2] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
2044 args [3] = LLVMConstInt (LLVMInt1Type (), TRUE, FALSE);
2045 args [4] = LLVMConstInt (LLVMInt32Type (), ordering, FALSE);
2046 emit_call (ctx, bb, builder_ref, get_intrinsic (ctx, intrins_name), args, 5);
2048 mono_llvm_build_store (*builder_ref, value, addr, is_faulting, barrier);
2053 emit_store (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, int size, LLVMValueRef value, LLVMValueRef addr, gboolean is_faulting)
2055 emit_store_general (ctx, bb, builder_ref, size, value, addr, is_faulting, LLVM_BARRIER_NONE);
2059 * emit_cond_system_exception:
2061 * Emit code to throw the exception EXC_TYPE if the condition CMP is false.
2062 * Might set the ctx exception.
2065 emit_cond_system_exception (EmitContext *ctx, MonoBasicBlock *bb, const char *exc_type, LLVMValueRef cmp)
2067 LLVMBasicBlockRef ex_bb, ex2_bb = NULL, noex_bb;
2068 LLVMBuilderRef builder;
2069 MonoClass *exc_class;
2070 LLVMValueRef args [2];
2071 LLVMValueRef callee;
2073 ex_bb = gen_bb (ctx, "EX_BB");
2075 ex2_bb = gen_bb (ctx, "EX2_BB");
2076 noex_bb = gen_bb (ctx, "NOEX_BB");
2078 LLVMBuildCondBr (ctx->builder, cmp, ex_bb, noex_bb);
2080 exc_class = mono_class_load_from_name (mono_get_corlib (), "System", exc_type);
2082 /* Emit exception throwing code */
2083 ctx->builder = builder = create_builder (ctx);
2084 LLVMPositionBuilderAtEnd (builder, ex_bb);
2086 if (ctx->cfg->llvm_only) {
2087 static LLVMTypeRef sig;
2090 sig = LLVMFunctionType1 (LLVMVoidType (), LLVMInt32Type (), FALSE);
2091 callee = get_callee (ctx, sig, MONO_PATCH_INFO_JIT_ICALL_ADDR, "mono_llvm_throw_corlib_exception");
2093 LLVMBuildBr (builder, ex2_bb);
2095 ctx->builder = builder = create_builder (ctx);
2096 LLVMPositionBuilderAtEnd (ctx->builder, ex2_bb);
2098 args [0] = LLVMConstInt (LLVMInt32Type (), exc_class->type_token - MONO_TOKEN_TYPE_DEF, FALSE);
2099 emit_call (ctx, bb, &builder, callee, args, 1);
2100 LLVMBuildUnreachable (builder);
2102 ctx->builder = builder = create_builder (ctx);
2103 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
2105 ctx->bblocks [bb->block_num].end_bblock = noex_bb;
2111 callee = ctx->module->throw_corlib_exception;
2114 const char *icall_name;
2116 sig = LLVMFunctionType2 (LLVMVoidType (), LLVMInt32Type (), LLVMPointerType (LLVMInt8Type (), 0), FALSE);
2117 icall_name = "llvm_throw_corlib_exception_abs_trampoline";
2119 if (ctx->cfg->compile_aot) {
2120 callee = get_callee (ctx, sig, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
2123 * Differences between the LLVM/non-LLVM throw corlib exception trampoline:
2124 * - On x86, LLVM generated code doesn't push the arguments
2125 * - The trampoline takes the throw address as an arguments, not a pc offset.
2127 gpointer target = resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
2128 callee = emit_jit_callee (ctx, "llvm_throw_corlib_exception_trampoline", sig, target);
2130 #if LLVM_API_VERSION > 100
2132 * Make sure that ex_bb starts with the invoke, so the block address points to it, and not to the load
2133 * added by emit_jit_callee ().
2135 ex2_bb = gen_bb (ctx, "EX2_BB");
2136 LLVMBuildBr (builder, ex2_bb);
2139 ctx->builder = builder = create_builder (ctx);
2140 LLVMPositionBuilderAtEnd (ctx->builder, ex2_bb);
2142 mono_memory_barrier ();
2143 ctx->module->throw_corlib_exception = callee;
2148 if (IS_TARGET_X86 || IS_TARGET_AMD64)
2149 args [0] = LLVMConstInt (LLVMInt32Type (), exc_class->type_token - MONO_TOKEN_TYPE_DEF, FALSE);
2151 args [0] = LLVMConstInt (LLVMInt32Type (), exc_class->type_token, FALSE);
2154 * The LLVM mono branch contains changes so a block address can be passed as an
2155 * argument to a call.
2157 args [1] = LLVMBlockAddress (ctx->lmethod, ex_bb);
2158 emit_call (ctx, bb, &builder, callee, args, 2);
2160 LLVMBuildUnreachable (builder);
2162 ctx->builder = builder = create_builder (ctx);
2163 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
2165 ctx->bblocks [bb->block_num].end_bblock = noex_bb;
2172 * emit_args_to_vtype:
2174 * Emit code to store the vtype in the arguments args to the address ADDRESS.
2177 emit_args_to_vtype (EmitContext *ctx, LLVMBuilderRef builder, MonoType *t, LLVMValueRef address, LLVMArgInfo *ainfo, LLVMValueRef *args)
2179 int j, size, nslots;
2181 size = mono_class_value_size (mono_class_from_mono_type (t), NULL);
2183 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (t))) {
2184 address = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (LLVMInt8Type (), 0), "");
2187 if (ainfo->storage == LLVMArgAsFpArgs)
2188 nslots = ainfo->nslots;
2192 for (j = 0; j < nslots; ++j) {
2193 LLVMValueRef index [2], addr, daddr;
2194 int part_size = size > sizeof (gpointer) ? sizeof (gpointer) : size;
2195 LLVMTypeRef part_type;
2197 while (part_size != 1 && part_size != 2 && part_size != 4 && part_size < 8)
2200 if (ainfo->pair_storage [j] == LLVMArgNone)
2203 switch (ainfo->pair_storage [j]) {
2204 case LLVMArgInIReg: {
2205 part_type = LLVMIntType (part_size * 8);
2206 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (t))) {
2207 index [0] = LLVMConstInt (LLVMInt32Type (), j * sizeof (gpointer), FALSE);
2208 addr = LLVMBuildGEP (builder, address, index, 1, "");
2210 daddr = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (IntPtrType (), 0), "");
2211 index [0] = LLVMConstInt (LLVMInt32Type (), j, FALSE);
2212 addr = LLVMBuildGEP (builder, daddr, index, 1, "");
2214 LLVMBuildStore (builder, convert (ctx, args [j], part_type), LLVMBuildBitCast (ctx->builder, addr, LLVMPointerType (part_type, 0), ""));
2217 case LLVMArgInFPReg: {
2218 LLVMTypeRef arg_type;
2220 if (ainfo->esize == 8)
2221 arg_type = LLVMDoubleType ();
2223 arg_type = LLVMFloatType ();
2225 index [0] = LLVMConstInt (LLVMInt32Type (), j, FALSE);
2226 daddr = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (arg_type, 0), "");
2227 addr = LLVMBuildGEP (builder, daddr, index, 1, "");
2228 LLVMBuildStore (builder, args [j], addr);
2234 g_assert_not_reached ();
2237 size -= sizeof (gpointer);
2242 * emit_vtype_to_args:
2244 * Emit code to load a vtype at address ADDRESS into scalar arguments. Store the arguments
2245 * into ARGS, and the number of arguments into NARGS.
2248 emit_vtype_to_args (EmitContext *ctx, LLVMBuilderRef builder, MonoType *t, LLVMValueRef address, LLVMArgInfo *ainfo, LLVMValueRef *args, guint32 *nargs)
2251 int j, size, nslots;
2252 LLVMTypeRef arg_type;
2254 size = get_vtype_size (t);
2256 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (t)))
2257 address = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (LLVMInt8Type (), 0), "");
2259 if (ainfo->storage == LLVMArgAsFpArgs)
2260 nslots = ainfo->nslots;
2263 for (j = 0; j < nslots; ++j) {
2264 LLVMValueRef index [2], addr, daddr;
2265 int partsize = size > sizeof (gpointer) ? sizeof (gpointer) : size;
2267 if (ainfo->pair_storage [j] == LLVMArgNone)
2270 switch (ainfo->pair_storage [j]) {
2272 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (t))) {
2273 index [0] = LLVMConstInt (LLVMInt32Type (), j * sizeof (gpointer), FALSE);
2274 addr = LLVMBuildGEP (builder, address, index, 1, "");
2276 daddr = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (IntPtrType (), 0), "");
2277 index [0] = LLVMConstInt (LLVMInt32Type (), j, FALSE);
2278 addr = LLVMBuildGEP (builder, daddr, index, 1, "");
2280 args [pindex ++] = convert (ctx, LLVMBuildLoad (builder, LLVMBuildBitCast (ctx->builder, addr, LLVMPointerType (LLVMIntType (partsize * 8), 0), ""), ""), IntPtrType ());
2282 case LLVMArgInFPReg:
2283 if (ainfo->esize == 8)
2284 arg_type = LLVMDoubleType ();
2286 arg_type = LLVMFloatType ();
2287 daddr = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (arg_type, 0), "");
2288 index [0] = LLVMConstInt (LLVMInt32Type (), j, FALSE);
2289 addr = LLVMBuildGEP (builder, daddr, index, 1, "");
2290 args [pindex ++] = LLVMBuildLoad (builder, addr, "");
2295 g_assert_not_reached ();
2297 size -= sizeof (gpointer);
2304 build_alloca_llvm_type_name (EmitContext *ctx, LLVMTypeRef t, int align, const char *name)
2307 * Have to place all alloca's at the end of the entry bb, since otherwise they would
2308 * get executed every time control reaches them.
2310 LLVMPositionBuilder (ctx->alloca_builder, get_bb (ctx, ctx->cfg->bb_entry), ctx->last_alloca);
2312 ctx->last_alloca = mono_llvm_build_alloca (ctx->alloca_builder, t, NULL, align, name);
2313 return ctx->last_alloca;
2317 build_alloca_llvm_type (EmitContext *ctx, LLVMTypeRef t, int align)
2319 return build_alloca_llvm_type_name (ctx, t, align, "");
2323 build_alloca (EmitContext *ctx, MonoType *t)
2325 MonoClass *k = mono_class_from_mono_type (t);
2328 g_assert (!mini_is_gsharedvt_variable_type (t));
2330 if (MONO_CLASS_IS_SIMD (ctx->cfg, k))
2333 align = mono_class_min_align (k);
2335 /* Sometimes align is not a power of 2 */
2336 while (mono_is_power_of_two (align) == -1)
2339 return build_alloca_llvm_type (ctx, type_to_llvm_type (ctx, t), align);
2343 emit_gsharedvt_ldaddr (EmitContext *ctx, int vreg)
2347 * Compute the address of the local as gsharedvt_locals_var + gsharedvt_info_var->locals_offsets [idx].
2349 MonoCompile *cfg = ctx->cfg;
2350 LLVMBuilderRef builder = ctx->builder;
2351 LLVMValueRef offset, offset_var;
2352 LLVMValueRef info_var = ctx->values [cfg->gsharedvt_info_var->dreg];
2353 LLVMValueRef locals_var = ctx->values [cfg->gsharedvt_locals_var->dreg];
2357 g_assert (info_var);
2358 g_assert (locals_var);
2360 int idx = cfg->gsharedvt_vreg_to_idx [vreg] - 1;
2362 offset = LLVMConstInt (LLVMInt32Type (), MONO_STRUCT_OFFSET (MonoGSharedVtMethodRuntimeInfo, entries) + (idx * sizeof (gpointer)), FALSE);
2363 ptr = LLVMBuildAdd (builder, convert (ctx, info_var, IntPtrType ()), convert (ctx, offset, IntPtrType ()), "");
2365 name = g_strdup_printf ("gsharedvt_local_%d_offset", vreg);
2366 offset_var = LLVMBuildLoad (builder, convert (ctx, ptr, LLVMPointerType (LLVMInt32Type (), 0)), name);
2368 return LLVMBuildAdd (builder, convert (ctx, locals_var, IntPtrType ()), convert (ctx, offset_var, IntPtrType ()), "");
2372 * Put the global into the 'llvm.used' array to prevent it from being optimized away.
2375 mark_as_used (MonoLLVMModule *module, LLVMValueRef global)
2378 module->used = g_ptr_array_sized_new (16);
2379 g_ptr_array_add (module->used, global);
2383 emit_llvm_used (MonoLLVMModule *module)
2385 LLVMModuleRef lmodule = module->lmodule;
2386 LLVMTypeRef used_type;
2387 LLVMValueRef used, *used_elem;
2393 used_type = LLVMArrayType (LLVMPointerType (LLVMInt8Type (), 0), module->used->len);
2394 used = LLVMAddGlobal (lmodule, used_type, "llvm.used");
2395 used_elem = g_new0 (LLVMValueRef, module->used->len);
2396 for (i = 0; i < module->used->len; ++i)
2397 used_elem [i] = LLVMConstBitCast ((LLVMValueRef)g_ptr_array_index (module->used, i), LLVMPointerType (LLVMInt8Type (), 0));
2398 LLVMSetInitializer (used, LLVMConstArray (LLVMPointerType (LLVMInt8Type (), 0), used_elem, module->used->len));
2399 LLVMSetLinkage (used, LLVMAppendingLinkage);
2400 LLVMSetSection (used, "llvm.metadata");
2406 * Emit a function mapping method indexes to their code
2409 emit_get_method (MonoLLVMModule *module)
2411 LLVMModuleRef lmodule = module->lmodule;
2412 LLVMValueRef func, switch_ins, m;
2413 LLVMBasicBlockRef entry_bb, fail_bb, bb, code_start_bb, code_end_bb;
2414 LLVMBasicBlockRef *bbs;
2416 LLVMBuilderRef builder;
2421 * Emit a switch statement. Emitting a table of function addresses is smaller/faster,
2422 * but generating code seems safer.
2424 rtype = LLVMPointerType (LLVMInt8Type (), 0);
2425 func = LLVMAddFunction (lmodule, module->get_method_symbol, LLVMFunctionType1 (rtype, LLVMInt32Type (), FALSE));
2426 LLVMSetLinkage (func, LLVMExternalLinkage);
2427 LLVMSetVisibility (func, LLVMHiddenVisibility);
2428 LLVMAddFunctionAttr (func, LLVMNoUnwindAttribute);
2429 module->get_method = func;
2431 entry_bb = LLVMAppendBasicBlock (func, "ENTRY");
2434 * Return llvm_code_start/llvm_code_end when called with -1/-2.
2435 * Hopefully, the toolchain doesn't reorder these functions. If it does,
2436 * then we will have to find another solution.
2439 name = g_strdup_printf ("BB_CODE_START");
2440 code_start_bb = LLVMAppendBasicBlock (func, name);
2442 builder = LLVMCreateBuilder ();
2443 LLVMPositionBuilderAtEnd (builder, code_start_bb);
2444 LLVMBuildRet (builder, LLVMBuildBitCast (builder, module->code_start, rtype, ""));
2446 name = g_strdup_printf ("BB_CODE_END");
2447 code_end_bb = LLVMAppendBasicBlock (func, name);
2449 builder = LLVMCreateBuilder ();
2450 LLVMPositionBuilderAtEnd (builder, code_end_bb);
2451 LLVMBuildRet (builder, LLVMBuildBitCast (builder, module->code_end, rtype, ""));
2453 bbs = g_new0 (LLVMBasicBlockRef, module->max_method_idx + 1);
2454 for (i = 0; i < module->max_method_idx + 1; ++i) {
2455 name = g_strdup_printf ("BB_%d", i);
2456 bb = LLVMAppendBasicBlock (func, name);
2460 builder = LLVMCreateBuilder ();
2461 LLVMPositionBuilderAtEnd (builder, bb);
2463 m = (LLVMValueRef)g_hash_table_lookup (module->idx_to_lmethod, GINT_TO_POINTER (i));
2465 LLVMBuildRet (builder, LLVMBuildBitCast (builder, m, rtype, ""));
2467 LLVMBuildRet (builder, LLVMConstNull (rtype));
2470 fail_bb = LLVMAppendBasicBlock (func, "FAIL");
2471 builder = LLVMCreateBuilder ();
2472 LLVMPositionBuilderAtEnd (builder, fail_bb);
2473 LLVMBuildRet (builder, LLVMConstNull (rtype));
2475 builder = LLVMCreateBuilder ();
2476 LLVMPositionBuilderAtEnd (builder, entry_bb);
2478 switch_ins = LLVMBuildSwitch (builder, LLVMGetParam (func, 0), fail_bb, 0);
2479 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), -1, FALSE), code_start_bb);
2480 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), -2, FALSE), code_end_bb);
2481 for (i = 0; i < module->max_method_idx + 1; ++i) {
2482 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), i, FALSE), bbs [i]);
2485 mark_as_used (module, func);
2489 * emit_get_unbox_tramp:
2491 * Emit a function mapping method indexes to their unbox trampoline
2494 emit_get_unbox_tramp (MonoLLVMModule *module)
2496 LLVMModuleRef lmodule = module->lmodule;
2497 LLVMValueRef func, switch_ins, m;
2498 LLVMBasicBlockRef entry_bb, fail_bb, bb;
2499 LLVMBasicBlockRef *bbs;
2501 LLVMBuilderRef builder;
2505 /* Similar to emit_get_method () */
2507 rtype = LLVMPointerType (LLVMInt8Type (), 0);
2508 func = LLVMAddFunction (lmodule, module->get_unbox_tramp_symbol, LLVMFunctionType1 (rtype, LLVMInt32Type (), FALSE));
2509 LLVMSetLinkage (func, LLVMExternalLinkage);
2510 LLVMSetVisibility (func, LLVMHiddenVisibility);
2511 LLVMAddFunctionAttr (func, LLVMNoUnwindAttribute);
2512 module->get_unbox_tramp = func;
2514 entry_bb = LLVMAppendBasicBlock (func, "ENTRY");
2516 bbs = g_new0 (LLVMBasicBlockRef, module->max_method_idx + 1);
2517 for (i = 0; i < module->max_method_idx + 1; ++i) {
2518 m = (LLVMValueRef)g_hash_table_lookup (module->idx_to_unbox_tramp, GINT_TO_POINTER (i));
2522 name = g_strdup_printf ("BB_%d", i);
2523 bb = LLVMAppendBasicBlock (func, name);
2527 builder = LLVMCreateBuilder ();
2528 LLVMPositionBuilderAtEnd (builder, bb);
2530 LLVMBuildRet (builder, LLVMBuildBitCast (builder, m, rtype, ""));
2533 fail_bb = LLVMAppendBasicBlock (func, "FAIL");
2534 builder = LLVMCreateBuilder ();
2535 LLVMPositionBuilderAtEnd (builder, fail_bb);
2536 LLVMBuildRet (builder, LLVMConstNull (rtype));
2538 builder = LLVMCreateBuilder ();
2539 LLVMPositionBuilderAtEnd (builder, entry_bb);
2541 switch_ins = LLVMBuildSwitch (builder, LLVMGetParam (func, 0), fail_bb, 0);
2542 for (i = 0; i < module->max_method_idx + 1; ++i) {
2543 m = (LLVMValueRef)g_hash_table_lookup (module->idx_to_unbox_tramp, GINT_TO_POINTER (i));
2547 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), i, FALSE), bbs [i]);
2550 mark_as_used (module, func);
2553 /* Add a function to mark the beginning of LLVM code */
2555 emit_llvm_code_start (MonoLLVMModule *module)
2557 LLVMModuleRef lmodule = module->lmodule;
2559 LLVMBasicBlockRef entry_bb;
2560 LLVMBuilderRef builder;
2562 func = LLVMAddFunction (lmodule, "llvm_code_start", LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE));
2563 LLVMSetLinkage (func, LLVMInternalLinkage);
2564 LLVMAddFunctionAttr (func, LLVMNoUnwindAttribute);
2565 module->code_start = func;
2566 entry_bb = LLVMAppendBasicBlock (func, "ENTRY");
2567 builder = LLVMCreateBuilder ();
2568 LLVMPositionBuilderAtEnd (builder, entry_bb);
2569 LLVMBuildRetVoid (builder);
2573 emit_init_icall_wrapper (MonoLLVMModule *module, const char *name, const char *icall_name, int subtype)
2575 LLVMModuleRef lmodule = module->lmodule;
2576 LLVMValueRef func, indexes [2], got_entry_addr, args [16], callee;
2577 LLVMBasicBlockRef entry_bb;
2578 LLVMBuilderRef builder;
2585 func = LLVMAddFunction (lmodule, name, LLVMFunctionType1 (LLVMVoidType (), LLVMInt32Type (), FALSE));
2586 sig = LLVMFunctionType2 (LLVMVoidType (), IntPtrType (), LLVMInt32Type (), FALSE);
2591 func = LLVMAddFunction (lmodule, name, LLVMFunctionType2 (LLVMVoidType (), LLVMInt32Type (), IntPtrType (), FALSE));
2592 sig = LLVMFunctionType3 (LLVMVoidType (), IntPtrType (), LLVMInt32Type (), IntPtrType (), FALSE);
2595 func = LLVMAddFunction (lmodule, name, LLVMFunctionType2 (LLVMVoidType (), LLVMInt32Type (), ObjRefType (), FALSE));
2596 sig = LLVMFunctionType3 (LLVMVoidType (), IntPtrType (), LLVMInt32Type (), ObjRefType (), FALSE);
2599 g_assert_not_reached ();
2601 LLVMSetLinkage (func, LLVMInternalLinkage);
2602 LLVMAddFunctionAttr (func, LLVMNoInlineAttribute);
2603 mono_llvm_set_preserveall_cc (func);
2604 entry_bb = LLVMAppendBasicBlock (func, "ENTRY");
2605 builder = LLVMCreateBuilder ();
2606 LLVMPositionBuilderAtEnd (builder, entry_bb);
2609 ji = g_new0 (MonoJumpInfo, 1);
2610 ji->type = MONO_PATCH_INFO_AOT_MODULE;
2611 ji = mono_aot_patch_info_dup (ji);
2612 got_offset = mono_aot_get_got_offset (ji);
2613 module->max_got_offset = MAX (module->max_got_offset, got_offset);
2614 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
2615 indexes [1] = LLVMConstInt (LLVMInt32Type (), got_offset, FALSE);
2616 got_entry_addr = LLVMBuildGEP (builder, module->got_var, indexes, 2, "");
2617 args [0] = LLVMBuildPtrToInt (builder, LLVMBuildLoad (builder, got_entry_addr, ""), IntPtrType (), "");
2618 args [1] = LLVMGetParam (func, 0);
2620 args [2] = LLVMGetParam (func, 1);
2622 ji = g_new0 (MonoJumpInfo, 1);
2623 ji->type = MONO_PATCH_INFO_INTERNAL_METHOD;
2624 ji->data.name = icall_name;
2625 ji = mono_aot_patch_info_dup (ji);
2626 got_offset = mono_aot_get_got_offset (ji);
2627 module->max_got_offset = MAX (module->max_got_offset, got_offset);
2628 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
2629 indexes [1] = LLVMConstInt (LLVMInt32Type (), got_offset, FALSE);
2630 got_entry_addr = LLVMBuildGEP (builder, module->got_var, indexes, 2, "");
2631 callee = LLVMBuildLoad (builder, got_entry_addr, "");
2632 callee = LLVMBuildBitCast (builder, callee, LLVMPointerType (sig, 0), "");
2633 LLVMBuildCall (builder, callee, args, LLVMCountParamTypes (sig), "");
2635 // Set the inited flag
2636 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
2637 indexes [1] = LLVMGetParam (func, 0);
2638 LLVMBuildStore (builder, LLVMConstInt (LLVMInt8Type (), 1, FALSE), LLVMBuildGEP (builder, module->inited_var, indexes, 2, ""));
2640 LLVMBuildRetVoid (builder);
2642 LLVMVerifyFunction(func, LLVMAbortProcessAction);
2647 * Emit wrappers around the C icalls used to initialize llvm methods, to
2648 * make the calling code smaller and to enable usage of the llvm
2649 * PreserveAll calling convention.
2652 emit_init_icall_wrappers (MonoLLVMModule *module)
2654 module->init_method = emit_init_icall_wrapper (module, "init_method", "mono_aot_init_llvm_method", 0);
2655 module->init_method_gshared_mrgctx = emit_init_icall_wrapper (module, "init_method_gshared_mrgctx", "mono_aot_init_gshared_method_mrgctx", 1);
2656 module->init_method_gshared_this = emit_init_icall_wrapper (module, "init_method_gshared_this", "mono_aot_init_gshared_method_this", 2);
2657 module->init_method_gshared_vtable = emit_init_icall_wrapper (module, "init_method_gshared_vtable", "mono_aot_init_gshared_method_vtable", 3);
2661 emit_llvm_code_end (MonoLLVMModule *module)
2663 LLVMModuleRef lmodule = module->lmodule;
2665 LLVMBasicBlockRef entry_bb;
2666 LLVMBuilderRef builder;
2668 func = LLVMAddFunction (lmodule, "llvm_code_end", LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE));
2669 LLVMSetLinkage (func, LLVMInternalLinkage);
2670 LLVMAddFunctionAttr (func, LLVMNoUnwindAttribute);
2671 module->code_end = func;
2672 entry_bb = LLVMAppendBasicBlock (func, "ENTRY");
2673 builder = LLVMCreateBuilder ();
2674 LLVMPositionBuilderAtEnd (builder, entry_bb);
2675 LLVMBuildRetVoid (builder);
2679 emit_div_check (EmitContext *ctx, LLVMBuilderRef builder, MonoBasicBlock *bb, MonoInst *ins, LLVMValueRef lhs, LLVMValueRef rhs)
2681 gboolean need_div_check = ctx->cfg->backend->need_div_check;
2684 /* LLVM doesn't know that these can throw an exception since they are not called through an intrinsic */
2685 need_div_check = TRUE;
2687 if (!need_div_check)
2690 switch (ins->opcode) {
2703 case OP_IDIV_UN_IMM:
2704 case OP_LDIV_UN_IMM:
2705 case OP_IREM_UN_IMM:
2706 case OP_LREM_UN_IMM: {
2708 gboolean is_signed = (ins->opcode == OP_IDIV || ins->opcode == OP_LDIV || ins->opcode == OP_IREM || ins->opcode == OP_LREM ||
2709 ins->opcode == OP_IDIV_IMM || ins->opcode == OP_LDIV_IMM || ins->opcode == OP_IREM_IMM || ins->opcode == OP_LREM_IMM);
2711 cmp = LLVMBuildICmp (builder, LLVMIntEQ, rhs, LLVMConstInt (LLVMTypeOf (rhs), 0, FALSE), "");
2712 emit_cond_system_exception (ctx, bb, "DivideByZeroException", cmp);
2715 builder = ctx->builder;
2717 /* b == -1 && a == 0x80000000 */
2719 LLVMValueRef c = (LLVMTypeOf (lhs) == LLVMInt32Type ()) ? LLVMConstInt (LLVMTypeOf (lhs), 0x80000000, FALSE) : LLVMConstInt (LLVMTypeOf (lhs), 0x8000000000000000LL, FALSE);
2720 LLVMValueRef cond1 = LLVMBuildICmp (builder, LLVMIntEQ, rhs, LLVMConstInt (LLVMTypeOf (rhs), -1, FALSE), "");
2721 LLVMValueRef cond2 = LLVMBuildICmp (builder, LLVMIntEQ, lhs, c, "");
2723 cmp = LLVMBuildICmp (builder, LLVMIntEQ, LLVMBuildAnd (builder, cond1, cond2, ""), LLVMConstInt (LLVMInt1Type (), 1, FALSE), "");
2724 emit_cond_system_exception (ctx, bb, "OverflowException", cmp);
2727 builder = ctx->builder;
2739 * Emit code to initialize the GOT slots used by the method.
2742 emit_init_method (EmitContext *ctx)
2744 LLVMValueRef indexes [16], args [16], callee;
2745 LLVMValueRef inited_var, cmp, call;
2746 LLVMBasicBlockRef inited_bb, notinited_bb;
2747 LLVMBuilderRef builder = ctx->builder;
2748 MonoCompile *cfg = ctx->cfg;
2750 ctx->module->max_inited_idx = MAX (ctx->module->max_inited_idx, cfg->method_index);
2752 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
2753 indexes [1] = LLVMConstInt (LLVMInt32Type (), cfg->method_index, FALSE);
2754 inited_var = LLVMBuildLoad (builder, LLVMBuildGEP (builder, ctx->module->inited_var, indexes, 2, ""), "is_inited");
2756 args [0] = inited_var;
2757 args [1] = LLVMConstInt (LLVMInt8Type (), 1, FALSE);
2758 inited_var = LLVMBuildCall (ctx->builder, get_intrinsic (ctx, "llvm.expect.i8"), args, 2, "");
2760 cmp = LLVMBuildICmp (builder, LLVMIntEQ, inited_var, LLVMConstInt (LLVMTypeOf (inited_var), 0, FALSE), "");
2762 inited_bb = ctx->inited_bb;
2763 notinited_bb = gen_bb (ctx, "NOTINITED_BB");
2765 LLVMBuildCondBr (ctx->builder, cmp, notinited_bb, inited_bb);
2767 builder = ctx->builder = create_builder (ctx);
2768 LLVMPositionBuilderAtEnd (ctx->builder, notinited_bb);
2771 if (ctx->rgctx_arg && cfg->method->is_inflated && mono_method_get_context (cfg->method)->method_inst) {
2772 args [0] = LLVMConstInt (LLVMInt32Type (), cfg->method_index, 0);
2773 args [1] = convert (ctx, ctx->rgctx_arg, IntPtrType ());
2774 callee = ctx->module->init_method_gshared_mrgctx;
2775 call = LLVMBuildCall (builder, callee, args, 2, "");
2776 } else if (ctx->rgctx_arg) {
2777 /* A vtable is passed as the rgctx argument */
2778 args [0] = LLVMConstInt (LLVMInt32Type (), cfg->method_index, 0);
2779 args [1] = convert (ctx, ctx->rgctx_arg, IntPtrType ());
2780 callee = ctx->module->init_method_gshared_vtable;
2781 call = LLVMBuildCall (builder, callee, args, 2, "");
2782 } else if (cfg->gshared) {
2783 args [0] = LLVMConstInt (LLVMInt32Type (), cfg->method_index, 0);
2784 args [1] = convert (ctx, ctx->this_arg, ObjRefType ());
2785 callee = ctx->module->init_method_gshared_this;
2786 call = LLVMBuildCall (builder, callee, args, 2, "");
2788 args [0] = LLVMConstInt (LLVMInt32Type (), cfg->method_index, 0);
2789 callee = ctx->module->init_method;
2790 call = LLVMBuildCall (builder, callee, args, 1, "");
2794 * This enables llvm to keep arguments in their original registers/
2795 * scratch registers, since the call will not clobber them.
2797 mono_llvm_set_call_preserveall_cc (call);
2799 LLVMBuildBr (builder, inited_bb);
2800 ctx->bblocks [cfg->bb_entry->block_num].end_bblock = inited_bb;
2802 builder = ctx->builder = create_builder (ctx);
2803 LLVMPositionBuilderAtEnd (ctx->builder, inited_bb);
2807 emit_unbox_tramp (EmitContext *ctx, const char *method_name, LLVMTypeRef method_type, LLVMValueRef method, int method_index)
2810 * Emit unbox trampoline using a tail call
2812 LLVMValueRef tramp, call, *args;
2813 LLVMBuilderRef builder;
2814 LLVMBasicBlockRef lbb;
2815 LLVMCallInfo *linfo;
2819 tramp_name = g_strdup_printf ("ut_%s", method_name);
2820 tramp = LLVMAddFunction (ctx->module->lmodule, tramp_name, method_type);
2821 LLVMSetLinkage (tramp, LLVMInternalLinkage);
2822 LLVMAddFunctionAttr (tramp, LLVMOptimizeForSizeAttribute);
2823 //LLVMAddFunctionAttr (tramp, LLVMNoUnwindAttribute);
2825 // FIXME: Reduce code duplication with mono_llvm_compile_method () etc.
2826 if (!ctx->llvm_only && ctx->rgctx_arg_pindex != -1)
2827 LLVMAddAttribute (LLVMGetParam (tramp, ctx->rgctx_arg_pindex), LLVMInRegAttribute);
2828 if (ctx->cfg->vret_addr) {
2829 LLVMSetValueName (LLVMGetParam (tramp, linfo->vret_arg_pindex), "vret");
2830 if (linfo->ret.storage == LLVMArgVtypeByRef) {
2831 LLVMAddAttribute (LLVMGetParam (tramp, linfo->vret_arg_pindex), LLVMStructRetAttribute);
2832 LLVMAddAttribute (LLVMGetParam (tramp, linfo->vret_arg_pindex), LLVMNoAliasAttribute);
2836 lbb = LLVMAppendBasicBlock (tramp, "");
2837 builder = LLVMCreateBuilder ();
2838 LLVMPositionBuilderAtEnd (builder, lbb);
2840 nargs = LLVMCountParamTypes (method_type);
2841 args = g_new0 (LLVMValueRef, nargs);
2842 for (i = 0; i < nargs; ++i) {
2843 args [i] = LLVMGetParam (tramp, i);
2844 if (i == ctx->this_arg_pindex) {
2845 LLVMTypeRef arg_type = LLVMTypeOf (args [i]);
2847 args [i] = LLVMBuildPtrToInt (builder, args [i], IntPtrType (), "");
2848 args [i] = LLVMBuildAdd (builder, args [i], LLVMConstInt (IntPtrType (), sizeof (MonoObject), FALSE), "");
2849 args [i] = LLVMBuildIntToPtr (builder, args [i], arg_type, "");
2852 call = LLVMBuildCall (builder, method, args, nargs, "");
2853 if (!ctx->llvm_only && ctx->rgctx_arg_pindex != -1)
2854 LLVMAddInstrAttribute (call, 1 + ctx->rgctx_arg_pindex, LLVMInRegAttribute);
2855 if (linfo->ret.storage == LLVMArgVtypeByRef)
2856 LLVMAddInstrAttribute (call, 1 + linfo->vret_arg_pindex, LLVMStructRetAttribute);
2858 // FIXME: This causes assertions in clang
2859 //mono_llvm_set_must_tail (call);
2860 if (LLVMGetReturnType (method_type) == LLVMVoidType ())
2861 LLVMBuildRetVoid (builder);
2863 LLVMBuildRet (builder, call);
2865 g_hash_table_insert (ctx->module->idx_to_unbox_tramp, GINT_TO_POINTER (method_index), tramp);
2871 * Emit code to load/convert arguments.
2874 emit_entry_bb (EmitContext *ctx, LLVMBuilderRef builder)
2877 MonoCompile *cfg = ctx->cfg;
2878 MonoMethodSignature *sig = ctx->sig;
2879 LLVMCallInfo *linfo = ctx->linfo;
2883 LLVMBuilderRef old_builder = ctx->builder;
2884 ctx->builder = builder;
2886 ctx->alloca_builder = create_builder (ctx);
2889 * Handle indirect/volatile variables by allocating memory for them
2890 * using 'alloca', and storing their address in a temporary.
2892 for (i = 0; i < cfg->num_varinfo; ++i) {
2893 MonoInst *var = cfg->varinfo [i];
2896 if (var->opcode == OP_GSHAREDVT_LOCAL || var->opcode == OP_GSHAREDVT_ARG_REGOFFSET) {
2897 } else if (var->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT) || (mini_type_is_vtype (var->inst_vtype) && !MONO_CLASS_IS_SIMD (ctx->cfg, var->klass))) {
2898 vtype = type_to_llvm_type (ctx, var->inst_vtype);
2901 /* Could be already created by an OP_VPHI */
2902 if (!ctx->addresses [var->dreg]) {
2903 ctx->addresses [var->dreg] = build_alloca (ctx, var->inst_vtype);
2904 //LLVMSetValueName (ctx->addresses [var->dreg], g_strdup_printf ("vreg_loc_%d", var->dreg));
2906 ctx->vreg_cli_types [var->dreg] = var->inst_vtype;
2910 names = g_new (char *, sig->param_count);
2911 mono_method_get_param_names (cfg->method, (const char **) names);
2913 for (i = 0; i < sig->param_count; ++i) {
2914 LLVMArgInfo *ainfo = &linfo->args [i + sig->hasthis];
2915 int reg = cfg->args [i + sig->hasthis]->dreg;
2918 pindex = ainfo->pindex;
2920 switch (ainfo->storage) {
2921 case LLVMArgVtypeInReg:
2922 case LLVMArgAsFpArgs: {
2923 LLVMValueRef args [8];
2926 pindex += ainfo->ndummy_fpargs;
2928 /* The argument is received as a set of int/fp arguments, store them into the real argument */
2929 memset (args, 0, sizeof (args));
2930 if (ainfo->storage == LLVMArgVtypeInReg) {
2931 args [0] = LLVMGetParam (ctx->lmethod, pindex);
2932 if (ainfo->pair_storage [1] != LLVMArgNone)
2933 args [1] = LLVMGetParam (ctx->lmethod, pindex + 1);
2935 g_assert (ainfo->nslots <= 8);
2936 for (j = 0; j < ainfo->nslots; ++j)
2937 args [j] = LLVMGetParam (ctx->lmethod, pindex + j);
2939 ctx->addresses [reg] = build_alloca (ctx, ainfo->type);
2941 emit_args_to_vtype (ctx, builder, ainfo->type, ctx->addresses [reg], ainfo, args);
2943 if (ainfo->storage == LLVMArgVtypeInReg && MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (ainfo->type))) {
2944 /* Treat these as normal values */
2945 ctx->values [reg] = LLVMBuildLoad (builder, ctx->addresses [reg], "");
2949 case LLVMArgVtypeByVal: {
2950 ctx->addresses [reg] = LLVMGetParam (ctx->lmethod, pindex);
2952 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (ainfo->type))) {
2953 /* Treat these as normal values */
2954 ctx->values [reg] = LLVMBuildLoad (builder, ctx->addresses [reg], "");
2958 case LLVMArgVtypeByRef: {
2959 /* The argument is passed by ref */
2960 ctx->addresses [reg] = LLVMGetParam (ctx->lmethod, pindex);
2963 case LLVMArgAsIArgs: {
2964 LLVMValueRef arg = LLVMGetParam (ctx->lmethod, pindex);
2967 /* The argument is received as an array of ints, store it into the real argument */
2968 ctx->addresses [reg] = build_alloca (ctx, ainfo->type);
2970 size = mono_class_value_size (mono_class_from_mono_type (ainfo->type), NULL);
2971 if (size < SIZEOF_VOID_P) {
2972 /* The upper bits of the registers might not be valid */
2973 LLVMValueRef val = LLVMBuildExtractValue (builder, arg, 0, "");
2974 LLVMValueRef dest = convert (ctx, ctx->addresses [reg], LLVMPointerType (LLVMIntType (size * 8), 0));
2975 LLVMBuildStore (ctx->builder, LLVMBuildTrunc (builder, val, LLVMIntType (size * 8), ""), dest);
2977 LLVMBuildStore (ctx->builder, arg, convert (ctx, ctx->addresses [reg], LLVMPointerType (LLVMTypeOf (arg), 0)));
2981 case LLVMArgVtypeAsScalar:
2982 g_assert_not_reached ();
2984 case LLVMArgGsharedvtFixed: {
2985 /* These are non-gsharedvt arguments passed by ref, the rest of the IR treats them as scalars */
2986 LLVMValueRef arg = LLVMGetParam (ctx->lmethod, pindex);
2989 name = g_strdup_printf ("arg_%s", names [i]);
2991 name = g_strdup_printf ("arg_%d", i);
2993 ctx->values [reg] = LLVMBuildLoad (builder, convert (ctx, arg, LLVMPointerType (type_to_llvm_type (ctx, ainfo->type), 0)), name);
2996 case LLVMArgGsharedvtFixedVtype: {
2997 LLVMValueRef arg = LLVMGetParam (ctx->lmethod, pindex);
3000 name = g_strdup_printf ("vtype_arg_%s", names [i]);
3002 name = g_strdup_printf ("vtype_arg_%d", i);
3004 /* Non-gsharedvt vtype argument passed by ref, the rest of the IR treats it as a vtype */
3005 g_assert (ctx->addresses [reg]);
3006 LLVMSetValueName (ctx->addresses [reg], name);
3007 LLVMBuildStore (builder, LLVMBuildLoad (builder, convert (ctx, arg, LLVMPointerType (type_to_llvm_type (ctx, ainfo->type), 0)), ""), ctx->addresses [reg]);
3010 case LLVMArgGsharedvtVariable:
3011 /* The IR treats these as variables with addresses */
3012 ctx->addresses [reg] = LLVMGetParam (ctx->lmethod, pindex);
3015 ctx->values [reg] = convert_full (ctx, ctx->values [reg], llvm_type_to_stack_type (cfg, type_to_llvm_type (ctx, ainfo->type)), type_is_unsigned (ctx, ainfo->type));
3022 emit_volatile_store (ctx, cfg->vret_addr->dreg);
3024 emit_volatile_store (ctx, cfg->args [0]->dreg);
3025 for (i = 0; i < sig->param_count; ++i)
3026 if (!mini_type_is_vtype (sig->params [i]))
3027 emit_volatile_store (ctx, cfg->args [i + sig->hasthis]->dreg);
3029 if (sig->hasthis && !cfg->rgctx_var && cfg->gshared) {
3030 LLVMValueRef this_alloc;
3033 * The exception handling code needs the location where the this argument was
3034 * stored for gshared methods. We create a separate alloca to hold it, and mark it
3035 * with the "mono.this" custom metadata to tell llvm that it needs to save its
3036 * location into the LSDA.
3038 this_alloc = mono_llvm_build_alloca (builder, ThisType (), LLVMConstInt (LLVMInt32Type (), 1, FALSE), 0, "");
3039 /* This volatile store will keep the alloca alive */
3040 mono_llvm_build_store (builder, ctx->values [cfg->args [0]->dreg], this_alloc, TRUE, LLVM_BARRIER_NONE);
3042 set_metadata_flag (this_alloc, "mono.this");
3045 if (cfg->rgctx_var) {
3046 LLVMValueRef rgctx_alloc, store;
3049 * We handle the rgctx arg similarly to the this pointer.
3051 g_assert (ctx->addresses [cfg->rgctx_var->dreg]);
3052 rgctx_alloc = ctx->addresses [cfg->rgctx_var->dreg];
3053 /* This volatile store will keep the alloca alive */
3054 store = mono_llvm_build_store (builder, convert (ctx, ctx->rgctx_arg, IntPtrType ()), rgctx_alloc, TRUE, LLVM_BARRIER_NONE);
3056 set_metadata_flag (rgctx_alloc, "mono.this");
3059 /* Initialize the method if needed */
3060 if (cfg->compile_aot && ctx->llvm_only) {
3061 /* Emit a location for the initialization code */
3062 ctx->init_bb = gen_bb (ctx, "INIT_BB");
3063 ctx->inited_bb = gen_bb (ctx, "INITED_BB");
3065 LLVMBuildBr (ctx->builder, ctx->init_bb);
3066 builder = ctx->builder = create_builder (ctx);
3067 LLVMPositionBuilderAtEnd (ctx->builder, ctx->inited_bb);
3068 ctx->bblocks [cfg->bb_entry->block_num].end_bblock = ctx->inited_bb;
3071 /* Compute nesting between clauses */
3072 ctx->nested_in = (GSList**)mono_mempool_alloc0 (cfg->mempool, sizeof (GSList*) * cfg->header->num_clauses);
3073 for (i = 0; i < cfg->header->num_clauses; ++i) {
3074 for (j = 0; j < cfg->header->num_clauses; ++j) {
3075 MonoExceptionClause *clause1 = &cfg->header->clauses [i];
3076 MonoExceptionClause *clause2 = &cfg->header->clauses [j];
3078 if (i != j && clause1->try_offset >= clause2->try_offset && clause1->handler_offset <= clause2->handler_offset)
3079 ctx->nested_in [i] = g_slist_prepend_mempool (cfg->mempool, ctx->nested_in [i], GINT_TO_POINTER (j));
3084 * For finally clauses, create an indicator variable telling OP_ENDFINALLY whenever
3085 * it needs to continue normally, or return back to the exception handling system.
3087 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
3091 if (!(bb->region != -1 && (bb->flags & BB_EXCEPTION_HANDLER)))
3094 clause_index = MONO_REGION_CLAUSE_INDEX (bb->region);
3095 g_hash_table_insert (ctx->region_to_handler, GUINT_TO_POINTER (mono_get_block_region_notry (cfg, bb->region)), bb);
3096 g_hash_table_insert (ctx->clause_to_handler, GINT_TO_POINTER (clause_index), bb);
3098 if (bb->in_scount == 0) {
3101 sprintf (name, "finally_ind_bb%d", bb->block_num);
3102 val = LLVMBuildAlloca (builder, LLVMInt32Type (), name);
3103 LLVMBuildStore (builder, LLVMConstInt (LLVMInt32Type (), 0, FALSE), val);
3105 ctx->bblocks [bb->block_num].finally_ind = val;
3107 /* Create a variable to hold the exception var */
3109 ctx->ex_var = LLVMBuildAlloca (builder, ObjRefType (), "exvar");
3113 * Create a new bblock which CALL_HANDLER/landing pads can branch to, because branching to the
3114 * LLVM bblock containing a landing pad causes problems for the
3115 * LLVM optimizer passes.
3117 sprintf (name, "BB%d_CALL_HANDLER_TARGET", bb->block_num);
3118 ctx->bblocks [bb->block_num].call_handler_target_bb = LLVMAppendBasicBlock (ctx->lmethod, name);
3120 ctx->builder = old_builder;
3124 process_call (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, MonoInst *ins)
3126 MonoCompile *cfg = ctx->cfg;
3127 LLVMValueRef *values = ctx->values;
3128 LLVMValueRef *addresses = ctx->addresses;
3129 MonoCallInst *call = (MonoCallInst*)ins;
3130 MonoMethodSignature *sig = call->signature;
3131 LLVMValueRef callee = NULL, lcall;
3133 LLVMCallInfo *cinfo;
3137 LLVMTypeRef llvm_sig;
3139 gboolean is_virtual, calli, preserveall;
3140 LLVMBuilderRef builder = *builder_ref;
3142 if (call->signature->call_convention != MONO_CALL_DEFAULT) {
3143 set_failure (ctx, "non-default callconv");
3147 cinfo = call->cinfo;
3149 if (call->rgctx_arg_reg)
3150 cinfo->rgctx_arg = TRUE;
3151 if (call->imt_arg_reg)
3152 cinfo->imt_arg = TRUE;
3154 vretaddr = (cinfo->ret.storage == LLVMArgVtypeRetAddr || cinfo->ret.storage == LLVMArgVtypeByRef || cinfo->ret.storage == LLVMArgGsharedvtFixed || cinfo->ret.storage == LLVMArgGsharedvtVariable || cinfo->ret.storage == LLVMArgGsharedvtFixedVtype);
3156 llvm_sig = sig_to_llvm_sig_full (ctx, sig, cinfo);
3160 is_virtual = (ins->opcode == OP_VOIDCALL_MEMBASE || ins->opcode == OP_CALL_MEMBASE || ins->opcode == OP_VCALL_MEMBASE || ins->opcode == OP_LCALL_MEMBASE || ins->opcode == OP_FCALL_MEMBASE || ins->opcode == OP_RCALL_MEMBASE);
3161 calli = !call->fptr_is_patch && (ins->opcode == OP_VOIDCALL_REG || ins->opcode == OP_CALL_REG || ins->opcode == OP_VCALL_REG || ins->opcode == OP_LCALL_REG || ins->opcode == OP_FCALL_REG || ins->opcode == OP_RCALL_REG);
3163 preserveall = FALSE;
3165 /* FIXME: Avoid creating duplicate methods */
3167 if (ins->flags & MONO_INST_HAS_METHOD) {
3171 if (cfg->compile_aot) {
3172 callee = get_callee (ctx, llvm_sig, MONO_PATCH_INFO_METHOD, call->method);
3174 set_failure (ctx, "can't encode patch");
3177 if (cfg->llvm_only && call->method->klass->image->assembly == ctx->module->assembly) {
3179 * Collect instructions representing the callee into a hash so they can be replaced
3180 * by the llvm method for the callee if the callee turns out to be direct
3181 * callable. Currently this only requires it to not fail llvm compilation.
3183 GSList *l = (GSList*)g_hash_table_lookup (ctx->method_to_callers, call->method);
3184 l = g_slist_prepend (l, callee);
3185 g_hash_table_insert (ctx->method_to_callers, call->method, l);
3189 static int tramp_index;
3192 name = g_strdup_printf ("tramp_%d", tramp_index);
3195 #if LLVM_API_VERSION > 100
3197 * Use our trampoline infrastructure for lazy compilation instead of llvm's.
3198 * Make all calls through a global. The address of the global will be saved in
3199 * MonoJitDomainInfo.llvm_jit_callees and updated when the method it refers to is
3202 LLVMValueRef tramp_var = g_hash_table_lookup (ctx->jit_callees, call->method);
3205 mono_create_jit_trampoline (mono_domain_get (),
3206 call->method, &error);
3207 if (!mono_error_ok (&error))
3208 mono_error_raise_exception (&error); /* FIXME: Don't raise here */
3209 tramp_var = LLVMAddGlobal (ctx->lmodule, LLVMPointerType (llvm_sig, 0), name);
3210 LLVMSetInitializer (tramp_var, LLVMConstIntToPtr (LLVMConstInt (LLVMInt64Type (), (guint64)(size_t)target, FALSE), LLVMPointerType (llvm_sig, 0)));
3211 LLVMSetLinkage (tramp_var, LLVMExternalLinkage);
3212 g_hash_table_insert (ctx->jit_callees, call->method, tramp_var);
3214 callee = LLVMBuildLoad (builder, tramp_var, "");
3217 mono_create_jit_trampoline (mono_domain_get (),
3218 call->method, &error);
3219 if (!mono_error_ok (&error))
3220 mono_error_raise_exception (&error); /* FIXME: Don't raise here */
3222 callee = LLVMAddFunction (ctx->lmodule, name, llvm_sig);
3225 if (!mono_error_ok (&error))
3226 mono_error_raise_exception (&error); /* FIXME: Don't raise here */
3227 LLVMAddGlobalMapping (ctx->module->ee, callee, target);
3232 if (!cfg->llvm_only && call->method && strstr (call->method->klass->name, "AsyncVoidMethodBuilder")) {
3233 /* LLVM miscompiles async methods */
3234 set_failure (ctx, "#13734");
3239 MonoJitICallInfo *info = mono_find_jit_icall_by_addr (call->fptr);
3245 memset (&ji, 0, sizeof (ji));
3246 ji.type = MONO_PATCH_INFO_JIT_ICALL_ADDR;
3247 ji.data.target = info->name;
3249 target = mono_resolve_patch_target (cfg->method, cfg->domain, NULL, &ji, FALSE);
3251 if (cfg->compile_aot) {
3252 callee = get_callee (ctx, llvm_sig, MONO_PATCH_INFO_INTERNAL_METHOD, (char*)info->name);
3254 set_failure (ctx, "can't encode patch");
3258 target = (gpointer)mono_icall_get_wrapper (info);
3259 callee = emit_jit_callee (ctx, "", llvm_sig, target);
3262 if (cfg->compile_aot) {
3264 if (cfg->abs_patches) {
3265 MonoJumpInfo *abs_ji = (MonoJumpInfo*)g_hash_table_lookup (cfg->abs_patches, call->fptr);
3267 callee = get_callee (ctx, llvm_sig, abs_ji->type, abs_ji->data.target);
3269 set_failure (ctx, "can't encode patch");
3275 set_failure (ctx, "aot");
3279 #if LLVM_API_VERSION > 100
3280 if (cfg->abs_patches) {
3281 MonoJumpInfo *abs_ji = (MonoJumpInfo*)g_hash_table_lookup (cfg->abs_patches, call->fptr);
3285 target = mono_resolve_patch_target (cfg->method, cfg->domain, NULL, abs_ji, FALSE, &error);
3286 mono_error_assert_ok (&error);
3287 callee = emit_jit_callee (ctx, "", llvm_sig, target);
3289 g_assert_not_reached ();
3292 g_assert_not_reached ();
3295 callee = LLVMAddFunction (ctx->lmodule, "", llvm_sig);
3297 if (cfg->abs_patches) {
3298 MonoJumpInfo *abs_ji = (MonoJumpInfo*)g_hash_table_lookup (cfg->abs_patches, call->fptr);
3303 * FIXME: Some trampolines might have
3304 * their own calling convention on some platforms.
3306 target = mono_resolve_patch_target (cfg->method, cfg->domain, NULL, abs_ji, FALSE, &error);
3307 mono_error_assert_ok (&error);
3308 LLVMAddGlobalMapping (ctx->module->ee, callee, target);
3312 LLVMAddGlobalMapping (ctx->module->ee, callee, (gpointer)call->fptr);
3319 int size = sizeof (gpointer);
3322 g_assert (ins->inst_offset % size == 0);
3323 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
3325 callee = convert (ctx, LLVMBuildLoad (builder, LLVMBuildGEP (builder, convert (ctx, values [ins->inst_basereg], LLVMPointerType (LLVMPointerType (IntPtrType (), 0), 0)), &index, 1, ""), ""), LLVMPointerType (llvm_sig, 0));
3327 callee = convert (ctx, values [ins->sreg1], LLVMPointerType (llvm_sig, 0));
3329 if (ins->flags & MONO_INST_HAS_METHOD) {
3334 * Collect and convert arguments
3336 nargs = (sig->param_count * 16) + sig->hasthis + vretaddr + call->rgctx_reg + call->imt_arg_reg;
3337 len = sizeof (LLVMValueRef) * nargs;
3338 args = (LLVMValueRef*)alloca (len);
3339 memset (args, 0, len);
3340 l = call->out_ireg_args;
3342 if (call->rgctx_arg_reg) {
3343 g_assert (values [call->rgctx_arg_reg]);
3344 g_assert (cinfo->rgctx_arg_pindex < nargs);
3346 * On ARM, the imt/rgctx argument is passed in a caller save register, but some of our trampolines etc. clobber it, leading to
3347 * problems is LLVM moves the arg assignment earlier. To work around this, save the argument into a stack slot and load
3348 * it using a volatile load.
3351 if (!ctx->imt_rgctx_loc)
3352 ctx->imt_rgctx_loc = build_alloca_llvm_type (ctx, ctx->module->ptr_type, sizeof (gpointer));
3353 LLVMBuildStore (builder, convert (ctx, ctx->values [call->rgctx_arg_reg], ctx->module->ptr_type), ctx->imt_rgctx_loc);
3354 args [cinfo->rgctx_arg_pindex] = mono_llvm_build_load (builder, ctx->imt_rgctx_loc, "", TRUE, LLVM_BARRIER_NONE);
3356 args [cinfo->rgctx_arg_pindex] = convert (ctx, values [call->rgctx_arg_reg], ctx->module->ptr_type);
3359 if (call->imt_arg_reg) {
3360 g_assert (!ctx->llvm_only);
3361 g_assert (values [call->imt_arg_reg]);
3362 g_assert (cinfo->imt_arg_pindex < nargs);
3364 if (!ctx->imt_rgctx_loc)
3365 ctx->imt_rgctx_loc = build_alloca_llvm_type (ctx, ctx->module->ptr_type, sizeof (gpointer));
3366 LLVMBuildStore (builder, convert (ctx, ctx->values [call->imt_arg_reg], ctx->module->ptr_type), ctx->imt_rgctx_loc);
3367 args [cinfo->imt_arg_pindex] = mono_llvm_build_load (builder, ctx->imt_rgctx_loc, "", TRUE, LLVM_BARRIER_NONE);
3369 args [cinfo->imt_arg_pindex] = convert (ctx, values [call->imt_arg_reg], ctx->module->ptr_type);
3372 switch (cinfo->ret.storage) {
3373 case LLVMArgGsharedvtVariable: {
3374 MonoInst *var = get_vreg_to_inst (cfg, call->inst.dreg);
3376 if (var && var->opcode == OP_GSHAREDVT_LOCAL) {
3377 args [cinfo->vret_arg_pindex] = convert (ctx, emit_gsharedvt_ldaddr (ctx, var->dreg), IntPtrType ());
3379 g_assert (addresses [call->inst.dreg]);
3380 args [cinfo->vret_arg_pindex] = addresses [call->inst.dreg];
3386 if (!addresses [call->inst.dreg])
3387 addresses [call->inst.dreg] = build_alloca (ctx, sig->ret);
3388 g_assert (cinfo->vret_arg_pindex < nargs);
3389 if (cinfo->ret.storage == LLVMArgVtypeByRef)
3390 args [cinfo->vret_arg_pindex] = addresses [call->inst.dreg];
3392 args [cinfo->vret_arg_pindex] = LLVMBuildPtrToInt (builder, addresses [call->inst.dreg], IntPtrType (), "");
3398 * Sometimes the same method is called with two different signatures (i.e. with and without 'this'), so
3399 * use the real callee for argument type conversion.
3401 LLVMTypeRef callee_type = LLVMGetElementType (LLVMTypeOf (callee));
3402 LLVMTypeRef *param_types = (LLVMTypeRef*)g_alloca (sizeof (LLVMTypeRef) * LLVMCountParamTypes (callee_type));
3403 LLVMGetParamTypes (callee_type, param_types);
3405 for (i = 0; i < sig->param_count + sig->hasthis; ++i) {
3408 LLVMArgInfo *ainfo = &call->cinfo->args [i];
3410 pindex = ainfo->pindex;
3412 regpair = (guint32)(gssize)(l->data);
3413 reg = regpair & 0xffffff;
3414 args [pindex] = values [reg];
3415 switch (ainfo->storage) {
3416 case LLVMArgVtypeInReg:
3417 case LLVMArgAsFpArgs: {
3421 for (j = 0; j < ainfo->ndummy_fpargs; ++j)
3422 args [pindex + j] = LLVMConstNull (LLVMDoubleType ());
3423 pindex += ainfo->ndummy_fpargs;
3425 g_assert (addresses [reg]);
3426 emit_vtype_to_args (ctx, builder, ainfo->type, addresses [reg], ainfo, args + pindex, &nargs);
3430 // FIXME: Get rid of the VMOVE
3433 case LLVMArgVtypeByVal:
3434 g_assert (addresses [reg]);
3435 args [pindex] = addresses [reg];
3437 case LLVMArgVtypeByRef: {
3438 g_assert (addresses [reg]);
3439 args [pindex] = convert (ctx, addresses [reg], LLVMPointerType (type_to_llvm_arg_type (ctx, ainfo->type), 0));
3442 case LLVMArgAsIArgs:
3443 g_assert (addresses [reg]);
3444 args [pindex] = LLVMBuildLoad (ctx->builder, convert (ctx, addresses [reg], LLVMPointerType (LLVMArrayType (IntPtrType (), ainfo->nslots), 0)), "");
3446 case LLVMArgVtypeAsScalar:
3447 g_assert_not_reached ();
3449 case LLVMArgGsharedvtFixed:
3450 case LLVMArgGsharedvtFixedVtype:
3451 g_assert (addresses [reg]);
3452 args [pindex] = convert (ctx, addresses [reg], LLVMPointerType (type_to_llvm_arg_type (ctx, ainfo->type), 0));
3454 case LLVMArgGsharedvtVariable:
3455 g_assert (addresses [reg]);
3456 args [pindex] = convert (ctx, addresses [reg], LLVMPointerType (IntPtrType (), 0));
3459 g_assert (args [pindex]);
3460 if (i == 0 && sig->hasthis)
3461 args [pindex] = convert (ctx, args [pindex], param_types [pindex]);
3463 args [pindex] = convert (ctx, args [pindex], type_to_llvm_arg_type (ctx, ainfo->type));
3466 g_assert (pindex <= nargs);
3471 // FIXME: Align call sites
3477 lcall = emit_call (ctx, bb, &builder, callee, args, LLVMCountParamTypes (llvm_sig));
3480 * Modify cconv and parameter attributes to pass rgctx/imt correctly.
3482 #if defined(MONO_ARCH_IMT_REG) && defined(MONO_ARCH_RGCTX_REG)
3483 g_assert (MONO_ARCH_IMT_REG == MONO_ARCH_RGCTX_REG);
3485 /* The two can't be used together, so use only one LLVM calling conv to pass them */
3486 g_assert (!(call->rgctx_arg_reg && call->imt_arg_reg));
3487 if (!sig->pinvoke && !cfg->llvm_only)
3488 LLVMSetInstructionCallConv (lcall, LLVMMono1CallConv);
3490 mono_llvm_set_call_preserveall_cc (lcall);
3492 if (cinfo->ret.storage == LLVMArgVtypeByRef)
3493 LLVMAddInstrAttribute (lcall, 1 + cinfo->vret_arg_pindex, LLVMStructRetAttribute);
3494 if (!ctx->llvm_only && call->rgctx_arg_reg)
3495 LLVMAddInstrAttribute (lcall, 1 + cinfo->rgctx_arg_pindex, LLVMInRegAttribute);
3496 if (call->imt_arg_reg)
3497 LLVMAddInstrAttribute (lcall, 1 + cinfo->imt_arg_pindex, LLVMInRegAttribute);
3499 /* Add byval attributes if needed */
3500 for (i = 0; i < sig->param_count; ++i) {
3501 LLVMArgInfo *ainfo = &call->cinfo->args [i + sig->hasthis];
3503 if (ainfo && ainfo->storage == LLVMArgVtypeByVal)
3504 LLVMAddInstrAttribute (lcall, 1 + ainfo->pindex, LLVMByValAttribute);
3508 * Convert the result
3510 switch (cinfo->ret.storage) {
3511 case LLVMArgVtypeInReg: {
3512 LLVMValueRef regs [2];
3514 if (LLVMTypeOf (lcall) == LLVMVoidType ())
3518 if (!addresses [ins->dreg])
3519 addresses [ins->dreg] = build_alloca (ctx, sig->ret);
3521 regs [0] = LLVMBuildExtractValue (builder, lcall, 0, "");
3522 if (cinfo->ret.pair_storage [1] != LLVMArgNone)
3523 regs [1] = LLVMBuildExtractValue (builder, lcall, 1, "");
3524 emit_args_to_vtype (ctx, builder, sig->ret, addresses [ins->dreg], &cinfo->ret, regs);
3527 case LLVMArgVtypeByVal:
3528 if (!addresses [call->inst.dreg])
3529 addresses [call->inst.dreg] = build_alloca (ctx, sig->ret);
3530 LLVMBuildStore (builder, lcall, addresses [call->inst.dreg]);
3532 case LLVMArgFpStruct:
3533 if (!addresses [call->inst.dreg])
3534 addresses [call->inst.dreg] = build_alloca (ctx, sig->ret);
3535 LLVMBuildStore (builder, lcall, convert_full (ctx, addresses [call->inst.dreg], LLVMPointerType (LLVMTypeOf (lcall), 0), FALSE));
3537 case LLVMArgVtypeAsScalar:
3538 if (!addresses [call->inst.dreg])
3539 addresses [call->inst.dreg] = build_alloca (ctx, sig->ret);
3540 LLVMBuildStore (builder, lcall, convert_full (ctx, addresses [call->inst.dreg], LLVMPointerType (LLVMTypeOf (lcall), 0), FALSE));
3542 case LLVMArgVtypeRetAddr:
3543 case LLVMArgVtypeByRef:
3544 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (sig->ret))) {
3545 /* Some opcodes like STOREX_MEMBASE access these by value */
3546 g_assert (addresses [call->inst.dreg]);
3547 values [ins->dreg] = LLVMBuildLoad (builder, convert_full (ctx, addresses [call->inst.dreg], LLVMPointerType (type_to_llvm_type (ctx, sig->ret), 0), FALSE), "");
3550 case LLVMArgGsharedvtVariable:
3552 case LLVMArgGsharedvtFixed:
3553 case LLVMArgGsharedvtFixedVtype:
3554 values [ins->dreg] = LLVMBuildLoad (builder, convert_full (ctx, addresses [call->inst.dreg], LLVMPointerType (type_to_llvm_type (ctx, sig->ret), 0), FALSE), "");
3557 if (sig->ret->type != MONO_TYPE_VOID)
3558 /* If the method returns an unsigned value, need to zext it */
3559 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));
3563 *builder_ref = ctx->builder;
3567 emit_llvmonly_throw (EmitContext *ctx, MonoBasicBlock *bb, gboolean rethrow, LLVMValueRef exc)
3569 const char *icall_name = rethrow ? "mono_llvm_rethrow_exception" : "mono_llvm_throw_exception";
3570 LLVMValueRef callee = rethrow ? ctx->module->rethrow : ctx->module->throw_icall;
3572 LLVMTypeRef exc_type = type_to_llvm_type (ctx, &mono_get_exception_class ()->byval_arg);
3575 LLVMTypeRef fun_sig = LLVMFunctionType1 (LLVMVoidType (), exc_type, FALSE);
3577 if (ctx->cfg->compile_aot) {
3578 callee = get_callee (ctx, fun_sig, MONO_PATCH_INFO_JIT_ICALL_ADDR, icall_name);
3580 callee = LLVMAddFunction (ctx->lmodule, icall_name, fun_sig);
3581 LLVMAddGlobalMapping (ctx->module->ee, callee, resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name));
3582 mono_memory_barrier ();
3585 ctx->module->rethrow = callee;
3587 ctx->module->throw_icall = callee;
3591 LLVMValueRef args [2];
3593 args [0] = convert (ctx, exc, exc_type);
3594 emit_call (ctx, bb, &ctx->builder, callee, args, 1);
3596 LLVMBuildUnreachable (ctx->builder);
3598 ctx->builder = create_builder (ctx);
3602 emit_throw (EmitContext *ctx, MonoBasicBlock *bb, gboolean rethrow, LLVMValueRef exc)
3604 MonoMethodSignature *throw_sig;
3605 LLVMValueRef callee, arg;
3606 const char *icall_name;
3608 callee = rethrow ? ctx->module->rethrow : ctx->module->throw_icall;
3609 icall_name = rethrow ? "mono_arch_rethrow_exception" : "mono_arch_throw_exception";
3612 throw_sig = mono_metadata_signature_alloc (mono_get_corlib (), 1);
3613 throw_sig->ret = &mono_get_void_class ()->byval_arg;
3614 throw_sig->params [0] = &mono_get_object_class ()->byval_arg;
3615 if (ctx->cfg->compile_aot) {
3616 callee = get_callee (ctx, sig_to_llvm_sig (ctx, throw_sig), MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
3621 * LLVM doesn't push the exception argument, so we need a different
3624 target = resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, rethrow ? "llvm_rethrow_exception_trampoline" : "llvm_throw_exception_trampoline");
3626 target = resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
3628 callee = emit_jit_callee (ctx, icall_name, sig_to_llvm_sig (ctx, throw_sig), target);
3631 mono_memory_barrier ();
3632 #if LLVM_API_VERSION < 100
3634 ctx->module->rethrow = callee;
3636 ctx->module->throw_icall = callee;
3639 arg = convert (ctx, exc, type_to_llvm_type (ctx, &mono_get_object_class ()->byval_arg));
3640 emit_call (ctx, bb, &ctx->builder, callee, &arg, 1);
3644 emit_resume_eh (EmitContext *ctx, MonoBasicBlock *bb)
3646 const char *icall_name = "mono_llvm_resume_exception";
3647 LLVMValueRef callee = ctx->module->resume_eh;
3649 LLVMTypeRef fun_sig = LLVMFunctionType0 (LLVMVoidType (), FALSE);
3652 if (ctx->cfg->compile_aot) {
3653 callee = get_callee (ctx, fun_sig, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
3655 callee = LLVMAddFunction (ctx->lmodule, icall_name, fun_sig);
3656 LLVMAddGlobalMapping (ctx->module->ee, callee, resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name));
3657 mono_memory_barrier ();
3659 ctx->module->resume_eh = callee;
3663 emit_call (ctx, bb, &ctx->builder, callee, NULL, 0);
3665 LLVMBuildUnreachable (ctx->builder);
3667 ctx->builder = create_builder (ctx);
3671 mono_llvm_emit_clear_exception_call (EmitContext *ctx, LLVMBuilderRef builder)
3673 const char *icall_name = "mono_llvm_clear_exception";
3675 LLVMTypeRef call_sig = LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE);
3676 LLVMValueRef callee = NULL;
3679 if (ctx->cfg->compile_aot) {
3680 callee = get_callee (ctx, call_sig, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
3682 // FIXME: This is broken.
3683 callee = LLVMAddFunction (ctx->lmodule, icall_name, call_sig);
3687 g_assert (builder && callee);
3689 return LLVMBuildCall (builder, callee, NULL, 0, "");
3693 mono_llvm_emit_load_exception_call (EmitContext *ctx, LLVMBuilderRef builder)
3695 const char *icall_name = "mono_llvm_load_exception";
3697 LLVMTypeRef call_sig = LLVMFunctionType (ObjRefType (), NULL, 0, FALSE);
3698 LLVMValueRef callee = NULL;
3701 if (ctx->cfg->compile_aot) {
3702 callee = get_callee (ctx, call_sig, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
3704 // FIXME: This is broken.
3705 callee = LLVMAddFunction (ctx->lmodule, icall_name, call_sig);
3709 g_assert (builder && callee);
3711 return LLVMBuildCall (builder, callee, NULL, 0, icall_name);
3716 mono_llvm_emit_match_exception_call (EmitContext *ctx, LLVMBuilderRef builder, gint32 region_start, gint32 region_end)
3718 const char *icall_name = "mono_llvm_match_exception";
3720 ctx->builder = builder;
3722 const int num_args = 5;
3723 LLVMValueRef args [num_args];
3724 args [0] = convert (ctx, get_aotconst (ctx, MONO_PATCH_INFO_AOT_JIT_INFO, GINT_TO_POINTER (ctx->cfg->method_index)), IntPtrType ());
3725 args [1] = LLVMConstInt (LLVMInt32Type (), region_start, 0);
3726 args [2] = LLVMConstInt (LLVMInt32Type (), region_end, 0);
3727 if (ctx->cfg->rgctx_var) {
3728 LLVMValueRef rgctx_alloc = ctx->addresses [ctx->cfg->rgctx_var->dreg];
3729 g_assert (rgctx_alloc);
3730 args [3] = LLVMBuildLoad (builder, convert (ctx, rgctx_alloc, LLVMPointerType (IntPtrType (), 0)), "");
3732 args [3] = LLVMConstInt (IntPtrType (), 0, 0);
3735 args [4] = convert (ctx, ctx->this_arg, IntPtrType ());
3737 args [4] = LLVMConstInt (IntPtrType (), 0, 0);
3739 LLVMTypeRef match_sig = LLVMFunctionType5 (LLVMInt32Type (), IntPtrType (), LLVMInt32Type (), LLVMInt32Type (), IntPtrType (), IntPtrType (), FALSE);
3740 LLVMValueRef callee = ctx->module->match_exc;
3743 if (ctx->cfg->compile_aot) {
3744 ctx->builder = builder;
3745 // get_callee expects ctx->builder to be the emitting builder
3746 callee = get_callee (ctx, match_sig, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
3748 callee = ctx->module->match_exc = LLVMAddFunction (ctx->lmodule, icall_name, match_sig);
3749 LLVMAddGlobalMapping (ctx->module->ee, ctx->module->match_exc, resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name));
3750 ctx->module->match_exc = callee;
3751 mono_memory_barrier ();
3755 g_assert (builder && callee);
3757 g_assert (ctx->ex_var);
3759 return LLVMBuildCall (builder, callee, args, num_args, icall_name);
3762 // FIXME: This won't work because the code-finding makes this
3764 /*#define MONO_PERSONALITY_DEBUG*/
3766 #ifdef MONO_PERSONALITY_DEBUG
3767 static const gboolean use_debug_personality = TRUE;
3768 static const char *default_personality_name = "mono_debug_personality";
3770 static const gboolean use_debug_personality = FALSE;
3771 static const char *default_personality_name = "__gxx_personality_v0";
3775 default_cpp_lpad_exc_signature (void)
3777 static gboolean inited = FALSE;
3778 static LLVMTypeRef sig;
3781 LLVMTypeRef signature [2];
3782 signature [0] = LLVMPointerType (LLVMInt8Type (), 0);
3783 signature [1] = LLVMInt32Type ();
3784 sig = LLVMStructType (signature, 2, FALSE);
3792 get_mono_personality (EmitContext *ctx)
3794 LLVMValueRef personality = NULL;
3795 static gint32 mapping_inited = FALSE;
3796 LLVMTypeRef personality_type = LLVMFunctionType (LLVMInt32Type (), NULL, 0, TRUE);
3798 if (!use_debug_personality) {
3799 if (ctx->cfg->compile_aot) {
3800 personality = get_intrinsic (ctx, default_personality_name);
3801 } else if (InterlockedCompareExchange (&mapping_inited, 1, 0) == 0) {
3802 personality = LLVMAddFunction (ctx->lmodule, default_personality_name, personality_type);
3803 LLVMAddGlobalMapping (ctx->module->ee, personality, personality);
3806 if (ctx->cfg->compile_aot) {
3807 personality = get_callee (ctx, personality_type, MONO_PATCH_INFO_INTERNAL_METHOD, default_personality_name);
3809 personality = LLVMAddFunction (ctx->lmodule, default_personality_name, personality_type);
3810 LLVMAddGlobalMapping (ctx->module->ee, personality, resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, default_personality_name));
3811 mono_memory_barrier ();
3815 g_assert (personality);
3819 static LLVMBasicBlockRef
3820 emit_landing_pad (EmitContext *ctx, int group_index, int group_size)
3822 MonoCompile *cfg = ctx->cfg;
3823 LLVMBuilderRef old_builder = ctx->builder;
3824 MonoExceptionClause *group_start = cfg->header->clauses + group_index;
3826 LLVMBuilderRef lpadBuilder = create_builder (ctx);
3827 ctx->builder = lpadBuilder;
3829 MonoBasicBlock *handler_bb = cfg->cil_offset_to_bb [CLAUSE_START (group_start)];
3830 g_assert (handler_bb);
3832 // <resultval> = landingpad <somety> personality <type> <pers_fn> <clause>+
3833 LLVMValueRef personality = get_mono_personality (ctx);
3834 g_assert (personality);
3836 char *bb_name = g_strdup_printf ("LPAD%d_BB", group_index);
3837 LLVMBasicBlockRef lpad_bb = gen_bb (ctx, bb_name);
3839 LLVMPositionBuilderAtEnd (lpadBuilder, lpad_bb);
3840 LLVMValueRef landing_pad = LLVMBuildLandingPad (lpadBuilder, default_cpp_lpad_exc_signature (), personality, 0, "");
3841 g_assert (landing_pad);
3843 LLVMValueRef cast = LLVMBuildBitCast (lpadBuilder, ctx->module->sentinel_exception, LLVMPointerType (LLVMInt8Type (), 0), "int8TypeInfo");
3844 LLVMAddClause (landing_pad, cast);
3846 LLVMBasicBlockRef resume_bb = gen_bb (ctx, "RESUME_BB");
3847 LLVMBuilderRef resume_builder = create_builder (ctx);
3848 ctx->builder = resume_builder;
3849 LLVMPositionBuilderAtEnd (resume_builder, resume_bb);
3851 emit_resume_eh (ctx, handler_bb);
3854 ctx->builder = lpadBuilder;
3855 LLVMPositionBuilderAtEnd (lpadBuilder, lpad_bb);
3857 gboolean finally_only = TRUE;
3859 MonoExceptionClause *group_cursor = group_start;
3861 for (int i = 0; i < group_size; i ++) {
3862 if (!(group_cursor->flags & MONO_EXCEPTION_CLAUSE_FINALLY))
3863 finally_only = FALSE;
3869 // Handle landing pad inlining
3871 if (!finally_only) {
3872 // So at each level of the exception stack we will match the exception again.
3873 // During that match, we need to compare against the handler types for the current
3874 // protected region. We send the try start and end so that we can only check against
3875 // handlers for this lexical protected region.
3876 LLVMValueRef match = mono_llvm_emit_match_exception_call (ctx, lpadBuilder, group_start->try_offset, group_start->try_offset + group_start->try_len);
3878 // if returns -1, resume
3879 LLVMValueRef switch_ins = LLVMBuildSwitch (lpadBuilder, match, resume_bb, group_size);
3881 // else move to that target bb
3882 for (int i=0; i < group_size; i++) {
3883 MonoExceptionClause *clause = group_start + i;
3884 int clause_index = clause - cfg->header->clauses;
3885 MonoBasicBlock *handler_bb = (MonoBasicBlock*)g_hash_table_lookup (ctx->clause_to_handler, GINT_TO_POINTER (clause_index));
3886 g_assert (handler_bb);
3887 g_assert (ctx->bblocks [handler_bb->block_num].call_handler_target_bb);
3888 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), clause_index, FALSE), ctx->bblocks [handler_bb->block_num].call_handler_target_bb);
3891 int clause_index = group_start - cfg->header->clauses;
3892 MonoBasicBlock *finally_bb = (MonoBasicBlock*)g_hash_table_lookup (ctx->clause_to_handler, GINT_TO_POINTER (clause_index));
3893 g_assert (finally_bb);
3895 LLVMBuildBr (ctx->builder, ctx->bblocks [finally_bb->block_num].call_handler_target_bb);
3898 ctx->builder = old_builder;
3905 emit_llvmonly_handler_start (EmitContext *ctx, MonoBasicBlock *bb, LLVMBasicBlockRef cbb)
3907 int clause_index = MONO_REGION_CLAUSE_INDEX (bb->region);
3908 MonoExceptionClause *clause = &ctx->cfg->header->clauses [clause_index];
3910 // Make exception available to catch blocks
3911 if (!(clause->flags & MONO_EXCEPTION_CLAUSE_FINALLY)) {
3912 LLVMValueRef mono_exc = mono_llvm_emit_load_exception_call (ctx, ctx->builder);
3914 g_assert (ctx->ex_var);
3915 LLVMBuildStore (ctx->builder, LLVMBuildBitCast (ctx->builder, mono_exc, ObjRefType (), ""), ctx->ex_var);
3917 if (bb->in_scount == 1) {
3918 MonoInst *exvar = bb->in_stack [0];
3919 g_assert (!ctx->values [exvar->dreg]);
3920 g_assert (ctx->ex_var);
3921 ctx->values [exvar->dreg] = LLVMBuildLoad (ctx->builder, ctx->ex_var, "save_exception");
3922 emit_volatile_store (ctx, exvar->dreg);
3925 mono_llvm_emit_clear_exception_call (ctx, ctx->builder);
3928 LLVMBuilderRef handler_builder = create_builder (ctx);
3929 LLVMBasicBlockRef target_bb = ctx->bblocks [bb->block_num].call_handler_target_bb;
3930 LLVMPositionBuilderAtEnd (handler_builder, target_bb);
3932 // Make the handler code end with a jump to cbb
3933 LLVMBuildBr (handler_builder, cbb);
3937 emit_handler_start (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef builder)
3939 MonoCompile *cfg = ctx->cfg;
3940 LLVMValueRef *values = ctx->values;
3941 LLVMModuleRef lmodule = ctx->lmodule;
3942 BBInfo *bblocks = ctx->bblocks;
3944 LLVMValueRef personality;
3945 LLVMValueRef landing_pad;
3946 LLVMBasicBlockRef target_bb;
3948 static int ti_generator;
3950 LLVMValueRef type_info;
3954 // <resultval> = landingpad <somety> personality <type> <pers_fn> <clause>+
3956 if (cfg->compile_aot) {
3957 /* Use a dummy personality function */
3958 personality = LLVMGetNamedFunction (lmodule, "mono_personality");
3959 g_assert (personality);
3961 #if LLVM_API_VERSION > 100
3962 LLVMTypeRef personality_type = LLVMFunctionType (LLVMInt32Type (), NULL, 0, TRUE);
3963 personality = LLVMAddFunction (ctx->lmodule, "mono_personality", personality_type);
3964 LLVMAddFunctionAttr (personality, LLVMNoUnwindAttribute);
3965 LLVMBasicBlockRef entry_bb = LLVMAppendBasicBlock (personality, "ENTRY");
3966 LLVMBuilderRef builder2 = LLVMCreateBuilder ();
3967 LLVMPositionBuilderAtEnd (builder2, entry_bb);
3968 LLVMBuildRet (builder2, LLVMConstInt (LLVMInt32Type (), 0, FALSE));
3970 static gint32 mapping_inited;
3972 personality = LLVMGetNamedFunction (lmodule, "mono_personality");
3974 if (InterlockedCompareExchange (&mapping_inited, 1, 0) == 0)
3975 LLVMAddGlobalMapping (ctx->module->ee, personality, (gpointer)mono_personality);
3979 i8ptr = LLVMPointerType (LLVMInt8Type (), 0);
3981 clause_index = (mono_get_block_region_notry (cfg, bb->region) >> 8) - 1;
3984 * Create the type info
3986 sprintf (ti_name, "type_info_%d", ti_generator);
3989 if (cfg->compile_aot) {
3990 /* decode_eh_frame () in aot-runtime.c will decode this */
3991 type_info = LLVMAddGlobal (lmodule, LLVMInt32Type (), ti_name);
3992 LLVMSetInitializer (type_info, LLVMConstInt (LLVMInt32Type (), clause_index, FALSE));
3995 * These symbols are not really used, the clause_index is embedded into the EH tables generated by DwarfMonoException in LLVM.
3997 LLVMSetLinkage (type_info, LLVMInternalLinkage);
3999 #if LLVM_API_VERSION > 100
4000 type_info = LLVMAddGlobal (lmodule, LLVMInt32Type (), ti_name);
4001 LLVMSetInitializer (type_info, LLVMConstInt (LLVMInt32Type (), clause_index, FALSE));
4006 * After the cfg mempool is freed, the type info will point to stale memory,
4007 * but this is not a problem, since we decode it once in exception_cb during
4010 ti = (gint32*)mono_mempool_alloc (cfg->mempool, sizeof (gint32));
4011 *(gint32*)ti = clause_index;
4013 type_info = LLVMAddGlobal (lmodule, i8ptr, ti_name);
4015 LLVMAddGlobalMapping (ctx->module->ee, type_info, ti);
4020 LLVMTypeRef members [2], ret_type;
4022 members [0] = i8ptr;
4023 members [1] = LLVMInt32Type ();
4024 ret_type = LLVMStructType (members, 2, FALSE);
4026 landing_pad = LLVMBuildLandingPad (builder, ret_type, personality, 1, "");
4027 LLVMAddClause (landing_pad, type_info);
4029 /* Store the exception into the exvar */
4031 LLVMBuildStore (builder, convert (ctx, LLVMBuildExtractValue (builder, landing_pad, 0, "ex_obj"), ObjRefType ()), ctx->ex_var);
4035 * LLVM throw sites are associated with a one landing pad, and LLVM generated
4036 * code expects control to be transferred to this landing pad even in the
4037 * presence of nested clauses. The landing pad needs to branch to the landing
4038 * pads belonging to nested clauses based on the selector value returned by
4039 * the landing pad instruction, which is passed to the landing pad in a
4040 * register by the EH code.
4042 target_bb = bblocks [bb->block_num].call_handler_target_bb;
4043 g_assert (target_bb);
4046 * Branch to the correct landing pad
4048 LLVMValueRef ex_selector = LLVMBuildExtractValue (builder, landing_pad, 1, "ex_selector");
4049 LLVMValueRef switch_ins = LLVMBuildSwitch (builder, ex_selector, target_bb, 0);
4051 for (l = ctx->nested_in [clause_index]; l; l = l->next) {
4052 int nesting_clause_index = GPOINTER_TO_INT (l->data);
4053 MonoBasicBlock *handler_bb;
4055 handler_bb = (MonoBasicBlock*)g_hash_table_lookup (ctx->clause_to_handler, GINT_TO_POINTER (nesting_clause_index));
4056 g_assert (handler_bb);
4058 g_assert (ctx->bblocks [handler_bb->block_num].call_handler_target_bb);
4059 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), nesting_clause_index, FALSE), ctx->bblocks [handler_bb->block_num].call_handler_target_bb);
4062 /* Start a new bblock which CALL_HANDLER can branch to */
4063 target_bb = bblocks [bb->block_num].call_handler_target_bb;
4065 ctx->builder = builder = create_builder (ctx);
4066 LLVMPositionBuilderAtEnd (ctx->builder, target_bb);
4068 ctx->bblocks [bb->block_num].end_bblock = target_bb;
4070 /* Store the exception into the IL level exvar */
4071 if (bb->in_scount == 1) {
4072 g_assert (bb->in_scount == 1);
4073 exvar = bb->in_stack [0];
4075 // FIXME: This is shared with filter clauses ?
4076 g_assert (!values [exvar->dreg]);
4078 g_assert (ctx->ex_var);
4079 values [exvar->dreg] = LLVMBuildLoad (builder, ctx->ex_var, "");
4080 emit_volatile_store (ctx, exvar->dreg);
4086 process_bb (EmitContext *ctx, MonoBasicBlock *bb)
4088 MonoCompile *cfg = ctx->cfg;
4089 MonoMethodSignature *sig = ctx->sig;
4090 LLVMValueRef method = ctx->lmethod;
4091 LLVMValueRef *values = ctx->values;
4092 LLVMValueRef *addresses = ctx->addresses;
4093 LLVMCallInfo *linfo = ctx->linfo;
4094 BBInfo *bblocks = ctx->bblocks;
4096 LLVMBasicBlockRef cbb;
4097 LLVMBuilderRef builder, starting_builder;
4098 gboolean has_terminator;
4100 LLVMValueRef lhs, rhs;
4103 cbb = get_end_bb (ctx, bb);
4105 builder = create_builder (ctx);
4106 ctx->builder = builder;
4107 LLVMPositionBuilderAtEnd (builder, cbb);
4112 if (bb->flags & BB_EXCEPTION_HANDLER) {
4113 if (!ctx->llvm_only && !bblocks [bb->block_num].invoke_target) {
4114 set_failure (ctx, "handler without invokes");
4119 emit_llvmonly_handler_start (ctx, bb, cbb);
4121 emit_handler_start (ctx, bb, builder);
4124 builder = ctx->builder;
4127 has_terminator = FALSE;
4128 starting_builder = builder;
4129 for (ins = bb->code; ins; ins = ins->next) {
4130 const char *spec = LLVM_INS_INFO (ins->opcode);
4132 char dname_buf [128];
4134 emit_dbg_loc (ctx, builder, ins->cil_code);
4139 * Some steps in llc are non-linear in the size of basic blocks, see #5714.
4140 * Start a new bblock. If the llvm optimization passes merge these, we
4141 * can work around that by doing a volatile load + cond branch from
4142 * localloc-ed memory.
4144 //set_failure (ctx, "basic block too long");
4145 cbb = gen_bb (ctx, "CONT_LONG_BB");
4146 LLVMBuildBr (ctx->builder, cbb);
4147 ctx->builder = builder = create_builder (ctx);
4148 LLVMPositionBuilderAtEnd (builder, cbb);
4149 ctx->bblocks [bb->block_num].end_bblock = cbb;
4154 /* There could be instructions after a terminator, skip them */
4157 if (spec [MONO_INST_DEST] != ' ' && !MONO_IS_STORE_MEMBASE (ins)) {
4158 sprintf (dname_buf, "t%d", ins->dreg);
4162 if (spec [MONO_INST_SRC1] != ' ' && spec [MONO_INST_SRC1] != 'v') {
4163 MonoInst *var = get_vreg_to_inst (cfg, ins->sreg1);
4165 if (var && var->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT) && var->opcode != OP_GSHAREDVT_ARG_REGOFFSET) {
4166 lhs = emit_volatile_load (ctx, ins->sreg1);
4168 /* It is ok for SETRET to have an uninitialized argument */
4169 if (!values [ins->sreg1] && ins->opcode != OP_SETRET) {
4170 set_failure (ctx, "sreg1");
4173 lhs = values [ins->sreg1];
4179 if (spec [MONO_INST_SRC2] != ' ' && spec [MONO_INST_SRC2] != ' ') {
4180 MonoInst *var = get_vreg_to_inst (cfg, ins->sreg2);
4181 if (var && var->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT)) {
4182 rhs = emit_volatile_load (ctx, ins->sreg2);
4184 if (!values [ins->sreg2]) {
4185 set_failure (ctx, "sreg2");
4188 rhs = values [ins->sreg2];
4194 //mono_print_ins (ins);
4195 switch (ins->opcode) {
4198 case OP_LIVERANGE_START:
4199 case OP_LIVERANGE_END:
4202 values [ins->dreg] = LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE);
4205 #if SIZEOF_VOID_P == 4
4206 values [ins->dreg] = LLVMConstInt (LLVMInt64Type (), GET_LONG_IMM (ins), FALSE);
4208 values [ins->dreg] = LLVMConstInt (LLVMInt64Type (), (gint64)ins->inst_c0, FALSE);
4212 values [ins->dreg] = LLVMConstReal (LLVMDoubleType (), *(double*)ins->inst_p0);
4216 values [ins->dreg] = LLVMConstReal (LLVMFloatType (), *(float*)ins->inst_p0);
4218 values [ins->dreg] = LLVMConstFPExt (LLVMConstReal (LLVMFloatType (), *(float*)ins->inst_p0), LLVMDoubleType ());
4220 case OP_DUMMY_ICONST:
4221 values [ins->dreg] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
4223 case OP_DUMMY_I8CONST:
4224 values [ins->dreg] = LLVMConstInt (LLVMInt64Type (), 0, FALSE);
4226 case OP_DUMMY_R8CONST:
4227 values [ins->dreg] = LLVMConstReal (LLVMDoubleType (), 0.0f);
4230 LLVMBasicBlockRef target_bb = get_bb (ctx, ins->inst_target_bb);
4231 LLVMBuildBr (builder, target_bb);
4232 has_terminator = TRUE;
4239 LLVMBasicBlockRef new_bb;
4240 LLVMBuilderRef new_builder;
4242 // The default branch is already handled
4243 // FIXME: Handle it here
4245 /* Start new bblock */
4246 sprintf (bb_name, "SWITCH_DEFAULT_BB%d", ctx->default_index ++);
4247 new_bb = LLVMAppendBasicBlock (ctx->lmethod, bb_name);
4249 lhs = convert (ctx, lhs, LLVMInt32Type ());
4250 v = LLVMBuildSwitch (builder, lhs, new_bb, GPOINTER_TO_UINT (ins->klass));
4251 for (i = 0; i < GPOINTER_TO_UINT (ins->klass); ++i) {
4252 MonoBasicBlock *target_bb = ins->inst_many_bb [i];
4254 LLVMAddCase (v, LLVMConstInt (LLVMInt32Type (), i, FALSE), get_bb (ctx, target_bb));
4257 new_builder = create_builder (ctx);
4258 LLVMPositionBuilderAtEnd (new_builder, new_bb);
4259 LLVMBuildUnreachable (new_builder);
4261 has_terminator = TRUE;
4262 g_assert (!ins->next);
4268 switch (linfo->ret.storage) {
4269 case LLVMArgVtypeInReg: {
4270 LLVMTypeRef ret_type = LLVMGetReturnType (LLVMGetElementType (LLVMTypeOf (method)));
4271 LLVMValueRef val, addr, retval;
4274 retval = LLVMGetUndef (ret_type);
4276 if (!addresses [ins->sreg1]) {
4278 * The return type is an LLVM vector type, have to convert between it and the
4279 * real return type which is a struct type.
4281 g_assert (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (sig->ret)));
4282 /* Convert to 2xi64 first */
4283 val = LLVMBuildBitCast (builder, values [ins->sreg1], LLVMVectorType (IntPtrType (), 2), "");
4285 for (i = 0; i < 2; ++i) {
4286 if (linfo->ret.pair_storage [i] == LLVMArgInIReg) {
4287 retval = LLVMBuildInsertValue (builder, retval, LLVMBuildExtractElement (builder, val, LLVMConstInt (LLVMInt32Type (), i, FALSE), ""), i, "");
4289 g_assert (linfo->ret.pair_storage [i] == LLVMArgNone);
4293 addr = LLVMBuildBitCast (builder, addresses [ins->sreg1], LLVMPointerType (ret_type, 0), "");
4294 for (i = 0; i < 2; ++i) {
4295 if (linfo->ret.pair_storage [i] == LLVMArgInIReg) {
4296 LLVMValueRef indexes [2], part_addr;
4298 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
4299 indexes [1] = LLVMConstInt (LLVMInt32Type (), i, FALSE);
4300 part_addr = LLVMBuildGEP (builder, addr, indexes, 2, "");
4302 retval = LLVMBuildInsertValue (builder, retval, LLVMBuildLoad (builder, part_addr, ""), i, "");
4304 g_assert (linfo->ret.pair_storage [i] == LLVMArgNone);
4308 LLVMBuildRet (builder, retval);
4311 case LLVMArgVtypeAsScalar: {
4312 LLVMTypeRef ret_type = LLVMGetReturnType (LLVMGetElementType (LLVMTypeOf (method)));
4313 LLVMValueRef retval;
4315 g_assert (addresses [ins->sreg1]);
4317 retval = LLVMBuildLoad (builder, LLVMBuildBitCast (builder, addresses [ins->sreg1], LLVMPointerType (ret_type, 0), ""), "");
4318 LLVMBuildRet (builder, retval);
4321 case LLVMArgVtypeByVal: {
4322 LLVMValueRef retval;
4324 g_assert (addresses [ins->sreg1]);
4325 retval = LLVMBuildLoad (builder, addresses [ins->sreg1], "");
4326 LLVMBuildRet (builder, retval);
4329 case LLVMArgVtypeByRef: {
4330 LLVMBuildRetVoid (builder);
4333 case LLVMArgGsharedvtFixed: {
4334 LLVMTypeRef ret_type = type_to_llvm_type (ctx, sig->ret);
4335 /* The return value is in lhs, need to store to the vret argument */
4336 /* sreg1 might not be set */
4338 g_assert (cfg->vret_addr);
4339 g_assert (values [cfg->vret_addr->dreg]);
4340 LLVMBuildStore (builder, convert (ctx, lhs, ret_type), convert (ctx, values [cfg->vret_addr->dreg], LLVMPointerType (ret_type, 0)));
4342 LLVMBuildRetVoid (builder);
4345 case LLVMArgGsharedvtFixedVtype: {
4347 LLVMBuildRetVoid (builder);
4350 case LLVMArgGsharedvtVariable: {
4352 LLVMBuildRetVoid (builder);
4355 case LLVMArgVtypeRetAddr: {
4356 LLVMBuildRetVoid (builder);
4359 case LLVMArgFpStruct: {
4360 LLVMTypeRef ret_type = LLVMGetReturnType (LLVMGetElementType (LLVMTypeOf (method)));
4361 LLVMValueRef retval;
4363 g_assert (addresses [ins->sreg1]);
4364 retval = LLVMBuildLoad (builder, convert (ctx, addresses [ins->sreg1], LLVMPointerType (ret_type, 0)), "");
4365 LLVMBuildRet (builder, retval);
4369 case LLVMArgNormal: {
4370 if (!lhs || ctx->is_dead [ins->sreg1]) {
4372 * The method did not set its return value, probably because it
4373 * ends with a throw.
4376 LLVMBuildRetVoid (builder);
4378 LLVMBuildRet (builder, LLVMConstNull (type_to_llvm_type (ctx, sig->ret)));
4380 LLVMBuildRet (builder, convert (ctx, lhs, type_to_llvm_type (ctx, sig->ret)));
4382 has_terminator = TRUE;
4386 g_assert_not_reached ();
4395 case OP_ICOMPARE_IMM:
4396 case OP_LCOMPARE_IMM:
4397 case OP_COMPARE_IMM: {
4399 LLVMValueRef cmp, args [16];
4400 gboolean likely = (ins->flags & MONO_INST_LIKELY) != 0;
4402 if (ins->next->opcode == OP_NOP)
4405 if (ins->next->opcode == OP_BR)
4406 /* The comparison result is not needed */
4409 rel = mono_opcode_to_cond (ins->next->opcode);
4411 if (ins->opcode == OP_ICOMPARE_IMM) {
4412 lhs = convert (ctx, lhs, LLVMInt32Type ());
4413 rhs = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
4415 if (ins->opcode == OP_LCOMPARE_IMM) {
4416 lhs = convert (ctx, lhs, LLVMInt64Type ());
4417 rhs = LLVMConstInt (LLVMInt64Type (), GET_LONG_IMM (ins), FALSE);
4419 if (ins->opcode == OP_LCOMPARE) {
4420 lhs = convert (ctx, lhs, LLVMInt64Type ());
4421 rhs = convert (ctx, rhs, LLVMInt64Type ());
4423 if (ins->opcode == OP_ICOMPARE) {
4424 lhs = convert (ctx, lhs, LLVMInt32Type ());
4425 rhs = convert (ctx, rhs, LLVMInt32Type ());
4429 if (LLVMGetTypeKind (LLVMTypeOf (lhs)) == LLVMPointerTypeKind)
4430 rhs = convert (ctx, rhs, LLVMTypeOf (lhs));
4431 else if (LLVMGetTypeKind (LLVMTypeOf (rhs)) == LLVMPointerTypeKind)
4432 lhs = convert (ctx, lhs, LLVMTypeOf (rhs));
4435 /* We use COMPARE+SETcc/Bcc, llvm uses SETcc+br cond */
4436 if (ins->opcode == OP_FCOMPARE) {
4437 cmp = LLVMBuildFCmp (builder, fpcond_to_llvm_cond [rel], convert (ctx, lhs, LLVMDoubleType ()), convert (ctx, rhs, LLVMDoubleType ()), "");
4438 } else if (ins->opcode == OP_RCOMPARE) {
4439 cmp = LLVMBuildFCmp (builder, fpcond_to_llvm_cond [rel], convert (ctx, lhs, LLVMFloatType ()), convert (ctx, rhs, LLVMFloatType ()), "");
4440 } else if (ins->opcode == OP_COMPARE_IMM) {
4441 if (LLVMGetTypeKind (LLVMTypeOf (lhs)) == LLVMPointerTypeKind && ins->inst_imm == 0)
4442 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], lhs, LLVMConstNull (LLVMTypeOf (lhs)), "");
4444 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE), "");
4445 } else if (ins->opcode == OP_LCOMPARE_IMM) {
4446 if (SIZEOF_REGISTER == 4 && COMPILE_LLVM (cfg)) {
4447 /* The immediate is encoded in two fields */
4448 guint64 l = ((guint64)(guint32)ins->inst_offset << 32) | ((guint32)ins->inst_imm);
4449 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, LLVMInt64Type ()), LLVMConstInt (LLVMInt64Type (), l, FALSE), "");
4451 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, LLVMInt64Type ()), LLVMConstInt (LLVMInt64Type (), ins->inst_imm, FALSE), "");
4454 else if (ins->opcode == OP_COMPARE) {
4455 if (LLVMGetTypeKind (LLVMTypeOf (lhs)) == LLVMPointerTypeKind && LLVMTypeOf (lhs) == LLVMTypeOf (rhs))
4456 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], lhs, rhs, "");
4458 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, IntPtrType ()), convert (ctx, rhs, IntPtrType ()), "");
4460 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], lhs, rhs, "");
4464 args [1] = LLVMConstInt (LLVMInt1Type (), 1, FALSE);
4465 cmp = LLVMBuildCall (ctx->builder, get_intrinsic (ctx, "llvm.expect.i1"), args, 2, "");
4468 if (MONO_IS_COND_BRANCH_OP (ins->next)) {
4469 if (ins->next->inst_true_bb == ins->next->inst_false_bb) {
4471 * If the target bb contains PHI instructions, LLVM requires
4472 * two PHI entries for this bblock, while we only generate one.
4473 * So convert this to an unconditional bblock. (bxc #171).
4475 LLVMBuildBr (builder, get_bb (ctx, ins->next->inst_true_bb));
4477 LLVMBuildCondBr (builder, cmp, get_bb (ctx, ins->next->inst_true_bb), get_bb (ctx, ins->next->inst_false_bb));
4479 has_terminator = TRUE;
4480 } else if (MONO_IS_SETCC (ins->next)) {
4481 sprintf (dname_buf, "t%d", ins->next->dreg);
4483 values [ins->next->dreg] = LLVMBuildZExt (builder, cmp, LLVMInt32Type (), dname);
4485 /* Add stores for volatile variables */
4486 emit_volatile_store (ctx, ins->next->dreg);
4487 } else if (MONO_IS_COND_EXC (ins->next)) {
4488 emit_cond_system_exception (ctx, bb, (const char*)ins->next->inst_p1, cmp);
4491 builder = ctx->builder;
4493 set_failure (ctx, "next");
4511 rel = mono_opcode_to_cond (ins->opcode);
4513 cmp = LLVMBuildFCmp (builder, fpcond_to_llvm_cond [rel], convert (ctx, lhs, LLVMDoubleType ()), convert (ctx, rhs, LLVMDoubleType ()), "");
4514 values [ins->dreg] = LLVMBuildZExt (builder, cmp, LLVMInt32Type (), dname);
4525 rel = mono_opcode_to_cond (ins->opcode);
4527 cmp = LLVMBuildFCmp (builder, fpcond_to_llvm_cond [rel], convert (ctx, lhs, LLVMFloatType ()), convert (ctx, rhs, LLVMFloatType ()), "");
4528 values [ins->dreg] = LLVMBuildZExt (builder, cmp, LLVMInt32Type (), dname);
4536 gboolean empty = TRUE;
4538 /* Check that all input bblocks really branch to us */
4539 for (i = 0; i < bb->in_count; ++i) {
4540 if (bb->in_bb [i]->last_ins && bb->in_bb [i]->last_ins->opcode == OP_NOT_REACHED)
4541 ins->inst_phi_args [i + 1] = -1;
4547 /* LLVM doesn't like phi instructions with zero operands */
4548 ctx->is_dead [ins->dreg] = TRUE;
4552 /* Created earlier, insert it now */
4553 LLVMInsertIntoBuilder (builder, values [ins->dreg]);
4555 for (i = 0; i < ins->inst_phi_args [0]; i++) {
4556 int sreg1 = ins->inst_phi_args [i + 1];
4560 * Count the number of times the incoming bblock branches to us,
4561 * since llvm requires a separate entry for each.
4563 if (bb->in_bb [i]->last_ins && bb->in_bb [i]->last_ins->opcode == OP_SWITCH) {
4564 MonoInst *switch_ins = bb->in_bb [i]->last_ins;
4567 for (j = 0; j < GPOINTER_TO_UINT (switch_ins->klass); ++j) {
4568 if (switch_ins->inst_many_bb [j] == bb)
4575 /* Remember for later */
4576 for (j = 0; j < count; ++j) {
4577 PhiNode *node = (PhiNode*)mono_mempool_alloc0 (ctx->mempool, sizeof (PhiNode));
4580 node->in_bb = bb->in_bb [i];
4582 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);
4592 values [ins->dreg] = lhs;
4596 MonoInst *var = get_vreg_to_inst (cfg, ins->dreg);
4599 values [ins->dreg] = lhs;
4601 if (var && var->klass->byval_arg.type == MONO_TYPE_R4) {
4603 * This is added by the spilling pass in case of the JIT,
4604 * but we have to do it ourselves.
4606 values [ins->dreg] = convert (ctx, values [ins->dreg], LLVMFloatType ());
4610 case OP_MOVE_F_TO_I4: {
4611 values [ins->dreg] = LLVMBuildBitCast (builder, LLVMBuildFPTrunc (builder, lhs, LLVMFloatType (), ""), LLVMInt32Type (), "");
4614 case OP_MOVE_I4_TO_F: {
4615 values [ins->dreg] = LLVMBuildFPExt (builder, LLVMBuildBitCast (builder, lhs, LLVMFloatType (), ""), LLVMDoubleType (), "");
4618 case OP_MOVE_F_TO_I8: {
4619 values [ins->dreg] = LLVMBuildBitCast (builder, lhs, LLVMInt64Type (), "");
4622 case OP_MOVE_I8_TO_F: {
4623 values [ins->dreg] = LLVMBuildBitCast (builder, lhs, LLVMDoubleType (), "");
4656 lhs = convert (ctx, lhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
4657 rhs = convert (ctx, rhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
4659 emit_div_check (ctx, builder, bb, ins, lhs, rhs);
4662 builder = ctx->builder;
4664 switch (ins->opcode) {
4667 values [ins->dreg] = LLVMBuildAdd (builder, lhs, rhs, dname);
4671 values [ins->dreg] = LLVMBuildSub (builder, lhs, rhs, dname);
4675 values [ins->dreg] = LLVMBuildMul (builder, lhs, rhs, dname);
4679 values [ins->dreg] = LLVMBuildSRem (builder, lhs, rhs, dname);
4683 values [ins->dreg] = LLVMBuildURem (builder, lhs, rhs, dname);
4687 values [ins->dreg] = LLVMBuildSDiv (builder, lhs, rhs, dname);
4691 values [ins->dreg] = LLVMBuildUDiv (builder, lhs, rhs, dname);
4695 values [ins->dreg] = LLVMBuildFDiv (builder, lhs, rhs, dname);
4699 values [ins->dreg] = LLVMBuildAnd (builder, lhs, rhs, dname);
4703 values [ins->dreg] = LLVMBuildOr (builder, lhs, rhs, dname);
4707 values [ins->dreg] = LLVMBuildXor (builder, lhs, rhs, dname);
4711 values [ins->dreg] = LLVMBuildShl (builder, lhs, rhs, dname);
4715 values [ins->dreg] = LLVMBuildAShr (builder, lhs, rhs, dname);
4719 values [ins->dreg] = LLVMBuildLShr (builder, lhs, rhs, dname);
4723 values [ins->dreg] = LLVMBuildFAdd (builder, lhs, rhs, dname);
4726 values [ins->dreg] = LLVMBuildFSub (builder, lhs, rhs, dname);
4729 values [ins->dreg] = LLVMBuildFMul (builder, lhs, rhs, dname);
4733 g_assert_not_reached ();
4740 lhs = convert (ctx, lhs, LLVMFloatType ());
4741 rhs = convert (ctx, rhs, LLVMFloatType ());
4742 switch (ins->opcode) {
4744 values [ins->dreg] = LLVMBuildFAdd (builder, lhs, rhs, dname);
4747 values [ins->dreg] = LLVMBuildFSub (builder, lhs, rhs, dname);
4750 values [ins->dreg] = LLVMBuildFMul (builder, lhs, rhs, dname);
4753 values [ins->dreg] = LLVMBuildFDiv (builder, lhs, rhs, dname);
4756 g_assert_not_reached ();
4765 case OP_IREM_UN_IMM:
4767 case OP_IDIV_UN_IMM:
4773 case OP_ISHR_UN_IMM:
4783 case OP_LSHR_UN_IMM:
4789 case OP_SHR_UN_IMM: {
4792 if (spec [MONO_INST_SRC1] == 'l') {
4793 imm = LLVMConstInt (LLVMInt64Type (), GET_LONG_IMM (ins), FALSE);
4795 imm = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
4798 emit_div_check (ctx, builder, bb, ins, lhs, imm);
4801 builder = ctx->builder;
4803 #if SIZEOF_VOID_P == 4
4804 if (ins->opcode == OP_LSHL_IMM || ins->opcode == OP_LSHR_IMM || ins->opcode == OP_LSHR_UN_IMM)
4805 imm = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
4808 if (LLVMGetTypeKind (LLVMTypeOf (lhs)) == LLVMPointerTypeKind)
4809 lhs = convert (ctx, lhs, IntPtrType ());
4810 imm = convert (ctx, imm, LLVMTypeOf (lhs));
4811 switch (ins->opcode) {
4815 values [ins->dreg] = LLVMBuildAdd (builder, lhs, imm, dname);
4819 values [ins->dreg] = LLVMBuildSub (builder, lhs, imm, dname);
4824 values [ins->dreg] = LLVMBuildMul (builder, lhs, imm, dname);
4828 values [ins->dreg] = LLVMBuildSDiv (builder, lhs, imm, dname);
4830 case OP_IDIV_UN_IMM:
4831 case OP_LDIV_UN_IMM:
4832 values [ins->dreg] = LLVMBuildUDiv (builder, lhs, imm, dname);
4836 values [ins->dreg] = LLVMBuildSRem (builder, lhs, imm, dname);
4838 case OP_IREM_UN_IMM:
4839 values [ins->dreg] = LLVMBuildURem (builder, lhs, imm, dname);
4844 values [ins->dreg] = LLVMBuildAnd (builder, lhs, imm, dname);
4848 values [ins->dreg] = LLVMBuildOr (builder, lhs, imm, dname);
4852 values [ins->dreg] = LLVMBuildXor (builder, lhs, imm, dname);
4857 values [ins->dreg] = LLVMBuildShl (builder, lhs, imm, dname);
4862 values [ins->dreg] = LLVMBuildAShr (builder, lhs, imm, dname);
4864 case OP_ISHR_UN_IMM:
4865 /* This is used to implement conv.u4, so the lhs could be an i8 */
4866 lhs = convert (ctx, lhs, LLVMInt32Type ());
4867 imm = convert (ctx, imm, LLVMInt32Type ());
4868 values [ins->dreg] = LLVMBuildLShr (builder, lhs, imm, dname);
4870 case OP_LSHR_UN_IMM:
4872 values [ins->dreg] = LLVMBuildLShr (builder, lhs, imm, dname);
4875 g_assert_not_reached ();
4880 values [ins->dreg] = LLVMBuildSub (builder, LLVMConstInt (LLVMInt32Type (), 0, FALSE), convert (ctx, lhs, LLVMInt32Type ()), dname);
4883 values [ins->dreg] = LLVMBuildSub (builder, LLVMConstInt (LLVMInt64Type (), 0, FALSE), lhs, dname);
4886 lhs = convert (ctx, lhs, LLVMDoubleType ());
4887 values [ins->dreg] = LLVMBuildFSub (builder, LLVMConstReal (LLVMDoubleType (), 0.0), lhs, dname);
4890 lhs = convert (ctx, lhs, LLVMFloatType ());
4891 values [ins->dreg] = LLVMBuildFSub (builder, LLVMConstReal (LLVMFloatType (), 0.0), lhs, dname);
4894 guint32 v = 0xffffffff;
4895 values [ins->dreg] = LLVMBuildXor (builder, LLVMConstInt (LLVMInt32Type (), v, FALSE), convert (ctx, lhs, LLVMInt32Type ()), dname);
4899 guint64 v = 0xffffffffffffffffLL;
4900 values [ins->dreg] = LLVMBuildXor (builder, LLVMConstInt (LLVMInt64Type (), v, FALSE), lhs, dname);
4903 #if defined(TARGET_X86) || defined(TARGET_AMD64)
4905 LLVMValueRef v1, v2;
4907 v1 = LLVMBuildMul (builder, convert (ctx, rhs, IntPtrType ()), LLVMConstInt (IntPtrType (), (1 << ins->backend.shift_amount), FALSE), "");
4908 v2 = LLVMBuildAdd (builder, convert (ctx, lhs, IntPtrType ()), v1, "");
4909 values [ins->dreg] = LLVMBuildAdd (builder, v2, LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE), dname);
4914 case OP_ICONV_TO_I1:
4915 case OP_ICONV_TO_I2:
4916 case OP_ICONV_TO_I4:
4917 case OP_ICONV_TO_U1:
4918 case OP_ICONV_TO_U2:
4919 case OP_ICONV_TO_U4:
4920 case OP_LCONV_TO_I1:
4921 case OP_LCONV_TO_I2:
4922 case OP_LCONV_TO_U1:
4923 case OP_LCONV_TO_U2:
4924 case OP_LCONV_TO_U4: {
4927 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);
4929 /* Have to do two casts since our vregs have type int */
4930 v = LLVMBuildTrunc (builder, lhs, op_to_llvm_type (ins->opcode), "");
4932 values [ins->dreg] = LLVMBuildSExt (builder, v, LLVMInt32Type (), dname);
4934 values [ins->dreg] = LLVMBuildZExt (builder, v, LLVMInt32Type (), dname);
4937 case OP_ICONV_TO_I8:
4938 values [ins->dreg] = LLVMBuildSExt (builder, lhs, LLVMInt64Type (), dname);
4940 case OP_ICONV_TO_U8:
4941 values [ins->dreg] = LLVMBuildZExt (builder, lhs, LLVMInt64Type (), dname);
4943 case OP_FCONV_TO_I4:
4944 case OP_RCONV_TO_I4:
4945 values [ins->dreg] = LLVMBuildFPToSI (builder, lhs, LLVMInt32Type (), dname);
4947 case OP_FCONV_TO_I1:
4948 case OP_RCONV_TO_I1:
4949 values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildFPToSI (builder, lhs, LLVMInt8Type (), dname), LLVMInt32Type (), "");
4951 case OP_FCONV_TO_U1:
4952 case OP_RCONV_TO_U1:
4953 values [ins->dreg] = LLVMBuildZExt (builder, LLVMBuildTrunc (builder, LLVMBuildFPToUI (builder, lhs, IntPtrType (), dname), LLVMInt8Type (), ""), LLVMInt32Type (), "");
4955 case OP_FCONV_TO_I2:
4956 case OP_RCONV_TO_I2:
4957 values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildFPToSI (builder, lhs, LLVMInt16Type (), dname), LLVMInt32Type (), "");
4959 case OP_FCONV_TO_U2:
4960 case OP_RCONV_TO_U2:
4961 values [ins->dreg] = LLVMBuildZExt (builder, LLVMBuildFPToUI (builder, lhs, LLVMInt16Type (), dname), LLVMInt32Type (), "");
4963 case OP_RCONV_TO_U4:
4964 values [ins->dreg] = LLVMBuildFPToUI (builder, lhs, LLVMInt32Type (), dname);
4966 case OP_FCONV_TO_I8:
4967 case OP_RCONV_TO_I8:
4968 values [ins->dreg] = LLVMBuildFPToSI (builder, lhs, LLVMInt64Type (), dname);
4971 values [ins->dreg] = LLVMBuildFPToSI (builder, lhs, IntPtrType (), dname);
4973 case OP_ICONV_TO_R8:
4974 case OP_LCONV_TO_R8:
4975 values [ins->dreg] = LLVMBuildSIToFP (builder, lhs, LLVMDoubleType (), dname);
4977 case OP_ICONV_TO_R_UN:
4978 case OP_LCONV_TO_R_UN:
4979 values [ins->dreg] = LLVMBuildUIToFP (builder, lhs, LLVMDoubleType (), dname);
4981 #if SIZEOF_VOID_P == 4
4984 case OP_LCONV_TO_I4:
4985 values [ins->dreg] = LLVMBuildTrunc (builder, lhs, LLVMInt32Type (), dname);
4987 case OP_ICONV_TO_R4:
4988 case OP_LCONV_TO_R4:
4989 v = LLVMBuildSIToFP (builder, lhs, LLVMFloatType (), "");
4991 values [ins->dreg] = v;
4993 values [ins->dreg] = LLVMBuildFPExt (builder, v, LLVMDoubleType (), dname);
4995 case OP_FCONV_TO_R4:
4996 v = LLVMBuildFPTrunc (builder, lhs, LLVMFloatType (), "");
4998 values [ins->dreg] = v;
5000 values [ins->dreg] = LLVMBuildFPExt (builder, v, LLVMDoubleType (), dname);
5002 case OP_RCONV_TO_R8:
5003 values [ins->dreg] = LLVMBuildFPExt (builder, lhs, LLVMDoubleType (), dname);
5005 case OP_RCONV_TO_R4:
5006 values [ins->dreg] = lhs;
5009 values [ins->dreg] = LLVMBuildSExt (builder, convert (ctx, lhs, LLVMInt32Type ()), LLVMInt64Type (), dname);
5012 values [ins->dreg] = LLVMBuildZExt (builder, convert (ctx, lhs, LLVMInt32Type ()), LLVMInt64Type (), dname);
5015 values [ins->dreg] = LLVMBuildTrunc (builder, lhs, LLVMInt32Type (), dname);
5017 case OP_LOCALLOC_IMM: {
5020 guint32 size = ins->inst_imm;
5021 size = (size + (MONO_ARCH_FRAME_ALIGNMENT - 1)) & ~ (MONO_ARCH_FRAME_ALIGNMENT - 1);
5023 v = mono_llvm_build_alloca (builder, LLVMInt8Type (), LLVMConstInt (LLVMInt32Type (), size, FALSE), MONO_ARCH_FRAME_ALIGNMENT, "");
5025 if (ins->flags & MONO_INST_INIT) {
5026 LLVMValueRef args [5];
5029 args [1] = LLVMConstInt (LLVMInt8Type (), 0, FALSE);
5030 args [2] = LLVMConstInt (LLVMInt32Type (), size, FALSE);
5031 args [3] = LLVMConstInt (LLVMInt32Type (), MONO_ARCH_FRAME_ALIGNMENT, FALSE);
5032 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
5033 LLVMBuildCall (builder, get_intrinsic (ctx, "llvm.memset.p0i8.i32"), args, 5, "");
5036 values [ins->dreg] = v;
5040 LLVMValueRef v, size;
5042 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), "");
5044 v = mono_llvm_build_alloca (builder, LLVMInt8Type (), size, MONO_ARCH_FRAME_ALIGNMENT, "");
5046 if (ins->flags & MONO_INST_INIT) {
5047 LLVMValueRef args [5];
5050 args [1] = LLVMConstInt (LLVMInt8Type (), 0, FALSE);
5052 args [3] = LLVMConstInt (LLVMInt32Type (), MONO_ARCH_FRAME_ALIGNMENT, FALSE);
5053 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
5054 LLVMBuildCall (builder, get_intrinsic (ctx, "llvm.memset.p0i8.i32"), args, 5, "");
5056 values [ins->dreg] = v;
5060 case OP_LOADI1_MEMBASE:
5061 case OP_LOADU1_MEMBASE:
5062 case OP_LOADI2_MEMBASE:
5063 case OP_LOADU2_MEMBASE:
5064 case OP_LOADI4_MEMBASE:
5065 case OP_LOADU4_MEMBASE:
5066 case OP_LOADI8_MEMBASE:
5067 case OP_LOADR4_MEMBASE:
5068 case OP_LOADR8_MEMBASE:
5069 case OP_LOAD_MEMBASE:
5077 LLVMValueRef base, index, addr;
5079 gboolean sext = FALSE, zext = FALSE;
5080 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
5082 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
5087 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)) {
5088 addr = LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE);
5093 if (ins->inst_offset == 0) {
5095 } else if (ins->inst_offset % size != 0) {
5096 /* Unaligned load */
5097 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset, FALSE);
5098 addr = LLVMBuildGEP (builder, convert (ctx, base, LLVMPointerType (LLVMInt8Type (), 0)), &index, 1, "");
5100 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
5101 addr = LLVMBuildGEP (builder, convert (ctx, base, LLVMPointerType (t, 0)), &index, 1, "");
5105 addr = convert (ctx, addr, LLVMPointerType (t, 0));
5107 values [ins->dreg] = emit_load (ctx, bb, &builder, size, addr, dname, is_volatile);
5109 if (!is_volatile && (ins->flags & MONO_INST_INVARIANT_LOAD)) {
5111 * These will signal LLVM that these loads do not alias any stores, and
5112 * they can't fail, allowing them to be hoisted out of loops.
5114 set_invariant_load_flag (values [ins->dreg]);
5115 #if LLVM_API_VERSION < 100
5116 set_metadata_flag (values [ins->dreg], "mono.nofail.load");
5121 values [ins->dreg] = LLVMBuildSExt (builder, values [ins->dreg], LLVMInt32Type (), dname);
5123 values [ins->dreg] = LLVMBuildZExt (builder, values [ins->dreg], LLVMInt32Type (), dname);
5124 else if (!cfg->r4fp && ins->opcode == OP_LOADR4_MEMBASE)
5125 values [ins->dreg] = LLVMBuildFPExt (builder, values [ins->dreg], LLVMDoubleType (), dname);
5129 case OP_STOREI1_MEMBASE_REG:
5130 case OP_STOREI2_MEMBASE_REG:
5131 case OP_STOREI4_MEMBASE_REG:
5132 case OP_STOREI8_MEMBASE_REG:
5133 case OP_STORER4_MEMBASE_REG:
5134 case OP_STORER8_MEMBASE_REG:
5135 case OP_STORE_MEMBASE_REG: {
5137 LLVMValueRef index, addr;
5139 gboolean sext = FALSE, zext = FALSE;
5140 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
5142 if (!values [ins->inst_destbasereg]) {
5143 set_failure (ctx, "inst_destbasereg");
5147 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
5149 if (ins->inst_offset % size != 0) {
5150 /* Unaligned store */
5151 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset, FALSE);
5152 addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (LLVMInt8Type (), 0)), &index, 1, "");
5154 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
5155 addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (t, 0)), &index, 1, "");
5157 emit_store (ctx, bb, &builder, size, convert (ctx, values [ins->sreg1], t), convert (ctx, addr, LLVMPointerType (t, 0)), is_volatile);
5161 case OP_STOREI1_MEMBASE_IMM:
5162 case OP_STOREI2_MEMBASE_IMM:
5163 case OP_STOREI4_MEMBASE_IMM:
5164 case OP_STOREI8_MEMBASE_IMM:
5165 case OP_STORE_MEMBASE_IMM: {
5167 LLVMValueRef index, addr;
5169 gboolean sext = FALSE, zext = FALSE;
5170 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
5172 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
5174 if (ins->inst_offset % size != 0) {
5175 /* Unaligned store */
5176 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset, FALSE);
5177 addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (LLVMInt8Type (), 0)), &index, 1, "");
5179 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
5180 addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (t, 0)), &index, 1, "");
5182 emit_store (ctx, bb, &builder, size, convert (ctx, LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE), t), convert (ctx, addr, LLVMPointerType (t, 0)), is_volatile);
5187 emit_load (ctx, bb, &builder, sizeof (gpointer), convert (ctx, lhs, LLVMPointerType (IntPtrType (), 0)), "", TRUE);
5189 case OP_OUTARG_VTRETADDR:
5197 case OP_VOIDCALL_MEMBASE:
5198 case OP_CALL_MEMBASE:
5199 case OP_LCALL_MEMBASE:
5200 case OP_FCALL_MEMBASE:
5201 case OP_RCALL_MEMBASE:
5202 case OP_VCALL_MEMBASE:
5203 case OP_VOIDCALL_REG:
5208 case OP_VCALL_REG: {
5209 process_call (ctx, bb, &builder, ins);
5214 LLVMValueRef indexes [2];
5215 MonoJumpInfo *tmp_ji, *ji;
5216 LLVMValueRef got_entry_addr;
5220 * FIXME: Can't allocate from the cfg mempool since that is freed if
5221 * the LLVM compile fails.
5223 tmp_ji = g_new0 (MonoJumpInfo, 1);
5224 tmp_ji->type = (MonoJumpInfoType)ins->inst_c1;
5225 tmp_ji->data.target = ins->inst_p0;
5227 ji = mono_aot_patch_info_dup (tmp_ji);
5230 ji->next = cfg->patch_info;
5231 cfg->patch_info = ji;
5233 //mono_add_patch_info (cfg, 0, (MonoJumpInfoType)ins->inst_i1, ins->inst_p0);
5234 got_offset = mono_aot_get_got_offset (cfg->patch_info);
5235 ctx->module->max_got_offset = MAX (ctx->module->max_got_offset, got_offset);
5236 if (!mono_aot_is_shared_got_offset (got_offset)) {
5237 //mono_print_ji (ji);
5239 ctx->has_got_access = TRUE;
5242 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
5243 indexes [1] = LLVMConstInt (LLVMInt32Type (), (gssize)got_offset, FALSE);
5244 got_entry_addr = LLVMBuildGEP (builder, ctx->module->got_var, indexes, 2, "");
5246 name = get_aotconst_name (ji->type, ji->data.target, got_offset);
5247 values [ins->dreg] = LLVMBuildLoad (builder, got_entry_addr, name);
5249 /* Can't use this in llvmonly mode since the got slots are initialized by the methods themselves */
5250 if (!cfg->llvm_only)
5251 set_invariant_load_flag (values [ins->dreg]);
5254 case OP_NOT_REACHED:
5255 LLVMBuildUnreachable (builder);
5256 has_terminator = TRUE;
5257 g_assert (bb->block_num < cfg->max_block_num);
5258 ctx->unreachable [bb->block_num] = TRUE;
5259 /* Might have instructions after this */
5261 MonoInst *next = ins->next;
5263 * FIXME: If later code uses the regs defined by these instructions,
5264 * compilation will fail.
5266 MONO_DELETE_INS (bb, next);
5270 MonoInst *var = ins->inst_i0;
5272 if (var->opcode == OP_VTARG_ADDR) {
5273 /* The variable contains the vtype address */
5274 values [ins->dreg] = values [var->dreg];
5275 } else if (var->opcode == OP_GSHAREDVT_LOCAL) {
5276 values [ins->dreg] = emit_gsharedvt_ldaddr (ctx, var->dreg);
5278 values [ins->dreg] = addresses [var->dreg];
5283 LLVMValueRef args [1];
5285 args [0] = convert (ctx, lhs, LLVMDoubleType ());
5286 values [ins->dreg] = LLVMBuildCall (builder, get_intrinsic (ctx, "llvm.sin.f64"), args, 1, dname);
5290 LLVMValueRef args [1];
5292 args [0] = convert (ctx, lhs, LLVMDoubleType ());
5293 values [ins->dreg] = LLVMBuildCall (builder, get_intrinsic (ctx, "llvm.cos.f64"), args, 1, dname);
5297 LLVMValueRef args [1];
5299 args [0] = convert (ctx, lhs, LLVMDoubleType ());
5300 values [ins->dreg] = LLVMBuildCall (builder, get_intrinsic (ctx, "llvm.sqrt.f64"), args, 1, dname);
5304 LLVMValueRef args [1];
5306 args [0] = convert (ctx, lhs, LLVMDoubleType ());
5307 values [ins->dreg] = LLVMBuildCall (builder, get_intrinsic (ctx, "fabs"), args, 1, dname);
5321 lhs = convert (ctx, lhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
5322 rhs = convert (ctx, rhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
5324 switch (ins->opcode) {
5327 v = LLVMBuildICmp (builder, LLVMIntSLE, lhs, rhs, "");
5331 v = LLVMBuildICmp (builder, LLVMIntSGE, lhs, rhs, "");
5335 v = LLVMBuildICmp (builder, LLVMIntULE, lhs, rhs, "");
5339 v = LLVMBuildICmp (builder, LLVMIntUGE, lhs, rhs, "");
5342 g_assert_not_reached ();
5345 values [ins->dreg] = LLVMBuildSelect (builder, v, lhs, rhs, dname);
5348 case OP_ATOMIC_EXCHANGE_I4:
5349 case OP_ATOMIC_EXCHANGE_I8: {
5350 LLVMValueRef args [2];
5353 if (ins->opcode == OP_ATOMIC_EXCHANGE_I4)
5354 t = LLVMInt32Type ();
5356 t = LLVMInt64Type ();
5358 g_assert (ins->inst_offset == 0);
5360 args [0] = convert (ctx, lhs, LLVMPointerType (t, 0));
5361 args [1] = convert (ctx, rhs, t);
5363 values [ins->dreg] = mono_llvm_build_atomic_rmw (builder, LLVM_ATOMICRMW_OP_XCHG, args [0], args [1]);
5366 case OP_ATOMIC_ADD_I4:
5367 case OP_ATOMIC_ADD_I8: {
5368 LLVMValueRef args [2];
5371 if (ins->opcode == OP_ATOMIC_ADD_I4)
5372 t = LLVMInt32Type ();
5374 t = LLVMInt64Type ();
5376 g_assert (ins->inst_offset == 0);
5378 args [0] = convert (ctx, lhs, LLVMPointerType (t, 0));
5379 args [1] = convert (ctx, rhs, t);
5380 values [ins->dreg] = LLVMBuildAdd (builder, mono_llvm_build_atomic_rmw (builder, LLVM_ATOMICRMW_OP_ADD, args [0], args [1]), args [1], dname);
5383 case OP_ATOMIC_CAS_I4:
5384 case OP_ATOMIC_CAS_I8: {
5385 LLVMValueRef args [3], val;
5388 if (ins->opcode == OP_ATOMIC_CAS_I4)
5389 t = LLVMInt32Type ();
5391 t = LLVMInt64Type ();
5393 args [0] = convert (ctx, lhs, LLVMPointerType (t, 0));
5395 args [1] = convert (ctx, values [ins->sreg3], t);
5397 args [2] = convert (ctx, values [ins->sreg2], t);
5398 val = mono_llvm_build_cmpxchg (builder, args [0], args [1], args [2]);
5399 /* cmpxchg returns a pair */
5400 values [ins->dreg] = LLVMBuildExtractValue (builder, val, 0, "");
5403 case OP_MEMORY_BARRIER: {
5404 mono_llvm_build_fence (builder, (BarrierKind) ins->backend.memory_barrier_kind);
5407 case OP_ATOMIC_LOAD_I1:
5408 case OP_ATOMIC_LOAD_I2:
5409 case OP_ATOMIC_LOAD_I4:
5410 case OP_ATOMIC_LOAD_I8:
5411 case OP_ATOMIC_LOAD_U1:
5412 case OP_ATOMIC_LOAD_U2:
5413 case OP_ATOMIC_LOAD_U4:
5414 case OP_ATOMIC_LOAD_U8:
5415 case OP_ATOMIC_LOAD_R4:
5416 case OP_ATOMIC_LOAD_R8: {
5417 set_failure (ctx, "atomic mono.load intrinsic");
5421 gboolean sext, zext;
5423 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
5424 BarrierKind barrier = (BarrierKind) ins->backend.memory_barrier_kind;
5425 LLVMValueRef index, addr;
5427 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
5432 if (ins->inst_offset != 0) {
5433 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
5434 addr = LLVMBuildGEP (builder, convert (ctx, lhs, LLVMPointerType (t, 0)), &index, 1, "");
5439 addr = convert (ctx, addr, LLVMPointerType (t, 0));
5441 values [ins->dreg] = emit_load_general (ctx, bb, &builder, size, addr, dname, is_volatile, barrier);
5444 values [ins->dreg] = LLVMBuildSExt (builder, values [ins->dreg], LLVMInt32Type (), dname);
5446 values [ins->dreg] = LLVMBuildZExt (builder, values [ins->dreg], LLVMInt32Type (), dname);
5450 case OP_ATOMIC_STORE_I1:
5451 case OP_ATOMIC_STORE_I2:
5452 case OP_ATOMIC_STORE_I4:
5453 case OP_ATOMIC_STORE_I8:
5454 case OP_ATOMIC_STORE_U1:
5455 case OP_ATOMIC_STORE_U2:
5456 case OP_ATOMIC_STORE_U4:
5457 case OP_ATOMIC_STORE_U8:
5458 case OP_ATOMIC_STORE_R4:
5459 case OP_ATOMIC_STORE_R8: {
5460 set_failure (ctx, "atomic mono.store intrinsic");
5464 gboolean sext, zext;
5466 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
5467 BarrierKind barrier = (BarrierKind) ins->backend.memory_barrier_kind;
5468 LLVMValueRef index, addr, value;
5470 if (!values [ins->inst_destbasereg]) {
5471 set_failure (ctx, "inst_destbasereg");
5475 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
5477 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
5478 addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (t, 0)), &index, 1, "");
5479 value = convert (ctx, values [ins->sreg1], t);
5481 emit_store_general (ctx, bb, &builder, size, value, addr, is_volatile, barrier);
5485 case OP_RELAXED_NOP: {
5486 #if defined(TARGET_AMD64) || defined(TARGET_X86)
5487 emit_call (ctx, bb, &builder, get_intrinsic (ctx, "llvm.x86.sse2.pause"), NULL, 0);
5494 #if (defined(TARGET_AMD64) || defined(TARGET_X86)) && defined(__linux__)
5496 // 257 == FS segment register
5497 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 257);
5499 // 256 == GS segment register
5500 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 256);
5503 values [ins->dreg] = LLVMBuildLoad (builder, LLVMBuildIntToPtr (builder, LLVMConstInt (IntPtrType (), ins->inst_offset, TRUE), ptrtype, ""), "");
5504 #elif defined(TARGET_AMD64) && defined(TARGET_OSX)
5505 /* See mono_amd64_emit_tls_get () */
5506 int offset = mono_amd64_get_tls_gs_offset () + (ins->inst_offset * 8);
5508 // 256 == GS segment register
5509 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 256);
5510 values [ins->dreg] = LLVMBuildLoad (builder, LLVMBuildIntToPtr (builder, LLVMConstInt (IntPtrType (), offset, TRUE), ptrtype, ""), "");
5512 set_failure (ctx, "opcode tls-get");
5518 case OP_TLS_GET_REG: {
5519 #if defined(TARGET_AMD64) && defined(TARGET_OSX)
5520 /* See emit_tls_get_reg () */
5521 // 256 == GS segment register
5522 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 256);
5523 values [ins->dreg] = LLVMBuildLoad (builder, LLVMBuildIntToPtr (builder, convert (ctx, lhs, LLVMInt32Type ()), ptrtype, ""), "");
5525 set_failure (ctx, "opcode tls-get");
5531 case OP_TLS_SET_REG: {
5532 #if defined(TARGET_AMD64) && defined(TARGET_OSX)
5533 /* See emit_tls_get_reg () */
5534 // 256 == GS segment register
5535 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 256);
5536 LLVMBuildStore (builder, convert (ctx, lhs, IntPtrType ()), LLVMBuildIntToPtr (builder, convert (ctx, rhs, LLVMInt32Type ()), ptrtype, ""));
5538 set_failure (ctx, "opcode tls-set-reg");
5548 case OP_IADD_OVF_UN:
5550 case OP_ISUB_OVF_UN:
5552 case OP_IMUL_OVF_UN:
5553 #if SIZEOF_VOID_P == 8
5555 case OP_LADD_OVF_UN:
5557 case OP_LSUB_OVF_UN:
5559 case OP_LMUL_OVF_UN:
5562 LLVMValueRef args [2], val, ovf, func;
5564 args [0] = convert (ctx, lhs, op_to_llvm_type (ins->opcode));
5565 args [1] = convert (ctx, rhs, op_to_llvm_type (ins->opcode));
5566 func = get_intrinsic (ctx, ovf_op_to_intrins (ins->opcode));
5568 val = LLVMBuildCall (builder, func, args, 2, "");
5569 values [ins->dreg] = LLVMBuildExtractValue (builder, val, 0, dname);
5570 ovf = LLVMBuildExtractValue (builder, val, 1, "");
5571 emit_cond_system_exception (ctx, bb, "OverflowException", ovf);
5574 builder = ctx->builder;
5580 * We currently model them using arrays. Promotion to local vregs is
5581 * disabled for them in mono_handle_global_vregs () in the LLVM case,
5582 * so we always have an entry in cfg->varinfo for them.
5583 * FIXME: Is this needed ?
5586 MonoClass *klass = ins->klass;
5587 LLVMValueRef args [5];
5591 set_failure (ctx, "!klass");
5595 if (!addresses [ins->dreg])
5596 addresses [ins->dreg] = build_alloca (ctx, &klass->byval_arg);
5597 args [0] = LLVMBuildBitCast (builder, addresses [ins->dreg], LLVMPointerType (LLVMInt8Type (), 0), "");
5598 args [1] = LLVMConstInt (LLVMInt8Type (), 0, FALSE);
5599 args [2] = LLVMConstInt (LLVMInt32Type (), mono_class_value_size (klass, NULL), FALSE);
5601 args [3] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
5602 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
5603 LLVMBuildCall (builder, get_intrinsic (ctx, "llvm.memset.p0i8.i32"), args, 5, "");
5606 case OP_DUMMY_VZERO:
5609 case OP_STOREV_MEMBASE:
5610 case OP_LOADV_MEMBASE:
5612 MonoClass *klass = ins->klass;
5613 LLVMValueRef src = NULL, dst, args [5];
5614 gboolean done = FALSE;
5618 set_failure (ctx, "!klass");
5622 if (mini_is_gsharedvt_klass (klass)) {
5624 set_failure (ctx, "gsharedvt");
5628 switch (ins->opcode) {
5629 case OP_STOREV_MEMBASE:
5630 if (cfg->gen_write_barriers && klass->has_references && ins->inst_destbasereg != cfg->frame_reg &&
5631 LLVMGetInstructionOpcode (values [ins->inst_destbasereg]) != LLVMAlloca) {
5632 /* Decomposed earlier */
5633 g_assert_not_reached ();
5636 if (!addresses [ins->sreg1]) {
5638 g_assert (values [ins->sreg1]);
5639 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));
5640 LLVMBuildStore (builder, values [ins->sreg1], dst);
5643 src = LLVMBuildBitCast (builder, addresses [ins->sreg1], LLVMPointerType (LLVMInt8Type (), 0), "");
5644 dst = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_destbasereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (LLVMInt8Type (), 0));
5647 case OP_LOADV_MEMBASE:
5648 if (!addresses [ins->dreg])
5649 addresses [ins->dreg] = build_alloca (ctx, &klass->byval_arg);
5650 src = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_basereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (LLVMInt8Type (), 0));
5651 dst = LLVMBuildBitCast (builder, addresses [ins->dreg], LLVMPointerType (LLVMInt8Type (), 0), "");
5654 if (!addresses [ins->sreg1])
5655 addresses [ins->sreg1] = build_alloca (ctx, &klass->byval_arg);
5656 if (!addresses [ins->dreg])
5657 addresses [ins->dreg] = build_alloca (ctx, &klass->byval_arg);
5658 src = LLVMBuildBitCast (builder, addresses [ins->sreg1], LLVMPointerType (LLVMInt8Type (), 0), "");
5659 dst = LLVMBuildBitCast (builder, addresses [ins->dreg], LLVMPointerType (LLVMInt8Type (), 0), "");
5662 g_assert_not_reached ();
5672 args [2] = LLVMConstInt (LLVMInt32Type (), mono_class_value_size (klass, NULL), FALSE);
5673 args [3] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
5675 args [3] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
5676 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
5677 LLVMBuildCall (builder, get_intrinsic (ctx, "llvm.memcpy.p0i8.p0i8.i32"), args, 5, "");
5680 case OP_LLVM_OUTARG_VT: {
5681 LLVMArgInfo *ainfo = (LLVMArgInfo*)ins->inst_p0;
5682 MonoType *t = mini_get_underlying_type (ins->inst_vtype);
5684 if (ainfo->storage == LLVMArgGsharedvtVariable) {
5685 MonoInst *var = get_vreg_to_inst (cfg, ins->sreg1);
5687 if (var && var->opcode == OP_GSHAREDVT_LOCAL) {
5688 addresses [ins->dreg] = convert (ctx, emit_gsharedvt_ldaddr (ctx, var->dreg), LLVMPointerType (IntPtrType (), 0));
5690 g_assert (addresses [ins->sreg1]);
5691 addresses [ins->dreg] = addresses [ins->sreg1];
5693 } else if (ainfo->storage == LLVMArgGsharedvtFixed) {
5694 if (!addresses [ins->sreg1]) {
5695 addresses [ins->sreg1] = build_alloca (ctx, t);
5696 g_assert (values [ins->sreg1]);
5698 LLVMBuildStore (builder, convert (ctx, values [ins->sreg1], LLVMGetElementType (LLVMTypeOf (addresses [ins->sreg1]))), addresses [ins->sreg1]);
5699 addresses [ins->dreg] = addresses [ins->sreg1];
5701 if (!addresses [ins->sreg1]) {
5702 addresses [ins->sreg1] = build_alloca (ctx, t);
5703 g_assert (values [ins->sreg1]);
5704 LLVMBuildStore (builder, convert (ctx, values [ins->sreg1], type_to_llvm_type (ctx, t)), addresses [ins->sreg1]);
5706 addresses [ins->dreg] = addresses [ins->sreg1];
5714 #if defined(TARGET_X86) || defined(TARGET_AMD64)
5716 values [ins->dreg] = LLVMConstNull (type_to_llvm_type (ctx, &ins->klass->byval_arg));
5719 case OP_LOADX_MEMBASE: {
5720 LLVMTypeRef t = type_to_llvm_type (ctx, &ins->klass->byval_arg);
5723 src = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_basereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (t, 0));
5724 values [ins->dreg] = mono_llvm_build_aligned_load (builder, src, "", FALSE, 1);
5727 case OP_STOREX_MEMBASE: {
5728 LLVMTypeRef t = LLVMTypeOf (values [ins->sreg1]);
5731 dest = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_destbasereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (t, 0));
5732 mono_llvm_build_aligned_store (builder, values [ins->sreg1], dest, FALSE, 1);
5739 values [ins->dreg] = LLVMBuildAdd (builder, lhs, rhs, "");
5743 values [ins->dreg] = LLVMBuildFAdd (builder, lhs, rhs, "");
5749 values [ins->dreg] = LLVMBuildSub (builder, lhs, rhs, "");
5753 values [ins->dreg] = LLVMBuildFSub (builder, lhs, rhs, "");
5757 values [ins->dreg] = LLVMBuildFMul (builder, lhs, rhs, "");
5761 values [ins->dreg] = LLVMBuildFDiv (builder, lhs, rhs, "");
5764 values [ins->dreg] = LLVMBuildAnd (builder, lhs, rhs, "");
5767 values [ins->dreg] = LLVMBuildOr (builder, lhs, rhs, "");
5770 values [ins->dreg] = LLVMBuildXor (builder, lhs, rhs, "");
5774 values [ins->dreg] = LLVMBuildMul (builder, lhs, rhs, "");
5785 LLVMValueRef v = NULL;
5787 switch (ins->opcode) {
5792 t = LLVMVectorType (LLVMInt32Type (), 4);
5793 rt = LLVMVectorType (LLVMFloatType (), 4);
5799 t = LLVMVectorType (LLVMInt64Type (), 2);
5800 rt = LLVMVectorType (LLVMDoubleType (), 2);
5803 t = LLVMInt32Type ();
5804 rt = LLVMInt32Type ();
5805 g_assert_not_reached ();
5808 lhs = LLVMBuildBitCast (builder, lhs, t, "");
5809 rhs = LLVMBuildBitCast (builder, rhs, t, "");
5810 switch (ins->opcode) {
5813 v = LLVMBuildAnd (builder, lhs, rhs, "");
5817 v = LLVMBuildOr (builder, lhs, rhs, "");
5821 v = LLVMBuildXor (builder, lhs, rhs, "");
5825 v = LLVMBuildAnd (builder, rhs, LLVMBuildNot (builder, lhs, ""), "");
5828 values [ins->dreg] = LLVMBuildBitCast (builder, v, rt, "");
5852 case OP_PADDB_SAT_UN:
5853 case OP_PADDW_SAT_UN:
5854 case OP_PSUBB_SAT_UN:
5855 case OP_PSUBW_SAT_UN:
5863 case OP_PMULW_HIGH_UN: {
5864 LLVMValueRef args [2];
5869 values [ins->dreg] = LLVMBuildCall (builder, get_intrinsic (ctx, simd_op_to_intrins (ins->opcode)), args, 2, dname);
5876 values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildICmp (builder, LLVMIntEQ, lhs, rhs, ""), LLVMTypeOf (lhs), "");
5880 values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildICmp (builder, LLVMIntSGT, lhs, rhs, ""), LLVMTypeOf (lhs), "");
5888 case OP_EXTRACTX_U2:
5890 case OP_EXTRACT_U1: {
5892 gboolean zext = FALSE;
5894 t = simd_op_to_llvm_type (ins->opcode);
5896 switch (ins->opcode) {
5904 case OP_EXTRACTX_U2:
5909 t = LLVMInt32Type ();
5910 g_assert_not_reached ();
5913 lhs = LLVMBuildBitCast (builder, lhs, t, "");
5914 values [ins->dreg] = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), "");
5916 values [ins->dreg] = LLVMBuildZExt (builder, values [ins->dreg], LLVMInt32Type (), "");
5925 case OP_EXPAND_R8: {
5926 LLVMTypeRef t = simd_op_to_llvm_type (ins->opcode);
5927 LLVMValueRef mask [16], v;
5930 for (i = 0; i < 16; ++i)
5931 mask [i] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
5933 v = convert (ctx, values [ins->sreg1], LLVMGetElementType (t));
5935 values [ins->dreg] = LLVMBuildInsertElement (builder, LLVMConstNull (t), v, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
5936 values [ins->dreg] = LLVMBuildShuffleVector (builder, values [ins->dreg], LLVMGetUndef (t), LLVMConstVector (mask, LLVMGetVectorSize (t)), "");
5941 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt8Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
5944 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt16Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
5947 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt32Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
5950 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt64Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
5953 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMFloatType ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
5956 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMDoubleType ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
5967 case OP_EXTRACT_MASK:
5974 v = convert (ctx, values [ins->sreg1], simd_op_to_llvm_type (ins->opcode));
5976 values [ins->dreg] = LLVMBuildCall (builder, get_intrinsic (ctx, simd_op_to_intrins (ins->opcode)), &v, 1, dname);
5982 LLVMValueRef args [3];
5986 args [2] = LLVMConstInt (LLVMInt8Type (), ins->inst_c0, FALSE);
5988 values [ins->dreg] = LLVMBuildCall (builder, get_intrinsic (ctx, simd_op_to_intrins (ins->opcode)), args, 3, dname);
5993 /* This is only used for implementing shifts by non-immediate */
5994 values [ins->dreg] = lhs;
6005 LLVMValueRef args [3];
6008 args [1] = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
6010 values [ins->dreg] = LLVMBuildCall (builder, get_intrinsic (ctx, simd_op_to_intrins (ins->opcode)), args, 2, dname);
6021 case OP_PSHLQ_REG: {
6022 LLVMValueRef args [3];
6025 args [1] = values [ins->sreg2];
6027 values [ins->dreg] = LLVMBuildCall (builder, get_intrinsic (ctx, simd_op_to_intrins (ins->opcode)), args, 2, dname);
6034 case OP_PSHUFLEW_LOW:
6035 case OP_PSHUFLEW_HIGH: {
6037 LLVMValueRef v1 = NULL, v2 = NULL, mask_values [16];
6038 int i, mask_size = 0;
6039 int imask = ins->inst_c0;
6041 /* Convert the x86 shuffle mask to LLVM's */
6042 switch (ins->opcode) {
6045 mask [0] = ((imask >> 0) & 3);
6046 mask [1] = ((imask >> 2) & 3);
6047 mask [2] = ((imask >> 4) & 3) + 4;
6048 mask [3] = ((imask >> 6) & 3) + 4;
6049 v1 = values [ins->sreg1];
6050 v2 = values [ins->sreg2];
6054 mask [0] = ((imask >> 0) & 1);
6055 mask [1] = ((imask >> 1) & 1) + 2;
6056 v1 = values [ins->sreg1];
6057 v2 = values [ins->sreg2];
6059 case OP_PSHUFLEW_LOW:
6061 mask [0] = ((imask >> 0) & 3);
6062 mask [1] = ((imask >> 2) & 3);
6063 mask [2] = ((imask >> 4) & 3);
6064 mask [3] = ((imask >> 6) & 3);
6069 v1 = values [ins->sreg1];
6070 v2 = LLVMGetUndef (LLVMTypeOf (v1));
6072 case OP_PSHUFLEW_HIGH:
6078 mask [4] = 4 + ((imask >> 0) & 3);
6079 mask [5] = 4 + ((imask >> 2) & 3);
6080 mask [6] = 4 + ((imask >> 4) & 3);
6081 mask [7] = 4 + ((imask >> 6) & 3);
6082 v1 = values [ins->sreg1];
6083 v2 = LLVMGetUndef (LLVMTypeOf (v1));
6087 mask [0] = ((imask >> 0) & 3);
6088 mask [1] = ((imask >> 2) & 3);
6089 mask [2] = ((imask >> 4) & 3);
6090 mask [3] = ((imask >> 6) & 3);
6091 v1 = values [ins->sreg1];
6092 v2 = LLVMGetUndef (LLVMTypeOf (v1));
6095 g_assert_not_reached ();
6097 for (i = 0; i < mask_size; ++i)
6098 mask_values [i] = LLVMConstInt (LLVMInt32Type (), mask [i], FALSE);
6100 values [ins->dreg] =
6101 LLVMBuildShuffleVector (builder, v1, v2,
6102 LLVMConstVector (mask_values, mask_size), dname);
6106 case OP_UNPACK_LOWB:
6107 case OP_UNPACK_LOWW:
6108 case OP_UNPACK_LOWD:
6109 case OP_UNPACK_LOWQ:
6110 case OP_UNPACK_LOWPS:
6111 case OP_UNPACK_LOWPD:
6112 case OP_UNPACK_HIGHB:
6113 case OP_UNPACK_HIGHW:
6114 case OP_UNPACK_HIGHD:
6115 case OP_UNPACK_HIGHQ:
6116 case OP_UNPACK_HIGHPS:
6117 case OP_UNPACK_HIGHPD: {
6119 LLVMValueRef mask_values [16];
6120 int i, mask_size = 0;
6121 gboolean low = FALSE;
6123 switch (ins->opcode) {
6124 case OP_UNPACK_LOWB:
6128 case OP_UNPACK_LOWW:
6132 case OP_UNPACK_LOWD:
6133 case OP_UNPACK_LOWPS:
6137 case OP_UNPACK_LOWQ:
6138 case OP_UNPACK_LOWPD:
6142 case OP_UNPACK_HIGHB:
6145 case OP_UNPACK_HIGHW:
6148 case OP_UNPACK_HIGHD:
6149 case OP_UNPACK_HIGHPS:
6152 case OP_UNPACK_HIGHQ:
6153 case OP_UNPACK_HIGHPD:
6157 g_assert_not_reached ();
6161 for (i = 0; i < (mask_size / 2); ++i) {
6163 mask [(i * 2) + 1] = mask_size + i;
6166 for (i = 0; i < (mask_size / 2); ++i) {
6167 mask [(i * 2)] = (mask_size / 2) + i;
6168 mask [(i * 2) + 1] = mask_size + (mask_size / 2) + i;
6172 for (i = 0; i < mask_size; ++i)
6173 mask_values [i] = LLVMConstInt (LLVMInt32Type (), mask [i], FALSE);
6175 values [ins->dreg] =
6176 LLVMBuildShuffleVector (builder, values [ins->sreg1], values [ins->sreg2],
6177 LLVMConstVector (mask_values, mask_size), dname);
6182 LLVMTypeRef t = simd_op_to_llvm_type (ins->opcode);
6183 LLVMValueRef v, val;
6185 v = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
6186 val = LLVMConstNull (t);
6187 val = LLVMBuildInsertElement (builder, val, v, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
6188 val = LLVMBuildInsertElement (builder, val, v, LLVMConstInt (LLVMInt32Type (), 1, FALSE), dname);
6190 values [ins->dreg] = val;
6194 case OP_DUPPS_HIGH: {
6195 LLVMTypeRef t = simd_op_to_llvm_type (ins->opcode);
6196 LLVMValueRef v1, v2, val;
6199 if (ins->opcode == OP_DUPPS_LOW) {
6200 v1 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
6201 v2 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 2, FALSE), "");
6203 v1 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 1, FALSE), "");
6204 v2 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 3, FALSE), "");
6206 val = LLVMConstNull (t);
6207 val = LLVMBuildInsertElement (builder, val, v1, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
6208 val = LLVMBuildInsertElement (builder, val, v1, LLVMConstInt (LLVMInt32Type (), 1, FALSE), "");
6209 val = LLVMBuildInsertElement (builder, val, v2, LLVMConstInt (LLVMInt32Type (), 2, FALSE), "");
6210 val = LLVMBuildInsertElement (builder, val, v2, LLVMConstInt (LLVMInt32Type (), 3, FALSE), "");
6212 values [ins->dreg] = val;
6222 * EXCEPTION HANDLING
6224 case OP_IMPLICIT_EXCEPTION:
6225 /* This marks a place where an implicit exception can happen */
6226 if (bb->region != -1)
6227 set_failure (ctx, "implicit-exception");
6231 gboolean rethrow = (ins->opcode == OP_RETHROW);
6232 if (ctx->llvm_only) {
6233 emit_llvmonly_throw (ctx, bb, rethrow, lhs);
6234 has_terminator = TRUE;
6235 ctx->unreachable [bb->block_num] = TRUE;
6237 emit_throw (ctx, bb, rethrow, lhs);
6238 builder = ctx->builder;
6242 case OP_CALL_HANDLER: {
6244 * We don't 'call' handlers, but instead simply branch to them.
6245 * The code generated by ENDFINALLY will branch back to us.
6247 LLVMBasicBlockRef noex_bb;
6249 BBInfo *info = &bblocks [ins->inst_target_bb->block_num];
6251 bb_list = info->call_handler_return_bbs;
6254 * Set the indicator variable for the finally clause.
6256 lhs = info->finally_ind;
6258 LLVMBuildStore (builder, LLVMConstInt (LLVMInt32Type (), g_slist_length (bb_list) + 1, FALSE), lhs);
6260 /* Branch to the finally clause */
6261 LLVMBuildBr (builder, info->call_handler_target_bb);
6263 noex_bb = gen_bb (ctx, "CALL_HANDLER_CONT_BB");
6264 info->call_handler_return_bbs = g_slist_append_mempool (cfg->mempool, info->call_handler_return_bbs, noex_bb);
6266 builder = ctx->builder = create_builder (ctx);
6267 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
6269 bblocks [bb->block_num].end_bblock = noex_bb;
6272 case OP_START_HANDLER: {
6275 case OP_ENDFINALLY: {
6276 LLVMBasicBlockRef resume_bb;
6277 MonoBasicBlock *handler_bb;
6278 LLVMValueRef val, switch_ins, callee;
6282 handler_bb = (MonoBasicBlock*)g_hash_table_lookup (ctx->region_to_handler, GUINT_TO_POINTER (mono_get_block_region_notry (cfg, bb->region)));
6283 g_assert (handler_bb);
6284 info = &bblocks [handler_bb->block_num];
6285 lhs = info->finally_ind;
6288 bb_list = info->call_handler_return_bbs;
6290 resume_bb = gen_bb (ctx, "ENDFINALLY_RESUME_BB");
6292 /* Load the finally variable */
6293 val = LLVMBuildLoad (builder, lhs, "");
6295 /* Reset the variable */
6296 LLVMBuildStore (builder, LLVMConstInt (LLVMInt32Type (), 0, FALSE), lhs);
6298 /* Branch to either resume_bb, or to the bblocks in bb_list */
6299 switch_ins = LLVMBuildSwitch (builder, val, resume_bb, g_slist_length (bb_list));
6301 * The other targets are added at the end to handle OP_CALL_HANDLER
6302 * opcodes processed later.
6304 info->endfinally_switch_ins_list = g_slist_append_mempool (cfg->mempool, info->endfinally_switch_ins_list, switch_ins);
6306 builder = ctx->builder = create_builder (ctx);
6307 LLVMPositionBuilderAtEnd (ctx->builder, resume_bb);
6309 if (ctx->llvm_only) {
6310 emit_resume_eh (ctx, bb);
6312 if (ctx->cfg->compile_aot) {
6313 callee = get_callee (ctx, LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE), MONO_PATCH_INFO_INTERNAL_METHOD, "llvm_resume_unwind_trampoline");
6315 #if LLVM_API_VERSION > 100
6316 MonoJitICallInfo *info;
6318 info = mono_find_jit_icall_by_name ("llvm_resume_unwind_trampoline");
6320 gpointer target = (void*)info->func;
6321 LLVMTypeRef icall_sig = LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE);
6322 callee = emit_jit_callee (ctx, "llvm_resume_unwind_trampoline", icall_sig, target);
6324 callee = LLVMGetNamedFunction (ctx->lmodule, "llvm_resume_unwind_trampoline");
6327 LLVMBuildCall (builder, callee, NULL, 0, "");
6328 LLVMBuildUnreachable (builder);
6331 has_terminator = TRUE;
6334 case OP_IL_SEQ_POINT:
6339 sprintf (reason, "opcode %s", mono_inst_name (ins->opcode));
6340 set_failure (ctx, reason);
6348 /* Convert the value to the type required by phi nodes */
6349 if (spec [MONO_INST_DEST] != ' ' && !MONO_IS_STORE_MEMBASE (ins) && ctx->vreg_types [ins->dreg]) {
6350 if (!values [ins->dreg])
6352 values [ins->dreg] = addresses [ins->dreg];
6354 values [ins->dreg] = convert (ctx, values [ins->dreg], ctx->vreg_types [ins->dreg]);
6357 /* Add stores for volatile variables */
6358 if (spec [MONO_INST_DEST] != ' ' && spec [MONO_INST_DEST] != 'v' && !MONO_IS_STORE_MEMBASE (ins))
6359 emit_volatile_store (ctx, ins->dreg);
6365 if (!has_terminator && bb->next_bb && (bb == cfg->bb_entry || bb->in_count > 0)) {
6366 LLVMBuildBr (builder, get_bb (ctx, bb->next_bb));
6369 if (bb == cfg->bb_exit && sig->ret->type == MONO_TYPE_VOID) {
6370 emit_dbg_loc (ctx, builder, cfg->header->code + cfg->header->code_size - 1);
6371 LLVMBuildRetVoid (builder);
6374 if (bb == cfg->bb_entry)
6375 ctx->last_alloca = LLVMGetLastInstruction (get_bb (ctx, cfg->bb_entry));
6379 * mono_llvm_check_method_supported:
6381 * Do some quick checks to decide whenever cfg->method can be compiled by LLVM, to avoid
6382 * compiling a method twice.
6385 mono_llvm_check_method_supported (MonoCompile *cfg)
6392 if (cfg->method->save_lmf) {
6393 cfg->exception_message = g_strdup ("lmf");
6394 cfg->disable_llvm = TRUE;
6396 if (cfg->disable_llvm)
6400 * Nested clauses where one of the clauses is a finally clause is
6401 * not supported, because LLVM can't figure out the control flow,
6402 * probably because we resume exception handling by calling our
6403 * own function instead of using the 'resume' llvm instruction.
6405 for (i = 0; i < cfg->header->num_clauses; ++i) {
6406 for (j = 0; j < cfg->header->num_clauses; ++j) {
6407 MonoExceptionClause *clause1 = &cfg->header->clauses [i];
6408 MonoExceptionClause *clause2 = &cfg->header->clauses [j];
6410 // FIXME: Nested try clauses fail in some cases too, i.e. #37273
6411 if (i != j && clause1->try_offset >= clause2->try_offset && clause1->handler_offset <= clause2->handler_offset) {
6412 //(clause1->flags == MONO_EXCEPTION_CLAUSE_FINALLY || clause2->flags == MONO_EXCEPTION_CLAUSE_FINALLY)) {
6413 cfg->exception_message = g_strdup ("nested clauses");
6414 cfg->disable_llvm = TRUE;
6419 if (cfg->disable_llvm)
6423 if (cfg->method->dynamic) {
6424 cfg->exception_message = g_strdup ("dynamic.");
6425 cfg->disable_llvm = TRUE;
6427 if (cfg->disable_llvm)
6431 static LLVMCallInfo*
6432 get_llvm_call_info (MonoCompile *cfg, MonoMethodSignature *sig)
6434 LLVMCallInfo *linfo;
6437 if (cfg->gsharedvt && cfg->llvm_only && mini_is_gsharedvt_variable_signature (sig)) {
6441 * Gsharedvt methods have the following calling convention:
6442 * - all arguments are passed by ref, even non generic ones
6443 * - the return value is returned by ref too, using a vret
6444 * argument passed after 'this'.
6446 n = sig->param_count + sig->hasthis;
6447 linfo = (LLVMCallInfo*)mono_mempool_alloc0 (cfg->mempool, sizeof (LLVMCallInfo) + (sizeof (LLVMArgInfo) * n));
6451 linfo->args [pindex ++].storage = LLVMArgNormal;
6453 if (sig->ret->type != MONO_TYPE_VOID) {
6454 if (mini_is_gsharedvt_variable_type (sig->ret))
6455 linfo->ret.storage = LLVMArgGsharedvtVariable;
6456 else if (mini_type_is_vtype (sig->ret))
6457 linfo->ret.storage = LLVMArgGsharedvtFixedVtype;
6459 linfo->ret.storage = LLVMArgGsharedvtFixed;
6460 linfo->vret_arg_index = pindex;
6462 linfo->ret.storage = LLVMArgNone;
6465 for (i = 0; i < sig->param_count; ++i) {
6466 if (sig->params [i]->byref)
6467 linfo->args [pindex].storage = LLVMArgNormal;
6468 else if (mini_is_gsharedvt_variable_type (sig->params [i]))
6469 linfo->args [pindex].storage = LLVMArgGsharedvtVariable;
6470 else if (mini_type_is_vtype (sig->params [i]))
6471 linfo->args [pindex].storage = LLVMArgGsharedvtFixedVtype;
6473 linfo->args [pindex].storage = LLVMArgGsharedvtFixed;
6474 linfo->args [pindex].type = sig->params [i];
6481 linfo = mono_arch_get_llvm_call_info (cfg, sig);
6482 for (i = 0; i < sig->param_count; ++i)
6483 linfo->args [i + sig->hasthis].type = sig->params [i];
6489 emit_method_inner (EmitContext *ctx);
6492 free_ctx (EmitContext *ctx)
6496 g_free (ctx->values);
6497 g_free (ctx->addresses);
6498 g_free (ctx->vreg_types);
6499 g_free (ctx->vreg_cli_types);
6500 g_free (ctx->is_dead);
6501 g_free (ctx->unreachable);
6502 g_ptr_array_free (ctx->phi_values, TRUE);
6503 g_free (ctx->bblocks);
6504 g_hash_table_destroy (ctx->region_to_handler);
6505 g_hash_table_destroy (ctx->clause_to_handler);
6506 g_hash_table_destroy (ctx->jit_callees);
6507 g_free (ctx->method_name);
6508 g_ptr_array_free (ctx->bblock_list, TRUE);
6510 for (l = ctx->builders; l; l = l->next) {
6511 LLVMBuilderRef builder = (LLVMBuilderRef)l->data;
6512 LLVMDisposeBuilder (builder);
6519 * mono_llvm_emit_method:
6521 * Emit LLVM IL from the mono IL, and compile it to native code using LLVM.
6524 mono_llvm_emit_method (MonoCompile *cfg)
6528 gboolean is_linkonce = FALSE;
6531 /* The code below might acquire the loader lock, so use it for global locking */
6532 mono_loader_lock ();
6534 /* Used to communicate with the callbacks */
6535 mono_native_tls_set_value (current_cfg_tls_id, cfg);
6537 ctx = g_new0 (EmitContext, 1);
6539 ctx->mempool = cfg->mempool;
6542 * This maps vregs to the LLVM instruction defining them
6544 ctx->values = g_new0 (LLVMValueRef, cfg->next_vreg);
6546 * This maps vregs for volatile variables to the LLVM instruction defining their
6549 ctx->addresses = g_new0 (LLVMValueRef, cfg->next_vreg);
6550 ctx->vreg_types = g_new0 (LLVMTypeRef, cfg->next_vreg);
6551 ctx->vreg_cli_types = g_new0 (MonoType*, cfg->next_vreg);
6552 ctx->phi_values = g_ptr_array_sized_new (256);
6554 * This signals whenever the vreg was defined by a phi node with no input vars
6555 * (i.e. all its input bblocks end with NOT_REACHABLE).
6557 ctx->is_dead = g_new0 (gboolean, cfg->next_vreg);
6558 /* Whenever the bblock is unreachable */
6559 ctx->unreachable = g_new0 (gboolean, cfg->max_block_num);
6560 ctx->bblock_list = g_ptr_array_sized_new (256);
6562 ctx->region_to_handler = g_hash_table_new (NULL, NULL);
6563 ctx->clause_to_handler = g_hash_table_new (NULL, NULL);
6564 ctx->method_to_callers = g_hash_table_new (NULL, NULL);
6565 ctx->jit_callees = g_hash_table_new (NULL, NULL);
6566 if (cfg->compile_aot) {
6567 ctx->module = &aot_module;
6571 * Allow the linker to discard duplicate copies of wrappers, generic instances etc. by using the 'linkonce'
6572 * linkage for them. This requires the following:
6573 * - the method needs to have a unique mangled name
6574 * - llvmonly mode, since the code in aot-runtime.c would initialize got slots in the wrong aot image etc.
6576 is_linkonce = ctx->module->llvm_only && ctx->module->static_link && mono_aot_is_linkonce_method (cfg->method);
6578 method_name = mono_aot_get_mangled_method_name (cfg->method);
6580 is_linkonce = FALSE;
6583 printf ("%s %s\n", mono_method_full_name (cfg->method, 1), method_name);
6585 printf ("%s\n", mono_method_full_name (cfg->method, 1));
6589 method_name = mono_aot_get_method_name (cfg);
6590 cfg->llvm_method_name = g_strdup (method_name);
6592 init_jit_module (cfg->domain);
6593 ctx->module = (MonoLLVMModule*)domain_jit_info (cfg->domain)->llvm_module;
6594 method_name = mono_method_full_name (cfg->method, TRUE);
6596 ctx->method_name = method_name;
6597 ctx->is_linkonce = is_linkonce;
6599 #if LLVM_API_VERSION > 100
6600 ctx->lmodule = LLVMModuleCreateWithName ("jit-module");
6602 ctx->lmodule = ctx->module->lmodule;
6604 ctx->llvm_only = ctx->module->llvm_only;
6606 emit_method_inner (ctx);
6608 if (!ctx_ok (ctx)) {
6610 /* Need to add unused phi nodes as they can be referenced by other values */
6611 LLVMBasicBlockRef phi_bb = LLVMAppendBasicBlock (ctx->lmethod, "PHI_BB");
6612 LLVMBuilderRef builder;
6614 builder = create_builder (ctx);
6615 LLVMPositionBuilderAtEnd (builder, phi_bb);
6617 for (i = 0; i < ctx->phi_values->len; ++i) {
6618 LLVMValueRef v = (LLVMValueRef)g_ptr_array_index (ctx->phi_values, i);
6619 if (LLVMGetInstructionParent (v) == NULL)
6620 LLVMInsertIntoBuilder (builder, v);
6623 LLVMDeleteFunction (ctx->lmethod);
6629 mono_native_tls_set_value (current_cfg_tls_id, NULL);
6631 mono_loader_unlock ();
6635 emit_method_inner (EmitContext *ctx)
6637 MonoCompile *cfg = ctx->cfg;
6638 MonoMethodSignature *sig;
6640 LLVMTypeRef method_type;
6641 LLVMValueRef method = NULL;
6642 LLVMValueRef *values = ctx->values;
6643 int i, max_block_num, bb_index;
6644 gboolean last = FALSE;
6645 LLVMCallInfo *linfo;
6646 LLVMModuleRef lmodule = ctx->lmodule;
6648 GPtrArray *bblock_list = ctx->bblock_list;
6649 MonoMethodHeader *header;
6650 MonoExceptionClause *clause;
6653 if (cfg->gsharedvt && !cfg->llvm_only) {
6654 set_failure (ctx, "gsharedvt");
6660 static int count = 0;
6663 if (g_getenv ("LLVM_COUNT")) {
6664 if (count == atoi (g_getenv ("LLVM_COUNT"))) {
6665 printf ("LAST: %s\n", mono_method_full_name (cfg->method, TRUE));
6669 if (count > atoi (g_getenv ("LLVM_COUNT"))) {
6670 set_failure (ctx, "count");
6677 sig = mono_method_signature (cfg->method);
6680 linfo = get_llvm_call_info (cfg, sig);
6686 linfo->rgctx_arg = TRUE;
6687 ctx->method_type = method_type = sig_to_llvm_sig_full (ctx, sig, linfo);
6691 method = LLVMAddFunction (lmodule, ctx->method_name, method_type);
6692 ctx->lmethod = method;
6694 if (!cfg->llvm_only)
6695 LLVMSetFunctionCallConv (method, LLVMMono1CallConv);
6696 LLVMSetLinkage (method, LLVMPrivateLinkage);
6698 LLVMAddFunctionAttr (method, LLVMUWTable);
6700 if (cfg->compile_aot) {
6701 LLVMSetLinkage (method, LLVMInternalLinkage);
6702 if (ctx->module->external_symbols) {
6703 LLVMSetLinkage (method, LLVMExternalLinkage);
6704 LLVMSetVisibility (method, LLVMHiddenVisibility);
6706 if (ctx->is_linkonce) {
6707 LLVMSetLinkage (method, LLVMLinkOnceAnyLinkage);
6708 LLVMSetVisibility (method, LLVMDefaultVisibility);
6711 #if LLVM_API_VERSION > 100
6712 LLVMSetLinkage (method, LLVMExternalLinkage);
6714 LLVMSetLinkage (method, LLVMPrivateLinkage);
6718 if (cfg->method->save_lmf && !cfg->llvm_only) {
6719 set_failure (ctx, "lmf");
6723 if (sig->pinvoke && cfg->method->wrapper_type != MONO_WRAPPER_RUNTIME_INVOKE && !cfg->llvm_only) {
6724 set_failure (ctx, "pinvoke signature");
6728 header = cfg->header;
6729 for (i = 0; i < header->num_clauses; ++i) {
6730 clause = &header->clauses [i];
6731 if (clause->flags != MONO_EXCEPTION_CLAUSE_FINALLY && clause->flags != MONO_EXCEPTION_CLAUSE_NONE) {
6732 set_failure (ctx, "non-finally/catch clause.");
6736 if (header->num_clauses || (cfg->method->iflags & METHOD_IMPL_ATTRIBUTE_NOINLINING) || cfg->no_inline)
6737 /* We can't handle inlined methods with clauses */
6738 LLVMAddFunctionAttr (method, LLVMNoInlineAttribute);
6740 if (linfo->rgctx_arg) {
6741 ctx->rgctx_arg = LLVMGetParam (method, linfo->rgctx_arg_pindex);
6742 ctx->rgctx_arg_pindex = linfo->rgctx_arg_pindex;
6744 * We mark the rgctx parameter with the inreg attribute, which is mapped to
6745 * MONO_ARCH_RGCTX_REG in the Mono calling convention in llvm, i.e.
6746 * CC_X86_64_Mono in X86CallingConv.td.
6748 if (!ctx->llvm_only)
6749 LLVMAddAttribute (ctx->rgctx_arg, LLVMInRegAttribute);
6750 LLVMSetValueName (ctx->rgctx_arg, "rgctx");
6752 ctx->rgctx_arg_pindex = -1;
6754 if (cfg->vret_addr) {
6755 values [cfg->vret_addr->dreg] = LLVMGetParam (method, linfo->vret_arg_pindex);
6756 LLVMSetValueName (values [cfg->vret_addr->dreg], "vret");
6757 if (linfo->ret.storage == LLVMArgVtypeByRef) {
6758 LLVMAddAttribute (LLVMGetParam (method, linfo->vret_arg_pindex), LLVMStructRetAttribute);
6759 LLVMAddAttribute (LLVMGetParam (method, linfo->vret_arg_pindex), LLVMNoAliasAttribute);
6764 ctx->this_arg_pindex = linfo->this_arg_pindex;
6765 ctx->this_arg = LLVMGetParam (method, linfo->this_arg_pindex);
6766 values [cfg->args [0]->dreg] = ctx->this_arg;
6767 LLVMSetValueName (values [cfg->args [0]->dreg], "this");
6770 names = g_new (char *, sig->param_count);
6771 mono_method_get_param_names (cfg->method, (const char **) names);
6773 for (i = 0; i < sig->param_count; ++i) {
6774 LLVMArgInfo *ainfo = &linfo->args [i + sig->hasthis];
6776 int pindex = ainfo->pindex + ainfo->ndummy_fpargs;
6779 for (j = 0; j < ainfo->ndummy_fpargs; ++j) {
6780 name = g_strdup_printf ("dummy_%d_%d", i, j);
6781 LLVMSetValueName (LLVMGetParam (method, ainfo->pindex + j), name);
6785 values [cfg->args [i + sig->hasthis]->dreg] = LLVMGetParam (method, pindex);
6786 if (ainfo->storage == LLVMArgGsharedvtFixed || ainfo->storage == LLVMArgGsharedvtFixedVtype) {
6787 if (names [i] && names [i][0] != '\0')
6788 name = g_strdup_printf ("p_arg_%s", names [i]);
6790 name = g_strdup_printf ("p_arg_%d", i);
6792 if (names [i] && names [i][0] != '\0')
6793 name = g_strdup_printf ("arg_%s", names [i]);
6795 name = g_strdup_printf ("arg_%d", i);
6797 LLVMSetValueName (values [cfg->args [i + sig->hasthis]->dreg], name);
6799 if (ainfo->storage == LLVMArgVtypeByVal)
6800 LLVMAddAttribute (LLVMGetParam (method, pindex), LLVMByValAttribute);
6802 if (ainfo->storage == LLVMArgVtypeByRef) {
6804 cfg->args [i + sig->hasthis]->opcode = OP_VTARG_ADDR;
6809 if (ctx->module->emit_dwarf && cfg->compile_aot && mono_debug_enabled ()) {
6810 ctx->minfo = mono_debug_lookup_method (cfg->method);
6811 ctx->dbg_md = emit_dbg_subprogram (ctx, cfg, method, ctx->method_name);
6815 for (bb = cfg->bb_entry; bb; bb = bb->next_bb)
6816 max_block_num = MAX (max_block_num, bb->block_num);
6817 ctx->bblocks = bblocks = g_new0 (BBInfo, max_block_num + 1);
6819 /* Add branches between non-consecutive bblocks */
6820 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
6821 if (bb->last_ins && MONO_IS_COND_BRANCH_OP (bb->last_ins) &&
6822 bb->next_bb != bb->last_ins->inst_false_bb) {
6824 MonoInst *inst = (MonoInst*)mono_mempool_alloc0 (cfg->mempool, sizeof (MonoInst));
6825 inst->opcode = OP_BR;
6826 inst->inst_target_bb = bb->last_ins->inst_false_bb;
6827 mono_bblock_add_inst (bb, inst);
6832 * The INDIRECT flag added by OP_LDADDR inhibits optimizations, even if the LDADDR
6833 * was later optimized away, so clear these flags, and add them back for the still
6834 * present OP_LDADDR instructions.
6836 for (i = 0; i < cfg->next_vreg; ++i) {
6839 ins = get_vreg_to_inst (cfg, i);
6840 if (ins && ins != cfg->rgctx_var)
6841 ins->flags &= ~MONO_INST_INDIRECT;
6845 * Make a first pass over the code to precreate PHI nodes/set INDIRECT flags.
6847 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
6849 LLVMBuilderRef builder;
6851 char dname_buf[128];
6853 builder = create_builder (ctx);
6855 for (ins = bb->code; ins; ins = ins->next) {
6856 switch (ins->opcode) {
6861 LLVMTypeRef phi_type = llvm_type_to_stack_type (cfg, type_to_llvm_type (ctx, &ins->klass->byval_arg));
6866 if (ins->opcode == OP_VPHI) {
6867 /* Treat valuetype PHI nodes as operating on the address itself */
6868 g_assert (ins->klass);
6869 phi_type = LLVMPointerType (type_to_llvm_type (ctx, &ins->klass->byval_arg), 0);
6873 * Have to precreate these, as they can be referenced by
6874 * earlier instructions.
6876 sprintf (dname_buf, "t%d", ins->dreg);
6878 values [ins->dreg] = LLVMBuildPhi (builder, phi_type, dname);
6880 if (ins->opcode == OP_VPHI)
6881 ctx->addresses [ins->dreg] = values [ins->dreg];
6883 g_ptr_array_add (ctx->phi_values, values [ins->dreg]);
6886 * Set the expected type of the incoming arguments since these have
6887 * to have the same type.
6889 for (i = 0; i < ins->inst_phi_args [0]; i++) {
6890 int sreg1 = ins->inst_phi_args [i + 1];
6893 ctx->vreg_types [sreg1] = phi_type;
6898 ((MonoInst*)ins->inst_p0)->flags |= MONO_INST_INDIRECT;
6907 * Create an ordering for bblocks, use the depth first order first, then
6908 * put the exception handling bblocks last.
6910 for (bb_index = 0; bb_index < cfg->num_bblocks; ++bb_index) {
6911 bb = cfg->bblocks [bb_index];
6912 if (!(bb->region != -1 && !MONO_BBLOCK_IS_IN_REGION (bb, MONO_REGION_TRY))) {
6913 g_ptr_array_add (bblock_list, bb);
6914 bblocks [bb->block_num].added = TRUE;
6918 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
6919 if (!bblocks [bb->block_num].added)
6920 g_ptr_array_add (bblock_list, bb);
6924 * Second pass: generate code.
6927 LLVMBuilderRef entry_builder = create_builder (ctx);
6928 LLVMBasicBlockRef entry_bb = get_bb (ctx, cfg->bb_entry);
6929 LLVMPositionBuilderAtEnd (entry_builder, entry_bb);
6930 emit_entry_bb (ctx, entry_builder);
6932 // Make landing pads first
6933 ctx->exc_meta = g_hash_table_new_full (NULL, NULL, NULL, NULL);
6935 if (ctx->llvm_only) {
6936 size_t group_index = 0;
6937 while (group_index < cfg->header->num_clauses) {
6939 size_t cursor = group_index;
6940 while (cursor < cfg->header->num_clauses &&
6941 CLAUSE_START (&cfg->header->clauses [cursor]) == CLAUSE_START (&cfg->header->clauses [group_index]) &&
6942 CLAUSE_END (&cfg->header->clauses [cursor]) == CLAUSE_END (&cfg->header->clauses [group_index])) {
6947 LLVMBasicBlockRef lpad_bb = emit_landing_pad (ctx, group_index, count);
6948 intptr_t key = CLAUSE_END (&cfg->header->clauses [group_index]);
6949 g_hash_table_insert (ctx->exc_meta, (gpointer)key, lpad_bb);
6951 group_index = cursor;
6955 for (bb_index = 0; bb_index < bblock_list->len; ++bb_index) {
6956 bb = (MonoBasicBlock*)g_ptr_array_index (bblock_list, bb_index);
6958 // Prune unreachable mono BBs.
6959 if (!(bb == cfg->bb_entry || bb->in_count > 0))
6962 process_bb (ctx, bb);
6966 g_hash_table_destroy (ctx->exc_meta);
6968 mono_memory_barrier ();
6970 /* Add incoming phi values */
6971 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
6972 GSList *l, *ins_list;
6974 ins_list = bblocks [bb->block_num].phi_nodes;
6976 for (l = ins_list; l; l = l->next) {
6977 PhiNode *node = (PhiNode*)l->data;
6978 MonoInst *phi = node->phi;
6979 int sreg1 = node->sreg;
6980 LLVMBasicBlockRef in_bb;
6985 in_bb = get_end_bb (ctx, node->in_bb);
6987 if (ctx->unreachable [node->in_bb->block_num])
6990 if (!values [sreg1]) {
6991 /* Can happen with values in EH clauses */
6992 set_failure (ctx, "incoming phi sreg1");
6996 if (phi->opcode == OP_VPHI) {
6997 g_assert (LLVMTypeOf (ctx->addresses [sreg1]) == LLVMTypeOf (values [phi->dreg]));
6998 LLVMAddIncoming (values [phi->dreg], &ctx->addresses [sreg1], &in_bb, 1);
7000 if (LLVMTypeOf (values [sreg1]) != LLVMTypeOf (values [phi->dreg])) {
7001 set_failure (ctx, "incoming phi arg type mismatch");
7004 g_assert (LLVMTypeOf (values [sreg1]) == LLVMTypeOf (values [phi->dreg]));
7005 LLVMAddIncoming (values [phi->dreg], &values [sreg1], &in_bb, 1);
7010 /* Nullify empty phi instructions */
7011 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
7012 GSList *l, *ins_list;
7014 ins_list = bblocks [bb->block_num].phi_nodes;
7016 for (l = ins_list; l; l = l->next) {
7017 PhiNode *node = (PhiNode*)l->data;
7018 MonoInst *phi = node->phi;
7019 LLVMValueRef phi_ins = values [phi->dreg];
7022 /* Already removed */
7025 if (LLVMCountIncoming (phi_ins) == 0) {
7026 mono_llvm_replace_uses_of (phi_ins, LLVMConstNull (LLVMTypeOf (phi_ins)));
7027 LLVMInstructionEraseFromParent (phi_ins);
7028 values [phi->dreg] = NULL;
7033 /* Create the SWITCH statements for ENDFINALLY instructions */
7034 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
7035 BBInfo *info = &bblocks [bb->block_num];
7037 for (l = info->endfinally_switch_ins_list; l; l = l->next) {
7038 LLVMValueRef switch_ins = (LLVMValueRef)l->data;
7039 GSList *bb_list = info->call_handler_return_bbs;
7041 for (i = 0; i < g_slist_length (bb_list); ++i)
7042 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), i + 1, FALSE), (LLVMBasicBlockRef)(g_slist_nth (bb_list, i)->data));
7046 /* Initialize the method if needed */
7047 if (cfg->compile_aot && ctx->llvm_only) {
7048 // FIXME: Add more shared got entries
7049 ctx->builder = create_builder (ctx);
7050 LLVMPositionBuilderAtEnd (ctx->builder, ctx->init_bb);
7052 ctx->module->max_method_idx = MAX (ctx->module->max_method_idx, cfg->method_index);
7054 // FIXME: beforefieldinit
7055 if (ctx->has_got_access || mono_class_get_cctor (cfg->method->klass)) {
7056 emit_init_method (ctx);
7058 LLVMBuildBr (ctx->builder, ctx->inited_bb);
7062 if (cfg->llvm_only) {
7063 GHashTableIter iter;
7065 GSList *callers, *l, *l2;
7068 * Add the contents of ctx->method_to_callers to module->method_to_callers.
7069 * We can't do this earlier, as it contains llvm instructions which can be
7070 * freed if compilation fails.
7071 * FIXME: Get rid of this when all methods can be llvm compiled.
7073 g_hash_table_iter_init (&iter, ctx->method_to_callers);
7074 while (g_hash_table_iter_next (&iter, (void**)&method, (void**)&callers)) {
7075 for (l = callers; l; l = l->next) {
7076 l2 = (GSList*)g_hash_table_lookup (ctx->module->method_to_callers, method);
7077 l2 = g_slist_prepend (l2, l->data);
7078 g_hash_table_insert (ctx->module->method_to_callers, method, l2);
7083 if (cfg->verbose_level > 1)
7084 mono_llvm_dump_value (method);
7086 if (cfg->compile_aot && !cfg->llvm_only)
7087 mark_as_used (ctx->module, method);
7089 if (cfg->compile_aot && !cfg->llvm_only) {
7090 LLVMValueRef md_args [16];
7091 LLVMValueRef md_node;
7094 method_index = mono_aot_get_method_index (cfg->orig_method);
7095 md_args [0] = LLVMMDString (ctx->method_name, strlen (ctx->method_name));
7096 md_args [1] = LLVMConstInt (LLVMInt32Type (), method_index, FALSE);
7097 md_node = LLVMMDNode (md_args, 2);
7098 LLVMAddNamedMetadataOperand (lmodule, "mono.function_indexes", md_node);
7099 //LLVMSetMetadata (method, md_kind, LLVMMDNode (&md_arg, 1));
7102 if (cfg->compile_aot) {
7103 /* Don't generate native code, keep the LLVM IR */
7104 if (cfg->verbose_level)
7105 printf ("%s emitted as %s\n", mono_method_full_name (cfg->method, TRUE), ctx->method_name);
7107 #if LLVM_API_VERSION < 100
7108 /* VerifyFunction can't handle some of the debug info created by DIBuilder in llvm 3.9 */
7109 int err = LLVMVerifyFunction(ctx->lmethod, LLVMPrintMessageAction);
7110 g_assert (err == 0);
7113 //LLVMVerifyFunction(method, 0);
7114 #if LLVM_API_VERSION > 100
7115 MonoDomain *domain = mono_domain_get ();
7116 MonoJitDomainInfo *domain_info;
7117 int nvars = g_hash_table_size (ctx->jit_callees);
7118 LLVMValueRef *callee_vars = g_new0 (LLVMValueRef, nvars);
7119 gpointer *callee_addrs = g_new0 (gpointer, nvars);
7120 GHashTableIter iter;
7126 * Compute the addresses of the LLVM globals pointing to the
7127 * methods called by the current method. Pass it to the trampoline
7128 * code so it can update them after their corresponding method was
7131 g_hash_table_iter_init (&iter, ctx->jit_callees);
7133 while (g_hash_table_iter_next (&iter, NULL, (void**)&var))
7134 callee_vars [i ++] = var;
7136 cfg->native_code = mono_llvm_compile_method (ctx->module->mono_ee, ctx->lmethod, nvars, callee_vars, callee_addrs, &eh_frame);
7138 decode_llvm_eh_info (ctx, eh_frame);
7140 mono_domain_lock (domain);
7141 domain_info = domain_jit_info (domain);
7142 if (!domain_info->llvm_jit_callees)
7143 domain_info->llvm_jit_callees = g_hash_table_new (NULL, NULL);
7144 g_hash_table_iter_init (&iter, ctx->jit_callees);
7146 while (g_hash_table_iter_next (&iter, (void**)&callee, (void**)&var)) {
7147 GSList *addrs = g_hash_table_lookup (domain_info->llvm_jit_callees, callee);
7148 addrs = g_slist_prepend (addrs, callee_addrs [i]);
7149 g_hash_table_insert (domain_info->llvm_jit_callees, callee, addrs);
7152 mono_domain_unlock (domain);
7154 mono_llvm_optimize_method (ctx->module->mono_ee, ctx->lmethod);
7156 if (cfg->verbose_level > 1)
7157 mono_llvm_dump_value (ctx->lmethod);
7159 cfg->native_code = (unsigned char*)LLVMGetPointerToGlobal (ctx->module->ee, ctx->lmethod);
7161 /* Set by emit_cb */
7162 g_assert (cfg->code_len);
7166 if (ctx->module->method_to_lmethod)
7167 g_hash_table_insert (ctx->module->method_to_lmethod, cfg->method, ctx->lmethod);
7168 if (ctx->module->idx_to_lmethod)
7169 g_hash_table_insert (ctx->module->idx_to_lmethod, GINT_TO_POINTER (cfg->method_index), ctx->lmethod);
7171 if (ctx->llvm_only && cfg->orig_method->klass->valuetype && !(cfg->orig_method->flags & METHOD_ATTRIBUTE_STATIC))
7172 emit_unbox_tramp (ctx, ctx->method_name, ctx->method_type, ctx->lmethod, cfg->method_index);
7176 * mono_llvm_create_vars:
7178 * Same as mono_arch_create_vars () for LLVM.
7181 mono_llvm_create_vars (MonoCompile *cfg)
7183 MonoMethodSignature *sig;
7185 sig = mono_method_signature (cfg->method);
7186 if (cfg->gsharedvt && cfg->llvm_only) {
7187 if (mini_is_gsharedvt_variable_signature (sig) && sig->ret->type != MONO_TYPE_VOID) {
7188 cfg->vret_addr = mono_compile_create_var (cfg, &mono_get_intptr_class ()->byval_arg, OP_ARG);
7189 if (G_UNLIKELY (cfg->verbose_level > 1)) {
7190 printf ("vret_addr = ");
7191 mono_print_ins (cfg->vret_addr);
7195 mono_arch_create_vars (cfg);
7200 * mono_llvm_emit_call:
7202 * Same as mono_arch_emit_call () for LLVM.
7205 mono_llvm_emit_call (MonoCompile *cfg, MonoCallInst *call)
7208 MonoMethodSignature *sig;
7209 int i, n, stack_size;
7214 sig = call->signature;
7215 n = sig->param_count + sig->hasthis;
7217 call->cinfo = get_llvm_call_info (cfg, sig);
7219 if (cfg->disable_llvm)
7222 if (sig->call_convention == MONO_CALL_VARARG) {
7223 cfg->exception_message = g_strdup ("varargs");
7224 cfg->disable_llvm = TRUE;
7227 for (i = 0; i < n; ++i) {
7230 ainfo = call->cinfo->args + i;
7232 in = call->args [i];
7234 /* Simply remember the arguments */
7235 switch (ainfo->storage) {
7236 case LLVMArgNormal: {
7237 MonoType *t = (sig->hasthis && i == 0) ? &mono_get_intptr_class ()->byval_arg : ainfo->type;
7240 opcode = mono_type_to_regmove (cfg, t);
7241 if (opcode == OP_FMOVE) {
7242 MONO_INST_NEW (cfg, ins, OP_FMOVE);
7243 ins->dreg = mono_alloc_freg (cfg);
7244 } else if (opcode == OP_LMOVE) {
7245 MONO_INST_NEW (cfg, ins, OP_LMOVE);
7246 ins->dreg = mono_alloc_lreg (cfg);
7247 } else if (opcode == OP_RMOVE) {
7248 MONO_INST_NEW (cfg, ins, OP_RMOVE);
7249 ins->dreg = mono_alloc_freg (cfg);
7251 MONO_INST_NEW (cfg, ins, OP_MOVE);
7252 ins->dreg = mono_alloc_ireg (cfg);
7254 ins->sreg1 = in->dreg;
7257 case LLVMArgVtypeByVal:
7258 case LLVMArgVtypeByRef:
7259 case LLVMArgVtypeInReg:
7260 case LLVMArgVtypeAsScalar:
7261 case LLVMArgAsIArgs:
7262 case LLVMArgAsFpArgs:
7263 case LLVMArgGsharedvtVariable:
7264 case LLVMArgGsharedvtFixed:
7265 case LLVMArgGsharedvtFixedVtype:
7266 MONO_INST_NEW (cfg, ins, OP_LLVM_OUTARG_VT);
7267 ins->dreg = mono_alloc_ireg (cfg);
7268 ins->sreg1 = in->dreg;
7269 ins->inst_p0 = mono_mempool_alloc0 (cfg->mempool, sizeof (LLVMArgInfo));
7270 memcpy (ins->inst_p0, ainfo, sizeof (LLVMArgInfo));
7271 ins->inst_vtype = ainfo->type;
7272 ins->klass = mono_class_from_mono_type (ainfo->type);
7275 cfg->exception_message = g_strdup ("ainfo->storage");
7276 cfg->disable_llvm = TRUE;
7280 if (!cfg->disable_llvm) {
7281 MONO_ADD_INS (cfg->cbb, ins);
7282 mono_call_inst_add_outarg_reg (cfg, call, ins->dreg, 0, FALSE);
7287 static unsigned char*
7288 alloc_cb (LLVMValueRef function, int size)
7292 cfg = (MonoCompile*)mono_native_tls_get_value (current_cfg_tls_id);
7296 return (unsigned char*)mono_domain_code_reserve (cfg->domain, size);
7298 return (unsigned char*)mono_domain_code_reserve (mono_domain_get (), size);
7303 emitted_cb (LLVMValueRef function, void *start, void *end)
7307 cfg = (MonoCompile*)mono_native_tls_get_value (current_cfg_tls_id);
7309 cfg->code_len = (guint8*)end - (guint8*)start;
7313 exception_cb (void *data)
7316 MonoJitExceptionInfo *ei;
7317 guint32 ei_len, i, j, nested_len, nindex;
7318 gpointer *type_info;
7319 int this_reg, this_offset;
7321 cfg = (MonoCompile*)mono_native_tls_get_value (current_cfg_tls_id);
7325 * data points to a DWARF FDE structure, convert it to our unwind format and
7327 * An alternative would be to save it directly, and modify our unwinder to work
7330 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);
7331 if (cfg->verbose_level > 1)
7332 mono_print_unwind_info (cfg->encoded_unwind_ops, cfg->encoded_unwind_ops_len);
7334 /* Count nested clauses */
7336 for (i = 0; i < ei_len; ++i) {
7337 gint32 cindex1 = *(gint32*)type_info [i];
7338 MonoExceptionClause *clause1 = &cfg->header->clauses [cindex1];
7340 for (j = 0; j < cfg->header->num_clauses; ++j) {
7342 MonoExceptionClause *clause2 = &cfg->header->clauses [cindex2];
7344 if (cindex1 != cindex2 && clause1->try_offset >= clause2->try_offset && clause1->handler_offset <= clause2->handler_offset) {
7350 cfg->llvm_ex_info = (MonoJitExceptionInfo*)mono_mempool_alloc0 (cfg->mempool, (ei_len + nested_len) * sizeof (MonoJitExceptionInfo));
7351 cfg->llvm_ex_info_len = ei_len + nested_len;
7352 memcpy (cfg->llvm_ex_info, ei, ei_len * sizeof (MonoJitExceptionInfo));
7353 /* Fill the rest of the information from the type info */
7354 for (i = 0; i < ei_len; ++i) {
7355 gint32 clause_index = *(gint32*)type_info [i];
7356 MonoExceptionClause *clause = &cfg->header->clauses [clause_index];
7358 cfg->llvm_ex_info [i].flags = clause->flags;
7359 cfg->llvm_ex_info [i].data.catch_class = clause->data.catch_class;
7360 cfg->llvm_ex_info [i].clause_index = clause_index;
7364 * For nested clauses, the LLVM produced exception info associates the try interval with
7365 * the innermost handler, while mono expects it to be associated with all nesting clauses.
7366 * So add new clauses which use the IL info (catch class etc.) from the nesting clause,
7367 * and everything else from the nested clause.
7370 for (i = 0; i < ei_len; ++i) {
7371 gint32 cindex1 = *(gint32*)type_info [i];
7372 MonoExceptionClause *clause1 = &cfg->header->clauses [cindex1];
7374 for (j = 0; j < cfg->header->num_clauses; ++j) {
7376 MonoExceptionClause *clause2 = &cfg->header->clauses [cindex2];
7377 MonoJitExceptionInfo *nesting_ei, *nested_ei;
7379 if (cindex1 != cindex2 && clause1->try_offset >= clause2->try_offset && clause1->handler_offset <= clause2->handler_offset) {
7380 /* clause1 is the nested clause */
7381 nested_ei = &cfg->llvm_ex_info [i];
7382 nesting_ei = &cfg->llvm_ex_info [nindex];
7385 memcpy (nesting_ei, nested_ei, sizeof (MonoJitExceptionInfo));
7387 nesting_ei->flags = clause2->flags;
7388 nesting_ei->data.catch_class = clause2->data.catch_class;
7389 nesting_ei->clause_index = cindex2;
7393 g_assert (nindex == ei_len + nested_len);
7394 cfg->llvm_this_reg = this_reg;
7395 cfg->llvm_this_offset = this_offset;
7397 /* type_info [i] is cfg mempool allocated, no need to free it */
7403 #if LLVM_API_VERSION > 100
7405 * decode_llvm_eh_info:
7407 * Decode the EH table emitted by llvm in jit mode, and store
7408 * the result into cfg.
7411 decode_llvm_eh_info (EmitContext *ctx, gpointer eh_frame)
7413 MonoCompile *cfg = ctx->cfg;
7416 MonoLLVMFDEInfo info;
7417 MonoJitExceptionInfo *ei;
7418 guint8 *p = eh_frame;
7419 int version, fde_count, fde_offset;
7420 guint32 ei_len, i, nested_len;
7421 gpointer *type_info;
7425 * Decode the one element EH table emitted by the MonoException class
7429 /* Similar to decode_llvm_mono_eh_frame () in aot-runtime.c */
7432 g_assert (version == 3);
7435 p = (guint8 *)ALIGN_PTR_TO (p, 4);
7437 fde_count = *(guint32*)p;
7441 g_assert (fde_count == 1);
7443 /* The only table entry */
7444 fde_offset = table [1];
7447 cfg->code_len = table [0];
7448 fde_len = table [1] - fde_offset;
7451 fde = (guint8*)eh_frame + fde_offset;
7452 cie = (guint8*)table;
7454 mono_unwind_decode_llvm_mono_fde (fde, fde_len, cie, cfg->native_code, &info);
7456 cfg->encoded_unwind_ops = info.unw_info;
7457 cfg->encoded_unwind_ops_len = info.unw_info_len;
7458 if (cfg->verbose_level > 1)
7459 mono_print_unwind_info (cfg->encoded_unwind_ops, cfg->encoded_unwind_ops_len);
7460 if (info.this_reg != -1) {
7461 cfg->llvm_this_reg = info.this_reg;
7462 cfg->llvm_this_offset = info.this_offset;
7466 ei_len = info.ex_info_len;
7467 type_info = info.type_info;
7469 // Nested clauses are currently disabled
7472 cfg->llvm_ex_info = (MonoJitExceptionInfo*)mono_mempool_alloc0 (cfg->mempool, (ei_len + nested_len) * sizeof (MonoJitExceptionInfo));
7473 cfg->llvm_ex_info_len = ei_len + nested_len;
7474 memcpy (cfg->llvm_ex_info, ei, ei_len * sizeof (MonoJitExceptionInfo));
7475 /* Fill the rest of the information from the type info */
7476 for (i = 0; i < ei_len; ++i) {
7477 gint32 clause_index = *(gint32*)type_info [i];
7478 MonoExceptionClause *clause = &cfg->header->clauses [clause_index];
7480 cfg->llvm_ex_info [i].flags = clause->flags;
7481 cfg->llvm_ex_info [i].data.catch_class = clause->data.catch_class;
7482 cfg->llvm_ex_info [i].clause_index = clause_index;
7488 dlsym_cb (const char *name, void **symbol)
7494 if (!strcmp (name, "__bzero")) {
7495 *symbol = (void*)bzero;
7497 current = mono_dl_open (NULL, 0, NULL);
7500 err = mono_dl_symbol (current, name, symbol);
7502 mono_dl_close (current);
7504 #ifdef MONO_ARCH_HAVE_CREATE_LLVM_NATIVE_THUNK
7505 *symbol = (char*)mono_arch_create_llvm_native_thunk (mono_domain_get (), (guint8*)(*symbol));
7511 AddFunc (LLVMModuleRef module, const char *name, LLVMTypeRef ret_type, LLVMTypeRef *param_types, int nparams)
7513 LLVMAddFunction (module, name, LLVMFunctionType (ret_type, param_types, nparams, FALSE));
7517 AddFunc2 (LLVMModuleRef module, const char *name, LLVMTypeRef ret_type, LLVMTypeRef param_type1, LLVMTypeRef param_type2)
7519 LLVMTypeRef param_types [4];
7521 param_types [0] = param_type1;
7522 param_types [1] = param_type2;
7524 AddFunc (module, name, ret_type, param_types, 2);
7530 INTRINS_SADD_OVF_I32,
7531 INTRINS_UADD_OVF_I32,
7532 INTRINS_SSUB_OVF_I32,
7533 INTRINS_USUB_OVF_I32,
7534 INTRINS_SMUL_OVF_I32,
7535 INTRINS_UMUL_OVF_I32,
7536 INTRINS_SADD_OVF_I64,
7537 INTRINS_UADD_OVF_I64,
7538 INTRINS_SSUB_OVF_I64,
7539 INTRINS_USUB_OVF_I64,
7540 INTRINS_SMUL_OVF_I64,
7541 INTRINS_UMUL_OVF_I64,
7548 #if defined(TARGET_AMD64) || defined(TARGET_X86)
7549 INTRINS_SSE_PMOVMSKB,
7550 INTRINS_SSE_PSRLI_W,
7551 INTRINS_SSE_PSRAI_W,
7552 INTRINS_SSE_PSLLI_W,
7553 INTRINS_SSE_PSRLI_D,
7554 INTRINS_SSE_PSRAI_D,
7555 INTRINS_SSE_PSLLI_D,
7556 INTRINS_SSE_PSRLI_Q,
7557 INTRINS_SSE_PSLLI_Q,
7558 INTRINS_SSE_SQRT_PD,
7559 INTRINS_SSE_SQRT_PS,
7560 INTRINS_SSE_RSQRT_PS,
7562 INTRINS_SSE_CVTTPD2DQ,
7563 INTRINS_SSE_CVTTPS2DQ,
7564 INTRINS_SSE_CVTDQ2PD,
7565 INTRINS_SSE_CVTDQ2PS,
7566 INTRINS_SSE_CVTPD2DQ,
7567 INTRINS_SSE_CVTPS2DQ,
7568 INTRINS_SSE_CVTPD2PS,
7569 INTRINS_SSE_CVTPS2PD,
7572 INTRINS_SSE_PACKSSWB,
7573 INTRINS_SSE_PACKUSWB,
7574 INTRINS_SSE_PACKSSDW,
7575 INTRINS_SSE_PACKUSDW,
7580 INTRINS_SSE_ADDSUBPS,
7585 INTRINS_SSE_ADDSUBPD,
7593 INTRINS_SSE_PADDUSW,
7594 INTRINS_SSE_PSUBUSW,
7602 INTRINS_SSE_PADDUSB,
7603 INTRINS_SSE_PSUBUSB,
7615 static IntrinsicDesc intrinsics[] = {
7616 {INTRINS_MEMSET, "llvm.memset.p0i8.i32"},
7617 {INTRINS_MEMCPY, "llvm.memcpy.p0i8.p0i8.i32"},
7618 {INTRINS_SADD_OVF_I32, "llvm.sadd.with.overflow.i32"},
7619 {INTRINS_UADD_OVF_I32, "llvm.uadd.with.overflow.i32"},
7620 {INTRINS_SSUB_OVF_I32, "llvm.ssub.with.overflow.i32"},
7621 {INTRINS_USUB_OVF_I32, "llvm.usub.with.overflow.i32"},
7622 {INTRINS_SMUL_OVF_I32, "llvm.smul.with.overflow.i32"},
7623 {INTRINS_UMUL_OVF_I32, "llvm.umul.with.overflow.i32"},
7624 {INTRINS_SADD_OVF_I64, "llvm.sadd.with.overflow.i64"},
7625 {INTRINS_UADD_OVF_I64, "llvm.uadd.with.overflow.i64"},
7626 {INTRINS_SSUB_OVF_I64, "llvm.ssub.with.overflow.i64"},
7627 {INTRINS_USUB_OVF_I64, "llvm.usub.with.overflow.i64"},
7628 {INTRINS_SMUL_OVF_I64, "llvm.smul.with.overflow.i64"},
7629 {INTRINS_UMUL_OVF_I64, "llvm.umul.with.overflow.i64"},
7630 {INTRINS_SIN, "llvm.sin.f64"},
7631 {INTRINS_COS, "llvm.cos.f64"},
7632 {INTRINS_SQRT, "llvm.sqrt.f64"},
7633 /* This isn't an intrinsic, instead llvm seems to special case it by name */
7634 {INTRINS_FABS, "fabs"},
7635 {INTRINS_EXPECT_I8, "llvm.expect.i8"},
7636 {INTRINS_EXPECT_I1, "llvm.expect.i1"},
7637 #if defined(TARGET_AMD64) || defined(TARGET_X86)
7638 {INTRINS_SSE_PMOVMSKB, "llvm.x86.sse2.pmovmskb.128"},
7639 {INTRINS_SSE_PSRLI_W, "llvm.x86.sse2.psrli.w"},
7640 {INTRINS_SSE_PSRAI_W, "llvm.x86.sse2.psrai.w"},
7641 {INTRINS_SSE_PSLLI_W, "llvm.x86.sse2.pslli.w"},
7642 {INTRINS_SSE_PSRLI_D, "llvm.x86.sse2.psrli.d"},
7643 {INTRINS_SSE_PSRAI_D, "llvm.x86.sse2.psrai.d"},
7644 {INTRINS_SSE_PSLLI_D, "llvm.x86.sse2.pslli.d"},
7645 {INTRINS_SSE_PSRLI_Q, "llvm.x86.sse2.psrli.q"},
7646 {INTRINS_SSE_PSLLI_Q, "llvm.x86.sse2.pslli.q"},
7647 {INTRINS_SSE_SQRT_PD, "llvm.x86.sse2.sqrt.pd"},
7648 {INTRINS_SSE_SQRT_PS, "llvm.x86.sse.sqrt.ps"},
7649 {INTRINS_SSE_RSQRT_PS, "llvm.x86.sse.rsqrt.ps"},
7650 {INTRINS_SSE_RCP_PS, "llvm.x86.sse.rcp.ps"},
7651 {INTRINS_SSE_CVTTPD2DQ, "llvm.x86.sse2.cvttpd2dq"},
7652 {INTRINS_SSE_CVTTPS2DQ, "llvm.x86.sse2.cvttps2dq"},
7653 {INTRINS_SSE_CVTDQ2PD, "llvm.x86.sse2.cvtdq2pd"},
7654 {INTRINS_SSE_CVTDQ2PS, "llvm.x86.sse2.cvtdq2ps"},
7655 {INTRINS_SSE_CVTPD2DQ, "llvm.x86.sse2.cvtpd2dq"},
7656 {INTRINS_SSE_CVTPS2DQ, "llvm.x86.sse2.cvtps2dq"},
7657 {INTRINS_SSE_CVTPD2PS, "llvm.x86.sse2.cvtpd2ps"},
7658 {INTRINS_SSE_CVTPS2PD, "llvm.x86.sse2.cvtps2pd"},
7659 {INTRINS_SSE_CMPPD, "llvm.x86.sse2.cmp.pd"},
7660 {INTRINS_SSE_CMPPS, "llvm.x86.sse.cmp.ps"},
7661 {INTRINS_SSE_PACKSSWB, "llvm.x86.sse2.packsswb.128"},
7662 {INTRINS_SSE_PACKUSWB, "llvm.x86.sse2.packuswb.128"},
7663 {INTRINS_SSE_PACKSSDW, "llvm.x86.sse2.packssdw.128"},
7664 {INTRINS_SSE_PACKUSDW, "llvm.x86.sse41.packusdw"},
7665 {INTRINS_SSE_MINPS, "llvm.x86.sse.min.ps"},
7666 {INTRINS_SSE_MAXPS, "llvm.x86.sse.max.ps"},
7667 {INTRINS_SSE_HADDPS, "llvm.x86.sse3.hadd.ps"},
7668 {INTRINS_SSE_HSUBPS, "llvm.x86.sse3.hsub.ps"},
7669 {INTRINS_SSE_ADDSUBPS, "llvm.x86.sse3.addsub.ps"},
7670 {INTRINS_SSE_MINPD, "llvm.x86.sse2.min.pd"},
7671 {INTRINS_SSE_MAXPD, "llvm.x86.sse2.max.pd"},
7672 {INTRINS_SSE_HADDPD, "llvm.x86.sse3.hadd.pd"},
7673 {INTRINS_SSE_HSUBPD, "llvm.x86.sse3.hsub.pd"},
7674 {INTRINS_SSE_ADDSUBPD, "llvm.x86.sse3.addsub.pd"},
7675 {INTRINS_SSE_PMINUD, "llvm.x86.sse41.pminud"},
7676 {INTRINS_SSE_PMAXUD, "llvm.x86.sse41.pmaxud"},
7677 {INTRINS_SSE_PMINUW, "llvm.x86.sse41.pminuw"},
7678 {INTRINS_SSE_PMINSW, "llvm.x86.sse2.pmins.w"},
7679 {INTRINS_SSE_PMAXUW, "llvm.x86.sse41.pmaxuw"},
7680 {INTRINS_SSE_PADDSW, "llvm.x86.sse2.padds.w"},
7681 {INTRINS_SSE_PSUBSW, "llvm.x86.sse2.psubs.w"},
7682 {INTRINS_SSE_PADDUSW, "llvm.x86.sse2.paddus.w"},
7683 {INTRINS_SSE_PSUBUSW, "llvm.x86.sse2.psubus.w"},
7684 {INTRINS_SSE_PAVGW, "llvm.x86.sse2.pavg.w"},
7685 {INTRINS_SSE_PMULHW, "llvm.x86.sse2.pmulh.w"},
7686 {INTRINS_SSE_PMULHU, "llvm.x86.sse2.pmulhu.w"},
7687 {INTRINS_SSE_PMINUB, "llvm.x86.sse2.pminu.b"},
7688 {INTRINS_SSE_PMAXUB, "llvm.x86.sse2.pmaxu.b"},
7689 {INTRINS_SE_PADDSB, "llvm.x86.sse2.padds.b"},
7690 {INTRINS_SSE_PSUBSB, "llvm.x86.sse2.psubs.b"},
7691 {INTRINS_SSE_PADDUSB, "llvm.x86.sse2.paddus.b"},
7692 {INTRINS_SSE_PSUBUSB, "llvm.x86.sse2.psubus.b"},
7693 {INTRINS_SSE_PAVGB, "llvm.x86.sse2.pavg.b"},
7694 {INTRINS_SSE_PAUSE, "llvm.x86.sse2.pause"}
7699 add_sse_binary (LLVMModuleRef module, const char *name, int type)
7701 LLVMTypeRef ret_type = type_to_simd_type (type);
7702 AddFunc2 (module, name, ret_type, ret_type, ret_type);
7706 add_intrinsic (LLVMModuleRef module, int id)
7709 LLVMTypeRef ret_type, arg_types [16];
7711 name = g_hash_table_lookup (intrins_id_to_name, GINT_TO_POINTER (id));
7715 case INTRINS_MEMSET: {
7716 LLVMTypeRef params [] = { LLVMPointerType (LLVMInt8Type (), 0), LLVMInt8Type (), LLVMInt32Type (), LLVMInt32Type (), LLVMInt1Type () };
7718 AddFunc (module, name, LLVMVoidType (), params, 5);
7721 case INTRINS_MEMCPY: {
7722 LLVMTypeRef params [] = { LLVMPointerType (LLVMInt8Type (), 0), LLVMPointerType (LLVMInt8Type (), 0), LLVMInt32Type (), LLVMInt32Type (), LLVMInt1Type () };
7724 AddFunc (module, name, LLVMVoidType (), params, 5);
7727 case INTRINS_SADD_OVF_I32:
7728 case INTRINS_UADD_OVF_I32:
7729 case INTRINS_SSUB_OVF_I32:
7730 case INTRINS_USUB_OVF_I32:
7731 case INTRINS_SMUL_OVF_I32:
7732 case INTRINS_UMUL_OVF_I32: {
7733 LLVMTypeRef ovf_res_i32 [] = { LLVMInt32Type (), LLVMInt1Type () };
7734 LLVMTypeRef params [] = { LLVMInt32Type (), LLVMInt32Type () };
7735 LLVMTypeRef ret_type = LLVMStructType (ovf_res_i32, 2, FALSE);
7737 AddFunc (module, name, ret_type, params, 2);
7740 case INTRINS_SADD_OVF_I64:
7741 case INTRINS_UADD_OVF_I64:
7742 case INTRINS_SSUB_OVF_I64:
7743 case INTRINS_USUB_OVF_I64:
7744 case INTRINS_SMUL_OVF_I64:
7745 case INTRINS_UMUL_OVF_I64: {
7746 LLVMTypeRef ovf_res_i64 [] = { LLVMInt64Type (), LLVMInt1Type () };
7747 LLVMTypeRef params [] = { LLVMInt64Type (), LLVMInt64Type () };
7748 LLVMTypeRef ret_type = LLVMStructType (ovf_res_i64, 2, FALSE);
7750 AddFunc (module, name, ret_type, params, 2);
7756 case INTRINS_FABS: {
7757 LLVMTypeRef params [] = { LLVMDoubleType () };
7759 AddFunc (module, name, LLVMDoubleType (), params, 1);
7762 case INTRINS_EXPECT_I8:
7763 AddFunc2 (module, name, LLVMInt8Type (), LLVMInt8Type (), LLVMInt8Type ());
7765 case INTRINS_EXPECT_I1:
7766 AddFunc2 (module, name, LLVMInt1Type (), LLVMInt1Type (), LLVMInt1Type ());
7768 #if defined(TARGET_AMD64) || defined(TARGET_X86)
7769 case INTRINS_SSE_PMOVMSKB:
7771 ret_type = LLVMInt32Type ();
7772 arg_types [0] = type_to_simd_type (MONO_TYPE_I1);
7773 AddFunc (module, name, ret_type, arg_types, 1);
7775 case INTRINS_SSE_PSRLI_W:
7776 case INTRINS_SSE_PSRAI_W:
7777 case INTRINS_SSE_PSLLI_W:
7779 ret_type = type_to_simd_type (MONO_TYPE_I2);
7780 arg_types [0] = ret_type;
7781 arg_types [1] = LLVMInt32Type ();
7782 AddFunc (module, name, ret_type, arg_types, 2);
7784 case INTRINS_SSE_PSRLI_D:
7785 case INTRINS_SSE_PSRAI_D:
7786 case INTRINS_SSE_PSLLI_D:
7787 ret_type = type_to_simd_type (MONO_TYPE_I4);
7788 arg_types [0] = ret_type;
7789 arg_types [1] = LLVMInt32Type ();
7790 AddFunc (module, name, ret_type, arg_types, 2);
7792 case INTRINS_SSE_PSRLI_Q:
7793 case INTRINS_SSE_PSLLI_Q:
7794 ret_type = type_to_simd_type (MONO_TYPE_I8);
7795 arg_types [0] = ret_type;
7796 arg_types [1] = LLVMInt32Type ();
7797 AddFunc (module, name, ret_type, arg_types, 2);
7799 case INTRINS_SSE_SQRT_PD:
7801 ret_type = type_to_simd_type (MONO_TYPE_R8);
7802 arg_types [0] = ret_type;
7803 AddFunc (module, name, ret_type, arg_types, 1);
7805 case INTRINS_SSE_SQRT_PS:
7806 ret_type = type_to_simd_type (MONO_TYPE_R4);
7807 arg_types [0] = ret_type;
7808 AddFunc (module, name, ret_type, arg_types, 1);
7810 case INTRINS_SSE_RSQRT_PS:
7811 ret_type = type_to_simd_type (MONO_TYPE_R4);
7812 arg_types [0] = ret_type;
7813 AddFunc (module, name, ret_type, arg_types, 1);
7815 case INTRINS_SSE_RCP_PS:
7816 ret_type = type_to_simd_type (MONO_TYPE_R4);
7817 arg_types [0] = ret_type;
7818 AddFunc (module, name, ret_type, arg_types, 1);
7820 case INTRINS_SSE_CVTTPD2DQ:
7821 ret_type = type_to_simd_type (MONO_TYPE_I4);
7822 arg_types [0] = type_to_simd_type (MONO_TYPE_R8);
7823 AddFunc (module, name, ret_type, arg_types, 1);
7825 case INTRINS_SSE_CVTTPS2DQ:
7826 ret_type = type_to_simd_type (MONO_TYPE_I4);
7827 arg_types [0] = type_to_simd_type (MONO_TYPE_R4);
7828 AddFunc (module, name, ret_type, arg_types, 1);
7830 case INTRINS_SSE_CVTDQ2PD:
7831 /* Conversion ops */
7832 ret_type = type_to_simd_type (MONO_TYPE_R8);
7833 arg_types [0] = type_to_simd_type (MONO_TYPE_I4);
7834 AddFunc (module, name, ret_type, arg_types, 1);
7836 case INTRINS_SSE_CVTDQ2PS:
7837 ret_type = type_to_simd_type (MONO_TYPE_R4);
7838 arg_types [0] = type_to_simd_type (MONO_TYPE_I4);
7839 AddFunc (module, name, ret_type, arg_types, 1);
7841 case INTRINS_SSE_CVTPD2DQ:
7842 ret_type = type_to_simd_type (MONO_TYPE_I4);
7843 arg_types [0] = type_to_simd_type (MONO_TYPE_R8);
7844 AddFunc (module, name, ret_type, arg_types, 1);
7846 case INTRINS_SSE_CVTPS2DQ:
7847 ret_type = type_to_simd_type (MONO_TYPE_I4);
7848 arg_types [0] = type_to_simd_type (MONO_TYPE_R4);
7849 AddFunc (module, name, ret_type, arg_types, 1);
7851 case INTRINS_SSE_CVTPD2PS:
7852 ret_type = type_to_simd_type (MONO_TYPE_R4);
7853 arg_types [0] = type_to_simd_type (MONO_TYPE_R8);
7854 AddFunc (module, name, ret_type, arg_types, 1);
7856 case INTRINS_SSE_CVTPS2PD:
7857 ret_type = type_to_simd_type (MONO_TYPE_R8);
7858 arg_types [0] = type_to_simd_type (MONO_TYPE_R4);
7859 AddFunc (module, name, ret_type, arg_types, 1);
7861 case INTRINS_SSE_CMPPD:
7863 ret_type = type_to_simd_type (MONO_TYPE_R8);
7864 arg_types [0] = ret_type;
7865 arg_types [1] = ret_type;
7866 arg_types [2] = LLVMInt8Type ();
7867 AddFunc (module, name, ret_type, arg_types, 3);
7869 case INTRINS_SSE_CMPPS:
7870 ret_type = type_to_simd_type (MONO_TYPE_R4);
7871 arg_types [0] = ret_type;
7872 arg_types [1] = ret_type;
7873 arg_types [2] = LLVMInt8Type ();
7874 AddFunc (module, name, ret_type, arg_types, 3);
7876 case INTRINS_SSE_PACKSSWB:
7877 case INTRINS_SSE_PACKUSWB:
7878 case INTRINS_SSE_PACKSSDW:
7880 ret_type = type_to_simd_type (MONO_TYPE_I1);
7881 arg_types [0] = type_to_simd_type (MONO_TYPE_I2);
7882 arg_types [1] = type_to_simd_type (MONO_TYPE_I2);
7883 AddFunc (module, name, ret_type, arg_types, 2);
7885 case INTRINS_SSE_PACKUSDW:
7886 ret_type = type_to_simd_type (MONO_TYPE_I2);
7887 arg_types [0] = type_to_simd_type (MONO_TYPE_I4);
7888 arg_types [1] = type_to_simd_type (MONO_TYPE_I4);
7889 AddFunc (module, name, ret_type, arg_types, 2);
7891 /* SSE Binary ops */
7892 case INTRINS_SSE_PMINUD:
7893 case INTRINS_SSE_PMAXUD:
7894 add_sse_binary (module, name, MONO_TYPE_I4);
7896 case INTRINS_SSE_PMINUW:
7897 case INTRINS_SSE_PMINSW:
7898 case INTRINS_SSE_PMAXUW:
7899 case INTRINS_SSE_PADDSW:
7900 case INTRINS_SSE_PSUBSW:
7901 case INTRINS_SSE_PADDUSW:
7902 case INTRINS_SSE_PSUBUSW:
7903 case INTRINS_SSE_PAVGW:
7904 case INTRINS_SSE_PMULHW:
7905 case INTRINS_SSE_PMULHU:
7906 add_sse_binary (module, name, MONO_TYPE_I2);
7908 case INTRINS_SSE_MINPS:
7909 case INTRINS_SSE_MAXPS:
7910 case INTRINS_SSE_HADDPS:
7911 case INTRINS_SSE_HSUBPS:
7912 case INTRINS_SSE_ADDSUBPS:
7913 add_sse_binary (module, name, MONO_TYPE_R4);
7915 case INTRINS_SSE_MINPD:
7916 case INTRINS_SSE_MAXPD:
7917 case INTRINS_SSE_HADDPD:
7918 case INTRINS_SSE_HSUBPD:
7919 case INTRINS_SSE_ADDSUBPD:
7920 add_sse_binary (module, name, MONO_TYPE_R8);
7922 case INTRINS_SSE_PMINUB:
7923 case INTRINS_SSE_PMAXUB:
7924 case INTRINS_SE_PADDSB:
7925 case INTRINS_SSE_PSUBSB:
7926 case INTRINS_SSE_PADDUSB:
7927 case INTRINS_SSE_PSUBUSB:
7928 case INTRINS_SSE_PAVGB:
7929 add_sse_binary (module, name, MONO_TYPE_I1);
7931 case INTRINS_SSE_PAUSE:
7932 AddFunc (module, "llvm.x86.sse2.pause", LLVMVoidType (), NULL, 0);
7936 g_assert_not_reached ();
7942 get_intrinsic (EmitContext *ctx, const char *name)
7944 #if LLVM_API_VERSION > 100
7948 * Every method is emitted into its own module so
7949 * we can add intrinsics on demand.
7951 res = LLVMGetNamedFunction (ctx->lmodule, name);
7955 /* No locking needed */
7956 id = GPOINTER_TO_INT (g_hash_table_lookup (intrins_name_to_id, name));
7959 printf ("%s\n", name);
7960 g_assert (id != -1);
7961 add_intrinsic (ctx->lmodule, id);
7962 res = LLVMGetNamedFunction (ctx->lmodule, name);
7970 res = LLVMGetNamedFunction (ctx->lmodule, name);
7977 add_intrinsics (LLVMModuleRef module)
7981 /* Emit declarations of instrinsics */
7983 * It would be nicer to emit only the intrinsics actually used, but LLVM's Module
7984 * type doesn't seem to do any locking.
7986 for (i = 0; i < INTRINS_NUM; ++i)
7987 add_intrinsic (module, i);
7991 AddFunc (module, "mono_personality", LLVMVoidType (), NULL, 0);
7993 AddFunc (module, "llvm_resume_unwind_trampoline", LLVMVoidType (), NULL, 0);
7996 /* SSE intrinsics */
7997 #if defined(TARGET_X86) || defined(TARGET_AMD64)
8001 /* Load/Store intrinsics */
8003 LLVMTypeRef arg_types [5];
8007 for (i = 1; i <= 8; i *= 2) {
8008 arg_types [0] = LLVMPointerType (LLVMIntType (i * 8), 0);
8009 arg_types [1] = LLVMInt32Type ();
8010 arg_types [2] = LLVMInt1Type ();
8011 arg_types [3] = LLVMInt32Type ();
8012 sprintf (name, "llvm.mono.load.i%d.p0i%d", i * 8, i * 8);
8013 AddFunc (module, name, LLVMIntType (i * 8), arg_types, 4);
8015 arg_types [0] = LLVMIntType (i * 8);
8016 arg_types [1] = LLVMPointerType (LLVMIntType (i * 8), 0);
8017 arg_types [2] = LLVMInt32Type ();
8018 arg_types [3] = LLVMInt1Type ();
8019 arg_types [4] = LLVMInt32Type ();
8020 sprintf (name, "llvm.mono.store.i%d.p0i%d", i * 8, i * 8);
8021 AddFunc (module, name, LLVMVoidType (), arg_types, 5);
8027 add_types (MonoLLVMModule *module)
8029 module->ptr_type = LLVMPointerType (sizeof (gpointer) == 8 ? LLVMInt64Type () : LLVMInt32Type (), 0);
8033 mono_llvm_init (void)
8038 mono_native_tls_alloc (¤t_cfg_tls_id, NULL);
8040 h = g_hash_table_new (NULL, NULL);
8041 for (i = 0; i < INTRINS_NUM; ++i)
8042 g_hash_table_insert (h, GINT_TO_POINTER (intrinsics [i].id), (gpointer)intrinsics [i].name);
8043 intrins_id_to_name = h;
8045 h = g_hash_table_new (g_str_hash, g_str_equal);
8046 for (i = 0; i < INTRINS_NUM; ++i)
8047 g_hash_table_insert (h, (gpointer)intrinsics [i].name, GINT_TO_POINTER (intrinsics [i].id + 1));
8048 intrins_name_to_id = h;
8052 init_jit_module (MonoDomain *domain)
8054 MonoJitDomainInfo *dinfo;
8055 MonoLLVMModule *module;
8058 dinfo = domain_jit_info (domain);
8059 if (dinfo->llvm_module)
8062 mono_loader_lock ();
8064 if (dinfo->llvm_module) {
8065 mono_loader_unlock ();
8069 module = g_new0 (MonoLLVMModule, 1);
8071 name = g_strdup_printf ("mono-%s", domain->friendly_name);
8072 module->lmodule = LLVMModuleCreateWithName (name);
8073 module->context = LLVMGetGlobalContext ();
8075 module->mono_ee = (MonoEERef*)mono_llvm_create_ee (LLVMCreateModuleProviderForExistingModule (module->lmodule), alloc_cb, emitted_cb, exception_cb, dlsym_cb, &module->ee);
8077 add_intrinsics (module->lmodule);
8080 module->llvm_types = g_hash_table_new (NULL, NULL);
8082 #if LLVM_API_VERSION < 100
8083 MonoJitICallInfo *info;
8085 info = mono_find_jit_icall_by_name ("llvm_resume_unwind_trampoline");
8087 LLVMAddGlobalMapping (module->ee, LLVMGetNamedFunction (module->lmodule, "llvm_resume_unwind_trampoline"), (void*)info->func);
8090 mono_memory_barrier ();
8092 dinfo->llvm_module = module;
8094 mono_loader_unlock ();
8098 mono_llvm_cleanup (void)
8100 MonoLLVMModule *module = &aot_module;
8102 if (module->lmodule)
8103 LLVMDisposeModule (module->lmodule);
8105 if (module->context)
8106 LLVMContextDispose (module->context);
8110 mono_llvm_free_domain_info (MonoDomain *domain)
8112 MonoJitDomainInfo *info = domain_jit_info (domain);
8113 MonoLLVMModule *module = (MonoLLVMModule*)info->llvm_module;
8119 if (module->llvm_types)
8120 g_hash_table_destroy (module->llvm_types);
8122 mono_llvm_dispose_ee (module->mono_ee);
8124 if (module->bb_names) {
8125 for (i = 0; i < module->bb_names_len; ++i)
8126 g_free (module->bb_names [i]);
8127 g_free (module->bb_names);
8129 //LLVMDisposeModule (module->module);
8133 info->llvm_module = NULL;
8137 mono_llvm_create_aot_module (MonoAssembly *assembly, const char *global_prefix, gboolean emit_dwarf, gboolean static_link, gboolean llvm_only)
8139 MonoLLVMModule *module = &aot_module;
8141 /* Delete previous module */
8142 if (module->plt_entries)
8143 g_hash_table_destroy (module->plt_entries);
8144 if (module->lmodule)
8145 LLVMDisposeModule (module->lmodule);
8147 memset (module, 0, sizeof (aot_module));
8149 module->lmodule = LLVMModuleCreateWithName ("aot");
8150 module->assembly = assembly;
8151 module->global_prefix = g_strdup (global_prefix);
8152 module->got_symbol = g_strdup_printf ("%s_llvm_got", global_prefix);
8153 module->eh_frame_symbol = g_strdup_printf ("%s_eh_frame", global_prefix);
8154 module->get_method_symbol = g_strdup_printf ("%s_get_method", global_prefix);
8155 module->get_unbox_tramp_symbol = g_strdup_printf ("%s_get_unbox_tramp", global_prefix);
8156 module->external_symbols = TRUE;
8157 module->emit_dwarf = emit_dwarf;
8158 module->static_link = static_link;
8159 module->llvm_only = llvm_only;
8160 /* The first few entries are reserved */
8161 module->max_got_offset = 16;
8162 module->context = LLVMContextCreate ();
8165 /* clang ignores our debug info because it has an invalid version */
8166 module->emit_dwarf = FALSE;
8168 #if LLVM_API_VERSION > 100
8169 module->emit_dwarf = FALSE;
8172 add_intrinsics (module->lmodule);
8175 #if LLVM_API_VERSION > 100
8176 if (module->emit_dwarf) {
8177 char *dir, *build_info, *s, *cu_name;
8179 module->di_builder = mono_llvm_create_di_builder (module->lmodule);
8182 dir = g_strdup (".");
8183 build_info = mono_get_runtime_build_info ();
8184 s = g_strdup_printf ("Mono AOT Compiler %s (LLVM)", build_info);
8185 cu_name = g_path_get_basename (assembly->image->name);
8186 module->cu = mono_llvm_di_create_compile_unit (module->di_builder, cu_name, dir, s);
8188 g_free (build_info);
8195 * We couldn't compute the type of the LLVM global representing the got because
8196 * its size is only known after all the methods have been emitted. So create
8197 * a dummy variable, and replace all uses it with the real got variable when
8198 * its size is known in mono_llvm_emit_aot_module ().
8201 LLVMTypeRef got_type = LLVMArrayType (module->ptr_type, 0);
8203 module->got_var = LLVMAddGlobal (module->lmodule, got_type, "mono_dummy_got");
8204 LLVMSetInitializer (module->got_var, LLVMConstNull (got_type));
8207 /* Add initialization array */
8209 LLVMTypeRef inited_type = LLVMArrayType (LLVMInt8Type (), 0);
8211 module->inited_var = LLVMAddGlobal (aot_module.lmodule, inited_type, "mono_inited_tmp");
8212 LLVMSetInitializer (module->inited_var, LLVMConstNull (inited_type));
8216 emit_init_icall_wrappers (module);
8218 emit_llvm_code_start (module);
8220 /* Add a dummy personality function */
8221 if (!use_debug_personality) {
8222 LLVMValueRef personality = LLVMAddFunction (module->lmodule, default_personality_name, LLVMFunctionType (LLVMInt32Type (), NULL, 0, TRUE));
8223 LLVMSetLinkage (personality, LLVMExternalLinkage);
8224 mark_as_used (module, personality);
8227 /* Add a reference to the c++ exception we throw/catch */
8229 LLVMTypeRef exc = LLVMPointerType (LLVMInt8Type (), 0);
8230 module->sentinel_exception = LLVMAddGlobal (module->lmodule, exc, "_ZTIPi");
8231 LLVMSetLinkage (module->sentinel_exception, LLVMExternalLinkage);
8232 mono_llvm_set_is_constant (module->sentinel_exception);
8235 module->llvm_types = g_hash_table_new (NULL, NULL);
8236 module->plt_entries = g_hash_table_new (g_str_hash, g_str_equal);
8237 module->plt_entries_ji = g_hash_table_new (NULL, NULL);
8238 module->direct_callables = g_hash_table_new (g_str_hash, g_str_equal);
8239 module->method_to_lmethod = g_hash_table_new (NULL, NULL);
8240 module->idx_to_lmethod = g_hash_table_new (NULL, NULL);
8241 module->idx_to_unbox_tramp = g_hash_table_new (NULL, NULL);
8242 module->method_to_callers = g_hash_table_new (NULL, NULL);
8246 llvm_array_from_uints (LLVMTypeRef el_type, guint32 *values, int nvalues)
8249 LLVMValueRef res, *vals;
8251 vals = g_new0 (LLVMValueRef, nvalues);
8252 for (i = 0; i < nvalues; ++i)
8253 vals [i] = LLVMConstInt (LLVMInt32Type (), values [i], FALSE);
8254 res = LLVMConstArray (LLVMInt32Type (), vals, nvalues);
8260 * mono_llvm_emit_aot_file_info:
8262 * Emit the MonoAotFileInfo structure.
8263 * Same as emit_aot_file_info () in aot-compiler.c.
8266 mono_llvm_emit_aot_file_info (MonoAotFileInfo *info, gboolean has_jitted_code)
8268 MonoLLVMModule *module = &aot_module;
8270 /* Save these for later */
8271 memcpy (&module->aot_info, info, sizeof (MonoAotFileInfo));
8272 module->has_jitted_code = has_jitted_code;
8276 * mono_llvm_emit_aot_data:
8278 * Emit the binary data DATA pointed to by symbol SYMBOL.
8281 mono_llvm_emit_aot_data (const char *symbol, guint8 *data, int data_len)
8283 MonoLLVMModule *module = &aot_module;
8287 type = LLVMArrayType (LLVMInt8Type (), data_len);
8288 d = LLVMAddGlobal (module->lmodule, type, symbol);
8289 LLVMSetVisibility (d, LLVMHiddenVisibility);
8290 LLVMSetLinkage (d, LLVMInternalLinkage);
8291 LLVMSetInitializer (d, mono_llvm_create_constant_data_array (data, data_len));
8292 mono_llvm_set_is_constant (d);
8295 /* Add a reference to a global defined in JITted code */
8297 AddJitGlobal (MonoLLVMModule *module, LLVMTypeRef type, const char *name)
8302 s = g_strdup_printf ("%s%s", module->global_prefix, name);
8303 v = LLVMAddGlobal (module->lmodule, LLVMInt8Type (), s);
8309 emit_aot_file_info (MonoLLVMModule *module)
8311 LLVMTypeRef file_info_type;
8312 LLVMTypeRef *eltypes, eltype;
8313 LLVMValueRef info_var;
8314 LLVMValueRef *fields;
8315 int i, nfields, tindex;
8316 MonoAotFileInfo *info;
8317 LLVMModuleRef lmodule = module->lmodule;
8319 info = &module->aot_info;
8321 /* Create an LLVM type to represent MonoAotFileInfo */
8322 nfields = 2 + MONO_AOT_FILE_INFO_NUM_SYMBOLS + 15 + 5;
8323 eltypes = g_new (LLVMTypeRef, nfields);
8325 eltypes [tindex ++] = LLVMInt32Type ();
8326 eltypes [tindex ++] = LLVMInt32Type ();
8328 for (i = 0; i < MONO_AOT_FILE_INFO_NUM_SYMBOLS; ++i)
8329 eltypes [tindex ++] = LLVMPointerType (LLVMInt8Type (), 0);
8331 for (i = 0; i < 15; ++i)
8332 eltypes [tindex ++] = LLVMInt32Type ();
8334 eltypes [tindex ++] = LLVMArrayType (LLVMInt32Type (), MONO_AOT_TABLE_NUM);
8335 for (i = 0; i < 4; ++i)
8336 eltypes [tindex ++] = LLVMArrayType (LLVMInt32Type (), MONO_AOT_TRAMP_NUM);
8337 g_assert (tindex == nfields);
8338 file_info_type = LLVMStructCreateNamed (module->context, "MonoAotFileInfo");
8339 LLVMStructSetBody (file_info_type, eltypes, nfields, FALSE);
8341 info_var = LLVMAddGlobal (lmodule, file_info_type, "mono_aot_file_info");
8342 if (module->static_link) {
8343 LLVMSetVisibility (info_var, LLVMHiddenVisibility);
8344 LLVMSetLinkage (info_var, LLVMInternalLinkage);
8346 fields = g_new (LLVMValueRef, nfields);
8348 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->version, FALSE);
8349 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->dummy, FALSE);
8353 * We use LLVMGetNamedGlobal () for symbol which are defined in LLVM code, and LLVMAddGlobal ()
8354 * for symbols defined in the .s file emitted by the aot compiler.
8356 eltype = eltypes [tindex];
8357 if (module->llvm_only)
8358 fields [tindex ++] = LLVMConstNull (eltype);
8360 fields [tindex ++] = AddJitGlobal (module, eltype, "jit_got");
8361 fields [tindex ++] = module->got_var;
8362 /* llc defines this directly */
8363 if (!module->llvm_only) {
8364 fields [tindex ++] = LLVMAddGlobal (lmodule, eltype, module->eh_frame_symbol);
8365 fields [tindex ++] = LLVMConstNull (eltype);
8366 fields [tindex ++] = LLVMConstNull (eltype);
8368 fields [tindex ++] = LLVMConstNull (eltype);
8369 fields [tindex ++] = module->get_method;
8370 fields [tindex ++] = module->get_unbox_tramp;
8372 if (module->has_jitted_code) {
8373 fields [tindex ++] = AddJitGlobal (module, eltype, "jit_code_start");
8374 fields [tindex ++] = AddJitGlobal (module, eltype, "jit_code_end");
8376 fields [tindex ++] = LLVMConstNull (eltype);
8377 fields [tindex ++] = LLVMConstNull (eltype);
8379 if (!module->llvm_only)
8380 fields [tindex ++] = AddJitGlobal (module, eltype, "method_addresses");
8382 fields [tindex ++] = LLVMConstNull (eltype);
8383 if (info->flags & MONO_AOT_FILE_FLAG_SEPARATE_DATA) {
8384 for (i = 0; i < MONO_AOT_TABLE_NUM; ++i)
8385 fields [tindex ++] = LLVMConstNull (eltype);
8387 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "blob");
8388 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "class_name_table");
8389 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "class_info_offsets");
8390 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "method_info_offsets");
8391 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "ex_info_offsets");
8392 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "extra_method_info_offsets");
8393 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "extra_method_table");
8394 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "got_info_offsets");
8395 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "llvm_got_info_offsets");
8396 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "image_table");
8398 /* Not needed (mem_end) */
8399 fields [tindex ++] = LLVMConstNull (eltype);
8400 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "assembly_guid");
8401 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "runtime_version");
8402 if (info->trampoline_size [0]) {
8403 fields [tindex ++] = AddJitGlobal (module, eltype, "specific_trampolines");
8404 fields [tindex ++] = AddJitGlobal (module, eltype, "static_rgctx_trampolines");
8405 fields [tindex ++] = AddJitGlobal (module, eltype, "imt_thunks");
8406 fields [tindex ++] = AddJitGlobal (module, eltype, "gsharedvt_arg_trampolines");
8408 fields [tindex ++] = LLVMConstNull (eltype);
8409 fields [tindex ++] = LLVMConstNull (eltype);
8410 fields [tindex ++] = LLVMConstNull (eltype);
8411 fields [tindex ++] = LLVMConstNull (eltype);
8413 if (module->static_link && !module->llvm_only)
8414 fields [tindex ++] = AddJitGlobal (module, eltype, "globals");
8416 fields [tindex ++] = LLVMConstNull (eltype);
8417 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "assembly_name");
8418 if (!module->llvm_only) {
8419 fields [tindex ++] = AddJitGlobal (module, eltype, "plt");
8420 fields [tindex ++] = AddJitGlobal (module, eltype, "plt_end");
8421 fields [tindex ++] = AddJitGlobal (module, eltype, "unwind_info");
8422 fields [tindex ++] = AddJitGlobal (module, eltype, "unbox_trampolines");
8423 fields [tindex ++] = AddJitGlobal (module, eltype, "unbox_trampolines_end");
8424 fields [tindex ++] = AddJitGlobal (module, eltype, "unbox_trampoline_addresses");
8426 fields [tindex ++] = LLVMConstNull (eltype);
8427 fields [tindex ++] = LLVMConstNull (eltype);
8428 fields [tindex ++] = LLVMConstNull (eltype);
8429 fields [tindex ++] = LLVMConstNull (eltype);
8430 fields [tindex ++] = LLVMConstNull (eltype);
8431 fields [tindex ++] = LLVMConstNull (eltype);
8434 for (i = 0; i < MONO_AOT_FILE_INFO_NUM_SYMBOLS; ++i)
8435 fields [2 + i] = LLVMConstBitCast (fields [2 + i], eltype);
8438 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->plt_got_offset_base, FALSE);
8439 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->got_size, FALSE);
8440 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->plt_size, FALSE);
8441 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->nmethods, FALSE);
8442 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->flags, FALSE);
8443 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->opts, FALSE);
8444 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->simd_opts, FALSE);
8445 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->gc_name_index, FALSE);
8446 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->num_rgctx_fetch_trampolines, FALSE);
8447 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->double_align, FALSE);
8448 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->long_align, FALSE);
8449 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->generic_tramp_num, FALSE);
8450 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->tramp_page_size, FALSE);
8451 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->nshared_got_entries, FALSE);
8452 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->datafile_size, FALSE);
8454 fields [tindex ++] = llvm_array_from_uints (LLVMInt32Type (), info->table_offsets, MONO_AOT_TABLE_NUM);
8455 fields [tindex ++] = llvm_array_from_uints (LLVMInt32Type (), info->num_trampolines, MONO_AOT_TRAMP_NUM);
8456 fields [tindex ++] = llvm_array_from_uints (LLVMInt32Type (), info->trampoline_got_offset_base, MONO_AOT_TRAMP_NUM);
8457 fields [tindex ++] = llvm_array_from_uints (LLVMInt32Type (), info->trampoline_size, MONO_AOT_TRAMP_NUM);
8458 fields [tindex ++] = llvm_array_from_uints (LLVMInt32Type (), info->tramp_page_code_offsets, MONO_AOT_TRAMP_NUM);
8459 g_assert (tindex == nfields);
8461 LLVMSetInitializer (info_var, LLVMConstNamedStruct (file_info_type, fields, nfields));
8463 if (module->static_link) {
8467 s = g_strdup_printf ("mono_aot_module_%s_info", module->assembly->aname.name);
8468 /* Get rid of characters which cannot occur in symbols */
8470 for (p = s; *p; ++p) {
8471 if (!(isalnum (*p) || *p == '_'))
8474 var = LLVMAddGlobal (module->lmodule, LLVMPointerType (LLVMInt8Type (), 0), s);
8476 LLVMSetInitializer (var, LLVMConstBitCast (LLVMGetNamedGlobal (module->lmodule, "mono_aot_file_info"), LLVMPointerType (LLVMInt8Type (), 0)));
8477 LLVMSetLinkage (var, LLVMExternalLinkage);
8482 * Emit the aot module into the LLVM bitcode file FILENAME.
8485 mono_llvm_emit_aot_module (const char *filename, const char *cu_name)
8487 LLVMTypeRef got_type, inited_type;
8488 LLVMValueRef real_got, real_inited;
8489 MonoLLVMModule *module = &aot_module;
8491 emit_llvm_code_end (module);
8494 * Create the real got variable and replace all uses of the dummy variable with
8497 got_type = LLVMArrayType (module->ptr_type, module->max_got_offset + 1);
8498 real_got = LLVMAddGlobal (module->lmodule, got_type, module->got_symbol);
8499 LLVMSetInitializer (real_got, LLVMConstNull (got_type));
8500 if (module->external_symbols) {
8501 LLVMSetLinkage (real_got, LLVMExternalLinkage);
8502 LLVMSetVisibility (real_got, LLVMHiddenVisibility);
8504 LLVMSetLinkage (real_got, LLVMInternalLinkage);
8506 mono_llvm_replace_uses_of (module->got_var, real_got);
8508 mark_as_used (&aot_module, real_got);
8510 /* Delete the dummy got so it doesn't become a global */
8511 LLVMDeleteGlobal (module->got_var);
8512 module->got_var = real_got;
8515 * Same for the init_var
8517 if (module->llvm_only) {
8518 inited_type = LLVMArrayType (LLVMInt8Type (), module->max_inited_idx + 1);
8519 real_inited = LLVMAddGlobal (module->lmodule, inited_type, "mono_inited");
8520 LLVMSetInitializer (real_inited, LLVMConstNull (inited_type));
8521 LLVMSetLinkage (real_inited, LLVMInternalLinkage);
8522 mono_llvm_replace_uses_of (module->inited_var, real_inited);
8523 LLVMDeleteGlobal (module->inited_var);
8526 if (module->llvm_only) {
8527 emit_get_method (&aot_module);
8528 emit_get_unbox_tramp (&aot_module);
8531 emit_llvm_used (&aot_module);
8532 emit_dbg_info (&aot_module, filename, cu_name);
8533 emit_aot_file_info (&aot_module);
8536 * Replace GOT entries for directly callable methods with the methods themselves.
8537 * It would be easier to implement this by predefining all methods before compiling
8538 * their bodies, but that couldn't handle the case when a method fails to compile
8541 if (module->llvm_only) {
8542 GHashTableIter iter;
8544 GSList *callers, *l;
8546 g_hash_table_iter_init (&iter, module->method_to_callers);
8547 while (g_hash_table_iter_next (&iter, (void**)&method, (void**)&callers)) {
8548 LLVMValueRef lmethod;
8550 lmethod = (LLVMValueRef)g_hash_table_lookup (module->method_to_lmethod, method);
8552 for (l = callers; l; l = l->next) {
8553 LLVMValueRef caller = (LLVMValueRef)l->data;
8555 mono_llvm_replace_uses_of (caller, lmethod);
8561 /* Replace PLT entries for directly callable methods with the methods themselves */
8563 GHashTableIter iter;
8565 LLVMValueRef callee;
8567 g_hash_table_iter_init (&iter, module->plt_entries_ji);
8568 while (g_hash_table_iter_next (&iter, (void**)&ji, (void**)&callee)) {
8569 if (mono_aot_is_direct_callable (ji)) {
8570 LLVMValueRef lmethod;
8572 lmethod = (LLVMValueRef)g_hash_table_lookup (module->method_to_lmethod, ji->data.method);
8573 /* The types might not match because the caller might pass an rgctx */
8574 if (lmethod && LLVMTypeOf (callee) == LLVMTypeOf (lmethod)) {
8575 mono_llvm_replace_uses_of (callee, lmethod);
8576 mono_aot_mark_unused_llvm_plt_entry (ji);
8586 if (LLVMVerifyModule (module->lmodule, LLVMReturnStatusAction, &verifier_err)) {
8587 g_assert_not_reached ();
8592 LLVMWriteBitcodeToFile (module->lmodule, filename);
8597 md_string (const char *s)
8599 return LLVMMDString (s, strlen (s));
8602 /* Debugging support */
8605 emit_dbg_info (MonoLLVMModule *module, const char *filename, const char *cu_name)
8607 LLVMModuleRef lmodule = module->lmodule;
8608 LLVMValueRef args [16], ver;
8611 * This can only be enabled when LLVM code is emitted into a separate object
8612 * file, since the AOT compiler also emits dwarf info,
8613 * and the abbrev indexes will not be correct since llvm has added its own
8616 if (!module->emit_dwarf)
8619 #if LLVM_API_VERSION > 100
8620 mono_llvm_di_builder_finalize (module->di_builder);
8622 LLVMValueRef cu_args [16], cu;
8624 char *build_info, *s, *dir;
8627 * Emit dwarf info in the form of LLVM metadata. There is some
8628 * out-of-date documentation at:
8629 * http://llvm.org/docs/SourceLevelDebugging.html
8630 * but most of this was gathered from the llvm and
8635 cu_args [n_cuargs ++] = LLVMConstInt (LLVMInt32Type (), DW_TAG_compile_unit, FALSE);
8636 /* CU name/compilation dir */
8637 dir = g_path_get_dirname (filename);
8638 args [0] = LLVMMDString (cu_name, strlen (cu_name));
8639 args [1] = LLVMMDString (dir, strlen (dir));
8640 cu_args [n_cuargs ++] = LLVMMDNode (args, 2);
8643 cu_args [n_cuargs ++] = LLVMConstInt (LLVMInt32Type (), DW_LANG_C99, FALSE);
8645 build_info = mono_get_runtime_build_info ();
8646 s = g_strdup_printf ("Mono AOT Compiler %s (LLVM)", build_info);
8647 cu_args [n_cuargs ++] = LLVMMDString (s, strlen (s));
8648 g_free (build_info);
8650 cu_args [n_cuargs ++] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
8652 cu_args [n_cuargs ++] = LLVMMDString ("", strlen (""));
8653 /* Runtime version */
8654 cu_args [n_cuargs ++] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
8656 cu_args [n_cuargs ++] = LLVMMDNode (args, 0);
8657 cu_args [n_cuargs ++] = LLVMMDNode (args, 0);
8659 if (module->subprogram_mds) {
8663 mds = g_new0 (LLVMValueRef, module->subprogram_mds->len);
8664 for (i = 0; i < module->subprogram_mds->len; ++i)
8665 mds [i] = (LLVMValueRef)g_ptr_array_index (module->subprogram_mds, i);
8666 cu_args [n_cuargs ++] = LLVMMDNode (mds, module->subprogram_mds->len);
8668 cu_args [n_cuargs ++] = LLVMMDNode (args, 0);
8671 cu_args [n_cuargs ++] = LLVMMDNode (args, 0);
8672 /* Imported modules */
8673 cu_args [n_cuargs ++] = LLVMMDNode (args, 0);
8675 cu_args [n_cuargs ++] = LLVMMDString ("", strlen (""));
8676 /* DebugEmissionKind = FullDebug */
8677 cu_args [n_cuargs ++] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
8678 cu = LLVMMDNode (cu_args, n_cuargs);
8679 LLVMAddNamedMetadataOperand (lmodule, "llvm.dbg.cu", cu);
8682 #if LLVM_API_VERSION > 100
8683 args [0] = LLVMConstInt (LLVMInt32Type (), 2, FALSE);
8684 args [1] = LLVMMDString ("Dwarf Version", strlen ("Dwarf Version"));
8685 args [2] = LLVMConstInt (LLVMInt32Type (), 2, FALSE);
8686 ver = LLVMMDNode (args, 3);
8687 LLVMAddNamedMetadataOperand (lmodule, "llvm.module.flags", ver);
8689 args [0] = LLVMConstInt (LLVMInt32Type (), 2, FALSE);
8690 args [1] = LLVMMDString ("Debug Info Version", strlen ("Debug Info Version"));
8691 args [2] = LLVMConstInt (LLVMInt64Type (), 3, FALSE);
8692 ver = LLVMMDNode (args, 3);
8693 LLVMAddNamedMetadataOperand (lmodule, "llvm.module.flags", ver);
8695 args [0] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
8696 args [1] = LLVMMDString ("Dwarf Version", strlen ("Dwarf Version"));
8697 args [2] = LLVMConstInt (LLVMInt32Type (), 2, FALSE);
8698 ver = LLVMMDNode (args, 3);
8699 LLVMAddNamedMetadataOperand (lmodule, "llvm.module.flags", ver);
8701 args [0] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
8702 args [1] = LLVMMDString ("Debug Info Version", strlen ("Debug Info Version"));
8703 args [2] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
8704 ver = LLVMMDNode (args, 3);
8705 LLVMAddNamedMetadataOperand (lmodule, "llvm.module.flags", ver);
8710 emit_dbg_subprogram (EmitContext *ctx, MonoCompile *cfg, LLVMValueRef method, const char *name)
8712 MonoLLVMModule *module = ctx->module;
8713 MonoDebugMethodInfo *minfo = ctx->minfo;
8714 char *source_file, *dir, *filename;
8715 LLVMValueRef md, args [16], ctx_args [16], md_args [64], type_args [16], ctx_md, type_md;
8716 MonoSymSeqPoint *sym_seq_points;
8722 mono_debug_symfile_get_seq_points (minfo, &source_file, NULL, NULL, &sym_seq_points, &n_seq_points);
8724 source_file = g_strdup ("<unknown>");
8725 dir = g_path_get_dirname (source_file);
8726 filename = g_path_get_basename (source_file);
8728 #if LLVM_API_VERSION > 100
8729 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);
8732 ctx_args [0] = LLVMConstInt (LLVMInt32Type (), 0x29, FALSE);
8733 args [0] = md_string (filename);
8734 args [1] = md_string (dir);
8735 ctx_args [1] = LLVMMDNode (args, 2);
8736 ctx_md = LLVMMDNode (ctx_args, 2);
8738 type_args [0] = LLVMConstInt (LLVMInt32Type (), DW_TAG_subroutine_type, FALSE);
8739 type_args [1] = NULL;
8740 type_args [2] = NULL;
8741 type_args [3] = LLVMMDString ("", 0);
8742 type_args [4] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
8743 type_args [5] = LLVMConstInt (LLVMInt64Type (), 0, FALSE);
8744 type_args [6] = LLVMConstInt (LLVMInt64Type (), 0, FALSE);
8745 type_args [7] = LLVMConstInt (LLVMInt64Type (), 0, FALSE);
8746 type_args [8] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
8747 type_args [9] = NULL;
8748 type_args [10] = NULL;
8749 type_args [11] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
8750 type_args [12] = NULL;
8751 type_args [13] = NULL;
8752 type_args [14] = NULL;
8753 type_md = LLVMMDNode (type_args, 14);
8755 /* http://llvm.org/docs/SourceLevelDebugging.html#subprogram-descriptors */
8756 md_args [0] = LLVMConstInt (LLVMInt32Type (), DW_TAG_subprogram, FALSE);
8757 /* Source directory + file pair */
8758 args [0] = md_string (filename);
8759 args [1] = md_string (dir);
8760 md_args [1] = LLVMMDNode (args ,2);
8761 md_args [2] = ctx_md;
8762 md_args [3] = md_string (cfg->method->name);
8763 md_args [4] = md_string (name);
8764 md_args [5] = md_string (name);
8767 md_args [6] = LLVMConstInt (LLVMInt32Type (), sym_seq_points [0].line, FALSE);
8769 md_args [6] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
8771 md_args [7] = type_md;
8773 md_args [8] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
8775 md_args [9] = LLVMConstInt (LLVMInt1Type (), 1, FALSE);
8777 md_args [10] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
8778 /* Index into a virtual function */
8779 md_args [11] = NULL;
8780 md_args [12] = NULL;
8782 md_args [13] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
8784 md_args [14] = LLVMConstInt (LLVMInt1Type (), 1, FALSE);
8785 /* Pointer to LLVM function */
8786 md_args [15] = method;
8787 /* Function template parameter */
8788 md_args [16] = NULL;
8789 /* Function declaration descriptor */
8790 md_args [17] = NULL;
8791 /* List of function variables */
8792 md_args [18] = LLVMMDNode (args, 0);
8794 md_args [19] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
8795 md = LLVMMDNode (md_args, 20);
8797 if (!module->subprogram_mds)
8798 module->subprogram_mds = g_ptr_array_new ();
8799 g_ptr_array_add (module->subprogram_mds, md);
8803 g_free (source_file);
8804 g_free (sym_seq_points);
8810 emit_dbg_loc (EmitContext *ctx, LLVMBuilderRef builder, const unsigned char *cil_code)
8812 MonoCompile *cfg = ctx->cfg;
8814 if (ctx->minfo && cil_code && cil_code >= cfg->header->code && cil_code < cfg->header->code + cfg->header->code_size) {
8815 MonoDebugSourceLocation *loc;
8816 LLVMValueRef loc_md;
8818 loc = mono_debug_symfile_lookup_location (ctx->minfo, cil_code - cfg->header->code);
8821 #if LLVM_API_VERSION > 100
8822 loc_md = mono_llvm_di_create_location (ctx->module->di_builder, ctx->dbg_md, loc->row, loc->column);
8823 mono_llvm_di_set_location (builder, loc_md);
8825 LLVMValueRef md_args [16];
8829 md_args [nmd_args ++] = LLVMConstInt (LLVMInt32Type (), loc->row, FALSE);
8830 md_args [nmd_args ++] = LLVMConstInt (LLVMInt32Type (), loc->column, FALSE);
8831 md_args [nmd_args ++] = ctx->dbg_md;
8832 md_args [nmd_args ++] = NULL;
8833 loc_md = LLVMMDNode (md_args, nmd_args);
8834 LLVMSetCurrentDebugLocation (builder, loc_md);
8836 mono_debug_symfile_free_location (loc);
8842 default_mono_llvm_unhandled_exception (void)
8844 MonoJitTlsData *jit_tls = mono_get_jit_tls ();
8845 MonoObject *target = mono_gchandle_get_target (jit_tls->thrown_exc);
8847 mono_unhandled_exception (target);
8848 exit (mono_environment_exitcode_get ());
8853 - Emit LLVM IR from the mono IR using the LLVM C API.
8854 - The original arch specific code remains, so we can fall back to it if we run
8855 into something we can't handle.
8859 A partial list of issues:
8860 - Handling of opcodes which can throw exceptions.
8862 In the mono JIT, these are implemented using code like this:
8869 push throw_pos - method
8870 call <exception trampoline>
8872 The problematic part is push throw_pos - method, which cannot be represented
8873 in the LLVM IR, since it does not support label values.
8874 -> this can be implemented in AOT mode using inline asm + labels, but cannot
8875 be implemented in JIT mode ?
8876 -> a possible but slower implementation would use the normal exception
8877 throwing code but it would need to control the placement of the throw code
8878 (it needs to be exactly after the compare+branch).
8879 -> perhaps add a PC offset intrinsics ?
8881 - efficient implementation of .ovf opcodes.
8883 These are currently implemented as:
8884 <ins which sets the condition codes>
8887 Some overflow opcodes are now supported by LLVM SVN.
8889 - exception handling, unwinding.
8890 - SSA is disabled for methods with exception handlers
8891 - How to obtain unwind info for LLVM compiled methods ?
8892 -> this is now solved by converting the unwind info generated by LLVM
8894 - LLVM uses the c++ exception handling framework, while we use our home grown
8895 code, and couldn't use the c++ one:
8896 - its not supported under VC++, other exotic platforms.
8897 - it might be impossible to support filter clauses with it.
8901 The trampolines need a predictable call sequence, since they need to disasm
8902 the calling code to obtain register numbers / offsets.
8904 LLVM currently generates this code in non-JIT mode:
8905 mov -0x98(%rax),%eax
8907 Here, the vtable pointer is lost.
8908 -> solution: use one vtable trampoline per class.
8910 - passing/receiving the IMT pointer/RGCTX.
8911 -> solution: pass them as normal arguments ?
8915 LLVM does not allow the specification of argument registers etc. This means
8916 that all calls are made according to the platform ABI.
8918 - passing/receiving vtypes.
8920 Vtypes passed/received in registers are handled by the front end by using
8921 a signature with scalar arguments, and loading the parts of the vtype into those
8924 Vtypes passed on the stack are handled using the 'byval' attribute.
8928 Supported though alloca, we need to emit the load/store code.
8932 The mono JIT uses pointer sized iregs/double fregs, while LLVM uses precisely
8933 typed registers, so we have to keep track of the precise LLVM type of each vreg.
8934 This is made easier because the IR is already in SSA form.
8935 An additional problem is that our IR is not consistent with types, i.e. i32/ia64
8936 types are frequently used incorrectly.
8941 Emit LLVM bytecode into a .bc file, compile it using llc into a .s file, then link
8942 it with the file containing the methods emitted by the JIT and the AOT data
8946 /* FIXME: Normalize some aspects of the mono IR to allow easier translation, like:
8947 * - each bblock should end with a branch
8948 * - setting the return value, making cfg->ret non-volatile
8949 * - avoid some transformations in the JIT which make it harder for us to generate
8951 * - use pointer types to help optimizations.