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;
2072 gboolean no_pc = FALSE;
2074 if (IS_TARGET_AMD64)
2075 /* Some platforms don't require the pc argument */
2078 ex_bb = gen_bb (ctx, "EX_BB");
2080 ex2_bb = gen_bb (ctx, "EX2_BB");
2081 noex_bb = gen_bb (ctx, "NOEX_BB");
2083 LLVMBuildCondBr (ctx->builder, cmp, ex_bb, noex_bb);
2085 exc_class = mono_class_load_from_name (mono_get_corlib (), "System", exc_type);
2087 /* Emit exception throwing code */
2088 ctx->builder = builder = create_builder (ctx);
2089 LLVMPositionBuilderAtEnd (builder, ex_bb);
2091 if (ctx->cfg->llvm_only) {
2092 static LLVMTypeRef sig;
2095 sig = LLVMFunctionType1 (LLVMVoidType (), LLVMInt32Type (), FALSE);
2096 callee = get_callee (ctx, sig, MONO_PATCH_INFO_JIT_ICALL_ADDR, "mono_llvm_throw_corlib_exception");
2098 LLVMBuildBr (builder, ex2_bb);
2100 ctx->builder = builder = create_builder (ctx);
2101 LLVMPositionBuilderAtEnd (ctx->builder, ex2_bb);
2103 args [0] = LLVMConstInt (LLVMInt32Type (), exc_class->type_token - MONO_TOKEN_TYPE_DEF, FALSE);
2104 emit_call (ctx, bb, &builder, callee, args, 1);
2105 LLVMBuildUnreachable (builder);
2107 ctx->builder = builder = create_builder (ctx);
2108 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
2110 ctx->bblocks [bb->block_num].end_bblock = noex_bb;
2116 callee = ctx->module->throw_corlib_exception;
2119 const char *icall_name;
2122 sig = LLVMFunctionType1 (LLVMVoidType (), LLVMInt32Type (), FALSE);
2124 sig = LLVMFunctionType2 (LLVMVoidType (), LLVMInt32Type (), LLVMPointerType (LLVMInt8Type (), 0), FALSE);
2125 icall_name = "llvm_throw_corlib_exception_abs_trampoline";
2127 if (ctx->cfg->compile_aot) {
2128 callee = get_callee (ctx, sig, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
2131 * Differences between the LLVM/non-LLVM throw corlib exception trampoline:
2132 * - On x86, LLVM generated code doesn't push the arguments
2133 * - The trampoline takes the throw address as an arguments, not a pc offset.
2135 gpointer target = resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
2136 callee = emit_jit_callee (ctx, "llvm_throw_corlib_exception_trampoline", sig, target);
2138 #if LLVM_API_VERSION > 100
2140 * Make sure that ex_bb starts with the invoke, so the block address points to it, and not to the load
2141 * added by emit_jit_callee ().
2143 ex2_bb = gen_bb (ctx, "EX2_BB");
2144 LLVMBuildBr (builder, ex2_bb);
2147 ctx->builder = builder = create_builder (ctx);
2148 LLVMPositionBuilderAtEnd (ctx->builder, ex2_bb);
2150 mono_memory_barrier ();
2151 ctx->module->throw_corlib_exception = callee;
2156 args [0] = LLVMConstInt (LLVMInt32Type (), exc_class->type_token - MONO_TOKEN_TYPE_DEF, FALSE);
2159 * The LLVM mono branch contains changes so a block address can be passed as an
2160 * argument to a call.
2163 emit_call (ctx, bb, &builder, callee, args, 1);
2165 args [1] = LLVMBlockAddress (ctx->lmethod, ex_bb);
2166 emit_call (ctx, bb, &builder, callee, args, 2);
2169 LLVMBuildUnreachable (builder);
2171 ctx->builder = builder = create_builder (ctx);
2172 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
2174 ctx->bblocks [bb->block_num].end_bblock = noex_bb;
2181 * emit_args_to_vtype:
2183 * Emit code to store the vtype in the arguments args to the address ADDRESS.
2186 emit_args_to_vtype (EmitContext *ctx, LLVMBuilderRef builder, MonoType *t, LLVMValueRef address, LLVMArgInfo *ainfo, LLVMValueRef *args)
2188 int j, size, nslots;
2190 size = mono_class_value_size (mono_class_from_mono_type (t), NULL);
2192 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (t))) {
2193 address = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (LLVMInt8Type (), 0), "");
2196 if (ainfo->storage == LLVMArgAsFpArgs)
2197 nslots = ainfo->nslots;
2201 for (j = 0; j < nslots; ++j) {
2202 LLVMValueRef index [2], addr, daddr;
2203 int part_size = size > sizeof (gpointer) ? sizeof (gpointer) : size;
2204 LLVMTypeRef part_type;
2206 while (part_size != 1 && part_size != 2 && part_size != 4 && part_size < 8)
2209 if (ainfo->pair_storage [j] == LLVMArgNone)
2212 switch (ainfo->pair_storage [j]) {
2213 case LLVMArgInIReg: {
2214 part_type = LLVMIntType (part_size * 8);
2215 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (t))) {
2216 index [0] = LLVMConstInt (LLVMInt32Type (), j * sizeof (gpointer), FALSE);
2217 addr = LLVMBuildGEP (builder, address, index, 1, "");
2219 daddr = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (IntPtrType (), 0), "");
2220 index [0] = LLVMConstInt (LLVMInt32Type (), j, FALSE);
2221 addr = LLVMBuildGEP (builder, daddr, index, 1, "");
2223 LLVMBuildStore (builder, convert (ctx, args [j], part_type), LLVMBuildBitCast (ctx->builder, addr, LLVMPointerType (part_type, 0), ""));
2226 case LLVMArgInFPReg: {
2227 LLVMTypeRef arg_type;
2229 if (ainfo->esize == 8)
2230 arg_type = LLVMDoubleType ();
2232 arg_type = LLVMFloatType ();
2234 index [0] = LLVMConstInt (LLVMInt32Type (), j, FALSE);
2235 daddr = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (arg_type, 0), "");
2236 addr = LLVMBuildGEP (builder, daddr, index, 1, "");
2237 LLVMBuildStore (builder, args [j], addr);
2243 g_assert_not_reached ();
2246 size -= sizeof (gpointer);
2251 * emit_vtype_to_args:
2253 * Emit code to load a vtype at address ADDRESS into scalar arguments. Store the arguments
2254 * into ARGS, and the number of arguments into NARGS.
2257 emit_vtype_to_args (EmitContext *ctx, LLVMBuilderRef builder, MonoType *t, LLVMValueRef address, LLVMArgInfo *ainfo, LLVMValueRef *args, guint32 *nargs)
2260 int j, size, nslots;
2261 LLVMTypeRef arg_type;
2263 size = get_vtype_size (t);
2265 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (t)))
2266 address = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (LLVMInt8Type (), 0), "");
2268 if (ainfo->storage == LLVMArgAsFpArgs)
2269 nslots = ainfo->nslots;
2272 for (j = 0; j < nslots; ++j) {
2273 LLVMValueRef index [2], addr, daddr;
2274 int partsize = size > sizeof (gpointer) ? sizeof (gpointer) : size;
2276 if (ainfo->pair_storage [j] == LLVMArgNone)
2279 switch (ainfo->pair_storage [j]) {
2281 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (t))) {
2282 index [0] = LLVMConstInt (LLVMInt32Type (), j * sizeof (gpointer), FALSE);
2283 addr = LLVMBuildGEP (builder, address, index, 1, "");
2285 daddr = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (IntPtrType (), 0), "");
2286 index [0] = LLVMConstInt (LLVMInt32Type (), j, FALSE);
2287 addr = LLVMBuildGEP (builder, daddr, index, 1, "");
2289 args [pindex ++] = convert (ctx, LLVMBuildLoad (builder, LLVMBuildBitCast (ctx->builder, addr, LLVMPointerType (LLVMIntType (partsize * 8), 0), ""), ""), IntPtrType ());
2291 case LLVMArgInFPReg:
2292 if (ainfo->esize == 8)
2293 arg_type = LLVMDoubleType ();
2295 arg_type = LLVMFloatType ();
2296 daddr = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (arg_type, 0), "");
2297 index [0] = LLVMConstInt (LLVMInt32Type (), j, FALSE);
2298 addr = LLVMBuildGEP (builder, daddr, index, 1, "");
2299 args [pindex ++] = LLVMBuildLoad (builder, addr, "");
2304 g_assert_not_reached ();
2306 size -= sizeof (gpointer);
2313 build_alloca_llvm_type_name (EmitContext *ctx, LLVMTypeRef t, int align, const char *name)
2316 * Have to place all alloca's at the end of the entry bb, since otherwise they would
2317 * get executed every time control reaches them.
2319 LLVMPositionBuilder (ctx->alloca_builder, get_bb (ctx, ctx->cfg->bb_entry), ctx->last_alloca);
2321 ctx->last_alloca = mono_llvm_build_alloca (ctx->alloca_builder, t, NULL, align, name);
2322 return ctx->last_alloca;
2326 build_alloca_llvm_type (EmitContext *ctx, LLVMTypeRef t, int align)
2328 return build_alloca_llvm_type_name (ctx, t, align, "");
2332 build_alloca (EmitContext *ctx, MonoType *t)
2334 MonoClass *k = mono_class_from_mono_type (t);
2337 g_assert (!mini_is_gsharedvt_variable_type (t));
2339 if (MONO_CLASS_IS_SIMD (ctx->cfg, k))
2342 align = mono_class_min_align (k);
2344 /* Sometimes align is not a power of 2 */
2345 while (mono_is_power_of_two (align) == -1)
2348 return build_alloca_llvm_type (ctx, type_to_llvm_type (ctx, t), align);
2352 emit_gsharedvt_ldaddr (EmitContext *ctx, int vreg)
2356 * Compute the address of the local as gsharedvt_locals_var + gsharedvt_info_var->locals_offsets [idx].
2358 MonoCompile *cfg = ctx->cfg;
2359 LLVMBuilderRef builder = ctx->builder;
2360 LLVMValueRef offset, offset_var;
2361 LLVMValueRef info_var = ctx->values [cfg->gsharedvt_info_var->dreg];
2362 LLVMValueRef locals_var = ctx->values [cfg->gsharedvt_locals_var->dreg];
2366 g_assert (info_var);
2367 g_assert (locals_var);
2369 int idx = cfg->gsharedvt_vreg_to_idx [vreg] - 1;
2371 offset = LLVMConstInt (LLVMInt32Type (), MONO_STRUCT_OFFSET (MonoGSharedVtMethodRuntimeInfo, entries) + (idx * sizeof (gpointer)), FALSE);
2372 ptr = LLVMBuildAdd (builder, convert (ctx, info_var, IntPtrType ()), convert (ctx, offset, IntPtrType ()), "");
2374 name = g_strdup_printf ("gsharedvt_local_%d_offset", vreg);
2375 offset_var = LLVMBuildLoad (builder, convert (ctx, ptr, LLVMPointerType (LLVMInt32Type (), 0)), name);
2377 return LLVMBuildAdd (builder, convert (ctx, locals_var, IntPtrType ()), convert (ctx, offset_var, IntPtrType ()), "");
2381 * Put the global into the 'llvm.used' array to prevent it from being optimized away.
2384 mark_as_used (MonoLLVMModule *module, LLVMValueRef global)
2387 module->used = g_ptr_array_sized_new (16);
2388 g_ptr_array_add (module->used, global);
2392 emit_llvm_used (MonoLLVMModule *module)
2394 LLVMModuleRef lmodule = module->lmodule;
2395 LLVMTypeRef used_type;
2396 LLVMValueRef used, *used_elem;
2402 used_type = LLVMArrayType (LLVMPointerType (LLVMInt8Type (), 0), module->used->len);
2403 used = LLVMAddGlobal (lmodule, used_type, "llvm.used");
2404 used_elem = g_new0 (LLVMValueRef, module->used->len);
2405 for (i = 0; i < module->used->len; ++i)
2406 used_elem [i] = LLVMConstBitCast ((LLVMValueRef)g_ptr_array_index (module->used, i), LLVMPointerType (LLVMInt8Type (), 0));
2407 LLVMSetInitializer (used, LLVMConstArray (LLVMPointerType (LLVMInt8Type (), 0), used_elem, module->used->len));
2408 LLVMSetLinkage (used, LLVMAppendingLinkage);
2409 LLVMSetSection (used, "llvm.metadata");
2415 * Emit a function mapping method indexes to their code
2418 emit_get_method (MonoLLVMModule *module)
2420 LLVMModuleRef lmodule = module->lmodule;
2421 LLVMValueRef func, switch_ins, m;
2422 LLVMBasicBlockRef entry_bb, fail_bb, bb, code_start_bb, code_end_bb;
2423 LLVMBasicBlockRef *bbs;
2425 LLVMBuilderRef builder;
2430 * Emit a switch statement. Emitting a table of function addresses is smaller/faster,
2431 * but generating code seems safer.
2433 rtype = LLVMPointerType (LLVMInt8Type (), 0);
2434 func = LLVMAddFunction (lmodule, module->get_method_symbol, LLVMFunctionType1 (rtype, LLVMInt32Type (), FALSE));
2435 LLVMSetLinkage (func, LLVMExternalLinkage);
2436 LLVMSetVisibility (func, LLVMHiddenVisibility);
2437 LLVMAddFunctionAttr (func, LLVMNoUnwindAttribute);
2438 module->get_method = func;
2440 entry_bb = LLVMAppendBasicBlock (func, "ENTRY");
2443 * Return llvm_code_start/llvm_code_end when called with -1/-2.
2444 * Hopefully, the toolchain doesn't reorder these functions. If it does,
2445 * then we will have to find another solution.
2448 name = g_strdup_printf ("BB_CODE_START");
2449 code_start_bb = LLVMAppendBasicBlock (func, name);
2451 builder = LLVMCreateBuilder ();
2452 LLVMPositionBuilderAtEnd (builder, code_start_bb);
2453 LLVMBuildRet (builder, LLVMBuildBitCast (builder, module->code_start, rtype, ""));
2455 name = g_strdup_printf ("BB_CODE_END");
2456 code_end_bb = LLVMAppendBasicBlock (func, name);
2458 builder = LLVMCreateBuilder ();
2459 LLVMPositionBuilderAtEnd (builder, code_end_bb);
2460 LLVMBuildRet (builder, LLVMBuildBitCast (builder, module->code_end, rtype, ""));
2462 bbs = g_new0 (LLVMBasicBlockRef, module->max_method_idx + 1);
2463 for (i = 0; i < module->max_method_idx + 1; ++i) {
2464 name = g_strdup_printf ("BB_%d", i);
2465 bb = LLVMAppendBasicBlock (func, name);
2469 builder = LLVMCreateBuilder ();
2470 LLVMPositionBuilderAtEnd (builder, bb);
2472 m = (LLVMValueRef)g_hash_table_lookup (module->idx_to_lmethod, GINT_TO_POINTER (i));
2474 LLVMBuildRet (builder, LLVMBuildBitCast (builder, m, rtype, ""));
2476 LLVMBuildRet (builder, LLVMConstNull (rtype));
2479 fail_bb = LLVMAppendBasicBlock (func, "FAIL");
2480 builder = LLVMCreateBuilder ();
2481 LLVMPositionBuilderAtEnd (builder, fail_bb);
2482 LLVMBuildRet (builder, LLVMConstNull (rtype));
2484 builder = LLVMCreateBuilder ();
2485 LLVMPositionBuilderAtEnd (builder, entry_bb);
2487 switch_ins = LLVMBuildSwitch (builder, LLVMGetParam (func, 0), fail_bb, 0);
2488 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), -1, FALSE), code_start_bb);
2489 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), -2, FALSE), code_end_bb);
2490 for (i = 0; i < module->max_method_idx + 1; ++i) {
2491 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), i, FALSE), bbs [i]);
2494 mark_as_used (module, func);
2498 * emit_get_unbox_tramp:
2500 * Emit a function mapping method indexes to their unbox trampoline
2503 emit_get_unbox_tramp (MonoLLVMModule *module)
2505 LLVMModuleRef lmodule = module->lmodule;
2506 LLVMValueRef func, switch_ins, m;
2507 LLVMBasicBlockRef entry_bb, fail_bb, bb;
2508 LLVMBasicBlockRef *bbs;
2510 LLVMBuilderRef builder;
2514 /* Similar to emit_get_method () */
2516 rtype = LLVMPointerType (LLVMInt8Type (), 0);
2517 func = LLVMAddFunction (lmodule, module->get_unbox_tramp_symbol, LLVMFunctionType1 (rtype, LLVMInt32Type (), FALSE));
2518 LLVMSetLinkage (func, LLVMExternalLinkage);
2519 LLVMSetVisibility (func, LLVMHiddenVisibility);
2520 LLVMAddFunctionAttr (func, LLVMNoUnwindAttribute);
2521 module->get_unbox_tramp = func;
2523 entry_bb = LLVMAppendBasicBlock (func, "ENTRY");
2525 bbs = g_new0 (LLVMBasicBlockRef, module->max_method_idx + 1);
2526 for (i = 0; i < module->max_method_idx + 1; ++i) {
2527 m = (LLVMValueRef)g_hash_table_lookup (module->idx_to_unbox_tramp, GINT_TO_POINTER (i));
2531 name = g_strdup_printf ("BB_%d", i);
2532 bb = LLVMAppendBasicBlock (func, name);
2536 builder = LLVMCreateBuilder ();
2537 LLVMPositionBuilderAtEnd (builder, bb);
2539 LLVMBuildRet (builder, LLVMBuildBitCast (builder, m, rtype, ""));
2542 fail_bb = LLVMAppendBasicBlock (func, "FAIL");
2543 builder = LLVMCreateBuilder ();
2544 LLVMPositionBuilderAtEnd (builder, fail_bb);
2545 LLVMBuildRet (builder, LLVMConstNull (rtype));
2547 builder = LLVMCreateBuilder ();
2548 LLVMPositionBuilderAtEnd (builder, entry_bb);
2550 switch_ins = LLVMBuildSwitch (builder, LLVMGetParam (func, 0), fail_bb, 0);
2551 for (i = 0; i < module->max_method_idx + 1; ++i) {
2552 m = (LLVMValueRef)g_hash_table_lookup (module->idx_to_unbox_tramp, GINT_TO_POINTER (i));
2556 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), i, FALSE), bbs [i]);
2559 mark_as_used (module, func);
2562 /* Add a function to mark the beginning of LLVM code */
2564 emit_llvm_code_start (MonoLLVMModule *module)
2566 LLVMModuleRef lmodule = module->lmodule;
2568 LLVMBasicBlockRef entry_bb;
2569 LLVMBuilderRef builder;
2571 func = LLVMAddFunction (lmodule, "llvm_code_start", LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE));
2572 LLVMSetLinkage (func, LLVMInternalLinkage);
2573 LLVMAddFunctionAttr (func, LLVMNoUnwindAttribute);
2574 module->code_start = func;
2575 entry_bb = LLVMAppendBasicBlock (func, "ENTRY");
2576 builder = LLVMCreateBuilder ();
2577 LLVMPositionBuilderAtEnd (builder, entry_bb);
2578 LLVMBuildRetVoid (builder);
2582 emit_init_icall_wrapper (MonoLLVMModule *module, const char *name, const char *icall_name, int subtype)
2584 LLVMModuleRef lmodule = module->lmodule;
2585 LLVMValueRef func, indexes [2], got_entry_addr, args [16], callee;
2586 LLVMBasicBlockRef entry_bb;
2587 LLVMBuilderRef builder;
2594 func = LLVMAddFunction (lmodule, name, LLVMFunctionType1 (LLVMVoidType (), LLVMInt32Type (), FALSE));
2595 sig = LLVMFunctionType2 (LLVMVoidType (), IntPtrType (), LLVMInt32Type (), FALSE);
2600 func = LLVMAddFunction (lmodule, name, LLVMFunctionType2 (LLVMVoidType (), LLVMInt32Type (), IntPtrType (), FALSE));
2601 sig = LLVMFunctionType3 (LLVMVoidType (), IntPtrType (), LLVMInt32Type (), IntPtrType (), FALSE);
2604 func = LLVMAddFunction (lmodule, name, LLVMFunctionType2 (LLVMVoidType (), LLVMInt32Type (), ObjRefType (), FALSE));
2605 sig = LLVMFunctionType3 (LLVMVoidType (), IntPtrType (), LLVMInt32Type (), ObjRefType (), FALSE);
2608 g_assert_not_reached ();
2610 LLVMSetLinkage (func, LLVMInternalLinkage);
2611 LLVMAddFunctionAttr (func, LLVMNoInlineAttribute);
2612 mono_llvm_set_preserveall_cc (func);
2613 entry_bb = LLVMAppendBasicBlock (func, "ENTRY");
2614 builder = LLVMCreateBuilder ();
2615 LLVMPositionBuilderAtEnd (builder, entry_bb);
2618 ji = g_new0 (MonoJumpInfo, 1);
2619 ji->type = MONO_PATCH_INFO_AOT_MODULE;
2620 ji = mono_aot_patch_info_dup (ji);
2621 got_offset = mono_aot_get_got_offset (ji);
2622 module->max_got_offset = MAX (module->max_got_offset, got_offset);
2623 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
2624 indexes [1] = LLVMConstInt (LLVMInt32Type (), got_offset, FALSE);
2625 got_entry_addr = LLVMBuildGEP (builder, module->got_var, indexes, 2, "");
2626 args [0] = LLVMBuildPtrToInt (builder, LLVMBuildLoad (builder, got_entry_addr, ""), IntPtrType (), "");
2627 args [1] = LLVMGetParam (func, 0);
2629 args [2] = LLVMGetParam (func, 1);
2631 ji = g_new0 (MonoJumpInfo, 1);
2632 ji->type = MONO_PATCH_INFO_INTERNAL_METHOD;
2633 ji->data.name = icall_name;
2634 ji = mono_aot_patch_info_dup (ji);
2635 got_offset = mono_aot_get_got_offset (ji);
2636 module->max_got_offset = MAX (module->max_got_offset, got_offset);
2637 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
2638 indexes [1] = LLVMConstInt (LLVMInt32Type (), got_offset, FALSE);
2639 got_entry_addr = LLVMBuildGEP (builder, module->got_var, indexes, 2, "");
2640 callee = LLVMBuildLoad (builder, got_entry_addr, "");
2641 callee = LLVMBuildBitCast (builder, callee, LLVMPointerType (sig, 0), "");
2642 LLVMBuildCall (builder, callee, args, LLVMCountParamTypes (sig), "");
2644 // Set the inited flag
2645 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
2646 indexes [1] = LLVMGetParam (func, 0);
2647 LLVMBuildStore (builder, LLVMConstInt (LLVMInt8Type (), 1, FALSE), LLVMBuildGEP (builder, module->inited_var, indexes, 2, ""));
2649 LLVMBuildRetVoid (builder);
2651 LLVMVerifyFunction(func, LLVMAbortProcessAction);
2656 * Emit wrappers around the C icalls used to initialize llvm methods, to
2657 * make the calling code smaller and to enable usage of the llvm
2658 * PreserveAll calling convention.
2661 emit_init_icall_wrappers (MonoLLVMModule *module)
2663 module->init_method = emit_init_icall_wrapper (module, "init_method", "mono_aot_init_llvm_method", 0);
2664 module->init_method_gshared_mrgctx = emit_init_icall_wrapper (module, "init_method_gshared_mrgctx", "mono_aot_init_gshared_method_mrgctx", 1);
2665 module->init_method_gshared_this = emit_init_icall_wrapper (module, "init_method_gshared_this", "mono_aot_init_gshared_method_this", 2);
2666 module->init_method_gshared_vtable = emit_init_icall_wrapper (module, "init_method_gshared_vtable", "mono_aot_init_gshared_method_vtable", 3);
2670 emit_llvm_code_end (MonoLLVMModule *module)
2672 LLVMModuleRef lmodule = module->lmodule;
2674 LLVMBasicBlockRef entry_bb;
2675 LLVMBuilderRef builder;
2677 func = LLVMAddFunction (lmodule, "llvm_code_end", LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE));
2678 LLVMSetLinkage (func, LLVMInternalLinkage);
2679 LLVMAddFunctionAttr (func, LLVMNoUnwindAttribute);
2680 module->code_end = func;
2681 entry_bb = LLVMAppendBasicBlock (func, "ENTRY");
2682 builder = LLVMCreateBuilder ();
2683 LLVMPositionBuilderAtEnd (builder, entry_bb);
2684 LLVMBuildRetVoid (builder);
2688 emit_div_check (EmitContext *ctx, LLVMBuilderRef builder, MonoBasicBlock *bb, MonoInst *ins, LLVMValueRef lhs, LLVMValueRef rhs)
2690 gboolean need_div_check = ctx->cfg->backend->need_div_check;
2693 /* LLVM doesn't know that these can throw an exception since they are not called through an intrinsic */
2694 need_div_check = TRUE;
2696 if (!need_div_check)
2699 switch (ins->opcode) {
2712 case OP_IDIV_UN_IMM:
2713 case OP_LDIV_UN_IMM:
2714 case OP_IREM_UN_IMM:
2715 case OP_LREM_UN_IMM: {
2717 gboolean is_signed = (ins->opcode == OP_IDIV || ins->opcode == OP_LDIV || ins->opcode == OP_IREM || ins->opcode == OP_LREM ||
2718 ins->opcode == OP_IDIV_IMM || ins->opcode == OP_LDIV_IMM || ins->opcode == OP_IREM_IMM || ins->opcode == OP_LREM_IMM);
2720 cmp = LLVMBuildICmp (builder, LLVMIntEQ, rhs, LLVMConstInt (LLVMTypeOf (rhs), 0, FALSE), "");
2721 emit_cond_system_exception (ctx, bb, "DivideByZeroException", cmp);
2724 builder = ctx->builder;
2726 /* b == -1 && a == 0x80000000 */
2728 LLVMValueRef c = (LLVMTypeOf (lhs) == LLVMInt32Type ()) ? LLVMConstInt (LLVMTypeOf (lhs), 0x80000000, FALSE) : LLVMConstInt (LLVMTypeOf (lhs), 0x8000000000000000LL, FALSE);
2729 LLVMValueRef cond1 = LLVMBuildICmp (builder, LLVMIntEQ, rhs, LLVMConstInt (LLVMTypeOf (rhs), -1, FALSE), "");
2730 LLVMValueRef cond2 = LLVMBuildICmp (builder, LLVMIntEQ, lhs, c, "");
2732 cmp = LLVMBuildICmp (builder, LLVMIntEQ, LLVMBuildAnd (builder, cond1, cond2, ""), LLVMConstInt (LLVMInt1Type (), 1, FALSE), "");
2733 emit_cond_system_exception (ctx, bb, "OverflowException", cmp);
2736 builder = ctx->builder;
2748 * Emit code to initialize the GOT slots used by the method.
2751 emit_init_method (EmitContext *ctx)
2753 LLVMValueRef indexes [16], args [16], callee;
2754 LLVMValueRef inited_var, cmp, call;
2755 LLVMBasicBlockRef inited_bb, notinited_bb;
2756 LLVMBuilderRef builder = ctx->builder;
2757 MonoCompile *cfg = ctx->cfg;
2759 ctx->module->max_inited_idx = MAX (ctx->module->max_inited_idx, cfg->method_index);
2761 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
2762 indexes [1] = LLVMConstInt (LLVMInt32Type (), cfg->method_index, FALSE);
2763 inited_var = LLVMBuildLoad (builder, LLVMBuildGEP (builder, ctx->module->inited_var, indexes, 2, ""), "is_inited");
2765 args [0] = inited_var;
2766 args [1] = LLVMConstInt (LLVMInt8Type (), 1, FALSE);
2767 inited_var = LLVMBuildCall (ctx->builder, get_intrinsic (ctx, "llvm.expect.i8"), args, 2, "");
2769 cmp = LLVMBuildICmp (builder, LLVMIntEQ, inited_var, LLVMConstInt (LLVMTypeOf (inited_var), 0, FALSE), "");
2771 inited_bb = ctx->inited_bb;
2772 notinited_bb = gen_bb (ctx, "NOTINITED_BB");
2774 LLVMBuildCondBr (ctx->builder, cmp, notinited_bb, inited_bb);
2776 builder = ctx->builder = create_builder (ctx);
2777 LLVMPositionBuilderAtEnd (ctx->builder, notinited_bb);
2780 if (ctx->rgctx_arg && cfg->method->is_inflated && mono_method_get_context (cfg->method)->method_inst) {
2781 args [0] = LLVMConstInt (LLVMInt32Type (), cfg->method_index, 0);
2782 args [1] = convert (ctx, ctx->rgctx_arg, IntPtrType ());
2783 callee = ctx->module->init_method_gshared_mrgctx;
2784 call = LLVMBuildCall (builder, callee, args, 2, "");
2785 } else if (ctx->rgctx_arg) {
2786 /* A vtable is passed as the rgctx argument */
2787 args [0] = LLVMConstInt (LLVMInt32Type (), cfg->method_index, 0);
2788 args [1] = convert (ctx, ctx->rgctx_arg, IntPtrType ());
2789 callee = ctx->module->init_method_gshared_vtable;
2790 call = LLVMBuildCall (builder, callee, args, 2, "");
2791 } else if (cfg->gshared) {
2792 args [0] = LLVMConstInt (LLVMInt32Type (), cfg->method_index, 0);
2793 args [1] = convert (ctx, ctx->this_arg, ObjRefType ());
2794 callee = ctx->module->init_method_gshared_this;
2795 call = LLVMBuildCall (builder, callee, args, 2, "");
2797 args [0] = LLVMConstInt (LLVMInt32Type (), cfg->method_index, 0);
2798 callee = ctx->module->init_method;
2799 call = LLVMBuildCall (builder, callee, args, 1, "");
2803 * This enables llvm to keep arguments in their original registers/
2804 * scratch registers, since the call will not clobber them.
2806 mono_llvm_set_call_preserveall_cc (call);
2808 LLVMBuildBr (builder, inited_bb);
2809 ctx->bblocks [cfg->bb_entry->block_num].end_bblock = inited_bb;
2811 builder = ctx->builder = create_builder (ctx);
2812 LLVMPositionBuilderAtEnd (ctx->builder, inited_bb);
2816 emit_unbox_tramp (EmitContext *ctx, const char *method_name, LLVMTypeRef method_type, LLVMValueRef method, int method_index)
2819 * Emit unbox trampoline using a tail call
2821 LLVMValueRef tramp, call, *args;
2822 LLVMBuilderRef builder;
2823 LLVMBasicBlockRef lbb;
2824 LLVMCallInfo *linfo;
2828 tramp_name = g_strdup_printf ("ut_%s", method_name);
2829 tramp = LLVMAddFunction (ctx->module->lmodule, tramp_name, method_type);
2830 LLVMSetLinkage (tramp, LLVMInternalLinkage);
2831 LLVMAddFunctionAttr (tramp, LLVMOptimizeForSizeAttribute);
2832 //LLVMAddFunctionAttr (tramp, LLVMNoUnwindAttribute);
2834 // FIXME: Reduce code duplication with mono_llvm_compile_method () etc.
2835 if (!ctx->llvm_only && ctx->rgctx_arg_pindex != -1)
2836 LLVMAddAttribute (LLVMGetParam (tramp, ctx->rgctx_arg_pindex), LLVMInRegAttribute);
2837 if (ctx->cfg->vret_addr) {
2838 LLVMSetValueName (LLVMGetParam (tramp, linfo->vret_arg_pindex), "vret");
2839 if (linfo->ret.storage == LLVMArgVtypeByRef) {
2840 LLVMAddAttribute (LLVMGetParam (tramp, linfo->vret_arg_pindex), LLVMStructRetAttribute);
2841 LLVMAddAttribute (LLVMGetParam (tramp, linfo->vret_arg_pindex), LLVMNoAliasAttribute);
2845 lbb = LLVMAppendBasicBlock (tramp, "");
2846 builder = LLVMCreateBuilder ();
2847 LLVMPositionBuilderAtEnd (builder, lbb);
2849 nargs = LLVMCountParamTypes (method_type);
2850 args = g_new0 (LLVMValueRef, nargs);
2851 for (i = 0; i < nargs; ++i) {
2852 args [i] = LLVMGetParam (tramp, i);
2853 if (i == ctx->this_arg_pindex) {
2854 LLVMTypeRef arg_type = LLVMTypeOf (args [i]);
2856 args [i] = LLVMBuildPtrToInt (builder, args [i], IntPtrType (), "");
2857 args [i] = LLVMBuildAdd (builder, args [i], LLVMConstInt (IntPtrType (), sizeof (MonoObject), FALSE), "");
2858 args [i] = LLVMBuildIntToPtr (builder, args [i], arg_type, "");
2861 call = LLVMBuildCall (builder, method, args, nargs, "");
2862 if (!ctx->llvm_only && ctx->rgctx_arg_pindex != -1)
2863 LLVMAddInstrAttribute (call, 1 + ctx->rgctx_arg_pindex, LLVMInRegAttribute);
2864 if (linfo->ret.storage == LLVMArgVtypeByRef)
2865 LLVMAddInstrAttribute (call, 1 + linfo->vret_arg_pindex, LLVMStructRetAttribute);
2867 // FIXME: This causes assertions in clang
2868 //mono_llvm_set_must_tail (call);
2869 if (LLVMGetReturnType (method_type) == LLVMVoidType ())
2870 LLVMBuildRetVoid (builder);
2872 LLVMBuildRet (builder, call);
2874 g_hash_table_insert (ctx->module->idx_to_unbox_tramp, GINT_TO_POINTER (method_index), tramp);
2880 * Emit code to load/convert arguments.
2883 emit_entry_bb (EmitContext *ctx, LLVMBuilderRef builder)
2886 MonoCompile *cfg = ctx->cfg;
2887 MonoMethodSignature *sig = ctx->sig;
2888 LLVMCallInfo *linfo = ctx->linfo;
2892 LLVMBuilderRef old_builder = ctx->builder;
2893 ctx->builder = builder;
2895 ctx->alloca_builder = create_builder (ctx);
2898 * Handle indirect/volatile variables by allocating memory for them
2899 * using 'alloca', and storing their address in a temporary.
2901 for (i = 0; i < cfg->num_varinfo; ++i) {
2902 MonoInst *var = cfg->varinfo [i];
2905 if (var->opcode == OP_GSHAREDVT_LOCAL || var->opcode == OP_GSHAREDVT_ARG_REGOFFSET) {
2906 } 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))) {
2907 vtype = type_to_llvm_type (ctx, var->inst_vtype);
2910 /* Could be already created by an OP_VPHI */
2911 if (!ctx->addresses [var->dreg]) {
2912 ctx->addresses [var->dreg] = build_alloca (ctx, var->inst_vtype);
2913 //LLVMSetValueName (ctx->addresses [var->dreg], g_strdup_printf ("vreg_loc_%d", var->dreg));
2915 ctx->vreg_cli_types [var->dreg] = var->inst_vtype;
2919 names = g_new (char *, sig->param_count);
2920 mono_method_get_param_names (cfg->method, (const char **) names);
2922 for (i = 0; i < sig->param_count; ++i) {
2923 LLVMArgInfo *ainfo = &linfo->args [i + sig->hasthis];
2924 int reg = cfg->args [i + sig->hasthis]->dreg;
2927 pindex = ainfo->pindex;
2929 switch (ainfo->storage) {
2930 case LLVMArgVtypeInReg:
2931 case LLVMArgAsFpArgs: {
2932 LLVMValueRef args [8];
2935 pindex += ainfo->ndummy_fpargs;
2937 /* The argument is received as a set of int/fp arguments, store them into the real argument */
2938 memset (args, 0, sizeof (args));
2939 if (ainfo->storage == LLVMArgVtypeInReg) {
2940 args [0] = LLVMGetParam (ctx->lmethod, pindex);
2941 if (ainfo->pair_storage [1] != LLVMArgNone)
2942 args [1] = LLVMGetParam (ctx->lmethod, pindex + 1);
2944 g_assert (ainfo->nslots <= 8);
2945 for (j = 0; j < ainfo->nslots; ++j)
2946 args [j] = LLVMGetParam (ctx->lmethod, pindex + j);
2948 ctx->addresses [reg] = build_alloca (ctx, ainfo->type);
2950 emit_args_to_vtype (ctx, builder, ainfo->type, ctx->addresses [reg], ainfo, args);
2952 if (ainfo->storage == LLVMArgVtypeInReg && 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 LLVMArgVtypeByVal: {
2959 ctx->addresses [reg] = LLVMGetParam (ctx->lmethod, pindex);
2961 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (ainfo->type))) {
2962 /* Treat these as normal values */
2963 ctx->values [reg] = LLVMBuildLoad (builder, ctx->addresses [reg], "");
2967 case LLVMArgVtypeByRef: {
2968 /* The argument is passed by ref */
2969 ctx->addresses [reg] = LLVMGetParam (ctx->lmethod, pindex);
2972 case LLVMArgAsIArgs: {
2973 LLVMValueRef arg = LLVMGetParam (ctx->lmethod, pindex);
2976 /* The argument is received as an array of ints, store it into the real argument */
2977 ctx->addresses [reg] = build_alloca (ctx, ainfo->type);
2979 size = mono_class_value_size (mono_class_from_mono_type (ainfo->type), NULL);
2980 if (size < SIZEOF_VOID_P) {
2981 /* The upper bits of the registers might not be valid */
2982 LLVMValueRef val = LLVMBuildExtractValue (builder, arg, 0, "");
2983 LLVMValueRef dest = convert (ctx, ctx->addresses [reg], LLVMPointerType (LLVMIntType (size * 8), 0));
2984 LLVMBuildStore (ctx->builder, LLVMBuildTrunc (builder, val, LLVMIntType (size * 8), ""), dest);
2986 LLVMBuildStore (ctx->builder, arg, convert (ctx, ctx->addresses [reg], LLVMPointerType (LLVMTypeOf (arg), 0)));
2990 case LLVMArgVtypeAsScalar:
2991 g_assert_not_reached ();
2993 case LLVMArgGsharedvtFixed: {
2994 /* These are non-gsharedvt arguments passed by ref, the rest of the IR treats them as scalars */
2995 LLVMValueRef arg = LLVMGetParam (ctx->lmethod, pindex);
2998 name = g_strdup_printf ("arg_%s", names [i]);
3000 name = g_strdup_printf ("arg_%d", i);
3002 ctx->values [reg] = LLVMBuildLoad (builder, convert (ctx, arg, LLVMPointerType (type_to_llvm_type (ctx, ainfo->type), 0)), name);
3005 case LLVMArgGsharedvtFixedVtype: {
3006 LLVMValueRef arg = LLVMGetParam (ctx->lmethod, pindex);
3009 name = g_strdup_printf ("vtype_arg_%s", names [i]);
3011 name = g_strdup_printf ("vtype_arg_%d", i);
3013 /* Non-gsharedvt vtype argument passed by ref, the rest of the IR treats it as a vtype */
3014 g_assert (ctx->addresses [reg]);
3015 LLVMSetValueName (ctx->addresses [reg], name);
3016 LLVMBuildStore (builder, LLVMBuildLoad (builder, convert (ctx, arg, LLVMPointerType (type_to_llvm_type (ctx, ainfo->type), 0)), ""), ctx->addresses [reg]);
3019 case LLVMArgGsharedvtVariable:
3020 /* The IR treats these as variables with addresses */
3021 ctx->addresses [reg] = LLVMGetParam (ctx->lmethod, pindex);
3024 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));
3031 emit_volatile_store (ctx, cfg->vret_addr->dreg);
3033 emit_volatile_store (ctx, cfg->args [0]->dreg);
3034 for (i = 0; i < sig->param_count; ++i)
3035 if (!mini_type_is_vtype (sig->params [i]))
3036 emit_volatile_store (ctx, cfg->args [i + sig->hasthis]->dreg);
3038 if (sig->hasthis && !cfg->rgctx_var && cfg->gshared) {
3039 LLVMValueRef this_alloc;
3042 * The exception handling code needs the location where the this argument was
3043 * stored for gshared methods. We create a separate alloca to hold it, and mark it
3044 * with the "mono.this" custom metadata to tell llvm that it needs to save its
3045 * location into the LSDA.
3047 this_alloc = mono_llvm_build_alloca (builder, ThisType (), LLVMConstInt (LLVMInt32Type (), 1, FALSE), 0, "");
3048 /* This volatile store will keep the alloca alive */
3049 mono_llvm_build_store (builder, ctx->values [cfg->args [0]->dreg], this_alloc, TRUE, LLVM_BARRIER_NONE);
3051 set_metadata_flag (this_alloc, "mono.this");
3054 if (cfg->rgctx_var) {
3055 LLVMValueRef rgctx_alloc, store;
3058 * We handle the rgctx arg similarly to the this pointer.
3060 g_assert (ctx->addresses [cfg->rgctx_var->dreg]);
3061 rgctx_alloc = ctx->addresses [cfg->rgctx_var->dreg];
3062 /* This volatile store will keep the alloca alive */
3063 store = mono_llvm_build_store (builder, convert (ctx, ctx->rgctx_arg, IntPtrType ()), rgctx_alloc, TRUE, LLVM_BARRIER_NONE);
3065 set_metadata_flag (rgctx_alloc, "mono.this");
3068 /* Initialize the method if needed */
3069 if (cfg->compile_aot && ctx->llvm_only) {
3070 /* Emit a location for the initialization code */
3071 ctx->init_bb = gen_bb (ctx, "INIT_BB");
3072 ctx->inited_bb = gen_bb (ctx, "INITED_BB");
3074 LLVMBuildBr (ctx->builder, ctx->init_bb);
3075 builder = ctx->builder = create_builder (ctx);
3076 LLVMPositionBuilderAtEnd (ctx->builder, ctx->inited_bb);
3077 ctx->bblocks [cfg->bb_entry->block_num].end_bblock = ctx->inited_bb;
3080 /* Compute nesting between clauses */
3081 ctx->nested_in = (GSList**)mono_mempool_alloc0 (cfg->mempool, sizeof (GSList*) * cfg->header->num_clauses);
3082 for (i = 0; i < cfg->header->num_clauses; ++i) {
3083 for (j = 0; j < cfg->header->num_clauses; ++j) {
3084 MonoExceptionClause *clause1 = &cfg->header->clauses [i];
3085 MonoExceptionClause *clause2 = &cfg->header->clauses [j];
3087 if (i != j && clause1->try_offset >= clause2->try_offset && clause1->handler_offset <= clause2->handler_offset)
3088 ctx->nested_in [i] = g_slist_prepend_mempool (cfg->mempool, ctx->nested_in [i], GINT_TO_POINTER (j));
3093 * For finally clauses, create an indicator variable telling OP_ENDFINALLY whenever
3094 * it needs to continue normally, or return back to the exception handling system.
3096 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
3100 if (!(bb->region != -1 && (bb->flags & BB_EXCEPTION_HANDLER)))
3103 clause_index = MONO_REGION_CLAUSE_INDEX (bb->region);
3104 g_hash_table_insert (ctx->region_to_handler, GUINT_TO_POINTER (mono_get_block_region_notry (cfg, bb->region)), bb);
3105 g_hash_table_insert (ctx->clause_to_handler, GINT_TO_POINTER (clause_index), bb);
3107 if (bb->in_scount == 0) {
3110 sprintf (name, "finally_ind_bb%d", bb->block_num);
3111 val = LLVMBuildAlloca (builder, LLVMInt32Type (), name);
3112 LLVMBuildStore (builder, LLVMConstInt (LLVMInt32Type (), 0, FALSE), val);
3114 ctx->bblocks [bb->block_num].finally_ind = val;
3116 /* Create a variable to hold the exception var */
3118 ctx->ex_var = LLVMBuildAlloca (builder, ObjRefType (), "exvar");
3122 * Create a new bblock which CALL_HANDLER/landing pads can branch to, because branching to the
3123 * LLVM bblock containing a landing pad causes problems for the
3124 * LLVM optimizer passes.
3126 sprintf (name, "BB%d_CALL_HANDLER_TARGET", bb->block_num);
3127 ctx->bblocks [bb->block_num].call_handler_target_bb = LLVMAppendBasicBlock (ctx->lmethod, name);
3129 ctx->builder = old_builder;
3133 process_call (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, MonoInst *ins)
3135 MonoCompile *cfg = ctx->cfg;
3136 LLVMValueRef *values = ctx->values;
3137 LLVMValueRef *addresses = ctx->addresses;
3138 MonoCallInst *call = (MonoCallInst*)ins;
3139 MonoMethodSignature *sig = call->signature;
3140 LLVMValueRef callee = NULL, lcall;
3142 LLVMCallInfo *cinfo;
3146 LLVMTypeRef llvm_sig;
3148 gboolean is_virtual, calli, preserveall;
3149 LLVMBuilderRef builder = *builder_ref;
3151 if (call->signature->call_convention != MONO_CALL_DEFAULT) {
3152 set_failure (ctx, "non-default callconv");
3156 cinfo = call->cinfo;
3158 if (call->rgctx_arg_reg)
3159 cinfo->rgctx_arg = TRUE;
3160 if (call->imt_arg_reg)
3161 cinfo->imt_arg = TRUE;
3163 vretaddr = (cinfo->ret.storage == LLVMArgVtypeRetAddr || cinfo->ret.storage == LLVMArgVtypeByRef || cinfo->ret.storage == LLVMArgGsharedvtFixed || cinfo->ret.storage == LLVMArgGsharedvtVariable || cinfo->ret.storage == LLVMArgGsharedvtFixedVtype);
3165 llvm_sig = sig_to_llvm_sig_full (ctx, sig, cinfo);
3169 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);
3170 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);
3172 preserveall = FALSE;
3174 /* FIXME: Avoid creating duplicate methods */
3176 if (ins->flags & MONO_INST_HAS_METHOD) {
3180 if (cfg->compile_aot) {
3181 callee = get_callee (ctx, llvm_sig, MONO_PATCH_INFO_METHOD, call->method);
3183 set_failure (ctx, "can't encode patch");
3186 if (cfg->llvm_only && call->method->klass->image->assembly == ctx->module->assembly) {
3188 * Collect instructions representing the callee into a hash so they can be replaced
3189 * by the llvm method for the callee if the callee turns out to be direct
3190 * callable. Currently this only requires it to not fail llvm compilation.
3192 GSList *l = (GSList*)g_hash_table_lookup (ctx->method_to_callers, call->method);
3193 l = g_slist_prepend (l, callee);
3194 g_hash_table_insert (ctx->method_to_callers, call->method, l);
3198 static int tramp_index;
3201 name = g_strdup_printf ("tramp_%d", tramp_index);
3204 #if LLVM_API_VERSION > 100
3206 * Use our trampoline infrastructure for lazy compilation instead of llvm's.
3207 * Make all calls through a global. The address of the global will be saved in
3208 * MonoJitDomainInfo.llvm_jit_callees and updated when the method it refers to is
3211 LLVMValueRef tramp_var = g_hash_table_lookup (ctx->jit_callees, call->method);
3214 mono_create_jit_trampoline (mono_domain_get (),
3215 call->method, &error);
3216 if (!mono_error_ok (&error))
3217 mono_error_raise_exception (&error); /* FIXME: Don't raise here */
3218 tramp_var = LLVMAddGlobal (ctx->lmodule, LLVMPointerType (llvm_sig, 0), name);
3219 LLVMSetInitializer (tramp_var, LLVMConstIntToPtr (LLVMConstInt (LLVMInt64Type (), (guint64)(size_t)target, FALSE), LLVMPointerType (llvm_sig, 0)));
3220 LLVMSetLinkage (tramp_var, LLVMExternalLinkage);
3221 g_hash_table_insert (ctx->jit_callees, call->method, tramp_var);
3223 callee = LLVMBuildLoad (builder, tramp_var, "");
3226 mono_create_jit_trampoline (mono_domain_get (),
3227 call->method, &error);
3228 if (!mono_error_ok (&error))
3229 mono_error_raise_exception (&error); /* FIXME: Don't raise here */
3231 callee = LLVMAddFunction (ctx->lmodule, name, llvm_sig);
3234 if (!mono_error_ok (&error))
3235 mono_error_raise_exception (&error); /* FIXME: Don't raise here */
3236 LLVMAddGlobalMapping (ctx->module->ee, callee, target);
3241 if (!cfg->llvm_only && call->method && strstr (call->method->klass->name, "AsyncVoidMethodBuilder")) {
3242 /* LLVM miscompiles async methods */
3243 set_failure (ctx, "#13734");
3248 MonoJitICallInfo *info = mono_find_jit_icall_by_addr (call->fptr);
3254 memset (&ji, 0, sizeof (ji));
3255 ji.type = MONO_PATCH_INFO_JIT_ICALL_ADDR;
3256 ji.data.target = info->name;
3258 target = mono_resolve_patch_target (cfg->method, cfg->domain, NULL, &ji, FALSE);
3260 if (cfg->compile_aot) {
3261 callee = get_callee (ctx, llvm_sig, MONO_PATCH_INFO_INTERNAL_METHOD, (char*)info->name);
3263 set_failure (ctx, "can't encode patch");
3267 target = (gpointer)mono_icall_get_wrapper (info);
3268 callee = emit_jit_callee (ctx, "", llvm_sig, target);
3271 if (cfg->compile_aot) {
3273 if (cfg->abs_patches) {
3274 MonoJumpInfo *abs_ji = (MonoJumpInfo*)g_hash_table_lookup (cfg->abs_patches, call->fptr);
3276 callee = get_callee (ctx, llvm_sig, abs_ji->type, abs_ji->data.target);
3278 set_failure (ctx, "can't encode patch");
3284 set_failure (ctx, "aot");
3288 #if LLVM_API_VERSION > 100
3289 if (cfg->abs_patches) {
3290 MonoJumpInfo *abs_ji = (MonoJumpInfo*)g_hash_table_lookup (cfg->abs_patches, call->fptr);
3294 target = mono_resolve_patch_target (cfg->method, cfg->domain, NULL, abs_ji, FALSE, &error);
3295 mono_error_assert_ok (&error);
3296 callee = emit_jit_callee (ctx, "", llvm_sig, target);
3298 g_assert_not_reached ();
3301 g_assert_not_reached ();
3304 callee = LLVMAddFunction (ctx->lmodule, "", llvm_sig);
3306 if (cfg->abs_patches) {
3307 MonoJumpInfo *abs_ji = (MonoJumpInfo*)g_hash_table_lookup (cfg->abs_patches, call->fptr);
3312 * FIXME: Some trampolines might have
3313 * their own calling convention on some platforms.
3315 target = mono_resolve_patch_target (cfg->method, cfg->domain, NULL, abs_ji, FALSE, &error);
3316 mono_error_assert_ok (&error);
3317 LLVMAddGlobalMapping (ctx->module->ee, callee, target);
3321 LLVMAddGlobalMapping (ctx->module->ee, callee, (gpointer)call->fptr);
3328 int size = sizeof (gpointer);
3331 g_assert (ins->inst_offset % size == 0);
3332 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
3334 callee = convert (ctx, LLVMBuildLoad (builder, LLVMBuildGEP (builder, convert (ctx, values [ins->inst_basereg], LLVMPointerType (LLVMPointerType (IntPtrType (), 0), 0)), &index, 1, ""), ""), LLVMPointerType (llvm_sig, 0));
3336 callee = convert (ctx, values [ins->sreg1], LLVMPointerType (llvm_sig, 0));
3338 if (ins->flags & MONO_INST_HAS_METHOD) {
3343 * Collect and convert arguments
3345 nargs = (sig->param_count * 16) + sig->hasthis + vretaddr + call->rgctx_reg + call->imt_arg_reg;
3346 len = sizeof (LLVMValueRef) * nargs;
3347 args = (LLVMValueRef*)alloca (len);
3348 memset (args, 0, len);
3349 l = call->out_ireg_args;
3351 if (call->rgctx_arg_reg) {
3352 g_assert (values [call->rgctx_arg_reg]);
3353 g_assert (cinfo->rgctx_arg_pindex < nargs);
3355 * On ARM, the imt/rgctx argument is passed in a caller save register, but some of our trampolines etc. clobber it, leading to
3356 * problems is LLVM moves the arg assignment earlier. To work around this, save the argument into a stack slot and load
3357 * it using a volatile load.
3360 if (!ctx->imt_rgctx_loc)
3361 ctx->imt_rgctx_loc = build_alloca_llvm_type (ctx, ctx->module->ptr_type, sizeof (gpointer));
3362 LLVMBuildStore (builder, convert (ctx, ctx->values [call->rgctx_arg_reg], ctx->module->ptr_type), ctx->imt_rgctx_loc);
3363 args [cinfo->rgctx_arg_pindex] = mono_llvm_build_load (builder, ctx->imt_rgctx_loc, "", TRUE, LLVM_BARRIER_NONE);
3365 args [cinfo->rgctx_arg_pindex] = convert (ctx, values [call->rgctx_arg_reg], ctx->module->ptr_type);
3368 if (call->imt_arg_reg) {
3369 g_assert (!ctx->llvm_only);
3370 g_assert (values [call->imt_arg_reg]);
3371 g_assert (cinfo->imt_arg_pindex < nargs);
3373 if (!ctx->imt_rgctx_loc)
3374 ctx->imt_rgctx_loc = build_alloca_llvm_type (ctx, ctx->module->ptr_type, sizeof (gpointer));
3375 LLVMBuildStore (builder, convert (ctx, ctx->values [call->imt_arg_reg], ctx->module->ptr_type), ctx->imt_rgctx_loc);
3376 args [cinfo->imt_arg_pindex] = mono_llvm_build_load (builder, ctx->imt_rgctx_loc, "", TRUE, LLVM_BARRIER_NONE);
3378 args [cinfo->imt_arg_pindex] = convert (ctx, values [call->imt_arg_reg], ctx->module->ptr_type);
3381 switch (cinfo->ret.storage) {
3382 case LLVMArgGsharedvtVariable: {
3383 MonoInst *var = get_vreg_to_inst (cfg, call->inst.dreg);
3385 if (var && var->opcode == OP_GSHAREDVT_LOCAL) {
3386 args [cinfo->vret_arg_pindex] = convert (ctx, emit_gsharedvt_ldaddr (ctx, var->dreg), IntPtrType ());
3388 g_assert (addresses [call->inst.dreg]);
3389 args [cinfo->vret_arg_pindex] = addresses [call->inst.dreg];
3395 if (!addresses [call->inst.dreg])
3396 addresses [call->inst.dreg] = build_alloca (ctx, sig->ret);
3397 g_assert (cinfo->vret_arg_pindex < nargs);
3398 if (cinfo->ret.storage == LLVMArgVtypeByRef)
3399 args [cinfo->vret_arg_pindex] = addresses [call->inst.dreg];
3401 args [cinfo->vret_arg_pindex] = LLVMBuildPtrToInt (builder, addresses [call->inst.dreg], IntPtrType (), "");
3407 * Sometimes the same method is called with two different signatures (i.e. with and without 'this'), so
3408 * use the real callee for argument type conversion.
3410 LLVMTypeRef callee_type = LLVMGetElementType (LLVMTypeOf (callee));
3411 LLVMTypeRef *param_types = (LLVMTypeRef*)g_alloca (sizeof (LLVMTypeRef) * LLVMCountParamTypes (callee_type));
3412 LLVMGetParamTypes (callee_type, param_types);
3414 for (i = 0; i < sig->param_count + sig->hasthis; ++i) {
3417 LLVMArgInfo *ainfo = &call->cinfo->args [i];
3419 pindex = ainfo->pindex;
3421 regpair = (guint32)(gssize)(l->data);
3422 reg = regpair & 0xffffff;
3423 args [pindex] = values [reg];
3424 switch (ainfo->storage) {
3425 case LLVMArgVtypeInReg:
3426 case LLVMArgAsFpArgs: {
3430 for (j = 0; j < ainfo->ndummy_fpargs; ++j)
3431 args [pindex + j] = LLVMConstNull (LLVMDoubleType ());
3432 pindex += ainfo->ndummy_fpargs;
3434 g_assert (addresses [reg]);
3435 emit_vtype_to_args (ctx, builder, ainfo->type, addresses [reg], ainfo, args + pindex, &nargs);
3439 // FIXME: Get rid of the VMOVE
3442 case LLVMArgVtypeByVal:
3443 g_assert (addresses [reg]);
3444 args [pindex] = addresses [reg];
3446 case LLVMArgVtypeByRef: {
3447 g_assert (addresses [reg]);
3448 args [pindex] = convert (ctx, addresses [reg], LLVMPointerType (type_to_llvm_arg_type (ctx, ainfo->type), 0));
3451 case LLVMArgAsIArgs:
3452 g_assert (addresses [reg]);
3453 args [pindex] = LLVMBuildLoad (ctx->builder, convert (ctx, addresses [reg], LLVMPointerType (LLVMArrayType (IntPtrType (), ainfo->nslots), 0)), "");
3455 case LLVMArgVtypeAsScalar:
3456 g_assert_not_reached ();
3458 case LLVMArgGsharedvtFixed:
3459 case LLVMArgGsharedvtFixedVtype:
3460 g_assert (addresses [reg]);
3461 args [pindex] = convert (ctx, addresses [reg], LLVMPointerType (type_to_llvm_arg_type (ctx, ainfo->type), 0));
3463 case LLVMArgGsharedvtVariable:
3464 g_assert (addresses [reg]);
3465 args [pindex] = convert (ctx, addresses [reg], LLVMPointerType (IntPtrType (), 0));
3468 g_assert (args [pindex]);
3469 if (i == 0 && sig->hasthis)
3470 args [pindex] = convert (ctx, args [pindex], param_types [pindex]);
3472 args [pindex] = convert (ctx, args [pindex], type_to_llvm_arg_type (ctx, ainfo->type));
3475 g_assert (pindex <= nargs);
3480 // FIXME: Align call sites
3486 lcall = emit_call (ctx, bb, &builder, callee, args, LLVMCountParamTypes (llvm_sig));
3489 * Modify cconv and parameter attributes to pass rgctx/imt correctly.
3491 #if defined(MONO_ARCH_IMT_REG) && defined(MONO_ARCH_RGCTX_REG)
3492 g_assert (MONO_ARCH_IMT_REG == MONO_ARCH_RGCTX_REG);
3494 /* The two can't be used together, so use only one LLVM calling conv to pass them */
3495 g_assert (!(call->rgctx_arg_reg && call->imt_arg_reg));
3496 if (!sig->pinvoke && !cfg->llvm_only)
3497 LLVMSetInstructionCallConv (lcall, LLVMMono1CallConv);
3499 mono_llvm_set_call_preserveall_cc (lcall);
3501 if (cinfo->ret.storage == LLVMArgVtypeByRef)
3502 LLVMAddInstrAttribute (lcall, 1 + cinfo->vret_arg_pindex, LLVMStructRetAttribute);
3503 if (!ctx->llvm_only && call->rgctx_arg_reg)
3504 LLVMAddInstrAttribute (lcall, 1 + cinfo->rgctx_arg_pindex, LLVMInRegAttribute);
3505 if (call->imt_arg_reg)
3506 LLVMAddInstrAttribute (lcall, 1 + cinfo->imt_arg_pindex, LLVMInRegAttribute);
3508 /* Add byval attributes if needed */
3509 for (i = 0; i < sig->param_count; ++i) {
3510 LLVMArgInfo *ainfo = &call->cinfo->args [i + sig->hasthis];
3512 if (ainfo && ainfo->storage == LLVMArgVtypeByVal)
3513 LLVMAddInstrAttribute (lcall, 1 + ainfo->pindex, LLVMByValAttribute);
3517 * Convert the result
3519 switch (cinfo->ret.storage) {
3520 case LLVMArgVtypeInReg: {
3521 LLVMValueRef regs [2];
3523 if (LLVMTypeOf (lcall) == LLVMVoidType ())
3527 if (!addresses [ins->dreg])
3528 addresses [ins->dreg] = build_alloca (ctx, sig->ret);
3530 regs [0] = LLVMBuildExtractValue (builder, lcall, 0, "");
3531 if (cinfo->ret.pair_storage [1] != LLVMArgNone)
3532 regs [1] = LLVMBuildExtractValue (builder, lcall, 1, "");
3533 emit_args_to_vtype (ctx, builder, sig->ret, addresses [ins->dreg], &cinfo->ret, regs);
3536 case LLVMArgVtypeByVal:
3537 if (!addresses [call->inst.dreg])
3538 addresses [call->inst.dreg] = build_alloca (ctx, sig->ret);
3539 LLVMBuildStore (builder, lcall, addresses [call->inst.dreg]);
3541 case LLVMArgFpStruct:
3542 if (!addresses [call->inst.dreg])
3543 addresses [call->inst.dreg] = build_alloca (ctx, sig->ret);
3544 LLVMBuildStore (builder, lcall, convert_full (ctx, addresses [call->inst.dreg], LLVMPointerType (LLVMTypeOf (lcall), 0), FALSE));
3546 case LLVMArgVtypeAsScalar:
3547 if (!addresses [call->inst.dreg])
3548 addresses [call->inst.dreg] = build_alloca (ctx, sig->ret);
3549 LLVMBuildStore (builder, lcall, convert_full (ctx, addresses [call->inst.dreg], LLVMPointerType (LLVMTypeOf (lcall), 0), FALSE));
3551 case LLVMArgVtypeRetAddr:
3552 case LLVMArgVtypeByRef:
3553 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (sig->ret))) {
3554 /* Some opcodes like STOREX_MEMBASE access these by value */
3555 g_assert (addresses [call->inst.dreg]);
3556 values [ins->dreg] = LLVMBuildLoad (builder, convert_full (ctx, addresses [call->inst.dreg], LLVMPointerType (type_to_llvm_type (ctx, sig->ret), 0), FALSE), "");
3559 case LLVMArgGsharedvtVariable:
3561 case LLVMArgGsharedvtFixed:
3562 case LLVMArgGsharedvtFixedVtype:
3563 values [ins->dreg] = LLVMBuildLoad (builder, convert_full (ctx, addresses [call->inst.dreg], LLVMPointerType (type_to_llvm_type (ctx, sig->ret), 0), FALSE), "");
3566 if (sig->ret->type != MONO_TYPE_VOID)
3567 /* If the method returns an unsigned value, need to zext it */
3568 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));
3572 *builder_ref = ctx->builder;
3576 emit_llvmonly_throw (EmitContext *ctx, MonoBasicBlock *bb, gboolean rethrow, LLVMValueRef exc)
3578 const char *icall_name = rethrow ? "mono_llvm_rethrow_exception" : "mono_llvm_throw_exception";
3579 LLVMValueRef callee = rethrow ? ctx->module->rethrow : ctx->module->throw_icall;
3581 LLVMTypeRef exc_type = type_to_llvm_type (ctx, &mono_get_exception_class ()->byval_arg);
3584 LLVMTypeRef fun_sig = LLVMFunctionType1 (LLVMVoidType (), exc_type, FALSE);
3586 if (ctx->cfg->compile_aot) {
3587 callee = get_callee (ctx, fun_sig, MONO_PATCH_INFO_JIT_ICALL_ADDR, icall_name);
3589 callee = LLVMAddFunction (ctx->lmodule, icall_name, fun_sig);
3590 LLVMAddGlobalMapping (ctx->module->ee, callee, resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name));
3591 mono_memory_barrier ();
3594 ctx->module->rethrow = callee;
3596 ctx->module->throw_icall = callee;
3600 LLVMValueRef args [2];
3602 args [0] = convert (ctx, exc, exc_type);
3603 emit_call (ctx, bb, &ctx->builder, callee, args, 1);
3605 LLVMBuildUnreachable (ctx->builder);
3607 ctx->builder = create_builder (ctx);
3611 emit_throw (EmitContext *ctx, MonoBasicBlock *bb, gboolean rethrow, LLVMValueRef exc)
3613 MonoMethodSignature *throw_sig;
3614 LLVMValueRef callee, arg;
3615 const char *icall_name;
3617 callee = rethrow ? ctx->module->rethrow : ctx->module->throw_icall;
3618 icall_name = rethrow ? "mono_arch_rethrow_exception" : "mono_arch_throw_exception";
3621 throw_sig = mono_metadata_signature_alloc (mono_get_corlib (), 1);
3622 throw_sig->ret = &mono_get_void_class ()->byval_arg;
3623 throw_sig->params [0] = &mono_get_object_class ()->byval_arg;
3624 if (ctx->cfg->compile_aot) {
3625 callee = get_callee (ctx, sig_to_llvm_sig (ctx, throw_sig), MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
3630 * LLVM doesn't push the exception argument, so we need a different
3633 target = resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, rethrow ? "llvm_rethrow_exception_trampoline" : "llvm_throw_exception_trampoline");
3635 target = resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
3637 callee = emit_jit_callee (ctx, icall_name, sig_to_llvm_sig (ctx, throw_sig), target);
3640 mono_memory_barrier ();
3641 #if LLVM_API_VERSION < 100
3643 ctx->module->rethrow = callee;
3645 ctx->module->throw_icall = callee;
3648 arg = convert (ctx, exc, type_to_llvm_type (ctx, &mono_get_object_class ()->byval_arg));
3649 emit_call (ctx, bb, &ctx->builder, callee, &arg, 1);
3653 emit_resume_eh (EmitContext *ctx, MonoBasicBlock *bb)
3655 const char *icall_name = "mono_llvm_resume_exception";
3656 LLVMValueRef callee = ctx->module->resume_eh;
3658 LLVMTypeRef fun_sig = LLVMFunctionType0 (LLVMVoidType (), FALSE);
3661 if (ctx->cfg->compile_aot) {
3662 callee = get_callee (ctx, fun_sig, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
3664 callee = LLVMAddFunction (ctx->lmodule, icall_name, fun_sig);
3665 LLVMAddGlobalMapping (ctx->module->ee, callee, resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name));
3666 mono_memory_barrier ();
3668 ctx->module->resume_eh = callee;
3672 emit_call (ctx, bb, &ctx->builder, callee, NULL, 0);
3674 LLVMBuildUnreachable (ctx->builder);
3676 ctx->builder = create_builder (ctx);
3680 mono_llvm_emit_clear_exception_call (EmitContext *ctx, LLVMBuilderRef builder)
3682 const char *icall_name = "mono_llvm_clear_exception";
3684 LLVMTypeRef call_sig = LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE);
3685 LLVMValueRef callee = NULL;
3688 if (ctx->cfg->compile_aot) {
3689 callee = get_callee (ctx, call_sig, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
3691 // FIXME: This is broken.
3692 callee = LLVMAddFunction (ctx->lmodule, icall_name, call_sig);
3696 g_assert (builder && callee);
3698 return LLVMBuildCall (builder, callee, NULL, 0, "");
3702 mono_llvm_emit_load_exception_call (EmitContext *ctx, LLVMBuilderRef builder)
3704 const char *icall_name = "mono_llvm_load_exception";
3706 LLVMTypeRef call_sig = LLVMFunctionType (ObjRefType (), NULL, 0, FALSE);
3707 LLVMValueRef callee = NULL;
3710 if (ctx->cfg->compile_aot) {
3711 callee = get_callee (ctx, call_sig, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
3713 // FIXME: This is broken.
3714 callee = LLVMAddFunction (ctx->lmodule, icall_name, call_sig);
3718 g_assert (builder && callee);
3720 return LLVMBuildCall (builder, callee, NULL, 0, icall_name);
3725 mono_llvm_emit_match_exception_call (EmitContext *ctx, LLVMBuilderRef builder, gint32 region_start, gint32 region_end)
3727 const char *icall_name = "mono_llvm_match_exception";
3729 ctx->builder = builder;
3731 const int num_args = 5;
3732 LLVMValueRef args [num_args];
3733 args [0] = convert (ctx, get_aotconst (ctx, MONO_PATCH_INFO_AOT_JIT_INFO, GINT_TO_POINTER (ctx->cfg->method_index)), IntPtrType ());
3734 args [1] = LLVMConstInt (LLVMInt32Type (), region_start, 0);
3735 args [2] = LLVMConstInt (LLVMInt32Type (), region_end, 0);
3736 if (ctx->cfg->rgctx_var) {
3737 LLVMValueRef rgctx_alloc = ctx->addresses [ctx->cfg->rgctx_var->dreg];
3738 g_assert (rgctx_alloc);
3739 args [3] = LLVMBuildLoad (builder, convert (ctx, rgctx_alloc, LLVMPointerType (IntPtrType (), 0)), "");
3741 args [3] = LLVMConstInt (IntPtrType (), 0, 0);
3744 args [4] = convert (ctx, ctx->this_arg, IntPtrType ());
3746 args [4] = LLVMConstInt (IntPtrType (), 0, 0);
3748 LLVMTypeRef match_sig = LLVMFunctionType5 (LLVMInt32Type (), IntPtrType (), LLVMInt32Type (), LLVMInt32Type (), IntPtrType (), IntPtrType (), FALSE);
3749 LLVMValueRef callee = ctx->module->match_exc;
3752 if (ctx->cfg->compile_aot) {
3753 ctx->builder = builder;
3754 // get_callee expects ctx->builder to be the emitting builder
3755 callee = get_callee (ctx, match_sig, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
3757 callee = ctx->module->match_exc = LLVMAddFunction (ctx->lmodule, icall_name, match_sig);
3758 LLVMAddGlobalMapping (ctx->module->ee, ctx->module->match_exc, resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name));
3759 ctx->module->match_exc = callee;
3760 mono_memory_barrier ();
3764 g_assert (builder && callee);
3766 g_assert (ctx->ex_var);
3768 return LLVMBuildCall (builder, callee, args, num_args, icall_name);
3771 // FIXME: This won't work because the code-finding makes this
3773 /*#define MONO_PERSONALITY_DEBUG*/
3775 #ifdef MONO_PERSONALITY_DEBUG
3776 static const gboolean use_debug_personality = TRUE;
3777 static const char *default_personality_name = "mono_debug_personality";
3779 static const gboolean use_debug_personality = FALSE;
3780 static const char *default_personality_name = "__gxx_personality_v0";
3784 default_cpp_lpad_exc_signature (void)
3786 static gboolean inited = FALSE;
3787 static LLVMTypeRef sig;
3790 LLVMTypeRef signature [2];
3791 signature [0] = LLVMPointerType (LLVMInt8Type (), 0);
3792 signature [1] = LLVMInt32Type ();
3793 sig = LLVMStructType (signature, 2, FALSE);
3801 get_mono_personality (EmitContext *ctx)
3803 LLVMValueRef personality = NULL;
3804 static gint32 mapping_inited = FALSE;
3805 LLVMTypeRef personality_type = LLVMFunctionType (LLVMInt32Type (), NULL, 0, TRUE);
3807 if (!use_debug_personality) {
3808 if (ctx->cfg->compile_aot) {
3809 personality = get_intrinsic (ctx, default_personality_name);
3810 } else if (InterlockedCompareExchange (&mapping_inited, 1, 0) == 0) {
3811 personality = LLVMAddFunction (ctx->lmodule, default_personality_name, personality_type);
3812 LLVMAddGlobalMapping (ctx->module->ee, personality, personality);
3815 if (ctx->cfg->compile_aot) {
3816 personality = get_callee (ctx, personality_type, MONO_PATCH_INFO_INTERNAL_METHOD, default_personality_name);
3818 personality = LLVMAddFunction (ctx->lmodule, default_personality_name, personality_type);
3819 LLVMAddGlobalMapping (ctx->module->ee, personality, resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, default_personality_name));
3820 mono_memory_barrier ();
3824 g_assert (personality);
3828 static LLVMBasicBlockRef
3829 emit_landing_pad (EmitContext *ctx, int group_index, int group_size)
3831 MonoCompile *cfg = ctx->cfg;
3832 LLVMBuilderRef old_builder = ctx->builder;
3833 MonoExceptionClause *group_start = cfg->header->clauses + group_index;
3835 LLVMBuilderRef lpadBuilder = create_builder (ctx);
3836 ctx->builder = lpadBuilder;
3838 MonoBasicBlock *handler_bb = cfg->cil_offset_to_bb [CLAUSE_START (group_start)];
3839 g_assert (handler_bb);
3841 // <resultval> = landingpad <somety> personality <type> <pers_fn> <clause>+
3842 LLVMValueRef personality = get_mono_personality (ctx);
3843 g_assert (personality);
3845 char *bb_name = g_strdup_printf ("LPAD%d_BB", group_index);
3846 LLVMBasicBlockRef lpad_bb = gen_bb (ctx, bb_name);
3848 LLVMPositionBuilderAtEnd (lpadBuilder, lpad_bb);
3849 LLVMValueRef landing_pad = LLVMBuildLandingPad (lpadBuilder, default_cpp_lpad_exc_signature (), personality, 0, "");
3850 g_assert (landing_pad);
3852 LLVMValueRef cast = LLVMBuildBitCast (lpadBuilder, ctx->module->sentinel_exception, LLVMPointerType (LLVMInt8Type (), 0), "int8TypeInfo");
3853 LLVMAddClause (landing_pad, cast);
3855 LLVMBasicBlockRef resume_bb = gen_bb (ctx, "RESUME_BB");
3856 LLVMBuilderRef resume_builder = create_builder (ctx);
3857 ctx->builder = resume_builder;
3858 LLVMPositionBuilderAtEnd (resume_builder, resume_bb);
3860 emit_resume_eh (ctx, handler_bb);
3863 ctx->builder = lpadBuilder;
3864 LLVMPositionBuilderAtEnd (lpadBuilder, lpad_bb);
3866 gboolean finally_only = TRUE;
3868 MonoExceptionClause *group_cursor = group_start;
3870 for (int i = 0; i < group_size; i ++) {
3871 if (!(group_cursor->flags & MONO_EXCEPTION_CLAUSE_FINALLY))
3872 finally_only = FALSE;
3878 // Handle landing pad inlining
3880 if (!finally_only) {
3881 // So at each level of the exception stack we will match the exception again.
3882 // During that match, we need to compare against the handler types for the current
3883 // protected region. We send the try start and end so that we can only check against
3884 // handlers for this lexical protected region.
3885 LLVMValueRef match = mono_llvm_emit_match_exception_call (ctx, lpadBuilder, group_start->try_offset, group_start->try_offset + group_start->try_len);
3887 // if returns -1, resume
3888 LLVMValueRef switch_ins = LLVMBuildSwitch (lpadBuilder, match, resume_bb, group_size);
3890 // else move to that target bb
3891 for (int i=0; i < group_size; i++) {
3892 MonoExceptionClause *clause = group_start + i;
3893 int clause_index = clause - cfg->header->clauses;
3894 MonoBasicBlock *handler_bb = (MonoBasicBlock*)g_hash_table_lookup (ctx->clause_to_handler, GINT_TO_POINTER (clause_index));
3895 g_assert (handler_bb);
3896 g_assert (ctx->bblocks [handler_bb->block_num].call_handler_target_bb);
3897 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), clause_index, FALSE), ctx->bblocks [handler_bb->block_num].call_handler_target_bb);
3900 int clause_index = group_start - cfg->header->clauses;
3901 MonoBasicBlock *finally_bb = (MonoBasicBlock*)g_hash_table_lookup (ctx->clause_to_handler, GINT_TO_POINTER (clause_index));
3902 g_assert (finally_bb);
3904 LLVMBuildBr (ctx->builder, ctx->bblocks [finally_bb->block_num].call_handler_target_bb);
3907 ctx->builder = old_builder;
3914 emit_llvmonly_handler_start (EmitContext *ctx, MonoBasicBlock *bb, LLVMBasicBlockRef cbb)
3916 int clause_index = MONO_REGION_CLAUSE_INDEX (bb->region);
3917 MonoExceptionClause *clause = &ctx->cfg->header->clauses [clause_index];
3919 // Make exception available to catch blocks
3920 if (!(clause->flags & MONO_EXCEPTION_CLAUSE_FINALLY)) {
3921 LLVMValueRef mono_exc = mono_llvm_emit_load_exception_call (ctx, ctx->builder);
3923 g_assert (ctx->ex_var);
3924 LLVMBuildStore (ctx->builder, LLVMBuildBitCast (ctx->builder, mono_exc, ObjRefType (), ""), ctx->ex_var);
3926 if (bb->in_scount == 1) {
3927 MonoInst *exvar = bb->in_stack [0];
3928 g_assert (!ctx->values [exvar->dreg]);
3929 g_assert (ctx->ex_var);
3930 ctx->values [exvar->dreg] = LLVMBuildLoad (ctx->builder, ctx->ex_var, "save_exception");
3931 emit_volatile_store (ctx, exvar->dreg);
3934 mono_llvm_emit_clear_exception_call (ctx, ctx->builder);
3937 LLVMBuilderRef handler_builder = create_builder (ctx);
3938 LLVMBasicBlockRef target_bb = ctx->bblocks [bb->block_num].call_handler_target_bb;
3939 LLVMPositionBuilderAtEnd (handler_builder, target_bb);
3941 // Make the handler code end with a jump to cbb
3942 LLVMBuildBr (handler_builder, cbb);
3946 emit_handler_start (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef builder)
3948 MonoCompile *cfg = ctx->cfg;
3949 LLVMValueRef *values = ctx->values;
3950 LLVMModuleRef lmodule = ctx->lmodule;
3951 BBInfo *bblocks = ctx->bblocks;
3953 LLVMValueRef personality;
3954 LLVMValueRef landing_pad;
3955 LLVMBasicBlockRef target_bb;
3957 static int ti_generator;
3959 LLVMValueRef type_info;
3963 // <resultval> = landingpad <somety> personality <type> <pers_fn> <clause>+
3965 if (cfg->compile_aot) {
3966 /* Use a dummy personality function */
3967 personality = LLVMGetNamedFunction (lmodule, "mono_personality");
3968 g_assert (personality);
3970 #if LLVM_API_VERSION > 100
3971 LLVMTypeRef personality_type = LLVMFunctionType (LLVMInt32Type (), NULL, 0, TRUE);
3972 personality = LLVMAddFunction (ctx->lmodule, "mono_personality", personality_type);
3973 LLVMAddFunctionAttr (personality, LLVMNoUnwindAttribute);
3974 LLVMBasicBlockRef entry_bb = LLVMAppendBasicBlock (personality, "ENTRY");
3975 LLVMBuilderRef builder2 = LLVMCreateBuilder ();
3976 LLVMPositionBuilderAtEnd (builder2, entry_bb);
3977 LLVMBuildRet (builder2, LLVMConstInt (LLVMInt32Type (), 0, FALSE));
3979 static gint32 mapping_inited;
3981 personality = LLVMGetNamedFunction (lmodule, "mono_personality");
3983 if (InterlockedCompareExchange (&mapping_inited, 1, 0) == 0)
3984 LLVMAddGlobalMapping (ctx->module->ee, personality, (gpointer)mono_personality);
3988 i8ptr = LLVMPointerType (LLVMInt8Type (), 0);
3990 clause_index = (mono_get_block_region_notry (cfg, bb->region) >> 8) - 1;
3993 * Create the type info
3995 sprintf (ti_name, "type_info_%d", ti_generator);
3998 if (cfg->compile_aot) {
3999 /* decode_eh_frame () in aot-runtime.c will decode this */
4000 type_info = LLVMAddGlobal (lmodule, LLVMInt32Type (), ti_name);
4001 LLVMSetInitializer (type_info, LLVMConstInt (LLVMInt32Type (), clause_index, FALSE));
4004 * These symbols are not really used, the clause_index is embedded into the EH tables generated by DwarfMonoException in LLVM.
4006 LLVMSetLinkage (type_info, LLVMInternalLinkage);
4008 #if LLVM_API_VERSION > 100
4009 type_info = LLVMAddGlobal (lmodule, LLVMInt32Type (), ti_name);
4010 LLVMSetInitializer (type_info, LLVMConstInt (LLVMInt32Type (), clause_index, FALSE));
4015 * After the cfg mempool is freed, the type info will point to stale memory,
4016 * but this is not a problem, since we decode it once in exception_cb during
4019 ti = (gint32*)mono_mempool_alloc (cfg->mempool, sizeof (gint32));
4020 *(gint32*)ti = clause_index;
4022 type_info = LLVMAddGlobal (lmodule, i8ptr, ti_name);
4024 LLVMAddGlobalMapping (ctx->module->ee, type_info, ti);
4029 LLVMTypeRef members [2], ret_type;
4031 members [0] = i8ptr;
4032 members [1] = LLVMInt32Type ();
4033 ret_type = LLVMStructType (members, 2, FALSE);
4035 landing_pad = LLVMBuildLandingPad (builder, ret_type, personality, 1, "");
4036 LLVMAddClause (landing_pad, type_info);
4038 /* Store the exception into the exvar */
4040 LLVMBuildStore (builder, convert (ctx, LLVMBuildExtractValue (builder, landing_pad, 0, "ex_obj"), ObjRefType ()), ctx->ex_var);
4044 * LLVM throw sites are associated with a one landing pad, and LLVM generated
4045 * code expects control to be transferred to this landing pad even in the
4046 * presence of nested clauses. The landing pad needs to branch to the landing
4047 * pads belonging to nested clauses based on the selector value returned by
4048 * the landing pad instruction, which is passed to the landing pad in a
4049 * register by the EH code.
4051 target_bb = bblocks [bb->block_num].call_handler_target_bb;
4052 g_assert (target_bb);
4055 * Branch to the correct landing pad
4057 LLVMValueRef ex_selector = LLVMBuildExtractValue (builder, landing_pad, 1, "ex_selector");
4058 LLVMValueRef switch_ins = LLVMBuildSwitch (builder, ex_selector, target_bb, 0);
4060 for (l = ctx->nested_in [clause_index]; l; l = l->next) {
4061 int nesting_clause_index = GPOINTER_TO_INT (l->data);
4062 MonoBasicBlock *handler_bb;
4064 handler_bb = (MonoBasicBlock*)g_hash_table_lookup (ctx->clause_to_handler, GINT_TO_POINTER (nesting_clause_index));
4065 g_assert (handler_bb);
4067 g_assert (ctx->bblocks [handler_bb->block_num].call_handler_target_bb);
4068 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), nesting_clause_index, FALSE), ctx->bblocks [handler_bb->block_num].call_handler_target_bb);
4071 /* Start a new bblock which CALL_HANDLER can branch to */
4072 target_bb = bblocks [bb->block_num].call_handler_target_bb;
4074 ctx->builder = builder = create_builder (ctx);
4075 LLVMPositionBuilderAtEnd (ctx->builder, target_bb);
4077 ctx->bblocks [bb->block_num].end_bblock = target_bb;
4079 /* Store the exception into the IL level exvar */
4080 if (bb->in_scount == 1) {
4081 g_assert (bb->in_scount == 1);
4082 exvar = bb->in_stack [0];
4084 // FIXME: This is shared with filter clauses ?
4085 g_assert (!values [exvar->dreg]);
4087 g_assert (ctx->ex_var);
4088 values [exvar->dreg] = LLVMBuildLoad (builder, ctx->ex_var, "");
4089 emit_volatile_store (ctx, exvar->dreg);
4095 process_bb (EmitContext *ctx, MonoBasicBlock *bb)
4097 MonoCompile *cfg = ctx->cfg;
4098 MonoMethodSignature *sig = ctx->sig;
4099 LLVMValueRef method = ctx->lmethod;
4100 LLVMValueRef *values = ctx->values;
4101 LLVMValueRef *addresses = ctx->addresses;
4102 LLVMCallInfo *linfo = ctx->linfo;
4103 BBInfo *bblocks = ctx->bblocks;
4105 LLVMBasicBlockRef cbb;
4106 LLVMBuilderRef builder, starting_builder;
4107 gboolean has_terminator;
4109 LLVMValueRef lhs, rhs;
4112 cbb = get_end_bb (ctx, bb);
4114 builder = create_builder (ctx);
4115 ctx->builder = builder;
4116 LLVMPositionBuilderAtEnd (builder, cbb);
4121 if (bb->flags & BB_EXCEPTION_HANDLER) {
4122 if (!ctx->llvm_only && !bblocks [bb->block_num].invoke_target) {
4123 set_failure (ctx, "handler without invokes");
4128 emit_llvmonly_handler_start (ctx, bb, cbb);
4130 emit_handler_start (ctx, bb, builder);
4133 builder = ctx->builder;
4136 has_terminator = FALSE;
4137 starting_builder = builder;
4138 for (ins = bb->code; ins; ins = ins->next) {
4139 const char *spec = LLVM_INS_INFO (ins->opcode);
4141 char dname_buf [128];
4143 emit_dbg_loc (ctx, builder, ins->cil_code);
4148 * Some steps in llc are non-linear in the size of basic blocks, see #5714.
4149 * Start a new bblock. If the llvm optimization passes merge these, we
4150 * can work around that by doing a volatile load + cond branch from
4151 * localloc-ed memory.
4153 //set_failure (ctx, "basic block too long");
4154 cbb = gen_bb (ctx, "CONT_LONG_BB");
4155 LLVMBuildBr (ctx->builder, cbb);
4156 ctx->builder = builder = create_builder (ctx);
4157 LLVMPositionBuilderAtEnd (builder, cbb);
4158 ctx->bblocks [bb->block_num].end_bblock = cbb;
4163 /* There could be instructions after a terminator, skip them */
4166 if (spec [MONO_INST_DEST] != ' ' && !MONO_IS_STORE_MEMBASE (ins)) {
4167 sprintf (dname_buf, "t%d", ins->dreg);
4171 if (spec [MONO_INST_SRC1] != ' ' && spec [MONO_INST_SRC1] != 'v') {
4172 MonoInst *var = get_vreg_to_inst (cfg, ins->sreg1);
4174 if (var && var->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT) && var->opcode != OP_GSHAREDVT_ARG_REGOFFSET) {
4175 lhs = emit_volatile_load (ctx, ins->sreg1);
4177 /* It is ok for SETRET to have an uninitialized argument */
4178 if (!values [ins->sreg1] && ins->opcode != OP_SETRET) {
4179 set_failure (ctx, "sreg1");
4182 lhs = values [ins->sreg1];
4188 if (spec [MONO_INST_SRC2] != ' ' && spec [MONO_INST_SRC2] != ' ') {
4189 MonoInst *var = get_vreg_to_inst (cfg, ins->sreg2);
4190 if (var && var->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT)) {
4191 rhs = emit_volatile_load (ctx, ins->sreg2);
4193 if (!values [ins->sreg2]) {
4194 set_failure (ctx, "sreg2");
4197 rhs = values [ins->sreg2];
4203 //mono_print_ins (ins);
4204 switch (ins->opcode) {
4207 case OP_LIVERANGE_START:
4208 case OP_LIVERANGE_END:
4211 values [ins->dreg] = LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE);
4214 #if SIZEOF_VOID_P == 4
4215 values [ins->dreg] = LLVMConstInt (LLVMInt64Type (), GET_LONG_IMM (ins), FALSE);
4217 values [ins->dreg] = LLVMConstInt (LLVMInt64Type (), (gint64)ins->inst_c0, FALSE);
4221 values [ins->dreg] = LLVMConstReal (LLVMDoubleType (), *(double*)ins->inst_p0);
4225 values [ins->dreg] = LLVMConstReal (LLVMFloatType (), *(float*)ins->inst_p0);
4227 values [ins->dreg] = LLVMConstFPExt (LLVMConstReal (LLVMFloatType (), *(float*)ins->inst_p0), LLVMDoubleType ());
4229 case OP_DUMMY_ICONST:
4230 values [ins->dreg] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
4232 case OP_DUMMY_I8CONST:
4233 values [ins->dreg] = LLVMConstInt (LLVMInt64Type (), 0, FALSE);
4235 case OP_DUMMY_R8CONST:
4236 values [ins->dreg] = LLVMConstReal (LLVMDoubleType (), 0.0f);
4239 LLVMBasicBlockRef target_bb = get_bb (ctx, ins->inst_target_bb);
4240 LLVMBuildBr (builder, target_bb);
4241 has_terminator = TRUE;
4248 LLVMBasicBlockRef new_bb;
4249 LLVMBuilderRef new_builder;
4251 // The default branch is already handled
4252 // FIXME: Handle it here
4254 /* Start new bblock */
4255 sprintf (bb_name, "SWITCH_DEFAULT_BB%d", ctx->default_index ++);
4256 new_bb = LLVMAppendBasicBlock (ctx->lmethod, bb_name);
4258 lhs = convert (ctx, lhs, LLVMInt32Type ());
4259 v = LLVMBuildSwitch (builder, lhs, new_bb, GPOINTER_TO_UINT (ins->klass));
4260 for (i = 0; i < GPOINTER_TO_UINT (ins->klass); ++i) {
4261 MonoBasicBlock *target_bb = ins->inst_many_bb [i];
4263 LLVMAddCase (v, LLVMConstInt (LLVMInt32Type (), i, FALSE), get_bb (ctx, target_bb));
4266 new_builder = create_builder (ctx);
4267 LLVMPositionBuilderAtEnd (new_builder, new_bb);
4268 LLVMBuildUnreachable (new_builder);
4270 has_terminator = TRUE;
4271 g_assert (!ins->next);
4277 switch (linfo->ret.storage) {
4278 case LLVMArgVtypeInReg: {
4279 LLVMTypeRef ret_type = LLVMGetReturnType (LLVMGetElementType (LLVMTypeOf (method)));
4280 LLVMValueRef val, addr, retval;
4283 retval = LLVMGetUndef (ret_type);
4285 if (!addresses [ins->sreg1]) {
4287 * The return type is an LLVM vector type, have to convert between it and the
4288 * real return type which is a struct type.
4290 g_assert (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (sig->ret)));
4291 /* Convert to 2xi64 first */
4292 val = LLVMBuildBitCast (builder, values [ins->sreg1], LLVMVectorType (IntPtrType (), 2), "");
4294 for (i = 0; i < 2; ++i) {
4295 if (linfo->ret.pair_storage [i] == LLVMArgInIReg) {
4296 retval = LLVMBuildInsertValue (builder, retval, LLVMBuildExtractElement (builder, val, LLVMConstInt (LLVMInt32Type (), i, FALSE), ""), i, "");
4298 g_assert (linfo->ret.pair_storage [i] == LLVMArgNone);
4302 addr = LLVMBuildBitCast (builder, addresses [ins->sreg1], LLVMPointerType (ret_type, 0), "");
4303 for (i = 0; i < 2; ++i) {
4304 if (linfo->ret.pair_storage [i] == LLVMArgInIReg) {
4305 LLVMValueRef indexes [2], part_addr;
4307 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
4308 indexes [1] = LLVMConstInt (LLVMInt32Type (), i, FALSE);
4309 part_addr = LLVMBuildGEP (builder, addr, indexes, 2, "");
4311 retval = LLVMBuildInsertValue (builder, retval, LLVMBuildLoad (builder, part_addr, ""), i, "");
4313 g_assert (linfo->ret.pair_storage [i] == LLVMArgNone);
4317 LLVMBuildRet (builder, retval);
4320 case LLVMArgVtypeAsScalar: {
4321 LLVMTypeRef ret_type = LLVMGetReturnType (LLVMGetElementType (LLVMTypeOf (method)));
4322 LLVMValueRef retval;
4324 g_assert (addresses [ins->sreg1]);
4326 retval = LLVMBuildLoad (builder, LLVMBuildBitCast (builder, addresses [ins->sreg1], LLVMPointerType (ret_type, 0), ""), "");
4327 LLVMBuildRet (builder, retval);
4330 case LLVMArgVtypeByVal: {
4331 LLVMValueRef retval;
4333 g_assert (addresses [ins->sreg1]);
4334 retval = LLVMBuildLoad (builder, addresses [ins->sreg1], "");
4335 LLVMBuildRet (builder, retval);
4338 case LLVMArgVtypeByRef: {
4339 LLVMBuildRetVoid (builder);
4342 case LLVMArgGsharedvtFixed: {
4343 LLVMTypeRef ret_type = type_to_llvm_type (ctx, sig->ret);
4344 /* The return value is in lhs, need to store to the vret argument */
4345 /* sreg1 might not be set */
4347 g_assert (cfg->vret_addr);
4348 g_assert (values [cfg->vret_addr->dreg]);
4349 LLVMBuildStore (builder, convert (ctx, lhs, ret_type), convert (ctx, values [cfg->vret_addr->dreg], LLVMPointerType (ret_type, 0)));
4351 LLVMBuildRetVoid (builder);
4354 case LLVMArgGsharedvtFixedVtype: {
4356 LLVMBuildRetVoid (builder);
4359 case LLVMArgGsharedvtVariable: {
4361 LLVMBuildRetVoid (builder);
4364 case LLVMArgVtypeRetAddr: {
4365 LLVMBuildRetVoid (builder);
4368 case LLVMArgFpStruct: {
4369 LLVMTypeRef ret_type = LLVMGetReturnType (LLVMGetElementType (LLVMTypeOf (method)));
4370 LLVMValueRef retval;
4372 g_assert (addresses [ins->sreg1]);
4373 retval = LLVMBuildLoad (builder, convert (ctx, addresses [ins->sreg1], LLVMPointerType (ret_type, 0)), "");
4374 LLVMBuildRet (builder, retval);
4378 case LLVMArgNormal: {
4379 if (!lhs || ctx->is_dead [ins->sreg1]) {
4381 * The method did not set its return value, probably because it
4382 * ends with a throw.
4385 LLVMBuildRetVoid (builder);
4387 LLVMBuildRet (builder, LLVMConstNull (type_to_llvm_type (ctx, sig->ret)));
4389 LLVMBuildRet (builder, convert (ctx, lhs, type_to_llvm_type (ctx, sig->ret)));
4391 has_terminator = TRUE;
4395 g_assert_not_reached ();
4404 case OP_ICOMPARE_IMM:
4405 case OP_LCOMPARE_IMM:
4406 case OP_COMPARE_IMM: {
4408 LLVMValueRef cmp, args [16];
4409 gboolean likely = (ins->flags & MONO_INST_LIKELY) != 0;
4411 if (ins->next->opcode == OP_NOP)
4414 if (ins->next->opcode == OP_BR)
4415 /* The comparison result is not needed */
4418 rel = mono_opcode_to_cond (ins->next->opcode);
4420 if (ins->opcode == OP_ICOMPARE_IMM) {
4421 lhs = convert (ctx, lhs, LLVMInt32Type ());
4422 rhs = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
4424 if (ins->opcode == OP_LCOMPARE_IMM) {
4425 lhs = convert (ctx, lhs, LLVMInt64Type ());
4426 rhs = LLVMConstInt (LLVMInt64Type (), GET_LONG_IMM (ins), FALSE);
4428 if (ins->opcode == OP_LCOMPARE) {
4429 lhs = convert (ctx, lhs, LLVMInt64Type ());
4430 rhs = convert (ctx, rhs, LLVMInt64Type ());
4432 if (ins->opcode == OP_ICOMPARE) {
4433 lhs = convert (ctx, lhs, LLVMInt32Type ());
4434 rhs = convert (ctx, rhs, LLVMInt32Type ());
4438 if (LLVMGetTypeKind (LLVMTypeOf (lhs)) == LLVMPointerTypeKind)
4439 rhs = convert (ctx, rhs, LLVMTypeOf (lhs));
4440 else if (LLVMGetTypeKind (LLVMTypeOf (rhs)) == LLVMPointerTypeKind)
4441 lhs = convert (ctx, lhs, LLVMTypeOf (rhs));
4444 /* We use COMPARE+SETcc/Bcc, llvm uses SETcc+br cond */
4445 if (ins->opcode == OP_FCOMPARE) {
4446 cmp = LLVMBuildFCmp (builder, fpcond_to_llvm_cond [rel], convert (ctx, lhs, LLVMDoubleType ()), convert (ctx, rhs, LLVMDoubleType ()), "");
4447 } else if (ins->opcode == OP_RCOMPARE) {
4448 cmp = LLVMBuildFCmp (builder, fpcond_to_llvm_cond [rel], convert (ctx, lhs, LLVMFloatType ()), convert (ctx, rhs, LLVMFloatType ()), "");
4449 } else if (ins->opcode == OP_COMPARE_IMM) {
4450 if (LLVMGetTypeKind (LLVMTypeOf (lhs)) == LLVMPointerTypeKind && ins->inst_imm == 0)
4451 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], lhs, LLVMConstNull (LLVMTypeOf (lhs)), "");
4453 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE), "");
4454 } else if (ins->opcode == OP_LCOMPARE_IMM) {
4455 if (SIZEOF_REGISTER == 4 && COMPILE_LLVM (cfg)) {
4456 /* The immediate is encoded in two fields */
4457 guint64 l = ((guint64)(guint32)ins->inst_offset << 32) | ((guint32)ins->inst_imm);
4458 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, LLVMInt64Type ()), LLVMConstInt (LLVMInt64Type (), l, FALSE), "");
4460 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, LLVMInt64Type ()), LLVMConstInt (LLVMInt64Type (), ins->inst_imm, FALSE), "");
4463 else if (ins->opcode == OP_COMPARE) {
4464 if (LLVMGetTypeKind (LLVMTypeOf (lhs)) == LLVMPointerTypeKind && LLVMTypeOf (lhs) == LLVMTypeOf (rhs))
4465 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], lhs, rhs, "");
4467 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, IntPtrType ()), convert (ctx, rhs, IntPtrType ()), "");
4469 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], lhs, rhs, "");
4473 args [1] = LLVMConstInt (LLVMInt1Type (), 1, FALSE);
4474 cmp = LLVMBuildCall (ctx->builder, get_intrinsic (ctx, "llvm.expect.i1"), args, 2, "");
4477 if (MONO_IS_COND_BRANCH_OP (ins->next)) {
4478 if (ins->next->inst_true_bb == ins->next->inst_false_bb) {
4480 * If the target bb contains PHI instructions, LLVM requires
4481 * two PHI entries for this bblock, while we only generate one.
4482 * So convert this to an unconditional bblock. (bxc #171).
4484 LLVMBuildBr (builder, get_bb (ctx, ins->next->inst_true_bb));
4486 LLVMBuildCondBr (builder, cmp, get_bb (ctx, ins->next->inst_true_bb), get_bb (ctx, ins->next->inst_false_bb));
4488 has_terminator = TRUE;
4489 } else if (MONO_IS_SETCC (ins->next)) {
4490 sprintf (dname_buf, "t%d", ins->next->dreg);
4492 values [ins->next->dreg] = LLVMBuildZExt (builder, cmp, LLVMInt32Type (), dname);
4494 /* Add stores for volatile variables */
4495 emit_volatile_store (ctx, ins->next->dreg);
4496 } else if (MONO_IS_COND_EXC (ins->next)) {
4497 emit_cond_system_exception (ctx, bb, (const char*)ins->next->inst_p1, cmp);
4500 builder = ctx->builder;
4502 set_failure (ctx, "next");
4520 rel = mono_opcode_to_cond (ins->opcode);
4522 cmp = LLVMBuildFCmp (builder, fpcond_to_llvm_cond [rel], convert (ctx, lhs, LLVMDoubleType ()), convert (ctx, rhs, LLVMDoubleType ()), "");
4523 values [ins->dreg] = LLVMBuildZExt (builder, cmp, LLVMInt32Type (), dname);
4534 rel = mono_opcode_to_cond (ins->opcode);
4536 cmp = LLVMBuildFCmp (builder, fpcond_to_llvm_cond [rel], convert (ctx, lhs, LLVMFloatType ()), convert (ctx, rhs, LLVMFloatType ()), "");
4537 values [ins->dreg] = LLVMBuildZExt (builder, cmp, LLVMInt32Type (), dname);
4545 gboolean empty = TRUE;
4547 /* Check that all input bblocks really branch to us */
4548 for (i = 0; i < bb->in_count; ++i) {
4549 if (bb->in_bb [i]->last_ins && bb->in_bb [i]->last_ins->opcode == OP_NOT_REACHED)
4550 ins->inst_phi_args [i + 1] = -1;
4556 /* LLVM doesn't like phi instructions with zero operands */
4557 ctx->is_dead [ins->dreg] = TRUE;
4561 /* Created earlier, insert it now */
4562 LLVMInsertIntoBuilder (builder, values [ins->dreg]);
4564 for (i = 0; i < ins->inst_phi_args [0]; i++) {
4565 int sreg1 = ins->inst_phi_args [i + 1];
4569 * Count the number of times the incoming bblock branches to us,
4570 * since llvm requires a separate entry for each.
4572 if (bb->in_bb [i]->last_ins && bb->in_bb [i]->last_ins->opcode == OP_SWITCH) {
4573 MonoInst *switch_ins = bb->in_bb [i]->last_ins;
4576 for (j = 0; j < GPOINTER_TO_UINT (switch_ins->klass); ++j) {
4577 if (switch_ins->inst_many_bb [j] == bb)
4584 /* Remember for later */
4585 for (j = 0; j < count; ++j) {
4586 PhiNode *node = (PhiNode*)mono_mempool_alloc0 (ctx->mempool, sizeof (PhiNode));
4589 node->in_bb = bb->in_bb [i];
4591 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);
4601 values [ins->dreg] = lhs;
4605 MonoInst *var = get_vreg_to_inst (cfg, ins->dreg);
4608 values [ins->dreg] = lhs;
4610 if (var && var->klass->byval_arg.type == MONO_TYPE_R4) {
4612 * This is added by the spilling pass in case of the JIT,
4613 * but we have to do it ourselves.
4615 values [ins->dreg] = convert (ctx, values [ins->dreg], LLVMFloatType ());
4619 case OP_MOVE_F_TO_I4: {
4620 values [ins->dreg] = LLVMBuildBitCast (builder, LLVMBuildFPTrunc (builder, lhs, LLVMFloatType (), ""), LLVMInt32Type (), "");
4623 case OP_MOVE_I4_TO_F: {
4624 values [ins->dreg] = LLVMBuildFPExt (builder, LLVMBuildBitCast (builder, lhs, LLVMFloatType (), ""), LLVMDoubleType (), "");
4627 case OP_MOVE_F_TO_I8: {
4628 values [ins->dreg] = LLVMBuildBitCast (builder, lhs, LLVMInt64Type (), "");
4631 case OP_MOVE_I8_TO_F: {
4632 values [ins->dreg] = LLVMBuildBitCast (builder, lhs, LLVMDoubleType (), "");
4665 lhs = convert (ctx, lhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
4666 rhs = convert (ctx, rhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
4668 emit_div_check (ctx, builder, bb, ins, lhs, rhs);
4671 builder = ctx->builder;
4673 switch (ins->opcode) {
4676 values [ins->dreg] = LLVMBuildAdd (builder, lhs, rhs, dname);
4680 values [ins->dreg] = LLVMBuildSub (builder, lhs, rhs, dname);
4684 values [ins->dreg] = LLVMBuildMul (builder, lhs, rhs, dname);
4688 values [ins->dreg] = LLVMBuildSRem (builder, lhs, rhs, dname);
4692 values [ins->dreg] = LLVMBuildURem (builder, lhs, rhs, dname);
4696 values [ins->dreg] = LLVMBuildSDiv (builder, lhs, rhs, dname);
4700 values [ins->dreg] = LLVMBuildUDiv (builder, lhs, rhs, dname);
4704 values [ins->dreg] = LLVMBuildFDiv (builder, lhs, rhs, dname);
4708 values [ins->dreg] = LLVMBuildAnd (builder, lhs, rhs, dname);
4712 values [ins->dreg] = LLVMBuildOr (builder, lhs, rhs, dname);
4716 values [ins->dreg] = LLVMBuildXor (builder, lhs, rhs, dname);
4720 values [ins->dreg] = LLVMBuildShl (builder, lhs, rhs, dname);
4724 values [ins->dreg] = LLVMBuildAShr (builder, lhs, rhs, dname);
4728 values [ins->dreg] = LLVMBuildLShr (builder, lhs, rhs, dname);
4732 values [ins->dreg] = LLVMBuildFAdd (builder, lhs, rhs, dname);
4735 values [ins->dreg] = LLVMBuildFSub (builder, lhs, rhs, dname);
4738 values [ins->dreg] = LLVMBuildFMul (builder, lhs, rhs, dname);
4742 g_assert_not_reached ();
4749 lhs = convert (ctx, lhs, LLVMFloatType ());
4750 rhs = convert (ctx, rhs, LLVMFloatType ());
4751 switch (ins->opcode) {
4753 values [ins->dreg] = LLVMBuildFAdd (builder, lhs, rhs, dname);
4756 values [ins->dreg] = LLVMBuildFSub (builder, lhs, rhs, dname);
4759 values [ins->dreg] = LLVMBuildFMul (builder, lhs, rhs, dname);
4762 values [ins->dreg] = LLVMBuildFDiv (builder, lhs, rhs, dname);
4765 g_assert_not_reached ();
4774 case OP_IREM_UN_IMM:
4776 case OP_IDIV_UN_IMM:
4782 case OP_ISHR_UN_IMM:
4792 case OP_LSHR_UN_IMM:
4798 case OP_SHR_UN_IMM: {
4801 if (spec [MONO_INST_SRC1] == 'l') {
4802 imm = LLVMConstInt (LLVMInt64Type (), GET_LONG_IMM (ins), FALSE);
4804 imm = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
4807 emit_div_check (ctx, builder, bb, ins, lhs, imm);
4810 builder = ctx->builder;
4812 #if SIZEOF_VOID_P == 4
4813 if (ins->opcode == OP_LSHL_IMM || ins->opcode == OP_LSHR_IMM || ins->opcode == OP_LSHR_UN_IMM)
4814 imm = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
4817 if (LLVMGetTypeKind (LLVMTypeOf (lhs)) == LLVMPointerTypeKind)
4818 lhs = convert (ctx, lhs, IntPtrType ());
4819 imm = convert (ctx, imm, LLVMTypeOf (lhs));
4820 switch (ins->opcode) {
4824 values [ins->dreg] = LLVMBuildAdd (builder, lhs, imm, dname);
4828 values [ins->dreg] = LLVMBuildSub (builder, lhs, imm, dname);
4833 values [ins->dreg] = LLVMBuildMul (builder, lhs, imm, dname);
4837 values [ins->dreg] = LLVMBuildSDiv (builder, lhs, imm, dname);
4839 case OP_IDIV_UN_IMM:
4840 case OP_LDIV_UN_IMM:
4841 values [ins->dreg] = LLVMBuildUDiv (builder, lhs, imm, dname);
4845 values [ins->dreg] = LLVMBuildSRem (builder, lhs, imm, dname);
4847 case OP_IREM_UN_IMM:
4848 values [ins->dreg] = LLVMBuildURem (builder, lhs, imm, dname);
4853 values [ins->dreg] = LLVMBuildAnd (builder, lhs, imm, dname);
4857 values [ins->dreg] = LLVMBuildOr (builder, lhs, imm, dname);
4861 values [ins->dreg] = LLVMBuildXor (builder, lhs, imm, dname);
4866 values [ins->dreg] = LLVMBuildShl (builder, lhs, imm, dname);
4871 values [ins->dreg] = LLVMBuildAShr (builder, lhs, imm, dname);
4873 case OP_ISHR_UN_IMM:
4874 /* This is used to implement conv.u4, so the lhs could be an i8 */
4875 lhs = convert (ctx, lhs, LLVMInt32Type ());
4876 imm = convert (ctx, imm, LLVMInt32Type ());
4877 values [ins->dreg] = LLVMBuildLShr (builder, lhs, imm, dname);
4879 case OP_LSHR_UN_IMM:
4881 values [ins->dreg] = LLVMBuildLShr (builder, lhs, imm, dname);
4884 g_assert_not_reached ();
4889 values [ins->dreg] = LLVMBuildSub (builder, LLVMConstInt (LLVMInt32Type (), 0, FALSE), convert (ctx, lhs, LLVMInt32Type ()), dname);
4892 values [ins->dreg] = LLVMBuildSub (builder, LLVMConstInt (LLVMInt64Type (), 0, FALSE), lhs, dname);
4895 lhs = convert (ctx, lhs, LLVMDoubleType ());
4896 values [ins->dreg] = LLVMBuildFSub (builder, LLVMConstReal (LLVMDoubleType (), 0.0), lhs, dname);
4899 lhs = convert (ctx, lhs, LLVMFloatType ());
4900 values [ins->dreg] = LLVMBuildFSub (builder, LLVMConstReal (LLVMFloatType (), 0.0), lhs, dname);
4903 guint32 v = 0xffffffff;
4904 values [ins->dreg] = LLVMBuildXor (builder, LLVMConstInt (LLVMInt32Type (), v, FALSE), convert (ctx, lhs, LLVMInt32Type ()), dname);
4908 guint64 v = 0xffffffffffffffffLL;
4909 values [ins->dreg] = LLVMBuildXor (builder, LLVMConstInt (LLVMInt64Type (), v, FALSE), lhs, dname);
4912 #if defined(TARGET_X86) || defined(TARGET_AMD64)
4914 LLVMValueRef v1, v2;
4916 v1 = LLVMBuildMul (builder, convert (ctx, rhs, IntPtrType ()), LLVMConstInt (IntPtrType (), (1 << ins->backend.shift_amount), FALSE), "");
4917 v2 = LLVMBuildAdd (builder, convert (ctx, lhs, IntPtrType ()), v1, "");
4918 values [ins->dreg] = LLVMBuildAdd (builder, v2, LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE), dname);
4923 case OP_ICONV_TO_I1:
4924 case OP_ICONV_TO_I2:
4925 case OP_ICONV_TO_I4:
4926 case OP_ICONV_TO_U1:
4927 case OP_ICONV_TO_U2:
4928 case OP_ICONV_TO_U4:
4929 case OP_LCONV_TO_I1:
4930 case OP_LCONV_TO_I2:
4931 case OP_LCONV_TO_U1:
4932 case OP_LCONV_TO_U2:
4933 case OP_LCONV_TO_U4: {
4936 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);
4938 /* Have to do two casts since our vregs have type int */
4939 v = LLVMBuildTrunc (builder, lhs, op_to_llvm_type (ins->opcode), "");
4941 values [ins->dreg] = LLVMBuildSExt (builder, v, LLVMInt32Type (), dname);
4943 values [ins->dreg] = LLVMBuildZExt (builder, v, LLVMInt32Type (), dname);
4946 case OP_ICONV_TO_I8:
4947 values [ins->dreg] = LLVMBuildSExt (builder, lhs, LLVMInt64Type (), dname);
4949 case OP_ICONV_TO_U8:
4950 values [ins->dreg] = LLVMBuildZExt (builder, lhs, LLVMInt64Type (), dname);
4952 case OP_FCONV_TO_I4:
4953 case OP_RCONV_TO_I4:
4954 values [ins->dreg] = LLVMBuildFPToSI (builder, lhs, LLVMInt32Type (), dname);
4956 case OP_FCONV_TO_I1:
4957 case OP_RCONV_TO_I1:
4958 values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildFPToSI (builder, lhs, LLVMInt8Type (), dname), LLVMInt32Type (), "");
4960 case OP_FCONV_TO_U1:
4961 case OP_RCONV_TO_U1:
4962 values [ins->dreg] = LLVMBuildZExt (builder, LLVMBuildTrunc (builder, LLVMBuildFPToUI (builder, lhs, IntPtrType (), dname), LLVMInt8Type (), ""), LLVMInt32Type (), "");
4964 case OP_FCONV_TO_I2:
4965 case OP_RCONV_TO_I2:
4966 values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildFPToSI (builder, lhs, LLVMInt16Type (), dname), LLVMInt32Type (), "");
4968 case OP_FCONV_TO_U2:
4969 case OP_RCONV_TO_U2:
4970 values [ins->dreg] = LLVMBuildZExt (builder, LLVMBuildFPToUI (builder, lhs, LLVMInt16Type (), dname), LLVMInt32Type (), "");
4972 case OP_RCONV_TO_U4:
4973 values [ins->dreg] = LLVMBuildFPToUI (builder, lhs, LLVMInt32Type (), dname);
4975 case OP_FCONV_TO_I8:
4976 case OP_RCONV_TO_I8:
4977 values [ins->dreg] = LLVMBuildFPToSI (builder, lhs, LLVMInt64Type (), dname);
4980 values [ins->dreg] = LLVMBuildFPToSI (builder, lhs, IntPtrType (), dname);
4982 case OP_ICONV_TO_R8:
4983 case OP_LCONV_TO_R8:
4984 values [ins->dreg] = LLVMBuildSIToFP (builder, lhs, LLVMDoubleType (), dname);
4986 case OP_ICONV_TO_R_UN:
4987 case OP_LCONV_TO_R_UN:
4988 values [ins->dreg] = LLVMBuildUIToFP (builder, lhs, LLVMDoubleType (), dname);
4990 #if SIZEOF_VOID_P == 4
4993 case OP_LCONV_TO_I4:
4994 values [ins->dreg] = LLVMBuildTrunc (builder, lhs, LLVMInt32Type (), dname);
4996 case OP_ICONV_TO_R4:
4997 case OP_LCONV_TO_R4:
4998 v = LLVMBuildSIToFP (builder, lhs, LLVMFloatType (), "");
5000 values [ins->dreg] = v;
5002 values [ins->dreg] = LLVMBuildFPExt (builder, v, LLVMDoubleType (), dname);
5004 case OP_FCONV_TO_R4:
5005 v = LLVMBuildFPTrunc (builder, lhs, LLVMFloatType (), "");
5007 values [ins->dreg] = v;
5009 values [ins->dreg] = LLVMBuildFPExt (builder, v, LLVMDoubleType (), dname);
5011 case OP_RCONV_TO_R8:
5012 values [ins->dreg] = LLVMBuildFPExt (builder, lhs, LLVMDoubleType (), dname);
5014 case OP_RCONV_TO_R4:
5015 values [ins->dreg] = lhs;
5018 values [ins->dreg] = LLVMBuildSExt (builder, convert (ctx, lhs, LLVMInt32Type ()), LLVMInt64Type (), dname);
5021 values [ins->dreg] = LLVMBuildZExt (builder, convert (ctx, lhs, LLVMInt32Type ()), LLVMInt64Type (), dname);
5024 values [ins->dreg] = LLVMBuildTrunc (builder, lhs, LLVMInt32Type (), dname);
5026 case OP_LOCALLOC_IMM: {
5029 guint32 size = ins->inst_imm;
5030 size = (size + (MONO_ARCH_FRAME_ALIGNMENT - 1)) & ~ (MONO_ARCH_FRAME_ALIGNMENT - 1);
5032 v = mono_llvm_build_alloca (builder, LLVMInt8Type (), LLVMConstInt (LLVMInt32Type (), size, FALSE), MONO_ARCH_FRAME_ALIGNMENT, "");
5034 if (ins->flags & MONO_INST_INIT) {
5035 LLVMValueRef args [5];
5038 args [1] = LLVMConstInt (LLVMInt8Type (), 0, FALSE);
5039 args [2] = LLVMConstInt (LLVMInt32Type (), size, FALSE);
5040 args [3] = LLVMConstInt (LLVMInt32Type (), MONO_ARCH_FRAME_ALIGNMENT, FALSE);
5041 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
5042 LLVMBuildCall (builder, get_intrinsic (ctx, "llvm.memset.p0i8.i32"), args, 5, "");
5045 values [ins->dreg] = v;
5049 LLVMValueRef v, size;
5051 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), "");
5053 v = mono_llvm_build_alloca (builder, LLVMInt8Type (), size, MONO_ARCH_FRAME_ALIGNMENT, "");
5055 if (ins->flags & MONO_INST_INIT) {
5056 LLVMValueRef args [5];
5059 args [1] = LLVMConstInt (LLVMInt8Type (), 0, FALSE);
5061 args [3] = LLVMConstInt (LLVMInt32Type (), MONO_ARCH_FRAME_ALIGNMENT, FALSE);
5062 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
5063 LLVMBuildCall (builder, get_intrinsic (ctx, "llvm.memset.p0i8.i32"), args, 5, "");
5065 values [ins->dreg] = v;
5069 case OP_LOADI1_MEMBASE:
5070 case OP_LOADU1_MEMBASE:
5071 case OP_LOADI2_MEMBASE:
5072 case OP_LOADU2_MEMBASE:
5073 case OP_LOADI4_MEMBASE:
5074 case OP_LOADU4_MEMBASE:
5075 case OP_LOADI8_MEMBASE:
5076 case OP_LOADR4_MEMBASE:
5077 case OP_LOADR8_MEMBASE:
5078 case OP_LOAD_MEMBASE:
5086 LLVMValueRef base, index, addr;
5088 gboolean sext = FALSE, zext = FALSE;
5089 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
5091 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
5096 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)) {
5097 addr = LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE);
5102 if (ins->inst_offset == 0) {
5104 } else if (ins->inst_offset % size != 0) {
5105 /* Unaligned load */
5106 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset, FALSE);
5107 addr = LLVMBuildGEP (builder, convert (ctx, base, LLVMPointerType (LLVMInt8Type (), 0)), &index, 1, "");
5109 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
5110 addr = LLVMBuildGEP (builder, convert (ctx, base, LLVMPointerType (t, 0)), &index, 1, "");
5114 addr = convert (ctx, addr, LLVMPointerType (t, 0));
5116 values [ins->dreg] = emit_load (ctx, bb, &builder, size, addr, dname, is_volatile);
5118 if (!is_volatile && (ins->flags & MONO_INST_INVARIANT_LOAD)) {
5120 * These will signal LLVM that these loads do not alias any stores, and
5121 * they can't fail, allowing them to be hoisted out of loops.
5123 set_invariant_load_flag (values [ins->dreg]);
5124 #if LLVM_API_VERSION < 100
5125 set_metadata_flag (values [ins->dreg], "mono.nofail.load");
5130 values [ins->dreg] = LLVMBuildSExt (builder, values [ins->dreg], LLVMInt32Type (), dname);
5132 values [ins->dreg] = LLVMBuildZExt (builder, values [ins->dreg], LLVMInt32Type (), dname);
5133 else if (!cfg->r4fp && ins->opcode == OP_LOADR4_MEMBASE)
5134 values [ins->dreg] = LLVMBuildFPExt (builder, values [ins->dreg], LLVMDoubleType (), dname);
5138 case OP_STOREI1_MEMBASE_REG:
5139 case OP_STOREI2_MEMBASE_REG:
5140 case OP_STOREI4_MEMBASE_REG:
5141 case OP_STOREI8_MEMBASE_REG:
5142 case OP_STORER4_MEMBASE_REG:
5143 case OP_STORER8_MEMBASE_REG:
5144 case OP_STORE_MEMBASE_REG: {
5146 LLVMValueRef index, addr;
5148 gboolean sext = FALSE, zext = FALSE;
5149 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
5151 if (!values [ins->inst_destbasereg]) {
5152 set_failure (ctx, "inst_destbasereg");
5156 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
5158 if (ins->inst_offset % size != 0) {
5159 /* Unaligned store */
5160 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset, FALSE);
5161 addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (LLVMInt8Type (), 0)), &index, 1, "");
5163 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
5164 addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (t, 0)), &index, 1, "");
5166 emit_store (ctx, bb, &builder, size, convert (ctx, values [ins->sreg1], t), convert (ctx, addr, LLVMPointerType (t, 0)), is_volatile);
5170 case OP_STOREI1_MEMBASE_IMM:
5171 case OP_STOREI2_MEMBASE_IMM:
5172 case OP_STOREI4_MEMBASE_IMM:
5173 case OP_STOREI8_MEMBASE_IMM:
5174 case OP_STORE_MEMBASE_IMM: {
5176 LLVMValueRef index, addr;
5178 gboolean sext = FALSE, zext = FALSE;
5179 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
5181 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
5183 if (ins->inst_offset % size != 0) {
5184 /* Unaligned store */
5185 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset, FALSE);
5186 addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (LLVMInt8Type (), 0)), &index, 1, "");
5188 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
5189 addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (t, 0)), &index, 1, "");
5191 emit_store (ctx, bb, &builder, size, convert (ctx, LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE), t), convert (ctx, addr, LLVMPointerType (t, 0)), is_volatile);
5196 emit_load (ctx, bb, &builder, sizeof (gpointer), convert (ctx, lhs, LLVMPointerType (IntPtrType (), 0)), "", TRUE);
5198 case OP_OUTARG_VTRETADDR:
5206 case OP_VOIDCALL_MEMBASE:
5207 case OP_CALL_MEMBASE:
5208 case OP_LCALL_MEMBASE:
5209 case OP_FCALL_MEMBASE:
5210 case OP_RCALL_MEMBASE:
5211 case OP_VCALL_MEMBASE:
5212 case OP_VOIDCALL_REG:
5217 case OP_VCALL_REG: {
5218 process_call (ctx, bb, &builder, ins);
5223 LLVMValueRef indexes [2];
5224 MonoJumpInfo *tmp_ji, *ji;
5225 LLVMValueRef got_entry_addr;
5229 * FIXME: Can't allocate from the cfg mempool since that is freed if
5230 * the LLVM compile fails.
5232 tmp_ji = g_new0 (MonoJumpInfo, 1);
5233 tmp_ji->type = (MonoJumpInfoType)ins->inst_c1;
5234 tmp_ji->data.target = ins->inst_p0;
5236 ji = mono_aot_patch_info_dup (tmp_ji);
5239 ji->next = cfg->patch_info;
5240 cfg->patch_info = ji;
5242 //mono_add_patch_info (cfg, 0, (MonoJumpInfoType)ins->inst_i1, ins->inst_p0);
5243 got_offset = mono_aot_get_got_offset (cfg->patch_info);
5244 ctx->module->max_got_offset = MAX (ctx->module->max_got_offset, got_offset);
5245 if (!mono_aot_is_shared_got_offset (got_offset)) {
5246 //mono_print_ji (ji);
5248 ctx->has_got_access = TRUE;
5251 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
5252 indexes [1] = LLVMConstInt (LLVMInt32Type (), (gssize)got_offset, FALSE);
5253 got_entry_addr = LLVMBuildGEP (builder, ctx->module->got_var, indexes, 2, "");
5255 name = get_aotconst_name (ji->type, ji->data.target, got_offset);
5256 values [ins->dreg] = LLVMBuildLoad (builder, got_entry_addr, name);
5258 /* Can't use this in llvmonly mode since the got slots are initialized by the methods themselves */
5259 if (!cfg->llvm_only)
5260 set_invariant_load_flag (values [ins->dreg]);
5263 case OP_NOT_REACHED:
5264 LLVMBuildUnreachable (builder);
5265 has_terminator = TRUE;
5266 g_assert (bb->block_num < cfg->max_block_num);
5267 ctx->unreachable [bb->block_num] = TRUE;
5268 /* Might have instructions after this */
5270 MonoInst *next = ins->next;
5272 * FIXME: If later code uses the regs defined by these instructions,
5273 * compilation will fail.
5275 MONO_DELETE_INS (bb, next);
5279 MonoInst *var = ins->inst_i0;
5281 if (var->opcode == OP_VTARG_ADDR) {
5282 /* The variable contains the vtype address */
5283 values [ins->dreg] = values [var->dreg];
5284 } else if (var->opcode == OP_GSHAREDVT_LOCAL) {
5285 values [ins->dreg] = emit_gsharedvt_ldaddr (ctx, var->dreg);
5287 values [ins->dreg] = addresses [var->dreg];
5292 LLVMValueRef args [1];
5294 args [0] = convert (ctx, lhs, LLVMDoubleType ());
5295 values [ins->dreg] = LLVMBuildCall (builder, get_intrinsic (ctx, "llvm.sin.f64"), args, 1, dname);
5299 LLVMValueRef args [1];
5301 args [0] = convert (ctx, lhs, LLVMDoubleType ());
5302 values [ins->dreg] = LLVMBuildCall (builder, get_intrinsic (ctx, "llvm.cos.f64"), args, 1, dname);
5306 LLVMValueRef args [1];
5308 args [0] = convert (ctx, lhs, LLVMDoubleType ());
5309 values [ins->dreg] = LLVMBuildCall (builder, get_intrinsic (ctx, "llvm.sqrt.f64"), args, 1, dname);
5313 LLVMValueRef args [1];
5315 args [0] = convert (ctx, lhs, LLVMDoubleType ());
5316 values [ins->dreg] = LLVMBuildCall (builder, get_intrinsic (ctx, "fabs"), args, 1, dname);
5330 lhs = convert (ctx, lhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
5331 rhs = convert (ctx, rhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
5333 switch (ins->opcode) {
5336 v = LLVMBuildICmp (builder, LLVMIntSLE, lhs, rhs, "");
5340 v = LLVMBuildICmp (builder, LLVMIntSGE, lhs, rhs, "");
5344 v = LLVMBuildICmp (builder, LLVMIntULE, lhs, rhs, "");
5348 v = LLVMBuildICmp (builder, LLVMIntUGE, lhs, rhs, "");
5351 g_assert_not_reached ();
5354 values [ins->dreg] = LLVMBuildSelect (builder, v, lhs, rhs, dname);
5357 case OP_ATOMIC_EXCHANGE_I4:
5358 case OP_ATOMIC_EXCHANGE_I8: {
5359 LLVMValueRef args [2];
5362 if (ins->opcode == OP_ATOMIC_EXCHANGE_I4)
5363 t = LLVMInt32Type ();
5365 t = LLVMInt64Type ();
5367 g_assert (ins->inst_offset == 0);
5369 args [0] = convert (ctx, lhs, LLVMPointerType (t, 0));
5370 args [1] = convert (ctx, rhs, t);
5372 values [ins->dreg] = mono_llvm_build_atomic_rmw (builder, LLVM_ATOMICRMW_OP_XCHG, args [0], args [1]);
5375 case OP_ATOMIC_ADD_I4:
5376 case OP_ATOMIC_ADD_I8: {
5377 LLVMValueRef args [2];
5380 if (ins->opcode == OP_ATOMIC_ADD_I4)
5381 t = LLVMInt32Type ();
5383 t = LLVMInt64Type ();
5385 g_assert (ins->inst_offset == 0);
5387 args [0] = convert (ctx, lhs, LLVMPointerType (t, 0));
5388 args [1] = convert (ctx, rhs, t);
5389 values [ins->dreg] = LLVMBuildAdd (builder, mono_llvm_build_atomic_rmw (builder, LLVM_ATOMICRMW_OP_ADD, args [0], args [1]), args [1], dname);
5392 case OP_ATOMIC_CAS_I4:
5393 case OP_ATOMIC_CAS_I8: {
5394 LLVMValueRef args [3], val;
5397 if (ins->opcode == OP_ATOMIC_CAS_I4)
5398 t = LLVMInt32Type ();
5400 t = LLVMInt64Type ();
5402 args [0] = convert (ctx, lhs, LLVMPointerType (t, 0));
5404 args [1] = convert (ctx, values [ins->sreg3], t);
5406 args [2] = convert (ctx, values [ins->sreg2], t);
5407 val = mono_llvm_build_cmpxchg (builder, args [0], args [1], args [2]);
5408 /* cmpxchg returns a pair */
5409 values [ins->dreg] = LLVMBuildExtractValue (builder, val, 0, "");
5412 case OP_MEMORY_BARRIER: {
5413 mono_llvm_build_fence (builder, (BarrierKind) ins->backend.memory_barrier_kind);
5416 case OP_ATOMIC_LOAD_I1:
5417 case OP_ATOMIC_LOAD_I2:
5418 case OP_ATOMIC_LOAD_I4:
5419 case OP_ATOMIC_LOAD_I8:
5420 case OP_ATOMIC_LOAD_U1:
5421 case OP_ATOMIC_LOAD_U2:
5422 case OP_ATOMIC_LOAD_U4:
5423 case OP_ATOMIC_LOAD_U8:
5424 case OP_ATOMIC_LOAD_R4:
5425 case OP_ATOMIC_LOAD_R8: {
5426 set_failure (ctx, "atomic mono.load intrinsic");
5430 gboolean sext, zext;
5432 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
5433 BarrierKind barrier = (BarrierKind) ins->backend.memory_barrier_kind;
5434 LLVMValueRef index, addr;
5436 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
5441 if (ins->inst_offset != 0) {
5442 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
5443 addr = LLVMBuildGEP (builder, convert (ctx, lhs, LLVMPointerType (t, 0)), &index, 1, "");
5448 addr = convert (ctx, addr, LLVMPointerType (t, 0));
5450 values [ins->dreg] = emit_load_general (ctx, bb, &builder, size, addr, dname, is_volatile, barrier);
5453 values [ins->dreg] = LLVMBuildSExt (builder, values [ins->dreg], LLVMInt32Type (), dname);
5455 values [ins->dreg] = LLVMBuildZExt (builder, values [ins->dreg], LLVMInt32Type (), dname);
5459 case OP_ATOMIC_STORE_I1:
5460 case OP_ATOMIC_STORE_I2:
5461 case OP_ATOMIC_STORE_I4:
5462 case OP_ATOMIC_STORE_I8:
5463 case OP_ATOMIC_STORE_U1:
5464 case OP_ATOMIC_STORE_U2:
5465 case OP_ATOMIC_STORE_U4:
5466 case OP_ATOMIC_STORE_U8:
5467 case OP_ATOMIC_STORE_R4:
5468 case OP_ATOMIC_STORE_R8: {
5469 set_failure (ctx, "atomic mono.store intrinsic");
5473 gboolean sext, zext;
5475 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
5476 BarrierKind barrier = (BarrierKind) ins->backend.memory_barrier_kind;
5477 LLVMValueRef index, addr, value;
5479 if (!values [ins->inst_destbasereg]) {
5480 set_failure (ctx, "inst_destbasereg");
5484 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
5486 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
5487 addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (t, 0)), &index, 1, "");
5488 value = convert (ctx, values [ins->sreg1], t);
5490 emit_store_general (ctx, bb, &builder, size, value, addr, is_volatile, barrier);
5494 case OP_RELAXED_NOP: {
5495 #if defined(TARGET_AMD64) || defined(TARGET_X86)
5496 emit_call (ctx, bb, &builder, get_intrinsic (ctx, "llvm.x86.sse2.pause"), NULL, 0);
5503 #if (defined(TARGET_AMD64) || defined(TARGET_X86)) && defined(__linux__)
5505 // 257 == FS segment register
5506 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 257);
5508 // 256 == GS segment register
5509 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 256);
5512 values [ins->dreg] = LLVMBuildLoad (builder, LLVMBuildIntToPtr (builder, LLVMConstInt (IntPtrType (), ins->inst_offset, TRUE), ptrtype, ""), "");
5513 #elif defined(TARGET_AMD64) && defined(TARGET_OSX)
5514 /* See mono_amd64_emit_tls_get () */
5515 int offset = mono_amd64_get_tls_gs_offset () + (ins->inst_offset * 8);
5517 // 256 == GS segment register
5518 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 256);
5519 values [ins->dreg] = LLVMBuildLoad (builder, LLVMBuildIntToPtr (builder, LLVMConstInt (IntPtrType (), offset, TRUE), ptrtype, ""), "");
5521 set_failure (ctx, "opcode tls-get");
5527 case OP_TLS_GET_REG: {
5528 #if defined(TARGET_AMD64) && defined(TARGET_OSX)
5529 /* See emit_tls_get_reg () */
5530 // 256 == GS segment register
5531 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 256);
5532 values [ins->dreg] = LLVMBuildLoad (builder, LLVMBuildIntToPtr (builder, convert (ctx, lhs, LLVMInt32Type ()), ptrtype, ""), "");
5534 set_failure (ctx, "opcode tls-get");
5540 case OP_TLS_SET_REG: {
5541 #if defined(TARGET_AMD64) && defined(TARGET_OSX)
5542 /* See emit_tls_get_reg () */
5543 // 256 == GS segment register
5544 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 256);
5545 LLVMBuildStore (builder, convert (ctx, lhs, IntPtrType ()), LLVMBuildIntToPtr (builder, convert (ctx, rhs, LLVMInt32Type ()), ptrtype, ""));
5547 set_failure (ctx, "opcode tls-set-reg");
5557 case OP_IADD_OVF_UN:
5559 case OP_ISUB_OVF_UN:
5561 case OP_IMUL_OVF_UN:
5562 #if SIZEOF_VOID_P == 8
5564 case OP_LADD_OVF_UN:
5566 case OP_LSUB_OVF_UN:
5568 case OP_LMUL_OVF_UN:
5571 LLVMValueRef args [2], val, ovf, func;
5573 args [0] = convert (ctx, lhs, op_to_llvm_type (ins->opcode));
5574 args [1] = convert (ctx, rhs, op_to_llvm_type (ins->opcode));
5575 func = get_intrinsic (ctx, ovf_op_to_intrins (ins->opcode));
5577 val = LLVMBuildCall (builder, func, args, 2, "");
5578 values [ins->dreg] = LLVMBuildExtractValue (builder, val, 0, dname);
5579 ovf = LLVMBuildExtractValue (builder, val, 1, "");
5580 emit_cond_system_exception (ctx, bb, "OverflowException", ovf);
5583 builder = ctx->builder;
5589 * We currently model them using arrays. Promotion to local vregs is
5590 * disabled for them in mono_handle_global_vregs () in the LLVM case,
5591 * so we always have an entry in cfg->varinfo for them.
5592 * FIXME: Is this needed ?
5595 MonoClass *klass = ins->klass;
5596 LLVMValueRef args [5];
5600 set_failure (ctx, "!klass");
5604 if (!addresses [ins->dreg])
5605 addresses [ins->dreg] = build_alloca (ctx, &klass->byval_arg);
5606 args [0] = LLVMBuildBitCast (builder, addresses [ins->dreg], LLVMPointerType (LLVMInt8Type (), 0), "");
5607 args [1] = LLVMConstInt (LLVMInt8Type (), 0, FALSE);
5608 args [2] = LLVMConstInt (LLVMInt32Type (), mono_class_value_size (klass, NULL), FALSE);
5610 args [3] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
5611 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
5612 LLVMBuildCall (builder, get_intrinsic (ctx, "llvm.memset.p0i8.i32"), args, 5, "");
5615 case OP_DUMMY_VZERO:
5618 case OP_STOREV_MEMBASE:
5619 case OP_LOADV_MEMBASE:
5621 MonoClass *klass = ins->klass;
5622 LLVMValueRef src = NULL, dst, args [5];
5623 gboolean done = FALSE;
5627 set_failure (ctx, "!klass");
5631 if (mini_is_gsharedvt_klass (klass)) {
5633 set_failure (ctx, "gsharedvt");
5637 switch (ins->opcode) {
5638 case OP_STOREV_MEMBASE:
5639 if (cfg->gen_write_barriers && klass->has_references && ins->inst_destbasereg != cfg->frame_reg &&
5640 LLVMGetInstructionOpcode (values [ins->inst_destbasereg]) != LLVMAlloca) {
5641 /* Decomposed earlier */
5642 g_assert_not_reached ();
5645 if (!addresses [ins->sreg1]) {
5647 g_assert (values [ins->sreg1]);
5648 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));
5649 LLVMBuildStore (builder, values [ins->sreg1], dst);
5652 src = LLVMBuildBitCast (builder, addresses [ins->sreg1], LLVMPointerType (LLVMInt8Type (), 0), "");
5653 dst = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_destbasereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (LLVMInt8Type (), 0));
5656 case OP_LOADV_MEMBASE:
5657 if (!addresses [ins->dreg])
5658 addresses [ins->dreg] = build_alloca (ctx, &klass->byval_arg);
5659 src = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_basereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (LLVMInt8Type (), 0));
5660 dst = LLVMBuildBitCast (builder, addresses [ins->dreg], LLVMPointerType (LLVMInt8Type (), 0), "");
5663 if (!addresses [ins->sreg1])
5664 addresses [ins->sreg1] = build_alloca (ctx, &klass->byval_arg);
5665 if (!addresses [ins->dreg])
5666 addresses [ins->dreg] = build_alloca (ctx, &klass->byval_arg);
5667 src = LLVMBuildBitCast (builder, addresses [ins->sreg1], LLVMPointerType (LLVMInt8Type (), 0), "");
5668 dst = LLVMBuildBitCast (builder, addresses [ins->dreg], LLVMPointerType (LLVMInt8Type (), 0), "");
5671 g_assert_not_reached ();
5681 args [2] = LLVMConstInt (LLVMInt32Type (), mono_class_value_size (klass, NULL), FALSE);
5682 args [3] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
5684 args [3] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
5685 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
5686 LLVMBuildCall (builder, get_intrinsic (ctx, "llvm.memcpy.p0i8.p0i8.i32"), args, 5, "");
5689 case OP_LLVM_OUTARG_VT: {
5690 LLVMArgInfo *ainfo = (LLVMArgInfo*)ins->inst_p0;
5691 MonoType *t = mini_get_underlying_type (ins->inst_vtype);
5693 if (ainfo->storage == LLVMArgGsharedvtVariable) {
5694 MonoInst *var = get_vreg_to_inst (cfg, ins->sreg1);
5696 if (var && var->opcode == OP_GSHAREDVT_LOCAL) {
5697 addresses [ins->dreg] = convert (ctx, emit_gsharedvt_ldaddr (ctx, var->dreg), LLVMPointerType (IntPtrType (), 0));
5699 g_assert (addresses [ins->sreg1]);
5700 addresses [ins->dreg] = addresses [ins->sreg1];
5702 } else if (ainfo->storage == LLVMArgGsharedvtFixed) {
5703 if (!addresses [ins->sreg1]) {
5704 addresses [ins->sreg1] = build_alloca (ctx, t);
5705 g_assert (values [ins->sreg1]);
5707 LLVMBuildStore (builder, convert (ctx, values [ins->sreg1], LLVMGetElementType (LLVMTypeOf (addresses [ins->sreg1]))), addresses [ins->sreg1]);
5708 addresses [ins->dreg] = addresses [ins->sreg1];
5710 if (!addresses [ins->sreg1]) {
5711 addresses [ins->sreg1] = build_alloca (ctx, t);
5712 g_assert (values [ins->sreg1]);
5713 LLVMBuildStore (builder, convert (ctx, values [ins->sreg1], type_to_llvm_type (ctx, t)), addresses [ins->sreg1]);
5715 addresses [ins->dreg] = addresses [ins->sreg1];
5723 #if defined(TARGET_X86) || defined(TARGET_AMD64)
5725 values [ins->dreg] = LLVMConstNull (type_to_llvm_type (ctx, &ins->klass->byval_arg));
5728 case OP_LOADX_MEMBASE: {
5729 LLVMTypeRef t = type_to_llvm_type (ctx, &ins->klass->byval_arg);
5732 src = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_basereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (t, 0));
5733 values [ins->dreg] = mono_llvm_build_aligned_load (builder, src, "", FALSE, 1);
5736 case OP_STOREX_MEMBASE: {
5737 LLVMTypeRef t = LLVMTypeOf (values [ins->sreg1]);
5740 dest = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_destbasereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (t, 0));
5741 mono_llvm_build_aligned_store (builder, values [ins->sreg1], dest, FALSE, 1);
5748 values [ins->dreg] = LLVMBuildAdd (builder, lhs, rhs, "");
5752 values [ins->dreg] = LLVMBuildFAdd (builder, lhs, rhs, "");
5758 values [ins->dreg] = LLVMBuildSub (builder, lhs, rhs, "");
5762 values [ins->dreg] = LLVMBuildFSub (builder, lhs, rhs, "");
5766 values [ins->dreg] = LLVMBuildFMul (builder, lhs, rhs, "");
5770 values [ins->dreg] = LLVMBuildFDiv (builder, lhs, rhs, "");
5773 values [ins->dreg] = LLVMBuildAnd (builder, lhs, rhs, "");
5776 values [ins->dreg] = LLVMBuildOr (builder, lhs, rhs, "");
5779 values [ins->dreg] = LLVMBuildXor (builder, lhs, rhs, "");
5783 values [ins->dreg] = LLVMBuildMul (builder, lhs, rhs, "");
5794 LLVMValueRef v = NULL;
5796 switch (ins->opcode) {
5801 t = LLVMVectorType (LLVMInt32Type (), 4);
5802 rt = LLVMVectorType (LLVMFloatType (), 4);
5808 t = LLVMVectorType (LLVMInt64Type (), 2);
5809 rt = LLVMVectorType (LLVMDoubleType (), 2);
5812 t = LLVMInt32Type ();
5813 rt = LLVMInt32Type ();
5814 g_assert_not_reached ();
5817 lhs = LLVMBuildBitCast (builder, lhs, t, "");
5818 rhs = LLVMBuildBitCast (builder, rhs, t, "");
5819 switch (ins->opcode) {
5822 v = LLVMBuildAnd (builder, lhs, rhs, "");
5826 v = LLVMBuildOr (builder, lhs, rhs, "");
5830 v = LLVMBuildXor (builder, lhs, rhs, "");
5834 v = LLVMBuildAnd (builder, rhs, LLVMBuildNot (builder, lhs, ""), "");
5837 values [ins->dreg] = LLVMBuildBitCast (builder, v, rt, "");
5861 case OP_PADDB_SAT_UN:
5862 case OP_PADDW_SAT_UN:
5863 case OP_PSUBB_SAT_UN:
5864 case OP_PSUBW_SAT_UN:
5872 case OP_PMULW_HIGH_UN: {
5873 LLVMValueRef args [2];
5878 values [ins->dreg] = LLVMBuildCall (builder, get_intrinsic (ctx, simd_op_to_intrins (ins->opcode)), args, 2, dname);
5885 values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildICmp (builder, LLVMIntEQ, lhs, rhs, ""), LLVMTypeOf (lhs), "");
5889 values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildICmp (builder, LLVMIntSGT, lhs, rhs, ""), LLVMTypeOf (lhs), "");
5897 case OP_EXTRACTX_U2:
5899 case OP_EXTRACT_U1: {
5901 gboolean zext = FALSE;
5903 t = simd_op_to_llvm_type (ins->opcode);
5905 switch (ins->opcode) {
5913 case OP_EXTRACTX_U2:
5918 t = LLVMInt32Type ();
5919 g_assert_not_reached ();
5922 lhs = LLVMBuildBitCast (builder, lhs, t, "");
5923 values [ins->dreg] = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), "");
5925 values [ins->dreg] = LLVMBuildZExt (builder, values [ins->dreg], LLVMInt32Type (), "");
5934 case OP_EXPAND_R8: {
5935 LLVMTypeRef t = simd_op_to_llvm_type (ins->opcode);
5936 LLVMValueRef mask [16], v;
5939 for (i = 0; i < 16; ++i)
5940 mask [i] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
5942 v = convert (ctx, values [ins->sreg1], LLVMGetElementType (t));
5944 values [ins->dreg] = LLVMBuildInsertElement (builder, LLVMConstNull (t), v, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
5945 values [ins->dreg] = LLVMBuildShuffleVector (builder, values [ins->dreg], LLVMGetUndef (t), LLVMConstVector (mask, LLVMGetVectorSize (t)), "");
5950 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt8Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
5953 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt16Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
5956 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt32Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
5959 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt64Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
5962 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMFloatType ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
5965 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMDoubleType ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
5976 case OP_EXTRACT_MASK:
5983 v = convert (ctx, values [ins->sreg1], simd_op_to_llvm_type (ins->opcode));
5985 values [ins->dreg] = LLVMBuildCall (builder, get_intrinsic (ctx, simd_op_to_intrins (ins->opcode)), &v, 1, dname);
5991 LLVMValueRef args [3];
5995 args [2] = LLVMConstInt (LLVMInt8Type (), ins->inst_c0, FALSE);
5997 values [ins->dreg] = LLVMBuildCall (builder, get_intrinsic (ctx, simd_op_to_intrins (ins->opcode)), args, 3, dname);
6002 /* This is only used for implementing shifts by non-immediate */
6003 values [ins->dreg] = lhs;
6014 LLVMValueRef args [3];
6017 args [1] = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
6019 values [ins->dreg] = LLVMBuildCall (builder, get_intrinsic (ctx, simd_op_to_intrins (ins->opcode)), args, 2, dname);
6030 case OP_PSHLQ_REG: {
6031 LLVMValueRef args [3];
6034 args [1] = values [ins->sreg2];
6036 values [ins->dreg] = LLVMBuildCall (builder, get_intrinsic (ctx, simd_op_to_intrins (ins->opcode)), args, 2, dname);
6043 case OP_PSHUFLEW_LOW:
6044 case OP_PSHUFLEW_HIGH: {
6046 LLVMValueRef v1 = NULL, v2 = NULL, mask_values [16];
6047 int i, mask_size = 0;
6048 int imask = ins->inst_c0;
6050 /* Convert the x86 shuffle mask to LLVM's */
6051 switch (ins->opcode) {
6054 mask [0] = ((imask >> 0) & 3);
6055 mask [1] = ((imask >> 2) & 3);
6056 mask [2] = ((imask >> 4) & 3) + 4;
6057 mask [3] = ((imask >> 6) & 3) + 4;
6058 v1 = values [ins->sreg1];
6059 v2 = values [ins->sreg2];
6063 mask [0] = ((imask >> 0) & 1);
6064 mask [1] = ((imask >> 1) & 1) + 2;
6065 v1 = values [ins->sreg1];
6066 v2 = values [ins->sreg2];
6068 case OP_PSHUFLEW_LOW:
6070 mask [0] = ((imask >> 0) & 3);
6071 mask [1] = ((imask >> 2) & 3);
6072 mask [2] = ((imask >> 4) & 3);
6073 mask [3] = ((imask >> 6) & 3);
6078 v1 = values [ins->sreg1];
6079 v2 = LLVMGetUndef (LLVMTypeOf (v1));
6081 case OP_PSHUFLEW_HIGH:
6087 mask [4] = 4 + ((imask >> 0) & 3);
6088 mask [5] = 4 + ((imask >> 2) & 3);
6089 mask [6] = 4 + ((imask >> 4) & 3);
6090 mask [7] = 4 + ((imask >> 6) & 3);
6091 v1 = values [ins->sreg1];
6092 v2 = LLVMGetUndef (LLVMTypeOf (v1));
6096 mask [0] = ((imask >> 0) & 3);
6097 mask [1] = ((imask >> 2) & 3);
6098 mask [2] = ((imask >> 4) & 3);
6099 mask [3] = ((imask >> 6) & 3);
6100 v1 = values [ins->sreg1];
6101 v2 = LLVMGetUndef (LLVMTypeOf (v1));
6104 g_assert_not_reached ();
6106 for (i = 0; i < mask_size; ++i)
6107 mask_values [i] = LLVMConstInt (LLVMInt32Type (), mask [i], FALSE);
6109 values [ins->dreg] =
6110 LLVMBuildShuffleVector (builder, v1, v2,
6111 LLVMConstVector (mask_values, mask_size), dname);
6115 case OP_UNPACK_LOWB:
6116 case OP_UNPACK_LOWW:
6117 case OP_UNPACK_LOWD:
6118 case OP_UNPACK_LOWQ:
6119 case OP_UNPACK_LOWPS:
6120 case OP_UNPACK_LOWPD:
6121 case OP_UNPACK_HIGHB:
6122 case OP_UNPACK_HIGHW:
6123 case OP_UNPACK_HIGHD:
6124 case OP_UNPACK_HIGHQ:
6125 case OP_UNPACK_HIGHPS:
6126 case OP_UNPACK_HIGHPD: {
6128 LLVMValueRef mask_values [16];
6129 int i, mask_size = 0;
6130 gboolean low = FALSE;
6132 switch (ins->opcode) {
6133 case OP_UNPACK_LOWB:
6137 case OP_UNPACK_LOWW:
6141 case OP_UNPACK_LOWD:
6142 case OP_UNPACK_LOWPS:
6146 case OP_UNPACK_LOWQ:
6147 case OP_UNPACK_LOWPD:
6151 case OP_UNPACK_HIGHB:
6154 case OP_UNPACK_HIGHW:
6157 case OP_UNPACK_HIGHD:
6158 case OP_UNPACK_HIGHPS:
6161 case OP_UNPACK_HIGHQ:
6162 case OP_UNPACK_HIGHPD:
6166 g_assert_not_reached ();
6170 for (i = 0; i < (mask_size / 2); ++i) {
6172 mask [(i * 2) + 1] = mask_size + i;
6175 for (i = 0; i < (mask_size / 2); ++i) {
6176 mask [(i * 2)] = (mask_size / 2) + i;
6177 mask [(i * 2) + 1] = mask_size + (mask_size / 2) + i;
6181 for (i = 0; i < mask_size; ++i)
6182 mask_values [i] = LLVMConstInt (LLVMInt32Type (), mask [i], FALSE);
6184 values [ins->dreg] =
6185 LLVMBuildShuffleVector (builder, values [ins->sreg1], values [ins->sreg2],
6186 LLVMConstVector (mask_values, mask_size), dname);
6191 LLVMTypeRef t = simd_op_to_llvm_type (ins->opcode);
6192 LLVMValueRef v, val;
6194 v = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
6195 val = LLVMConstNull (t);
6196 val = LLVMBuildInsertElement (builder, val, v, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
6197 val = LLVMBuildInsertElement (builder, val, v, LLVMConstInt (LLVMInt32Type (), 1, FALSE), dname);
6199 values [ins->dreg] = val;
6203 case OP_DUPPS_HIGH: {
6204 LLVMTypeRef t = simd_op_to_llvm_type (ins->opcode);
6205 LLVMValueRef v1, v2, val;
6208 if (ins->opcode == OP_DUPPS_LOW) {
6209 v1 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
6210 v2 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 2, FALSE), "");
6212 v1 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 1, FALSE), "");
6213 v2 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 3, FALSE), "");
6215 val = LLVMConstNull (t);
6216 val = LLVMBuildInsertElement (builder, val, v1, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
6217 val = LLVMBuildInsertElement (builder, val, v1, LLVMConstInt (LLVMInt32Type (), 1, FALSE), "");
6218 val = LLVMBuildInsertElement (builder, val, v2, LLVMConstInt (LLVMInt32Type (), 2, FALSE), "");
6219 val = LLVMBuildInsertElement (builder, val, v2, LLVMConstInt (LLVMInt32Type (), 3, FALSE), "");
6221 values [ins->dreg] = val;
6231 * EXCEPTION HANDLING
6233 case OP_IMPLICIT_EXCEPTION:
6234 /* This marks a place where an implicit exception can happen */
6235 if (bb->region != -1)
6236 set_failure (ctx, "implicit-exception");
6240 gboolean rethrow = (ins->opcode == OP_RETHROW);
6241 if (ctx->llvm_only) {
6242 emit_llvmonly_throw (ctx, bb, rethrow, lhs);
6243 has_terminator = TRUE;
6244 ctx->unreachable [bb->block_num] = TRUE;
6246 emit_throw (ctx, bb, rethrow, lhs);
6247 builder = ctx->builder;
6251 case OP_CALL_HANDLER: {
6253 * We don't 'call' handlers, but instead simply branch to them.
6254 * The code generated by ENDFINALLY will branch back to us.
6256 LLVMBasicBlockRef noex_bb;
6258 BBInfo *info = &bblocks [ins->inst_target_bb->block_num];
6260 bb_list = info->call_handler_return_bbs;
6263 * Set the indicator variable for the finally clause.
6265 lhs = info->finally_ind;
6267 LLVMBuildStore (builder, LLVMConstInt (LLVMInt32Type (), g_slist_length (bb_list) + 1, FALSE), lhs);
6269 /* Branch to the finally clause */
6270 LLVMBuildBr (builder, info->call_handler_target_bb);
6272 noex_bb = gen_bb (ctx, "CALL_HANDLER_CONT_BB");
6273 info->call_handler_return_bbs = g_slist_append_mempool (cfg->mempool, info->call_handler_return_bbs, noex_bb);
6275 builder = ctx->builder = create_builder (ctx);
6276 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
6278 bblocks [bb->block_num].end_bblock = noex_bb;
6281 case OP_START_HANDLER: {
6284 case OP_ENDFINALLY: {
6285 LLVMBasicBlockRef resume_bb;
6286 MonoBasicBlock *handler_bb;
6287 LLVMValueRef val, switch_ins, callee;
6291 handler_bb = (MonoBasicBlock*)g_hash_table_lookup (ctx->region_to_handler, GUINT_TO_POINTER (mono_get_block_region_notry (cfg, bb->region)));
6292 g_assert (handler_bb);
6293 info = &bblocks [handler_bb->block_num];
6294 lhs = info->finally_ind;
6297 bb_list = info->call_handler_return_bbs;
6299 resume_bb = gen_bb (ctx, "ENDFINALLY_RESUME_BB");
6301 /* Load the finally variable */
6302 val = LLVMBuildLoad (builder, lhs, "");
6304 /* Reset the variable */
6305 LLVMBuildStore (builder, LLVMConstInt (LLVMInt32Type (), 0, FALSE), lhs);
6307 /* Branch to either resume_bb, or to the bblocks in bb_list */
6308 switch_ins = LLVMBuildSwitch (builder, val, resume_bb, g_slist_length (bb_list));
6310 * The other targets are added at the end to handle OP_CALL_HANDLER
6311 * opcodes processed later.
6313 info->endfinally_switch_ins_list = g_slist_append_mempool (cfg->mempool, info->endfinally_switch_ins_list, switch_ins);
6315 builder = ctx->builder = create_builder (ctx);
6316 LLVMPositionBuilderAtEnd (ctx->builder, resume_bb);
6318 if (ctx->llvm_only) {
6319 emit_resume_eh (ctx, bb);
6321 if (ctx->cfg->compile_aot) {
6322 callee = get_callee (ctx, LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE), MONO_PATCH_INFO_INTERNAL_METHOD, "llvm_resume_unwind_trampoline");
6324 #if LLVM_API_VERSION > 100
6325 MonoJitICallInfo *info;
6327 info = mono_find_jit_icall_by_name ("llvm_resume_unwind_trampoline");
6329 gpointer target = (void*)info->func;
6330 LLVMTypeRef icall_sig = LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE);
6331 callee = emit_jit_callee (ctx, "llvm_resume_unwind_trampoline", icall_sig, target);
6333 callee = LLVMGetNamedFunction (ctx->lmodule, "llvm_resume_unwind_trampoline");
6336 LLVMBuildCall (builder, callee, NULL, 0, "");
6337 LLVMBuildUnreachable (builder);
6340 has_terminator = TRUE;
6343 case OP_IL_SEQ_POINT:
6348 sprintf (reason, "opcode %s", mono_inst_name (ins->opcode));
6349 set_failure (ctx, reason);
6357 /* Convert the value to the type required by phi nodes */
6358 if (spec [MONO_INST_DEST] != ' ' && !MONO_IS_STORE_MEMBASE (ins) && ctx->vreg_types [ins->dreg]) {
6359 if (!values [ins->dreg])
6361 values [ins->dreg] = addresses [ins->dreg];
6363 values [ins->dreg] = convert (ctx, values [ins->dreg], ctx->vreg_types [ins->dreg]);
6366 /* Add stores for volatile variables */
6367 if (spec [MONO_INST_DEST] != ' ' && spec [MONO_INST_DEST] != 'v' && !MONO_IS_STORE_MEMBASE (ins))
6368 emit_volatile_store (ctx, ins->dreg);
6374 if (!has_terminator && bb->next_bb && (bb == cfg->bb_entry || bb->in_count > 0)) {
6375 LLVMBuildBr (builder, get_bb (ctx, bb->next_bb));
6378 if (bb == cfg->bb_exit && sig->ret->type == MONO_TYPE_VOID) {
6379 emit_dbg_loc (ctx, builder, cfg->header->code + cfg->header->code_size - 1);
6380 LLVMBuildRetVoid (builder);
6383 if (bb == cfg->bb_entry)
6384 ctx->last_alloca = LLVMGetLastInstruction (get_bb (ctx, cfg->bb_entry));
6388 * mono_llvm_check_method_supported:
6390 * Do some quick checks to decide whenever cfg->method can be compiled by LLVM, to avoid
6391 * compiling a method twice.
6394 mono_llvm_check_method_supported (MonoCompile *cfg)
6401 if (cfg->method->save_lmf) {
6402 cfg->exception_message = g_strdup ("lmf");
6403 cfg->disable_llvm = TRUE;
6405 if (cfg->disable_llvm)
6409 * Nested clauses where one of the clauses is a finally clause is
6410 * not supported, because LLVM can't figure out the control flow,
6411 * probably because we resume exception handling by calling our
6412 * own function instead of using the 'resume' llvm instruction.
6414 for (i = 0; i < cfg->header->num_clauses; ++i) {
6415 for (j = 0; j < cfg->header->num_clauses; ++j) {
6416 MonoExceptionClause *clause1 = &cfg->header->clauses [i];
6417 MonoExceptionClause *clause2 = &cfg->header->clauses [j];
6419 // FIXME: Nested try clauses fail in some cases too, i.e. #37273
6420 if (i != j && clause1->try_offset >= clause2->try_offset && clause1->handler_offset <= clause2->handler_offset) {
6421 //(clause1->flags == MONO_EXCEPTION_CLAUSE_FINALLY || clause2->flags == MONO_EXCEPTION_CLAUSE_FINALLY)) {
6422 cfg->exception_message = g_strdup ("nested clauses");
6423 cfg->disable_llvm = TRUE;
6428 if (cfg->disable_llvm)
6432 if (cfg->method->dynamic) {
6433 cfg->exception_message = g_strdup ("dynamic.");
6434 cfg->disable_llvm = TRUE;
6436 if (cfg->disable_llvm)
6440 static LLVMCallInfo*
6441 get_llvm_call_info (MonoCompile *cfg, MonoMethodSignature *sig)
6443 LLVMCallInfo *linfo;
6446 if (cfg->gsharedvt && cfg->llvm_only && mini_is_gsharedvt_variable_signature (sig)) {
6450 * Gsharedvt methods have the following calling convention:
6451 * - all arguments are passed by ref, even non generic ones
6452 * - the return value is returned by ref too, using a vret
6453 * argument passed after 'this'.
6455 n = sig->param_count + sig->hasthis;
6456 linfo = (LLVMCallInfo*)mono_mempool_alloc0 (cfg->mempool, sizeof (LLVMCallInfo) + (sizeof (LLVMArgInfo) * n));
6460 linfo->args [pindex ++].storage = LLVMArgNormal;
6462 if (sig->ret->type != MONO_TYPE_VOID) {
6463 if (mini_is_gsharedvt_variable_type (sig->ret))
6464 linfo->ret.storage = LLVMArgGsharedvtVariable;
6465 else if (mini_type_is_vtype (sig->ret))
6466 linfo->ret.storage = LLVMArgGsharedvtFixedVtype;
6468 linfo->ret.storage = LLVMArgGsharedvtFixed;
6469 linfo->vret_arg_index = pindex;
6471 linfo->ret.storage = LLVMArgNone;
6474 for (i = 0; i < sig->param_count; ++i) {
6475 if (sig->params [i]->byref)
6476 linfo->args [pindex].storage = LLVMArgNormal;
6477 else if (mini_is_gsharedvt_variable_type (sig->params [i]))
6478 linfo->args [pindex].storage = LLVMArgGsharedvtVariable;
6479 else if (mini_type_is_vtype (sig->params [i]))
6480 linfo->args [pindex].storage = LLVMArgGsharedvtFixedVtype;
6482 linfo->args [pindex].storage = LLVMArgGsharedvtFixed;
6483 linfo->args [pindex].type = sig->params [i];
6490 linfo = mono_arch_get_llvm_call_info (cfg, sig);
6491 for (i = 0; i < sig->param_count; ++i)
6492 linfo->args [i + sig->hasthis].type = sig->params [i];
6498 emit_method_inner (EmitContext *ctx);
6501 free_ctx (EmitContext *ctx)
6505 g_free (ctx->values);
6506 g_free (ctx->addresses);
6507 g_free (ctx->vreg_types);
6508 g_free (ctx->vreg_cli_types);
6509 g_free (ctx->is_dead);
6510 g_free (ctx->unreachable);
6511 g_ptr_array_free (ctx->phi_values, TRUE);
6512 g_free (ctx->bblocks);
6513 g_hash_table_destroy (ctx->region_to_handler);
6514 g_hash_table_destroy (ctx->clause_to_handler);
6515 g_hash_table_destroy (ctx->jit_callees);
6516 g_free (ctx->method_name);
6517 g_ptr_array_free (ctx->bblock_list, TRUE);
6519 for (l = ctx->builders; l; l = l->next) {
6520 LLVMBuilderRef builder = (LLVMBuilderRef)l->data;
6521 LLVMDisposeBuilder (builder);
6528 * mono_llvm_emit_method:
6530 * Emit LLVM IL from the mono IL, and compile it to native code using LLVM.
6533 mono_llvm_emit_method (MonoCompile *cfg)
6537 gboolean is_linkonce = FALSE;
6540 /* The code below might acquire the loader lock, so use it for global locking */
6541 mono_loader_lock ();
6543 /* Used to communicate with the callbacks */
6544 mono_native_tls_set_value (current_cfg_tls_id, cfg);
6546 ctx = g_new0 (EmitContext, 1);
6548 ctx->mempool = cfg->mempool;
6551 * This maps vregs to the LLVM instruction defining them
6553 ctx->values = g_new0 (LLVMValueRef, cfg->next_vreg);
6555 * This maps vregs for volatile variables to the LLVM instruction defining their
6558 ctx->addresses = g_new0 (LLVMValueRef, cfg->next_vreg);
6559 ctx->vreg_types = g_new0 (LLVMTypeRef, cfg->next_vreg);
6560 ctx->vreg_cli_types = g_new0 (MonoType*, cfg->next_vreg);
6561 ctx->phi_values = g_ptr_array_sized_new (256);
6563 * This signals whenever the vreg was defined by a phi node with no input vars
6564 * (i.e. all its input bblocks end with NOT_REACHABLE).
6566 ctx->is_dead = g_new0 (gboolean, cfg->next_vreg);
6567 /* Whenever the bblock is unreachable */
6568 ctx->unreachable = g_new0 (gboolean, cfg->max_block_num);
6569 ctx->bblock_list = g_ptr_array_sized_new (256);
6571 ctx->region_to_handler = g_hash_table_new (NULL, NULL);
6572 ctx->clause_to_handler = g_hash_table_new (NULL, NULL);
6573 ctx->method_to_callers = g_hash_table_new (NULL, NULL);
6574 ctx->jit_callees = g_hash_table_new (NULL, NULL);
6575 if (cfg->compile_aot) {
6576 ctx->module = &aot_module;
6580 * Allow the linker to discard duplicate copies of wrappers, generic instances etc. by using the 'linkonce'
6581 * linkage for them. This requires the following:
6582 * - the method needs to have a unique mangled name
6583 * - llvmonly mode, since the code in aot-runtime.c would initialize got slots in the wrong aot image etc.
6585 is_linkonce = ctx->module->llvm_only && ctx->module->static_link && mono_aot_is_linkonce_method (cfg->method);
6587 method_name = mono_aot_get_mangled_method_name (cfg->method);
6589 is_linkonce = FALSE;
6592 printf ("%s %s\n", mono_method_full_name (cfg->method, 1), method_name);
6594 printf ("%s\n", mono_method_full_name (cfg->method, 1));
6598 method_name = mono_aot_get_method_name (cfg);
6599 cfg->llvm_method_name = g_strdup (method_name);
6601 init_jit_module (cfg->domain);
6602 ctx->module = (MonoLLVMModule*)domain_jit_info (cfg->domain)->llvm_module;
6603 method_name = mono_method_full_name (cfg->method, TRUE);
6605 ctx->method_name = method_name;
6606 ctx->is_linkonce = is_linkonce;
6608 #if LLVM_API_VERSION > 100
6609 ctx->lmodule = LLVMModuleCreateWithName ("jit-module");
6611 ctx->lmodule = ctx->module->lmodule;
6613 ctx->llvm_only = ctx->module->llvm_only;
6615 emit_method_inner (ctx);
6617 if (!ctx_ok (ctx)) {
6619 /* Need to add unused phi nodes as they can be referenced by other values */
6620 LLVMBasicBlockRef phi_bb = LLVMAppendBasicBlock (ctx->lmethod, "PHI_BB");
6621 LLVMBuilderRef builder;
6623 builder = create_builder (ctx);
6624 LLVMPositionBuilderAtEnd (builder, phi_bb);
6626 for (i = 0; i < ctx->phi_values->len; ++i) {
6627 LLVMValueRef v = (LLVMValueRef)g_ptr_array_index (ctx->phi_values, i);
6628 if (LLVMGetInstructionParent (v) == NULL)
6629 LLVMInsertIntoBuilder (builder, v);
6632 LLVMDeleteFunction (ctx->lmethod);
6638 mono_native_tls_set_value (current_cfg_tls_id, NULL);
6640 mono_loader_unlock ();
6644 emit_method_inner (EmitContext *ctx)
6646 MonoCompile *cfg = ctx->cfg;
6647 MonoMethodSignature *sig;
6649 LLVMTypeRef method_type;
6650 LLVMValueRef method = NULL;
6651 LLVMValueRef *values = ctx->values;
6652 int i, max_block_num, bb_index;
6653 gboolean last = FALSE;
6654 LLVMCallInfo *linfo;
6655 LLVMModuleRef lmodule = ctx->lmodule;
6657 GPtrArray *bblock_list = ctx->bblock_list;
6658 MonoMethodHeader *header;
6659 MonoExceptionClause *clause;
6662 if (cfg->gsharedvt && !cfg->llvm_only) {
6663 set_failure (ctx, "gsharedvt");
6669 static int count = 0;
6672 if (g_getenv ("LLVM_COUNT")) {
6673 if (count == atoi (g_getenv ("LLVM_COUNT"))) {
6674 printf ("LAST: %s\n", mono_method_full_name (cfg->method, TRUE));
6678 if (count > atoi (g_getenv ("LLVM_COUNT"))) {
6679 set_failure (ctx, "count");
6686 sig = mono_method_signature (cfg->method);
6689 linfo = get_llvm_call_info (cfg, sig);
6695 linfo->rgctx_arg = TRUE;
6696 ctx->method_type = method_type = sig_to_llvm_sig_full (ctx, sig, linfo);
6700 method = LLVMAddFunction (lmodule, ctx->method_name, method_type);
6701 ctx->lmethod = method;
6703 if (!cfg->llvm_only)
6704 LLVMSetFunctionCallConv (method, LLVMMono1CallConv);
6705 LLVMSetLinkage (method, LLVMPrivateLinkage);
6707 LLVMAddFunctionAttr (method, LLVMUWTable);
6709 if (cfg->compile_aot) {
6710 LLVMSetLinkage (method, LLVMInternalLinkage);
6711 if (ctx->module->external_symbols) {
6712 LLVMSetLinkage (method, LLVMExternalLinkage);
6713 LLVMSetVisibility (method, LLVMHiddenVisibility);
6715 if (ctx->is_linkonce) {
6716 LLVMSetLinkage (method, LLVMLinkOnceAnyLinkage);
6717 LLVMSetVisibility (method, LLVMDefaultVisibility);
6720 #if LLVM_API_VERSION > 100
6721 LLVMSetLinkage (method, LLVMExternalLinkage);
6723 LLVMSetLinkage (method, LLVMPrivateLinkage);
6727 if (cfg->method->save_lmf && !cfg->llvm_only) {
6728 set_failure (ctx, "lmf");
6732 if (sig->pinvoke && cfg->method->wrapper_type != MONO_WRAPPER_RUNTIME_INVOKE && !cfg->llvm_only) {
6733 set_failure (ctx, "pinvoke signature");
6737 header = cfg->header;
6738 for (i = 0; i < header->num_clauses; ++i) {
6739 clause = &header->clauses [i];
6740 if (clause->flags != MONO_EXCEPTION_CLAUSE_FINALLY && clause->flags != MONO_EXCEPTION_CLAUSE_NONE) {
6741 set_failure (ctx, "non-finally/catch clause.");
6745 if (header->num_clauses || (cfg->method->iflags & METHOD_IMPL_ATTRIBUTE_NOINLINING) || cfg->no_inline)
6746 /* We can't handle inlined methods with clauses */
6747 LLVMAddFunctionAttr (method, LLVMNoInlineAttribute);
6749 if (linfo->rgctx_arg) {
6750 ctx->rgctx_arg = LLVMGetParam (method, linfo->rgctx_arg_pindex);
6751 ctx->rgctx_arg_pindex = linfo->rgctx_arg_pindex;
6753 * We mark the rgctx parameter with the inreg attribute, which is mapped to
6754 * MONO_ARCH_RGCTX_REG in the Mono calling convention in llvm, i.e.
6755 * CC_X86_64_Mono in X86CallingConv.td.
6757 if (!ctx->llvm_only)
6758 LLVMAddAttribute (ctx->rgctx_arg, LLVMInRegAttribute);
6759 LLVMSetValueName (ctx->rgctx_arg, "rgctx");
6761 ctx->rgctx_arg_pindex = -1;
6763 if (cfg->vret_addr) {
6764 values [cfg->vret_addr->dreg] = LLVMGetParam (method, linfo->vret_arg_pindex);
6765 LLVMSetValueName (values [cfg->vret_addr->dreg], "vret");
6766 if (linfo->ret.storage == LLVMArgVtypeByRef) {
6767 LLVMAddAttribute (LLVMGetParam (method, linfo->vret_arg_pindex), LLVMStructRetAttribute);
6768 LLVMAddAttribute (LLVMGetParam (method, linfo->vret_arg_pindex), LLVMNoAliasAttribute);
6773 ctx->this_arg_pindex = linfo->this_arg_pindex;
6774 ctx->this_arg = LLVMGetParam (method, linfo->this_arg_pindex);
6775 values [cfg->args [0]->dreg] = ctx->this_arg;
6776 LLVMSetValueName (values [cfg->args [0]->dreg], "this");
6779 names = g_new (char *, sig->param_count);
6780 mono_method_get_param_names (cfg->method, (const char **) names);
6782 for (i = 0; i < sig->param_count; ++i) {
6783 LLVMArgInfo *ainfo = &linfo->args [i + sig->hasthis];
6785 int pindex = ainfo->pindex + ainfo->ndummy_fpargs;
6788 for (j = 0; j < ainfo->ndummy_fpargs; ++j) {
6789 name = g_strdup_printf ("dummy_%d_%d", i, j);
6790 LLVMSetValueName (LLVMGetParam (method, ainfo->pindex + j), name);
6794 values [cfg->args [i + sig->hasthis]->dreg] = LLVMGetParam (method, pindex);
6795 if (ainfo->storage == LLVMArgGsharedvtFixed || ainfo->storage == LLVMArgGsharedvtFixedVtype) {
6796 if (names [i] && names [i][0] != '\0')
6797 name = g_strdup_printf ("p_arg_%s", names [i]);
6799 name = g_strdup_printf ("p_arg_%d", i);
6801 if (names [i] && names [i][0] != '\0')
6802 name = g_strdup_printf ("arg_%s", names [i]);
6804 name = g_strdup_printf ("arg_%d", i);
6806 LLVMSetValueName (values [cfg->args [i + sig->hasthis]->dreg], name);
6808 if (ainfo->storage == LLVMArgVtypeByVal)
6809 LLVMAddAttribute (LLVMGetParam (method, pindex), LLVMByValAttribute);
6811 if (ainfo->storage == LLVMArgVtypeByRef) {
6813 cfg->args [i + sig->hasthis]->opcode = OP_VTARG_ADDR;
6818 if (ctx->module->emit_dwarf && cfg->compile_aot && mono_debug_enabled ()) {
6819 ctx->minfo = mono_debug_lookup_method (cfg->method);
6820 ctx->dbg_md = emit_dbg_subprogram (ctx, cfg, method, ctx->method_name);
6824 for (bb = cfg->bb_entry; bb; bb = bb->next_bb)
6825 max_block_num = MAX (max_block_num, bb->block_num);
6826 ctx->bblocks = bblocks = g_new0 (BBInfo, max_block_num + 1);
6828 /* Add branches between non-consecutive bblocks */
6829 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
6830 if (bb->last_ins && MONO_IS_COND_BRANCH_OP (bb->last_ins) &&
6831 bb->next_bb != bb->last_ins->inst_false_bb) {
6833 MonoInst *inst = (MonoInst*)mono_mempool_alloc0 (cfg->mempool, sizeof (MonoInst));
6834 inst->opcode = OP_BR;
6835 inst->inst_target_bb = bb->last_ins->inst_false_bb;
6836 mono_bblock_add_inst (bb, inst);
6841 * The INDIRECT flag added by OP_LDADDR inhibits optimizations, even if the LDADDR
6842 * was later optimized away, so clear these flags, and add them back for the still
6843 * present OP_LDADDR instructions.
6845 for (i = 0; i < cfg->next_vreg; ++i) {
6848 ins = get_vreg_to_inst (cfg, i);
6849 if (ins && ins != cfg->rgctx_var)
6850 ins->flags &= ~MONO_INST_INDIRECT;
6854 * Make a first pass over the code to precreate PHI nodes/set INDIRECT flags.
6856 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
6858 LLVMBuilderRef builder;
6860 char dname_buf[128];
6862 builder = create_builder (ctx);
6864 for (ins = bb->code; ins; ins = ins->next) {
6865 switch (ins->opcode) {
6870 LLVMTypeRef phi_type = llvm_type_to_stack_type (cfg, type_to_llvm_type (ctx, &ins->klass->byval_arg));
6875 if (ins->opcode == OP_VPHI) {
6876 /* Treat valuetype PHI nodes as operating on the address itself */
6877 g_assert (ins->klass);
6878 phi_type = LLVMPointerType (type_to_llvm_type (ctx, &ins->klass->byval_arg), 0);
6882 * Have to precreate these, as they can be referenced by
6883 * earlier instructions.
6885 sprintf (dname_buf, "t%d", ins->dreg);
6887 values [ins->dreg] = LLVMBuildPhi (builder, phi_type, dname);
6889 if (ins->opcode == OP_VPHI)
6890 ctx->addresses [ins->dreg] = values [ins->dreg];
6892 g_ptr_array_add (ctx->phi_values, values [ins->dreg]);
6895 * Set the expected type of the incoming arguments since these have
6896 * to have the same type.
6898 for (i = 0; i < ins->inst_phi_args [0]; i++) {
6899 int sreg1 = ins->inst_phi_args [i + 1];
6902 ctx->vreg_types [sreg1] = phi_type;
6907 ((MonoInst*)ins->inst_p0)->flags |= MONO_INST_INDIRECT;
6916 * Create an ordering for bblocks, use the depth first order first, then
6917 * put the exception handling bblocks last.
6919 for (bb_index = 0; bb_index < cfg->num_bblocks; ++bb_index) {
6920 bb = cfg->bblocks [bb_index];
6921 if (!(bb->region != -1 && !MONO_BBLOCK_IS_IN_REGION (bb, MONO_REGION_TRY))) {
6922 g_ptr_array_add (bblock_list, bb);
6923 bblocks [bb->block_num].added = TRUE;
6927 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
6928 if (!bblocks [bb->block_num].added)
6929 g_ptr_array_add (bblock_list, bb);
6933 * Second pass: generate code.
6936 LLVMBuilderRef entry_builder = create_builder (ctx);
6937 LLVMBasicBlockRef entry_bb = get_bb (ctx, cfg->bb_entry);
6938 LLVMPositionBuilderAtEnd (entry_builder, entry_bb);
6939 emit_entry_bb (ctx, entry_builder);
6941 // Make landing pads first
6942 ctx->exc_meta = g_hash_table_new_full (NULL, NULL, NULL, NULL);
6944 if (ctx->llvm_only) {
6945 size_t group_index = 0;
6946 while (group_index < cfg->header->num_clauses) {
6948 size_t cursor = group_index;
6949 while (cursor < cfg->header->num_clauses &&
6950 CLAUSE_START (&cfg->header->clauses [cursor]) == CLAUSE_START (&cfg->header->clauses [group_index]) &&
6951 CLAUSE_END (&cfg->header->clauses [cursor]) == CLAUSE_END (&cfg->header->clauses [group_index])) {
6956 LLVMBasicBlockRef lpad_bb = emit_landing_pad (ctx, group_index, count);
6957 intptr_t key = CLAUSE_END (&cfg->header->clauses [group_index]);
6958 g_hash_table_insert (ctx->exc_meta, (gpointer)key, lpad_bb);
6960 group_index = cursor;
6964 for (bb_index = 0; bb_index < bblock_list->len; ++bb_index) {
6965 bb = (MonoBasicBlock*)g_ptr_array_index (bblock_list, bb_index);
6967 // Prune unreachable mono BBs.
6968 if (!(bb == cfg->bb_entry || bb->in_count > 0))
6971 process_bb (ctx, bb);
6975 g_hash_table_destroy (ctx->exc_meta);
6977 mono_memory_barrier ();
6979 /* Add incoming phi values */
6980 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
6981 GSList *l, *ins_list;
6983 ins_list = bblocks [bb->block_num].phi_nodes;
6985 for (l = ins_list; l; l = l->next) {
6986 PhiNode *node = (PhiNode*)l->data;
6987 MonoInst *phi = node->phi;
6988 int sreg1 = node->sreg;
6989 LLVMBasicBlockRef in_bb;
6994 in_bb = get_end_bb (ctx, node->in_bb);
6996 if (ctx->unreachable [node->in_bb->block_num])
6999 if (!values [sreg1]) {
7000 /* Can happen with values in EH clauses */
7001 set_failure (ctx, "incoming phi sreg1");
7005 if (phi->opcode == OP_VPHI) {
7006 g_assert (LLVMTypeOf (ctx->addresses [sreg1]) == LLVMTypeOf (values [phi->dreg]));
7007 LLVMAddIncoming (values [phi->dreg], &ctx->addresses [sreg1], &in_bb, 1);
7009 if (LLVMTypeOf (values [sreg1]) != LLVMTypeOf (values [phi->dreg])) {
7010 set_failure (ctx, "incoming phi arg type mismatch");
7013 g_assert (LLVMTypeOf (values [sreg1]) == LLVMTypeOf (values [phi->dreg]));
7014 LLVMAddIncoming (values [phi->dreg], &values [sreg1], &in_bb, 1);
7019 /* Nullify empty phi instructions */
7020 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
7021 GSList *l, *ins_list;
7023 ins_list = bblocks [bb->block_num].phi_nodes;
7025 for (l = ins_list; l; l = l->next) {
7026 PhiNode *node = (PhiNode*)l->data;
7027 MonoInst *phi = node->phi;
7028 LLVMValueRef phi_ins = values [phi->dreg];
7031 /* Already removed */
7034 if (LLVMCountIncoming (phi_ins) == 0) {
7035 mono_llvm_replace_uses_of (phi_ins, LLVMConstNull (LLVMTypeOf (phi_ins)));
7036 LLVMInstructionEraseFromParent (phi_ins);
7037 values [phi->dreg] = NULL;
7042 /* Create the SWITCH statements for ENDFINALLY instructions */
7043 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
7044 BBInfo *info = &bblocks [bb->block_num];
7046 for (l = info->endfinally_switch_ins_list; l; l = l->next) {
7047 LLVMValueRef switch_ins = (LLVMValueRef)l->data;
7048 GSList *bb_list = info->call_handler_return_bbs;
7050 for (i = 0; i < g_slist_length (bb_list); ++i)
7051 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), i + 1, FALSE), (LLVMBasicBlockRef)(g_slist_nth (bb_list, i)->data));
7055 /* Initialize the method if needed */
7056 if (cfg->compile_aot && ctx->llvm_only) {
7057 // FIXME: Add more shared got entries
7058 ctx->builder = create_builder (ctx);
7059 LLVMPositionBuilderAtEnd (ctx->builder, ctx->init_bb);
7061 ctx->module->max_method_idx = MAX (ctx->module->max_method_idx, cfg->method_index);
7063 // FIXME: beforefieldinit
7064 if (ctx->has_got_access || mono_class_get_cctor (cfg->method->klass)) {
7065 emit_init_method (ctx);
7067 LLVMBuildBr (ctx->builder, ctx->inited_bb);
7071 if (cfg->llvm_only) {
7072 GHashTableIter iter;
7074 GSList *callers, *l, *l2;
7077 * Add the contents of ctx->method_to_callers to module->method_to_callers.
7078 * We can't do this earlier, as it contains llvm instructions which can be
7079 * freed if compilation fails.
7080 * FIXME: Get rid of this when all methods can be llvm compiled.
7082 g_hash_table_iter_init (&iter, ctx->method_to_callers);
7083 while (g_hash_table_iter_next (&iter, (void**)&method, (void**)&callers)) {
7084 for (l = callers; l; l = l->next) {
7085 l2 = (GSList*)g_hash_table_lookup (ctx->module->method_to_callers, method);
7086 l2 = g_slist_prepend (l2, l->data);
7087 g_hash_table_insert (ctx->module->method_to_callers, method, l2);
7092 if (cfg->verbose_level > 1)
7093 mono_llvm_dump_value (method);
7095 if (cfg->compile_aot && !cfg->llvm_only)
7096 mark_as_used (ctx->module, method);
7098 if (cfg->compile_aot && !cfg->llvm_only) {
7099 LLVMValueRef md_args [16];
7100 LLVMValueRef md_node;
7103 method_index = mono_aot_get_method_index (cfg->orig_method);
7104 md_args [0] = LLVMMDString (ctx->method_name, strlen (ctx->method_name));
7105 md_args [1] = LLVMConstInt (LLVMInt32Type (), method_index, FALSE);
7106 md_node = LLVMMDNode (md_args, 2);
7107 LLVMAddNamedMetadataOperand (lmodule, "mono.function_indexes", md_node);
7108 //LLVMSetMetadata (method, md_kind, LLVMMDNode (&md_arg, 1));
7111 if (cfg->compile_aot) {
7112 /* Don't generate native code, keep the LLVM IR */
7113 if (cfg->verbose_level)
7114 printf ("%s emitted as %s\n", mono_method_full_name (cfg->method, TRUE), ctx->method_name);
7116 #if LLVM_API_VERSION < 100
7117 /* VerifyFunction can't handle some of the debug info created by DIBuilder in llvm 3.9 */
7118 int err = LLVMVerifyFunction(ctx->lmethod, LLVMPrintMessageAction);
7119 g_assert (err == 0);
7122 //LLVMVerifyFunction(method, 0);
7123 #if LLVM_API_VERSION > 100
7124 MonoDomain *domain = mono_domain_get ();
7125 MonoJitDomainInfo *domain_info;
7126 int nvars = g_hash_table_size (ctx->jit_callees);
7127 LLVMValueRef *callee_vars = g_new0 (LLVMValueRef, nvars);
7128 gpointer *callee_addrs = g_new0 (gpointer, nvars);
7129 GHashTableIter iter;
7135 * Compute the addresses of the LLVM globals pointing to the
7136 * methods called by the current method. Pass it to the trampoline
7137 * code so it can update them after their corresponding method was
7140 g_hash_table_iter_init (&iter, ctx->jit_callees);
7142 while (g_hash_table_iter_next (&iter, NULL, (void**)&var))
7143 callee_vars [i ++] = var;
7145 cfg->native_code = mono_llvm_compile_method (ctx->module->mono_ee, ctx->lmethod, nvars, callee_vars, callee_addrs, &eh_frame);
7147 decode_llvm_eh_info (ctx, eh_frame);
7149 mono_domain_lock (domain);
7150 domain_info = domain_jit_info (domain);
7151 if (!domain_info->llvm_jit_callees)
7152 domain_info->llvm_jit_callees = g_hash_table_new (NULL, NULL);
7153 g_hash_table_iter_init (&iter, ctx->jit_callees);
7155 while (g_hash_table_iter_next (&iter, (void**)&callee, (void**)&var)) {
7156 GSList *addrs = g_hash_table_lookup (domain_info->llvm_jit_callees, callee);
7157 addrs = g_slist_prepend (addrs, callee_addrs [i]);
7158 g_hash_table_insert (domain_info->llvm_jit_callees, callee, addrs);
7161 mono_domain_unlock (domain);
7163 mono_llvm_optimize_method (ctx->module->mono_ee, ctx->lmethod);
7165 if (cfg->verbose_level > 1)
7166 mono_llvm_dump_value (ctx->lmethod);
7168 cfg->native_code = (unsigned char*)LLVMGetPointerToGlobal (ctx->module->ee, ctx->lmethod);
7170 /* Set by emit_cb */
7171 g_assert (cfg->code_len);
7175 if (ctx->module->method_to_lmethod)
7176 g_hash_table_insert (ctx->module->method_to_lmethod, cfg->method, ctx->lmethod);
7177 if (ctx->module->idx_to_lmethod)
7178 g_hash_table_insert (ctx->module->idx_to_lmethod, GINT_TO_POINTER (cfg->method_index), ctx->lmethod);
7180 if (ctx->llvm_only && cfg->orig_method->klass->valuetype && !(cfg->orig_method->flags & METHOD_ATTRIBUTE_STATIC))
7181 emit_unbox_tramp (ctx, ctx->method_name, ctx->method_type, ctx->lmethod, cfg->method_index);
7185 * mono_llvm_create_vars:
7187 * Same as mono_arch_create_vars () for LLVM.
7190 mono_llvm_create_vars (MonoCompile *cfg)
7192 MonoMethodSignature *sig;
7194 sig = mono_method_signature (cfg->method);
7195 if (cfg->gsharedvt && cfg->llvm_only) {
7196 if (mini_is_gsharedvt_variable_signature (sig) && sig->ret->type != MONO_TYPE_VOID) {
7197 cfg->vret_addr = mono_compile_create_var (cfg, &mono_get_intptr_class ()->byval_arg, OP_ARG);
7198 if (G_UNLIKELY (cfg->verbose_level > 1)) {
7199 printf ("vret_addr = ");
7200 mono_print_ins (cfg->vret_addr);
7204 mono_arch_create_vars (cfg);
7209 * mono_llvm_emit_call:
7211 * Same as mono_arch_emit_call () for LLVM.
7214 mono_llvm_emit_call (MonoCompile *cfg, MonoCallInst *call)
7217 MonoMethodSignature *sig;
7218 int i, n, stack_size;
7223 sig = call->signature;
7224 n = sig->param_count + sig->hasthis;
7226 call->cinfo = get_llvm_call_info (cfg, sig);
7228 if (cfg->disable_llvm)
7231 if (sig->call_convention == MONO_CALL_VARARG) {
7232 cfg->exception_message = g_strdup ("varargs");
7233 cfg->disable_llvm = TRUE;
7236 for (i = 0; i < n; ++i) {
7239 ainfo = call->cinfo->args + i;
7241 in = call->args [i];
7243 /* Simply remember the arguments */
7244 switch (ainfo->storage) {
7245 case LLVMArgNormal: {
7246 MonoType *t = (sig->hasthis && i == 0) ? &mono_get_intptr_class ()->byval_arg : ainfo->type;
7249 opcode = mono_type_to_regmove (cfg, t);
7250 if (opcode == OP_FMOVE) {
7251 MONO_INST_NEW (cfg, ins, OP_FMOVE);
7252 ins->dreg = mono_alloc_freg (cfg);
7253 } else if (opcode == OP_LMOVE) {
7254 MONO_INST_NEW (cfg, ins, OP_LMOVE);
7255 ins->dreg = mono_alloc_lreg (cfg);
7256 } else if (opcode == OP_RMOVE) {
7257 MONO_INST_NEW (cfg, ins, OP_RMOVE);
7258 ins->dreg = mono_alloc_freg (cfg);
7260 MONO_INST_NEW (cfg, ins, OP_MOVE);
7261 ins->dreg = mono_alloc_ireg (cfg);
7263 ins->sreg1 = in->dreg;
7266 case LLVMArgVtypeByVal:
7267 case LLVMArgVtypeByRef:
7268 case LLVMArgVtypeInReg:
7269 case LLVMArgVtypeAsScalar:
7270 case LLVMArgAsIArgs:
7271 case LLVMArgAsFpArgs:
7272 case LLVMArgGsharedvtVariable:
7273 case LLVMArgGsharedvtFixed:
7274 case LLVMArgGsharedvtFixedVtype:
7275 MONO_INST_NEW (cfg, ins, OP_LLVM_OUTARG_VT);
7276 ins->dreg = mono_alloc_ireg (cfg);
7277 ins->sreg1 = in->dreg;
7278 ins->inst_p0 = mono_mempool_alloc0 (cfg->mempool, sizeof (LLVMArgInfo));
7279 memcpy (ins->inst_p0, ainfo, sizeof (LLVMArgInfo));
7280 ins->inst_vtype = ainfo->type;
7281 ins->klass = mono_class_from_mono_type (ainfo->type);
7284 cfg->exception_message = g_strdup ("ainfo->storage");
7285 cfg->disable_llvm = TRUE;
7289 if (!cfg->disable_llvm) {
7290 MONO_ADD_INS (cfg->cbb, ins);
7291 mono_call_inst_add_outarg_reg (cfg, call, ins->dreg, 0, FALSE);
7296 static unsigned char*
7297 alloc_cb (LLVMValueRef function, int size)
7301 cfg = (MonoCompile*)mono_native_tls_get_value (current_cfg_tls_id);
7305 return (unsigned char*)mono_domain_code_reserve (cfg->domain, size);
7307 return (unsigned char*)mono_domain_code_reserve (mono_domain_get (), size);
7312 emitted_cb (LLVMValueRef function, void *start, void *end)
7316 cfg = (MonoCompile*)mono_native_tls_get_value (current_cfg_tls_id);
7318 cfg->code_len = (guint8*)end - (guint8*)start;
7322 exception_cb (void *data)
7325 MonoJitExceptionInfo *ei;
7326 guint32 ei_len, i, j, nested_len, nindex;
7327 gpointer *type_info;
7328 int this_reg, this_offset;
7330 cfg = (MonoCompile*)mono_native_tls_get_value (current_cfg_tls_id);
7334 * data points to a DWARF FDE structure, convert it to our unwind format and
7336 * An alternative would be to save it directly, and modify our unwinder to work
7339 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);
7340 if (cfg->verbose_level > 1)
7341 mono_print_unwind_info (cfg->encoded_unwind_ops, cfg->encoded_unwind_ops_len);
7343 /* Count nested clauses */
7345 for (i = 0; i < ei_len; ++i) {
7346 gint32 cindex1 = *(gint32*)type_info [i];
7347 MonoExceptionClause *clause1 = &cfg->header->clauses [cindex1];
7349 for (j = 0; j < cfg->header->num_clauses; ++j) {
7351 MonoExceptionClause *clause2 = &cfg->header->clauses [cindex2];
7353 if (cindex1 != cindex2 && clause1->try_offset >= clause2->try_offset && clause1->handler_offset <= clause2->handler_offset) {
7359 cfg->llvm_ex_info = (MonoJitExceptionInfo*)mono_mempool_alloc0 (cfg->mempool, (ei_len + nested_len) * sizeof (MonoJitExceptionInfo));
7360 cfg->llvm_ex_info_len = ei_len + nested_len;
7361 memcpy (cfg->llvm_ex_info, ei, ei_len * sizeof (MonoJitExceptionInfo));
7362 /* Fill the rest of the information from the type info */
7363 for (i = 0; i < ei_len; ++i) {
7364 gint32 clause_index = *(gint32*)type_info [i];
7365 MonoExceptionClause *clause = &cfg->header->clauses [clause_index];
7367 cfg->llvm_ex_info [i].flags = clause->flags;
7368 cfg->llvm_ex_info [i].data.catch_class = clause->data.catch_class;
7369 cfg->llvm_ex_info [i].clause_index = clause_index;
7373 * For nested clauses, the LLVM produced exception info associates the try interval with
7374 * the innermost handler, while mono expects it to be associated with all nesting clauses.
7375 * So add new clauses which use the IL info (catch class etc.) from the nesting clause,
7376 * and everything else from the nested clause.
7379 for (i = 0; i < ei_len; ++i) {
7380 gint32 cindex1 = *(gint32*)type_info [i];
7381 MonoExceptionClause *clause1 = &cfg->header->clauses [cindex1];
7383 for (j = 0; j < cfg->header->num_clauses; ++j) {
7385 MonoExceptionClause *clause2 = &cfg->header->clauses [cindex2];
7386 MonoJitExceptionInfo *nesting_ei, *nested_ei;
7388 if (cindex1 != cindex2 && clause1->try_offset >= clause2->try_offset && clause1->handler_offset <= clause2->handler_offset) {
7389 /* clause1 is the nested clause */
7390 nested_ei = &cfg->llvm_ex_info [i];
7391 nesting_ei = &cfg->llvm_ex_info [nindex];
7394 memcpy (nesting_ei, nested_ei, sizeof (MonoJitExceptionInfo));
7396 nesting_ei->flags = clause2->flags;
7397 nesting_ei->data.catch_class = clause2->data.catch_class;
7398 nesting_ei->clause_index = cindex2;
7402 g_assert (nindex == ei_len + nested_len);
7403 cfg->llvm_this_reg = this_reg;
7404 cfg->llvm_this_offset = this_offset;
7406 /* type_info [i] is cfg mempool allocated, no need to free it */
7412 #if LLVM_API_VERSION > 100
7414 * decode_llvm_eh_info:
7416 * Decode the EH table emitted by llvm in jit mode, and store
7417 * the result into cfg.
7420 decode_llvm_eh_info (EmitContext *ctx, gpointer eh_frame)
7422 MonoCompile *cfg = ctx->cfg;
7425 MonoLLVMFDEInfo info;
7426 MonoJitExceptionInfo *ei;
7427 guint8 *p = eh_frame;
7428 int version, fde_count, fde_offset;
7429 guint32 ei_len, i, nested_len;
7430 gpointer *type_info;
7434 * Decode the one element EH table emitted by the MonoException class
7438 /* Similar to decode_llvm_mono_eh_frame () in aot-runtime.c */
7441 g_assert (version == 3);
7444 p = (guint8 *)ALIGN_PTR_TO (p, 4);
7446 fde_count = *(guint32*)p;
7450 g_assert (fde_count == 1);
7452 /* The only table entry */
7453 fde_offset = table [1];
7456 cfg->code_len = table [0];
7457 fde_len = table [1] - fde_offset;
7460 fde = (guint8*)eh_frame + fde_offset;
7461 cie = (guint8*)table;
7463 mono_unwind_decode_llvm_mono_fde (fde, fde_len, cie, cfg->native_code, &info);
7465 cfg->encoded_unwind_ops = info.unw_info;
7466 cfg->encoded_unwind_ops_len = info.unw_info_len;
7467 if (cfg->verbose_level > 1)
7468 mono_print_unwind_info (cfg->encoded_unwind_ops, cfg->encoded_unwind_ops_len);
7469 if (info.this_reg != -1) {
7470 cfg->llvm_this_reg = info.this_reg;
7471 cfg->llvm_this_offset = info.this_offset;
7475 ei_len = info.ex_info_len;
7476 type_info = info.type_info;
7478 // Nested clauses are currently disabled
7481 cfg->llvm_ex_info = (MonoJitExceptionInfo*)mono_mempool_alloc0 (cfg->mempool, (ei_len + nested_len) * sizeof (MonoJitExceptionInfo));
7482 cfg->llvm_ex_info_len = ei_len + nested_len;
7483 memcpy (cfg->llvm_ex_info, ei, ei_len * sizeof (MonoJitExceptionInfo));
7484 /* Fill the rest of the information from the type info */
7485 for (i = 0; i < ei_len; ++i) {
7486 gint32 clause_index = *(gint32*)type_info [i];
7487 MonoExceptionClause *clause = &cfg->header->clauses [clause_index];
7489 cfg->llvm_ex_info [i].flags = clause->flags;
7490 cfg->llvm_ex_info [i].data.catch_class = clause->data.catch_class;
7491 cfg->llvm_ex_info [i].clause_index = clause_index;
7497 dlsym_cb (const char *name, void **symbol)
7503 if (!strcmp (name, "__bzero")) {
7504 *symbol = (void*)bzero;
7506 current = mono_dl_open (NULL, 0, NULL);
7509 err = mono_dl_symbol (current, name, symbol);
7511 mono_dl_close (current);
7513 #ifdef MONO_ARCH_HAVE_CREATE_LLVM_NATIVE_THUNK
7514 *symbol = (char*)mono_arch_create_llvm_native_thunk (mono_domain_get (), (guint8*)(*symbol));
7520 AddFunc (LLVMModuleRef module, const char *name, LLVMTypeRef ret_type, LLVMTypeRef *param_types, int nparams)
7522 LLVMAddFunction (module, name, LLVMFunctionType (ret_type, param_types, nparams, FALSE));
7526 AddFunc2 (LLVMModuleRef module, const char *name, LLVMTypeRef ret_type, LLVMTypeRef param_type1, LLVMTypeRef param_type2)
7528 LLVMTypeRef param_types [4];
7530 param_types [0] = param_type1;
7531 param_types [1] = param_type2;
7533 AddFunc (module, name, ret_type, param_types, 2);
7539 INTRINS_SADD_OVF_I32,
7540 INTRINS_UADD_OVF_I32,
7541 INTRINS_SSUB_OVF_I32,
7542 INTRINS_USUB_OVF_I32,
7543 INTRINS_SMUL_OVF_I32,
7544 INTRINS_UMUL_OVF_I32,
7545 INTRINS_SADD_OVF_I64,
7546 INTRINS_UADD_OVF_I64,
7547 INTRINS_SSUB_OVF_I64,
7548 INTRINS_USUB_OVF_I64,
7549 INTRINS_SMUL_OVF_I64,
7550 INTRINS_UMUL_OVF_I64,
7557 #if defined(TARGET_AMD64) || defined(TARGET_X86)
7558 INTRINS_SSE_PMOVMSKB,
7559 INTRINS_SSE_PSRLI_W,
7560 INTRINS_SSE_PSRAI_W,
7561 INTRINS_SSE_PSLLI_W,
7562 INTRINS_SSE_PSRLI_D,
7563 INTRINS_SSE_PSRAI_D,
7564 INTRINS_SSE_PSLLI_D,
7565 INTRINS_SSE_PSRLI_Q,
7566 INTRINS_SSE_PSLLI_Q,
7567 INTRINS_SSE_SQRT_PD,
7568 INTRINS_SSE_SQRT_PS,
7569 INTRINS_SSE_RSQRT_PS,
7571 INTRINS_SSE_CVTTPD2DQ,
7572 INTRINS_SSE_CVTTPS2DQ,
7573 INTRINS_SSE_CVTDQ2PD,
7574 INTRINS_SSE_CVTDQ2PS,
7575 INTRINS_SSE_CVTPD2DQ,
7576 INTRINS_SSE_CVTPS2DQ,
7577 INTRINS_SSE_CVTPD2PS,
7578 INTRINS_SSE_CVTPS2PD,
7581 INTRINS_SSE_PACKSSWB,
7582 INTRINS_SSE_PACKUSWB,
7583 INTRINS_SSE_PACKSSDW,
7584 INTRINS_SSE_PACKUSDW,
7589 INTRINS_SSE_ADDSUBPS,
7594 INTRINS_SSE_ADDSUBPD,
7602 INTRINS_SSE_PADDUSW,
7603 INTRINS_SSE_PSUBUSW,
7611 INTRINS_SSE_PADDUSB,
7612 INTRINS_SSE_PSUBUSB,
7624 static IntrinsicDesc intrinsics[] = {
7625 {INTRINS_MEMSET, "llvm.memset.p0i8.i32"},
7626 {INTRINS_MEMCPY, "llvm.memcpy.p0i8.p0i8.i32"},
7627 {INTRINS_SADD_OVF_I32, "llvm.sadd.with.overflow.i32"},
7628 {INTRINS_UADD_OVF_I32, "llvm.uadd.with.overflow.i32"},
7629 {INTRINS_SSUB_OVF_I32, "llvm.ssub.with.overflow.i32"},
7630 {INTRINS_USUB_OVF_I32, "llvm.usub.with.overflow.i32"},
7631 {INTRINS_SMUL_OVF_I32, "llvm.smul.with.overflow.i32"},
7632 {INTRINS_UMUL_OVF_I32, "llvm.umul.with.overflow.i32"},
7633 {INTRINS_SADD_OVF_I64, "llvm.sadd.with.overflow.i64"},
7634 {INTRINS_UADD_OVF_I64, "llvm.uadd.with.overflow.i64"},
7635 {INTRINS_SSUB_OVF_I64, "llvm.ssub.with.overflow.i64"},
7636 {INTRINS_USUB_OVF_I64, "llvm.usub.with.overflow.i64"},
7637 {INTRINS_SMUL_OVF_I64, "llvm.smul.with.overflow.i64"},
7638 {INTRINS_UMUL_OVF_I64, "llvm.umul.with.overflow.i64"},
7639 {INTRINS_SIN, "llvm.sin.f64"},
7640 {INTRINS_COS, "llvm.cos.f64"},
7641 {INTRINS_SQRT, "llvm.sqrt.f64"},
7642 /* This isn't an intrinsic, instead llvm seems to special case it by name */
7643 {INTRINS_FABS, "fabs"},
7644 {INTRINS_EXPECT_I8, "llvm.expect.i8"},
7645 {INTRINS_EXPECT_I1, "llvm.expect.i1"},
7646 #if defined(TARGET_AMD64) || defined(TARGET_X86)
7647 {INTRINS_SSE_PMOVMSKB, "llvm.x86.sse2.pmovmskb.128"},
7648 {INTRINS_SSE_PSRLI_W, "llvm.x86.sse2.psrli.w"},
7649 {INTRINS_SSE_PSRAI_W, "llvm.x86.sse2.psrai.w"},
7650 {INTRINS_SSE_PSLLI_W, "llvm.x86.sse2.pslli.w"},
7651 {INTRINS_SSE_PSRLI_D, "llvm.x86.sse2.psrli.d"},
7652 {INTRINS_SSE_PSRAI_D, "llvm.x86.sse2.psrai.d"},
7653 {INTRINS_SSE_PSLLI_D, "llvm.x86.sse2.pslli.d"},
7654 {INTRINS_SSE_PSRLI_Q, "llvm.x86.sse2.psrli.q"},
7655 {INTRINS_SSE_PSLLI_Q, "llvm.x86.sse2.pslli.q"},
7656 {INTRINS_SSE_SQRT_PD, "llvm.x86.sse2.sqrt.pd"},
7657 {INTRINS_SSE_SQRT_PS, "llvm.x86.sse.sqrt.ps"},
7658 {INTRINS_SSE_RSQRT_PS, "llvm.x86.sse.rsqrt.ps"},
7659 {INTRINS_SSE_RCP_PS, "llvm.x86.sse.rcp.ps"},
7660 {INTRINS_SSE_CVTTPD2DQ, "llvm.x86.sse2.cvttpd2dq"},
7661 {INTRINS_SSE_CVTTPS2DQ, "llvm.x86.sse2.cvttps2dq"},
7662 {INTRINS_SSE_CVTDQ2PD, "llvm.x86.sse2.cvtdq2pd"},
7663 {INTRINS_SSE_CVTDQ2PS, "llvm.x86.sse2.cvtdq2ps"},
7664 {INTRINS_SSE_CVTPD2DQ, "llvm.x86.sse2.cvtpd2dq"},
7665 {INTRINS_SSE_CVTPS2DQ, "llvm.x86.sse2.cvtps2dq"},
7666 {INTRINS_SSE_CVTPD2PS, "llvm.x86.sse2.cvtpd2ps"},
7667 {INTRINS_SSE_CVTPS2PD, "llvm.x86.sse2.cvtps2pd"},
7668 {INTRINS_SSE_CMPPD, "llvm.x86.sse2.cmp.pd"},
7669 {INTRINS_SSE_CMPPS, "llvm.x86.sse.cmp.ps"},
7670 {INTRINS_SSE_PACKSSWB, "llvm.x86.sse2.packsswb.128"},
7671 {INTRINS_SSE_PACKUSWB, "llvm.x86.sse2.packuswb.128"},
7672 {INTRINS_SSE_PACKSSDW, "llvm.x86.sse2.packssdw.128"},
7673 {INTRINS_SSE_PACKUSDW, "llvm.x86.sse41.packusdw"},
7674 {INTRINS_SSE_MINPS, "llvm.x86.sse.min.ps"},
7675 {INTRINS_SSE_MAXPS, "llvm.x86.sse.max.ps"},
7676 {INTRINS_SSE_HADDPS, "llvm.x86.sse3.hadd.ps"},
7677 {INTRINS_SSE_HSUBPS, "llvm.x86.sse3.hsub.ps"},
7678 {INTRINS_SSE_ADDSUBPS, "llvm.x86.sse3.addsub.ps"},
7679 {INTRINS_SSE_MINPD, "llvm.x86.sse2.min.pd"},
7680 {INTRINS_SSE_MAXPD, "llvm.x86.sse2.max.pd"},
7681 {INTRINS_SSE_HADDPD, "llvm.x86.sse3.hadd.pd"},
7682 {INTRINS_SSE_HSUBPD, "llvm.x86.sse3.hsub.pd"},
7683 {INTRINS_SSE_ADDSUBPD, "llvm.x86.sse3.addsub.pd"},
7684 {INTRINS_SSE_PMINUD, "llvm.x86.sse41.pminud"},
7685 {INTRINS_SSE_PMAXUD, "llvm.x86.sse41.pmaxud"},
7686 {INTRINS_SSE_PMINUW, "llvm.x86.sse41.pminuw"},
7687 {INTRINS_SSE_PMINSW, "llvm.x86.sse2.pmins.w"},
7688 {INTRINS_SSE_PMAXUW, "llvm.x86.sse41.pmaxuw"},
7689 {INTRINS_SSE_PADDSW, "llvm.x86.sse2.padds.w"},
7690 {INTRINS_SSE_PSUBSW, "llvm.x86.sse2.psubs.w"},
7691 {INTRINS_SSE_PADDUSW, "llvm.x86.sse2.paddus.w"},
7692 {INTRINS_SSE_PSUBUSW, "llvm.x86.sse2.psubus.w"},
7693 {INTRINS_SSE_PAVGW, "llvm.x86.sse2.pavg.w"},
7694 {INTRINS_SSE_PMULHW, "llvm.x86.sse2.pmulh.w"},
7695 {INTRINS_SSE_PMULHU, "llvm.x86.sse2.pmulhu.w"},
7696 {INTRINS_SSE_PMINUB, "llvm.x86.sse2.pminu.b"},
7697 {INTRINS_SSE_PMAXUB, "llvm.x86.sse2.pmaxu.b"},
7698 {INTRINS_SE_PADDSB, "llvm.x86.sse2.padds.b"},
7699 {INTRINS_SSE_PSUBSB, "llvm.x86.sse2.psubs.b"},
7700 {INTRINS_SSE_PADDUSB, "llvm.x86.sse2.paddus.b"},
7701 {INTRINS_SSE_PSUBUSB, "llvm.x86.sse2.psubus.b"},
7702 {INTRINS_SSE_PAVGB, "llvm.x86.sse2.pavg.b"},
7703 {INTRINS_SSE_PAUSE, "llvm.x86.sse2.pause"}
7708 add_sse_binary (LLVMModuleRef module, const char *name, int type)
7710 LLVMTypeRef ret_type = type_to_simd_type (type);
7711 AddFunc2 (module, name, ret_type, ret_type, ret_type);
7715 add_intrinsic (LLVMModuleRef module, int id)
7718 LLVMTypeRef ret_type, arg_types [16];
7720 name = g_hash_table_lookup (intrins_id_to_name, GINT_TO_POINTER (id));
7724 case INTRINS_MEMSET: {
7725 LLVMTypeRef params [] = { LLVMPointerType (LLVMInt8Type (), 0), LLVMInt8Type (), LLVMInt32Type (), LLVMInt32Type (), LLVMInt1Type () };
7727 AddFunc (module, name, LLVMVoidType (), params, 5);
7730 case INTRINS_MEMCPY: {
7731 LLVMTypeRef params [] = { LLVMPointerType (LLVMInt8Type (), 0), LLVMPointerType (LLVMInt8Type (), 0), LLVMInt32Type (), LLVMInt32Type (), LLVMInt1Type () };
7733 AddFunc (module, name, LLVMVoidType (), params, 5);
7736 case INTRINS_SADD_OVF_I32:
7737 case INTRINS_UADD_OVF_I32:
7738 case INTRINS_SSUB_OVF_I32:
7739 case INTRINS_USUB_OVF_I32:
7740 case INTRINS_SMUL_OVF_I32:
7741 case INTRINS_UMUL_OVF_I32: {
7742 LLVMTypeRef ovf_res_i32 [] = { LLVMInt32Type (), LLVMInt1Type () };
7743 LLVMTypeRef params [] = { LLVMInt32Type (), LLVMInt32Type () };
7744 LLVMTypeRef ret_type = LLVMStructType (ovf_res_i32, 2, FALSE);
7746 AddFunc (module, name, ret_type, params, 2);
7749 case INTRINS_SADD_OVF_I64:
7750 case INTRINS_UADD_OVF_I64:
7751 case INTRINS_SSUB_OVF_I64:
7752 case INTRINS_USUB_OVF_I64:
7753 case INTRINS_SMUL_OVF_I64:
7754 case INTRINS_UMUL_OVF_I64: {
7755 LLVMTypeRef ovf_res_i64 [] = { LLVMInt64Type (), LLVMInt1Type () };
7756 LLVMTypeRef params [] = { LLVMInt64Type (), LLVMInt64Type () };
7757 LLVMTypeRef ret_type = LLVMStructType (ovf_res_i64, 2, FALSE);
7759 AddFunc (module, name, ret_type, params, 2);
7765 case INTRINS_FABS: {
7766 LLVMTypeRef params [] = { LLVMDoubleType () };
7768 AddFunc (module, name, LLVMDoubleType (), params, 1);
7771 case INTRINS_EXPECT_I8:
7772 AddFunc2 (module, name, LLVMInt8Type (), LLVMInt8Type (), LLVMInt8Type ());
7774 case INTRINS_EXPECT_I1:
7775 AddFunc2 (module, name, LLVMInt1Type (), LLVMInt1Type (), LLVMInt1Type ());
7777 #if defined(TARGET_AMD64) || defined(TARGET_X86)
7778 case INTRINS_SSE_PMOVMSKB:
7780 ret_type = LLVMInt32Type ();
7781 arg_types [0] = type_to_simd_type (MONO_TYPE_I1);
7782 AddFunc (module, name, ret_type, arg_types, 1);
7784 case INTRINS_SSE_PSRLI_W:
7785 case INTRINS_SSE_PSRAI_W:
7786 case INTRINS_SSE_PSLLI_W:
7788 ret_type = type_to_simd_type (MONO_TYPE_I2);
7789 arg_types [0] = ret_type;
7790 arg_types [1] = LLVMInt32Type ();
7791 AddFunc (module, name, ret_type, arg_types, 2);
7793 case INTRINS_SSE_PSRLI_D:
7794 case INTRINS_SSE_PSRAI_D:
7795 case INTRINS_SSE_PSLLI_D:
7796 ret_type = type_to_simd_type (MONO_TYPE_I4);
7797 arg_types [0] = ret_type;
7798 arg_types [1] = LLVMInt32Type ();
7799 AddFunc (module, name, ret_type, arg_types, 2);
7801 case INTRINS_SSE_PSRLI_Q:
7802 case INTRINS_SSE_PSLLI_Q:
7803 ret_type = type_to_simd_type (MONO_TYPE_I8);
7804 arg_types [0] = ret_type;
7805 arg_types [1] = LLVMInt32Type ();
7806 AddFunc (module, name, ret_type, arg_types, 2);
7808 case INTRINS_SSE_SQRT_PD:
7810 ret_type = type_to_simd_type (MONO_TYPE_R8);
7811 arg_types [0] = ret_type;
7812 AddFunc (module, name, ret_type, arg_types, 1);
7814 case INTRINS_SSE_SQRT_PS:
7815 ret_type = type_to_simd_type (MONO_TYPE_R4);
7816 arg_types [0] = ret_type;
7817 AddFunc (module, name, ret_type, arg_types, 1);
7819 case INTRINS_SSE_RSQRT_PS:
7820 ret_type = type_to_simd_type (MONO_TYPE_R4);
7821 arg_types [0] = ret_type;
7822 AddFunc (module, name, ret_type, arg_types, 1);
7824 case INTRINS_SSE_RCP_PS:
7825 ret_type = type_to_simd_type (MONO_TYPE_R4);
7826 arg_types [0] = ret_type;
7827 AddFunc (module, name, ret_type, arg_types, 1);
7829 case INTRINS_SSE_CVTTPD2DQ:
7830 ret_type = type_to_simd_type (MONO_TYPE_I4);
7831 arg_types [0] = type_to_simd_type (MONO_TYPE_R8);
7832 AddFunc (module, name, ret_type, arg_types, 1);
7834 case INTRINS_SSE_CVTTPS2DQ:
7835 ret_type = type_to_simd_type (MONO_TYPE_I4);
7836 arg_types [0] = type_to_simd_type (MONO_TYPE_R4);
7837 AddFunc (module, name, ret_type, arg_types, 1);
7839 case INTRINS_SSE_CVTDQ2PD:
7840 /* Conversion ops */
7841 ret_type = type_to_simd_type (MONO_TYPE_R8);
7842 arg_types [0] = type_to_simd_type (MONO_TYPE_I4);
7843 AddFunc (module, name, ret_type, arg_types, 1);
7845 case INTRINS_SSE_CVTDQ2PS:
7846 ret_type = type_to_simd_type (MONO_TYPE_R4);
7847 arg_types [0] = type_to_simd_type (MONO_TYPE_I4);
7848 AddFunc (module, name, ret_type, arg_types, 1);
7850 case INTRINS_SSE_CVTPD2DQ:
7851 ret_type = type_to_simd_type (MONO_TYPE_I4);
7852 arg_types [0] = type_to_simd_type (MONO_TYPE_R8);
7853 AddFunc (module, name, ret_type, arg_types, 1);
7855 case INTRINS_SSE_CVTPS2DQ:
7856 ret_type = type_to_simd_type (MONO_TYPE_I4);
7857 arg_types [0] = type_to_simd_type (MONO_TYPE_R4);
7858 AddFunc (module, name, ret_type, arg_types, 1);
7860 case INTRINS_SSE_CVTPD2PS:
7861 ret_type = type_to_simd_type (MONO_TYPE_R4);
7862 arg_types [0] = type_to_simd_type (MONO_TYPE_R8);
7863 AddFunc (module, name, ret_type, arg_types, 1);
7865 case INTRINS_SSE_CVTPS2PD:
7866 ret_type = type_to_simd_type (MONO_TYPE_R8);
7867 arg_types [0] = type_to_simd_type (MONO_TYPE_R4);
7868 AddFunc (module, name, ret_type, arg_types, 1);
7870 case INTRINS_SSE_CMPPD:
7872 ret_type = type_to_simd_type (MONO_TYPE_R8);
7873 arg_types [0] = ret_type;
7874 arg_types [1] = ret_type;
7875 arg_types [2] = LLVMInt8Type ();
7876 AddFunc (module, name, ret_type, arg_types, 3);
7878 case INTRINS_SSE_CMPPS:
7879 ret_type = type_to_simd_type (MONO_TYPE_R4);
7880 arg_types [0] = ret_type;
7881 arg_types [1] = ret_type;
7882 arg_types [2] = LLVMInt8Type ();
7883 AddFunc (module, name, ret_type, arg_types, 3);
7885 case INTRINS_SSE_PACKSSWB:
7886 case INTRINS_SSE_PACKUSWB:
7887 case INTRINS_SSE_PACKSSDW:
7889 ret_type = type_to_simd_type (MONO_TYPE_I1);
7890 arg_types [0] = type_to_simd_type (MONO_TYPE_I2);
7891 arg_types [1] = type_to_simd_type (MONO_TYPE_I2);
7892 AddFunc (module, name, ret_type, arg_types, 2);
7894 case INTRINS_SSE_PACKUSDW:
7895 ret_type = type_to_simd_type (MONO_TYPE_I2);
7896 arg_types [0] = type_to_simd_type (MONO_TYPE_I4);
7897 arg_types [1] = type_to_simd_type (MONO_TYPE_I4);
7898 AddFunc (module, name, ret_type, arg_types, 2);
7900 /* SSE Binary ops */
7901 case INTRINS_SSE_PMINUD:
7902 case INTRINS_SSE_PMAXUD:
7903 add_sse_binary (module, name, MONO_TYPE_I4);
7905 case INTRINS_SSE_PMINUW:
7906 case INTRINS_SSE_PMINSW:
7907 case INTRINS_SSE_PMAXUW:
7908 case INTRINS_SSE_PADDSW:
7909 case INTRINS_SSE_PSUBSW:
7910 case INTRINS_SSE_PADDUSW:
7911 case INTRINS_SSE_PSUBUSW:
7912 case INTRINS_SSE_PAVGW:
7913 case INTRINS_SSE_PMULHW:
7914 case INTRINS_SSE_PMULHU:
7915 add_sse_binary (module, name, MONO_TYPE_I2);
7917 case INTRINS_SSE_MINPS:
7918 case INTRINS_SSE_MAXPS:
7919 case INTRINS_SSE_HADDPS:
7920 case INTRINS_SSE_HSUBPS:
7921 case INTRINS_SSE_ADDSUBPS:
7922 add_sse_binary (module, name, MONO_TYPE_R4);
7924 case INTRINS_SSE_MINPD:
7925 case INTRINS_SSE_MAXPD:
7926 case INTRINS_SSE_HADDPD:
7927 case INTRINS_SSE_HSUBPD:
7928 case INTRINS_SSE_ADDSUBPD:
7929 add_sse_binary (module, name, MONO_TYPE_R8);
7931 case INTRINS_SSE_PMINUB:
7932 case INTRINS_SSE_PMAXUB:
7933 case INTRINS_SE_PADDSB:
7934 case INTRINS_SSE_PSUBSB:
7935 case INTRINS_SSE_PADDUSB:
7936 case INTRINS_SSE_PSUBUSB:
7937 case INTRINS_SSE_PAVGB:
7938 add_sse_binary (module, name, MONO_TYPE_I1);
7940 case INTRINS_SSE_PAUSE:
7941 AddFunc (module, "llvm.x86.sse2.pause", LLVMVoidType (), NULL, 0);
7945 g_assert_not_reached ();
7951 get_intrinsic (EmitContext *ctx, const char *name)
7953 #if LLVM_API_VERSION > 100
7957 * Every method is emitted into its own module so
7958 * we can add intrinsics on demand.
7960 res = LLVMGetNamedFunction (ctx->lmodule, name);
7964 /* No locking needed */
7965 id = GPOINTER_TO_INT (g_hash_table_lookup (intrins_name_to_id, name));
7968 printf ("%s\n", name);
7969 g_assert (id != -1);
7970 add_intrinsic (ctx->lmodule, id);
7971 res = LLVMGetNamedFunction (ctx->lmodule, name);
7979 res = LLVMGetNamedFunction (ctx->lmodule, name);
7986 add_intrinsics (LLVMModuleRef module)
7990 /* Emit declarations of instrinsics */
7992 * It would be nicer to emit only the intrinsics actually used, but LLVM's Module
7993 * type doesn't seem to do any locking.
7995 for (i = 0; i < INTRINS_NUM; ++i)
7996 add_intrinsic (module, i);
8000 AddFunc (module, "mono_personality", LLVMVoidType (), NULL, 0);
8002 AddFunc (module, "llvm_resume_unwind_trampoline", LLVMVoidType (), NULL, 0);
8005 /* SSE intrinsics */
8006 #if defined(TARGET_X86) || defined(TARGET_AMD64)
8010 /* Load/Store intrinsics */
8012 LLVMTypeRef arg_types [5];
8016 for (i = 1; i <= 8; i *= 2) {
8017 arg_types [0] = LLVMPointerType (LLVMIntType (i * 8), 0);
8018 arg_types [1] = LLVMInt32Type ();
8019 arg_types [2] = LLVMInt1Type ();
8020 arg_types [3] = LLVMInt32Type ();
8021 sprintf (name, "llvm.mono.load.i%d.p0i%d", i * 8, i * 8);
8022 AddFunc (module, name, LLVMIntType (i * 8), arg_types, 4);
8024 arg_types [0] = LLVMIntType (i * 8);
8025 arg_types [1] = LLVMPointerType (LLVMIntType (i * 8), 0);
8026 arg_types [2] = LLVMInt32Type ();
8027 arg_types [3] = LLVMInt1Type ();
8028 arg_types [4] = LLVMInt32Type ();
8029 sprintf (name, "llvm.mono.store.i%d.p0i%d", i * 8, i * 8);
8030 AddFunc (module, name, LLVMVoidType (), arg_types, 5);
8036 add_types (MonoLLVMModule *module)
8038 module->ptr_type = LLVMPointerType (sizeof (gpointer) == 8 ? LLVMInt64Type () : LLVMInt32Type (), 0);
8042 mono_llvm_init (void)
8047 mono_native_tls_alloc (¤t_cfg_tls_id, NULL);
8049 h = g_hash_table_new (NULL, NULL);
8050 for (i = 0; i < INTRINS_NUM; ++i)
8051 g_hash_table_insert (h, GINT_TO_POINTER (intrinsics [i].id), (gpointer)intrinsics [i].name);
8052 intrins_id_to_name = h;
8054 h = g_hash_table_new (g_str_hash, g_str_equal);
8055 for (i = 0; i < INTRINS_NUM; ++i)
8056 g_hash_table_insert (h, (gpointer)intrinsics [i].name, GINT_TO_POINTER (intrinsics [i].id + 1));
8057 intrins_name_to_id = h;
8061 init_jit_module (MonoDomain *domain)
8063 MonoJitDomainInfo *dinfo;
8064 MonoLLVMModule *module;
8067 dinfo = domain_jit_info (domain);
8068 if (dinfo->llvm_module)
8071 mono_loader_lock ();
8073 if (dinfo->llvm_module) {
8074 mono_loader_unlock ();
8078 module = g_new0 (MonoLLVMModule, 1);
8080 name = g_strdup_printf ("mono-%s", domain->friendly_name);
8081 module->lmodule = LLVMModuleCreateWithName (name);
8082 module->context = LLVMGetGlobalContext ();
8084 module->mono_ee = (MonoEERef*)mono_llvm_create_ee (LLVMCreateModuleProviderForExistingModule (module->lmodule), alloc_cb, emitted_cb, exception_cb, dlsym_cb, &module->ee);
8086 add_intrinsics (module->lmodule);
8089 module->llvm_types = g_hash_table_new (NULL, NULL);
8091 #if LLVM_API_VERSION < 100
8092 MonoJitICallInfo *info;
8094 info = mono_find_jit_icall_by_name ("llvm_resume_unwind_trampoline");
8096 LLVMAddGlobalMapping (module->ee, LLVMGetNamedFunction (module->lmodule, "llvm_resume_unwind_trampoline"), (void*)info->func);
8099 mono_memory_barrier ();
8101 dinfo->llvm_module = module;
8103 mono_loader_unlock ();
8107 mono_llvm_cleanup (void)
8109 MonoLLVMModule *module = &aot_module;
8111 if (module->lmodule)
8112 LLVMDisposeModule (module->lmodule);
8114 if (module->context)
8115 LLVMContextDispose (module->context);
8119 mono_llvm_free_domain_info (MonoDomain *domain)
8121 MonoJitDomainInfo *info = domain_jit_info (domain);
8122 MonoLLVMModule *module = (MonoLLVMModule*)info->llvm_module;
8128 if (module->llvm_types)
8129 g_hash_table_destroy (module->llvm_types);
8131 mono_llvm_dispose_ee (module->mono_ee);
8133 if (module->bb_names) {
8134 for (i = 0; i < module->bb_names_len; ++i)
8135 g_free (module->bb_names [i]);
8136 g_free (module->bb_names);
8138 //LLVMDisposeModule (module->module);
8142 info->llvm_module = NULL;
8146 mono_llvm_create_aot_module (MonoAssembly *assembly, const char *global_prefix, gboolean emit_dwarf, gboolean static_link, gboolean llvm_only)
8148 MonoLLVMModule *module = &aot_module;
8150 /* Delete previous module */
8151 if (module->plt_entries)
8152 g_hash_table_destroy (module->plt_entries);
8153 if (module->lmodule)
8154 LLVMDisposeModule (module->lmodule);
8156 memset (module, 0, sizeof (aot_module));
8158 module->lmodule = LLVMModuleCreateWithName ("aot");
8159 module->assembly = assembly;
8160 module->global_prefix = g_strdup (global_prefix);
8161 module->got_symbol = g_strdup_printf ("%s_llvm_got", global_prefix);
8162 module->eh_frame_symbol = g_strdup_printf ("%s_eh_frame", global_prefix);
8163 module->get_method_symbol = g_strdup_printf ("%s_get_method", global_prefix);
8164 module->get_unbox_tramp_symbol = g_strdup_printf ("%s_get_unbox_tramp", global_prefix);
8165 module->external_symbols = TRUE;
8166 module->emit_dwarf = emit_dwarf;
8167 module->static_link = static_link;
8168 module->llvm_only = llvm_only;
8169 /* The first few entries are reserved */
8170 module->max_got_offset = 16;
8171 module->context = LLVMContextCreate ();
8174 /* clang ignores our debug info because it has an invalid version */
8175 module->emit_dwarf = FALSE;
8177 #if LLVM_API_VERSION > 100
8178 module->emit_dwarf = FALSE;
8181 add_intrinsics (module->lmodule);
8184 #if LLVM_API_VERSION > 100
8185 if (module->emit_dwarf) {
8186 char *dir, *build_info, *s, *cu_name;
8188 module->di_builder = mono_llvm_create_di_builder (module->lmodule);
8191 dir = g_strdup (".");
8192 build_info = mono_get_runtime_build_info ();
8193 s = g_strdup_printf ("Mono AOT Compiler %s (LLVM)", build_info);
8194 cu_name = g_path_get_basename (assembly->image->name);
8195 module->cu = mono_llvm_di_create_compile_unit (module->di_builder, cu_name, dir, s);
8197 g_free (build_info);
8204 * We couldn't compute the type of the LLVM global representing the got because
8205 * its size is only known after all the methods have been emitted. So create
8206 * a dummy variable, and replace all uses it with the real got variable when
8207 * its size is known in mono_llvm_emit_aot_module ().
8210 LLVMTypeRef got_type = LLVMArrayType (module->ptr_type, 0);
8212 module->got_var = LLVMAddGlobal (module->lmodule, got_type, "mono_dummy_got");
8213 LLVMSetInitializer (module->got_var, LLVMConstNull (got_type));
8216 /* Add initialization array */
8218 LLVMTypeRef inited_type = LLVMArrayType (LLVMInt8Type (), 0);
8220 module->inited_var = LLVMAddGlobal (aot_module.lmodule, inited_type, "mono_inited_tmp");
8221 LLVMSetInitializer (module->inited_var, LLVMConstNull (inited_type));
8225 emit_init_icall_wrappers (module);
8227 emit_llvm_code_start (module);
8229 /* Add a dummy personality function */
8230 if (!use_debug_personality) {
8231 LLVMValueRef personality = LLVMAddFunction (module->lmodule, default_personality_name, LLVMFunctionType (LLVMInt32Type (), NULL, 0, TRUE));
8232 LLVMSetLinkage (personality, LLVMExternalLinkage);
8233 mark_as_used (module, personality);
8236 /* Add a reference to the c++ exception we throw/catch */
8238 LLVMTypeRef exc = LLVMPointerType (LLVMInt8Type (), 0);
8239 module->sentinel_exception = LLVMAddGlobal (module->lmodule, exc, "_ZTIPi");
8240 LLVMSetLinkage (module->sentinel_exception, LLVMExternalLinkage);
8241 mono_llvm_set_is_constant (module->sentinel_exception);
8244 module->llvm_types = g_hash_table_new (NULL, NULL);
8245 module->plt_entries = g_hash_table_new (g_str_hash, g_str_equal);
8246 module->plt_entries_ji = g_hash_table_new (NULL, NULL);
8247 module->direct_callables = g_hash_table_new (g_str_hash, g_str_equal);
8248 module->method_to_lmethod = g_hash_table_new (NULL, NULL);
8249 module->idx_to_lmethod = g_hash_table_new (NULL, NULL);
8250 module->idx_to_unbox_tramp = g_hash_table_new (NULL, NULL);
8251 module->method_to_callers = g_hash_table_new (NULL, NULL);
8255 llvm_array_from_uints (LLVMTypeRef el_type, guint32 *values, int nvalues)
8258 LLVMValueRef res, *vals;
8260 vals = g_new0 (LLVMValueRef, nvalues);
8261 for (i = 0; i < nvalues; ++i)
8262 vals [i] = LLVMConstInt (LLVMInt32Type (), values [i], FALSE);
8263 res = LLVMConstArray (LLVMInt32Type (), vals, nvalues);
8269 * mono_llvm_emit_aot_file_info:
8271 * Emit the MonoAotFileInfo structure.
8272 * Same as emit_aot_file_info () in aot-compiler.c.
8275 mono_llvm_emit_aot_file_info (MonoAotFileInfo *info, gboolean has_jitted_code)
8277 MonoLLVMModule *module = &aot_module;
8279 /* Save these for later */
8280 memcpy (&module->aot_info, info, sizeof (MonoAotFileInfo));
8281 module->has_jitted_code = has_jitted_code;
8285 * mono_llvm_emit_aot_data:
8287 * Emit the binary data DATA pointed to by symbol SYMBOL.
8290 mono_llvm_emit_aot_data (const char *symbol, guint8 *data, int data_len)
8292 MonoLLVMModule *module = &aot_module;
8296 type = LLVMArrayType (LLVMInt8Type (), data_len);
8297 d = LLVMAddGlobal (module->lmodule, type, symbol);
8298 LLVMSetVisibility (d, LLVMHiddenVisibility);
8299 LLVMSetLinkage (d, LLVMInternalLinkage);
8300 LLVMSetInitializer (d, mono_llvm_create_constant_data_array (data, data_len));
8301 mono_llvm_set_is_constant (d);
8304 /* Add a reference to a global defined in JITted code */
8306 AddJitGlobal (MonoLLVMModule *module, LLVMTypeRef type, const char *name)
8311 s = g_strdup_printf ("%s%s", module->global_prefix, name);
8312 v = LLVMAddGlobal (module->lmodule, LLVMInt8Type (), s);
8318 emit_aot_file_info (MonoLLVMModule *module)
8320 LLVMTypeRef file_info_type;
8321 LLVMTypeRef *eltypes, eltype;
8322 LLVMValueRef info_var;
8323 LLVMValueRef *fields;
8324 int i, nfields, tindex;
8325 MonoAotFileInfo *info;
8326 LLVMModuleRef lmodule = module->lmodule;
8328 info = &module->aot_info;
8330 /* Create an LLVM type to represent MonoAotFileInfo */
8331 nfields = 2 + MONO_AOT_FILE_INFO_NUM_SYMBOLS + 15 + 5;
8332 eltypes = g_new (LLVMTypeRef, nfields);
8334 eltypes [tindex ++] = LLVMInt32Type ();
8335 eltypes [tindex ++] = LLVMInt32Type ();
8337 for (i = 0; i < MONO_AOT_FILE_INFO_NUM_SYMBOLS; ++i)
8338 eltypes [tindex ++] = LLVMPointerType (LLVMInt8Type (), 0);
8340 for (i = 0; i < 15; ++i)
8341 eltypes [tindex ++] = LLVMInt32Type ();
8343 eltypes [tindex ++] = LLVMArrayType (LLVMInt32Type (), MONO_AOT_TABLE_NUM);
8344 for (i = 0; i < 4; ++i)
8345 eltypes [tindex ++] = LLVMArrayType (LLVMInt32Type (), MONO_AOT_TRAMP_NUM);
8346 g_assert (tindex == nfields);
8347 file_info_type = LLVMStructCreateNamed (module->context, "MonoAotFileInfo");
8348 LLVMStructSetBody (file_info_type, eltypes, nfields, FALSE);
8350 info_var = LLVMAddGlobal (lmodule, file_info_type, "mono_aot_file_info");
8351 if (module->static_link) {
8352 LLVMSetVisibility (info_var, LLVMHiddenVisibility);
8353 LLVMSetLinkage (info_var, LLVMInternalLinkage);
8355 fields = g_new (LLVMValueRef, nfields);
8357 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->version, FALSE);
8358 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->dummy, FALSE);
8362 * We use LLVMGetNamedGlobal () for symbol which are defined in LLVM code, and LLVMAddGlobal ()
8363 * for symbols defined in the .s file emitted by the aot compiler.
8365 eltype = eltypes [tindex];
8366 if (module->llvm_only)
8367 fields [tindex ++] = LLVMConstNull (eltype);
8369 fields [tindex ++] = AddJitGlobal (module, eltype, "jit_got");
8370 fields [tindex ++] = module->got_var;
8371 /* llc defines this directly */
8372 if (!module->llvm_only) {
8373 fields [tindex ++] = LLVMAddGlobal (lmodule, eltype, module->eh_frame_symbol);
8374 fields [tindex ++] = LLVMConstNull (eltype);
8375 fields [tindex ++] = LLVMConstNull (eltype);
8377 fields [tindex ++] = LLVMConstNull (eltype);
8378 fields [tindex ++] = module->get_method;
8379 fields [tindex ++] = module->get_unbox_tramp;
8381 if (module->has_jitted_code) {
8382 fields [tindex ++] = AddJitGlobal (module, eltype, "jit_code_start");
8383 fields [tindex ++] = AddJitGlobal (module, eltype, "jit_code_end");
8385 fields [tindex ++] = LLVMConstNull (eltype);
8386 fields [tindex ++] = LLVMConstNull (eltype);
8388 if (!module->llvm_only)
8389 fields [tindex ++] = AddJitGlobal (module, eltype, "method_addresses");
8391 fields [tindex ++] = LLVMConstNull (eltype);
8392 if (info->flags & MONO_AOT_FILE_FLAG_SEPARATE_DATA) {
8393 for (i = 0; i < MONO_AOT_TABLE_NUM; ++i)
8394 fields [tindex ++] = LLVMConstNull (eltype);
8396 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "blob");
8397 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "class_name_table");
8398 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "class_info_offsets");
8399 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "method_info_offsets");
8400 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "ex_info_offsets");
8401 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "extra_method_info_offsets");
8402 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "extra_method_table");
8403 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "got_info_offsets");
8404 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "llvm_got_info_offsets");
8405 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "image_table");
8407 /* Not needed (mem_end) */
8408 fields [tindex ++] = LLVMConstNull (eltype);
8409 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "assembly_guid");
8410 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "runtime_version");
8411 if (info->trampoline_size [0]) {
8412 fields [tindex ++] = AddJitGlobal (module, eltype, "specific_trampolines");
8413 fields [tindex ++] = AddJitGlobal (module, eltype, "static_rgctx_trampolines");
8414 fields [tindex ++] = AddJitGlobal (module, eltype, "imt_thunks");
8415 fields [tindex ++] = AddJitGlobal (module, eltype, "gsharedvt_arg_trampolines");
8417 fields [tindex ++] = LLVMConstNull (eltype);
8418 fields [tindex ++] = LLVMConstNull (eltype);
8419 fields [tindex ++] = LLVMConstNull (eltype);
8420 fields [tindex ++] = LLVMConstNull (eltype);
8422 if (module->static_link && !module->llvm_only)
8423 fields [tindex ++] = AddJitGlobal (module, eltype, "globals");
8425 fields [tindex ++] = LLVMConstNull (eltype);
8426 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "assembly_name");
8427 if (!module->llvm_only) {
8428 fields [tindex ++] = AddJitGlobal (module, eltype, "plt");
8429 fields [tindex ++] = AddJitGlobal (module, eltype, "plt_end");
8430 fields [tindex ++] = AddJitGlobal (module, eltype, "unwind_info");
8431 fields [tindex ++] = AddJitGlobal (module, eltype, "unbox_trampolines");
8432 fields [tindex ++] = AddJitGlobal (module, eltype, "unbox_trampolines_end");
8433 fields [tindex ++] = AddJitGlobal (module, eltype, "unbox_trampoline_addresses");
8435 fields [tindex ++] = LLVMConstNull (eltype);
8436 fields [tindex ++] = LLVMConstNull (eltype);
8437 fields [tindex ++] = LLVMConstNull (eltype);
8438 fields [tindex ++] = LLVMConstNull (eltype);
8439 fields [tindex ++] = LLVMConstNull (eltype);
8440 fields [tindex ++] = LLVMConstNull (eltype);
8443 for (i = 0; i < MONO_AOT_FILE_INFO_NUM_SYMBOLS; ++i)
8444 fields [2 + i] = LLVMConstBitCast (fields [2 + i], eltype);
8447 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->plt_got_offset_base, FALSE);
8448 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->got_size, FALSE);
8449 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->plt_size, FALSE);
8450 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->nmethods, FALSE);
8451 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->flags, FALSE);
8452 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->opts, FALSE);
8453 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->simd_opts, FALSE);
8454 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->gc_name_index, FALSE);
8455 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->num_rgctx_fetch_trampolines, FALSE);
8456 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->double_align, FALSE);
8457 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->long_align, FALSE);
8458 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->generic_tramp_num, FALSE);
8459 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->tramp_page_size, FALSE);
8460 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->nshared_got_entries, FALSE);
8461 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->datafile_size, FALSE);
8463 fields [tindex ++] = llvm_array_from_uints (LLVMInt32Type (), info->table_offsets, MONO_AOT_TABLE_NUM);
8464 fields [tindex ++] = llvm_array_from_uints (LLVMInt32Type (), info->num_trampolines, MONO_AOT_TRAMP_NUM);
8465 fields [tindex ++] = llvm_array_from_uints (LLVMInt32Type (), info->trampoline_got_offset_base, MONO_AOT_TRAMP_NUM);
8466 fields [tindex ++] = llvm_array_from_uints (LLVMInt32Type (), info->trampoline_size, MONO_AOT_TRAMP_NUM);
8467 fields [tindex ++] = llvm_array_from_uints (LLVMInt32Type (), info->tramp_page_code_offsets, MONO_AOT_TRAMP_NUM);
8468 g_assert (tindex == nfields);
8470 LLVMSetInitializer (info_var, LLVMConstNamedStruct (file_info_type, fields, nfields));
8472 if (module->static_link) {
8476 s = g_strdup_printf ("mono_aot_module_%s_info", module->assembly->aname.name);
8477 /* Get rid of characters which cannot occur in symbols */
8479 for (p = s; *p; ++p) {
8480 if (!(isalnum (*p) || *p == '_'))
8483 var = LLVMAddGlobal (module->lmodule, LLVMPointerType (LLVMInt8Type (), 0), s);
8485 LLVMSetInitializer (var, LLVMConstBitCast (LLVMGetNamedGlobal (module->lmodule, "mono_aot_file_info"), LLVMPointerType (LLVMInt8Type (), 0)));
8486 LLVMSetLinkage (var, LLVMExternalLinkage);
8491 * Emit the aot module into the LLVM bitcode file FILENAME.
8494 mono_llvm_emit_aot_module (const char *filename, const char *cu_name)
8496 LLVMTypeRef got_type, inited_type;
8497 LLVMValueRef real_got, real_inited;
8498 MonoLLVMModule *module = &aot_module;
8500 emit_llvm_code_end (module);
8503 * Create the real got variable and replace all uses of the dummy variable with
8506 got_type = LLVMArrayType (module->ptr_type, module->max_got_offset + 1);
8507 real_got = LLVMAddGlobal (module->lmodule, got_type, module->got_symbol);
8508 LLVMSetInitializer (real_got, LLVMConstNull (got_type));
8509 if (module->external_symbols) {
8510 LLVMSetLinkage (real_got, LLVMExternalLinkage);
8511 LLVMSetVisibility (real_got, LLVMHiddenVisibility);
8513 LLVMSetLinkage (real_got, LLVMInternalLinkage);
8515 mono_llvm_replace_uses_of (module->got_var, real_got);
8517 mark_as_used (&aot_module, real_got);
8519 /* Delete the dummy got so it doesn't become a global */
8520 LLVMDeleteGlobal (module->got_var);
8521 module->got_var = real_got;
8524 * Same for the init_var
8526 if (module->llvm_only) {
8527 inited_type = LLVMArrayType (LLVMInt8Type (), module->max_inited_idx + 1);
8528 real_inited = LLVMAddGlobal (module->lmodule, inited_type, "mono_inited");
8529 LLVMSetInitializer (real_inited, LLVMConstNull (inited_type));
8530 LLVMSetLinkage (real_inited, LLVMInternalLinkage);
8531 mono_llvm_replace_uses_of (module->inited_var, real_inited);
8532 LLVMDeleteGlobal (module->inited_var);
8535 if (module->llvm_only) {
8536 emit_get_method (&aot_module);
8537 emit_get_unbox_tramp (&aot_module);
8540 emit_llvm_used (&aot_module);
8541 emit_dbg_info (&aot_module, filename, cu_name);
8542 emit_aot_file_info (&aot_module);
8545 * Replace GOT entries for directly callable methods with the methods themselves.
8546 * It would be easier to implement this by predefining all methods before compiling
8547 * their bodies, but that couldn't handle the case when a method fails to compile
8550 if (module->llvm_only) {
8551 GHashTableIter iter;
8553 GSList *callers, *l;
8555 g_hash_table_iter_init (&iter, module->method_to_callers);
8556 while (g_hash_table_iter_next (&iter, (void**)&method, (void**)&callers)) {
8557 LLVMValueRef lmethod;
8559 lmethod = (LLVMValueRef)g_hash_table_lookup (module->method_to_lmethod, method);
8561 for (l = callers; l; l = l->next) {
8562 LLVMValueRef caller = (LLVMValueRef)l->data;
8564 mono_llvm_replace_uses_of (caller, lmethod);
8570 /* Replace PLT entries for directly callable methods with the methods themselves */
8572 GHashTableIter iter;
8574 LLVMValueRef callee;
8576 g_hash_table_iter_init (&iter, module->plt_entries_ji);
8577 while (g_hash_table_iter_next (&iter, (void**)&ji, (void**)&callee)) {
8578 if (mono_aot_is_direct_callable (ji)) {
8579 LLVMValueRef lmethod;
8581 lmethod = (LLVMValueRef)g_hash_table_lookup (module->method_to_lmethod, ji->data.method);
8582 /* The types might not match because the caller might pass an rgctx */
8583 if (lmethod && LLVMTypeOf (callee) == LLVMTypeOf (lmethod)) {
8584 mono_llvm_replace_uses_of (callee, lmethod);
8585 mono_aot_mark_unused_llvm_plt_entry (ji);
8595 if (LLVMVerifyModule (module->lmodule, LLVMReturnStatusAction, &verifier_err)) {
8596 g_assert_not_reached ();
8601 LLVMWriteBitcodeToFile (module->lmodule, filename);
8606 md_string (const char *s)
8608 return LLVMMDString (s, strlen (s));
8611 /* Debugging support */
8614 emit_dbg_info (MonoLLVMModule *module, const char *filename, const char *cu_name)
8616 LLVMModuleRef lmodule = module->lmodule;
8617 LLVMValueRef args [16], ver;
8620 * This can only be enabled when LLVM code is emitted into a separate object
8621 * file, since the AOT compiler also emits dwarf info,
8622 * and the abbrev indexes will not be correct since llvm has added its own
8625 if (!module->emit_dwarf)
8628 #if LLVM_API_VERSION > 100
8629 mono_llvm_di_builder_finalize (module->di_builder);
8631 LLVMValueRef cu_args [16], cu;
8633 char *build_info, *s, *dir;
8636 * Emit dwarf info in the form of LLVM metadata. There is some
8637 * out-of-date documentation at:
8638 * http://llvm.org/docs/SourceLevelDebugging.html
8639 * but most of this was gathered from the llvm and
8644 cu_args [n_cuargs ++] = LLVMConstInt (LLVMInt32Type (), DW_TAG_compile_unit, FALSE);
8645 /* CU name/compilation dir */
8646 dir = g_path_get_dirname (filename);
8647 args [0] = LLVMMDString (cu_name, strlen (cu_name));
8648 args [1] = LLVMMDString (dir, strlen (dir));
8649 cu_args [n_cuargs ++] = LLVMMDNode (args, 2);
8652 cu_args [n_cuargs ++] = LLVMConstInt (LLVMInt32Type (), DW_LANG_C99, FALSE);
8654 build_info = mono_get_runtime_build_info ();
8655 s = g_strdup_printf ("Mono AOT Compiler %s (LLVM)", build_info);
8656 cu_args [n_cuargs ++] = LLVMMDString (s, strlen (s));
8657 g_free (build_info);
8659 cu_args [n_cuargs ++] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
8661 cu_args [n_cuargs ++] = LLVMMDString ("", strlen (""));
8662 /* Runtime version */
8663 cu_args [n_cuargs ++] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
8665 cu_args [n_cuargs ++] = LLVMMDNode (args, 0);
8666 cu_args [n_cuargs ++] = LLVMMDNode (args, 0);
8668 if (module->subprogram_mds) {
8672 mds = g_new0 (LLVMValueRef, module->subprogram_mds->len);
8673 for (i = 0; i < module->subprogram_mds->len; ++i)
8674 mds [i] = (LLVMValueRef)g_ptr_array_index (module->subprogram_mds, i);
8675 cu_args [n_cuargs ++] = LLVMMDNode (mds, module->subprogram_mds->len);
8677 cu_args [n_cuargs ++] = LLVMMDNode (args, 0);
8680 cu_args [n_cuargs ++] = LLVMMDNode (args, 0);
8681 /* Imported modules */
8682 cu_args [n_cuargs ++] = LLVMMDNode (args, 0);
8684 cu_args [n_cuargs ++] = LLVMMDString ("", strlen (""));
8685 /* DebugEmissionKind = FullDebug */
8686 cu_args [n_cuargs ++] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
8687 cu = LLVMMDNode (cu_args, n_cuargs);
8688 LLVMAddNamedMetadataOperand (lmodule, "llvm.dbg.cu", cu);
8691 #if LLVM_API_VERSION > 100
8692 args [0] = LLVMConstInt (LLVMInt32Type (), 2, FALSE);
8693 args [1] = LLVMMDString ("Dwarf Version", strlen ("Dwarf Version"));
8694 args [2] = LLVMConstInt (LLVMInt32Type (), 2, FALSE);
8695 ver = LLVMMDNode (args, 3);
8696 LLVMAddNamedMetadataOperand (lmodule, "llvm.module.flags", ver);
8698 args [0] = LLVMConstInt (LLVMInt32Type (), 2, FALSE);
8699 args [1] = LLVMMDString ("Debug Info Version", strlen ("Debug Info Version"));
8700 args [2] = LLVMConstInt (LLVMInt64Type (), 3, FALSE);
8701 ver = LLVMMDNode (args, 3);
8702 LLVMAddNamedMetadataOperand (lmodule, "llvm.module.flags", ver);
8704 args [0] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
8705 args [1] = LLVMMDString ("Dwarf Version", strlen ("Dwarf Version"));
8706 args [2] = LLVMConstInt (LLVMInt32Type (), 2, FALSE);
8707 ver = LLVMMDNode (args, 3);
8708 LLVMAddNamedMetadataOperand (lmodule, "llvm.module.flags", ver);
8710 args [0] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
8711 args [1] = LLVMMDString ("Debug Info Version", strlen ("Debug Info Version"));
8712 args [2] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
8713 ver = LLVMMDNode (args, 3);
8714 LLVMAddNamedMetadataOperand (lmodule, "llvm.module.flags", ver);
8719 emit_dbg_subprogram (EmitContext *ctx, MonoCompile *cfg, LLVMValueRef method, const char *name)
8721 MonoLLVMModule *module = ctx->module;
8722 MonoDebugMethodInfo *minfo = ctx->minfo;
8723 char *source_file, *dir, *filename;
8724 LLVMValueRef md, args [16], ctx_args [16], md_args [64], type_args [16], ctx_md, type_md;
8725 MonoSymSeqPoint *sym_seq_points;
8731 mono_debug_symfile_get_seq_points (minfo, &source_file, NULL, NULL, &sym_seq_points, &n_seq_points);
8733 source_file = g_strdup ("<unknown>");
8734 dir = g_path_get_dirname (source_file);
8735 filename = g_path_get_basename (source_file);
8737 #if LLVM_API_VERSION > 100
8738 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);
8741 ctx_args [0] = LLVMConstInt (LLVMInt32Type (), 0x29, FALSE);
8742 args [0] = md_string (filename);
8743 args [1] = md_string (dir);
8744 ctx_args [1] = LLVMMDNode (args, 2);
8745 ctx_md = LLVMMDNode (ctx_args, 2);
8747 type_args [0] = LLVMConstInt (LLVMInt32Type (), DW_TAG_subroutine_type, FALSE);
8748 type_args [1] = NULL;
8749 type_args [2] = NULL;
8750 type_args [3] = LLVMMDString ("", 0);
8751 type_args [4] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
8752 type_args [5] = LLVMConstInt (LLVMInt64Type (), 0, FALSE);
8753 type_args [6] = LLVMConstInt (LLVMInt64Type (), 0, FALSE);
8754 type_args [7] = LLVMConstInt (LLVMInt64Type (), 0, FALSE);
8755 type_args [8] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
8756 type_args [9] = NULL;
8757 type_args [10] = NULL;
8758 type_args [11] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
8759 type_args [12] = NULL;
8760 type_args [13] = NULL;
8761 type_args [14] = NULL;
8762 type_md = LLVMMDNode (type_args, 14);
8764 /* http://llvm.org/docs/SourceLevelDebugging.html#subprogram-descriptors */
8765 md_args [0] = LLVMConstInt (LLVMInt32Type (), DW_TAG_subprogram, FALSE);
8766 /* Source directory + file pair */
8767 args [0] = md_string (filename);
8768 args [1] = md_string (dir);
8769 md_args [1] = LLVMMDNode (args ,2);
8770 md_args [2] = ctx_md;
8771 md_args [3] = md_string (cfg->method->name);
8772 md_args [4] = md_string (name);
8773 md_args [5] = md_string (name);
8776 md_args [6] = LLVMConstInt (LLVMInt32Type (), sym_seq_points [0].line, FALSE);
8778 md_args [6] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
8780 md_args [7] = type_md;
8782 md_args [8] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
8784 md_args [9] = LLVMConstInt (LLVMInt1Type (), 1, FALSE);
8786 md_args [10] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
8787 /* Index into a virtual function */
8788 md_args [11] = NULL;
8789 md_args [12] = NULL;
8791 md_args [13] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
8793 md_args [14] = LLVMConstInt (LLVMInt1Type (), 1, FALSE);
8794 /* Pointer to LLVM function */
8795 md_args [15] = method;
8796 /* Function template parameter */
8797 md_args [16] = NULL;
8798 /* Function declaration descriptor */
8799 md_args [17] = NULL;
8800 /* List of function variables */
8801 md_args [18] = LLVMMDNode (args, 0);
8803 md_args [19] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
8804 md = LLVMMDNode (md_args, 20);
8806 if (!module->subprogram_mds)
8807 module->subprogram_mds = g_ptr_array_new ();
8808 g_ptr_array_add (module->subprogram_mds, md);
8812 g_free (source_file);
8813 g_free (sym_seq_points);
8819 emit_dbg_loc (EmitContext *ctx, LLVMBuilderRef builder, const unsigned char *cil_code)
8821 MonoCompile *cfg = ctx->cfg;
8823 if (ctx->minfo && cil_code && cil_code >= cfg->header->code && cil_code < cfg->header->code + cfg->header->code_size) {
8824 MonoDebugSourceLocation *loc;
8825 LLVMValueRef loc_md;
8827 loc = mono_debug_symfile_lookup_location (ctx->minfo, cil_code - cfg->header->code);
8830 #if LLVM_API_VERSION > 100
8831 loc_md = mono_llvm_di_create_location (ctx->module->di_builder, ctx->dbg_md, loc->row, loc->column);
8832 mono_llvm_di_set_location (builder, loc_md);
8834 LLVMValueRef md_args [16];
8838 md_args [nmd_args ++] = LLVMConstInt (LLVMInt32Type (), loc->row, FALSE);
8839 md_args [nmd_args ++] = LLVMConstInt (LLVMInt32Type (), loc->column, FALSE);
8840 md_args [nmd_args ++] = ctx->dbg_md;
8841 md_args [nmd_args ++] = NULL;
8842 loc_md = LLVMMDNode (md_args, nmd_args);
8843 LLVMSetCurrentDebugLocation (builder, loc_md);
8845 mono_debug_symfile_free_location (loc);
8851 default_mono_llvm_unhandled_exception (void)
8853 MonoJitTlsData *jit_tls = mono_get_jit_tls ();
8854 MonoObject *target = mono_gchandle_get_target (jit_tls->thrown_exc);
8856 mono_unhandled_exception (target);
8857 exit (mono_environment_exitcode_get ());
8862 - Emit LLVM IR from the mono IR using the LLVM C API.
8863 - The original arch specific code remains, so we can fall back to it if we run
8864 into something we can't handle.
8868 A partial list of issues:
8869 - Handling of opcodes which can throw exceptions.
8871 In the mono JIT, these are implemented using code like this:
8878 push throw_pos - method
8879 call <exception trampoline>
8881 The problematic part is push throw_pos - method, which cannot be represented
8882 in the LLVM IR, since it does not support label values.
8883 -> this can be implemented in AOT mode using inline asm + labels, but cannot
8884 be implemented in JIT mode ?
8885 -> a possible but slower implementation would use the normal exception
8886 throwing code but it would need to control the placement of the throw code
8887 (it needs to be exactly after the compare+branch).
8888 -> perhaps add a PC offset intrinsics ?
8890 - efficient implementation of .ovf opcodes.
8892 These are currently implemented as:
8893 <ins which sets the condition codes>
8896 Some overflow opcodes are now supported by LLVM SVN.
8898 - exception handling, unwinding.
8899 - SSA is disabled for methods with exception handlers
8900 - How to obtain unwind info for LLVM compiled methods ?
8901 -> this is now solved by converting the unwind info generated by LLVM
8903 - LLVM uses the c++ exception handling framework, while we use our home grown
8904 code, and couldn't use the c++ one:
8905 - its not supported under VC++, other exotic platforms.
8906 - it might be impossible to support filter clauses with it.
8910 The trampolines need a predictable call sequence, since they need to disasm
8911 the calling code to obtain register numbers / offsets.
8913 LLVM currently generates this code in non-JIT mode:
8914 mov -0x98(%rax),%eax
8916 Here, the vtable pointer is lost.
8917 -> solution: use one vtable trampoline per class.
8919 - passing/receiving the IMT pointer/RGCTX.
8920 -> solution: pass them as normal arguments ?
8924 LLVM does not allow the specification of argument registers etc. This means
8925 that all calls are made according to the platform ABI.
8927 - passing/receiving vtypes.
8929 Vtypes passed/received in registers are handled by the front end by using
8930 a signature with scalar arguments, and loading the parts of the vtype into those
8933 Vtypes passed on the stack are handled using the 'byval' attribute.
8937 Supported though alloca, we need to emit the load/store code.
8941 The mono JIT uses pointer sized iregs/double fregs, while LLVM uses precisely
8942 typed registers, so we have to keep track of the precise LLVM type of each vreg.
8943 This is made easier because the IR is already in SSA form.
8944 An additional problem is that our IR is not consistent with types, i.e. i32/ia64
8945 types are frequently used incorrectly.
8950 Emit LLVM bytecode into a .bc file, compile it using llc into a .s file, then link
8951 it with the file containing the methods emitted by the JIT and the AOT data
8955 /* FIXME: Normalize some aspects of the mono IR to allow easier translation, like:
8956 * - each bblock should end with a branch
8957 * - setting the return value, making cfg->ret non-volatile
8958 * - avoid some transformations in the JIT which make it harder for us to generate
8960 * - use pointer types to help optimizations.