2 * mini-llvm.c: llvm "Backend" for the mono JIT
4 * Copyright 2009-2011 Novell Inc (http://www.novell.com)
5 * Copyright 2011 Xamarin Inc (http://www.xamarin.com)
6 * Licensed under the MIT license. See LICENSE file in the project root for full license information.
10 #include <mono/metadata/debug-helpers.h>
11 #include <mono/metadata/debug-mono-symfile.h>
12 #include <mono/metadata/mempool-internals.h>
13 #include <mono/metadata/environment.h>
14 #include <mono/metadata/object-internals.h>
15 #include <mono/metadata/abi-details.h>
16 #include <mono/utils/mono-tls.h>
17 #include <mono/utils/mono-dl.h>
18 #include <mono/utils/mono-time.h>
19 #include <mono/utils/freebsd-dwarf.h>
21 #ifndef __STDC_LIMIT_MACROS
22 #define __STDC_LIMIT_MACROS
24 #ifndef __STDC_CONSTANT_MACROS
25 #define __STDC_CONSTANT_MACROS
28 #include "llvm-c/BitWriter.h"
29 #include "llvm-c/Analysis.h"
31 #include "mini-llvm-cpp.h"
33 #include "aot-compiler.h"
34 #include "mini-llvm.h"
39 extern void *memset(void *, int, size_t);
40 void bzero (void *to, size_t count) { memset (to, 0, count); }
44 #if LLVM_API_VERSION < 4
45 #error "The version of the mono llvm repository is too old."
48 #define ALIGN_PTR_TO(ptr,align) (gpointer)((((gssize)(ptr)) + (align - 1)) & (~(align - 1)))
51 * Information associated by mono with LLVM modules.
54 LLVMModuleRef lmodule;
55 LLVMValueRef throw_icall, rethrow, match_exc, throw_corlib_exception, resume_eh;
56 GHashTable *llvm_types;
58 const char *got_symbol;
59 const char *get_method_symbol;
60 const char *get_unbox_tramp_symbol;
61 GHashTable *plt_entries;
62 GHashTable *plt_entries_ji;
63 GHashTable *method_to_lmethod;
64 GHashTable *direct_callables;
69 GPtrArray *subprogram_mds;
71 LLVMExecutionEngineRef ee;
72 gboolean external_symbols;
77 MonoAssembly *assembly;
79 MonoAotFileInfo aot_info;
80 const char *jit_got_symbol;
81 const char *eh_frame_symbol;
82 LLVMValueRef get_method, get_unbox_tramp;
83 LLVMValueRef init_method, init_method_gshared_mrgctx, init_method_gshared_this, init_method_gshared_vtable;
84 LLVMValueRef code_start, code_end;
85 LLVMValueRef inited_var;
86 int max_inited_idx, max_method_idx;
87 gboolean has_jitted_code;
90 GHashTable *idx_to_lmethod;
91 GHashTable *idx_to_unbox_tramp;
92 /* Maps a MonoMethod to LLVM instructions representing it */
93 GHashTable *method_to_callers;
94 LLVMContextRef context;
95 LLVMValueRef sentinel_exception;
96 void *di_builder, *cu;
100 * Information associated by the backend with mono basic blocks.
103 LLVMBasicBlockRef bblock, end_bblock;
104 LLVMValueRef finally_ind;
105 gboolean added, invoke_target;
107 * If this bblock is the start of a finally clause, this is a list of bblocks it
108 * needs to branch to in ENDFINALLY.
110 GSList *call_handler_return_bbs;
112 * If this bblock is the start of a finally clause, this is the bblock that
113 * CALL_HANDLER needs to branch to.
115 LLVMBasicBlockRef call_handler_target_bb;
116 /* The list of switch statements generated by ENDFINALLY instructions */
117 GSList *endfinally_switch_ins_list;
122 * Structure containing emit state
125 MonoMemPool *mempool;
127 /* Maps method names to the corresponding LLVMValueRef */
128 GHashTable *emitted_method_decls;
131 LLVMValueRef lmethod;
132 MonoLLVMModule *module;
133 LLVMModuleRef lmodule;
135 int sindex, default_index, ex_index;
136 LLVMBuilderRef builder;
137 LLVMValueRef *values, *addresses;
138 MonoType **vreg_cli_types;
140 MonoMethodSignature *sig;
142 GHashTable *region_to_handler;
143 GHashTable *clause_to_handler;
144 LLVMBuilderRef alloca_builder;
145 LLVMValueRef last_alloca;
146 LLVMValueRef rgctx_arg;
147 LLVMValueRef this_arg;
148 LLVMTypeRef *vreg_types;
149 LLVMTypeRef method_type;
150 LLVMBasicBlockRef init_bb, inited_bb;
152 gboolean *unreachable;
154 gboolean has_got_access;
155 gboolean is_linkonce;
156 int this_arg_pindex, rgctx_arg_pindex;
157 LLVMValueRef imt_rgctx_loc;
158 GHashTable *llvm_types;
160 MonoDebugMethodInfo *minfo;
162 /* For every clause, the clauses it is nested in */
165 GHashTable *exc_meta;
166 GHashTable *method_to_callers;
167 GPtrArray *phi_values;
168 GPtrArray *bblock_list;
170 GHashTable *jit_callees;
176 MonoBasicBlock *in_bb;
181 * Instruction metadata
182 * This is the same as ins_info, but LREG != IREG.
190 #define MINI_OP(a,b,dest,src1,src2) dest, src1, src2, ' ',
191 #define MINI_OP3(a,b,dest,src1,src2,src3) dest, src1, src2, src3,
198 /* keep in sync with the enum in mini.h */
201 #include "mini-ops.h"
206 #if SIZEOF_VOID_P == 4
207 #define GET_LONG_IMM(ins) (((guint64)(ins)->inst_ms_word << 32) | (guint64)(guint32)(ins)->inst_ls_word)
209 #define GET_LONG_IMM(ins) ((ins)->inst_imm)
212 #define LLVM_INS_INFO(opcode) (&llvm_ins_info [((opcode) - OP_START - 1) * 4])
215 #define TRACE_FAILURE(msg) do { printf ("%s\n", msg); } while (0)
217 #define TRACE_FAILURE(msg)
221 #define IS_TARGET_X86 1
223 #define IS_TARGET_X86 0
227 #define IS_TARGET_AMD64 1
229 #define IS_TARGET_AMD64 0
232 #define ctx_ok(ctx) (!(ctx)->cfg->disable_llvm)
234 static LLVMIntPredicate cond_to_llvm_cond [] = {
247 static LLVMRealPredicate fpcond_to_llvm_cond [] = {
260 static MonoNativeTlsKey current_cfg_tls_id;
262 static MonoLLVMModule aot_module;
264 static GHashTable *intrins_id_to_name;
265 static GHashTable *intrins_name_to_id;
267 static void init_jit_module (MonoDomain *domain);
269 static void emit_dbg_loc (EmitContext *ctx, LLVMBuilderRef builder, const unsigned char *cil_code);
270 static LLVMValueRef emit_dbg_subprogram (EmitContext *ctx, MonoCompile *cfg, LLVMValueRef method, const char *name);
271 static void emit_dbg_info (MonoLLVMModule *module, const char *filename, const char *cu_name);
272 static void emit_cond_system_exception (EmitContext *ctx, MonoBasicBlock *bb, const char *exc_type, LLVMValueRef cmp);
273 static LLVMValueRef get_intrinsic (EmitContext *ctx, const char *name);
274 static void decode_llvm_eh_info (EmitContext *ctx, gpointer eh_frame);
277 set_failure (EmitContext *ctx, const char *message)
279 TRACE_FAILURE (reason);
280 ctx->cfg->exception_message = g_strdup (message);
281 ctx->cfg->disable_llvm = TRUE;
287 * The LLVM type with width == sizeof (gpointer)
292 return sizeof (gpointer) == 8 ? LLVMInt64Type () : LLVMInt32Type ();
298 return sizeof (gpointer) == 8 ? LLVMPointerType (LLVMInt64Type (), 0) : LLVMPointerType (LLVMInt32Type (), 0);
304 return sizeof (gpointer) == 8 ? LLVMPointerType (LLVMInt64Type (), 0) : LLVMPointerType (LLVMInt32Type (), 0);
310 * Return the size of the LLVM representation of the vtype T.
313 get_vtype_size (MonoType *t)
317 size = mono_class_value_size (mono_class_from_mono_type (t), NULL);
319 /* LLVMArgAsIArgs depends on this since it stores whole words */
320 while (size < 2 * sizeof (gpointer) && mono_is_power_of_two (size) == -1)
327 * simd_class_to_llvm_type:
329 * Return the LLVM type corresponding to the Mono.SIMD class KLASS
332 simd_class_to_llvm_type (EmitContext *ctx, MonoClass *klass)
334 if (!strcmp (klass->name, "Vector2d")) {
335 return LLVMVectorType (LLVMDoubleType (), 2);
336 } else if (!strcmp (klass->name, "Vector2l")) {
337 return LLVMVectorType (LLVMInt64Type (), 2);
338 } else if (!strcmp (klass->name, "Vector2ul")) {
339 return LLVMVectorType (LLVMInt64Type (), 2);
340 } else if (!strcmp (klass->name, "Vector4i")) {
341 return LLVMVectorType (LLVMInt32Type (), 4);
342 } else if (!strcmp (klass->name, "Vector4ui")) {
343 return LLVMVectorType (LLVMInt32Type (), 4);
344 } else if (!strcmp (klass->name, "Vector4f")) {
345 return LLVMVectorType (LLVMFloatType (), 4);
346 } else if (!strcmp (klass->name, "Vector8s")) {
347 return LLVMVectorType (LLVMInt16Type (), 8);
348 } else if (!strcmp (klass->name, "Vector8us")) {
349 return LLVMVectorType (LLVMInt16Type (), 8);
350 } else if (!strcmp (klass->name, "Vector16sb")) {
351 return LLVMVectorType (LLVMInt8Type (), 16);
352 } else if (!strcmp (klass->name, "Vector16b")) {
353 return LLVMVectorType (LLVMInt8Type (), 16);
355 printf ("%s\n", klass->name);
361 /* Return the 128 bit SIMD type corresponding to the mono type TYPE */
362 static inline G_GNUC_UNUSED LLVMTypeRef
363 type_to_simd_type (int type)
367 return LLVMVectorType (LLVMInt8Type (), 16);
369 return LLVMVectorType (LLVMInt16Type (), 8);
371 return LLVMVectorType (LLVMInt32Type (), 4);
373 return LLVMVectorType (LLVMInt64Type (), 2);
375 return LLVMVectorType (LLVMDoubleType (), 2);
377 return LLVMVectorType (LLVMFloatType (), 4);
379 g_assert_not_reached ();
385 create_llvm_type_for_type (MonoLLVMModule *module, MonoClass *klass)
387 int i, size, nfields, esize;
388 LLVMTypeRef *eltypes;
393 t = &klass->byval_arg;
395 if (mini_type_is_hfa (t, &nfields, &esize)) {
397 * This is needed on arm64 where HFAs are returned in
401 eltypes = g_new (LLVMTypeRef, size);
402 for (i = 0; i < size; ++i)
403 eltypes [i] = esize == 4 ? LLVMFloatType () : LLVMDoubleType ();
405 size = get_vtype_size (t);
407 eltypes = g_new (LLVMTypeRef, size);
408 for (i = 0; i < size; ++i)
409 eltypes [i] = LLVMInt8Type ();
412 name = mono_type_full_name (&klass->byval_arg);
413 ltype = LLVMStructCreateNamed (module->context, name);
414 LLVMStructSetBody (ltype, eltypes, size, FALSE);
424 * Return the LLVM type corresponding to T.
427 type_to_llvm_type (EmitContext *ctx, MonoType *t)
429 t = mini_get_underlying_type (t);
433 return LLVMVoidType ();
435 return LLVMInt8Type ();
437 return LLVMInt16Type ();
439 return LLVMInt32Type ();
441 return LLVMInt8Type ();
443 return LLVMInt16Type ();
445 return LLVMInt32Type ();
446 case MONO_TYPE_BOOLEAN:
447 return LLVMInt8Type ();
450 return LLVMInt64Type ();
452 return LLVMInt16Type ();
454 return LLVMFloatType ();
456 return LLVMDoubleType ();
459 return IntPtrType ();
460 case MONO_TYPE_OBJECT:
461 case MONO_TYPE_CLASS:
462 case MONO_TYPE_ARRAY:
463 case MONO_TYPE_SZARRAY:
464 case MONO_TYPE_STRING:
466 return ObjRefType ();
469 /* Because of generic sharing */
470 return ObjRefType ();
471 case MONO_TYPE_GENERICINST:
472 if (!mono_type_generic_inst_is_valuetype (t))
473 return ObjRefType ();
475 case MONO_TYPE_VALUETYPE:
476 case MONO_TYPE_TYPEDBYREF: {
480 klass = mono_class_from_mono_type (t);
482 if (MONO_CLASS_IS_SIMD (ctx->cfg, klass))
483 return simd_class_to_llvm_type (ctx, klass);
486 return type_to_llvm_type (ctx, mono_class_enum_basetype (klass));
488 ltype = (LLVMTypeRef)g_hash_table_lookup (ctx->module->llvm_types, klass);
490 ltype = create_llvm_type_for_type (ctx->module, klass);
491 g_hash_table_insert (ctx->module->llvm_types, klass, ltype);
497 printf ("X: %d\n", t->type);
498 ctx->cfg->exception_message = g_strdup_printf ("type %s", mono_type_full_name (t));
499 ctx->cfg->disable_llvm = TRUE;
507 * Return whenever T is an unsigned int type.
510 type_is_unsigned (EmitContext *ctx, MonoType *t)
512 t = mini_get_underlying_type (t);
528 * type_to_llvm_arg_type:
530 * Same as type_to_llvm_type, but treat i8/i16 as i32.
533 type_to_llvm_arg_type (EmitContext *ctx, MonoType *t)
535 LLVMTypeRef ptype = type_to_llvm_type (ctx, t);
537 if (ctx->cfg->llvm_only)
541 * This works on all abis except arm64/ios which passes multiple
542 * arguments in one stack slot.
545 if (ptype == LLVMInt8Type () || ptype == LLVMInt16Type ()) {
547 * LLVM generates code which only sets the lower bits, while JITted
548 * code expects all the bits to be set.
550 ptype = LLVMInt32Type ();
558 * llvm_type_to_stack_type:
560 * Return the LLVM type which needs to be used when a value of type TYPE is pushed
563 static G_GNUC_UNUSED LLVMTypeRef
564 llvm_type_to_stack_type (MonoCompile *cfg, LLVMTypeRef type)
568 if (type == LLVMInt8Type ())
569 return LLVMInt32Type ();
570 else if (type == LLVMInt16Type ())
571 return LLVMInt32Type ();
572 else if (!cfg->r4fp && type == LLVMFloatType ())
573 return LLVMDoubleType ();
579 * regtype_to_llvm_type:
581 * Return the LLVM type corresponding to the regtype C used in instruction
585 regtype_to_llvm_type (char c)
589 return LLVMInt32Type ();
591 return LLVMInt64Type ();
593 return LLVMDoubleType ();
602 * Return the LLVM type corresponding to the unary/binary opcode OPCODE.
605 op_to_llvm_type (int opcode)
610 return LLVMInt8Type ();
613 return LLVMInt8Type ();
616 return LLVMInt16Type ();
619 return LLVMInt16Type ();
622 return LLVMInt32Type ();
625 return LLVMInt32Type ();
627 return LLVMInt64Type ();
629 return LLVMFloatType ();
631 return LLVMDoubleType ();
633 return LLVMInt64Type ();
635 return LLVMInt32Type ();
637 return LLVMInt64Type ();
642 return LLVMInt8Type ();
647 return LLVMInt16Type ();
649 return LLVMInt32Type ();
652 return sizeof (gpointer) == 8 ? LLVMInt64Type () : LLVMInt32Type ();
659 return LLVMInt32Type ();
666 return LLVMInt64Type ();
668 printf ("%s\n", mono_inst_name (opcode));
669 g_assert_not_reached ();
674 #define CLAUSE_START(clause) ((clause)->try_offset)
675 #define CLAUSE_END(clause) (((clause))->try_offset + ((clause))->try_len)
678 * load_store_to_llvm_type:
680 * Return the size/sign/zero extension corresponding to the load/store opcode
684 load_store_to_llvm_type (int opcode, int *size, gboolean *sext, gboolean *zext)
690 case OP_LOADI1_MEMBASE:
691 case OP_STOREI1_MEMBASE_REG:
692 case OP_STOREI1_MEMBASE_IMM:
693 case OP_ATOMIC_LOAD_I1:
694 case OP_ATOMIC_STORE_I1:
697 return LLVMInt8Type ();
698 case OP_LOADU1_MEMBASE:
700 case OP_ATOMIC_LOAD_U1:
701 case OP_ATOMIC_STORE_U1:
704 return LLVMInt8Type ();
705 case OP_LOADI2_MEMBASE:
706 case OP_STOREI2_MEMBASE_REG:
707 case OP_STOREI2_MEMBASE_IMM:
708 case OP_ATOMIC_LOAD_I2:
709 case OP_ATOMIC_STORE_I2:
712 return LLVMInt16Type ();
713 case OP_LOADU2_MEMBASE:
715 case OP_ATOMIC_LOAD_U2:
716 case OP_ATOMIC_STORE_U2:
719 return LLVMInt16Type ();
720 case OP_LOADI4_MEMBASE:
721 case OP_LOADU4_MEMBASE:
724 case OP_STOREI4_MEMBASE_REG:
725 case OP_STOREI4_MEMBASE_IMM:
726 case OP_ATOMIC_LOAD_I4:
727 case OP_ATOMIC_STORE_I4:
728 case OP_ATOMIC_LOAD_U4:
729 case OP_ATOMIC_STORE_U4:
731 return LLVMInt32Type ();
732 case OP_LOADI8_MEMBASE:
734 case OP_STOREI8_MEMBASE_REG:
735 case OP_STOREI8_MEMBASE_IMM:
736 case OP_ATOMIC_LOAD_I8:
737 case OP_ATOMIC_STORE_I8:
738 case OP_ATOMIC_LOAD_U8:
739 case OP_ATOMIC_STORE_U8:
741 return LLVMInt64Type ();
742 case OP_LOADR4_MEMBASE:
743 case OP_STORER4_MEMBASE_REG:
744 case OP_ATOMIC_LOAD_R4:
745 case OP_ATOMIC_STORE_R4:
747 return LLVMFloatType ();
748 case OP_LOADR8_MEMBASE:
749 case OP_STORER8_MEMBASE_REG:
750 case OP_ATOMIC_LOAD_R8:
751 case OP_ATOMIC_STORE_R8:
753 return LLVMDoubleType ();
754 case OP_LOAD_MEMBASE:
756 case OP_STORE_MEMBASE_REG:
757 case OP_STORE_MEMBASE_IMM:
758 *size = sizeof (gpointer);
759 return IntPtrType ();
761 g_assert_not_reached ();
769 * Return the LLVM intrinsics corresponding to the overflow opcode OPCODE.
772 ovf_op_to_intrins (int opcode)
776 return "llvm.sadd.with.overflow.i32";
778 return "llvm.uadd.with.overflow.i32";
780 return "llvm.ssub.with.overflow.i32";
782 return "llvm.usub.with.overflow.i32";
784 return "llvm.smul.with.overflow.i32";
786 return "llvm.umul.with.overflow.i32";
788 return "llvm.sadd.with.overflow.i64";
790 return "llvm.uadd.with.overflow.i64";
792 return "llvm.ssub.with.overflow.i64";
794 return "llvm.usub.with.overflow.i64";
796 return "llvm.smul.with.overflow.i64";
798 return "llvm.umul.with.overflow.i64";
800 g_assert_not_reached ();
806 simd_op_to_intrins (int opcode)
809 #if defined(TARGET_X86) || defined(TARGET_AMD64)
811 return "llvm.x86.sse2.min.pd";
813 return "llvm.x86.sse.min.ps";
815 return "llvm.x86.sse41.pminud";
817 return "llvm.x86.sse41.pminuw";
819 return "llvm.x86.sse2.pminu.b";
821 return "llvm.x86.sse2.pmins.w";
823 return "llvm.x86.sse2.max.pd";
825 return "llvm.x86.sse.max.ps";
827 return "llvm.x86.sse3.hadd.pd";
829 return "llvm.x86.sse3.hadd.ps";
831 return "llvm.x86.sse3.hsub.pd";
833 return "llvm.x86.sse3.hsub.ps";
835 return "llvm.x86.sse41.pmaxud";
837 return "llvm.x86.sse41.pmaxuw";
839 return "llvm.x86.sse2.pmaxu.b";
841 return "llvm.x86.sse3.addsub.ps";
843 return "llvm.x86.sse3.addsub.pd";
844 case OP_EXTRACT_MASK:
845 return "llvm.x86.sse2.pmovmskb.128";
848 return "llvm.x86.sse2.psrli.w";
851 return "llvm.x86.sse2.psrli.d";
854 return "llvm.x86.sse2.psrli.q";
857 return "llvm.x86.sse2.pslli.w";
860 return "llvm.x86.sse2.pslli.d";
863 return "llvm.x86.sse2.pslli.q";
866 return "llvm.x86.sse2.psrai.w";
869 return "llvm.x86.sse2.psrai.d";
871 return "llvm.x86.sse2.padds.b";
873 return "llvm.x86.sse2.padds.w";
875 return "llvm.x86.sse2.psubs.b";
877 return "llvm.x86.sse2.psubs.w";
878 case OP_PADDB_SAT_UN:
879 return "llvm.x86.sse2.paddus.b";
880 case OP_PADDW_SAT_UN:
881 return "llvm.x86.sse2.paddus.w";
882 case OP_PSUBB_SAT_UN:
883 return "llvm.x86.sse2.psubus.b";
884 case OP_PSUBW_SAT_UN:
885 return "llvm.x86.sse2.psubus.w";
887 return "llvm.x86.sse2.pavg.b";
889 return "llvm.x86.sse2.pavg.w";
891 return "llvm.x86.sse.sqrt.ps";
893 return "llvm.x86.sse2.sqrt.pd";
895 return "llvm.x86.sse.rsqrt.ps";
897 return "llvm.x86.sse.rcp.ps";
899 return "llvm.x86.sse2.cvtdq2pd";
901 return "llvm.x86.sse2.cvtdq2ps";
903 return "llvm.x86.sse2.cvtpd2dq";
905 return "llvm.x86.sse2.cvtps2dq";
907 return "llvm.x86.sse2.cvtpd2ps";
909 return "llvm.x86.sse2.cvtps2pd";
911 return "llvm.x86.sse2.cvttpd2dq";
913 return "llvm.x86.sse2.cvttps2dq";
915 return "llvm.x86.sse.cmp.ps";
917 return "llvm.x86.sse2.cmp.pd";
919 return "llvm.x86.sse2.packsswb.128";
921 return "llvm.x86.sse2.packssdw.128";
923 return "llvm.x86.sse2.packuswb.128";
925 return "llvm.x86.sse41.packusdw";
927 return "llvm.x86.sse2.pmulh.w";
928 case OP_PMULW_HIGH_UN:
929 return "llvm.x86.sse2.pmulhu.w";
932 g_assert_not_reached ();
938 simd_op_to_llvm_type (int opcode)
940 #if defined(TARGET_X86) || defined(TARGET_AMD64)
944 return type_to_simd_type (MONO_TYPE_R8);
947 return type_to_simd_type (MONO_TYPE_I8);
950 return type_to_simd_type (MONO_TYPE_I4);
955 return type_to_simd_type (MONO_TYPE_I2);
959 return type_to_simd_type (MONO_TYPE_I1);
961 return type_to_simd_type (MONO_TYPE_R4);
964 return type_to_simd_type (MONO_TYPE_I4);
968 return type_to_simd_type (MONO_TYPE_R8);
972 return type_to_simd_type (MONO_TYPE_R4);
973 case OP_EXTRACT_MASK:
974 return type_to_simd_type (MONO_TYPE_I1);
980 return type_to_simd_type (MONO_TYPE_R4);
983 return type_to_simd_type (MONO_TYPE_R8);
985 g_assert_not_reached ();
996 * Return the LLVM basic block corresponding to BB.
998 static LLVMBasicBlockRef
999 get_bb (EmitContext *ctx, MonoBasicBlock *bb)
1001 char bb_name_buf [128];
1004 if (ctx->bblocks [bb->block_num].bblock == NULL) {
1005 if (bb->flags & BB_EXCEPTION_HANDLER) {
1006 int clause_index = (mono_get_block_region_notry (ctx->cfg, bb->region) >> 8) - 1;
1007 sprintf (bb_name_buf, "EH_CLAUSE%d_BB%d", clause_index, bb->block_num);
1008 bb_name = bb_name_buf;
1009 } else if (bb->block_num < 256) {
1010 if (!ctx->module->bb_names) {
1011 ctx->module->bb_names_len = 256;
1012 ctx->module->bb_names = g_new0 (char*, ctx->module->bb_names_len);
1014 if (!ctx->module->bb_names [bb->block_num]) {
1017 n = g_strdup_printf ("BB%d", bb->block_num);
1018 mono_memory_barrier ();
1019 ctx->module->bb_names [bb->block_num] = n;
1021 bb_name = ctx->module->bb_names [bb->block_num];
1023 sprintf (bb_name_buf, "BB%d", bb->block_num);
1024 bb_name = bb_name_buf;
1027 ctx->bblocks [bb->block_num].bblock = LLVMAppendBasicBlock (ctx->lmethod, bb_name);
1028 ctx->bblocks [bb->block_num].end_bblock = ctx->bblocks [bb->block_num].bblock;
1031 return ctx->bblocks [bb->block_num].bblock;
1037 * Return the last LLVM bblock corresponding to BB.
1038 * This might not be equal to the bb returned by get_bb () since we need to generate
1039 * multiple LLVM bblocks for a mono bblock to handle throwing exceptions.
1041 static LLVMBasicBlockRef
1042 get_end_bb (EmitContext *ctx, MonoBasicBlock *bb)
1045 return ctx->bblocks [bb->block_num].end_bblock;
1048 static LLVMBasicBlockRef
1049 gen_bb (EmitContext *ctx, const char *prefix)
1053 sprintf (bb_name, "%s%d", prefix, ++ ctx->ex_index);
1054 return LLVMAppendBasicBlock (ctx->lmethod, bb_name);
1060 * Return the target of the patch identified by TYPE and TARGET.
1063 resolve_patch (MonoCompile *cfg, MonoJumpInfoType type, gconstpointer target)
1069 memset (&ji, 0, sizeof (ji));
1071 ji.data.target = target;
1073 res = mono_resolve_patch_target (cfg->method, cfg->domain, NULL, &ji, FALSE, &error);
1074 mono_error_assert_ok (&error);
1082 * Emit code to convert the LLVM value V to DTYPE.
1085 convert_full (EmitContext *ctx, LLVMValueRef v, LLVMTypeRef dtype, gboolean is_unsigned)
1087 LLVMTypeRef stype = LLVMTypeOf (v);
1089 if (stype != dtype) {
1090 gboolean ext = FALSE;
1093 if (dtype == LLVMInt64Type () && (stype == LLVMInt32Type () || stype == LLVMInt16Type () || stype == LLVMInt8Type ()))
1095 else if (dtype == LLVMInt32Type () && (stype == LLVMInt16Type () || stype == LLVMInt8Type ()))
1097 else if (dtype == LLVMInt16Type () && (stype == LLVMInt8Type ()))
1101 return is_unsigned ? LLVMBuildZExt (ctx->builder, v, dtype, "") : LLVMBuildSExt (ctx->builder, v, dtype, "");
1103 if (dtype == LLVMDoubleType () && stype == LLVMFloatType ())
1104 return LLVMBuildFPExt (ctx->builder, v, dtype, "");
1107 if (stype == LLVMInt64Type () && (dtype == LLVMInt32Type () || dtype == LLVMInt16Type () || dtype == LLVMInt8Type ()))
1108 return LLVMBuildTrunc (ctx->builder, v, dtype, "");
1109 if (stype == LLVMInt32Type () && (dtype == LLVMInt16Type () || dtype == LLVMInt8Type ()))
1110 return LLVMBuildTrunc (ctx->builder, v, dtype, "");
1111 if (stype == LLVMInt16Type () && dtype == LLVMInt8Type ())
1112 return LLVMBuildTrunc (ctx->builder, v, dtype, "");
1113 if (stype == LLVMDoubleType () && dtype == LLVMFloatType ())
1114 return LLVMBuildFPTrunc (ctx->builder, v, dtype, "");
1116 if (LLVMGetTypeKind (stype) == LLVMPointerTypeKind && LLVMGetTypeKind (dtype) == LLVMPointerTypeKind)
1117 return LLVMBuildBitCast (ctx->builder, v, dtype, "");
1118 if (LLVMGetTypeKind (dtype) == LLVMPointerTypeKind)
1119 return LLVMBuildIntToPtr (ctx->builder, v, dtype, "");
1120 if (LLVMGetTypeKind (stype) == LLVMPointerTypeKind)
1121 return LLVMBuildPtrToInt (ctx->builder, v, dtype, "");
1123 if (mono_arch_is_soft_float ()) {
1124 if (stype == LLVMInt32Type () && dtype == LLVMFloatType ())
1125 return LLVMBuildBitCast (ctx->builder, v, dtype, "");
1126 if (stype == LLVMInt32Type () && dtype == LLVMDoubleType ())
1127 return LLVMBuildBitCast (ctx->builder, LLVMBuildZExt (ctx->builder, v, LLVMInt64Type (), ""), dtype, "");
1130 if (LLVMGetTypeKind (stype) == LLVMVectorTypeKind && LLVMGetTypeKind (dtype) == LLVMVectorTypeKind)
1131 return LLVMBuildBitCast (ctx->builder, v, dtype, "");
1134 LLVMDumpValue (LLVMConstNull (dtype));
1135 g_assert_not_reached ();
1143 convert (EmitContext *ctx, LLVMValueRef v, LLVMTypeRef dtype)
1145 return convert_full (ctx, v, dtype, FALSE);
1149 * emit_volatile_load:
1151 * If vreg is volatile, emit a load from its address.
1154 emit_volatile_load (EmitContext *ctx, int vreg)
1158 LLVMValueRef v = LLVMBuildLoad (ctx->builder, ctx->addresses [vreg], "");
1159 t = ctx->vreg_cli_types [vreg];
1160 if (t && !t->byref) {
1162 * Might have to zero extend since llvm doesn't have
1165 if (t->type == MONO_TYPE_U1 || t->type == MONO_TYPE_U2 || t->type == MONO_TYPE_CHAR || t->type == MONO_TYPE_BOOLEAN)
1166 v = LLVMBuildZExt (ctx->builder, v, LLVMInt32Type (), "");
1167 else if (t->type == MONO_TYPE_I1 || t->type == MONO_TYPE_I2)
1168 v = LLVMBuildSExt (ctx->builder, v, LLVMInt32Type (), "");
1169 else if (t->type == MONO_TYPE_U8)
1170 v = LLVMBuildZExt (ctx->builder, v, LLVMInt64Type (), "");
1177 * emit_volatile_store:
1179 * If VREG is volatile, emit a store from its value to its address.
1182 emit_volatile_store (EmitContext *ctx, int vreg)
1184 MonoInst *var = get_vreg_to_inst (ctx->cfg, vreg);
1186 if (var && var->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT)) {
1187 g_assert (ctx->addresses [vreg]);
1188 LLVMBuildStore (ctx->builder, convert (ctx, ctx->values [vreg], type_to_llvm_type (ctx, var->inst_vtype)), ctx->addresses [vreg]);
1193 sig_to_llvm_sig_no_cinfo (EmitContext *ctx, MonoMethodSignature *sig)
1195 LLVMTypeRef ret_type;
1196 LLVMTypeRef *param_types = NULL;
1201 rtype = mini_get_underlying_type (sig->ret);
1202 ret_type = type_to_llvm_type (ctx, rtype);
1206 param_types = g_new0 (LLVMTypeRef, (sig->param_count * 8) + 3);
1210 param_types [pindex ++] = ThisType ();
1211 for (i = 0; i < sig->param_count; ++i)
1212 param_types [pindex ++] = type_to_llvm_arg_type (ctx, sig->params [i]);
1214 if (!ctx_ok (ctx)) {
1215 g_free (param_types);
1219 res = LLVMFunctionType (ret_type, param_types, pindex, FALSE);
1220 g_free (param_types);
1226 * sig_to_llvm_sig_full:
1228 * Return the LLVM signature corresponding to the mono signature SIG using the
1229 * calling convention information in CINFO. Fill out the parameter mapping information in CINFO.
1232 sig_to_llvm_sig_full (EmitContext *ctx, MonoMethodSignature *sig, LLVMCallInfo *cinfo)
1234 LLVMTypeRef ret_type;
1235 LLVMTypeRef *param_types = NULL;
1237 int i, j, pindex, vret_arg_pindex = 0;
1238 gboolean vretaddr = FALSE;
1242 return sig_to_llvm_sig_no_cinfo (ctx, sig);
1244 rtype = mini_get_underlying_type (sig->ret);
1245 ret_type = type_to_llvm_type (ctx, rtype);
1249 switch (cinfo->ret.storage) {
1250 case LLVMArgVtypeInReg:
1251 /* LLVM models this by returning an aggregate value */
1252 if (cinfo->ret.pair_storage [0] == LLVMArgInIReg && cinfo->ret.pair_storage [1] == LLVMArgNone) {
1253 LLVMTypeRef members [2];
1255 members [0] = IntPtrType ();
1256 ret_type = LLVMStructType (members, 1, FALSE);
1257 } else if (cinfo->ret.pair_storage [0] == LLVMArgNone && cinfo->ret.pair_storage [1] == LLVMArgNone) {
1259 ret_type = LLVMVoidType ();
1260 } else if (cinfo->ret.pair_storage [0] == LLVMArgInIReg && cinfo->ret.pair_storage [1] == LLVMArgInIReg) {
1261 LLVMTypeRef members [2];
1263 members [0] = IntPtrType ();
1264 members [1] = IntPtrType ();
1265 ret_type = LLVMStructType (members, 2, FALSE);
1267 g_assert_not_reached ();
1270 case LLVMArgVtypeByVal:
1271 /* Vtype returned normally by val */
1273 case LLVMArgVtypeAsScalar: {
1274 int size = mono_class_value_size (mono_class_from_mono_type (rtype), NULL);
1275 /* LLVM models this by returning an int */
1276 if (size < SIZEOF_VOID_P) {
1277 g_assert (cinfo->ret.nslots == 1);
1278 ret_type = LLVMIntType (size * 8);
1280 g_assert (cinfo->ret.nslots == 1 || cinfo->ret.nslots == 2);
1281 ret_type = LLVMIntType (cinfo->ret.nslots * sizeof (mgreg_t) * 8);
1285 case LLVMArgAsIArgs:
1286 ret_type = LLVMArrayType (IntPtrType (), cinfo->ret.nslots);
1288 case LLVMArgFpStruct: {
1289 /* Vtype returned as a fp struct */
1290 LLVMTypeRef members [16];
1292 /* Have to create our own structure since we don't map fp structures to LLVM fp structures yet */
1293 for (i = 0; i < cinfo->ret.nslots; ++i)
1294 members [i] = cinfo->ret.esize == 8 ? LLVMDoubleType () : LLVMFloatType ();
1295 ret_type = LLVMStructType (members, cinfo->ret.nslots, FALSE);
1298 case LLVMArgVtypeByRef:
1299 /* Vtype returned using a hidden argument */
1300 ret_type = LLVMVoidType ();
1302 case LLVMArgVtypeRetAddr:
1303 case LLVMArgGsharedvtFixed:
1304 case LLVMArgGsharedvtFixedVtype:
1305 case LLVMArgGsharedvtVariable:
1307 ret_type = LLVMVoidType ();
1313 param_types = g_new0 (LLVMTypeRef, (sig->param_count * 8) + 3);
1315 if (cinfo->ret.storage == LLVMArgVtypeByRef) {
1317 * Has to be the first argument because of the sret argument attribute
1318 * FIXME: This might conflict with passing 'this' as the first argument, but
1319 * this is only used on arm64 which has a dedicated struct return register.
1321 cinfo->vret_arg_pindex = pindex;
1322 param_types [pindex] = type_to_llvm_arg_type (ctx, sig->ret);
1323 if (!ctx_ok (ctx)) {
1324 g_free (param_types);
1327 param_types [pindex] = LLVMPointerType (param_types [pindex], 0);
1330 if (!ctx->llvm_only && cinfo->rgctx_arg) {
1331 cinfo->rgctx_arg_pindex = pindex;
1332 param_types [pindex] = ctx->module->ptr_type;
1335 if (cinfo->imt_arg) {
1336 cinfo->imt_arg_pindex = pindex;
1337 param_types [pindex] = ctx->module->ptr_type;
1341 /* Compute the index in the LLVM signature where the vret arg needs to be passed */
1342 vret_arg_pindex = pindex;
1343 if (cinfo->vret_arg_index == 1) {
1344 /* Add the slots consumed by the first argument */
1345 LLVMArgInfo *ainfo = &cinfo->args [0];
1346 switch (ainfo->storage) {
1347 case LLVMArgVtypeInReg:
1348 for (j = 0; j < 2; ++j) {
1349 if (ainfo->pair_storage [j] == LLVMArgInIReg)
1358 cinfo->vret_arg_pindex = vret_arg_pindex;
1361 if (vretaddr && vret_arg_pindex == pindex)
1362 param_types [pindex ++] = IntPtrType ();
1364 cinfo->this_arg_pindex = pindex;
1365 param_types [pindex ++] = ThisType ();
1366 cinfo->args [0].pindex = cinfo->this_arg_pindex;
1368 if (vretaddr && vret_arg_pindex == pindex)
1369 param_types [pindex ++] = IntPtrType ();
1370 for (i = 0; i < sig->param_count; ++i) {
1371 LLVMArgInfo *ainfo = &cinfo->args [i + sig->hasthis];
1373 if (vretaddr && vret_arg_pindex == pindex)
1374 param_types [pindex ++] = IntPtrType ();
1375 ainfo->pindex = pindex;
1377 switch (ainfo->storage) {
1378 case LLVMArgVtypeInReg:
1379 for (j = 0; j < 2; ++j) {
1380 switch (ainfo->pair_storage [j]) {
1382 param_types [pindex ++] = LLVMIntType (sizeof (gpointer) * 8);
1387 g_assert_not_reached ();
1391 case LLVMArgVtypeByVal:
1392 param_types [pindex] = type_to_llvm_arg_type (ctx, ainfo->type);
1395 param_types [pindex] = LLVMPointerType (param_types [pindex], 0);
1398 case LLVMArgAsIArgs:
1399 param_types [pindex] = LLVMArrayType (IntPtrType (), ainfo->nslots);
1402 case LLVMArgVtypeByRef:
1403 param_types [pindex] = type_to_llvm_arg_type (ctx, ainfo->type);
1406 param_types [pindex] = LLVMPointerType (param_types [pindex], 0);
1409 case LLVMArgAsFpArgs: {
1412 /* Emit dummy fp arguments if needed so the rest is passed on the stack */
1413 for (j = 0; j < ainfo->ndummy_fpargs; ++j)
1414 param_types [pindex ++] = LLVMDoubleType ();
1415 for (j = 0; j < ainfo->nslots; ++j)
1416 param_types [pindex ++] = ainfo->esize == 8 ? LLVMDoubleType () : LLVMFloatType ();
1419 case LLVMArgVtypeAsScalar:
1420 g_assert_not_reached ();
1422 case LLVMArgGsharedvtFixed:
1423 case LLVMArgGsharedvtFixedVtype:
1424 param_types [pindex ++] = LLVMPointerType (type_to_llvm_arg_type (ctx, ainfo->type), 0);
1426 case LLVMArgGsharedvtVariable:
1427 param_types [pindex ++] = LLVMPointerType (IntPtrType (), 0);
1430 param_types [pindex ++] = type_to_llvm_arg_type (ctx, ainfo->type);
1434 if (!ctx_ok (ctx)) {
1435 g_free (param_types);
1438 if (vretaddr && vret_arg_pindex == pindex)
1439 param_types [pindex ++] = IntPtrType ();
1440 if (ctx->llvm_only && cinfo->rgctx_arg) {
1441 /* Pass the rgctx as the last argument */
1442 cinfo->rgctx_arg_pindex = pindex;
1443 param_types [pindex] = ctx->module->ptr_type;
1447 res = LLVMFunctionType (ret_type, param_types, pindex, FALSE);
1448 g_free (param_types);
1454 sig_to_llvm_sig (EmitContext *ctx, MonoMethodSignature *sig)
1456 return sig_to_llvm_sig_full (ctx, sig, NULL);
1460 * LLVMFunctionType1:
1462 * Create an LLVM function type from the arguments.
1464 static G_GNUC_UNUSED LLVMTypeRef
1465 LLVMFunctionType0 (LLVMTypeRef ReturnType,
1468 return LLVMFunctionType (ReturnType, NULL, 0, IsVarArg);
1472 * LLVMFunctionType1:
1474 * Create an LLVM function type from the arguments.
1476 static G_GNUC_UNUSED LLVMTypeRef
1477 LLVMFunctionType1 (LLVMTypeRef ReturnType,
1478 LLVMTypeRef ParamType1,
1481 LLVMTypeRef param_types [1];
1483 param_types [0] = ParamType1;
1485 return LLVMFunctionType (ReturnType, param_types, 1, IsVarArg);
1489 * LLVMFunctionType2:
1491 * Create an LLVM function type from the arguments.
1493 static G_GNUC_UNUSED LLVMTypeRef
1494 LLVMFunctionType2 (LLVMTypeRef ReturnType,
1495 LLVMTypeRef ParamType1,
1496 LLVMTypeRef ParamType2,
1499 LLVMTypeRef param_types [2];
1501 param_types [0] = ParamType1;
1502 param_types [1] = ParamType2;
1504 return LLVMFunctionType (ReturnType, param_types, 2, IsVarArg);
1508 * LLVMFunctionType3:
1510 * Create an LLVM function type from the arguments.
1512 static G_GNUC_UNUSED LLVMTypeRef
1513 LLVMFunctionType3 (LLVMTypeRef ReturnType,
1514 LLVMTypeRef ParamType1,
1515 LLVMTypeRef ParamType2,
1516 LLVMTypeRef ParamType3,
1519 LLVMTypeRef param_types [3];
1521 param_types [0] = ParamType1;
1522 param_types [1] = ParamType2;
1523 param_types [2] = ParamType3;
1525 return LLVMFunctionType (ReturnType, param_types, 3, IsVarArg);
1528 static G_GNUC_UNUSED LLVMTypeRef
1529 LLVMFunctionType5 (LLVMTypeRef ReturnType,
1530 LLVMTypeRef ParamType1,
1531 LLVMTypeRef ParamType2,
1532 LLVMTypeRef ParamType3,
1533 LLVMTypeRef ParamType4,
1534 LLVMTypeRef ParamType5,
1537 LLVMTypeRef param_types [5];
1539 param_types [0] = ParamType1;
1540 param_types [1] = ParamType2;
1541 param_types [2] = ParamType3;
1542 param_types [3] = ParamType4;
1543 param_types [4] = ParamType5;
1545 return LLVMFunctionType (ReturnType, param_types, 5, IsVarArg);
1551 * Create an LLVM builder and remember it so it can be freed later.
1553 static LLVMBuilderRef
1554 create_builder (EmitContext *ctx)
1556 LLVMBuilderRef builder = LLVMCreateBuilder ();
1558 ctx->builders = g_slist_prepend_mempool (ctx->cfg->mempool, ctx->builders, builder);
1564 get_aotconst_name (MonoJumpInfoType type, gconstpointer data, int got_offset)
1569 case MONO_PATCH_INFO_INTERNAL_METHOD:
1570 name = g_strdup_printf ("jit_icall_%s", data);
1572 case MONO_PATCH_INFO_RGCTX_SLOT_INDEX: {
1573 MonoJumpInfoRgctxEntry *entry = (MonoJumpInfoRgctxEntry*)data;
1574 name = g_strdup_printf ("RGCTX_SLOT_INDEX_%s", mono_rgctx_info_type_to_str (entry->info_type));
1578 name = g_strdup_printf ("%s_%d", mono_ji_type_to_string (type), got_offset);
1586 get_aotconst_typed (EmitContext *ctx, MonoJumpInfoType type, gconstpointer data, LLVMTypeRef llvm_type)
1590 LLVMValueRef indexes [2];
1592 LLVMValueRef got_entry_addr, load;
1593 LLVMBuilderRef builder = ctx->builder;
1598 ji = g_new0 (MonoJumpInfo, 1);
1600 ji->data.target = data;
1602 ji = mono_aot_patch_info_dup (ji);
1604 ji->next = cfg->patch_info;
1605 cfg->patch_info = ji;
1607 got_offset = mono_aot_get_got_offset (cfg->patch_info);
1608 ctx->module->max_got_offset = MAX (ctx->module->max_got_offset, got_offset);
1610 * If the got slot is shared, it means its initialized when the aot image is loaded, so we don't need to
1611 * explicitly initialize it.
1613 if (!mono_aot_is_shared_got_offset (got_offset)) {
1614 //mono_print_ji (ji);
1616 ctx->has_got_access = TRUE;
1619 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
1620 indexes [1] = LLVMConstInt (LLVMInt32Type (), (gssize)got_offset, FALSE);
1621 got_entry_addr = LLVMBuildGEP (builder, ctx->module->got_var, indexes, 2, "");
1623 name = get_aotconst_name (type, data, got_offset);
1625 load = LLVMBuildLoad (builder, got_entry_addr, "");
1626 load = convert (ctx, load, llvm_type);
1627 LLVMSetValueName (load, name ? name : "");
1629 load = LLVMBuildLoad (builder, got_entry_addr, name ? name : "");
1632 //set_invariant_load_flag (load);
1638 get_aotconst (EmitContext *ctx, MonoJumpInfoType type, gconstpointer data)
1640 return get_aotconst_typed (ctx, type, data, NULL);
1644 get_callee (EmitContext *ctx, LLVMTypeRef llvm_sig, MonoJumpInfoType type, gconstpointer data)
1646 LLVMValueRef callee;
1648 if (ctx->llvm_only) {
1649 callee_name = mono_aot_get_direct_call_symbol (type, data);
1651 /* Directly callable */
1653 callee = (LLVMValueRef)g_hash_table_lookup (ctx->module->direct_callables, callee_name);
1655 callee = LLVMAddFunction (ctx->lmodule, callee_name, llvm_sig);
1657 LLVMSetVisibility (callee, LLVMHiddenVisibility);
1659 g_hash_table_insert (ctx->module->direct_callables, (char*)callee_name, callee);
1661 /* LLVMTypeRef's are uniqued */
1662 if (LLVMGetElementType (LLVMTypeOf (callee)) != llvm_sig)
1663 return LLVMConstBitCast (callee, LLVMPointerType (llvm_sig, 0));
1665 g_free (callee_name);
1671 * Calls are made through the GOT.
1673 return get_aotconst_typed (ctx, type, data, LLVMPointerType (llvm_sig, 0));
1675 MonoJumpInfo *ji = NULL;
1677 callee_name = mono_aot_get_plt_symbol (type, data);
1681 if (ctx->cfg->compile_aot)
1682 /* Add a patch so referenced wrappers can be compiled in full aot mode */
1683 mono_add_patch_info (ctx->cfg, 0, type, data);
1686 callee = (LLVMValueRef)g_hash_table_lookup (ctx->module->plt_entries, callee_name);
1688 callee = LLVMAddFunction (ctx->lmodule, callee_name, llvm_sig);
1690 LLVMSetVisibility (callee, LLVMHiddenVisibility);
1692 g_hash_table_insert (ctx->module->plt_entries, (char*)callee_name, callee);
1695 if (ctx->cfg->compile_aot) {
1696 ji = g_new0 (MonoJumpInfo, 1);
1698 ji->data.target = data;
1700 g_hash_table_insert (ctx->module->plt_entries_ji, ji, callee);
1708 emit_jit_callee (EmitContext *ctx, const char *name, LLVMTypeRef llvm_sig, gpointer target)
1710 #if LLVM_API_VERSION > 100
1711 LLVMValueRef tramp_var = LLVMAddGlobal (ctx->lmodule, LLVMPointerType (llvm_sig, 0), name);
1712 LLVMSetInitializer (tramp_var, LLVMConstIntToPtr (LLVMConstInt (LLVMInt64Type (), (guint64)(size_t)target, FALSE), LLVMPointerType (llvm_sig, 0)));
1713 LLVMSetLinkage (tramp_var, LLVMExternalLinkage);
1714 LLVMValueRef callee = LLVMBuildLoad (ctx->builder, tramp_var, "");
1717 LLVMValueRef callee = LLVMAddFunction (ctx->lmodule, "", llvm_sig);
1718 LLVMAddGlobalMapping (ctx->module->ee, callee, target);
1724 get_handler_clause (MonoCompile *cfg, MonoBasicBlock *bb)
1726 MonoMethodHeader *header = cfg->header;
1727 MonoExceptionClause *clause;
1731 if (bb->region != -1 && MONO_BBLOCK_IS_IN_REGION (bb, MONO_REGION_TRY))
1732 return (bb->region >> 8) - 1;
1735 for (i = 0; i < header->num_clauses; ++i) {
1736 clause = &header->clauses [i];
1738 if (MONO_OFFSET_IN_CLAUSE (clause, bb->real_offset) && clause->flags == MONO_EXCEPTION_CLAUSE_NONE)
1745 static MonoExceptionClause *
1746 get_most_deep_clause (MonoCompile *cfg, EmitContext *ctx, MonoBasicBlock *bb)
1748 // Since they're sorted by nesting we just need
1749 // the first one that the bb is a member of
1750 for (int i = 0; i < cfg->header->num_clauses; i++) {
1751 MonoExceptionClause *curr = &cfg->header->clauses [i];
1753 if (MONO_OFFSET_IN_CLAUSE (curr, bb->real_offset))
1761 set_metadata_flag (LLVMValueRef v, const char *flag_name)
1763 LLVMValueRef md_arg;
1766 md_kind = LLVMGetMDKindID (flag_name, strlen (flag_name));
1767 md_arg = LLVMMDString ("mono", 4);
1768 LLVMSetMetadata (v, md_kind, LLVMMDNode (&md_arg, 1));
1772 set_invariant_load_flag (LLVMValueRef v)
1774 LLVMValueRef md_arg;
1776 const char *flag_name;
1778 // FIXME: Cache this
1779 flag_name = "invariant.load";
1780 md_kind = LLVMGetMDKindID (flag_name, strlen (flag_name));
1781 md_arg = LLVMMDString ("<index>", strlen ("<index>"));
1782 LLVMSetMetadata (v, md_kind, LLVMMDNode (&md_arg, 1));
1788 * Emit an LLVM call or invoke instruction depending on whenever the call is inside
1792 emit_call (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, LLVMValueRef callee, LLVMValueRef *args, int pindex)
1794 MonoCompile *cfg = ctx->cfg;
1795 LLVMValueRef lcall = NULL;
1796 LLVMBuilderRef builder = *builder_ref;
1797 MonoExceptionClause *clause;
1799 if (ctx->llvm_only) {
1800 clause = get_most_deep_clause (cfg, ctx, bb);
1803 g_assert (clause->flags == MONO_EXCEPTION_CLAUSE_NONE || clause->flags == MONO_EXCEPTION_CLAUSE_FINALLY);
1806 * Have to use an invoke instead of a call, branching to the
1807 * handler bblock of the clause containing this bblock.
1809 intptr_t key = CLAUSE_END(clause);
1811 LLVMBasicBlockRef lpad_bb = (LLVMBasicBlockRef)g_hash_table_lookup (ctx->exc_meta, (gconstpointer)key);
1813 // FIXME: Find the one that has the lowest end bound for the right start address
1814 // FIXME: Finally + nesting
1817 LLVMBasicBlockRef noex_bb = gen_bb (ctx, "CALL_NOEX_BB");
1820 lcall = LLVMBuildInvoke (builder, callee, args, pindex, noex_bb, lpad_bb, "");
1822 builder = ctx->builder = create_builder (ctx);
1823 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
1825 ctx->bblocks [bb->block_num].end_bblock = noex_bb;
1829 int clause_index = get_handler_clause (cfg, bb);
1831 if (clause_index != -1) {
1832 MonoMethodHeader *header = cfg->header;
1833 MonoExceptionClause *ec = &header->clauses [clause_index];
1834 MonoBasicBlock *tblock;
1835 LLVMBasicBlockRef ex_bb, noex_bb;
1838 * Have to use an invoke instead of a call, branching to the
1839 * handler bblock of the clause containing this bblock.
1842 g_assert (ec->flags == MONO_EXCEPTION_CLAUSE_NONE || ec->flags == MONO_EXCEPTION_CLAUSE_FINALLY);
1844 tblock = cfg->cil_offset_to_bb [ec->handler_offset];
1847 ctx->bblocks [tblock->block_num].invoke_target = TRUE;
1849 ex_bb = get_bb (ctx, tblock);
1851 noex_bb = gen_bb (ctx, "NOEX_BB");
1854 lcall = LLVMBuildInvoke (builder, callee, args, pindex, noex_bb, ex_bb, "");
1856 builder = ctx->builder = create_builder (ctx);
1857 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
1859 ctx->bblocks [bb->block_num].end_bblock = noex_bb;
1864 lcall = LLVMBuildCall (builder, callee, args, pindex, "");
1865 ctx->builder = builder;
1869 *builder_ref = ctx->builder;
1875 emit_load_general (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, int size, LLVMValueRef addr, const char *name, gboolean is_faulting, BarrierKind barrier)
1877 const char *intrins_name;
1878 LLVMValueRef args [16], res;
1879 LLVMTypeRef addr_type;
1880 gboolean use_intrinsics = TRUE;
1882 #if LLVM_API_VERSION > 100
1883 if (is_faulting && bb->region != -1 && !ctx->cfg->llvm_only) {
1884 /* The llvm.mono.load/store intrinsics are not supported by this llvm version, emit an explicit null check instead */
1885 LLVMValueRef cmp = LLVMBuildICmp (*builder_ref, LLVMIntEQ, addr, LLVMConstNull (LLVMTypeOf (addr)), "");
1886 emit_cond_system_exception (ctx, bb, "NullReferenceException", cmp);
1887 *builder_ref = ctx->builder;
1888 use_intrinsics = FALSE;
1892 if (is_faulting && bb->region != -1 && !ctx->cfg->llvm_only && use_intrinsics) {
1893 LLVMAtomicOrdering ordering;
1896 case LLVM_BARRIER_NONE:
1897 ordering = LLVMAtomicOrderingNotAtomic;
1899 case LLVM_BARRIER_ACQ:
1900 ordering = LLVMAtomicOrderingAcquire;
1902 case LLVM_BARRIER_SEQ:
1903 ordering = LLVMAtomicOrderingSequentiallyConsistent;
1906 g_assert_not_reached ();
1911 * We handle loads which can fault by calling a mono specific intrinsic
1912 * using an invoke, so they are handled properly inside try blocks.
1913 * We can't use this outside clauses, since LLVM optimizes intrinsics which
1914 * are marked with IntrReadArgMem.
1918 intrins_name = "llvm.mono.load.i8.p0i8";
1921 intrins_name = "llvm.mono.load.i16.p0i16";
1924 intrins_name = "llvm.mono.load.i32.p0i32";
1927 intrins_name = "llvm.mono.load.i64.p0i64";
1930 g_assert_not_reached ();
1933 addr_type = LLVMTypeOf (addr);
1934 if (addr_type == LLVMPointerType (LLVMDoubleType (), 0) || addr_type == LLVMPointerType (LLVMFloatType (), 0))
1935 addr = LLVMBuildBitCast (*builder_ref, addr, LLVMPointerType (LLVMIntType (size * 8), 0), "");
1938 args [1] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
1939 args [2] = LLVMConstInt (LLVMInt1Type (), TRUE, FALSE);
1940 args [3] = LLVMConstInt (LLVMInt32Type (), ordering, FALSE);
1941 res = emit_call (ctx, bb, builder_ref, get_intrinsic (ctx, intrins_name), args, 4);
1943 if (addr_type == LLVMPointerType (LLVMDoubleType (), 0))
1944 res = LLVMBuildBitCast (*builder_ref, res, LLVMDoubleType (), "");
1945 else if (addr_type == LLVMPointerType (LLVMFloatType (), 0))
1946 res = LLVMBuildBitCast (*builder_ref, res, LLVMFloatType (), "");
1953 * We emit volatile loads for loads which can fault, because otherwise
1954 * LLVM will generate invalid code when encountering a load from a
1957 res = mono_llvm_build_load (*builder_ref, addr, name, is_faulting, barrier);
1959 /* Mark it with a custom metadata */
1962 set_metadata_flag (res, "mono.faulting.load");
1970 emit_load (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, int size, LLVMValueRef addr, const char *name, gboolean is_faulting)
1972 return emit_load_general (ctx, bb, builder_ref, size, addr, name, is_faulting, LLVM_BARRIER_NONE);
1976 emit_store_general (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, int size, LLVMValueRef value, LLVMValueRef addr, gboolean is_faulting, BarrierKind barrier)
1978 const char *intrins_name;
1979 LLVMValueRef args [16];
1980 gboolean use_intrinsics = TRUE;
1982 #if LLVM_API_VERSION > 100
1983 if (is_faulting && bb->region != -1 && !ctx->cfg->llvm_only) {
1984 /* The llvm.mono.load/store intrinsics are not supported by this llvm version, emit an explicit null check instead */
1985 LLVMValueRef cmp = LLVMBuildICmp (*builder_ref, LLVMIntEQ, addr, LLVMConstNull (LLVMTypeOf (addr)), "");
1986 emit_cond_system_exception (ctx, bb, "NullReferenceException", cmp);
1987 *builder_ref = ctx->builder;
1988 use_intrinsics = FALSE;
1992 if (is_faulting && bb->region != -1 && !ctx->cfg->llvm_only && use_intrinsics) {
1993 LLVMAtomicOrdering ordering;
1996 case LLVM_BARRIER_NONE:
1997 ordering = LLVMAtomicOrderingNotAtomic;
1999 case LLVM_BARRIER_REL:
2000 ordering = LLVMAtomicOrderingRelease;
2002 case LLVM_BARRIER_SEQ:
2003 ordering = LLVMAtomicOrderingSequentiallyConsistent;
2006 g_assert_not_reached ();
2012 intrins_name = "llvm.mono.store.i8.p0i8";
2015 intrins_name = "llvm.mono.store.i16.p0i16";
2018 intrins_name = "llvm.mono.store.i32.p0i32";
2021 intrins_name = "llvm.mono.store.i64.p0i64";
2024 g_assert_not_reached ();
2027 if (LLVMTypeOf (value) == LLVMDoubleType () || LLVMTypeOf (value) == LLVMFloatType ()) {
2028 value = LLVMBuildBitCast (*builder_ref, value, LLVMIntType (size * 8), "");
2029 addr = LLVMBuildBitCast (*builder_ref, addr, LLVMPointerType (LLVMIntType (size * 8), 0), "");
2034 args [2] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
2035 args [3] = LLVMConstInt (LLVMInt1Type (), TRUE, FALSE);
2036 args [4] = LLVMConstInt (LLVMInt32Type (), ordering, FALSE);
2037 emit_call (ctx, bb, builder_ref, get_intrinsic (ctx, intrins_name), args, 5);
2039 if (barrier != LLVM_BARRIER_NONE)
2040 mono_llvm_build_aligned_store (*builder_ref, value, addr, barrier, size);
2042 mono_llvm_build_store (*builder_ref, value, addr, is_faulting, barrier);
2047 emit_store (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, int size, LLVMValueRef value, LLVMValueRef addr, gboolean is_faulting)
2049 emit_store_general (ctx, bb, builder_ref, size, value, addr, is_faulting, LLVM_BARRIER_NONE);
2053 * emit_cond_system_exception:
2055 * Emit code to throw the exception EXC_TYPE if the condition CMP is false.
2056 * Might set the ctx exception.
2059 emit_cond_system_exception (EmitContext *ctx, MonoBasicBlock *bb, const char *exc_type, LLVMValueRef cmp)
2061 LLVMBasicBlockRef ex_bb, ex2_bb = NULL, noex_bb;
2062 LLVMBuilderRef builder;
2063 MonoClass *exc_class;
2064 LLVMValueRef args [2];
2065 LLVMValueRef callee;
2066 gboolean no_pc = FALSE;
2068 if (IS_TARGET_AMD64)
2069 /* Some platforms don't require the pc argument */
2072 ex_bb = gen_bb (ctx, "EX_BB");
2074 ex2_bb = gen_bb (ctx, "EX2_BB");
2075 noex_bb = gen_bb (ctx, "NOEX_BB");
2077 LLVMBuildCondBr (ctx->builder, cmp, ex_bb, noex_bb);
2079 exc_class = mono_class_load_from_name (mono_get_corlib (), "System", exc_type);
2081 /* Emit exception throwing code */
2082 ctx->builder = builder = create_builder (ctx);
2083 LLVMPositionBuilderAtEnd (builder, ex_bb);
2085 if (ctx->cfg->llvm_only) {
2086 static LLVMTypeRef sig;
2089 sig = LLVMFunctionType1 (LLVMVoidType (), LLVMInt32Type (), FALSE);
2090 callee = get_callee (ctx, sig, MONO_PATCH_INFO_JIT_ICALL_ADDR, "mono_llvm_throw_corlib_exception");
2092 LLVMBuildBr (builder, ex2_bb);
2094 ctx->builder = builder = create_builder (ctx);
2095 LLVMPositionBuilderAtEnd (ctx->builder, ex2_bb);
2097 args [0] = LLVMConstInt (LLVMInt32Type (), exc_class->type_token - MONO_TOKEN_TYPE_DEF, FALSE);
2098 emit_call (ctx, bb, &builder, callee, args, 1);
2099 LLVMBuildUnreachable (builder);
2101 ctx->builder = builder = create_builder (ctx);
2102 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
2104 ctx->bblocks [bb->block_num].end_bblock = noex_bb;
2110 callee = ctx->module->throw_corlib_exception;
2113 const char *icall_name;
2116 sig = LLVMFunctionType1 (LLVMVoidType (), LLVMInt32Type (), FALSE);
2118 sig = LLVMFunctionType2 (LLVMVoidType (), LLVMInt32Type (), LLVMPointerType (LLVMInt8Type (), 0), FALSE);
2119 icall_name = "llvm_throw_corlib_exception_abs_trampoline";
2121 if (ctx->cfg->compile_aot) {
2122 callee = get_callee (ctx, sig, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
2125 * Differences between the LLVM/non-LLVM throw corlib exception trampoline:
2126 * - On x86, LLVM generated code doesn't push the arguments
2127 * - The trampoline takes the throw address as an arguments, not a pc offset.
2129 gpointer target = resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
2130 callee = emit_jit_callee (ctx, "llvm_throw_corlib_exception_trampoline", sig, target);
2132 #if LLVM_API_VERSION > 100
2134 * Make sure that ex_bb starts with the invoke, so the block address points to it, and not to the load
2135 * added by emit_jit_callee ().
2137 ex2_bb = gen_bb (ctx, "EX2_BB");
2138 LLVMBuildBr (builder, ex2_bb);
2141 ctx->builder = builder = create_builder (ctx);
2142 LLVMPositionBuilderAtEnd (ctx->builder, ex2_bb);
2144 mono_memory_barrier ();
2145 ctx->module->throw_corlib_exception = callee;
2150 args [0] = LLVMConstInt (LLVMInt32Type (), exc_class->type_token - MONO_TOKEN_TYPE_DEF, FALSE);
2153 * The LLVM mono branch contains changes so a block address can be passed as an
2154 * argument to a call.
2157 emit_call (ctx, bb, &builder, callee, args, 1);
2159 args [1] = LLVMBlockAddress (ctx->lmethod, ex_bb);
2160 emit_call (ctx, bb, &builder, callee, args, 2);
2163 LLVMBuildUnreachable (builder);
2165 ctx->builder = builder = create_builder (ctx);
2166 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
2168 ctx->bblocks [bb->block_num].end_bblock = noex_bb;
2175 * emit_args_to_vtype:
2177 * Emit code to store the vtype in the arguments args to the address ADDRESS.
2180 emit_args_to_vtype (EmitContext *ctx, LLVMBuilderRef builder, MonoType *t, LLVMValueRef address, LLVMArgInfo *ainfo, LLVMValueRef *args)
2182 int j, size, nslots;
2184 size = mono_class_value_size (mono_class_from_mono_type (t), NULL);
2186 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (t))) {
2187 address = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (LLVMInt8Type (), 0), "");
2190 if (ainfo->storage == LLVMArgAsFpArgs)
2191 nslots = ainfo->nslots;
2195 for (j = 0; j < nslots; ++j) {
2196 LLVMValueRef index [2], addr, daddr;
2197 int part_size = size > sizeof (gpointer) ? sizeof (gpointer) : size;
2198 LLVMTypeRef part_type;
2200 while (part_size != 1 && part_size != 2 && part_size != 4 && part_size < 8)
2203 if (ainfo->pair_storage [j] == LLVMArgNone)
2206 switch (ainfo->pair_storage [j]) {
2207 case LLVMArgInIReg: {
2208 part_type = LLVMIntType (part_size * 8);
2209 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (t))) {
2210 index [0] = LLVMConstInt (LLVMInt32Type (), j * sizeof (gpointer), FALSE);
2211 addr = LLVMBuildGEP (builder, address, index, 1, "");
2213 daddr = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (IntPtrType (), 0), "");
2214 index [0] = LLVMConstInt (LLVMInt32Type (), j, FALSE);
2215 addr = LLVMBuildGEP (builder, daddr, index, 1, "");
2217 LLVMBuildStore (builder, convert (ctx, args [j], part_type), LLVMBuildBitCast (ctx->builder, addr, LLVMPointerType (part_type, 0), ""));
2220 case LLVMArgInFPReg: {
2221 LLVMTypeRef arg_type;
2223 if (ainfo->esize == 8)
2224 arg_type = LLVMDoubleType ();
2226 arg_type = LLVMFloatType ();
2228 index [0] = LLVMConstInt (LLVMInt32Type (), j, FALSE);
2229 daddr = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (arg_type, 0), "");
2230 addr = LLVMBuildGEP (builder, daddr, index, 1, "");
2231 LLVMBuildStore (builder, args [j], addr);
2237 g_assert_not_reached ();
2240 size -= sizeof (gpointer);
2245 * emit_vtype_to_args:
2247 * Emit code to load a vtype at address ADDRESS into scalar arguments. Store the arguments
2248 * into ARGS, and the number of arguments into NARGS.
2251 emit_vtype_to_args (EmitContext *ctx, LLVMBuilderRef builder, MonoType *t, LLVMValueRef address, LLVMArgInfo *ainfo, LLVMValueRef *args, guint32 *nargs)
2254 int j, size, nslots;
2255 LLVMTypeRef arg_type;
2257 size = get_vtype_size (t);
2259 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (t)))
2260 address = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (LLVMInt8Type (), 0), "");
2262 if (ainfo->storage == LLVMArgAsFpArgs)
2263 nslots = ainfo->nslots;
2266 for (j = 0; j < nslots; ++j) {
2267 LLVMValueRef index [2], addr, daddr;
2268 int partsize = size > sizeof (gpointer) ? sizeof (gpointer) : size;
2270 if (ainfo->pair_storage [j] == LLVMArgNone)
2273 switch (ainfo->pair_storage [j]) {
2275 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (t))) {
2276 index [0] = LLVMConstInt (LLVMInt32Type (), j * sizeof (gpointer), FALSE);
2277 addr = LLVMBuildGEP (builder, address, index, 1, "");
2279 daddr = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (IntPtrType (), 0), "");
2280 index [0] = LLVMConstInt (LLVMInt32Type (), j, FALSE);
2281 addr = LLVMBuildGEP (builder, daddr, index, 1, "");
2283 args [pindex ++] = convert (ctx, LLVMBuildLoad (builder, LLVMBuildBitCast (ctx->builder, addr, LLVMPointerType (LLVMIntType (partsize * 8), 0), ""), ""), IntPtrType ());
2285 case LLVMArgInFPReg:
2286 if (ainfo->esize == 8)
2287 arg_type = LLVMDoubleType ();
2289 arg_type = LLVMFloatType ();
2290 daddr = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (arg_type, 0), "");
2291 index [0] = LLVMConstInt (LLVMInt32Type (), j, FALSE);
2292 addr = LLVMBuildGEP (builder, daddr, index, 1, "");
2293 args [pindex ++] = LLVMBuildLoad (builder, addr, "");
2298 g_assert_not_reached ();
2300 size -= sizeof (gpointer);
2307 build_alloca_llvm_type_name (EmitContext *ctx, LLVMTypeRef t, int align, const char *name)
2310 * Have to place all alloca's at the end of the entry bb, since otherwise they would
2311 * get executed every time control reaches them.
2313 LLVMPositionBuilder (ctx->alloca_builder, get_bb (ctx, ctx->cfg->bb_entry), ctx->last_alloca);
2315 ctx->last_alloca = mono_llvm_build_alloca (ctx->alloca_builder, t, NULL, align, name);
2316 return ctx->last_alloca;
2320 build_alloca_llvm_type (EmitContext *ctx, LLVMTypeRef t, int align)
2322 return build_alloca_llvm_type_name (ctx, t, align, "");
2326 build_alloca (EmitContext *ctx, MonoType *t)
2328 MonoClass *k = mono_class_from_mono_type (t);
2331 g_assert (!mini_is_gsharedvt_variable_type (t));
2333 if (MONO_CLASS_IS_SIMD (ctx->cfg, k))
2336 align = mono_class_min_align (k);
2338 /* Sometimes align is not a power of 2 */
2339 while (mono_is_power_of_two (align) == -1)
2342 return build_alloca_llvm_type (ctx, type_to_llvm_type (ctx, t), align);
2346 emit_gsharedvt_ldaddr (EmitContext *ctx, int vreg)
2350 * Compute the address of the local as gsharedvt_locals_var + gsharedvt_info_var->locals_offsets [idx].
2352 MonoCompile *cfg = ctx->cfg;
2353 LLVMBuilderRef builder = ctx->builder;
2354 LLVMValueRef offset, offset_var;
2355 LLVMValueRef info_var = ctx->values [cfg->gsharedvt_info_var->dreg];
2356 LLVMValueRef locals_var = ctx->values [cfg->gsharedvt_locals_var->dreg];
2360 g_assert (info_var);
2361 g_assert (locals_var);
2363 int idx = cfg->gsharedvt_vreg_to_idx [vreg] - 1;
2365 offset = LLVMConstInt (LLVMInt32Type (), MONO_STRUCT_OFFSET (MonoGSharedVtMethodRuntimeInfo, entries) + (idx * sizeof (gpointer)), FALSE);
2366 ptr = LLVMBuildAdd (builder, convert (ctx, info_var, IntPtrType ()), convert (ctx, offset, IntPtrType ()), "");
2368 name = g_strdup_printf ("gsharedvt_local_%d_offset", vreg);
2369 offset_var = LLVMBuildLoad (builder, convert (ctx, ptr, LLVMPointerType (LLVMInt32Type (), 0)), name);
2371 return LLVMBuildAdd (builder, convert (ctx, locals_var, IntPtrType ()), convert (ctx, offset_var, IntPtrType ()), "");
2375 * Put the global into the 'llvm.used' array to prevent it from being optimized away.
2378 mark_as_used (MonoLLVMModule *module, LLVMValueRef global)
2381 module->used = g_ptr_array_sized_new (16);
2382 g_ptr_array_add (module->used, global);
2386 emit_llvm_used (MonoLLVMModule *module)
2388 LLVMModuleRef lmodule = module->lmodule;
2389 LLVMTypeRef used_type;
2390 LLVMValueRef used, *used_elem;
2396 used_type = LLVMArrayType (LLVMPointerType (LLVMInt8Type (), 0), module->used->len);
2397 used = LLVMAddGlobal (lmodule, used_type, "llvm.used");
2398 used_elem = g_new0 (LLVMValueRef, module->used->len);
2399 for (i = 0; i < module->used->len; ++i)
2400 used_elem [i] = LLVMConstBitCast ((LLVMValueRef)g_ptr_array_index (module->used, i), LLVMPointerType (LLVMInt8Type (), 0));
2401 LLVMSetInitializer (used, LLVMConstArray (LLVMPointerType (LLVMInt8Type (), 0), used_elem, module->used->len));
2402 LLVMSetLinkage (used, LLVMAppendingLinkage);
2403 LLVMSetSection (used, "llvm.metadata");
2409 * Emit a function mapping method indexes to their code
2412 emit_get_method (MonoLLVMModule *module)
2414 LLVMModuleRef lmodule = module->lmodule;
2415 LLVMValueRef func, switch_ins, m;
2416 LLVMBasicBlockRef entry_bb, fail_bb, bb, code_start_bb, code_end_bb;
2417 LLVMBasicBlockRef *bbs;
2419 LLVMBuilderRef builder;
2424 * Emit a switch statement. Emitting a table of function addresses is smaller/faster,
2425 * but generating code seems safer.
2427 rtype = LLVMPointerType (LLVMInt8Type (), 0);
2428 func = LLVMAddFunction (lmodule, module->get_method_symbol, LLVMFunctionType1 (rtype, LLVMInt32Type (), FALSE));
2429 LLVMSetLinkage (func, LLVMExternalLinkage);
2430 LLVMSetVisibility (func, LLVMHiddenVisibility);
2431 LLVMAddFunctionAttr (func, LLVMNoUnwindAttribute);
2432 module->get_method = func;
2434 entry_bb = LLVMAppendBasicBlock (func, "ENTRY");
2437 * Return llvm_code_start/llvm_code_end when called with -1/-2.
2438 * Hopefully, the toolchain doesn't reorder these functions. If it does,
2439 * then we will have to find another solution.
2442 name = g_strdup_printf ("BB_CODE_START");
2443 code_start_bb = LLVMAppendBasicBlock (func, name);
2445 builder = LLVMCreateBuilder ();
2446 LLVMPositionBuilderAtEnd (builder, code_start_bb);
2447 LLVMBuildRet (builder, LLVMBuildBitCast (builder, module->code_start, rtype, ""));
2449 name = g_strdup_printf ("BB_CODE_END");
2450 code_end_bb = LLVMAppendBasicBlock (func, name);
2452 builder = LLVMCreateBuilder ();
2453 LLVMPositionBuilderAtEnd (builder, code_end_bb);
2454 LLVMBuildRet (builder, LLVMBuildBitCast (builder, module->code_end, rtype, ""));
2456 bbs = g_new0 (LLVMBasicBlockRef, module->max_method_idx + 1);
2457 for (i = 0; i < module->max_method_idx + 1; ++i) {
2458 name = g_strdup_printf ("BB_%d", i);
2459 bb = LLVMAppendBasicBlock (func, name);
2463 builder = LLVMCreateBuilder ();
2464 LLVMPositionBuilderAtEnd (builder, bb);
2466 m = (LLVMValueRef)g_hash_table_lookup (module->idx_to_lmethod, GINT_TO_POINTER (i));
2468 LLVMBuildRet (builder, LLVMBuildBitCast (builder, m, rtype, ""));
2470 LLVMBuildRet (builder, LLVMConstNull (rtype));
2473 fail_bb = LLVMAppendBasicBlock (func, "FAIL");
2474 builder = LLVMCreateBuilder ();
2475 LLVMPositionBuilderAtEnd (builder, fail_bb);
2476 LLVMBuildRet (builder, LLVMConstNull (rtype));
2478 builder = LLVMCreateBuilder ();
2479 LLVMPositionBuilderAtEnd (builder, entry_bb);
2481 switch_ins = LLVMBuildSwitch (builder, LLVMGetParam (func, 0), fail_bb, 0);
2482 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), -1, FALSE), code_start_bb);
2483 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), -2, FALSE), code_end_bb);
2484 for (i = 0; i < module->max_method_idx + 1; ++i) {
2485 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), i, FALSE), bbs [i]);
2488 mark_as_used (module, func);
2492 * emit_get_unbox_tramp:
2494 * Emit a function mapping method indexes to their unbox trampoline
2497 emit_get_unbox_tramp (MonoLLVMModule *module)
2499 LLVMModuleRef lmodule = module->lmodule;
2500 LLVMValueRef func, switch_ins, m;
2501 LLVMBasicBlockRef entry_bb, fail_bb, bb;
2502 LLVMBasicBlockRef *bbs;
2504 LLVMBuilderRef builder;
2508 /* Similar to emit_get_method () */
2510 rtype = LLVMPointerType (LLVMInt8Type (), 0);
2511 func = LLVMAddFunction (lmodule, module->get_unbox_tramp_symbol, LLVMFunctionType1 (rtype, LLVMInt32Type (), FALSE));
2512 LLVMSetLinkage (func, LLVMExternalLinkage);
2513 LLVMSetVisibility (func, LLVMHiddenVisibility);
2514 LLVMAddFunctionAttr (func, LLVMNoUnwindAttribute);
2515 module->get_unbox_tramp = func;
2517 entry_bb = LLVMAppendBasicBlock (func, "ENTRY");
2519 bbs = g_new0 (LLVMBasicBlockRef, module->max_method_idx + 1);
2520 for (i = 0; i < module->max_method_idx + 1; ++i) {
2521 m = (LLVMValueRef)g_hash_table_lookup (module->idx_to_unbox_tramp, GINT_TO_POINTER (i));
2525 name = g_strdup_printf ("BB_%d", i);
2526 bb = LLVMAppendBasicBlock (func, name);
2530 builder = LLVMCreateBuilder ();
2531 LLVMPositionBuilderAtEnd (builder, bb);
2533 LLVMBuildRet (builder, LLVMBuildBitCast (builder, m, rtype, ""));
2536 fail_bb = LLVMAppendBasicBlock (func, "FAIL");
2537 builder = LLVMCreateBuilder ();
2538 LLVMPositionBuilderAtEnd (builder, fail_bb);
2539 LLVMBuildRet (builder, LLVMConstNull (rtype));
2541 builder = LLVMCreateBuilder ();
2542 LLVMPositionBuilderAtEnd (builder, entry_bb);
2544 switch_ins = LLVMBuildSwitch (builder, LLVMGetParam (func, 0), fail_bb, 0);
2545 for (i = 0; i < module->max_method_idx + 1; ++i) {
2546 m = (LLVMValueRef)g_hash_table_lookup (module->idx_to_unbox_tramp, GINT_TO_POINTER (i));
2550 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), i, FALSE), bbs [i]);
2553 mark_as_used (module, func);
2556 /* Add a function to mark the beginning of LLVM code */
2558 emit_llvm_code_start (MonoLLVMModule *module)
2560 LLVMModuleRef lmodule = module->lmodule;
2562 LLVMBasicBlockRef entry_bb;
2563 LLVMBuilderRef builder;
2565 func = LLVMAddFunction (lmodule, "llvm_code_start", LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE));
2566 LLVMSetLinkage (func, LLVMInternalLinkage);
2567 LLVMAddFunctionAttr (func, LLVMNoUnwindAttribute);
2568 module->code_start = func;
2569 entry_bb = LLVMAppendBasicBlock (func, "ENTRY");
2570 builder = LLVMCreateBuilder ();
2571 LLVMPositionBuilderAtEnd (builder, entry_bb);
2572 LLVMBuildRetVoid (builder);
2576 emit_init_icall_wrapper (MonoLLVMModule *module, const char *name, const char *icall_name, int subtype)
2578 LLVMModuleRef lmodule = module->lmodule;
2579 LLVMValueRef func, indexes [2], got_entry_addr, args [16], callee;
2580 LLVMBasicBlockRef entry_bb;
2581 LLVMBuilderRef builder;
2588 func = LLVMAddFunction (lmodule, name, LLVMFunctionType1 (LLVMVoidType (), LLVMInt32Type (), FALSE));
2589 sig = LLVMFunctionType2 (LLVMVoidType (), IntPtrType (), LLVMInt32Type (), FALSE);
2594 func = LLVMAddFunction (lmodule, name, LLVMFunctionType2 (LLVMVoidType (), LLVMInt32Type (), IntPtrType (), FALSE));
2595 sig = LLVMFunctionType3 (LLVMVoidType (), IntPtrType (), LLVMInt32Type (), IntPtrType (), FALSE);
2598 func = LLVMAddFunction (lmodule, name, LLVMFunctionType2 (LLVMVoidType (), LLVMInt32Type (), ObjRefType (), FALSE));
2599 sig = LLVMFunctionType3 (LLVMVoidType (), IntPtrType (), LLVMInt32Type (), ObjRefType (), FALSE);
2602 g_assert_not_reached ();
2604 LLVMSetLinkage (func, LLVMInternalLinkage);
2605 LLVMAddFunctionAttr (func, LLVMNoInlineAttribute);
2606 mono_llvm_set_preserveall_cc (func);
2607 entry_bb = LLVMAppendBasicBlock (func, "ENTRY");
2608 builder = LLVMCreateBuilder ();
2609 LLVMPositionBuilderAtEnd (builder, entry_bb);
2612 ji = g_new0 (MonoJumpInfo, 1);
2613 ji->type = MONO_PATCH_INFO_AOT_MODULE;
2614 ji = mono_aot_patch_info_dup (ji);
2615 got_offset = mono_aot_get_got_offset (ji);
2616 module->max_got_offset = MAX (module->max_got_offset, got_offset);
2617 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
2618 indexes [1] = LLVMConstInt (LLVMInt32Type (), got_offset, FALSE);
2619 got_entry_addr = LLVMBuildGEP (builder, module->got_var, indexes, 2, "");
2620 args [0] = LLVMBuildPtrToInt (builder, LLVMBuildLoad (builder, got_entry_addr, ""), IntPtrType (), "");
2621 args [1] = LLVMGetParam (func, 0);
2623 args [2] = LLVMGetParam (func, 1);
2625 ji = g_new0 (MonoJumpInfo, 1);
2626 ji->type = MONO_PATCH_INFO_INTERNAL_METHOD;
2627 ji->data.name = icall_name;
2628 ji = mono_aot_patch_info_dup (ji);
2629 got_offset = mono_aot_get_got_offset (ji);
2630 module->max_got_offset = MAX (module->max_got_offset, got_offset);
2631 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
2632 indexes [1] = LLVMConstInt (LLVMInt32Type (), got_offset, FALSE);
2633 got_entry_addr = LLVMBuildGEP (builder, module->got_var, indexes, 2, "");
2634 callee = LLVMBuildLoad (builder, got_entry_addr, "");
2635 callee = LLVMBuildBitCast (builder, callee, LLVMPointerType (sig, 0), "");
2636 LLVMBuildCall (builder, callee, args, LLVMCountParamTypes (sig), "");
2638 // Set the inited flag
2639 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
2640 indexes [1] = LLVMGetParam (func, 0);
2641 LLVMBuildStore (builder, LLVMConstInt (LLVMInt8Type (), 1, FALSE), LLVMBuildGEP (builder, module->inited_var, indexes, 2, ""));
2643 LLVMBuildRetVoid (builder);
2645 LLVMVerifyFunction(func, LLVMAbortProcessAction);
2650 * Emit wrappers around the C icalls used to initialize llvm methods, to
2651 * make the calling code smaller and to enable usage of the llvm
2652 * PreserveAll calling convention.
2655 emit_init_icall_wrappers (MonoLLVMModule *module)
2657 module->init_method = emit_init_icall_wrapper (module, "init_method", "mono_aot_init_llvm_method", 0);
2658 module->init_method_gshared_mrgctx = emit_init_icall_wrapper (module, "init_method_gshared_mrgctx", "mono_aot_init_gshared_method_mrgctx", 1);
2659 module->init_method_gshared_this = emit_init_icall_wrapper (module, "init_method_gshared_this", "mono_aot_init_gshared_method_this", 2);
2660 module->init_method_gshared_vtable = emit_init_icall_wrapper (module, "init_method_gshared_vtable", "mono_aot_init_gshared_method_vtable", 3);
2664 emit_llvm_code_end (MonoLLVMModule *module)
2666 LLVMModuleRef lmodule = module->lmodule;
2668 LLVMBasicBlockRef entry_bb;
2669 LLVMBuilderRef builder;
2671 func = LLVMAddFunction (lmodule, "llvm_code_end", LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE));
2672 LLVMSetLinkage (func, LLVMInternalLinkage);
2673 LLVMAddFunctionAttr (func, LLVMNoUnwindAttribute);
2674 module->code_end = func;
2675 entry_bb = LLVMAppendBasicBlock (func, "ENTRY");
2676 builder = LLVMCreateBuilder ();
2677 LLVMPositionBuilderAtEnd (builder, entry_bb);
2678 LLVMBuildRetVoid (builder);
2682 emit_div_check (EmitContext *ctx, LLVMBuilderRef builder, MonoBasicBlock *bb, MonoInst *ins, LLVMValueRef lhs, LLVMValueRef rhs)
2684 gboolean need_div_check = ctx->cfg->backend->need_div_check;
2687 /* LLVM doesn't know that these can throw an exception since they are not called through an intrinsic */
2688 need_div_check = TRUE;
2690 if (!need_div_check)
2693 switch (ins->opcode) {
2706 case OP_IDIV_UN_IMM:
2707 case OP_LDIV_UN_IMM:
2708 case OP_IREM_UN_IMM:
2709 case OP_LREM_UN_IMM: {
2711 gboolean is_signed = (ins->opcode == OP_IDIV || ins->opcode == OP_LDIV || ins->opcode == OP_IREM || ins->opcode == OP_LREM ||
2712 ins->opcode == OP_IDIV_IMM || ins->opcode == OP_LDIV_IMM || ins->opcode == OP_IREM_IMM || ins->opcode == OP_LREM_IMM);
2714 cmp = LLVMBuildICmp (builder, LLVMIntEQ, rhs, LLVMConstInt (LLVMTypeOf (rhs), 0, FALSE), "");
2715 emit_cond_system_exception (ctx, bb, "DivideByZeroException", cmp);
2718 builder = ctx->builder;
2720 /* b == -1 && a == 0x80000000 */
2722 LLVMValueRef c = (LLVMTypeOf (lhs) == LLVMInt32Type ()) ? LLVMConstInt (LLVMTypeOf (lhs), 0x80000000, FALSE) : LLVMConstInt (LLVMTypeOf (lhs), 0x8000000000000000LL, FALSE);
2723 LLVMValueRef cond1 = LLVMBuildICmp (builder, LLVMIntEQ, rhs, LLVMConstInt (LLVMTypeOf (rhs), -1, FALSE), "");
2724 LLVMValueRef cond2 = LLVMBuildICmp (builder, LLVMIntEQ, lhs, c, "");
2726 cmp = LLVMBuildICmp (builder, LLVMIntEQ, LLVMBuildAnd (builder, cond1, cond2, ""), LLVMConstInt (LLVMInt1Type (), 1, FALSE), "");
2727 emit_cond_system_exception (ctx, bb, "OverflowException", cmp);
2730 builder = ctx->builder;
2742 * Emit code to initialize the GOT slots used by the method.
2745 emit_init_method (EmitContext *ctx)
2747 LLVMValueRef indexes [16], args [16], callee;
2748 LLVMValueRef inited_var, cmp, call;
2749 LLVMBasicBlockRef inited_bb, notinited_bb;
2750 LLVMBuilderRef builder = ctx->builder;
2751 MonoCompile *cfg = ctx->cfg;
2753 ctx->module->max_inited_idx = MAX (ctx->module->max_inited_idx, cfg->method_index);
2755 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
2756 indexes [1] = LLVMConstInt (LLVMInt32Type (), cfg->method_index, FALSE);
2757 inited_var = LLVMBuildLoad (builder, LLVMBuildGEP (builder, ctx->module->inited_var, indexes, 2, ""), "is_inited");
2759 args [0] = inited_var;
2760 args [1] = LLVMConstInt (LLVMInt8Type (), 1, FALSE);
2761 inited_var = LLVMBuildCall (ctx->builder, get_intrinsic (ctx, "llvm.expect.i8"), args, 2, "");
2763 cmp = LLVMBuildICmp (builder, LLVMIntEQ, inited_var, LLVMConstInt (LLVMTypeOf (inited_var), 0, FALSE), "");
2765 inited_bb = ctx->inited_bb;
2766 notinited_bb = gen_bb (ctx, "NOTINITED_BB");
2768 LLVMBuildCondBr (ctx->builder, cmp, notinited_bb, inited_bb);
2770 builder = ctx->builder = create_builder (ctx);
2771 LLVMPositionBuilderAtEnd (ctx->builder, notinited_bb);
2774 if (ctx->rgctx_arg && cfg->method->is_inflated && mono_method_get_context (cfg->method)->method_inst) {
2775 args [0] = LLVMConstInt (LLVMInt32Type (), cfg->method_index, 0);
2776 args [1] = convert (ctx, ctx->rgctx_arg, IntPtrType ());
2777 callee = ctx->module->init_method_gshared_mrgctx;
2778 call = LLVMBuildCall (builder, callee, args, 2, "");
2779 } else if (ctx->rgctx_arg) {
2780 /* A vtable is passed as the rgctx argument */
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_vtable;
2784 call = LLVMBuildCall (builder, callee, args, 2, "");
2785 } else if (cfg->gshared) {
2786 args [0] = LLVMConstInt (LLVMInt32Type (), cfg->method_index, 0);
2787 args [1] = convert (ctx, ctx->this_arg, ObjRefType ());
2788 callee = ctx->module->init_method_gshared_this;
2789 call = LLVMBuildCall (builder, callee, args, 2, "");
2791 args [0] = LLVMConstInt (LLVMInt32Type (), cfg->method_index, 0);
2792 callee = ctx->module->init_method;
2793 call = LLVMBuildCall (builder, callee, args, 1, "");
2797 * This enables llvm to keep arguments in their original registers/
2798 * scratch registers, since the call will not clobber them.
2800 mono_llvm_set_call_preserveall_cc (call);
2802 LLVMBuildBr (builder, inited_bb);
2803 ctx->bblocks [cfg->bb_entry->block_num].end_bblock = inited_bb;
2805 builder = ctx->builder = create_builder (ctx);
2806 LLVMPositionBuilderAtEnd (ctx->builder, inited_bb);
2810 emit_unbox_tramp (EmitContext *ctx, const char *method_name, LLVMTypeRef method_type, LLVMValueRef method, int method_index)
2813 * Emit unbox trampoline using a tail call
2815 LLVMValueRef tramp, call, *args;
2816 LLVMBuilderRef builder;
2817 LLVMBasicBlockRef lbb;
2818 LLVMCallInfo *linfo;
2822 tramp_name = g_strdup_printf ("ut_%s", method_name);
2823 tramp = LLVMAddFunction (ctx->module->lmodule, tramp_name, method_type);
2824 LLVMSetLinkage (tramp, LLVMInternalLinkage);
2825 LLVMAddFunctionAttr (tramp, LLVMOptimizeForSizeAttribute);
2826 //LLVMAddFunctionAttr (tramp, LLVMNoUnwindAttribute);
2828 // FIXME: Reduce code duplication with mono_llvm_compile_method () etc.
2829 if (!ctx->llvm_only && ctx->rgctx_arg_pindex != -1)
2830 LLVMAddAttribute (LLVMGetParam (tramp, ctx->rgctx_arg_pindex), LLVMInRegAttribute);
2831 if (ctx->cfg->vret_addr) {
2832 LLVMSetValueName (LLVMGetParam (tramp, linfo->vret_arg_pindex), "vret");
2833 if (linfo->ret.storage == LLVMArgVtypeByRef) {
2834 LLVMAddAttribute (LLVMGetParam (tramp, linfo->vret_arg_pindex), LLVMStructRetAttribute);
2835 LLVMAddAttribute (LLVMGetParam (tramp, linfo->vret_arg_pindex), LLVMNoAliasAttribute);
2839 lbb = LLVMAppendBasicBlock (tramp, "");
2840 builder = LLVMCreateBuilder ();
2841 LLVMPositionBuilderAtEnd (builder, lbb);
2843 nargs = LLVMCountParamTypes (method_type);
2844 args = g_new0 (LLVMValueRef, nargs);
2845 for (i = 0; i < nargs; ++i) {
2846 args [i] = LLVMGetParam (tramp, i);
2847 if (i == ctx->this_arg_pindex) {
2848 LLVMTypeRef arg_type = LLVMTypeOf (args [i]);
2850 args [i] = LLVMBuildPtrToInt (builder, args [i], IntPtrType (), "");
2851 args [i] = LLVMBuildAdd (builder, args [i], LLVMConstInt (IntPtrType (), sizeof (MonoObject), FALSE), "");
2852 args [i] = LLVMBuildIntToPtr (builder, args [i], arg_type, "");
2855 call = LLVMBuildCall (builder, method, args, nargs, "");
2856 if (!ctx->llvm_only && ctx->rgctx_arg_pindex != -1)
2857 LLVMAddInstrAttribute (call, 1 + ctx->rgctx_arg_pindex, LLVMInRegAttribute);
2858 if (linfo->ret.storage == LLVMArgVtypeByRef)
2859 LLVMAddInstrAttribute (call, 1 + linfo->vret_arg_pindex, LLVMStructRetAttribute);
2861 // FIXME: This causes assertions in clang
2862 //mono_llvm_set_must_tail (call);
2863 if (LLVMGetReturnType (method_type) == LLVMVoidType ())
2864 LLVMBuildRetVoid (builder);
2866 LLVMBuildRet (builder, call);
2868 g_hash_table_insert (ctx->module->idx_to_unbox_tramp, GINT_TO_POINTER (method_index), tramp);
2874 * Emit code to load/convert arguments.
2877 emit_entry_bb (EmitContext *ctx, LLVMBuilderRef builder)
2880 MonoCompile *cfg = ctx->cfg;
2881 MonoMethodSignature *sig = ctx->sig;
2882 LLVMCallInfo *linfo = ctx->linfo;
2886 LLVMBuilderRef old_builder = ctx->builder;
2887 ctx->builder = builder;
2889 ctx->alloca_builder = create_builder (ctx);
2892 * Handle indirect/volatile variables by allocating memory for them
2893 * using 'alloca', and storing their address in a temporary.
2895 for (i = 0; i < cfg->num_varinfo; ++i) {
2896 MonoInst *var = cfg->varinfo [i];
2899 if (var->opcode == OP_GSHAREDVT_LOCAL || var->opcode == OP_GSHAREDVT_ARG_REGOFFSET) {
2900 } 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))) {
2901 vtype = type_to_llvm_type (ctx, var->inst_vtype);
2904 /* Could be already created by an OP_VPHI */
2905 if (!ctx->addresses [var->dreg]) {
2906 ctx->addresses [var->dreg] = build_alloca (ctx, var->inst_vtype);
2907 //LLVMSetValueName (ctx->addresses [var->dreg], g_strdup_printf ("vreg_loc_%d", var->dreg));
2909 ctx->vreg_cli_types [var->dreg] = var->inst_vtype;
2913 names = g_new (char *, sig->param_count);
2914 mono_method_get_param_names (cfg->method, (const char **) names);
2916 for (i = 0; i < sig->param_count; ++i) {
2917 LLVMArgInfo *ainfo = &linfo->args [i + sig->hasthis];
2918 int reg = cfg->args [i + sig->hasthis]->dreg;
2921 pindex = ainfo->pindex;
2923 switch (ainfo->storage) {
2924 case LLVMArgVtypeInReg:
2925 case LLVMArgAsFpArgs: {
2926 LLVMValueRef args [8];
2929 pindex += ainfo->ndummy_fpargs;
2931 /* The argument is received as a set of int/fp arguments, store them into the real argument */
2932 memset (args, 0, sizeof (args));
2933 if (ainfo->storage == LLVMArgVtypeInReg) {
2934 args [0] = LLVMGetParam (ctx->lmethod, pindex);
2935 if (ainfo->pair_storage [1] != LLVMArgNone)
2936 args [1] = LLVMGetParam (ctx->lmethod, pindex + 1);
2938 g_assert (ainfo->nslots <= 8);
2939 for (j = 0; j < ainfo->nslots; ++j)
2940 args [j] = LLVMGetParam (ctx->lmethod, pindex + j);
2942 ctx->addresses [reg] = build_alloca (ctx, ainfo->type);
2944 emit_args_to_vtype (ctx, builder, ainfo->type, ctx->addresses [reg], ainfo, args);
2946 if (ainfo->storage == LLVMArgVtypeInReg && MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (ainfo->type))) {
2947 /* Treat these as normal values */
2948 ctx->values [reg] = LLVMBuildLoad (builder, ctx->addresses [reg], "");
2952 case LLVMArgVtypeByVal: {
2953 ctx->addresses [reg] = LLVMGetParam (ctx->lmethod, pindex);
2955 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (ainfo->type))) {
2956 /* Treat these as normal values */
2957 ctx->values [reg] = LLVMBuildLoad (builder, ctx->addresses [reg], "");
2961 case LLVMArgVtypeByRef: {
2962 /* The argument is passed by ref */
2963 ctx->addresses [reg] = LLVMGetParam (ctx->lmethod, pindex);
2966 case LLVMArgAsIArgs: {
2967 LLVMValueRef arg = LLVMGetParam (ctx->lmethod, pindex);
2970 /* The argument is received as an array of ints, store it into the real argument */
2971 ctx->addresses [reg] = build_alloca (ctx, ainfo->type);
2973 size = mono_class_value_size (mono_class_from_mono_type (ainfo->type), NULL);
2974 if (size < SIZEOF_VOID_P) {
2975 /* The upper bits of the registers might not be valid */
2976 LLVMValueRef val = LLVMBuildExtractValue (builder, arg, 0, "");
2977 LLVMValueRef dest = convert (ctx, ctx->addresses [reg], LLVMPointerType (LLVMIntType (size * 8), 0));
2978 LLVMBuildStore (ctx->builder, LLVMBuildTrunc (builder, val, LLVMIntType (size * 8), ""), dest);
2980 LLVMBuildStore (ctx->builder, arg, convert (ctx, ctx->addresses [reg], LLVMPointerType (LLVMTypeOf (arg), 0)));
2984 case LLVMArgVtypeAsScalar:
2985 g_assert_not_reached ();
2987 case LLVMArgGsharedvtFixed: {
2988 /* These are non-gsharedvt arguments passed by ref, the rest of the IR treats them as scalars */
2989 LLVMValueRef arg = LLVMGetParam (ctx->lmethod, pindex);
2992 name = g_strdup_printf ("arg_%s", names [i]);
2994 name = g_strdup_printf ("arg_%d", i);
2996 ctx->values [reg] = LLVMBuildLoad (builder, convert (ctx, arg, LLVMPointerType (type_to_llvm_type (ctx, ainfo->type), 0)), name);
2999 case LLVMArgGsharedvtFixedVtype: {
3000 LLVMValueRef arg = LLVMGetParam (ctx->lmethod, pindex);
3003 name = g_strdup_printf ("vtype_arg_%s", names [i]);
3005 name = g_strdup_printf ("vtype_arg_%d", i);
3007 /* Non-gsharedvt vtype argument passed by ref, the rest of the IR treats it as a vtype */
3008 g_assert (ctx->addresses [reg]);
3009 LLVMSetValueName (ctx->addresses [reg], name);
3010 LLVMBuildStore (builder, LLVMBuildLoad (builder, convert (ctx, arg, LLVMPointerType (type_to_llvm_type (ctx, ainfo->type), 0)), ""), ctx->addresses [reg]);
3013 case LLVMArgGsharedvtVariable:
3014 /* The IR treats these as variables with addresses */
3015 ctx->addresses [reg] = LLVMGetParam (ctx->lmethod, pindex);
3018 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));
3025 emit_volatile_store (ctx, cfg->vret_addr->dreg);
3027 emit_volatile_store (ctx, cfg->args [0]->dreg);
3028 for (i = 0; i < sig->param_count; ++i)
3029 if (!mini_type_is_vtype (sig->params [i]))
3030 emit_volatile_store (ctx, cfg->args [i + sig->hasthis]->dreg);
3032 if (sig->hasthis && !cfg->rgctx_var && cfg->gshared) {
3033 LLVMValueRef this_alloc;
3036 * The exception handling code needs the location where the this argument was
3037 * stored for gshared methods. We create a separate alloca to hold it, and mark it
3038 * with the "mono.this" custom metadata to tell llvm that it needs to save its
3039 * location into the LSDA.
3041 this_alloc = mono_llvm_build_alloca (builder, ThisType (), LLVMConstInt (LLVMInt32Type (), 1, FALSE), 0, "");
3042 /* This volatile store will keep the alloca alive */
3043 mono_llvm_build_store (builder, ctx->values [cfg->args [0]->dreg], this_alloc, TRUE, LLVM_BARRIER_NONE);
3045 set_metadata_flag (this_alloc, "mono.this");
3048 if (cfg->rgctx_var) {
3049 LLVMValueRef rgctx_alloc, store;
3052 * We handle the rgctx arg similarly to the this pointer.
3054 g_assert (ctx->addresses [cfg->rgctx_var->dreg]);
3055 rgctx_alloc = ctx->addresses [cfg->rgctx_var->dreg];
3056 /* This volatile store will keep the alloca alive */
3057 store = mono_llvm_build_store (builder, convert (ctx, ctx->rgctx_arg, IntPtrType ()), rgctx_alloc, TRUE, LLVM_BARRIER_NONE);
3059 set_metadata_flag (rgctx_alloc, "mono.this");
3062 /* Initialize the method if needed */
3063 if (cfg->compile_aot && ctx->llvm_only) {
3064 /* Emit a location for the initialization code */
3065 ctx->init_bb = gen_bb (ctx, "INIT_BB");
3066 ctx->inited_bb = gen_bb (ctx, "INITED_BB");
3068 LLVMBuildBr (ctx->builder, ctx->init_bb);
3069 builder = ctx->builder = create_builder (ctx);
3070 LLVMPositionBuilderAtEnd (ctx->builder, ctx->inited_bb);
3071 ctx->bblocks [cfg->bb_entry->block_num].end_bblock = ctx->inited_bb;
3074 /* Compute nesting between clauses */
3075 ctx->nested_in = (GSList**)mono_mempool_alloc0 (cfg->mempool, sizeof (GSList*) * cfg->header->num_clauses);
3076 for (i = 0; i < cfg->header->num_clauses; ++i) {
3077 for (j = 0; j < cfg->header->num_clauses; ++j) {
3078 MonoExceptionClause *clause1 = &cfg->header->clauses [i];
3079 MonoExceptionClause *clause2 = &cfg->header->clauses [j];
3081 if (i != j && clause1->try_offset >= clause2->try_offset && clause1->handler_offset <= clause2->handler_offset)
3082 ctx->nested_in [i] = g_slist_prepend_mempool (cfg->mempool, ctx->nested_in [i], GINT_TO_POINTER (j));
3087 * For finally clauses, create an indicator variable telling OP_ENDFINALLY whenever
3088 * it needs to continue normally, or return back to the exception handling system.
3090 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
3094 if (!(bb->region != -1 && (bb->flags & BB_EXCEPTION_HANDLER)))
3097 clause_index = MONO_REGION_CLAUSE_INDEX (bb->region);
3098 g_hash_table_insert (ctx->region_to_handler, GUINT_TO_POINTER (mono_get_block_region_notry (cfg, bb->region)), bb);
3099 g_hash_table_insert (ctx->clause_to_handler, GINT_TO_POINTER (clause_index), bb);
3101 if (bb->in_scount == 0) {
3104 sprintf (name, "finally_ind_bb%d", bb->block_num);
3105 val = LLVMBuildAlloca (builder, LLVMInt32Type (), name);
3106 LLVMBuildStore (builder, LLVMConstInt (LLVMInt32Type (), 0, FALSE), val);
3108 ctx->bblocks [bb->block_num].finally_ind = val;
3110 /* Create a variable to hold the exception var */
3112 ctx->ex_var = LLVMBuildAlloca (builder, ObjRefType (), "exvar");
3116 * Create a new bblock which CALL_HANDLER/landing pads can branch to, because branching to the
3117 * LLVM bblock containing a landing pad causes problems for the
3118 * LLVM optimizer passes.
3120 sprintf (name, "BB%d_CALL_HANDLER_TARGET", bb->block_num);
3121 ctx->bblocks [bb->block_num].call_handler_target_bb = LLVMAppendBasicBlock (ctx->lmethod, name);
3123 ctx->builder = old_builder;
3127 process_call (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, MonoInst *ins)
3129 MonoCompile *cfg = ctx->cfg;
3130 LLVMValueRef *values = ctx->values;
3131 LLVMValueRef *addresses = ctx->addresses;
3132 MonoCallInst *call = (MonoCallInst*)ins;
3133 MonoMethodSignature *sig = call->signature;
3134 LLVMValueRef callee = NULL, lcall;
3136 LLVMCallInfo *cinfo;
3140 LLVMTypeRef llvm_sig;
3142 gboolean is_virtual, calli, preserveall;
3143 LLVMBuilderRef builder = *builder_ref;
3145 if ((call->signature->call_convention != MONO_CALL_DEFAULT) && !((call->signature->call_convention == MONO_CALL_C) && ctx->llvm_only)) {
3146 set_failure (ctx, "non-default callconv");
3150 cinfo = call->cinfo;
3152 if (call->rgctx_arg_reg)
3153 cinfo->rgctx_arg = TRUE;
3154 if (call->imt_arg_reg)
3155 cinfo->imt_arg = TRUE;
3157 vretaddr = (cinfo->ret.storage == LLVMArgVtypeRetAddr || cinfo->ret.storage == LLVMArgVtypeByRef || cinfo->ret.storage == LLVMArgGsharedvtFixed || cinfo->ret.storage == LLVMArgGsharedvtVariable || cinfo->ret.storage == LLVMArgGsharedvtFixedVtype);
3159 llvm_sig = sig_to_llvm_sig_full (ctx, sig, cinfo);
3163 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);
3164 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);
3166 preserveall = FALSE;
3168 /* FIXME: Avoid creating duplicate methods */
3170 if (ins->flags & MONO_INST_HAS_METHOD) {
3174 if (cfg->compile_aot) {
3175 callee = get_callee (ctx, llvm_sig, MONO_PATCH_INFO_METHOD, call->method);
3177 set_failure (ctx, "can't encode patch");
3180 if (cfg->llvm_only && call->method->klass->image->assembly == ctx->module->assembly) {
3182 * Collect instructions representing the callee into a hash so they can be replaced
3183 * by the llvm method for the callee if the callee turns out to be direct
3184 * callable. Currently this only requires it to not fail llvm compilation.
3186 GSList *l = (GSList*)g_hash_table_lookup (ctx->method_to_callers, call->method);
3187 l = g_slist_prepend (l, callee);
3188 g_hash_table_insert (ctx->method_to_callers, call->method, l);
3192 static int tramp_index;
3195 name = g_strdup_printf ("tramp_%d", tramp_index);
3198 #if LLVM_API_VERSION > 100
3200 * Use our trampoline infrastructure for lazy compilation instead of llvm's.
3201 * Make all calls through a global. The address of the global will be saved in
3202 * MonoJitDomainInfo.llvm_jit_callees and updated when the method it refers to is
3205 LLVMValueRef tramp_var = g_hash_table_lookup (ctx->jit_callees, call->method);
3208 mono_create_jit_trampoline (mono_domain_get (),
3209 call->method, &error);
3210 if (!is_ok (&error)) {
3211 set_failure (ctx, mono_error_get_message (&error));
3212 mono_error_cleanup (&error);
3216 tramp_var = LLVMAddGlobal (ctx->lmodule, LLVMPointerType (llvm_sig, 0), name);
3217 LLVMSetInitializer (tramp_var, LLVMConstIntToPtr (LLVMConstInt (LLVMInt64Type (), (guint64)(size_t)target, FALSE), LLVMPointerType (llvm_sig, 0)));
3218 LLVMSetLinkage (tramp_var, LLVMExternalLinkage);
3219 g_hash_table_insert (ctx->jit_callees, call->method, tramp_var);
3221 callee = LLVMBuildLoad (builder, tramp_var, "");
3224 mono_create_jit_trampoline (mono_domain_get (),
3225 call->method, &error);
3226 if (!is_ok (&error)) {
3228 set_failure (ctx, mono_error_get_message (&error));
3229 mono_error_cleanup (&error);
3233 callee = LLVMAddFunction (ctx->lmodule, name, llvm_sig);
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 LLVMArgAsIArgs:
3542 case LLVMArgFpStruct:
3543 if (!addresses [call->inst.dreg])
3544 addresses [call->inst.dreg] = build_alloca (ctx, sig->ret);
3545 LLVMBuildStore (builder, lcall, convert_full (ctx, addresses [call->inst.dreg], LLVMPointerType (LLVMTypeOf (lcall), 0), FALSE));
3547 case LLVMArgVtypeAsScalar:
3548 if (!addresses [call->inst.dreg])
3549 addresses [call->inst.dreg] = build_alloca (ctx, sig->ret);
3550 LLVMBuildStore (builder, lcall, convert_full (ctx, addresses [call->inst.dreg], LLVMPointerType (LLVMTypeOf (lcall), 0), FALSE));
3552 case LLVMArgVtypeRetAddr:
3553 case LLVMArgVtypeByRef:
3554 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (sig->ret))) {
3555 /* Some opcodes like STOREX_MEMBASE access these by value */
3556 g_assert (addresses [call->inst.dreg]);
3557 values [ins->dreg] = LLVMBuildLoad (builder, convert_full (ctx, addresses [call->inst.dreg], LLVMPointerType (type_to_llvm_type (ctx, sig->ret), 0), FALSE), "");
3560 case LLVMArgGsharedvtVariable:
3562 case LLVMArgGsharedvtFixed:
3563 case LLVMArgGsharedvtFixedVtype:
3564 values [ins->dreg] = LLVMBuildLoad (builder, convert_full (ctx, addresses [call->inst.dreg], LLVMPointerType (type_to_llvm_type (ctx, sig->ret), 0), FALSE), "");
3567 if (sig->ret->type != MONO_TYPE_VOID)
3568 /* If the method returns an unsigned value, need to zext it */
3569 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));
3573 *builder_ref = ctx->builder;
3577 emit_llvmonly_throw (EmitContext *ctx, MonoBasicBlock *bb, gboolean rethrow, LLVMValueRef exc)
3579 const char *icall_name = rethrow ? "mono_llvm_rethrow_exception" : "mono_llvm_throw_exception";
3580 LLVMValueRef callee = rethrow ? ctx->module->rethrow : ctx->module->throw_icall;
3582 LLVMTypeRef exc_type = type_to_llvm_type (ctx, &mono_get_exception_class ()->byval_arg);
3585 LLVMTypeRef fun_sig = LLVMFunctionType1 (LLVMVoidType (), exc_type, FALSE);
3587 if (ctx->cfg->compile_aot) {
3588 callee = get_callee (ctx, fun_sig, MONO_PATCH_INFO_JIT_ICALL_ADDR, icall_name);
3590 callee = LLVMAddFunction (ctx->lmodule, icall_name, fun_sig);
3591 LLVMAddGlobalMapping (ctx->module->ee, callee, resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name));
3592 mono_memory_barrier ();
3595 ctx->module->rethrow = callee;
3597 ctx->module->throw_icall = callee;
3601 LLVMValueRef args [2];
3603 args [0] = convert (ctx, exc, exc_type);
3604 emit_call (ctx, bb, &ctx->builder, callee, args, 1);
3606 LLVMBuildUnreachable (ctx->builder);
3608 ctx->builder = create_builder (ctx);
3612 emit_throw (EmitContext *ctx, MonoBasicBlock *bb, gboolean rethrow, LLVMValueRef exc)
3614 MonoMethodSignature *throw_sig;
3615 LLVMValueRef callee, arg;
3616 const char *icall_name;
3618 callee = rethrow ? ctx->module->rethrow : ctx->module->throw_icall;
3619 icall_name = rethrow ? "mono_arch_rethrow_exception" : "mono_arch_throw_exception";
3622 throw_sig = mono_metadata_signature_alloc (mono_get_corlib (), 1);
3623 throw_sig->ret = &mono_get_void_class ()->byval_arg;
3624 throw_sig->params [0] = &mono_get_object_class ()->byval_arg;
3625 if (ctx->cfg->compile_aot) {
3626 callee = get_callee (ctx, sig_to_llvm_sig (ctx, throw_sig), MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
3631 * LLVM doesn't push the exception argument, so we need a different
3634 target = resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, rethrow ? "llvm_rethrow_exception_trampoline" : "llvm_throw_exception_trampoline");
3636 target = resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
3638 callee = emit_jit_callee (ctx, icall_name, sig_to_llvm_sig (ctx, throw_sig), target);
3641 mono_memory_barrier ();
3642 #if LLVM_API_VERSION < 100
3644 ctx->module->rethrow = callee;
3646 ctx->module->throw_icall = callee;
3649 arg = convert (ctx, exc, type_to_llvm_type (ctx, &mono_get_object_class ()->byval_arg));
3650 emit_call (ctx, bb, &ctx->builder, callee, &arg, 1);
3654 emit_resume_eh (EmitContext *ctx, MonoBasicBlock *bb)
3656 const char *icall_name = "mono_llvm_resume_exception";
3657 LLVMValueRef callee = ctx->module->resume_eh;
3659 LLVMTypeRef fun_sig = LLVMFunctionType0 (LLVMVoidType (), FALSE);
3662 if (ctx->cfg->compile_aot) {
3663 callee = get_callee (ctx, fun_sig, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
3665 callee = LLVMAddFunction (ctx->lmodule, icall_name, fun_sig);
3666 LLVMAddGlobalMapping (ctx->module->ee, callee, resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name));
3667 mono_memory_barrier ();
3669 ctx->module->resume_eh = callee;
3673 emit_call (ctx, bb, &ctx->builder, callee, NULL, 0);
3675 LLVMBuildUnreachable (ctx->builder);
3677 ctx->builder = create_builder (ctx);
3681 mono_llvm_emit_clear_exception_call (EmitContext *ctx, LLVMBuilderRef builder)
3683 const char *icall_name = "mono_llvm_clear_exception";
3685 LLVMTypeRef call_sig = LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE);
3686 LLVMValueRef callee = NULL;
3689 if (ctx->cfg->compile_aot) {
3690 callee = get_callee (ctx, call_sig, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
3692 // FIXME: This is broken.
3693 callee = LLVMAddFunction (ctx->lmodule, icall_name, call_sig);
3697 g_assert (builder && callee);
3699 return LLVMBuildCall (builder, callee, NULL, 0, "");
3703 mono_llvm_emit_load_exception_call (EmitContext *ctx, LLVMBuilderRef builder)
3705 const char *icall_name = "mono_llvm_load_exception";
3707 LLVMTypeRef call_sig = LLVMFunctionType (ObjRefType (), NULL, 0, FALSE);
3708 LLVMValueRef callee = NULL;
3711 if (ctx->cfg->compile_aot) {
3712 callee = get_callee (ctx, call_sig, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
3714 // FIXME: This is broken.
3715 callee = LLVMAddFunction (ctx->lmodule, icall_name, call_sig);
3719 g_assert (builder && callee);
3721 return LLVMBuildCall (builder, callee, NULL, 0, icall_name);
3726 mono_llvm_emit_match_exception_call (EmitContext *ctx, LLVMBuilderRef builder, gint32 region_start, gint32 region_end)
3728 const char *icall_name = "mono_llvm_match_exception";
3730 ctx->builder = builder;
3732 const int num_args = 5;
3733 LLVMValueRef args [num_args];
3734 args [0] = convert (ctx, get_aotconst (ctx, MONO_PATCH_INFO_AOT_JIT_INFO, GINT_TO_POINTER (ctx->cfg->method_index)), IntPtrType ());
3735 args [1] = LLVMConstInt (LLVMInt32Type (), region_start, 0);
3736 args [2] = LLVMConstInt (LLVMInt32Type (), region_end, 0);
3737 if (ctx->cfg->rgctx_var) {
3738 LLVMValueRef rgctx_alloc = ctx->addresses [ctx->cfg->rgctx_var->dreg];
3739 g_assert (rgctx_alloc);
3740 args [3] = LLVMBuildLoad (builder, convert (ctx, rgctx_alloc, LLVMPointerType (IntPtrType (), 0)), "");
3742 args [3] = LLVMConstInt (IntPtrType (), 0, 0);
3745 args [4] = convert (ctx, ctx->this_arg, IntPtrType ());
3747 args [4] = LLVMConstInt (IntPtrType (), 0, 0);
3749 LLVMTypeRef match_sig = LLVMFunctionType5 (LLVMInt32Type (), IntPtrType (), LLVMInt32Type (), LLVMInt32Type (), IntPtrType (), IntPtrType (), FALSE);
3750 LLVMValueRef callee = ctx->module->match_exc;
3753 if (ctx->cfg->compile_aot) {
3754 ctx->builder = builder;
3755 // get_callee expects ctx->builder to be the emitting builder
3756 callee = get_callee (ctx, match_sig, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
3758 callee = ctx->module->match_exc = LLVMAddFunction (ctx->lmodule, icall_name, match_sig);
3759 LLVMAddGlobalMapping (ctx->module->ee, ctx->module->match_exc, resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name));
3760 ctx->module->match_exc = callee;
3761 mono_memory_barrier ();
3765 g_assert (builder && callee);
3767 g_assert (ctx->ex_var);
3769 return LLVMBuildCall (builder, callee, args, num_args, icall_name);
3772 // FIXME: This won't work because the code-finding makes this
3774 /*#define MONO_PERSONALITY_DEBUG*/
3776 #ifdef MONO_PERSONALITY_DEBUG
3777 static const gboolean use_debug_personality = TRUE;
3778 static const char *default_personality_name = "mono_debug_personality";
3780 static const gboolean use_debug_personality = FALSE;
3781 static const char *default_personality_name = "__gxx_personality_v0";
3785 default_cpp_lpad_exc_signature (void)
3787 static gboolean inited = FALSE;
3788 static LLVMTypeRef sig;
3791 LLVMTypeRef signature [2];
3792 signature [0] = LLVMPointerType (LLVMInt8Type (), 0);
3793 signature [1] = LLVMInt32Type ();
3794 sig = LLVMStructType (signature, 2, FALSE);
3802 get_mono_personality (EmitContext *ctx)
3804 LLVMValueRef personality = NULL;
3805 static gint32 mapping_inited = FALSE;
3806 LLVMTypeRef personality_type = LLVMFunctionType (LLVMInt32Type (), NULL, 0, TRUE);
3808 if (!use_debug_personality) {
3809 if (ctx->cfg->compile_aot) {
3810 personality = get_intrinsic (ctx, default_personality_name);
3811 } else if (InterlockedCompareExchange (&mapping_inited, 1, 0) == 0) {
3812 personality = LLVMAddFunction (ctx->lmodule, default_personality_name, personality_type);
3813 LLVMAddGlobalMapping (ctx->module->ee, personality, personality);
3816 if (ctx->cfg->compile_aot) {
3817 personality = get_callee (ctx, personality_type, MONO_PATCH_INFO_INTERNAL_METHOD, default_personality_name);
3819 personality = LLVMAddFunction (ctx->lmodule, default_personality_name, personality_type);
3820 LLVMAddGlobalMapping (ctx->module->ee, personality, resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, default_personality_name));
3821 mono_memory_barrier ();
3825 g_assert (personality);
3829 static LLVMBasicBlockRef
3830 emit_landing_pad (EmitContext *ctx, int group_index, int group_size)
3832 MonoCompile *cfg = ctx->cfg;
3833 LLVMBuilderRef old_builder = ctx->builder;
3834 MonoExceptionClause *group_start = cfg->header->clauses + group_index;
3836 LLVMBuilderRef lpadBuilder = create_builder (ctx);
3837 ctx->builder = lpadBuilder;
3839 MonoBasicBlock *handler_bb = cfg->cil_offset_to_bb [CLAUSE_START (group_start)];
3840 g_assert (handler_bb);
3842 // <resultval> = landingpad <somety> personality <type> <pers_fn> <clause>+
3843 LLVMValueRef personality = get_mono_personality (ctx);
3844 g_assert (personality);
3846 char *bb_name = g_strdup_printf ("LPAD%d_BB", group_index);
3847 LLVMBasicBlockRef lpad_bb = gen_bb (ctx, bb_name);
3849 LLVMPositionBuilderAtEnd (lpadBuilder, lpad_bb);
3850 LLVMValueRef landing_pad = LLVMBuildLandingPad (lpadBuilder, default_cpp_lpad_exc_signature (), personality, 0, "");
3851 g_assert (landing_pad);
3853 LLVMValueRef cast = LLVMBuildBitCast (lpadBuilder, ctx->module->sentinel_exception, LLVMPointerType (LLVMInt8Type (), 0), "int8TypeInfo");
3854 LLVMAddClause (landing_pad, cast);
3856 LLVMBasicBlockRef resume_bb = gen_bb (ctx, "RESUME_BB");
3857 LLVMBuilderRef resume_builder = create_builder (ctx);
3858 ctx->builder = resume_builder;
3859 LLVMPositionBuilderAtEnd (resume_builder, resume_bb);
3861 emit_resume_eh (ctx, handler_bb);
3864 ctx->builder = lpadBuilder;
3865 LLVMPositionBuilderAtEnd (lpadBuilder, lpad_bb);
3867 gboolean finally_only = TRUE;
3869 MonoExceptionClause *group_cursor = group_start;
3871 for (int i = 0; i < group_size; i ++) {
3872 if (!(group_cursor->flags & MONO_EXCEPTION_CLAUSE_FINALLY))
3873 finally_only = FALSE;
3879 // Handle landing pad inlining
3881 if (!finally_only) {
3882 // So at each level of the exception stack we will match the exception again.
3883 // During that match, we need to compare against the handler types for the current
3884 // protected region. We send the try start and end so that we can only check against
3885 // handlers for this lexical protected region.
3886 LLVMValueRef match = mono_llvm_emit_match_exception_call (ctx, lpadBuilder, group_start->try_offset, group_start->try_offset + group_start->try_len);
3888 // if returns -1, resume
3889 LLVMValueRef switch_ins = LLVMBuildSwitch (lpadBuilder, match, resume_bb, group_size);
3891 // else move to that target bb
3892 for (int i=0; i < group_size; i++) {
3893 MonoExceptionClause *clause = group_start + i;
3894 int clause_index = clause - cfg->header->clauses;
3895 MonoBasicBlock *handler_bb = (MonoBasicBlock*)g_hash_table_lookup (ctx->clause_to_handler, GINT_TO_POINTER (clause_index));
3896 g_assert (handler_bb);
3897 g_assert (ctx->bblocks [handler_bb->block_num].call_handler_target_bb);
3898 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), clause_index, FALSE), ctx->bblocks [handler_bb->block_num].call_handler_target_bb);
3901 int clause_index = group_start - cfg->header->clauses;
3902 MonoBasicBlock *finally_bb = (MonoBasicBlock*)g_hash_table_lookup (ctx->clause_to_handler, GINT_TO_POINTER (clause_index));
3903 g_assert (finally_bb);
3905 LLVMBuildBr (ctx->builder, ctx->bblocks [finally_bb->block_num].call_handler_target_bb);
3908 ctx->builder = old_builder;
3915 emit_llvmonly_handler_start (EmitContext *ctx, MonoBasicBlock *bb, LLVMBasicBlockRef cbb)
3917 int clause_index = MONO_REGION_CLAUSE_INDEX (bb->region);
3918 MonoExceptionClause *clause = &ctx->cfg->header->clauses [clause_index];
3920 // Make exception available to catch blocks
3921 if (!(clause->flags & MONO_EXCEPTION_CLAUSE_FINALLY)) {
3922 LLVMValueRef mono_exc = mono_llvm_emit_load_exception_call (ctx, ctx->builder);
3924 g_assert (ctx->ex_var);
3925 LLVMBuildStore (ctx->builder, LLVMBuildBitCast (ctx->builder, mono_exc, ObjRefType (), ""), ctx->ex_var);
3927 if (bb->in_scount == 1) {
3928 MonoInst *exvar = bb->in_stack [0];
3929 g_assert (!ctx->values [exvar->dreg]);
3930 g_assert (ctx->ex_var);
3931 ctx->values [exvar->dreg] = LLVMBuildLoad (ctx->builder, ctx->ex_var, "save_exception");
3932 emit_volatile_store (ctx, exvar->dreg);
3935 mono_llvm_emit_clear_exception_call (ctx, ctx->builder);
3938 LLVMBuilderRef handler_builder = create_builder (ctx);
3939 LLVMBasicBlockRef target_bb = ctx->bblocks [bb->block_num].call_handler_target_bb;
3940 LLVMPositionBuilderAtEnd (handler_builder, target_bb);
3942 // Make the handler code end with a jump to cbb
3943 LLVMBuildBr (handler_builder, cbb);
3947 emit_handler_start (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef builder)
3949 MonoCompile *cfg = ctx->cfg;
3950 LLVMValueRef *values = ctx->values;
3951 LLVMModuleRef lmodule = ctx->lmodule;
3952 BBInfo *bblocks = ctx->bblocks;
3954 LLVMValueRef personality;
3955 LLVMValueRef landing_pad;
3956 LLVMBasicBlockRef target_bb;
3958 static int ti_generator;
3960 LLVMValueRef type_info;
3964 // <resultval> = landingpad <somety> personality <type> <pers_fn> <clause>+
3966 if (cfg->compile_aot) {
3967 /* Use a dummy personality function */
3968 personality = LLVMGetNamedFunction (lmodule, "mono_personality");
3969 g_assert (personality);
3971 #if LLVM_API_VERSION > 100
3972 LLVMTypeRef personality_type = LLVMFunctionType (LLVMInt32Type (), NULL, 0, TRUE);
3973 personality = LLVMAddFunction (ctx->lmodule, "mono_personality", personality_type);
3974 LLVMAddFunctionAttr (personality, LLVMNoUnwindAttribute);
3975 LLVMBasicBlockRef entry_bb = LLVMAppendBasicBlock (personality, "ENTRY");
3976 LLVMBuilderRef builder2 = LLVMCreateBuilder ();
3977 LLVMPositionBuilderAtEnd (builder2, entry_bb);
3978 LLVMBuildRet (builder2, LLVMConstInt (LLVMInt32Type (), 0, FALSE));
3980 static gint32 mapping_inited;
3982 personality = LLVMGetNamedFunction (lmodule, "mono_personality");
3984 if (InterlockedCompareExchange (&mapping_inited, 1, 0) == 0)
3985 LLVMAddGlobalMapping (ctx->module->ee, personality, (gpointer)mono_personality);
3989 i8ptr = LLVMPointerType (LLVMInt8Type (), 0);
3991 clause_index = (mono_get_block_region_notry (cfg, bb->region) >> 8) - 1;
3994 * Create the type info
3996 sprintf (ti_name, "type_info_%d", ti_generator);
3999 if (cfg->compile_aot) {
4000 /* decode_eh_frame () in aot-runtime.c will decode this */
4001 type_info = LLVMAddGlobal (lmodule, LLVMInt32Type (), ti_name);
4002 LLVMSetInitializer (type_info, LLVMConstInt (LLVMInt32Type (), clause_index, FALSE));
4005 * These symbols are not really used, the clause_index is embedded into the EH tables generated by DwarfMonoException in LLVM.
4007 LLVMSetLinkage (type_info, LLVMInternalLinkage);
4009 #if LLVM_API_VERSION > 100
4010 type_info = LLVMAddGlobal (lmodule, LLVMInt32Type (), ti_name);
4011 LLVMSetInitializer (type_info, LLVMConstInt (LLVMInt32Type (), clause_index, FALSE));
4016 * After the cfg mempool is freed, the type info will point to stale memory,
4017 * but this is not a problem, since we decode it once in exception_cb during
4020 ti = (gint32*)mono_mempool_alloc (cfg->mempool, sizeof (gint32));
4021 *(gint32*)ti = clause_index;
4023 type_info = LLVMAddGlobal (lmodule, i8ptr, ti_name);
4025 LLVMAddGlobalMapping (ctx->module->ee, type_info, ti);
4030 LLVMTypeRef members [2], ret_type;
4032 members [0] = i8ptr;
4033 members [1] = LLVMInt32Type ();
4034 ret_type = LLVMStructType (members, 2, FALSE);
4036 landing_pad = LLVMBuildLandingPad (builder, ret_type, personality, 1, "");
4037 LLVMAddClause (landing_pad, type_info);
4039 /* Store the exception into the exvar */
4041 LLVMBuildStore (builder, convert (ctx, LLVMBuildExtractValue (builder, landing_pad, 0, "ex_obj"), ObjRefType ()), ctx->ex_var);
4045 * LLVM throw sites are associated with a one landing pad, and LLVM generated
4046 * code expects control to be transferred to this landing pad even in the
4047 * presence of nested clauses. The landing pad needs to branch to the landing
4048 * pads belonging to nested clauses based on the selector value returned by
4049 * the landing pad instruction, which is passed to the landing pad in a
4050 * register by the EH code.
4052 target_bb = bblocks [bb->block_num].call_handler_target_bb;
4053 g_assert (target_bb);
4056 * Branch to the correct landing pad
4058 LLVMValueRef ex_selector = LLVMBuildExtractValue (builder, landing_pad, 1, "ex_selector");
4059 LLVMValueRef switch_ins = LLVMBuildSwitch (builder, ex_selector, target_bb, 0);
4061 for (l = ctx->nested_in [clause_index]; l; l = l->next) {
4062 int nesting_clause_index = GPOINTER_TO_INT (l->data);
4063 MonoBasicBlock *handler_bb;
4065 handler_bb = (MonoBasicBlock*)g_hash_table_lookup (ctx->clause_to_handler, GINT_TO_POINTER (nesting_clause_index));
4066 g_assert (handler_bb);
4068 g_assert (ctx->bblocks [handler_bb->block_num].call_handler_target_bb);
4069 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), nesting_clause_index, FALSE), ctx->bblocks [handler_bb->block_num].call_handler_target_bb);
4072 /* Start a new bblock which CALL_HANDLER can branch to */
4073 target_bb = bblocks [bb->block_num].call_handler_target_bb;
4075 ctx->builder = builder = create_builder (ctx);
4076 LLVMPositionBuilderAtEnd (ctx->builder, target_bb);
4078 ctx->bblocks [bb->block_num].end_bblock = target_bb;
4080 /* Store the exception into the IL level exvar */
4081 if (bb->in_scount == 1) {
4082 g_assert (bb->in_scount == 1);
4083 exvar = bb->in_stack [0];
4085 // FIXME: This is shared with filter clauses ?
4086 g_assert (!values [exvar->dreg]);
4088 g_assert (ctx->ex_var);
4089 values [exvar->dreg] = LLVMBuildLoad (builder, ctx->ex_var, "");
4090 emit_volatile_store (ctx, exvar->dreg);
4096 process_bb (EmitContext *ctx, MonoBasicBlock *bb)
4098 MonoCompile *cfg = ctx->cfg;
4099 MonoMethodSignature *sig = ctx->sig;
4100 LLVMValueRef method = ctx->lmethod;
4101 LLVMValueRef *values = ctx->values;
4102 LLVMValueRef *addresses = ctx->addresses;
4103 LLVMCallInfo *linfo = ctx->linfo;
4104 BBInfo *bblocks = ctx->bblocks;
4106 LLVMBasicBlockRef cbb;
4107 LLVMBuilderRef builder, starting_builder;
4108 gboolean has_terminator;
4110 LLVMValueRef lhs, rhs;
4113 cbb = get_end_bb (ctx, bb);
4115 builder = create_builder (ctx);
4116 ctx->builder = builder;
4117 LLVMPositionBuilderAtEnd (builder, cbb);
4122 if (bb->flags & BB_EXCEPTION_HANDLER) {
4123 if (!ctx->llvm_only && !bblocks [bb->block_num].invoke_target) {
4124 set_failure (ctx, "handler without invokes");
4129 emit_llvmonly_handler_start (ctx, bb, cbb);
4131 emit_handler_start (ctx, bb, builder);
4134 builder = ctx->builder;
4137 has_terminator = FALSE;
4138 starting_builder = builder;
4139 for (ins = bb->code; ins; ins = ins->next) {
4140 const char *spec = LLVM_INS_INFO (ins->opcode);
4142 char dname_buf [128];
4144 emit_dbg_loc (ctx, builder, ins->cil_code);
4149 * Some steps in llc are non-linear in the size of basic blocks, see #5714.
4150 * Start a new bblock. If the llvm optimization passes merge these, we
4151 * can work around that by doing a volatile load + cond branch from
4152 * localloc-ed memory.
4154 //set_failure (ctx, "basic block too long");
4155 cbb = gen_bb (ctx, "CONT_LONG_BB");
4156 LLVMBuildBr (ctx->builder, cbb);
4157 ctx->builder = builder = create_builder (ctx);
4158 LLVMPositionBuilderAtEnd (builder, cbb);
4159 ctx->bblocks [bb->block_num].end_bblock = cbb;
4164 /* There could be instructions after a terminator, skip them */
4167 if (spec [MONO_INST_DEST] != ' ' && !MONO_IS_STORE_MEMBASE (ins)) {
4168 sprintf (dname_buf, "t%d", ins->dreg);
4172 if (spec [MONO_INST_SRC1] != ' ' && spec [MONO_INST_SRC1] != 'v') {
4173 MonoInst *var = get_vreg_to_inst (cfg, ins->sreg1);
4175 if (var && var->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT) && var->opcode != OP_GSHAREDVT_ARG_REGOFFSET) {
4176 lhs = emit_volatile_load (ctx, ins->sreg1);
4178 /* It is ok for SETRET to have an uninitialized argument */
4179 if (!values [ins->sreg1] && ins->opcode != OP_SETRET) {
4180 set_failure (ctx, "sreg1");
4183 lhs = values [ins->sreg1];
4189 if (spec [MONO_INST_SRC2] != ' ' && spec [MONO_INST_SRC2] != ' ') {
4190 MonoInst *var = get_vreg_to_inst (cfg, ins->sreg2);
4191 if (var && var->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT)) {
4192 rhs = emit_volatile_load (ctx, ins->sreg2);
4194 if (!values [ins->sreg2]) {
4195 set_failure (ctx, "sreg2");
4198 rhs = values [ins->sreg2];
4204 //mono_print_ins (ins);
4205 switch (ins->opcode) {
4208 case OP_LIVERANGE_START:
4209 case OP_LIVERANGE_END:
4212 values [ins->dreg] = LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE);
4215 #if SIZEOF_VOID_P == 4
4216 values [ins->dreg] = LLVMConstInt (LLVMInt64Type (), GET_LONG_IMM (ins), FALSE);
4218 values [ins->dreg] = LLVMConstInt (LLVMInt64Type (), (gint64)ins->inst_c0, FALSE);
4222 values [ins->dreg] = LLVMConstReal (LLVMDoubleType (), *(double*)ins->inst_p0);
4226 values [ins->dreg] = LLVMConstReal (LLVMFloatType (), *(float*)ins->inst_p0);
4228 values [ins->dreg] = LLVMConstFPExt (LLVMConstReal (LLVMFloatType (), *(float*)ins->inst_p0), LLVMDoubleType ());
4230 case OP_DUMMY_ICONST:
4231 values [ins->dreg] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
4233 case OP_DUMMY_I8CONST:
4234 values [ins->dreg] = LLVMConstInt (LLVMInt64Type (), 0, FALSE);
4236 case OP_DUMMY_R8CONST:
4237 values [ins->dreg] = LLVMConstReal (LLVMDoubleType (), 0.0f);
4240 LLVMBasicBlockRef target_bb = get_bb (ctx, ins->inst_target_bb);
4241 LLVMBuildBr (builder, target_bb);
4242 has_terminator = TRUE;
4249 LLVMBasicBlockRef new_bb;
4250 LLVMBuilderRef new_builder;
4252 // The default branch is already handled
4253 // FIXME: Handle it here
4255 /* Start new bblock */
4256 sprintf (bb_name, "SWITCH_DEFAULT_BB%d", ctx->default_index ++);
4257 new_bb = LLVMAppendBasicBlock (ctx->lmethod, bb_name);
4259 lhs = convert (ctx, lhs, LLVMInt32Type ());
4260 v = LLVMBuildSwitch (builder, lhs, new_bb, GPOINTER_TO_UINT (ins->klass));
4261 for (i = 0; i < GPOINTER_TO_UINT (ins->klass); ++i) {
4262 MonoBasicBlock *target_bb = ins->inst_many_bb [i];
4264 LLVMAddCase (v, LLVMConstInt (LLVMInt32Type (), i, FALSE), get_bb (ctx, target_bb));
4267 new_builder = create_builder (ctx);
4268 LLVMPositionBuilderAtEnd (new_builder, new_bb);
4269 LLVMBuildUnreachable (new_builder);
4271 has_terminator = TRUE;
4272 g_assert (!ins->next);
4278 switch (linfo->ret.storage) {
4279 case LLVMArgVtypeInReg: {
4280 LLVMTypeRef ret_type = LLVMGetReturnType (LLVMGetElementType (LLVMTypeOf (method)));
4281 LLVMValueRef val, addr, retval;
4284 retval = LLVMGetUndef (ret_type);
4286 if (!addresses [ins->sreg1]) {
4288 * The return type is an LLVM vector type, have to convert between it and the
4289 * real return type which is a struct type.
4291 g_assert (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (sig->ret)));
4292 /* Convert to 2xi64 first */
4293 val = LLVMBuildBitCast (builder, values [ins->sreg1], LLVMVectorType (IntPtrType (), 2), "");
4295 for (i = 0; i < 2; ++i) {
4296 if (linfo->ret.pair_storage [i] == LLVMArgInIReg) {
4297 retval = LLVMBuildInsertValue (builder, retval, LLVMBuildExtractElement (builder, val, LLVMConstInt (LLVMInt32Type (), i, FALSE), ""), i, "");
4299 g_assert (linfo->ret.pair_storage [i] == LLVMArgNone);
4303 addr = LLVMBuildBitCast (builder, addresses [ins->sreg1], LLVMPointerType (ret_type, 0), "");
4304 for (i = 0; i < 2; ++i) {
4305 if (linfo->ret.pair_storage [i] == LLVMArgInIReg) {
4306 LLVMValueRef indexes [2], part_addr;
4308 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
4309 indexes [1] = LLVMConstInt (LLVMInt32Type (), i, FALSE);
4310 part_addr = LLVMBuildGEP (builder, addr, indexes, 2, "");
4312 retval = LLVMBuildInsertValue (builder, retval, LLVMBuildLoad (builder, part_addr, ""), i, "");
4314 g_assert (linfo->ret.pair_storage [i] == LLVMArgNone);
4318 LLVMBuildRet (builder, retval);
4321 case LLVMArgVtypeAsScalar: {
4322 LLVMTypeRef ret_type = LLVMGetReturnType (LLVMGetElementType (LLVMTypeOf (method)));
4323 LLVMValueRef retval;
4325 g_assert (addresses [ins->sreg1]);
4327 retval = LLVMBuildLoad (builder, LLVMBuildBitCast (builder, addresses [ins->sreg1], LLVMPointerType (ret_type, 0), ""), "");
4328 LLVMBuildRet (builder, retval);
4331 case LLVMArgVtypeByVal: {
4332 LLVMValueRef retval;
4334 g_assert (addresses [ins->sreg1]);
4335 retval = LLVMBuildLoad (builder, addresses [ins->sreg1], "");
4336 LLVMBuildRet (builder, retval);
4339 case LLVMArgVtypeByRef: {
4340 LLVMBuildRetVoid (builder);
4343 case LLVMArgGsharedvtFixed: {
4344 LLVMTypeRef ret_type = type_to_llvm_type (ctx, sig->ret);
4345 /* The return value is in lhs, need to store to the vret argument */
4346 /* sreg1 might not be set */
4348 g_assert (cfg->vret_addr);
4349 g_assert (values [cfg->vret_addr->dreg]);
4350 LLVMBuildStore (builder, convert (ctx, lhs, ret_type), convert (ctx, values [cfg->vret_addr->dreg], LLVMPointerType (ret_type, 0)));
4352 LLVMBuildRetVoid (builder);
4355 case LLVMArgGsharedvtFixedVtype: {
4357 LLVMBuildRetVoid (builder);
4360 case LLVMArgGsharedvtVariable: {
4362 LLVMBuildRetVoid (builder);
4365 case LLVMArgVtypeRetAddr: {
4366 LLVMBuildRetVoid (builder);
4369 case LLVMArgAsIArgs:
4370 case LLVMArgFpStruct: {
4371 LLVMTypeRef ret_type = LLVMGetReturnType (LLVMGetElementType (LLVMTypeOf (method)));
4372 LLVMValueRef retval;
4374 g_assert (addresses [ins->sreg1]);
4375 retval = LLVMBuildLoad (builder, convert (ctx, addresses [ins->sreg1], LLVMPointerType (ret_type, 0)), "");
4376 LLVMBuildRet (builder, retval);
4380 case LLVMArgNormal: {
4381 if (!lhs || ctx->is_dead [ins->sreg1]) {
4383 * The method did not set its return value, probably because it
4384 * ends with a throw.
4387 LLVMBuildRetVoid (builder);
4389 LLVMBuildRet (builder, LLVMConstNull (type_to_llvm_type (ctx, sig->ret)));
4391 LLVMBuildRet (builder, convert (ctx, lhs, type_to_llvm_type (ctx, sig->ret)));
4393 has_terminator = TRUE;
4397 g_assert_not_reached ();
4406 case OP_ICOMPARE_IMM:
4407 case OP_LCOMPARE_IMM:
4408 case OP_COMPARE_IMM: {
4410 LLVMValueRef cmp, args [16];
4411 gboolean likely = (ins->flags & MONO_INST_LIKELY) != 0;
4413 if (ins->next->opcode == OP_NOP)
4416 if (ins->next->opcode == OP_BR)
4417 /* The comparison result is not needed */
4420 rel = mono_opcode_to_cond (ins->next->opcode);
4422 if (ins->opcode == OP_ICOMPARE_IMM) {
4423 lhs = convert (ctx, lhs, LLVMInt32Type ());
4424 rhs = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
4426 if (ins->opcode == OP_LCOMPARE_IMM) {
4427 lhs = convert (ctx, lhs, LLVMInt64Type ());
4428 rhs = LLVMConstInt (LLVMInt64Type (), GET_LONG_IMM (ins), FALSE);
4430 if (ins->opcode == OP_LCOMPARE) {
4431 lhs = convert (ctx, lhs, LLVMInt64Type ());
4432 rhs = convert (ctx, rhs, LLVMInt64Type ());
4434 if (ins->opcode == OP_ICOMPARE) {
4435 lhs = convert (ctx, lhs, LLVMInt32Type ());
4436 rhs = convert (ctx, rhs, LLVMInt32Type ());
4440 if (LLVMGetTypeKind (LLVMTypeOf (lhs)) == LLVMPointerTypeKind)
4441 rhs = convert (ctx, rhs, LLVMTypeOf (lhs));
4442 else if (LLVMGetTypeKind (LLVMTypeOf (rhs)) == LLVMPointerTypeKind)
4443 lhs = convert (ctx, lhs, LLVMTypeOf (rhs));
4446 /* We use COMPARE+SETcc/Bcc, llvm uses SETcc+br cond */
4447 if (ins->opcode == OP_FCOMPARE) {
4448 cmp = LLVMBuildFCmp (builder, fpcond_to_llvm_cond [rel], convert (ctx, lhs, LLVMDoubleType ()), convert (ctx, rhs, LLVMDoubleType ()), "");
4449 } else if (ins->opcode == OP_RCOMPARE) {
4450 cmp = LLVMBuildFCmp (builder, fpcond_to_llvm_cond [rel], convert (ctx, lhs, LLVMFloatType ()), convert (ctx, rhs, LLVMFloatType ()), "");
4451 } else if (ins->opcode == OP_COMPARE_IMM) {
4452 if (LLVMGetTypeKind (LLVMTypeOf (lhs)) == LLVMPointerTypeKind && ins->inst_imm == 0)
4453 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], lhs, LLVMConstNull (LLVMTypeOf (lhs)), "");
4455 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE), "");
4456 } else if (ins->opcode == OP_LCOMPARE_IMM) {
4457 if (SIZEOF_REGISTER == 4 && COMPILE_LLVM (cfg)) {
4458 /* The immediate is encoded in two fields */
4459 guint64 l = ((guint64)(guint32)ins->inst_offset << 32) | ((guint32)ins->inst_imm);
4460 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, LLVMInt64Type ()), LLVMConstInt (LLVMInt64Type (), l, FALSE), "");
4462 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, LLVMInt64Type ()), LLVMConstInt (LLVMInt64Type (), ins->inst_imm, FALSE), "");
4465 else if (ins->opcode == OP_COMPARE) {
4466 if (LLVMGetTypeKind (LLVMTypeOf (lhs)) == LLVMPointerTypeKind && LLVMTypeOf (lhs) == LLVMTypeOf (rhs))
4467 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], lhs, rhs, "");
4469 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, IntPtrType ()), convert (ctx, rhs, IntPtrType ()), "");
4471 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], lhs, rhs, "");
4475 args [1] = LLVMConstInt (LLVMInt1Type (), 1, FALSE);
4476 cmp = LLVMBuildCall (ctx->builder, get_intrinsic (ctx, "llvm.expect.i1"), args, 2, "");
4479 if (MONO_IS_COND_BRANCH_OP (ins->next)) {
4480 if (ins->next->inst_true_bb == ins->next->inst_false_bb) {
4482 * If the target bb contains PHI instructions, LLVM requires
4483 * two PHI entries for this bblock, while we only generate one.
4484 * So convert this to an unconditional bblock. (bxc #171).
4486 LLVMBuildBr (builder, get_bb (ctx, ins->next->inst_true_bb));
4488 LLVMBuildCondBr (builder, cmp, get_bb (ctx, ins->next->inst_true_bb), get_bb (ctx, ins->next->inst_false_bb));
4490 has_terminator = TRUE;
4491 } else if (MONO_IS_SETCC (ins->next)) {
4492 sprintf (dname_buf, "t%d", ins->next->dreg);
4494 values [ins->next->dreg] = LLVMBuildZExt (builder, cmp, LLVMInt32Type (), dname);
4496 /* Add stores for volatile variables */
4497 emit_volatile_store (ctx, ins->next->dreg);
4498 } else if (MONO_IS_COND_EXC (ins->next)) {
4499 emit_cond_system_exception (ctx, bb, (const char*)ins->next->inst_p1, cmp);
4502 builder = ctx->builder;
4504 set_failure (ctx, "next");
4522 rel = mono_opcode_to_cond (ins->opcode);
4524 cmp = LLVMBuildFCmp (builder, fpcond_to_llvm_cond [rel], convert (ctx, lhs, LLVMDoubleType ()), convert (ctx, rhs, LLVMDoubleType ()), "");
4525 values [ins->dreg] = LLVMBuildZExt (builder, cmp, LLVMInt32Type (), dname);
4536 rel = mono_opcode_to_cond (ins->opcode);
4538 cmp = LLVMBuildFCmp (builder, fpcond_to_llvm_cond [rel], convert (ctx, lhs, LLVMFloatType ()), convert (ctx, rhs, LLVMFloatType ()), "");
4539 values [ins->dreg] = LLVMBuildZExt (builder, cmp, LLVMInt32Type (), dname);
4547 gboolean empty = TRUE;
4549 /* Check that all input bblocks really branch to us */
4550 for (i = 0; i < bb->in_count; ++i) {
4551 if (bb->in_bb [i]->last_ins && bb->in_bb [i]->last_ins->opcode == OP_NOT_REACHED)
4552 ins->inst_phi_args [i + 1] = -1;
4558 /* LLVM doesn't like phi instructions with zero operands */
4559 ctx->is_dead [ins->dreg] = TRUE;
4563 /* Created earlier, insert it now */
4564 LLVMInsertIntoBuilder (builder, values [ins->dreg]);
4566 for (i = 0; i < ins->inst_phi_args [0]; i++) {
4567 int sreg1 = ins->inst_phi_args [i + 1];
4571 * Count the number of times the incoming bblock branches to us,
4572 * since llvm requires a separate entry for each.
4574 if (bb->in_bb [i]->last_ins && bb->in_bb [i]->last_ins->opcode == OP_SWITCH) {
4575 MonoInst *switch_ins = bb->in_bb [i]->last_ins;
4578 for (j = 0; j < GPOINTER_TO_UINT (switch_ins->klass); ++j) {
4579 if (switch_ins->inst_many_bb [j] == bb)
4586 /* Remember for later */
4587 for (j = 0; j < count; ++j) {
4588 PhiNode *node = (PhiNode*)mono_mempool_alloc0 (ctx->mempool, sizeof (PhiNode));
4591 node->in_bb = bb->in_bb [i];
4593 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);
4603 values [ins->dreg] = lhs;
4607 MonoInst *var = get_vreg_to_inst (cfg, ins->dreg);
4610 values [ins->dreg] = lhs;
4612 if (var && var->klass->byval_arg.type == MONO_TYPE_R4) {
4614 * This is added by the spilling pass in case of the JIT,
4615 * but we have to do it ourselves.
4617 values [ins->dreg] = convert (ctx, values [ins->dreg], LLVMFloatType ());
4621 case OP_MOVE_F_TO_I4: {
4622 values [ins->dreg] = LLVMBuildBitCast (builder, LLVMBuildFPTrunc (builder, lhs, LLVMFloatType (), ""), LLVMInt32Type (), "");
4625 case OP_MOVE_I4_TO_F: {
4626 values [ins->dreg] = LLVMBuildFPExt (builder, LLVMBuildBitCast (builder, lhs, LLVMFloatType (), ""), LLVMDoubleType (), "");
4629 case OP_MOVE_F_TO_I8: {
4630 values [ins->dreg] = LLVMBuildBitCast (builder, lhs, LLVMInt64Type (), "");
4633 case OP_MOVE_I8_TO_F: {
4634 values [ins->dreg] = LLVMBuildBitCast (builder, lhs, LLVMDoubleType (), "");
4667 lhs = convert (ctx, lhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
4668 rhs = convert (ctx, rhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
4670 emit_div_check (ctx, builder, bb, ins, lhs, rhs);
4673 builder = ctx->builder;
4675 switch (ins->opcode) {
4678 values [ins->dreg] = LLVMBuildAdd (builder, lhs, rhs, dname);
4682 values [ins->dreg] = LLVMBuildSub (builder, lhs, rhs, dname);
4686 values [ins->dreg] = LLVMBuildMul (builder, lhs, rhs, dname);
4690 values [ins->dreg] = LLVMBuildSRem (builder, lhs, rhs, dname);
4694 values [ins->dreg] = LLVMBuildURem (builder, lhs, rhs, dname);
4698 values [ins->dreg] = LLVMBuildSDiv (builder, lhs, rhs, dname);
4702 values [ins->dreg] = LLVMBuildUDiv (builder, lhs, rhs, dname);
4706 values [ins->dreg] = LLVMBuildFDiv (builder, lhs, rhs, dname);
4710 values [ins->dreg] = LLVMBuildAnd (builder, lhs, rhs, dname);
4714 values [ins->dreg] = LLVMBuildOr (builder, lhs, rhs, dname);
4718 values [ins->dreg] = LLVMBuildXor (builder, lhs, rhs, dname);
4722 values [ins->dreg] = LLVMBuildShl (builder, lhs, rhs, dname);
4726 values [ins->dreg] = LLVMBuildAShr (builder, lhs, rhs, dname);
4730 values [ins->dreg] = LLVMBuildLShr (builder, lhs, rhs, dname);
4734 values [ins->dreg] = LLVMBuildFAdd (builder, lhs, rhs, dname);
4737 values [ins->dreg] = LLVMBuildFSub (builder, lhs, rhs, dname);
4740 values [ins->dreg] = LLVMBuildFMul (builder, lhs, rhs, dname);
4744 g_assert_not_reached ();
4751 lhs = convert (ctx, lhs, LLVMFloatType ());
4752 rhs = convert (ctx, rhs, LLVMFloatType ());
4753 switch (ins->opcode) {
4755 values [ins->dreg] = LLVMBuildFAdd (builder, lhs, rhs, dname);
4758 values [ins->dreg] = LLVMBuildFSub (builder, lhs, rhs, dname);
4761 values [ins->dreg] = LLVMBuildFMul (builder, lhs, rhs, dname);
4764 values [ins->dreg] = LLVMBuildFDiv (builder, lhs, rhs, dname);
4767 g_assert_not_reached ();
4776 case OP_IREM_UN_IMM:
4778 case OP_IDIV_UN_IMM:
4784 case OP_ISHR_UN_IMM:
4794 case OP_LSHR_UN_IMM:
4800 case OP_SHR_UN_IMM: {
4803 if (spec [MONO_INST_SRC1] == 'l') {
4804 imm = LLVMConstInt (LLVMInt64Type (), GET_LONG_IMM (ins), FALSE);
4806 imm = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
4809 emit_div_check (ctx, builder, bb, ins, lhs, imm);
4812 builder = ctx->builder;
4814 #if SIZEOF_VOID_P == 4
4815 if (ins->opcode == OP_LSHL_IMM || ins->opcode == OP_LSHR_IMM || ins->opcode == OP_LSHR_UN_IMM)
4816 imm = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
4819 if (LLVMGetTypeKind (LLVMTypeOf (lhs)) == LLVMPointerTypeKind)
4820 lhs = convert (ctx, lhs, IntPtrType ());
4821 imm = convert (ctx, imm, LLVMTypeOf (lhs));
4822 switch (ins->opcode) {
4826 values [ins->dreg] = LLVMBuildAdd (builder, lhs, imm, dname);
4830 values [ins->dreg] = LLVMBuildSub (builder, lhs, imm, dname);
4835 values [ins->dreg] = LLVMBuildMul (builder, lhs, imm, dname);
4839 values [ins->dreg] = LLVMBuildSDiv (builder, lhs, imm, dname);
4841 case OP_IDIV_UN_IMM:
4842 case OP_LDIV_UN_IMM:
4843 values [ins->dreg] = LLVMBuildUDiv (builder, lhs, imm, dname);
4847 values [ins->dreg] = LLVMBuildSRem (builder, lhs, imm, dname);
4849 case OP_IREM_UN_IMM:
4850 values [ins->dreg] = LLVMBuildURem (builder, lhs, imm, dname);
4855 values [ins->dreg] = LLVMBuildAnd (builder, lhs, imm, dname);
4859 values [ins->dreg] = LLVMBuildOr (builder, lhs, imm, dname);
4863 values [ins->dreg] = LLVMBuildXor (builder, lhs, imm, dname);
4868 values [ins->dreg] = LLVMBuildShl (builder, lhs, imm, dname);
4873 values [ins->dreg] = LLVMBuildAShr (builder, lhs, imm, dname);
4875 case OP_ISHR_UN_IMM:
4876 /* This is used to implement conv.u4, so the lhs could be an i8 */
4877 lhs = convert (ctx, lhs, LLVMInt32Type ());
4878 imm = convert (ctx, imm, LLVMInt32Type ());
4879 values [ins->dreg] = LLVMBuildLShr (builder, lhs, imm, dname);
4881 case OP_LSHR_UN_IMM:
4883 values [ins->dreg] = LLVMBuildLShr (builder, lhs, imm, dname);
4886 g_assert_not_reached ();
4891 values [ins->dreg] = LLVMBuildSub (builder, LLVMConstInt (LLVMInt32Type (), 0, FALSE), convert (ctx, lhs, LLVMInt32Type ()), dname);
4894 values [ins->dreg] = LLVMBuildSub (builder, LLVMConstInt (LLVMInt64Type (), 0, FALSE), lhs, dname);
4897 lhs = convert (ctx, lhs, LLVMDoubleType ());
4898 values [ins->dreg] = LLVMBuildFSub (builder, LLVMConstReal (LLVMDoubleType (), 0.0), lhs, dname);
4901 lhs = convert (ctx, lhs, LLVMFloatType ());
4902 values [ins->dreg] = LLVMBuildFSub (builder, LLVMConstReal (LLVMFloatType (), 0.0), lhs, dname);
4905 guint32 v = 0xffffffff;
4906 values [ins->dreg] = LLVMBuildXor (builder, LLVMConstInt (LLVMInt32Type (), v, FALSE), convert (ctx, lhs, LLVMInt32Type ()), dname);
4910 guint64 v = 0xffffffffffffffffLL;
4911 values [ins->dreg] = LLVMBuildXor (builder, LLVMConstInt (LLVMInt64Type (), v, FALSE), lhs, dname);
4914 #if defined(TARGET_X86) || defined(TARGET_AMD64)
4916 LLVMValueRef v1, v2;
4918 v1 = LLVMBuildMul (builder, convert (ctx, rhs, IntPtrType ()), LLVMConstInt (IntPtrType (), (1 << ins->backend.shift_amount), FALSE), "");
4919 v2 = LLVMBuildAdd (builder, convert (ctx, lhs, IntPtrType ()), v1, "");
4920 values [ins->dreg] = LLVMBuildAdd (builder, v2, LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE), dname);
4925 case OP_ICONV_TO_I1:
4926 case OP_ICONV_TO_I2:
4927 case OP_ICONV_TO_I4:
4928 case OP_ICONV_TO_U1:
4929 case OP_ICONV_TO_U2:
4930 case OP_ICONV_TO_U4:
4931 case OP_LCONV_TO_I1:
4932 case OP_LCONV_TO_I2:
4933 case OP_LCONV_TO_U1:
4934 case OP_LCONV_TO_U2:
4935 case OP_LCONV_TO_U4: {
4938 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);
4940 /* Have to do two casts since our vregs have type int */
4941 v = LLVMBuildTrunc (builder, lhs, op_to_llvm_type (ins->opcode), "");
4943 values [ins->dreg] = LLVMBuildSExt (builder, v, LLVMInt32Type (), dname);
4945 values [ins->dreg] = LLVMBuildZExt (builder, v, LLVMInt32Type (), dname);
4948 case OP_ICONV_TO_I8:
4949 values [ins->dreg] = LLVMBuildSExt (builder, lhs, LLVMInt64Type (), dname);
4951 case OP_ICONV_TO_U8:
4952 values [ins->dreg] = LLVMBuildZExt (builder, lhs, LLVMInt64Type (), dname);
4954 case OP_FCONV_TO_I4:
4955 case OP_RCONV_TO_I4:
4956 values [ins->dreg] = LLVMBuildFPToSI (builder, lhs, LLVMInt32Type (), dname);
4958 case OP_FCONV_TO_I1:
4959 case OP_RCONV_TO_I1:
4960 values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildFPToSI (builder, lhs, LLVMInt8Type (), dname), LLVMInt32Type (), "");
4962 case OP_FCONV_TO_U1:
4963 case OP_RCONV_TO_U1:
4964 values [ins->dreg] = LLVMBuildZExt (builder, LLVMBuildTrunc (builder, LLVMBuildFPToUI (builder, lhs, IntPtrType (), dname), LLVMInt8Type (), ""), LLVMInt32Type (), "");
4966 case OP_FCONV_TO_I2:
4967 case OP_RCONV_TO_I2:
4968 values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildFPToSI (builder, lhs, LLVMInt16Type (), dname), LLVMInt32Type (), "");
4970 case OP_FCONV_TO_U2:
4971 case OP_RCONV_TO_U2:
4972 values [ins->dreg] = LLVMBuildZExt (builder, LLVMBuildFPToUI (builder, lhs, LLVMInt16Type (), dname), LLVMInt32Type (), "");
4974 case OP_RCONV_TO_U4:
4975 values [ins->dreg] = LLVMBuildFPToUI (builder, lhs, LLVMInt32Type (), dname);
4977 case OP_FCONV_TO_I8:
4978 case OP_RCONV_TO_I8:
4979 values [ins->dreg] = LLVMBuildFPToSI (builder, lhs, LLVMInt64Type (), dname);
4982 values [ins->dreg] = LLVMBuildFPToSI (builder, lhs, IntPtrType (), dname);
4984 case OP_ICONV_TO_R8:
4985 case OP_LCONV_TO_R8:
4986 values [ins->dreg] = LLVMBuildSIToFP (builder, lhs, LLVMDoubleType (), dname);
4988 case OP_ICONV_TO_R_UN:
4989 case OP_LCONV_TO_R_UN:
4990 values [ins->dreg] = LLVMBuildUIToFP (builder, lhs, LLVMDoubleType (), dname);
4992 #if SIZEOF_VOID_P == 4
4995 case OP_LCONV_TO_I4:
4996 values [ins->dreg] = LLVMBuildTrunc (builder, lhs, LLVMInt32Type (), dname);
4998 case OP_ICONV_TO_R4:
4999 case OP_LCONV_TO_R4:
5000 v = LLVMBuildSIToFP (builder, lhs, LLVMFloatType (), "");
5002 values [ins->dreg] = v;
5004 values [ins->dreg] = LLVMBuildFPExt (builder, v, LLVMDoubleType (), dname);
5006 case OP_FCONV_TO_R4:
5007 v = LLVMBuildFPTrunc (builder, lhs, LLVMFloatType (), "");
5009 values [ins->dreg] = v;
5011 values [ins->dreg] = LLVMBuildFPExt (builder, v, LLVMDoubleType (), dname);
5013 case OP_RCONV_TO_R8:
5014 values [ins->dreg] = LLVMBuildFPExt (builder, lhs, LLVMDoubleType (), dname);
5016 case OP_RCONV_TO_R4:
5017 values [ins->dreg] = lhs;
5020 values [ins->dreg] = LLVMBuildSExt (builder, convert (ctx, lhs, LLVMInt32Type ()), LLVMInt64Type (), dname);
5023 values [ins->dreg] = LLVMBuildZExt (builder, convert (ctx, lhs, LLVMInt32Type ()), LLVMInt64Type (), dname);
5026 values [ins->dreg] = LLVMBuildTrunc (builder, lhs, LLVMInt32Type (), dname);
5028 case OP_LOCALLOC_IMM: {
5031 guint32 size = ins->inst_imm;
5032 size = (size + (MONO_ARCH_FRAME_ALIGNMENT - 1)) & ~ (MONO_ARCH_FRAME_ALIGNMENT - 1);
5034 v = mono_llvm_build_alloca (builder, LLVMInt8Type (), LLVMConstInt (LLVMInt32Type (), size, FALSE), MONO_ARCH_FRAME_ALIGNMENT, "");
5036 if (ins->flags & MONO_INST_INIT) {
5037 LLVMValueRef args [5];
5040 args [1] = LLVMConstInt (LLVMInt8Type (), 0, FALSE);
5041 args [2] = LLVMConstInt (LLVMInt32Type (), size, FALSE);
5042 args [3] = LLVMConstInt (LLVMInt32Type (), MONO_ARCH_FRAME_ALIGNMENT, FALSE);
5043 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
5044 LLVMBuildCall (builder, get_intrinsic (ctx, "llvm.memset.p0i8.i32"), args, 5, "");
5047 values [ins->dreg] = v;
5051 LLVMValueRef v, size;
5053 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), "");
5055 v = mono_llvm_build_alloca (builder, LLVMInt8Type (), size, MONO_ARCH_FRAME_ALIGNMENT, "");
5057 if (ins->flags & MONO_INST_INIT) {
5058 LLVMValueRef args [5];
5061 args [1] = LLVMConstInt (LLVMInt8Type (), 0, FALSE);
5063 args [3] = LLVMConstInt (LLVMInt32Type (), MONO_ARCH_FRAME_ALIGNMENT, FALSE);
5064 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
5065 LLVMBuildCall (builder, get_intrinsic (ctx, "llvm.memset.p0i8.i32"), args, 5, "");
5067 values [ins->dreg] = v;
5071 case OP_LOADI1_MEMBASE:
5072 case OP_LOADU1_MEMBASE:
5073 case OP_LOADI2_MEMBASE:
5074 case OP_LOADU2_MEMBASE:
5075 case OP_LOADI4_MEMBASE:
5076 case OP_LOADU4_MEMBASE:
5077 case OP_LOADI8_MEMBASE:
5078 case OP_LOADR4_MEMBASE:
5079 case OP_LOADR8_MEMBASE:
5080 case OP_LOAD_MEMBASE:
5088 LLVMValueRef base, index, addr;
5090 gboolean sext = FALSE, zext = FALSE;
5091 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
5093 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
5098 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)) {
5099 addr = LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE);
5104 if (ins->inst_offset == 0) {
5106 } else if (ins->inst_offset % size != 0) {
5107 /* Unaligned load */
5108 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset, FALSE);
5109 addr = LLVMBuildGEP (builder, convert (ctx, base, LLVMPointerType (LLVMInt8Type (), 0)), &index, 1, "");
5111 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
5112 addr = LLVMBuildGEP (builder, convert (ctx, base, LLVMPointerType (t, 0)), &index, 1, "");
5116 addr = convert (ctx, addr, LLVMPointerType (t, 0));
5118 values [ins->dreg] = emit_load (ctx, bb, &builder, size, addr, dname, is_volatile);
5120 if (!is_volatile && (ins->flags & MONO_INST_INVARIANT_LOAD)) {
5122 * These will signal LLVM that these loads do not alias any stores, and
5123 * they can't fail, allowing them to be hoisted out of loops.
5125 set_invariant_load_flag (values [ins->dreg]);
5126 #if LLVM_API_VERSION < 100
5127 set_metadata_flag (values [ins->dreg], "mono.nofail.load");
5132 values [ins->dreg] = LLVMBuildSExt (builder, values [ins->dreg], LLVMInt32Type (), dname);
5134 values [ins->dreg] = LLVMBuildZExt (builder, values [ins->dreg], LLVMInt32Type (), dname);
5135 else if (!cfg->r4fp && ins->opcode == OP_LOADR4_MEMBASE)
5136 values [ins->dreg] = LLVMBuildFPExt (builder, values [ins->dreg], LLVMDoubleType (), dname);
5140 case OP_STOREI1_MEMBASE_REG:
5141 case OP_STOREI2_MEMBASE_REG:
5142 case OP_STOREI4_MEMBASE_REG:
5143 case OP_STOREI8_MEMBASE_REG:
5144 case OP_STORER4_MEMBASE_REG:
5145 case OP_STORER8_MEMBASE_REG:
5146 case OP_STORE_MEMBASE_REG: {
5148 LLVMValueRef index, addr;
5150 gboolean sext = FALSE, zext = FALSE;
5151 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
5153 if (!values [ins->inst_destbasereg]) {
5154 set_failure (ctx, "inst_destbasereg");
5158 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
5160 if (ins->inst_offset % size != 0) {
5161 /* Unaligned store */
5162 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset, FALSE);
5163 addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (LLVMInt8Type (), 0)), &index, 1, "");
5165 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
5166 addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (t, 0)), &index, 1, "");
5168 emit_store (ctx, bb, &builder, size, convert (ctx, values [ins->sreg1], t), convert (ctx, addr, LLVMPointerType (t, 0)), is_volatile);
5172 case OP_STOREI1_MEMBASE_IMM:
5173 case OP_STOREI2_MEMBASE_IMM:
5174 case OP_STOREI4_MEMBASE_IMM:
5175 case OP_STOREI8_MEMBASE_IMM:
5176 case OP_STORE_MEMBASE_IMM: {
5178 LLVMValueRef index, addr;
5180 gboolean sext = FALSE, zext = FALSE;
5181 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
5183 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
5185 if (ins->inst_offset % size != 0) {
5186 /* Unaligned store */
5187 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset, FALSE);
5188 addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (LLVMInt8Type (), 0)), &index, 1, "");
5190 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
5191 addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (t, 0)), &index, 1, "");
5193 emit_store (ctx, bb, &builder, size, convert (ctx, LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE), t), convert (ctx, addr, LLVMPointerType (t, 0)), is_volatile);
5198 emit_load (ctx, bb, &builder, sizeof (gpointer), convert (ctx, lhs, LLVMPointerType (IntPtrType (), 0)), "", TRUE);
5200 case OP_OUTARG_VTRETADDR:
5208 case OP_VOIDCALL_MEMBASE:
5209 case OP_CALL_MEMBASE:
5210 case OP_LCALL_MEMBASE:
5211 case OP_FCALL_MEMBASE:
5212 case OP_RCALL_MEMBASE:
5213 case OP_VCALL_MEMBASE:
5214 case OP_VOIDCALL_REG:
5219 case OP_VCALL_REG: {
5220 process_call (ctx, bb, &builder, ins);
5225 LLVMValueRef indexes [2];
5226 MonoJumpInfo *tmp_ji, *ji;
5227 LLVMValueRef got_entry_addr;
5231 * FIXME: Can't allocate from the cfg mempool since that is freed if
5232 * the LLVM compile fails.
5234 tmp_ji = g_new0 (MonoJumpInfo, 1);
5235 tmp_ji->type = (MonoJumpInfoType)ins->inst_c1;
5236 tmp_ji->data.target = ins->inst_p0;
5238 ji = mono_aot_patch_info_dup (tmp_ji);
5241 if (ji->type == MONO_PATCH_INFO_ICALL_ADDR) {
5242 char *symbol = mono_aot_get_direct_call_symbol (MONO_PATCH_INFO_ICALL_ADDR_CALL, ji->data.target);
5245 * Avoid emitting a got entry for these since the method is directly called, and it might not be
5246 * resolvable at runtime using dlsym ().
5249 values [ins->dreg] = LLVMConstInt (IntPtrType (), 0, FALSE);
5254 ji->next = cfg->patch_info;
5255 cfg->patch_info = ji;
5257 //mono_add_patch_info (cfg, 0, (MonoJumpInfoType)ins->inst_i1, ins->inst_p0);
5258 got_offset = mono_aot_get_got_offset (cfg->patch_info);
5259 ctx->module->max_got_offset = MAX (ctx->module->max_got_offset, got_offset);
5260 if (!mono_aot_is_shared_got_offset (got_offset)) {
5261 //mono_print_ji (ji);
5263 ctx->has_got_access = TRUE;
5266 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
5267 indexes [1] = LLVMConstInt (LLVMInt32Type (), (gssize)got_offset, FALSE);
5268 got_entry_addr = LLVMBuildGEP (builder, ctx->module->got_var, indexes, 2, "");
5270 name = get_aotconst_name (ji->type, ji->data.target, got_offset);
5271 values [ins->dreg] = LLVMBuildLoad (builder, got_entry_addr, name);
5273 /* Can't use this in llvmonly mode since the got slots are initialized by the methods themselves */
5274 if (!cfg->llvm_only)
5275 set_invariant_load_flag (values [ins->dreg]);
5278 case OP_NOT_REACHED:
5279 LLVMBuildUnreachable (builder);
5280 has_terminator = TRUE;
5281 g_assert (bb->block_num < cfg->max_block_num);
5282 ctx->unreachable [bb->block_num] = TRUE;
5283 /* Might have instructions after this */
5285 MonoInst *next = ins->next;
5287 * FIXME: If later code uses the regs defined by these instructions,
5288 * compilation will fail.
5290 MONO_DELETE_INS (bb, next);
5294 MonoInst *var = ins->inst_i0;
5296 if (var->opcode == OP_VTARG_ADDR) {
5297 /* The variable contains the vtype address */
5298 values [ins->dreg] = values [var->dreg];
5299 } else if (var->opcode == OP_GSHAREDVT_LOCAL) {
5300 values [ins->dreg] = emit_gsharedvt_ldaddr (ctx, var->dreg);
5302 values [ins->dreg] = addresses [var->dreg];
5307 LLVMValueRef args [1];
5309 args [0] = convert (ctx, lhs, LLVMDoubleType ());
5310 values [ins->dreg] = LLVMBuildCall (builder, get_intrinsic (ctx, "llvm.sin.f64"), args, 1, dname);
5314 LLVMValueRef args [1];
5316 args [0] = convert (ctx, lhs, LLVMDoubleType ());
5317 values [ins->dreg] = LLVMBuildCall (builder, get_intrinsic (ctx, "llvm.cos.f64"), args, 1, dname);
5321 LLVMValueRef args [1];
5323 args [0] = convert (ctx, lhs, LLVMDoubleType ());
5324 values [ins->dreg] = LLVMBuildCall (builder, get_intrinsic (ctx, "llvm.sqrt.f64"), args, 1, dname);
5328 LLVMValueRef args [1];
5330 args [0] = convert (ctx, lhs, LLVMDoubleType ());
5331 values [ins->dreg] = LLVMBuildCall (builder, get_intrinsic (ctx, "fabs"), args, 1, dname);
5345 lhs = convert (ctx, lhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
5346 rhs = convert (ctx, rhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
5348 switch (ins->opcode) {
5351 v = LLVMBuildICmp (builder, LLVMIntSLE, lhs, rhs, "");
5355 v = LLVMBuildICmp (builder, LLVMIntSGE, lhs, rhs, "");
5359 v = LLVMBuildICmp (builder, LLVMIntULE, lhs, rhs, "");
5363 v = LLVMBuildICmp (builder, LLVMIntUGE, lhs, rhs, "");
5366 g_assert_not_reached ();
5369 values [ins->dreg] = LLVMBuildSelect (builder, v, lhs, rhs, dname);
5372 case OP_ATOMIC_EXCHANGE_I4:
5373 case OP_ATOMIC_EXCHANGE_I8: {
5374 LLVMValueRef args [2];
5377 if (ins->opcode == OP_ATOMIC_EXCHANGE_I4)
5378 t = LLVMInt32Type ();
5380 t = LLVMInt64Type ();
5382 g_assert (ins->inst_offset == 0);
5384 args [0] = convert (ctx, lhs, LLVMPointerType (t, 0));
5385 args [1] = convert (ctx, rhs, t);
5387 values [ins->dreg] = mono_llvm_build_atomic_rmw (builder, LLVM_ATOMICRMW_OP_XCHG, args [0], args [1]);
5390 case OP_ATOMIC_ADD_I4:
5391 case OP_ATOMIC_ADD_I8: {
5392 LLVMValueRef args [2];
5395 if (ins->opcode == OP_ATOMIC_ADD_I4)
5396 t = LLVMInt32Type ();
5398 t = LLVMInt64Type ();
5400 g_assert (ins->inst_offset == 0);
5402 args [0] = convert (ctx, lhs, LLVMPointerType (t, 0));
5403 args [1] = convert (ctx, rhs, t);
5404 values [ins->dreg] = LLVMBuildAdd (builder, mono_llvm_build_atomic_rmw (builder, LLVM_ATOMICRMW_OP_ADD, args [0], args [1]), args [1], dname);
5407 case OP_ATOMIC_CAS_I4:
5408 case OP_ATOMIC_CAS_I8: {
5409 LLVMValueRef args [3], val;
5412 if (ins->opcode == OP_ATOMIC_CAS_I4)
5413 t = LLVMInt32Type ();
5415 t = LLVMInt64Type ();
5417 args [0] = convert (ctx, lhs, LLVMPointerType (t, 0));
5419 args [1] = convert (ctx, values [ins->sreg3], t);
5421 args [2] = convert (ctx, values [ins->sreg2], t);
5422 val = mono_llvm_build_cmpxchg (builder, args [0], args [1], args [2]);
5423 /* cmpxchg returns a pair */
5424 values [ins->dreg] = LLVMBuildExtractValue (builder, val, 0, "");
5427 case OP_MEMORY_BARRIER: {
5428 mono_llvm_build_fence (builder, (BarrierKind) ins->backend.memory_barrier_kind);
5431 case OP_ATOMIC_LOAD_I1:
5432 case OP_ATOMIC_LOAD_I2:
5433 case OP_ATOMIC_LOAD_I4:
5434 case OP_ATOMIC_LOAD_I8:
5435 case OP_ATOMIC_LOAD_U1:
5436 case OP_ATOMIC_LOAD_U2:
5437 case OP_ATOMIC_LOAD_U4:
5438 case OP_ATOMIC_LOAD_U8:
5439 case OP_ATOMIC_LOAD_R4:
5440 case OP_ATOMIC_LOAD_R8: {
5441 set_failure (ctx, "atomic mono.load intrinsic");
5445 gboolean sext, zext;
5447 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
5448 BarrierKind barrier = (BarrierKind) ins->backend.memory_barrier_kind;
5449 LLVMValueRef index, addr;
5451 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
5456 if (ins->inst_offset != 0) {
5457 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
5458 addr = LLVMBuildGEP (builder, convert (ctx, lhs, LLVMPointerType (t, 0)), &index, 1, "");
5463 addr = convert (ctx, addr, LLVMPointerType (t, 0));
5465 values [ins->dreg] = emit_load_general (ctx, bb, &builder, size, addr, dname, is_volatile, barrier);
5468 values [ins->dreg] = LLVMBuildSExt (builder, values [ins->dreg], LLVMInt32Type (), dname);
5470 values [ins->dreg] = LLVMBuildZExt (builder, values [ins->dreg], LLVMInt32Type (), dname);
5474 case OP_ATOMIC_STORE_I1:
5475 case OP_ATOMIC_STORE_I2:
5476 case OP_ATOMIC_STORE_I4:
5477 case OP_ATOMIC_STORE_I8:
5478 case OP_ATOMIC_STORE_U1:
5479 case OP_ATOMIC_STORE_U2:
5480 case OP_ATOMIC_STORE_U4:
5481 case OP_ATOMIC_STORE_U8:
5482 case OP_ATOMIC_STORE_R4:
5483 case OP_ATOMIC_STORE_R8: {
5485 gboolean sext, zext;
5487 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
5488 BarrierKind barrier = (BarrierKind) ins->backend.memory_barrier_kind;
5489 LLVMValueRef index, addr, value;
5491 if (!cfg->llvm_only) {
5492 set_failure (ctx, "atomic mono.store intrinsic");
5496 if (!values [ins->inst_destbasereg]) {
5497 set_failure (ctx, "inst_destbasereg");
5501 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
5503 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
5504 addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (t, 0)), &index, 1, "");
5505 value = convert (ctx, values [ins->sreg1], t);
5507 emit_store_general (ctx, bb, &builder, size, value, addr, is_volatile, barrier);
5510 case OP_RELAXED_NOP: {
5511 #if defined(TARGET_AMD64) || defined(TARGET_X86)
5512 emit_call (ctx, bb, &builder, get_intrinsic (ctx, "llvm.x86.sse2.pause"), NULL, 0);
5519 #if (defined(TARGET_AMD64) || defined(TARGET_X86)) && defined(__linux__)
5521 // 257 == FS segment register
5522 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 257);
5524 // 256 == GS segment register
5525 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 256);
5528 values [ins->dreg] = LLVMBuildLoad (builder, LLVMBuildIntToPtr (builder, LLVMConstInt (IntPtrType (), ins->inst_offset, TRUE), ptrtype, ""), "");
5529 #elif defined(TARGET_AMD64) && defined(TARGET_OSX)
5530 /* See mono_amd64_emit_tls_get () */
5531 int offset = mono_amd64_get_tls_gs_offset () + (ins->inst_offset * 8);
5533 // 256 == GS segment register
5534 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 256);
5535 values [ins->dreg] = LLVMBuildLoad (builder, LLVMBuildIntToPtr (builder, LLVMConstInt (IntPtrType (), offset, TRUE), ptrtype, ""), "");
5537 set_failure (ctx, "opcode tls-get");
5543 case OP_TLS_GET_REG: {
5544 #if defined(TARGET_AMD64) && defined(TARGET_OSX)
5545 /* See emit_tls_get_reg () */
5546 // 256 == GS segment register
5547 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 256);
5548 values [ins->dreg] = LLVMBuildLoad (builder, LLVMBuildIntToPtr (builder, convert (ctx, lhs, LLVMInt32Type ()), ptrtype, ""), "");
5550 set_failure (ctx, "opcode tls-get");
5556 case OP_TLS_SET_REG: {
5557 #if defined(TARGET_AMD64) && defined(TARGET_OSX)
5558 /* See emit_tls_get_reg () */
5559 // 256 == GS segment register
5560 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 256);
5561 LLVMBuildStore (builder, convert (ctx, lhs, IntPtrType ()), LLVMBuildIntToPtr (builder, convert (ctx, rhs, LLVMInt32Type ()), ptrtype, ""));
5563 set_failure (ctx, "opcode tls-set-reg");
5568 case OP_GC_SAFE_POINT: {
5569 LLVMValueRef val, cmp, callee;
5570 LLVMBasicBlockRef poll_bb, cont_bb;
5571 static LLVMTypeRef sig;
5572 const char *icall_name = "mono_threads_state_poll";
5575 sig = LLVMFunctionType0 (LLVMVoidType (), FALSE);
5579 * mono_threads_state_poll ();
5580 * FIXME: Use a preserveall wrapper
5582 val = mono_llvm_build_load (builder, convert (ctx, lhs, LLVMPointerType (IntPtrType (), 0)), "", TRUE, LLVM_BARRIER_NONE);
5583 cmp = LLVMBuildICmp (builder, LLVMIntEQ, val, LLVMConstNull (LLVMTypeOf (val)), "");
5584 poll_bb = gen_bb (ctx, "POLL_BB");
5585 cont_bb = gen_bb (ctx, "CONT_BB");
5586 LLVMBuildCondBr (builder, cmp, cont_bb, poll_bb);
5588 ctx->builder = builder = create_builder (ctx);
5589 LLVMPositionBuilderAtEnd (builder, poll_bb);
5591 if (ctx->cfg->compile_aot) {
5592 callee = get_callee (ctx, sig, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
5594 gpointer target = resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
5595 callee = emit_jit_callee (ctx, icall_name, sig, target);
5597 LLVMBuildCall (builder, callee, NULL, 0, "");
5598 LLVMBuildBr (builder, cont_bb);
5600 ctx->builder = builder = create_builder (ctx);
5601 LLVMPositionBuilderAtEnd (builder, cont_bb);
5602 ctx->bblocks [bb->block_num].end_bblock = cont_bb;
5610 case OP_IADD_OVF_UN:
5612 case OP_ISUB_OVF_UN:
5614 case OP_IMUL_OVF_UN:
5616 case OP_LADD_OVF_UN:
5618 case OP_LSUB_OVF_UN:
5620 case OP_LMUL_OVF_UN:
5622 LLVMValueRef args [2], val, ovf, func;
5624 args [0] = convert (ctx, lhs, op_to_llvm_type (ins->opcode));
5625 args [1] = convert (ctx, rhs, op_to_llvm_type (ins->opcode));
5626 func = get_intrinsic (ctx, ovf_op_to_intrins (ins->opcode));
5628 val = LLVMBuildCall (builder, func, args, 2, "");
5629 values [ins->dreg] = LLVMBuildExtractValue (builder, val, 0, dname);
5630 ovf = LLVMBuildExtractValue (builder, val, 1, "");
5631 emit_cond_system_exception (ctx, bb, "OverflowException", ovf);
5634 builder = ctx->builder;
5640 * We currently model them using arrays. Promotion to local vregs is
5641 * disabled for them in mono_handle_global_vregs () in the LLVM case,
5642 * so we always have an entry in cfg->varinfo for them.
5643 * FIXME: Is this needed ?
5646 MonoClass *klass = ins->klass;
5647 LLVMValueRef args [5];
5651 set_failure (ctx, "!klass");
5655 if (!addresses [ins->dreg])
5656 addresses [ins->dreg] = build_alloca (ctx, &klass->byval_arg);
5657 args [0] = LLVMBuildBitCast (builder, addresses [ins->dreg], LLVMPointerType (LLVMInt8Type (), 0), "");
5658 args [1] = LLVMConstInt (LLVMInt8Type (), 0, FALSE);
5659 args [2] = LLVMConstInt (LLVMInt32Type (), mono_class_value_size (klass, NULL), FALSE);
5661 args [3] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
5662 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
5663 LLVMBuildCall (builder, get_intrinsic (ctx, "llvm.memset.p0i8.i32"), args, 5, "");
5666 case OP_DUMMY_VZERO:
5669 case OP_STOREV_MEMBASE:
5670 case OP_LOADV_MEMBASE:
5672 MonoClass *klass = ins->klass;
5673 LLVMValueRef src = NULL, dst, args [5];
5674 gboolean done = FALSE;
5678 set_failure (ctx, "!klass");
5682 if (mini_is_gsharedvt_klass (klass)) {
5684 set_failure (ctx, "gsharedvt");
5688 switch (ins->opcode) {
5689 case OP_STOREV_MEMBASE:
5690 if (cfg->gen_write_barriers && klass->has_references && ins->inst_destbasereg != cfg->frame_reg &&
5691 LLVMGetInstructionOpcode (values [ins->inst_destbasereg]) != LLVMAlloca) {
5692 /* Decomposed earlier */
5693 g_assert_not_reached ();
5696 if (!addresses [ins->sreg1]) {
5698 g_assert (values [ins->sreg1]);
5699 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));
5700 LLVMBuildStore (builder, values [ins->sreg1], dst);
5703 src = LLVMBuildBitCast (builder, addresses [ins->sreg1], LLVMPointerType (LLVMInt8Type (), 0), "");
5704 dst = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_destbasereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (LLVMInt8Type (), 0));
5707 case OP_LOADV_MEMBASE:
5708 if (!addresses [ins->dreg])
5709 addresses [ins->dreg] = build_alloca (ctx, &klass->byval_arg);
5710 src = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_basereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (LLVMInt8Type (), 0));
5711 dst = LLVMBuildBitCast (builder, addresses [ins->dreg], LLVMPointerType (LLVMInt8Type (), 0), "");
5714 if (!addresses [ins->sreg1])
5715 addresses [ins->sreg1] = build_alloca (ctx, &klass->byval_arg);
5716 if (!addresses [ins->dreg])
5717 addresses [ins->dreg] = build_alloca (ctx, &klass->byval_arg);
5718 src = LLVMBuildBitCast (builder, addresses [ins->sreg1], LLVMPointerType (LLVMInt8Type (), 0), "");
5719 dst = LLVMBuildBitCast (builder, addresses [ins->dreg], LLVMPointerType (LLVMInt8Type (), 0), "");
5722 g_assert_not_reached ();
5732 args [2] = LLVMConstInt (LLVMInt32Type (), mono_class_value_size (klass, NULL), FALSE);
5733 args [3] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
5735 args [3] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
5736 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
5737 LLVMBuildCall (builder, get_intrinsic (ctx, "llvm.memcpy.p0i8.p0i8.i32"), args, 5, "");
5740 case OP_LLVM_OUTARG_VT: {
5741 LLVMArgInfo *ainfo = (LLVMArgInfo*)ins->inst_p0;
5742 MonoType *t = mini_get_underlying_type (ins->inst_vtype);
5744 if (ainfo->storage == LLVMArgGsharedvtVariable) {
5745 MonoInst *var = get_vreg_to_inst (cfg, ins->sreg1);
5747 if (var && var->opcode == OP_GSHAREDVT_LOCAL) {
5748 addresses [ins->dreg] = convert (ctx, emit_gsharedvt_ldaddr (ctx, var->dreg), LLVMPointerType (IntPtrType (), 0));
5750 g_assert (addresses [ins->sreg1]);
5751 addresses [ins->dreg] = addresses [ins->sreg1];
5753 } else if (ainfo->storage == LLVMArgGsharedvtFixed) {
5754 if (!addresses [ins->sreg1]) {
5755 addresses [ins->sreg1] = build_alloca (ctx, t);
5756 g_assert (values [ins->sreg1]);
5758 LLVMBuildStore (builder, convert (ctx, values [ins->sreg1], LLVMGetElementType (LLVMTypeOf (addresses [ins->sreg1]))), addresses [ins->sreg1]);
5759 addresses [ins->dreg] = addresses [ins->sreg1];
5761 if (!addresses [ins->sreg1]) {
5762 addresses [ins->sreg1] = build_alloca (ctx, t);
5763 g_assert (values [ins->sreg1]);
5764 LLVMBuildStore (builder, convert (ctx, values [ins->sreg1], type_to_llvm_type (ctx, t)), addresses [ins->sreg1]);
5766 addresses [ins->dreg] = addresses [ins->sreg1];
5774 #if defined(TARGET_X86) || defined(TARGET_AMD64)
5776 values [ins->dreg] = LLVMConstNull (type_to_llvm_type (ctx, &ins->klass->byval_arg));
5779 case OP_LOADX_MEMBASE: {
5780 LLVMTypeRef t = type_to_llvm_type (ctx, &ins->klass->byval_arg);
5783 src = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_basereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (t, 0));
5784 values [ins->dreg] = mono_llvm_build_aligned_load (builder, src, "", FALSE, 1);
5787 case OP_STOREX_MEMBASE: {
5788 LLVMTypeRef t = LLVMTypeOf (values [ins->sreg1]);
5791 dest = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_destbasereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (t, 0));
5792 mono_llvm_build_aligned_store (builder, values [ins->sreg1], dest, FALSE, 1);
5799 values [ins->dreg] = LLVMBuildAdd (builder, lhs, rhs, "");
5803 values [ins->dreg] = LLVMBuildFAdd (builder, lhs, rhs, "");
5809 values [ins->dreg] = LLVMBuildSub (builder, lhs, rhs, "");
5813 values [ins->dreg] = LLVMBuildFSub (builder, lhs, rhs, "");
5817 values [ins->dreg] = LLVMBuildFMul (builder, lhs, rhs, "");
5821 values [ins->dreg] = LLVMBuildFDiv (builder, lhs, rhs, "");
5824 values [ins->dreg] = LLVMBuildAnd (builder, lhs, rhs, "");
5827 values [ins->dreg] = LLVMBuildOr (builder, lhs, rhs, "");
5830 values [ins->dreg] = LLVMBuildXor (builder, lhs, rhs, "");
5834 values [ins->dreg] = LLVMBuildMul (builder, lhs, rhs, "");
5845 LLVMValueRef v = NULL;
5847 switch (ins->opcode) {
5852 t = LLVMVectorType (LLVMInt32Type (), 4);
5853 rt = LLVMVectorType (LLVMFloatType (), 4);
5859 t = LLVMVectorType (LLVMInt64Type (), 2);
5860 rt = LLVMVectorType (LLVMDoubleType (), 2);
5863 t = LLVMInt32Type ();
5864 rt = LLVMInt32Type ();
5865 g_assert_not_reached ();
5868 lhs = LLVMBuildBitCast (builder, lhs, t, "");
5869 rhs = LLVMBuildBitCast (builder, rhs, t, "");
5870 switch (ins->opcode) {
5873 v = LLVMBuildAnd (builder, lhs, rhs, "");
5877 v = LLVMBuildOr (builder, lhs, rhs, "");
5881 v = LLVMBuildXor (builder, lhs, rhs, "");
5885 v = LLVMBuildAnd (builder, rhs, LLVMBuildNot (builder, lhs, ""), "");
5888 values [ins->dreg] = LLVMBuildBitCast (builder, v, rt, "");
5912 case OP_PADDB_SAT_UN:
5913 case OP_PADDW_SAT_UN:
5914 case OP_PSUBB_SAT_UN:
5915 case OP_PSUBW_SAT_UN:
5923 case OP_PMULW_HIGH_UN: {
5924 LLVMValueRef args [2];
5929 values [ins->dreg] = LLVMBuildCall (builder, get_intrinsic (ctx, simd_op_to_intrins (ins->opcode)), args, 2, dname);
5936 values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildICmp (builder, LLVMIntEQ, lhs, rhs, ""), LLVMTypeOf (lhs), "");
5940 values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildICmp (builder, LLVMIntSGT, lhs, rhs, ""), LLVMTypeOf (lhs), "");
5948 case OP_EXTRACTX_U2:
5950 case OP_EXTRACT_U1: {
5952 gboolean zext = FALSE;
5954 t = simd_op_to_llvm_type (ins->opcode);
5956 switch (ins->opcode) {
5964 case OP_EXTRACTX_U2:
5969 t = LLVMInt32Type ();
5970 g_assert_not_reached ();
5973 lhs = LLVMBuildBitCast (builder, lhs, t, "");
5974 values [ins->dreg] = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), "");
5976 values [ins->dreg] = LLVMBuildZExt (builder, values [ins->dreg], LLVMInt32Type (), "");
5985 case OP_EXPAND_R8: {
5986 LLVMTypeRef t = simd_op_to_llvm_type (ins->opcode);
5987 LLVMValueRef mask [16], v;
5990 for (i = 0; i < 16; ++i)
5991 mask [i] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
5993 v = convert (ctx, values [ins->sreg1], LLVMGetElementType (t));
5995 values [ins->dreg] = LLVMBuildInsertElement (builder, LLVMConstNull (t), v, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
5996 values [ins->dreg] = LLVMBuildShuffleVector (builder, values [ins->dreg], LLVMGetUndef (t), LLVMConstVector (mask, LLVMGetVectorSize (t)), "");
6001 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt8Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
6004 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt16Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
6007 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt32Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
6010 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt64Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
6013 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMFloatType ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
6016 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMDoubleType ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
6027 case OP_EXTRACT_MASK:
6034 v = convert (ctx, values [ins->sreg1], simd_op_to_llvm_type (ins->opcode));
6036 values [ins->dreg] = LLVMBuildCall (builder, get_intrinsic (ctx, simd_op_to_intrins (ins->opcode)), &v, 1, dname);
6042 LLVMValueRef args [3];
6046 args [2] = LLVMConstInt (LLVMInt8Type (), ins->inst_c0, FALSE);
6048 values [ins->dreg] = LLVMBuildCall (builder, get_intrinsic (ctx, simd_op_to_intrins (ins->opcode)), args, 3, dname);
6053 /* This is only used for implementing shifts by non-immediate */
6054 values [ins->dreg] = lhs;
6065 LLVMValueRef args [3];
6068 args [1] = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
6070 values [ins->dreg] = LLVMBuildCall (builder, get_intrinsic (ctx, simd_op_to_intrins (ins->opcode)), args, 2, dname);
6081 case OP_PSHLQ_REG: {
6082 LLVMValueRef args [3];
6085 args [1] = values [ins->sreg2];
6087 values [ins->dreg] = LLVMBuildCall (builder, get_intrinsic (ctx, simd_op_to_intrins (ins->opcode)), args, 2, dname);
6094 case OP_PSHUFLEW_LOW:
6095 case OP_PSHUFLEW_HIGH: {
6097 LLVMValueRef v1 = NULL, v2 = NULL, mask_values [16];
6098 int i, mask_size = 0;
6099 int imask = ins->inst_c0;
6101 /* Convert the x86 shuffle mask to LLVM's */
6102 switch (ins->opcode) {
6105 mask [0] = ((imask >> 0) & 3);
6106 mask [1] = ((imask >> 2) & 3);
6107 mask [2] = ((imask >> 4) & 3) + 4;
6108 mask [3] = ((imask >> 6) & 3) + 4;
6109 v1 = values [ins->sreg1];
6110 v2 = values [ins->sreg2];
6114 mask [0] = ((imask >> 0) & 1);
6115 mask [1] = ((imask >> 1) & 1) + 2;
6116 v1 = values [ins->sreg1];
6117 v2 = values [ins->sreg2];
6119 case OP_PSHUFLEW_LOW:
6121 mask [0] = ((imask >> 0) & 3);
6122 mask [1] = ((imask >> 2) & 3);
6123 mask [2] = ((imask >> 4) & 3);
6124 mask [3] = ((imask >> 6) & 3);
6129 v1 = values [ins->sreg1];
6130 v2 = LLVMGetUndef (LLVMTypeOf (v1));
6132 case OP_PSHUFLEW_HIGH:
6138 mask [4] = 4 + ((imask >> 0) & 3);
6139 mask [5] = 4 + ((imask >> 2) & 3);
6140 mask [6] = 4 + ((imask >> 4) & 3);
6141 mask [7] = 4 + ((imask >> 6) & 3);
6142 v1 = values [ins->sreg1];
6143 v2 = LLVMGetUndef (LLVMTypeOf (v1));
6147 mask [0] = ((imask >> 0) & 3);
6148 mask [1] = ((imask >> 2) & 3);
6149 mask [2] = ((imask >> 4) & 3);
6150 mask [3] = ((imask >> 6) & 3);
6151 v1 = values [ins->sreg1];
6152 v2 = LLVMGetUndef (LLVMTypeOf (v1));
6155 g_assert_not_reached ();
6157 for (i = 0; i < mask_size; ++i)
6158 mask_values [i] = LLVMConstInt (LLVMInt32Type (), mask [i], FALSE);
6160 values [ins->dreg] =
6161 LLVMBuildShuffleVector (builder, v1, v2,
6162 LLVMConstVector (mask_values, mask_size), dname);
6166 case OP_UNPACK_LOWB:
6167 case OP_UNPACK_LOWW:
6168 case OP_UNPACK_LOWD:
6169 case OP_UNPACK_LOWQ:
6170 case OP_UNPACK_LOWPS:
6171 case OP_UNPACK_LOWPD:
6172 case OP_UNPACK_HIGHB:
6173 case OP_UNPACK_HIGHW:
6174 case OP_UNPACK_HIGHD:
6175 case OP_UNPACK_HIGHQ:
6176 case OP_UNPACK_HIGHPS:
6177 case OP_UNPACK_HIGHPD: {
6179 LLVMValueRef mask_values [16];
6180 int i, mask_size = 0;
6181 gboolean low = FALSE;
6183 switch (ins->opcode) {
6184 case OP_UNPACK_LOWB:
6188 case OP_UNPACK_LOWW:
6192 case OP_UNPACK_LOWD:
6193 case OP_UNPACK_LOWPS:
6197 case OP_UNPACK_LOWQ:
6198 case OP_UNPACK_LOWPD:
6202 case OP_UNPACK_HIGHB:
6205 case OP_UNPACK_HIGHW:
6208 case OP_UNPACK_HIGHD:
6209 case OP_UNPACK_HIGHPS:
6212 case OP_UNPACK_HIGHQ:
6213 case OP_UNPACK_HIGHPD:
6217 g_assert_not_reached ();
6221 for (i = 0; i < (mask_size / 2); ++i) {
6223 mask [(i * 2) + 1] = mask_size + i;
6226 for (i = 0; i < (mask_size / 2); ++i) {
6227 mask [(i * 2)] = (mask_size / 2) + i;
6228 mask [(i * 2) + 1] = mask_size + (mask_size / 2) + i;
6232 for (i = 0; i < mask_size; ++i)
6233 mask_values [i] = LLVMConstInt (LLVMInt32Type (), mask [i], FALSE);
6235 values [ins->dreg] =
6236 LLVMBuildShuffleVector (builder, values [ins->sreg1], values [ins->sreg2],
6237 LLVMConstVector (mask_values, mask_size), dname);
6242 LLVMTypeRef t = simd_op_to_llvm_type (ins->opcode);
6243 LLVMValueRef v, val;
6245 v = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
6246 val = LLVMConstNull (t);
6247 val = LLVMBuildInsertElement (builder, val, v, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
6248 val = LLVMBuildInsertElement (builder, val, v, LLVMConstInt (LLVMInt32Type (), 1, FALSE), dname);
6250 values [ins->dreg] = val;
6254 case OP_DUPPS_HIGH: {
6255 LLVMTypeRef t = simd_op_to_llvm_type (ins->opcode);
6256 LLVMValueRef v1, v2, val;
6259 if (ins->opcode == OP_DUPPS_LOW) {
6260 v1 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
6261 v2 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 2, FALSE), "");
6263 v1 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 1, FALSE), "");
6264 v2 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 3, FALSE), "");
6266 val = LLVMConstNull (t);
6267 val = LLVMBuildInsertElement (builder, val, v1, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
6268 val = LLVMBuildInsertElement (builder, val, v1, LLVMConstInt (LLVMInt32Type (), 1, FALSE), "");
6269 val = LLVMBuildInsertElement (builder, val, v2, LLVMConstInt (LLVMInt32Type (), 2, FALSE), "");
6270 val = LLVMBuildInsertElement (builder, val, v2, LLVMConstInt (LLVMInt32Type (), 3, FALSE), "");
6272 values [ins->dreg] = val;
6282 * EXCEPTION HANDLING
6284 case OP_IMPLICIT_EXCEPTION:
6285 /* This marks a place where an implicit exception can happen */
6286 if (bb->region != -1)
6287 set_failure (ctx, "implicit-exception");
6291 gboolean rethrow = (ins->opcode == OP_RETHROW);
6292 if (ctx->llvm_only) {
6293 emit_llvmonly_throw (ctx, bb, rethrow, lhs);
6294 has_terminator = TRUE;
6295 ctx->unreachable [bb->block_num] = TRUE;
6297 emit_throw (ctx, bb, rethrow, lhs);
6298 builder = ctx->builder;
6302 case OP_CALL_HANDLER: {
6304 * We don't 'call' handlers, but instead simply branch to them.
6305 * The code generated by ENDFINALLY will branch back to us.
6307 LLVMBasicBlockRef noex_bb;
6309 BBInfo *info = &bblocks [ins->inst_target_bb->block_num];
6311 bb_list = info->call_handler_return_bbs;
6314 * Set the indicator variable for the finally clause.
6316 lhs = info->finally_ind;
6318 LLVMBuildStore (builder, LLVMConstInt (LLVMInt32Type (), g_slist_length (bb_list) + 1, FALSE), lhs);
6320 /* Branch to the finally clause */
6321 LLVMBuildBr (builder, info->call_handler_target_bb);
6323 noex_bb = gen_bb (ctx, "CALL_HANDLER_CONT_BB");
6324 info->call_handler_return_bbs = g_slist_append_mempool (cfg->mempool, info->call_handler_return_bbs, noex_bb);
6326 builder = ctx->builder = create_builder (ctx);
6327 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
6329 bblocks [bb->block_num].end_bblock = noex_bb;
6332 case OP_START_HANDLER: {
6335 case OP_ENDFINALLY: {
6336 LLVMBasicBlockRef resume_bb;
6337 MonoBasicBlock *handler_bb;
6338 LLVMValueRef val, switch_ins, callee;
6342 handler_bb = (MonoBasicBlock*)g_hash_table_lookup (ctx->region_to_handler, GUINT_TO_POINTER (mono_get_block_region_notry (cfg, bb->region)));
6343 g_assert (handler_bb);
6344 info = &bblocks [handler_bb->block_num];
6345 lhs = info->finally_ind;
6348 bb_list = info->call_handler_return_bbs;
6350 resume_bb = gen_bb (ctx, "ENDFINALLY_RESUME_BB");
6352 /* Load the finally variable */
6353 val = LLVMBuildLoad (builder, lhs, "");
6355 /* Reset the variable */
6356 LLVMBuildStore (builder, LLVMConstInt (LLVMInt32Type (), 0, FALSE), lhs);
6358 /* Branch to either resume_bb, or to the bblocks in bb_list */
6359 switch_ins = LLVMBuildSwitch (builder, val, resume_bb, g_slist_length (bb_list));
6361 * The other targets are added at the end to handle OP_CALL_HANDLER
6362 * opcodes processed later.
6364 info->endfinally_switch_ins_list = g_slist_append_mempool (cfg->mempool, info->endfinally_switch_ins_list, switch_ins);
6366 builder = ctx->builder = create_builder (ctx);
6367 LLVMPositionBuilderAtEnd (ctx->builder, resume_bb);
6369 if (ctx->llvm_only) {
6370 emit_resume_eh (ctx, bb);
6372 if (ctx->cfg->compile_aot) {
6373 callee = get_callee (ctx, LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE), MONO_PATCH_INFO_INTERNAL_METHOD, "llvm_resume_unwind_trampoline");
6375 #if LLVM_API_VERSION > 100
6376 MonoJitICallInfo *info;
6378 info = mono_find_jit_icall_by_name ("llvm_resume_unwind_trampoline");
6380 gpointer target = (void*)info->func;
6381 LLVMTypeRef icall_sig = LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE);
6382 callee = emit_jit_callee (ctx, "llvm_resume_unwind_trampoline", icall_sig, target);
6384 callee = LLVMGetNamedFunction (ctx->lmodule, "llvm_resume_unwind_trampoline");
6387 LLVMBuildCall (builder, callee, NULL, 0, "");
6388 LLVMBuildUnreachable (builder);
6391 has_terminator = TRUE;
6394 case OP_IL_SEQ_POINT:
6399 sprintf (reason, "opcode %s", mono_inst_name (ins->opcode));
6400 set_failure (ctx, reason);
6408 /* Convert the value to the type required by phi nodes */
6409 if (spec [MONO_INST_DEST] != ' ' && !MONO_IS_STORE_MEMBASE (ins) && ctx->vreg_types [ins->dreg]) {
6410 if (!values [ins->dreg])
6412 values [ins->dreg] = addresses [ins->dreg];
6414 values [ins->dreg] = convert (ctx, values [ins->dreg], ctx->vreg_types [ins->dreg]);
6417 /* Add stores for volatile variables */
6418 if (spec [MONO_INST_DEST] != ' ' && spec [MONO_INST_DEST] != 'v' && !MONO_IS_STORE_MEMBASE (ins))
6419 emit_volatile_store (ctx, ins->dreg);
6425 if (!has_terminator && bb->next_bb && (bb == cfg->bb_entry || bb->in_count > 0)) {
6426 LLVMBuildBr (builder, get_bb (ctx, bb->next_bb));
6429 if (bb == cfg->bb_exit && sig->ret->type == MONO_TYPE_VOID) {
6430 emit_dbg_loc (ctx, builder, cfg->header->code + cfg->header->code_size - 1);
6431 LLVMBuildRetVoid (builder);
6434 if (bb == cfg->bb_entry)
6435 ctx->last_alloca = LLVMGetLastInstruction (get_bb (ctx, cfg->bb_entry));
6439 * mono_llvm_check_method_supported:
6441 * Do some quick checks to decide whenever cfg->method can be compiled by LLVM, to avoid
6442 * compiling a method twice.
6445 mono_llvm_check_method_supported (MonoCompile *cfg)
6452 if (cfg->method->save_lmf) {
6453 cfg->exception_message = g_strdup ("lmf");
6454 cfg->disable_llvm = TRUE;
6456 if (cfg->disable_llvm)
6460 * Nested clauses where one of the clauses is a finally clause is
6461 * not supported, because LLVM can't figure out the control flow,
6462 * probably because we resume exception handling by calling our
6463 * own function instead of using the 'resume' llvm instruction.
6465 for (i = 0; i < cfg->header->num_clauses; ++i) {
6466 for (j = 0; j < cfg->header->num_clauses; ++j) {
6467 MonoExceptionClause *clause1 = &cfg->header->clauses [i];
6468 MonoExceptionClause *clause2 = &cfg->header->clauses [j];
6470 // FIXME: Nested try clauses fail in some cases too, i.e. #37273
6471 if (i != j && clause1->try_offset >= clause2->try_offset && clause1->handler_offset <= clause2->handler_offset) {
6472 //(clause1->flags == MONO_EXCEPTION_CLAUSE_FINALLY || clause2->flags == MONO_EXCEPTION_CLAUSE_FINALLY)) {
6473 cfg->exception_message = g_strdup ("nested clauses");
6474 cfg->disable_llvm = TRUE;
6479 if (cfg->disable_llvm)
6483 if (cfg->method->dynamic) {
6484 cfg->exception_message = g_strdup ("dynamic.");
6485 cfg->disable_llvm = TRUE;
6487 if (cfg->disable_llvm)
6491 static LLVMCallInfo*
6492 get_llvm_call_info (MonoCompile *cfg, MonoMethodSignature *sig)
6494 LLVMCallInfo *linfo;
6497 if (cfg->gsharedvt && cfg->llvm_only && mini_is_gsharedvt_variable_signature (sig)) {
6501 * Gsharedvt methods have the following calling convention:
6502 * - all arguments are passed by ref, even non generic ones
6503 * - the return value is returned by ref too, using a vret
6504 * argument passed after 'this'.
6506 n = sig->param_count + sig->hasthis;
6507 linfo = (LLVMCallInfo*)mono_mempool_alloc0 (cfg->mempool, sizeof (LLVMCallInfo) + (sizeof (LLVMArgInfo) * n));
6511 linfo->args [pindex ++].storage = LLVMArgNormal;
6513 if (sig->ret->type != MONO_TYPE_VOID) {
6514 if (mini_is_gsharedvt_variable_type (sig->ret))
6515 linfo->ret.storage = LLVMArgGsharedvtVariable;
6516 else if (mini_type_is_vtype (sig->ret))
6517 linfo->ret.storage = LLVMArgGsharedvtFixedVtype;
6519 linfo->ret.storage = LLVMArgGsharedvtFixed;
6520 linfo->vret_arg_index = pindex;
6522 linfo->ret.storage = LLVMArgNone;
6525 for (i = 0; i < sig->param_count; ++i) {
6526 if (sig->params [i]->byref)
6527 linfo->args [pindex].storage = LLVMArgNormal;
6528 else if (mini_is_gsharedvt_variable_type (sig->params [i]))
6529 linfo->args [pindex].storage = LLVMArgGsharedvtVariable;
6530 else if (mini_type_is_vtype (sig->params [i]))
6531 linfo->args [pindex].storage = LLVMArgGsharedvtFixedVtype;
6533 linfo->args [pindex].storage = LLVMArgGsharedvtFixed;
6534 linfo->args [pindex].type = sig->params [i];
6541 linfo = mono_arch_get_llvm_call_info (cfg, sig);
6542 for (i = 0; i < sig->param_count; ++i)
6543 linfo->args [i + sig->hasthis].type = sig->params [i];
6549 emit_method_inner (EmitContext *ctx);
6552 free_ctx (EmitContext *ctx)
6556 g_free (ctx->values);
6557 g_free (ctx->addresses);
6558 g_free (ctx->vreg_types);
6559 g_free (ctx->vreg_cli_types);
6560 g_free (ctx->is_dead);
6561 g_free (ctx->unreachable);
6562 g_ptr_array_free (ctx->phi_values, TRUE);
6563 g_free (ctx->bblocks);
6564 g_hash_table_destroy (ctx->region_to_handler);
6565 g_hash_table_destroy (ctx->clause_to_handler);
6566 g_hash_table_destroy (ctx->jit_callees);
6567 g_free (ctx->method_name);
6568 g_ptr_array_free (ctx->bblock_list, TRUE);
6570 for (l = ctx->builders; l; l = l->next) {
6571 LLVMBuilderRef builder = (LLVMBuilderRef)l->data;
6572 LLVMDisposeBuilder (builder);
6579 * mono_llvm_emit_method:
6581 * Emit LLVM IL from the mono IL, and compile it to native code using LLVM.
6584 mono_llvm_emit_method (MonoCompile *cfg)
6588 gboolean is_linkonce = FALSE;
6591 /* The code below might acquire the loader lock, so use it for global locking */
6592 mono_loader_lock ();
6594 /* Used to communicate with the callbacks */
6595 mono_native_tls_set_value (current_cfg_tls_id, cfg);
6597 ctx = g_new0 (EmitContext, 1);
6599 ctx->mempool = cfg->mempool;
6602 * This maps vregs to the LLVM instruction defining them
6604 ctx->values = g_new0 (LLVMValueRef, cfg->next_vreg);
6606 * This maps vregs for volatile variables to the LLVM instruction defining their
6609 ctx->addresses = g_new0 (LLVMValueRef, cfg->next_vreg);
6610 ctx->vreg_types = g_new0 (LLVMTypeRef, cfg->next_vreg);
6611 ctx->vreg_cli_types = g_new0 (MonoType*, cfg->next_vreg);
6612 ctx->phi_values = g_ptr_array_sized_new (256);
6614 * This signals whenever the vreg was defined by a phi node with no input vars
6615 * (i.e. all its input bblocks end with NOT_REACHABLE).
6617 ctx->is_dead = g_new0 (gboolean, cfg->next_vreg);
6618 /* Whenever the bblock is unreachable */
6619 ctx->unreachable = g_new0 (gboolean, cfg->max_block_num);
6620 ctx->bblock_list = g_ptr_array_sized_new (256);
6622 ctx->region_to_handler = g_hash_table_new (NULL, NULL);
6623 ctx->clause_to_handler = g_hash_table_new (NULL, NULL);
6624 ctx->method_to_callers = g_hash_table_new (NULL, NULL);
6625 ctx->jit_callees = g_hash_table_new (NULL, NULL);
6626 if (cfg->compile_aot) {
6627 ctx->module = &aot_module;
6631 * Allow the linker to discard duplicate copies of wrappers, generic instances etc. by using the 'linkonce'
6632 * linkage for them. This requires the following:
6633 * - the method needs to have a unique mangled name
6634 * - llvmonly mode, since the code in aot-runtime.c would initialize got slots in the wrong aot image etc.
6636 is_linkonce = ctx->module->llvm_only && ctx->module->static_link && mono_aot_is_linkonce_method (cfg->method);
6638 method_name = mono_aot_get_mangled_method_name (cfg->method);
6640 is_linkonce = FALSE;
6643 printf ("%s %s\n", mono_method_full_name (cfg->method, 1), method_name);
6645 printf ("%s\n", mono_method_full_name (cfg->method, 1));
6649 method_name = mono_aot_get_method_name (cfg);
6650 cfg->llvm_method_name = g_strdup (method_name);
6652 init_jit_module (cfg->domain);
6653 ctx->module = (MonoLLVMModule*)domain_jit_info (cfg->domain)->llvm_module;
6654 method_name = mono_method_full_name (cfg->method, TRUE);
6656 ctx->method_name = method_name;
6657 ctx->is_linkonce = is_linkonce;
6659 #if LLVM_API_VERSION > 100
6660 ctx->lmodule = LLVMModuleCreateWithName ("jit-module");
6662 ctx->lmodule = ctx->module->lmodule;
6664 ctx->llvm_only = ctx->module->llvm_only;
6666 emit_method_inner (ctx);
6668 if (!ctx_ok (ctx)) {
6670 /* Need to add unused phi nodes as they can be referenced by other values */
6671 LLVMBasicBlockRef phi_bb = LLVMAppendBasicBlock (ctx->lmethod, "PHI_BB");
6672 LLVMBuilderRef builder;
6674 builder = create_builder (ctx);
6675 LLVMPositionBuilderAtEnd (builder, phi_bb);
6677 for (i = 0; i < ctx->phi_values->len; ++i) {
6678 LLVMValueRef v = (LLVMValueRef)g_ptr_array_index (ctx->phi_values, i);
6679 if (LLVMGetInstructionParent (v) == NULL)
6680 LLVMInsertIntoBuilder (builder, v);
6683 LLVMDeleteFunction (ctx->lmethod);
6689 mono_native_tls_set_value (current_cfg_tls_id, NULL);
6691 mono_loader_unlock ();
6695 emit_method_inner (EmitContext *ctx)
6697 MonoCompile *cfg = ctx->cfg;
6698 MonoMethodSignature *sig;
6700 LLVMTypeRef method_type;
6701 LLVMValueRef method = NULL;
6702 LLVMValueRef *values = ctx->values;
6703 int i, max_block_num, bb_index;
6704 gboolean last = FALSE;
6705 LLVMCallInfo *linfo;
6706 LLVMModuleRef lmodule = ctx->lmodule;
6708 GPtrArray *bblock_list = ctx->bblock_list;
6709 MonoMethodHeader *header;
6710 MonoExceptionClause *clause;
6713 if (cfg->gsharedvt && !cfg->llvm_only) {
6714 set_failure (ctx, "gsharedvt");
6720 static int count = 0;
6723 if (g_getenv ("LLVM_COUNT")) {
6724 if (count == atoi (g_getenv ("LLVM_COUNT"))) {
6725 printf ("LAST: %s\n", mono_method_full_name (cfg->method, TRUE));
6729 if (count > atoi (g_getenv ("LLVM_COUNT"))) {
6730 set_failure (ctx, "count");
6737 sig = mono_method_signature (cfg->method);
6740 linfo = get_llvm_call_info (cfg, sig);
6746 linfo->rgctx_arg = TRUE;
6747 ctx->method_type = method_type = sig_to_llvm_sig_full (ctx, sig, linfo);
6751 method = LLVMAddFunction (lmodule, ctx->method_name, method_type);
6752 ctx->lmethod = method;
6754 if (!cfg->llvm_only)
6755 LLVMSetFunctionCallConv (method, LLVMMono1CallConv);
6756 LLVMSetLinkage (method, LLVMPrivateLinkage);
6758 LLVMAddFunctionAttr (method, LLVMUWTable);
6760 if (cfg->compile_aot) {
6761 LLVMSetLinkage (method, LLVMInternalLinkage);
6762 if (ctx->module->external_symbols) {
6763 LLVMSetLinkage (method, LLVMExternalLinkage);
6764 LLVMSetVisibility (method, LLVMHiddenVisibility);
6766 if (ctx->is_linkonce) {
6767 LLVMSetLinkage (method, LLVMLinkOnceAnyLinkage);
6768 LLVMSetVisibility (method, LLVMDefaultVisibility);
6771 #if LLVM_API_VERSION > 100
6772 LLVMSetLinkage (method, LLVMExternalLinkage);
6774 LLVMSetLinkage (method, LLVMPrivateLinkage);
6778 if (cfg->method->save_lmf && !cfg->llvm_only) {
6779 set_failure (ctx, "lmf");
6783 if (sig->pinvoke && cfg->method->wrapper_type != MONO_WRAPPER_RUNTIME_INVOKE && !cfg->llvm_only) {
6784 set_failure (ctx, "pinvoke signature");
6788 header = cfg->header;
6789 for (i = 0; i < header->num_clauses; ++i) {
6790 clause = &header->clauses [i];
6791 if (clause->flags != MONO_EXCEPTION_CLAUSE_FINALLY && clause->flags != MONO_EXCEPTION_CLAUSE_NONE) {
6792 set_failure (ctx, "non-finally/catch clause.");
6796 if (header->num_clauses || (cfg->method->iflags & METHOD_IMPL_ATTRIBUTE_NOINLINING) || cfg->no_inline)
6797 /* We can't handle inlined methods with clauses */
6798 LLVMAddFunctionAttr (method, LLVMNoInlineAttribute);
6800 if (linfo->rgctx_arg) {
6801 ctx->rgctx_arg = LLVMGetParam (method, linfo->rgctx_arg_pindex);
6802 ctx->rgctx_arg_pindex = linfo->rgctx_arg_pindex;
6804 * We mark the rgctx parameter with the inreg attribute, which is mapped to
6805 * MONO_ARCH_RGCTX_REG in the Mono calling convention in llvm, i.e.
6806 * CC_X86_64_Mono in X86CallingConv.td.
6808 if (!ctx->llvm_only)
6809 LLVMAddAttribute (ctx->rgctx_arg, LLVMInRegAttribute);
6810 LLVMSetValueName (ctx->rgctx_arg, "rgctx");
6812 ctx->rgctx_arg_pindex = -1;
6814 if (cfg->vret_addr) {
6815 values [cfg->vret_addr->dreg] = LLVMGetParam (method, linfo->vret_arg_pindex);
6816 LLVMSetValueName (values [cfg->vret_addr->dreg], "vret");
6817 if (linfo->ret.storage == LLVMArgVtypeByRef) {
6818 LLVMAddAttribute (LLVMGetParam (method, linfo->vret_arg_pindex), LLVMStructRetAttribute);
6819 LLVMAddAttribute (LLVMGetParam (method, linfo->vret_arg_pindex), LLVMNoAliasAttribute);
6824 ctx->this_arg_pindex = linfo->this_arg_pindex;
6825 ctx->this_arg = LLVMGetParam (method, linfo->this_arg_pindex);
6826 values [cfg->args [0]->dreg] = ctx->this_arg;
6827 LLVMSetValueName (values [cfg->args [0]->dreg], "this");
6830 names = g_new (char *, sig->param_count);
6831 mono_method_get_param_names (cfg->method, (const char **) names);
6833 for (i = 0; i < sig->param_count; ++i) {
6834 LLVMArgInfo *ainfo = &linfo->args [i + sig->hasthis];
6836 int pindex = ainfo->pindex + ainfo->ndummy_fpargs;
6839 for (j = 0; j < ainfo->ndummy_fpargs; ++j) {
6840 name = g_strdup_printf ("dummy_%d_%d", i, j);
6841 LLVMSetValueName (LLVMGetParam (method, ainfo->pindex + j), name);
6845 values [cfg->args [i + sig->hasthis]->dreg] = LLVMGetParam (method, pindex);
6846 if (ainfo->storage == LLVMArgGsharedvtFixed || ainfo->storage == LLVMArgGsharedvtFixedVtype) {
6847 if (names [i] && names [i][0] != '\0')
6848 name = g_strdup_printf ("p_arg_%s", names [i]);
6850 name = g_strdup_printf ("p_arg_%d", i);
6852 if (names [i] && names [i][0] != '\0')
6853 name = g_strdup_printf ("arg_%s", names [i]);
6855 name = g_strdup_printf ("arg_%d", i);
6857 LLVMSetValueName (values [cfg->args [i + sig->hasthis]->dreg], name);
6859 if (ainfo->storage == LLVMArgVtypeByVal)
6860 LLVMAddAttribute (LLVMGetParam (method, pindex), LLVMByValAttribute);
6862 if (ainfo->storage == LLVMArgVtypeByRef) {
6864 cfg->args [i + sig->hasthis]->opcode = OP_VTARG_ADDR;
6869 if (ctx->module->emit_dwarf && cfg->compile_aot && mono_debug_enabled ()) {
6870 ctx->minfo = mono_debug_lookup_method (cfg->method);
6871 ctx->dbg_md = emit_dbg_subprogram (ctx, cfg, method, ctx->method_name);
6875 for (bb = cfg->bb_entry; bb; bb = bb->next_bb)
6876 max_block_num = MAX (max_block_num, bb->block_num);
6877 ctx->bblocks = bblocks = g_new0 (BBInfo, max_block_num + 1);
6879 /* Add branches between non-consecutive bblocks */
6880 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
6881 if (bb->last_ins && MONO_IS_COND_BRANCH_OP (bb->last_ins) &&
6882 bb->next_bb != bb->last_ins->inst_false_bb) {
6884 MonoInst *inst = (MonoInst*)mono_mempool_alloc0 (cfg->mempool, sizeof (MonoInst));
6885 inst->opcode = OP_BR;
6886 inst->inst_target_bb = bb->last_ins->inst_false_bb;
6887 mono_bblock_add_inst (bb, inst);
6892 * The INDIRECT flag added by OP_LDADDR inhibits optimizations, even if the LDADDR
6893 * was later optimized away, so clear these flags, and add them back for the still
6894 * present OP_LDADDR instructions.
6896 for (i = 0; i < cfg->next_vreg; ++i) {
6899 ins = get_vreg_to_inst (cfg, i);
6900 if (ins && ins != cfg->rgctx_var)
6901 ins->flags &= ~MONO_INST_INDIRECT;
6905 * Make a first pass over the code to precreate PHI nodes/set INDIRECT flags.
6907 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
6909 LLVMBuilderRef builder;
6911 char dname_buf[128];
6913 builder = create_builder (ctx);
6915 for (ins = bb->code; ins; ins = ins->next) {
6916 switch (ins->opcode) {
6921 LLVMTypeRef phi_type = llvm_type_to_stack_type (cfg, type_to_llvm_type (ctx, &ins->klass->byval_arg));
6926 if (ins->opcode == OP_VPHI) {
6927 /* Treat valuetype PHI nodes as operating on the address itself */
6928 g_assert (ins->klass);
6929 phi_type = LLVMPointerType (type_to_llvm_type (ctx, &ins->klass->byval_arg), 0);
6933 * Have to precreate these, as they can be referenced by
6934 * earlier instructions.
6936 sprintf (dname_buf, "t%d", ins->dreg);
6938 values [ins->dreg] = LLVMBuildPhi (builder, phi_type, dname);
6940 if (ins->opcode == OP_VPHI)
6941 ctx->addresses [ins->dreg] = values [ins->dreg];
6943 g_ptr_array_add (ctx->phi_values, values [ins->dreg]);
6946 * Set the expected type of the incoming arguments since these have
6947 * to have the same type.
6949 for (i = 0; i < ins->inst_phi_args [0]; i++) {
6950 int sreg1 = ins->inst_phi_args [i + 1];
6953 ctx->vreg_types [sreg1] = phi_type;
6958 ((MonoInst*)ins->inst_p0)->flags |= MONO_INST_INDIRECT;
6967 * Create an ordering for bblocks, use the depth first order first, then
6968 * put the exception handling bblocks last.
6970 for (bb_index = 0; bb_index < cfg->num_bblocks; ++bb_index) {
6971 bb = cfg->bblocks [bb_index];
6972 if (!(bb->region != -1 && !MONO_BBLOCK_IS_IN_REGION (bb, MONO_REGION_TRY))) {
6973 g_ptr_array_add (bblock_list, bb);
6974 bblocks [bb->block_num].added = TRUE;
6978 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
6979 if (!bblocks [bb->block_num].added)
6980 g_ptr_array_add (bblock_list, bb);
6984 * Second pass: generate code.
6987 LLVMBuilderRef entry_builder = create_builder (ctx);
6988 LLVMBasicBlockRef entry_bb = get_bb (ctx, cfg->bb_entry);
6989 LLVMPositionBuilderAtEnd (entry_builder, entry_bb);
6990 emit_entry_bb (ctx, entry_builder);
6992 // Make landing pads first
6993 ctx->exc_meta = g_hash_table_new_full (NULL, NULL, NULL, NULL);
6995 if (ctx->llvm_only) {
6996 size_t group_index = 0;
6997 while (group_index < cfg->header->num_clauses) {
6999 size_t cursor = group_index;
7000 while (cursor < cfg->header->num_clauses &&
7001 CLAUSE_START (&cfg->header->clauses [cursor]) == CLAUSE_START (&cfg->header->clauses [group_index]) &&
7002 CLAUSE_END (&cfg->header->clauses [cursor]) == CLAUSE_END (&cfg->header->clauses [group_index])) {
7007 LLVMBasicBlockRef lpad_bb = emit_landing_pad (ctx, group_index, count);
7008 intptr_t key = CLAUSE_END (&cfg->header->clauses [group_index]);
7009 g_hash_table_insert (ctx->exc_meta, (gpointer)key, lpad_bb);
7011 group_index = cursor;
7015 for (bb_index = 0; bb_index < bblock_list->len; ++bb_index) {
7016 bb = (MonoBasicBlock*)g_ptr_array_index (bblock_list, bb_index);
7018 // Prune unreachable mono BBs.
7019 if (!(bb == cfg->bb_entry || bb->in_count > 0))
7022 process_bb (ctx, bb);
7026 g_hash_table_destroy (ctx->exc_meta);
7028 mono_memory_barrier ();
7030 /* Add incoming phi values */
7031 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
7032 GSList *l, *ins_list;
7034 ins_list = bblocks [bb->block_num].phi_nodes;
7036 for (l = ins_list; l; l = l->next) {
7037 PhiNode *node = (PhiNode*)l->data;
7038 MonoInst *phi = node->phi;
7039 int sreg1 = node->sreg;
7040 LLVMBasicBlockRef in_bb;
7045 in_bb = get_end_bb (ctx, node->in_bb);
7047 if (ctx->unreachable [node->in_bb->block_num])
7050 if (!values [sreg1]) {
7051 /* Can happen with values in EH clauses */
7052 set_failure (ctx, "incoming phi sreg1");
7056 if (phi->opcode == OP_VPHI) {
7057 g_assert (LLVMTypeOf (ctx->addresses [sreg1]) == LLVMTypeOf (values [phi->dreg]));
7058 LLVMAddIncoming (values [phi->dreg], &ctx->addresses [sreg1], &in_bb, 1);
7060 if (LLVMTypeOf (values [sreg1]) != LLVMTypeOf (values [phi->dreg])) {
7061 set_failure (ctx, "incoming phi arg type mismatch");
7064 g_assert (LLVMTypeOf (values [sreg1]) == LLVMTypeOf (values [phi->dreg]));
7065 LLVMAddIncoming (values [phi->dreg], &values [sreg1], &in_bb, 1);
7070 /* Nullify empty phi instructions */
7071 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
7072 GSList *l, *ins_list;
7074 ins_list = bblocks [bb->block_num].phi_nodes;
7076 for (l = ins_list; l; l = l->next) {
7077 PhiNode *node = (PhiNode*)l->data;
7078 MonoInst *phi = node->phi;
7079 LLVMValueRef phi_ins = values [phi->dreg];
7082 /* Already removed */
7085 if (LLVMCountIncoming (phi_ins) == 0) {
7086 mono_llvm_replace_uses_of (phi_ins, LLVMConstNull (LLVMTypeOf (phi_ins)));
7087 LLVMInstructionEraseFromParent (phi_ins);
7088 values [phi->dreg] = NULL;
7093 /* Create the SWITCH statements for ENDFINALLY instructions */
7094 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
7095 BBInfo *info = &bblocks [bb->block_num];
7097 for (l = info->endfinally_switch_ins_list; l; l = l->next) {
7098 LLVMValueRef switch_ins = (LLVMValueRef)l->data;
7099 GSList *bb_list = info->call_handler_return_bbs;
7101 for (i = 0; i < g_slist_length (bb_list); ++i)
7102 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), i + 1, FALSE), (LLVMBasicBlockRef)(g_slist_nth (bb_list, i)->data));
7106 /* Initialize the method if needed */
7107 if (cfg->compile_aot && ctx->llvm_only) {
7108 // FIXME: Add more shared got entries
7109 ctx->builder = create_builder (ctx);
7110 LLVMPositionBuilderAtEnd (ctx->builder, ctx->init_bb);
7112 ctx->module->max_method_idx = MAX (ctx->module->max_method_idx, cfg->method_index);
7114 // FIXME: beforefieldinit
7115 if (ctx->has_got_access || mono_class_get_cctor (cfg->method->klass)) {
7117 * linkonce methods shouldn't have initialization,
7118 * because they might belong to assemblies which
7119 * haven't been loaded yet.
7121 g_assert (!ctx->is_linkonce);
7122 emit_init_method (ctx);
7124 LLVMBuildBr (ctx->builder, ctx->inited_bb);
7128 if (cfg->llvm_only) {
7129 GHashTableIter iter;
7131 GSList *callers, *l, *l2;
7134 * Add the contents of ctx->method_to_callers to module->method_to_callers.
7135 * We can't do this earlier, as it contains llvm instructions which can be
7136 * freed if compilation fails.
7137 * FIXME: Get rid of this when all methods can be llvm compiled.
7139 g_hash_table_iter_init (&iter, ctx->method_to_callers);
7140 while (g_hash_table_iter_next (&iter, (void**)&method, (void**)&callers)) {
7141 for (l = callers; l; l = l->next) {
7142 l2 = (GSList*)g_hash_table_lookup (ctx->module->method_to_callers, method);
7143 l2 = g_slist_prepend (l2, l->data);
7144 g_hash_table_insert (ctx->module->method_to_callers, method, l2);
7149 if (cfg->verbose_level > 1)
7150 mono_llvm_dump_value (method);
7152 if (cfg->compile_aot && !cfg->llvm_only)
7153 mark_as_used (ctx->module, method);
7155 if (cfg->compile_aot && !cfg->llvm_only) {
7156 LLVMValueRef md_args [16];
7157 LLVMValueRef md_node;
7160 method_index = mono_aot_get_method_index (cfg->orig_method);
7161 md_args [0] = LLVMMDString (ctx->method_name, strlen (ctx->method_name));
7162 md_args [1] = LLVMConstInt (LLVMInt32Type (), method_index, FALSE);
7163 md_node = LLVMMDNode (md_args, 2);
7164 LLVMAddNamedMetadataOperand (lmodule, "mono.function_indexes", md_node);
7165 //LLVMSetMetadata (method, md_kind, LLVMMDNode (&md_arg, 1));
7168 if (cfg->compile_aot) {
7169 /* Don't generate native code, keep the LLVM IR */
7170 if (cfg->verbose_level)
7171 printf ("%s emitted as %s\n", mono_method_full_name (cfg->method, TRUE), ctx->method_name);
7173 #if LLVM_API_VERSION < 100
7174 /* VerifyFunction can't handle some of the debug info created by DIBuilder in llvm 3.9 */
7175 int err = LLVMVerifyFunction(ctx->lmethod, LLVMPrintMessageAction);
7176 g_assert (err == 0);
7179 //LLVMVerifyFunction(method, 0);
7180 #if LLVM_API_VERSION > 100
7181 MonoDomain *domain = mono_domain_get ();
7182 MonoJitDomainInfo *domain_info;
7183 int nvars = g_hash_table_size (ctx->jit_callees);
7184 LLVMValueRef *callee_vars = g_new0 (LLVMValueRef, nvars);
7185 gpointer *callee_addrs = g_new0 (gpointer, nvars);
7186 GHashTableIter iter;
7192 * Compute the addresses of the LLVM globals pointing to the
7193 * methods called by the current method. Pass it to the trampoline
7194 * code so it can update them after their corresponding method was
7197 g_hash_table_iter_init (&iter, ctx->jit_callees);
7199 while (g_hash_table_iter_next (&iter, NULL, (void**)&var))
7200 callee_vars [i ++] = var;
7202 cfg->native_code = mono_llvm_compile_method (ctx->module->mono_ee, ctx->lmethod, nvars, callee_vars, callee_addrs, &eh_frame);
7204 decode_llvm_eh_info (ctx, eh_frame);
7206 mono_domain_lock (domain);
7207 domain_info = domain_jit_info (domain);
7208 if (!domain_info->llvm_jit_callees)
7209 domain_info->llvm_jit_callees = g_hash_table_new (NULL, NULL);
7210 g_hash_table_iter_init (&iter, ctx->jit_callees);
7212 while (g_hash_table_iter_next (&iter, (void**)&callee, (void**)&var)) {
7213 GSList *addrs = g_hash_table_lookup (domain_info->llvm_jit_callees, callee);
7214 addrs = g_slist_prepend (addrs, callee_addrs [i]);
7215 g_hash_table_insert (domain_info->llvm_jit_callees, callee, addrs);
7218 mono_domain_unlock (domain);
7220 mono_llvm_optimize_method (ctx->module->mono_ee, ctx->lmethod);
7222 if (cfg->verbose_level > 1)
7223 mono_llvm_dump_value (ctx->lmethod);
7225 cfg->native_code = (unsigned char*)LLVMGetPointerToGlobal (ctx->module->ee, ctx->lmethod);
7227 /* Set by emit_cb */
7228 g_assert (cfg->code_len);
7232 if (ctx->module->method_to_lmethod)
7233 g_hash_table_insert (ctx->module->method_to_lmethod, cfg->method, ctx->lmethod);
7234 if (ctx->module->idx_to_lmethod)
7235 g_hash_table_insert (ctx->module->idx_to_lmethod, GINT_TO_POINTER (cfg->method_index), ctx->lmethod);
7237 if (ctx->llvm_only && cfg->orig_method->klass->valuetype && !(cfg->orig_method->flags & METHOD_ATTRIBUTE_STATIC))
7238 emit_unbox_tramp (ctx, ctx->method_name, ctx->method_type, ctx->lmethod, cfg->method_index);
7242 * mono_llvm_create_vars:
7244 * Same as mono_arch_create_vars () for LLVM.
7247 mono_llvm_create_vars (MonoCompile *cfg)
7249 MonoMethodSignature *sig;
7251 sig = mono_method_signature (cfg->method);
7252 if (cfg->gsharedvt && cfg->llvm_only) {
7253 if (mini_is_gsharedvt_variable_signature (sig) && sig->ret->type != MONO_TYPE_VOID) {
7254 cfg->vret_addr = mono_compile_create_var (cfg, &mono_get_intptr_class ()->byval_arg, OP_ARG);
7255 if (G_UNLIKELY (cfg->verbose_level > 1)) {
7256 printf ("vret_addr = ");
7257 mono_print_ins (cfg->vret_addr);
7261 mono_arch_create_vars (cfg);
7266 * mono_llvm_emit_call:
7268 * Same as mono_arch_emit_call () for LLVM.
7271 mono_llvm_emit_call (MonoCompile *cfg, MonoCallInst *call)
7274 MonoMethodSignature *sig;
7275 int i, n, stack_size;
7280 sig = call->signature;
7281 n = sig->param_count + sig->hasthis;
7283 call->cinfo = get_llvm_call_info (cfg, sig);
7285 if (cfg->disable_llvm)
7288 if (sig->call_convention == MONO_CALL_VARARG) {
7289 cfg->exception_message = g_strdup ("varargs");
7290 cfg->disable_llvm = TRUE;
7293 for (i = 0; i < n; ++i) {
7296 ainfo = call->cinfo->args + i;
7298 in = call->args [i];
7300 /* Simply remember the arguments */
7301 switch (ainfo->storage) {
7302 case LLVMArgNormal: {
7303 MonoType *t = (sig->hasthis && i == 0) ? &mono_get_intptr_class ()->byval_arg : ainfo->type;
7306 opcode = mono_type_to_regmove (cfg, t);
7307 if (opcode == OP_FMOVE) {
7308 MONO_INST_NEW (cfg, ins, OP_FMOVE);
7309 ins->dreg = mono_alloc_freg (cfg);
7310 } else if (opcode == OP_LMOVE) {
7311 MONO_INST_NEW (cfg, ins, OP_LMOVE);
7312 ins->dreg = mono_alloc_lreg (cfg);
7313 } else if (opcode == OP_RMOVE) {
7314 MONO_INST_NEW (cfg, ins, OP_RMOVE);
7315 ins->dreg = mono_alloc_freg (cfg);
7317 MONO_INST_NEW (cfg, ins, OP_MOVE);
7318 ins->dreg = mono_alloc_ireg (cfg);
7320 ins->sreg1 = in->dreg;
7323 case LLVMArgVtypeByVal:
7324 case LLVMArgVtypeByRef:
7325 case LLVMArgVtypeInReg:
7326 case LLVMArgVtypeAsScalar:
7327 case LLVMArgAsIArgs:
7328 case LLVMArgAsFpArgs:
7329 case LLVMArgGsharedvtVariable:
7330 case LLVMArgGsharedvtFixed:
7331 case LLVMArgGsharedvtFixedVtype:
7332 MONO_INST_NEW (cfg, ins, OP_LLVM_OUTARG_VT);
7333 ins->dreg = mono_alloc_ireg (cfg);
7334 ins->sreg1 = in->dreg;
7335 ins->inst_p0 = mono_mempool_alloc0 (cfg->mempool, sizeof (LLVMArgInfo));
7336 memcpy (ins->inst_p0, ainfo, sizeof (LLVMArgInfo));
7337 ins->inst_vtype = ainfo->type;
7338 ins->klass = mono_class_from_mono_type (ainfo->type);
7341 cfg->exception_message = g_strdup ("ainfo->storage");
7342 cfg->disable_llvm = TRUE;
7346 if (!cfg->disable_llvm) {
7347 MONO_ADD_INS (cfg->cbb, ins);
7348 mono_call_inst_add_outarg_reg (cfg, call, ins->dreg, 0, FALSE);
7353 static unsigned char*
7354 alloc_cb (LLVMValueRef function, int size)
7358 cfg = (MonoCompile*)mono_native_tls_get_value (current_cfg_tls_id);
7362 return (unsigned char*)mono_domain_code_reserve (cfg->domain, size);
7364 return (unsigned char*)mono_domain_code_reserve (mono_domain_get (), size);
7369 emitted_cb (LLVMValueRef function, void *start, void *end)
7373 cfg = (MonoCompile*)mono_native_tls_get_value (current_cfg_tls_id);
7375 cfg->code_len = (guint8*)end - (guint8*)start;
7379 exception_cb (void *data)
7382 MonoJitExceptionInfo *ei;
7383 guint32 ei_len, i, j, nested_len, nindex;
7384 gpointer *type_info;
7385 int this_reg, this_offset;
7387 cfg = (MonoCompile*)mono_native_tls_get_value (current_cfg_tls_id);
7391 * data points to a DWARF FDE structure, convert it to our unwind format and
7393 * An alternative would be to save it directly, and modify our unwinder to work
7396 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);
7397 if (cfg->verbose_level > 1)
7398 mono_print_unwind_info (cfg->encoded_unwind_ops, cfg->encoded_unwind_ops_len);
7400 /* Count nested clauses */
7402 for (i = 0; i < ei_len; ++i) {
7403 gint32 cindex1 = *(gint32*)type_info [i];
7404 MonoExceptionClause *clause1 = &cfg->header->clauses [cindex1];
7406 for (j = 0; j < cfg->header->num_clauses; ++j) {
7408 MonoExceptionClause *clause2 = &cfg->header->clauses [cindex2];
7410 if (cindex1 != cindex2 && clause1->try_offset >= clause2->try_offset && clause1->handler_offset <= clause2->handler_offset) {
7416 cfg->llvm_ex_info = (MonoJitExceptionInfo*)mono_mempool_alloc0 (cfg->mempool, (ei_len + nested_len) * sizeof (MonoJitExceptionInfo));
7417 cfg->llvm_ex_info_len = ei_len + nested_len;
7418 memcpy (cfg->llvm_ex_info, ei, ei_len * sizeof (MonoJitExceptionInfo));
7419 /* Fill the rest of the information from the type info */
7420 for (i = 0; i < ei_len; ++i) {
7421 gint32 clause_index = *(gint32*)type_info [i];
7422 MonoExceptionClause *clause = &cfg->header->clauses [clause_index];
7424 cfg->llvm_ex_info [i].flags = clause->flags;
7425 cfg->llvm_ex_info [i].data.catch_class = clause->data.catch_class;
7426 cfg->llvm_ex_info [i].clause_index = clause_index;
7430 * For nested clauses, the LLVM produced exception info associates the try interval with
7431 * the innermost handler, while mono expects it to be associated with all nesting clauses.
7432 * So add new clauses which use the IL info (catch class etc.) from the nesting clause,
7433 * and everything else from the nested clause.
7436 for (i = 0; i < ei_len; ++i) {
7437 gint32 cindex1 = *(gint32*)type_info [i];
7438 MonoExceptionClause *clause1 = &cfg->header->clauses [cindex1];
7440 for (j = 0; j < cfg->header->num_clauses; ++j) {
7442 MonoExceptionClause *clause2 = &cfg->header->clauses [cindex2];
7443 MonoJitExceptionInfo *nesting_ei, *nested_ei;
7445 if (cindex1 != cindex2 && clause1->try_offset >= clause2->try_offset && clause1->handler_offset <= clause2->handler_offset) {
7446 /* clause1 is the nested clause */
7447 nested_ei = &cfg->llvm_ex_info [i];
7448 nesting_ei = &cfg->llvm_ex_info [nindex];
7451 memcpy (nesting_ei, nested_ei, sizeof (MonoJitExceptionInfo));
7453 nesting_ei->flags = clause2->flags;
7454 nesting_ei->data.catch_class = clause2->data.catch_class;
7455 nesting_ei->clause_index = cindex2;
7459 g_assert (nindex == ei_len + nested_len);
7460 cfg->llvm_this_reg = this_reg;
7461 cfg->llvm_this_offset = this_offset;
7463 /* type_info [i] is cfg mempool allocated, no need to free it */
7469 #if LLVM_API_VERSION > 100
7471 * decode_llvm_eh_info:
7473 * Decode the EH table emitted by llvm in jit mode, and store
7474 * the result into cfg.
7477 decode_llvm_eh_info (EmitContext *ctx, gpointer eh_frame)
7479 MonoCompile *cfg = ctx->cfg;
7482 MonoLLVMFDEInfo info;
7483 MonoJitExceptionInfo *ei;
7484 guint8 *p = eh_frame;
7485 int version, fde_count, fde_offset;
7486 guint32 ei_len, i, nested_len;
7487 gpointer *type_info;
7491 * Decode the one element EH table emitted by the MonoException class
7495 /* Similar to decode_llvm_mono_eh_frame () in aot-runtime.c */
7498 g_assert (version == 3);
7501 p = (guint8 *)ALIGN_PTR_TO (p, 4);
7503 fde_count = *(guint32*)p;
7507 g_assert (fde_count == 1);
7509 /* The only table entry */
7510 fde_offset = table [1];
7513 cfg->code_len = table [0];
7514 fde_len = table [1] - fde_offset;
7517 fde = (guint8*)eh_frame + fde_offset;
7518 cie = (guint8*)table;
7520 mono_unwind_decode_llvm_mono_fde (fde, fde_len, cie, cfg->native_code, &info);
7522 cfg->encoded_unwind_ops = info.unw_info;
7523 cfg->encoded_unwind_ops_len = info.unw_info_len;
7524 if (cfg->verbose_level > 1)
7525 mono_print_unwind_info (cfg->encoded_unwind_ops, cfg->encoded_unwind_ops_len);
7526 if (info.this_reg != -1) {
7527 cfg->llvm_this_reg = info.this_reg;
7528 cfg->llvm_this_offset = info.this_offset;
7532 ei_len = info.ex_info_len;
7533 type_info = info.type_info;
7535 // Nested clauses are currently disabled
7538 cfg->llvm_ex_info = (MonoJitExceptionInfo*)mono_mempool_alloc0 (cfg->mempool, (ei_len + nested_len) * sizeof (MonoJitExceptionInfo));
7539 cfg->llvm_ex_info_len = ei_len + nested_len;
7540 memcpy (cfg->llvm_ex_info, ei, ei_len * sizeof (MonoJitExceptionInfo));
7541 /* Fill the rest of the information from the type info */
7542 for (i = 0; i < ei_len; ++i) {
7543 gint32 clause_index = *(gint32*)type_info [i];
7544 MonoExceptionClause *clause = &cfg->header->clauses [clause_index];
7546 cfg->llvm_ex_info [i].flags = clause->flags;
7547 cfg->llvm_ex_info [i].data.catch_class = clause->data.catch_class;
7548 cfg->llvm_ex_info [i].clause_index = clause_index;
7554 dlsym_cb (const char *name, void **symbol)
7560 if (!strcmp (name, "__bzero")) {
7561 *symbol = (void*)bzero;
7563 current = mono_dl_open (NULL, 0, NULL);
7566 err = mono_dl_symbol (current, name, symbol);
7568 mono_dl_close (current);
7570 #ifdef MONO_ARCH_HAVE_CREATE_LLVM_NATIVE_THUNK
7571 *symbol = (char*)mono_arch_create_llvm_native_thunk (mono_domain_get (), (guint8*)(*symbol));
7577 AddFunc (LLVMModuleRef module, const char *name, LLVMTypeRef ret_type, LLVMTypeRef *param_types, int nparams)
7579 LLVMAddFunction (module, name, LLVMFunctionType (ret_type, param_types, nparams, FALSE));
7583 AddFunc2 (LLVMModuleRef module, const char *name, LLVMTypeRef ret_type, LLVMTypeRef param_type1, LLVMTypeRef param_type2)
7585 LLVMTypeRef param_types [4];
7587 param_types [0] = param_type1;
7588 param_types [1] = param_type2;
7590 AddFunc (module, name, ret_type, param_types, 2);
7596 INTRINS_SADD_OVF_I32,
7597 INTRINS_UADD_OVF_I32,
7598 INTRINS_SSUB_OVF_I32,
7599 INTRINS_USUB_OVF_I32,
7600 INTRINS_SMUL_OVF_I32,
7601 INTRINS_UMUL_OVF_I32,
7602 INTRINS_SADD_OVF_I64,
7603 INTRINS_UADD_OVF_I64,
7604 INTRINS_SSUB_OVF_I64,
7605 INTRINS_USUB_OVF_I64,
7606 INTRINS_SMUL_OVF_I64,
7607 INTRINS_UMUL_OVF_I64,
7614 #if defined(TARGET_AMD64) || defined(TARGET_X86)
7615 INTRINS_SSE_PMOVMSKB,
7616 INTRINS_SSE_PSRLI_W,
7617 INTRINS_SSE_PSRAI_W,
7618 INTRINS_SSE_PSLLI_W,
7619 INTRINS_SSE_PSRLI_D,
7620 INTRINS_SSE_PSRAI_D,
7621 INTRINS_SSE_PSLLI_D,
7622 INTRINS_SSE_PSRLI_Q,
7623 INTRINS_SSE_PSLLI_Q,
7624 INTRINS_SSE_SQRT_PD,
7625 INTRINS_SSE_SQRT_PS,
7626 INTRINS_SSE_RSQRT_PS,
7628 INTRINS_SSE_CVTTPD2DQ,
7629 INTRINS_SSE_CVTTPS2DQ,
7630 INTRINS_SSE_CVTDQ2PD,
7631 INTRINS_SSE_CVTDQ2PS,
7632 INTRINS_SSE_CVTPD2DQ,
7633 INTRINS_SSE_CVTPS2DQ,
7634 INTRINS_SSE_CVTPD2PS,
7635 INTRINS_SSE_CVTPS2PD,
7638 INTRINS_SSE_PACKSSWB,
7639 INTRINS_SSE_PACKUSWB,
7640 INTRINS_SSE_PACKSSDW,
7641 INTRINS_SSE_PACKUSDW,
7646 INTRINS_SSE_ADDSUBPS,
7651 INTRINS_SSE_ADDSUBPD,
7659 INTRINS_SSE_PADDUSW,
7660 INTRINS_SSE_PSUBUSW,
7668 INTRINS_SSE_PADDUSB,
7669 INTRINS_SSE_PSUBUSB,
7681 static IntrinsicDesc intrinsics[] = {
7682 {INTRINS_MEMSET, "llvm.memset.p0i8.i32"},
7683 {INTRINS_MEMCPY, "llvm.memcpy.p0i8.p0i8.i32"},
7684 {INTRINS_SADD_OVF_I32, "llvm.sadd.with.overflow.i32"},
7685 {INTRINS_UADD_OVF_I32, "llvm.uadd.with.overflow.i32"},
7686 {INTRINS_SSUB_OVF_I32, "llvm.ssub.with.overflow.i32"},
7687 {INTRINS_USUB_OVF_I32, "llvm.usub.with.overflow.i32"},
7688 {INTRINS_SMUL_OVF_I32, "llvm.smul.with.overflow.i32"},
7689 {INTRINS_UMUL_OVF_I32, "llvm.umul.with.overflow.i32"},
7690 {INTRINS_SADD_OVF_I64, "llvm.sadd.with.overflow.i64"},
7691 {INTRINS_UADD_OVF_I64, "llvm.uadd.with.overflow.i64"},
7692 {INTRINS_SSUB_OVF_I64, "llvm.ssub.with.overflow.i64"},
7693 {INTRINS_USUB_OVF_I64, "llvm.usub.with.overflow.i64"},
7694 {INTRINS_SMUL_OVF_I64, "llvm.smul.with.overflow.i64"},
7695 {INTRINS_UMUL_OVF_I64, "llvm.umul.with.overflow.i64"},
7696 {INTRINS_SIN, "llvm.sin.f64"},
7697 {INTRINS_COS, "llvm.cos.f64"},
7698 {INTRINS_SQRT, "llvm.sqrt.f64"},
7699 /* This isn't an intrinsic, instead llvm seems to special case it by name */
7700 {INTRINS_FABS, "fabs"},
7701 {INTRINS_EXPECT_I8, "llvm.expect.i8"},
7702 {INTRINS_EXPECT_I1, "llvm.expect.i1"},
7703 #if defined(TARGET_AMD64) || defined(TARGET_X86)
7704 {INTRINS_SSE_PMOVMSKB, "llvm.x86.sse2.pmovmskb.128"},
7705 {INTRINS_SSE_PSRLI_W, "llvm.x86.sse2.psrli.w"},
7706 {INTRINS_SSE_PSRAI_W, "llvm.x86.sse2.psrai.w"},
7707 {INTRINS_SSE_PSLLI_W, "llvm.x86.sse2.pslli.w"},
7708 {INTRINS_SSE_PSRLI_D, "llvm.x86.sse2.psrli.d"},
7709 {INTRINS_SSE_PSRAI_D, "llvm.x86.sse2.psrai.d"},
7710 {INTRINS_SSE_PSLLI_D, "llvm.x86.sse2.pslli.d"},
7711 {INTRINS_SSE_PSRLI_Q, "llvm.x86.sse2.psrli.q"},
7712 {INTRINS_SSE_PSLLI_Q, "llvm.x86.sse2.pslli.q"},
7713 {INTRINS_SSE_SQRT_PD, "llvm.x86.sse2.sqrt.pd"},
7714 {INTRINS_SSE_SQRT_PS, "llvm.x86.sse.sqrt.ps"},
7715 {INTRINS_SSE_RSQRT_PS, "llvm.x86.sse.rsqrt.ps"},
7716 {INTRINS_SSE_RCP_PS, "llvm.x86.sse.rcp.ps"},
7717 {INTRINS_SSE_CVTTPD2DQ, "llvm.x86.sse2.cvttpd2dq"},
7718 {INTRINS_SSE_CVTTPS2DQ, "llvm.x86.sse2.cvttps2dq"},
7719 {INTRINS_SSE_CVTDQ2PD, "llvm.x86.sse2.cvtdq2pd"},
7720 {INTRINS_SSE_CVTDQ2PS, "llvm.x86.sse2.cvtdq2ps"},
7721 {INTRINS_SSE_CVTPD2DQ, "llvm.x86.sse2.cvtpd2dq"},
7722 {INTRINS_SSE_CVTPS2DQ, "llvm.x86.sse2.cvtps2dq"},
7723 {INTRINS_SSE_CVTPD2PS, "llvm.x86.sse2.cvtpd2ps"},
7724 {INTRINS_SSE_CVTPS2PD, "llvm.x86.sse2.cvtps2pd"},
7725 {INTRINS_SSE_CMPPD, "llvm.x86.sse2.cmp.pd"},
7726 {INTRINS_SSE_CMPPS, "llvm.x86.sse.cmp.ps"},
7727 {INTRINS_SSE_PACKSSWB, "llvm.x86.sse2.packsswb.128"},
7728 {INTRINS_SSE_PACKUSWB, "llvm.x86.sse2.packuswb.128"},
7729 {INTRINS_SSE_PACKSSDW, "llvm.x86.sse2.packssdw.128"},
7730 {INTRINS_SSE_PACKUSDW, "llvm.x86.sse41.packusdw"},
7731 {INTRINS_SSE_MINPS, "llvm.x86.sse.min.ps"},
7732 {INTRINS_SSE_MAXPS, "llvm.x86.sse.max.ps"},
7733 {INTRINS_SSE_HADDPS, "llvm.x86.sse3.hadd.ps"},
7734 {INTRINS_SSE_HSUBPS, "llvm.x86.sse3.hsub.ps"},
7735 {INTRINS_SSE_ADDSUBPS, "llvm.x86.sse3.addsub.ps"},
7736 {INTRINS_SSE_MINPD, "llvm.x86.sse2.min.pd"},
7737 {INTRINS_SSE_MAXPD, "llvm.x86.sse2.max.pd"},
7738 {INTRINS_SSE_HADDPD, "llvm.x86.sse3.hadd.pd"},
7739 {INTRINS_SSE_HSUBPD, "llvm.x86.sse3.hsub.pd"},
7740 {INTRINS_SSE_ADDSUBPD, "llvm.x86.sse3.addsub.pd"},
7741 {INTRINS_SSE_PMINUD, "llvm.x86.sse41.pminud"},
7742 {INTRINS_SSE_PMAXUD, "llvm.x86.sse41.pmaxud"},
7743 {INTRINS_SSE_PMINUW, "llvm.x86.sse41.pminuw"},
7744 {INTRINS_SSE_PMINSW, "llvm.x86.sse2.pmins.w"},
7745 {INTRINS_SSE_PMAXUW, "llvm.x86.sse41.pmaxuw"},
7746 {INTRINS_SSE_PADDSW, "llvm.x86.sse2.padds.w"},
7747 {INTRINS_SSE_PSUBSW, "llvm.x86.sse2.psubs.w"},
7748 {INTRINS_SSE_PADDUSW, "llvm.x86.sse2.paddus.w"},
7749 {INTRINS_SSE_PSUBUSW, "llvm.x86.sse2.psubus.w"},
7750 {INTRINS_SSE_PAVGW, "llvm.x86.sse2.pavg.w"},
7751 {INTRINS_SSE_PMULHW, "llvm.x86.sse2.pmulh.w"},
7752 {INTRINS_SSE_PMULHU, "llvm.x86.sse2.pmulhu.w"},
7753 {INTRINS_SSE_PMINUB, "llvm.x86.sse2.pminu.b"},
7754 {INTRINS_SSE_PMAXUB, "llvm.x86.sse2.pmaxu.b"},
7755 {INTRINS_SE_PADDSB, "llvm.x86.sse2.padds.b"},
7756 {INTRINS_SSE_PSUBSB, "llvm.x86.sse2.psubs.b"},
7757 {INTRINS_SSE_PADDUSB, "llvm.x86.sse2.paddus.b"},
7758 {INTRINS_SSE_PSUBUSB, "llvm.x86.sse2.psubus.b"},
7759 {INTRINS_SSE_PAVGB, "llvm.x86.sse2.pavg.b"},
7760 {INTRINS_SSE_PAUSE, "llvm.x86.sse2.pause"}
7765 add_sse_binary (LLVMModuleRef module, const char *name, int type)
7767 LLVMTypeRef ret_type = type_to_simd_type (type);
7768 AddFunc2 (module, name, ret_type, ret_type, ret_type);
7772 add_intrinsic (LLVMModuleRef module, int id)
7775 #if defined(TARGET_AMD64) || defined(TARGET_X86)
7776 LLVMTypeRef ret_type, arg_types [16];
7779 name = g_hash_table_lookup (intrins_id_to_name, GINT_TO_POINTER (id));
7783 case INTRINS_MEMSET: {
7784 LLVMTypeRef params [] = { LLVMPointerType (LLVMInt8Type (), 0), LLVMInt8Type (), LLVMInt32Type (), LLVMInt32Type (), LLVMInt1Type () };
7786 AddFunc (module, name, LLVMVoidType (), params, 5);
7789 case INTRINS_MEMCPY: {
7790 LLVMTypeRef params [] = { LLVMPointerType (LLVMInt8Type (), 0), LLVMPointerType (LLVMInt8Type (), 0), LLVMInt32Type (), LLVMInt32Type (), LLVMInt1Type () };
7792 AddFunc (module, name, LLVMVoidType (), params, 5);
7795 case INTRINS_SADD_OVF_I32:
7796 case INTRINS_UADD_OVF_I32:
7797 case INTRINS_SSUB_OVF_I32:
7798 case INTRINS_USUB_OVF_I32:
7799 case INTRINS_SMUL_OVF_I32:
7800 case INTRINS_UMUL_OVF_I32: {
7801 LLVMTypeRef ovf_res_i32 [] = { LLVMInt32Type (), LLVMInt1Type () };
7802 LLVMTypeRef params [] = { LLVMInt32Type (), LLVMInt32Type () };
7803 LLVMTypeRef ret_type = LLVMStructType (ovf_res_i32, 2, FALSE);
7805 AddFunc (module, name, ret_type, params, 2);
7808 case INTRINS_SADD_OVF_I64:
7809 case INTRINS_UADD_OVF_I64:
7810 case INTRINS_SSUB_OVF_I64:
7811 case INTRINS_USUB_OVF_I64:
7812 case INTRINS_SMUL_OVF_I64:
7813 case INTRINS_UMUL_OVF_I64: {
7814 LLVMTypeRef ovf_res_i64 [] = { LLVMInt64Type (), LLVMInt1Type () };
7815 LLVMTypeRef params [] = { LLVMInt64Type (), LLVMInt64Type () };
7816 LLVMTypeRef ret_type = LLVMStructType (ovf_res_i64, 2, FALSE);
7818 AddFunc (module, name, ret_type, params, 2);
7824 case INTRINS_FABS: {
7825 LLVMTypeRef params [] = { LLVMDoubleType () };
7827 AddFunc (module, name, LLVMDoubleType (), params, 1);
7830 case INTRINS_EXPECT_I8:
7831 AddFunc2 (module, name, LLVMInt8Type (), LLVMInt8Type (), LLVMInt8Type ());
7833 case INTRINS_EXPECT_I1:
7834 AddFunc2 (module, name, LLVMInt1Type (), LLVMInt1Type (), LLVMInt1Type ());
7836 #if defined(TARGET_AMD64) || defined(TARGET_X86)
7837 case INTRINS_SSE_PMOVMSKB:
7839 ret_type = LLVMInt32Type ();
7840 arg_types [0] = type_to_simd_type (MONO_TYPE_I1);
7841 AddFunc (module, name, ret_type, arg_types, 1);
7843 case INTRINS_SSE_PSRLI_W:
7844 case INTRINS_SSE_PSRAI_W:
7845 case INTRINS_SSE_PSLLI_W:
7847 ret_type = type_to_simd_type (MONO_TYPE_I2);
7848 arg_types [0] = ret_type;
7849 arg_types [1] = LLVMInt32Type ();
7850 AddFunc (module, name, ret_type, arg_types, 2);
7852 case INTRINS_SSE_PSRLI_D:
7853 case INTRINS_SSE_PSRAI_D:
7854 case INTRINS_SSE_PSLLI_D:
7855 ret_type = type_to_simd_type (MONO_TYPE_I4);
7856 arg_types [0] = ret_type;
7857 arg_types [1] = LLVMInt32Type ();
7858 AddFunc (module, name, ret_type, arg_types, 2);
7860 case INTRINS_SSE_PSRLI_Q:
7861 case INTRINS_SSE_PSLLI_Q:
7862 ret_type = type_to_simd_type (MONO_TYPE_I8);
7863 arg_types [0] = ret_type;
7864 arg_types [1] = LLVMInt32Type ();
7865 AddFunc (module, name, ret_type, arg_types, 2);
7867 case INTRINS_SSE_SQRT_PD:
7869 ret_type = type_to_simd_type (MONO_TYPE_R8);
7870 arg_types [0] = ret_type;
7871 AddFunc (module, name, ret_type, arg_types, 1);
7873 case INTRINS_SSE_SQRT_PS:
7874 ret_type = type_to_simd_type (MONO_TYPE_R4);
7875 arg_types [0] = ret_type;
7876 AddFunc (module, name, ret_type, arg_types, 1);
7878 case INTRINS_SSE_RSQRT_PS:
7879 ret_type = type_to_simd_type (MONO_TYPE_R4);
7880 arg_types [0] = ret_type;
7881 AddFunc (module, name, ret_type, arg_types, 1);
7883 case INTRINS_SSE_RCP_PS:
7884 ret_type = type_to_simd_type (MONO_TYPE_R4);
7885 arg_types [0] = ret_type;
7886 AddFunc (module, name, ret_type, arg_types, 1);
7888 case INTRINS_SSE_CVTTPD2DQ:
7889 ret_type = type_to_simd_type (MONO_TYPE_I4);
7890 arg_types [0] = type_to_simd_type (MONO_TYPE_R8);
7891 AddFunc (module, name, ret_type, arg_types, 1);
7893 case INTRINS_SSE_CVTTPS2DQ:
7894 ret_type = type_to_simd_type (MONO_TYPE_I4);
7895 arg_types [0] = type_to_simd_type (MONO_TYPE_R4);
7896 AddFunc (module, name, ret_type, arg_types, 1);
7898 case INTRINS_SSE_CVTDQ2PD:
7899 /* Conversion ops */
7900 ret_type = type_to_simd_type (MONO_TYPE_R8);
7901 arg_types [0] = type_to_simd_type (MONO_TYPE_I4);
7902 AddFunc (module, name, ret_type, arg_types, 1);
7904 case INTRINS_SSE_CVTDQ2PS:
7905 ret_type = type_to_simd_type (MONO_TYPE_R4);
7906 arg_types [0] = type_to_simd_type (MONO_TYPE_I4);
7907 AddFunc (module, name, ret_type, arg_types, 1);
7909 case INTRINS_SSE_CVTPD2DQ:
7910 ret_type = type_to_simd_type (MONO_TYPE_I4);
7911 arg_types [0] = type_to_simd_type (MONO_TYPE_R8);
7912 AddFunc (module, name, ret_type, arg_types, 1);
7914 case INTRINS_SSE_CVTPS2DQ:
7915 ret_type = type_to_simd_type (MONO_TYPE_I4);
7916 arg_types [0] = type_to_simd_type (MONO_TYPE_R4);
7917 AddFunc (module, name, ret_type, arg_types, 1);
7919 case INTRINS_SSE_CVTPD2PS:
7920 ret_type = type_to_simd_type (MONO_TYPE_R4);
7921 arg_types [0] = type_to_simd_type (MONO_TYPE_R8);
7922 AddFunc (module, name, ret_type, arg_types, 1);
7924 case INTRINS_SSE_CVTPS2PD:
7925 ret_type = type_to_simd_type (MONO_TYPE_R8);
7926 arg_types [0] = type_to_simd_type (MONO_TYPE_R4);
7927 AddFunc (module, name, ret_type, arg_types, 1);
7929 case INTRINS_SSE_CMPPD:
7931 ret_type = type_to_simd_type (MONO_TYPE_R8);
7932 arg_types [0] = ret_type;
7933 arg_types [1] = ret_type;
7934 arg_types [2] = LLVMInt8Type ();
7935 AddFunc (module, name, ret_type, arg_types, 3);
7937 case INTRINS_SSE_CMPPS:
7938 ret_type = type_to_simd_type (MONO_TYPE_R4);
7939 arg_types [0] = ret_type;
7940 arg_types [1] = ret_type;
7941 arg_types [2] = LLVMInt8Type ();
7942 AddFunc (module, name, ret_type, arg_types, 3);
7944 case INTRINS_SSE_PACKSSWB:
7945 case INTRINS_SSE_PACKUSWB:
7946 case INTRINS_SSE_PACKSSDW:
7948 ret_type = type_to_simd_type (MONO_TYPE_I1);
7949 arg_types [0] = type_to_simd_type (MONO_TYPE_I2);
7950 arg_types [1] = type_to_simd_type (MONO_TYPE_I2);
7951 AddFunc (module, name, ret_type, arg_types, 2);
7953 case INTRINS_SSE_PACKUSDW:
7954 ret_type = type_to_simd_type (MONO_TYPE_I2);
7955 arg_types [0] = type_to_simd_type (MONO_TYPE_I4);
7956 arg_types [1] = type_to_simd_type (MONO_TYPE_I4);
7957 AddFunc (module, name, ret_type, arg_types, 2);
7959 /* SSE Binary ops */
7960 case INTRINS_SSE_PMINUD:
7961 case INTRINS_SSE_PMAXUD:
7962 add_sse_binary (module, name, MONO_TYPE_I4);
7964 case INTRINS_SSE_PMINUW:
7965 case INTRINS_SSE_PMINSW:
7966 case INTRINS_SSE_PMAXUW:
7967 case INTRINS_SSE_PADDSW:
7968 case INTRINS_SSE_PSUBSW:
7969 case INTRINS_SSE_PADDUSW:
7970 case INTRINS_SSE_PSUBUSW:
7971 case INTRINS_SSE_PAVGW:
7972 case INTRINS_SSE_PMULHW:
7973 case INTRINS_SSE_PMULHU:
7974 add_sse_binary (module, name, MONO_TYPE_I2);
7976 case INTRINS_SSE_MINPS:
7977 case INTRINS_SSE_MAXPS:
7978 case INTRINS_SSE_HADDPS:
7979 case INTRINS_SSE_HSUBPS:
7980 case INTRINS_SSE_ADDSUBPS:
7981 add_sse_binary (module, name, MONO_TYPE_R4);
7983 case INTRINS_SSE_MINPD:
7984 case INTRINS_SSE_MAXPD:
7985 case INTRINS_SSE_HADDPD:
7986 case INTRINS_SSE_HSUBPD:
7987 case INTRINS_SSE_ADDSUBPD:
7988 add_sse_binary (module, name, MONO_TYPE_R8);
7990 case INTRINS_SSE_PMINUB:
7991 case INTRINS_SSE_PMAXUB:
7992 case INTRINS_SE_PADDSB:
7993 case INTRINS_SSE_PSUBSB:
7994 case INTRINS_SSE_PADDUSB:
7995 case INTRINS_SSE_PSUBUSB:
7996 case INTRINS_SSE_PAVGB:
7997 add_sse_binary (module, name, MONO_TYPE_I1);
7999 case INTRINS_SSE_PAUSE:
8000 AddFunc (module, "llvm.x86.sse2.pause", LLVMVoidType (), NULL, 0);
8004 g_assert_not_reached ();
8010 get_intrinsic (EmitContext *ctx, const char *name)
8012 #if LLVM_API_VERSION > 100
8016 * Every method is emitted into its own module so
8017 * we can add intrinsics on demand.
8019 res = LLVMGetNamedFunction (ctx->lmodule, name);
8023 /* No locking needed */
8024 id = GPOINTER_TO_INT (g_hash_table_lookup (intrins_name_to_id, name));
8027 printf ("%s\n", name);
8028 g_assert (id != -1);
8029 add_intrinsic (ctx->lmodule, id);
8030 res = LLVMGetNamedFunction (ctx->lmodule, name);
8038 res = LLVMGetNamedFunction (ctx->lmodule, name);
8045 add_intrinsics (LLVMModuleRef module)
8049 /* Emit declarations of instrinsics */
8051 * It would be nicer to emit only the intrinsics actually used, but LLVM's Module
8052 * type doesn't seem to do any locking.
8054 for (i = 0; i < INTRINS_NUM; ++i)
8055 add_intrinsic (module, i);
8059 AddFunc (module, "mono_personality", LLVMVoidType (), NULL, 0);
8061 AddFunc (module, "llvm_resume_unwind_trampoline", LLVMVoidType (), NULL, 0);
8064 /* SSE intrinsics */
8065 #if defined(TARGET_X86) || defined(TARGET_AMD64)
8069 /* Load/Store intrinsics */
8071 LLVMTypeRef arg_types [5];
8075 for (i = 1; i <= 8; i *= 2) {
8076 arg_types [0] = LLVMPointerType (LLVMIntType (i * 8), 0);
8077 arg_types [1] = LLVMInt32Type ();
8078 arg_types [2] = LLVMInt1Type ();
8079 arg_types [3] = LLVMInt32Type ();
8080 sprintf (name, "llvm.mono.load.i%d.p0i%d", i * 8, i * 8);
8081 AddFunc (module, name, LLVMIntType (i * 8), arg_types, 4);
8083 arg_types [0] = LLVMIntType (i * 8);
8084 arg_types [1] = LLVMPointerType (LLVMIntType (i * 8), 0);
8085 arg_types [2] = LLVMInt32Type ();
8086 arg_types [3] = LLVMInt1Type ();
8087 arg_types [4] = LLVMInt32Type ();
8088 sprintf (name, "llvm.mono.store.i%d.p0i%d", i * 8, i * 8);
8089 AddFunc (module, name, LLVMVoidType (), arg_types, 5);
8095 add_types (MonoLLVMModule *module)
8097 module->ptr_type = LLVMPointerType (sizeof (gpointer) == 8 ? LLVMInt64Type () : LLVMInt32Type (), 0);
8101 mono_llvm_init (void)
8106 mono_native_tls_alloc (¤t_cfg_tls_id, NULL);
8108 h = g_hash_table_new (NULL, NULL);
8109 for (i = 0; i < INTRINS_NUM; ++i)
8110 g_hash_table_insert (h, GINT_TO_POINTER (intrinsics [i].id), (gpointer)intrinsics [i].name);
8111 intrins_id_to_name = h;
8113 h = g_hash_table_new (g_str_hash, g_str_equal);
8114 for (i = 0; i < INTRINS_NUM; ++i)
8115 g_hash_table_insert (h, (gpointer)intrinsics [i].name, GINT_TO_POINTER (intrinsics [i].id + 1));
8116 intrins_name_to_id = h;
8120 init_jit_module (MonoDomain *domain)
8122 MonoJitDomainInfo *dinfo;
8123 MonoLLVMModule *module;
8126 dinfo = domain_jit_info (domain);
8127 if (dinfo->llvm_module)
8130 mono_loader_lock ();
8132 if (dinfo->llvm_module) {
8133 mono_loader_unlock ();
8137 module = g_new0 (MonoLLVMModule, 1);
8139 name = g_strdup_printf ("mono-%s", domain->friendly_name);
8140 module->lmodule = LLVMModuleCreateWithName (name);
8141 module->context = LLVMGetGlobalContext ();
8143 module->mono_ee = (MonoEERef*)mono_llvm_create_ee (LLVMCreateModuleProviderForExistingModule (module->lmodule), alloc_cb, emitted_cb, exception_cb, dlsym_cb, &module->ee);
8145 add_intrinsics (module->lmodule);
8148 module->llvm_types = g_hash_table_new (NULL, NULL);
8150 #if LLVM_API_VERSION < 100
8151 MonoJitICallInfo *info;
8153 info = mono_find_jit_icall_by_name ("llvm_resume_unwind_trampoline");
8155 LLVMAddGlobalMapping (module->ee, LLVMGetNamedFunction (module->lmodule, "llvm_resume_unwind_trampoline"), (void*)info->func);
8158 mono_memory_barrier ();
8160 dinfo->llvm_module = module;
8162 mono_loader_unlock ();
8166 mono_llvm_cleanup (void)
8168 MonoLLVMModule *module = &aot_module;
8170 if (module->lmodule)
8171 LLVMDisposeModule (module->lmodule);
8173 if (module->context)
8174 LLVMContextDispose (module->context);
8178 mono_llvm_free_domain_info (MonoDomain *domain)
8180 MonoJitDomainInfo *info = domain_jit_info (domain);
8181 MonoLLVMModule *module = (MonoLLVMModule*)info->llvm_module;
8187 if (module->llvm_types)
8188 g_hash_table_destroy (module->llvm_types);
8190 mono_llvm_dispose_ee (module->mono_ee);
8192 if (module->bb_names) {
8193 for (i = 0; i < module->bb_names_len; ++i)
8194 g_free (module->bb_names [i]);
8195 g_free (module->bb_names);
8197 //LLVMDisposeModule (module->module);
8201 info->llvm_module = NULL;
8205 mono_llvm_create_aot_module (MonoAssembly *assembly, const char *global_prefix, gboolean emit_dwarf, gboolean static_link, gboolean llvm_only)
8207 MonoLLVMModule *module = &aot_module;
8209 /* Delete previous module */
8210 if (module->plt_entries)
8211 g_hash_table_destroy (module->plt_entries);
8212 if (module->lmodule)
8213 LLVMDisposeModule (module->lmodule);
8215 memset (module, 0, sizeof (aot_module));
8217 module->lmodule = LLVMModuleCreateWithName ("aot");
8218 module->assembly = assembly;
8219 module->global_prefix = g_strdup (global_prefix);
8220 module->got_symbol = g_strdup_printf ("%s_llvm_got", global_prefix);
8221 module->eh_frame_symbol = g_strdup_printf ("%s_eh_frame", global_prefix);
8222 module->get_method_symbol = g_strdup_printf ("%s_get_method", global_prefix);
8223 module->get_unbox_tramp_symbol = g_strdup_printf ("%s_get_unbox_tramp", global_prefix);
8224 module->external_symbols = TRUE;
8225 module->emit_dwarf = emit_dwarf;
8226 module->static_link = static_link;
8227 module->llvm_only = llvm_only;
8228 /* The first few entries are reserved */
8229 module->max_got_offset = 16;
8230 module->context = LLVMContextCreate ();
8233 /* clang ignores our debug info because it has an invalid version */
8234 module->emit_dwarf = FALSE;
8236 #if LLVM_API_VERSION > 100
8237 module->emit_dwarf = FALSE;
8240 add_intrinsics (module->lmodule);
8243 #if LLVM_API_VERSION > 100
8244 if (module->emit_dwarf) {
8245 char *dir, *build_info, *s, *cu_name;
8247 module->di_builder = mono_llvm_create_di_builder (module->lmodule);
8250 dir = g_strdup (".");
8251 build_info = mono_get_runtime_build_info ();
8252 s = g_strdup_printf ("Mono AOT Compiler %s (LLVM)", build_info);
8253 cu_name = g_path_get_basename (assembly->image->name);
8254 module->cu = mono_llvm_di_create_compile_unit (module->di_builder, cu_name, dir, s);
8256 g_free (build_info);
8263 * We couldn't compute the type of the LLVM global representing the got because
8264 * its size is only known after all the methods have been emitted. So create
8265 * a dummy variable, and replace all uses it with the real got variable when
8266 * its size is known in mono_llvm_emit_aot_module ().
8269 LLVMTypeRef got_type = LLVMArrayType (module->ptr_type, 0);
8271 module->got_var = LLVMAddGlobal (module->lmodule, got_type, "mono_dummy_got");
8272 LLVMSetInitializer (module->got_var, LLVMConstNull (got_type));
8275 /* Add initialization array */
8277 LLVMTypeRef inited_type = LLVMArrayType (LLVMInt8Type (), 0);
8279 module->inited_var = LLVMAddGlobal (aot_module.lmodule, inited_type, "mono_inited_tmp");
8280 LLVMSetInitializer (module->inited_var, LLVMConstNull (inited_type));
8284 emit_init_icall_wrappers (module);
8286 emit_llvm_code_start (module);
8288 /* Add a dummy personality function */
8289 if (!use_debug_personality) {
8290 LLVMValueRef personality = LLVMAddFunction (module->lmodule, default_personality_name, LLVMFunctionType (LLVMInt32Type (), NULL, 0, TRUE));
8291 LLVMSetLinkage (personality, LLVMExternalLinkage);
8292 mark_as_used (module, personality);
8295 /* Add a reference to the c++ exception we throw/catch */
8297 LLVMTypeRef exc = LLVMPointerType (LLVMInt8Type (), 0);
8298 module->sentinel_exception = LLVMAddGlobal (module->lmodule, exc, "_ZTIPi");
8299 LLVMSetLinkage (module->sentinel_exception, LLVMExternalLinkage);
8300 mono_llvm_set_is_constant (module->sentinel_exception);
8303 module->llvm_types = g_hash_table_new (NULL, NULL);
8304 module->plt_entries = g_hash_table_new (g_str_hash, g_str_equal);
8305 module->plt_entries_ji = g_hash_table_new (NULL, NULL);
8306 module->direct_callables = g_hash_table_new (g_str_hash, g_str_equal);
8307 module->method_to_lmethod = g_hash_table_new (NULL, NULL);
8308 module->idx_to_lmethod = g_hash_table_new (NULL, NULL);
8309 module->idx_to_unbox_tramp = g_hash_table_new (NULL, NULL);
8310 module->method_to_callers = g_hash_table_new (NULL, NULL);
8314 llvm_array_from_uints (LLVMTypeRef el_type, guint32 *values, int nvalues)
8317 LLVMValueRef res, *vals;
8319 vals = g_new0 (LLVMValueRef, nvalues);
8320 for (i = 0; i < nvalues; ++i)
8321 vals [i] = LLVMConstInt (LLVMInt32Type (), values [i], FALSE);
8322 res = LLVMConstArray (LLVMInt32Type (), vals, nvalues);
8328 * mono_llvm_emit_aot_file_info:
8330 * Emit the MonoAotFileInfo structure.
8331 * Same as emit_aot_file_info () in aot-compiler.c.
8334 mono_llvm_emit_aot_file_info (MonoAotFileInfo *info, gboolean has_jitted_code)
8336 MonoLLVMModule *module = &aot_module;
8338 /* Save these for later */
8339 memcpy (&module->aot_info, info, sizeof (MonoAotFileInfo));
8340 module->has_jitted_code = has_jitted_code;
8344 * mono_llvm_emit_aot_data:
8346 * Emit the binary data DATA pointed to by symbol SYMBOL.
8349 mono_llvm_emit_aot_data (const char *symbol, guint8 *data, int data_len)
8351 MonoLLVMModule *module = &aot_module;
8355 type = LLVMArrayType (LLVMInt8Type (), data_len);
8356 d = LLVMAddGlobal (module->lmodule, type, symbol);
8357 LLVMSetVisibility (d, LLVMHiddenVisibility);
8358 LLVMSetLinkage (d, LLVMInternalLinkage);
8359 LLVMSetInitializer (d, mono_llvm_create_constant_data_array (data, data_len));
8360 mono_llvm_set_is_constant (d);
8363 /* Add a reference to a global defined in JITted code */
8365 AddJitGlobal (MonoLLVMModule *module, LLVMTypeRef type, const char *name)
8370 s = g_strdup_printf ("%s%s", module->global_prefix, name);
8371 v = LLVMAddGlobal (module->lmodule, LLVMInt8Type (), s);
8377 emit_aot_file_info (MonoLLVMModule *module)
8379 LLVMTypeRef file_info_type;
8380 LLVMTypeRef *eltypes, eltype;
8381 LLVMValueRef info_var;
8382 LLVMValueRef *fields;
8383 int i, nfields, tindex;
8384 MonoAotFileInfo *info;
8385 LLVMModuleRef lmodule = module->lmodule;
8387 info = &module->aot_info;
8389 /* Create an LLVM type to represent MonoAotFileInfo */
8390 nfields = 2 + MONO_AOT_FILE_INFO_NUM_SYMBOLS + 15 + 5;
8391 eltypes = g_new (LLVMTypeRef, nfields);
8393 eltypes [tindex ++] = LLVMInt32Type ();
8394 eltypes [tindex ++] = LLVMInt32Type ();
8396 for (i = 0; i < MONO_AOT_FILE_INFO_NUM_SYMBOLS; ++i)
8397 eltypes [tindex ++] = LLVMPointerType (LLVMInt8Type (), 0);
8399 for (i = 0; i < 15; ++i)
8400 eltypes [tindex ++] = LLVMInt32Type ();
8402 eltypes [tindex ++] = LLVMArrayType (LLVMInt32Type (), MONO_AOT_TABLE_NUM);
8403 for (i = 0; i < 4; ++i)
8404 eltypes [tindex ++] = LLVMArrayType (LLVMInt32Type (), MONO_AOT_TRAMP_NUM);
8405 g_assert (tindex == nfields);
8406 file_info_type = LLVMStructCreateNamed (module->context, "MonoAotFileInfo");
8407 LLVMStructSetBody (file_info_type, eltypes, nfields, FALSE);
8409 info_var = LLVMAddGlobal (lmodule, file_info_type, "mono_aot_file_info");
8410 if (module->static_link) {
8411 LLVMSetVisibility (info_var, LLVMHiddenVisibility);
8412 LLVMSetLinkage (info_var, LLVMInternalLinkage);
8414 fields = g_new (LLVMValueRef, nfields);
8416 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->version, FALSE);
8417 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->dummy, FALSE);
8421 * We use LLVMGetNamedGlobal () for symbol which are defined in LLVM code, and LLVMAddGlobal ()
8422 * for symbols defined in the .s file emitted by the aot compiler.
8424 eltype = eltypes [tindex];
8425 if (module->llvm_only)
8426 fields [tindex ++] = LLVMConstNull (eltype);
8428 fields [tindex ++] = AddJitGlobal (module, eltype, "jit_got");
8429 fields [tindex ++] = module->got_var;
8430 /* llc defines this directly */
8431 if (!module->llvm_only) {
8432 fields [tindex ++] = LLVMAddGlobal (lmodule, eltype, module->eh_frame_symbol);
8433 fields [tindex ++] = LLVMConstNull (eltype);
8434 fields [tindex ++] = LLVMConstNull (eltype);
8436 fields [tindex ++] = LLVMConstNull (eltype);
8437 fields [tindex ++] = module->get_method;
8438 fields [tindex ++] = module->get_unbox_tramp;
8440 if (module->has_jitted_code) {
8441 fields [tindex ++] = AddJitGlobal (module, eltype, "jit_code_start");
8442 fields [tindex ++] = AddJitGlobal (module, eltype, "jit_code_end");
8444 fields [tindex ++] = LLVMConstNull (eltype);
8445 fields [tindex ++] = LLVMConstNull (eltype);
8447 if (!module->llvm_only)
8448 fields [tindex ++] = AddJitGlobal (module, eltype, "method_addresses");
8450 fields [tindex ++] = LLVMConstNull (eltype);
8451 if (info->flags & MONO_AOT_FILE_FLAG_SEPARATE_DATA) {
8452 for (i = 0; i < MONO_AOT_TABLE_NUM; ++i)
8453 fields [tindex ++] = LLVMConstNull (eltype);
8455 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "blob");
8456 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "class_name_table");
8457 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "class_info_offsets");
8458 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "method_info_offsets");
8459 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "ex_info_offsets");
8460 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "extra_method_info_offsets");
8461 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "extra_method_table");
8462 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "got_info_offsets");
8463 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "llvm_got_info_offsets");
8464 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "image_table");
8466 /* Not needed (mem_end) */
8467 fields [tindex ++] = LLVMConstNull (eltype);
8468 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "assembly_guid");
8469 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "runtime_version");
8470 if (info->trampoline_size [0]) {
8471 fields [tindex ++] = AddJitGlobal (module, eltype, "specific_trampolines");
8472 fields [tindex ++] = AddJitGlobal (module, eltype, "static_rgctx_trampolines");
8473 fields [tindex ++] = AddJitGlobal (module, eltype, "imt_thunks");
8474 fields [tindex ++] = AddJitGlobal (module, eltype, "gsharedvt_arg_trampolines");
8476 fields [tindex ++] = LLVMConstNull (eltype);
8477 fields [tindex ++] = LLVMConstNull (eltype);
8478 fields [tindex ++] = LLVMConstNull (eltype);
8479 fields [tindex ++] = LLVMConstNull (eltype);
8481 if (module->static_link && !module->llvm_only)
8482 fields [tindex ++] = AddJitGlobal (module, eltype, "globals");
8484 fields [tindex ++] = LLVMConstNull (eltype);
8485 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "assembly_name");
8486 if (!module->llvm_only) {
8487 fields [tindex ++] = AddJitGlobal (module, eltype, "plt");
8488 fields [tindex ++] = AddJitGlobal (module, eltype, "plt_end");
8489 fields [tindex ++] = AddJitGlobal (module, eltype, "unwind_info");
8490 fields [tindex ++] = AddJitGlobal (module, eltype, "unbox_trampolines");
8491 fields [tindex ++] = AddJitGlobal (module, eltype, "unbox_trampolines_end");
8492 fields [tindex ++] = AddJitGlobal (module, eltype, "unbox_trampoline_addresses");
8494 fields [tindex ++] = LLVMConstNull (eltype);
8495 fields [tindex ++] = LLVMConstNull (eltype);
8496 fields [tindex ++] = LLVMConstNull (eltype);
8497 fields [tindex ++] = LLVMConstNull (eltype);
8498 fields [tindex ++] = LLVMConstNull (eltype);
8499 fields [tindex ++] = LLVMConstNull (eltype);
8502 for (i = 0; i < MONO_AOT_FILE_INFO_NUM_SYMBOLS; ++i)
8503 fields [2 + i] = LLVMConstBitCast (fields [2 + i], eltype);
8506 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->plt_got_offset_base, FALSE);
8507 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->got_size, FALSE);
8508 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->plt_size, FALSE);
8509 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->nmethods, FALSE);
8510 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->flags, FALSE);
8511 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->opts, FALSE);
8512 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->simd_opts, FALSE);
8513 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->gc_name_index, FALSE);
8514 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->num_rgctx_fetch_trampolines, FALSE);
8515 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->double_align, FALSE);
8516 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->long_align, FALSE);
8517 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->generic_tramp_num, FALSE);
8518 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->tramp_page_size, FALSE);
8519 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->nshared_got_entries, FALSE);
8520 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->datafile_size, FALSE);
8522 fields [tindex ++] = llvm_array_from_uints (LLVMInt32Type (), info->table_offsets, MONO_AOT_TABLE_NUM);
8523 fields [tindex ++] = llvm_array_from_uints (LLVMInt32Type (), info->num_trampolines, MONO_AOT_TRAMP_NUM);
8524 fields [tindex ++] = llvm_array_from_uints (LLVMInt32Type (), info->trampoline_got_offset_base, MONO_AOT_TRAMP_NUM);
8525 fields [tindex ++] = llvm_array_from_uints (LLVMInt32Type (), info->trampoline_size, MONO_AOT_TRAMP_NUM);
8526 fields [tindex ++] = llvm_array_from_uints (LLVMInt32Type (), info->tramp_page_code_offsets, MONO_AOT_TRAMP_NUM);
8527 g_assert (tindex == nfields);
8529 LLVMSetInitializer (info_var, LLVMConstNamedStruct (file_info_type, fields, nfields));
8531 if (module->static_link) {
8535 s = g_strdup_printf ("mono_aot_module_%s_info", module->assembly->aname.name);
8536 /* Get rid of characters which cannot occur in symbols */
8538 for (p = s; *p; ++p) {
8539 if (!(isalnum (*p) || *p == '_'))
8542 var = LLVMAddGlobal (module->lmodule, LLVMPointerType (LLVMInt8Type (), 0), s);
8544 LLVMSetInitializer (var, LLVMConstBitCast (LLVMGetNamedGlobal (module->lmodule, "mono_aot_file_info"), LLVMPointerType (LLVMInt8Type (), 0)));
8545 LLVMSetLinkage (var, LLVMExternalLinkage);
8550 * Emit the aot module into the LLVM bitcode file FILENAME.
8553 mono_llvm_emit_aot_module (const char *filename, const char *cu_name)
8555 LLVMTypeRef got_type, inited_type;
8556 LLVMValueRef real_got, real_inited;
8557 MonoLLVMModule *module = &aot_module;
8559 emit_llvm_code_end (module);
8562 * Create the real got variable and replace all uses of the dummy variable with
8565 got_type = LLVMArrayType (module->ptr_type, module->max_got_offset + 1);
8566 real_got = LLVMAddGlobal (module->lmodule, got_type, module->got_symbol);
8567 LLVMSetInitializer (real_got, LLVMConstNull (got_type));
8568 if (module->external_symbols) {
8569 LLVMSetLinkage (real_got, LLVMExternalLinkage);
8570 LLVMSetVisibility (real_got, LLVMHiddenVisibility);
8572 LLVMSetLinkage (real_got, LLVMInternalLinkage);
8574 mono_llvm_replace_uses_of (module->got_var, real_got);
8576 mark_as_used (&aot_module, real_got);
8578 /* Delete the dummy got so it doesn't become a global */
8579 LLVMDeleteGlobal (module->got_var);
8580 module->got_var = real_got;
8583 * Same for the init_var
8585 if (module->llvm_only) {
8586 inited_type = LLVMArrayType (LLVMInt8Type (), module->max_inited_idx + 1);
8587 real_inited = LLVMAddGlobal (module->lmodule, inited_type, "mono_inited");
8588 LLVMSetInitializer (real_inited, LLVMConstNull (inited_type));
8589 LLVMSetLinkage (real_inited, LLVMInternalLinkage);
8590 mono_llvm_replace_uses_of (module->inited_var, real_inited);
8591 LLVMDeleteGlobal (module->inited_var);
8594 if (module->llvm_only) {
8595 emit_get_method (&aot_module);
8596 emit_get_unbox_tramp (&aot_module);
8599 emit_llvm_used (&aot_module);
8600 emit_dbg_info (&aot_module, filename, cu_name);
8601 emit_aot_file_info (&aot_module);
8604 * Replace GOT entries for directly callable methods with the methods themselves.
8605 * It would be easier to implement this by predefining all methods before compiling
8606 * their bodies, but that couldn't handle the case when a method fails to compile
8609 if (module->llvm_only) {
8610 GHashTableIter iter;
8612 GSList *callers, *l;
8614 g_hash_table_iter_init (&iter, module->method_to_callers);
8615 while (g_hash_table_iter_next (&iter, (void**)&method, (void**)&callers)) {
8616 LLVMValueRef lmethod;
8618 lmethod = (LLVMValueRef)g_hash_table_lookup (module->method_to_lmethod, method);
8620 for (l = callers; l; l = l->next) {
8621 LLVMValueRef caller = (LLVMValueRef)l->data;
8623 mono_llvm_replace_uses_of (caller, lmethod);
8629 /* Replace PLT entries for directly callable methods with the methods themselves */
8631 GHashTableIter iter;
8633 LLVMValueRef callee;
8635 g_hash_table_iter_init (&iter, module->plt_entries_ji);
8636 while (g_hash_table_iter_next (&iter, (void**)&ji, (void**)&callee)) {
8637 if (mono_aot_is_direct_callable (ji)) {
8638 LLVMValueRef lmethod;
8640 lmethod = (LLVMValueRef)g_hash_table_lookup (module->method_to_lmethod, ji->data.method);
8641 /* The types might not match because the caller might pass an rgctx */
8642 if (lmethod && LLVMTypeOf (callee) == LLVMTypeOf (lmethod)) {
8643 mono_llvm_replace_uses_of (callee, lmethod);
8644 mono_aot_mark_unused_llvm_plt_entry (ji);
8654 if (LLVMVerifyModule (module->lmodule, LLVMReturnStatusAction, &verifier_err)) {
8655 g_assert_not_reached ();
8660 LLVMWriteBitcodeToFile (module->lmodule, filename);
8665 md_string (const char *s)
8667 return LLVMMDString (s, strlen (s));
8670 /* Debugging support */
8673 emit_dbg_info (MonoLLVMModule *module, const char *filename, const char *cu_name)
8675 LLVMModuleRef lmodule = module->lmodule;
8676 LLVMValueRef args [16], ver;
8679 * This can only be enabled when LLVM code is emitted into a separate object
8680 * file, since the AOT compiler also emits dwarf info,
8681 * and the abbrev indexes will not be correct since llvm has added its own
8684 if (!module->emit_dwarf)
8687 #if LLVM_API_VERSION > 100
8688 mono_llvm_di_builder_finalize (module->di_builder);
8690 LLVMValueRef cu_args [16], cu;
8692 char *build_info, *s, *dir;
8695 * Emit dwarf info in the form of LLVM metadata. There is some
8696 * out-of-date documentation at:
8697 * http://llvm.org/docs/SourceLevelDebugging.html
8698 * but most of this was gathered from the llvm and
8703 cu_args [n_cuargs ++] = LLVMConstInt (LLVMInt32Type (), DW_TAG_compile_unit, FALSE);
8704 /* CU name/compilation dir */
8705 dir = g_path_get_dirname (filename);
8706 args [0] = LLVMMDString (cu_name, strlen (cu_name));
8707 args [1] = LLVMMDString (dir, strlen (dir));
8708 cu_args [n_cuargs ++] = LLVMMDNode (args, 2);
8711 cu_args [n_cuargs ++] = LLVMConstInt (LLVMInt32Type (), DW_LANG_C99, FALSE);
8713 build_info = mono_get_runtime_build_info ();
8714 s = g_strdup_printf ("Mono AOT Compiler %s (LLVM)", build_info);
8715 cu_args [n_cuargs ++] = LLVMMDString (s, strlen (s));
8716 g_free (build_info);
8718 cu_args [n_cuargs ++] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
8720 cu_args [n_cuargs ++] = LLVMMDString ("", strlen (""));
8721 /* Runtime version */
8722 cu_args [n_cuargs ++] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
8724 cu_args [n_cuargs ++] = LLVMMDNode (args, 0);
8725 cu_args [n_cuargs ++] = LLVMMDNode (args, 0);
8727 if (module->subprogram_mds) {
8731 mds = g_new0 (LLVMValueRef, module->subprogram_mds->len);
8732 for (i = 0; i < module->subprogram_mds->len; ++i)
8733 mds [i] = (LLVMValueRef)g_ptr_array_index (module->subprogram_mds, i);
8734 cu_args [n_cuargs ++] = LLVMMDNode (mds, module->subprogram_mds->len);
8736 cu_args [n_cuargs ++] = LLVMMDNode (args, 0);
8739 cu_args [n_cuargs ++] = LLVMMDNode (args, 0);
8740 /* Imported modules */
8741 cu_args [n_cuargs ++] = LLVMMDNode (args, 0);
8743 cu_args [n_cuargs ++] = LLVMMDString ("", strlen (""));
8744 /* DebugEmissionKind = FullDebug */
8745 cu_args [n_cuargs ++] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
8746 cu = LLVMMDNode (cu_args, n_cuargs);
8747 LLVMAddNamedMetadataOperand (lmodule, "llvm.dbg.cu", cu);
8750 #if LLVM_API_VERSION > 100
8751 args [0] = LLVMConstInt (LLVMInt32Type (), 2, FALSE);
8752 args [1] = LLVMMDString ("Dwarf Version", strlen ("Dwarf Version"));
8753 args [2] = LLVMConstInt (LLVMInt32Type (), 2, FALSE);
8754 ver = LLVMMDNode (args, 3);
8755 LLVMAddNamedMetadataOperand (lmodule, "llvm.module.flags", ver);
8757 args [0] = LLVMConstInt (LLVMInt32Type (), 2, FALSE);
8758 args [1] = LLVMMDString ("Debug Info Version", strlen ("Debug Info Version"));
8759 args [2] = LLVMConstInt (LLVMInt64Type (), 3, FALSE);
8760 ver = LLVMMDNode (args, 3);
8761 LLVMAddNamedMetadataOperand (lmodule, "llvm.module.flags", ver);
8763 args [0] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
8764 args [1] = LLVMMDString ("Dwarf Version", strlen ("Dwarf Version"));
8765 args [2] = LLVMConstInt (LLVMInt32Type (), 2, FALSE);
8766 ver = LLVMMDNode (args, 3);
8767 LLVMAddNamedMetadataOperand (lmodule, "llvm.module.flags", ver);
8769 args [0] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
8770 args [1] = LLVMMDString ("Debug Info Version", strlen ("Debug Info Version"));
8771 args [2] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
8772 ver = LLVMMDNode (args, 3);
8773 LLVMAddNamedMetadataOperand (lmodule, "llvm.module.flags", ver);
8778 emit_dbg_subprogram (EmitContext *ctx, MonoCompile *cfg, LLVMValueRef method, const char *name)
8780 MonoLLVMModule *module = ctx->module;
8781 MonoDebugMethodInfo *minfo = ctx->minfo;
8782 char *source_file, *dir, *filename;
8783 LLVMValueRef md, args [16], ctx_args [16], md_args [64], type_args [16], ctx_md, type_md;
8784 MonoSymSeqPoint *sym_seq_points;
8790 mono_debug_symfile_get_seq_points (minfo, &source_file, NULL, NULL, &sym_seq_points, &n_seq_points);
8792 source_file = g_strdup ("<unknown>");
8793 dir = g_path_get_dirname (source_file);
8794 filename = g_path_get_basename (source_file);
8796 #if LLVM_API_VERSION > 100
8797 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);
8800 ctx_args [0] = LLVMConstInt (LLVMInt32Type (), 0x29, FALSE);
8801 args [0] = md_string (filename);
8802 args [1] = md_string (dir);
8803 ctx_args [1] = LLVMMDNode (args, 2);
8804 ctx_md = LLVMMDNode (ctx_args, 2);
8806 type_args [0] = LLVMConstInt (LLVMInt32Type (), DW_TAG_subroutine_type, FALSE);
8807 type_args [1] = NULL;
8808 type_args [2] = NULL;
8809 type_args [3] = LLVMMDString ("", 0);
8810 type_args [4] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
8811 type_args [5] = LLVMConstInt (LLVMInt64Type (), 0, FALSE);
8812 type_args [6] = LLVMConstInt (LLVMInt64Type (), 0, FALSE);
8813 type_args [7] = LLVMConstInt (LLVMInt64Type (), 0, FALSE);
8814 type_args [8] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
8815 type_args [9] = NULL;
8816 type_args [10] = NULL;
8817 type_args [11] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
8818 type_args [12] = NULL;
8819 type_args [13] = NULL;
8820 type_args [14] = NULL;
8821 type_md = LLVMMDNode (type_args, 14);
8823 /* http://llvm.org/docs/SourceLevelDebugging.html#subprogram-descriptors */
8824 md_args [0] = LLVMConstInt (LLVMInt32Type (), DW_TAG_subprogram, FALSE);
8825 /* Source directory + file pair */
8826 args [0] = md_string (filename);
8827 args [1] = md_string (dir);
8828 md_args [1] = LLVMMDNode (args ,2);
8829 md_args [2] = ctx_md;
8830 md_args [3] = md_string (cfg->method->name);
8831 md_args [4] = md_string (name);
8832 md_args [5] = md_string (name);
8835 md_args [6] = LLVMConstInt (LLVMInt32Type (), sym_seq_points [0].line, FALSE);
8837 md_args [6] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
8839 md_args [7] = type_md;
8841 md_args [8] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
8843 md_args [9] = LLVMConstInt (LLVMInt1Type (), 1, FALSE);
8845 md_args [10] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
8846 /* Index into a virtual function */
8847 md_args [11] = NULL;
8848 md_args [12] = NULL;
8850 md_args [13] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
8852 md_args [14] = LLVMConstInt (LLVMInt1Type (), 1, FALSE);
8853 /* Pointer to LLVM function */
8854 md_args [15] = method;
8855 /* Function template parameter */
8856 md_args [16] = NULL;
8857 /* Function declaration descriptor */
8858 md_args [17] = NULL;
8859 /* List of function variables */
8860 md_args [18] = LLVMMDNode (args, 0);
8862 md_args [19] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
8863 md = LLVMMDNode (md_args, 20);
8865 if (!module->subprogram_mds)
8866 module->subprogram_mds = g_ptr_array_new ();
8867 g_ptr_array_add (module->subprogram_mds, md);
8871 g_free (source_file);
8872 g_free (sym_seq_points);
8878 emit_dbg_loc (EmitContext *ctx, LLVMBuilderRef builder, const unsigned char *cil_code)
8880 MonoCompile *cfg = ctx->cfg;
8882 if (ctx->minfo && cil_code && cil_code >= cfg->header->code && cil_code < cfg->header->code + cfg->header->code_size) {
8883 MonoDebugSourceLocation *loc;
8884 LLVMValueRef loc_md;
8886 loc = mono_debug_symfile_lookup_location (ctx->minfo, cil_code - cfg->header->code);
8889 #if LLVM_API_VERSION > 100
8890 loc_md = mono_llvm_di_create_location (ctx->module->di_builder, ctx->dbg_md, loc->row, loc->column);
8891 mono_llvm_di_set_location (builder, loc_md);
8893 LLVMValueRef md_args [16];
8897 md_args [nmd_args ++] = LLVMConstInt (LLVMInt32Type (), loc->row, FALSE);
8898 md_args [nmd_args ++] = LLVMConstInt (LLVMInt32Type (), loc->column, FALSE);
8899 md_args [nmd_args ++] = ctx->dbg_md;
8900 md_args [nmd_args ++] = NULL;
8901 loc_md = LLVMMDNode (md_args, nmd_args);
8902 LLVMSetCurrentDebugLocation (builder, loc_md);
8904 mono_debug_symfile_free_location (loc);
8910 default_mono_llvm_unhandled_exception (void)
8912 MonoJitTlsData *jit_tls = mono_get_jit_tls ();
8913 MonoObject *target = mono_gchandle_get_target (jit_tls->thrown_exc);
8915 mono_unhandled_exception (target);
8916 exit (mono_environment_exitcode_get ());
8921 - Emit LLVM IR from the mono IR using the LLVM C API.
8922 - The original arch specific code remains, so we can fall back to it if we run
8923 into something we can't handle.
8927 A partial list of issues:
8928 - Handling of opcodes which can throw exceptions.
8930 In the mono JIT, these are implemented using code like this:
8937 push throw_pos - method
8938 call <exception trampoline>
8940 The problematic part is push throw_pos - method, which cannot be represented
8941 in the LLVM IR, since it does not support label values.
8942 -> this can be implemented in AOT mode using inline asm + labels, but cannot
8943 be implemented in JIT mode ?
8944 -> a possible but slower implementation would use the normal exception
8945 throwing code but it would need to control the placement of the throw code
8946 (it needs to be exactly after the compare+branch).
8947 -> perhaps add a PC offset intrinsics ?
8949 - efficient implementation of .ovf opcodes.
8951 These are currently implemented as:
8952 <ins which sets the condition codes>
8955 Some overflow opcodes are now supported by LLVM SVN.
8957 - exception handling, unwinding.
8958 - SSA is disabled for methods with exception handlers
8959 - How to obtain unwind info for LLVM compiled methods ?
8960 -> this is now solved by converting the unwind info generated by LLVM
8962 - LLVM uses the c++ exception handling framework, while we use our home grown
8963 code, and couldn't use the c++ one:
8964 - its not supported under VC++, other exotic platforms.
8965 - it might be impossible to support filter clauses with it.
8969 The trampolines need a predictable call sequence, since they need to disasm
8970 the calling code to obtain register numbers / offsets.
8972 LLVM currently generates this code in non-JIT mode:
8973 mov -0x98(%rax),%eax
8975 Here, the vtable pointer is lost.
8976 -> solution: use one vtable trampoline per class.
8978 - passing/receiving the IMT pointer/RGCTX.
8979 -> solution: pass them as normal arguments ?
8983 LLVM does not allow the specification of argument registers etc. This means
8984 that all calls are made according to the platform ABI.
8986 - passing/receiving vtypes.
8988 Vtypes passed/received in registers are handled by the front end by using
8989 a signature with scalar arguments, and loading the parts of the vtype into those
8992 Vtypes passed on the stack are handled using the 'byval' attribute.
8996 Supported though alloca, we need to emit the load/store code.
9000 The mono JIT uses pointer sized iregs/double fregs, while LLVM uses precisely
9001 typed registers, so we have to keep track of the precise LLVM type of each vreg.
9002 This is made easier because the IR is already in SSA form.
9003 An additional problem is that our IR is not consistent with types, i.e. i32/ia64
9004 types are frequently used incorrectly.
9009 Emit LLVM bytecode into a .bc file, compile it using llc into a .s file, then link
9010 it with the file containing the methods emitted by the JIT and the AOT data
9014 /* FIXME: Normalize some aspects of the mono IR to allow easier translation, like:
9015 * - each bblock should end with a branch
9016 * - setting the return value, making cfg->ret non-volatile
9017 * - avoid some transformations in the JIT which make it harder for us to generate
9019 * - use pointer types to help optimizations.