2 * mini-llvm.c: llvm "Backend" for the mono JIT
4 * Copyright 2009-2011 Novell Inc (http://www.novell.com)
5 * Copyright 2011 Xamarin Inc (http://www.xamarin.com)
6 * Licensed under the MIT license. See LICENSE file in the project root for full license information.
10 #include <mono/metadata/debug-helpers.h>
11 #include <mono/metadata/debug-mono-symfile.h>
12 #include <mono/metadata/mempool-internals.h>
13 #include <mono/metadata/environment.h>
14 #include <mono/metadata/object-internals.h>
15 #include <mono/metadata/abi-details.h>
16 #include <mono/utils/mono-tls.h>
17 #include <mono/utils/mono-dl.h>
18 #include <mono/utils/mono-time.h>
19 #include <mono/utils/freebsd-dwarf.h>
21 #ifndef __STDC_LIMIT_MACROS
22 #define __STDC_LIMIT_MACROS
24 #ifndef __STDC_CONSTANT_MACROS
25 #define __STDC_CONSTANT_MACROS
28 #include "llvm-c/BitWriter.h"
29 #include "llvm-c/Analysis.h"
31 #include "mini-llvm-cpp.h"
33 #include "aot-compiler.h"
34 #include "mini-llvm.h"
39 extern void *memset(void *, int, size_t);
40 void bzero (void *to, size_t count) { memset (to, 0, count); }
44 #if LLVM_API_VERSION < 4
45 #error "The version of the mono llvm repository is too old."
48 #define ALIGN_PTR_TO(ptr,align) (gpointer)((((gssize)(ptr)) + (align - 1)) & (~(align - 1)))
51 * Information associated by mono with LLVM modules.
54 LLVMModuleRef lmodule;
55 LLVMValueRef throw_icall, rethrow, match_exc, throw_corlib_exception, resume_eh;
56 GHashTable *llvm_types;
58 const char *got_symbol;
59 const char *get_method_symbol;
60 const char *get_unbox_tramp_symbol;
61 GHashTable *plt_entries;
62 GHashTable *plt_entries_ji;
63 GHashTable *method_to_lmethod;
64 GHashTable *direct_callables;
69 GPtrArray *subprogram_mds;
71 LLVMExecutionEngineRef ee;
72 gboolean external_symbols;
77 MonoAssembly *assembly;
79 MonoAotFileInfo aot_info;
80 const char *jit_got_symbol;
81 const char *eh_frame_symbol;
82 LLVMValueRef get_method, get_unbox_tramp;
83 LLVMValueRef init_method, init_method_gshared_mrgctx, init_method_gshared_this, init_method_gshared_vtable;
84 LLVMValueRef code_start, code_end;
85 LLVMValueRef inited_var;
86 int max_inited_idx, max_method_idx;
87 gboolean has_jitted_code;
90 GHashTable *idx_to_lmethod;
91 GHashTable *idx_to_unbox_tramp;
92 /* Maps a MonoMethod to LLVM instructions representing it */
93 GHashTable *method_to_callers;
94 LLVMContextRef context;
95 LLVMValueRef sentinel_exception;
96 void *di_builder, *cu;
100 * Information associated by the backend with mono basic blocks.
103 LLVMBasicBlockRef bblock, end_bblock;
104 LLVMValueRef finally_ind;
105 gboolean added, invoke_target;
107 * If this bblock is the start of a finally clause, this is a list of bblocks it
108 * needs to branch to in ENDFINALLY.
110 GSList *call_handler_return_bbs;
112 * If this bblock is the start of a finally clause, this is the bblock that
113 * CALL_HANDLER needs to branch to.
115 LLVMBasicBlockRef call_handler_target_bb;
116 /* The list of switch statements generated by ENDFINALLY instructions */
117 GSList *endfinally_switch_ins_list;
122 * Structure containing emit state
125 MonoMemPool *mempool;
127 /* Maps method names to the corresponding LLVMValueRef */
128 GHashTable *emitted_method_decls;
131 LLVMValueRef lmethod;
132 MonoLLVMModule *module;
133 LLVMModuleRef lmodule;
135 int sindex, default_index, ex_index;
136 LLVMBuilderRef builder;
137 LLVMValueRef *values, *addresses;
138 MonoType **vreg_cli_types;
140 MonoMethodSignature *sig;
142 GHashTable *region_to_handler;
143 GHashTable *clause_to_handler;
144 LLVMBuilderRef alloca_builder;
145 LLVMValueRef last_alloca;
146 LLVMValueRef rgctx_arg;
147 LLVMValueRef this_arg;
148 LLVMTypeRef *vreg_types;
149 LLVMTypeRef method_type;
150 LLVMBasicBlockRef init_bb, inited_bb;
152 gboolean *unreachable;
154 gboolean has_got_access;
155 gboolean is_linkonce;
156 int this_arg_pindex, rgctx_arg_pindex;
157 LLVMValueRef imt_rgctx_loc;
158 GHashTable *llvm_types;
160 MonoDebugMethodInfo *minfo;
162 /* For every clause, the clauses it is nested in */
165 GHashTable *exc_meta;
166 GHashTable *method_to_callers;
167 GPtrArray *phi_values;
168 GPtrArray *bblock_list;
170 GHashTable *jit_callees;
176 MonoBasicBlock *in_bb;
181 * Instruction metadata
182 * This is the same as ins_info, but LREG != IREG.
190 #define MINI_OP(a,b,dest,src1,src2) dest, src1, src2, ' ',
191 #define MINI_OP3(a,b,dest,src1,src2,src3) dest, src1, src2, src3,
198 /* keep in sync with the enum in mini.h */
201 #include "mini-ops.h"
206 #if SIZEOF_VOID_P == 4
207 #define GET_LONG_IMM(ins) (((guint64)(ins)->inst_ms_word << 32) | (guint64)(guint32)(ins)->inst_ls_word)
209 #define GET_LONG_IMM(ins) ((ins)->inst_imm)
212 #define LLVM_INS_INFO(opcode) (&llvm_ins_info [((opcode) - OP_START - 1) * 4])
215 #define TRACE_FAILURE(msg) do { printf ("%s\n", msg); } while (0)
217 #define TRACE_FAILURE(msg)
221 #define IS_TARGET_X86 1
223 #define IS_TARGET_X86 0
227 #define IS_TARGET_AMD64 1
229 #define IS_TARGET_AMD64 0
232 #define ctx_ok(ctx) (!(ctx)->cfg->disable_llvm)
234 static LLVMIntPredicate cond_to_llvm_cond [] = {
247 static LLVMRealPredicate fpcond_to_llvm_cond [] = {
260 static MonoNativeTlsKey current_cfg_tls_id;
262 static MonoLLVMModule aot_module;
264 static GHashTable *intrins_id_to_name;
265 static GHashTable *intrins_name_to_id;
267 static void init_jit_module (MonoDomain *domain);
269 static void emit_dbg_loc (EmitContext *ctx, LLVMBuilderRef builder, const unsigned char *cil_code);
270 static LLVMValueRef emit_dbg_subprogram (EmitContext *ctx, MonoCompile *cfg, LLVMValueRef method, const char *name);
271 static void emit_dbg_info (MonoLLVMModule *module, const char *filename, const char *cu_name);
272 static void emit_cond_system_exception (EmitContext *ctx, MonoBasicBlock *bb, const char *exc_type, LLVMValueRef cmp);
273 static LLVMValueRef get_intrinsic (EmitContext *ctx, const char *name);
274 static void decode_llvm_eh_info (EmitContext *ctx, gpointer eh_frame);
277 set_failure (EmitContext *ctx, const char *message)
279 TRACE_FAILURE (reason);
280 ctx->cfg->exception_message = g_strdup (message);
281 ctx->cfg->disable_llvm = TRUE;
287 * The LLVM type with width == sizeof (gpointer)
292 return sizeof (gpointer) == 8 ? LLVMInt64Type () : LLVMInt32Type ();
298 return sizeof (gpointer) == 8 ? LLVMPointerType (LLVMInt64Type (), 0) : LLVMPointerType (LLVMInt32Type (), 0);
304 return sizeof (gpointer) == 8 ? LLVMPointerType (LLVMInt64Type (), 0) : LLVMPointerType (LLVMInt32Type (), 0);
310 * Return the size of the LLVM representation of the vtype T.
313 get_vtype_size (MonoType *t)
317 size = mono_class_value_size (mono_class_from_mono_type (t), NULL);
319 /* LLVMArgAsIArgs depends on this since it stores whole words */
320 while (size < 2 * sizeof (gpointer) && mono_is_power_of_two (size) == -1)
327 * simd_class_to_llvm_type:
329 * Return the LLVM type corresponding to the Mono.SIMD class KLASS
332 simd_class_to_llvm_type (EmitContext *ctx, MonoClass *klass)
334 if (!strcmp (klass->name, "Vector2d")) {
335 return LLVMVectorType (LLVMDoubleType (), 2);
336 } else if (!strcmp (klass->name, "Vector2l")) {
337 return LLVMVectorType (LLVMInt64Type (), 2);
338 } else if (!strcmp (klass->name, "Vector2ul")) {
339 return LLVMVectorType (LLVMInt64Type (), 2);
340 } else if (!strcmp (klass->name, "Vector4i")) {
341 return LLVMVectorType (LLVMInt32Type (), 4);
342 } else if (!strcmp (klass->name, "Vector4ui")) {
343 return LLVMVectorType (LLVMInt32Type (), 4);
344 } else if (!strcmp (klass->name, "Vector4f")) {
345 return LLVMVectorType (LLVMFloatType (), 4);
346 } else if (!strcmp (klass->name, "Vector8s")) {
347 return LLVMVectorType (LLVMInt16Type (), 8);
348 } else if (!strcmp (klass->name, "Vector8us")) {
349 return LLVMVectorType (LLVMInt16Type (), 8);
350 } else if (!strcmp (klass->name, "Vector16sb")) {
351 return LLVMVectorType (LLVMInt8Type (), 16);
352 } else if (!strcmp (klass->name, "Vector16b")) {
353 return LLVMVectorType (LLVMInt8Type (), 16);
355 printf ("%s\n", klass->name);
361 /* Return the 128 bit SIMD type corresponding to the mono type TYPE */
362 static inline G_GNUC_UNUSED LLVMTypeRef
363 type_to_simd_type (int type)
367 return LLVMVectorType (LLVMInt8Type (), 16);
369 return LLVMVectorType (LLVMInt16Type (), 8);
371 return LLVMVectorType (LLVMInt32Type (), 4);
373 return LLVMVectorType (LLVMInt64Type (), 2);
375 return LLVMVectorType (LLVMDoubleType (), 2);
377 return LLVMVectorType (LLVMFloatType (), 4);
379 g_assert_not_reached ();
385 create_llvm_type_for_type (MonoLLVMModule *module, MonoClass *klass)
387 int i, size, nfields, esize;
388 LLVMTypeRef *eltypes;
393 t = &klass->byval_arg;
395 if (mini_type_is_hfa (t, &nfields, &esize)) {
397 * This is needed on arm64 where HFAs are returned in
401 eltypes = g_new (LLVMTypeRef, size);
402 for (i = 0; i < size; ++i)
403 eltypes [i] = esize == 4 ? LLVMFloatType () : LLVMDoubleType ();
405 size = get_vtype_size (t);
407 eltypes = g_new (LLVMTypeRef, size);
408 for (i = 0; i < size; ++i)
409 eltypes [i] = LLVMInt8Type ();
412 name = mono_type_full_name (&klass->byval_arg);
413 ltype = LLVMStructCreateNamed (module->context, name);
414 LLVMStructSetBody (ltype, eltypes, size, FALSE);
424 * Return the LLVM type corresponding to T.
427 type_to_llvm_type (EmitContext *ctx, MonoType *t)
429 t = mini_get_underlying_type (t);
433 return LLVMVoidType ();
435 return LLVMInt8Type ();
437 return LLVMInt16Type ();
439 return LLVMInt32Type ();
441 return LLVMInt8Type ();
443 return LLVMInt16Type ();
445 return LLVMInt32Type ();
446 case MONO_TYPE_BOOLEAN:
447 return LLVMInt8Type ();
450 return LLVMInt64Type ();
452 return LLVMInt16Type ();
454 return LLVMFloatType ();
456 return LLVMDoubleType ();
459 return IntPtrType ();
460 case MONO_TYPE_OBJECT:
461 case MONO_TYPE_CLASS:
462 case MONO_TYPE_ARRAY:
463 case MONO_TYPE_SZARRAY:
464 case MONO_TYPE_STRING:
466 return ObjRefType ();
469 /* Because of generic sharing */
470 return ObjRefType ();
471 case MONO_TYPE_GENERICINST:
472 if (!mono_type_generic_inst_is_valuetype (t))
473 return ObjRefType ();
475 case MONO_TYPE_VALUETYPE:
476 case MONO_TYPE_TYPEDBYREF: {
480 klass = mono_class_from_mono_type (t);
482 if (MONO_CLASS_IS_SIMD (ctx->cfg, klass))
483 return simd_class_to_llvm_type (ctx, klass);
486 return type_to_llvm_type (ctx, mono_class_enum_basetype (klass));
488 ltype = (LLVMTypeRef)g_hash_table_lookup (ctx->module->llvm_types, klass);
490 ltype = create_llvm_type_for_type (ctx->module, klass);
491 g_hash_table_insert (ctx->module->llvm_types, klass, ltype);
497 printf ("X: %d\n", t->type);
498 ctx->cfg->exception_message = g_strdup_printf ("type %s", mono_type_full_name (t));
499 ctx->cfg->disable_llvm = TRUE;
507 * Return whenever T is an unsigned int type.
510 type_is_unsigned (EmitContext *ctx, MonoType *t)
512 t = mini_get_underlying_type (t);
528 * type_to_llvm_arg_type:
530 * Same as type_to_llvm_type, but treat i8/i16 as i32.
533 type_to_llvm_arg_type (EmitContext *ctx, MonoType *t)
535 LLVMTypeRef ptype = type_to_llvm_type (ctx, t);
537 if (ctx->cfg->llvm_only)
541 * This works on all abis except arm64/ios which passes multiple
542 * arguments in one stack slot.
545 if (ptype == LLVMInt8Type () || ptype == LLVMInt16Type ()) {
547 * LLVM generates code which only sets the lower bits, while JITted
548 * code expects all the bits to be set.
550 ptype = LLVMInt32Type ();
558 * llvm_type_to_stack_type:
560 * Return the LLVM type which needs to be used when a value of type TYPE is pushed
563 static G_GNUC_UNUSED LLVMTypeRef
564 llvm_type_to_stack_type (MonoCompile *cfg, LLVMTypeRef type)
568 if (type == LLVMInt8Type ())
569 return LLVMInt32Type ();
570 else if (type == LLVMInt16Type ())
571 return LLVMInt32Type ();
572 else if (!cfg->r4fp && type == LLVMFloatType ())
573 return LLVMDoubleType ();
579 * regtype_to_llvm_type:
581 * Return the LLVM type corresponding to the regtype C used in instruction
585 regtype_to_llvm_type (char c)
589 return LLVMInt32Type ();
591 return LLVMInt64Type ();
593 return LLVMDoubleType ();
602 * Return the LLVM type corresponding to the unary/binary opcode OPCODE.
605 op_to_llvm_type (int opcode)
610 return LLVMInt8Type ();
613 return LLVMInt8Type ();
616 return LLVMInt16Type ();
619 return LLVMInt16Type ();
622 return LLVMInt32Type ();
625 return LLVMInt32Type ();
627 return LLVMInt64Type ();
629 return LLVMFloatType ();
631 return LLVMDoubleType ();
633 return LLVMInt64Type ();
635 return LLVMInt32Type ();
637 return LLVMInt64Type ();
642 return LLVMInt8Type ();
647 return LLVMInt16Type ();
649 return LLVMInt32Type ();
652 return sizeof (gpointer) == 8 ? LLVMInt64Type () : LLVMInt32Type ();
659 return LLVMInt32Type ();
666 return LLVMInt64Type ();
668 printf ("%s\n", mono_inst_name (opcode));
669 g_assert_not_reached ();
674 #define CLAUSE_START(clause) ((clause)->try_offset)
675 #define CLAUSE_END(clause) (((clause))->try_offset + ((clause))->try_len)
678 * load_store_to_llvm_type:
680 * Return the size/sign/zero extension corresponding to the load/store opcode
684 load_store_to_llvm_type (int opcode, int *size, gboolean *sext, gboolean *zext)
690 case OP_LOADI1_MEMBASE:
691 case OP_STOREI1_MEMBASE_REG:
692 case OP_STOREI1_MEMBASE_IMM:
693 case OP_ATOMIC_LOAD_I1:
694 case OP_ATOMIC_STORE_I1:
697 return LLVMInt8Type ();
698 case OP_LOADU1_MEMBASE:
700 case OP_ATOMIC_LOAD_U1:
701 case OP_ATOMIC_STORE_U1:
704 return LLVMInt8Type ();
705 case OP_LOADI2_MEMBASE:
706 case OP_STOREI2_MEMBASE_REG:
707 case OP_STOREI2_MEMBASE_IMM:
708 case OP_ATOMIC_LOAD_I2:
709 case OP_ATOMIC_STORE_I2:
712 return LLVMInt16Type ();
713 case OP_LOADU2_MEMBASE:
715 case OP_ATOMIC_LOAD_U2:
716 case OP_ATOMIC_STORE_U2:
719 return LLVMInt16Type ();
720 case OP_LOADI4_MEMBASE:
721 case OP_LOADU4_MEMBASE:
724 case OP_STOREI4_MEMBASE_REG:
725 case OP_STOREI4_MEMBASE_IMM:
726 case OP_ATOMIC_LOAD_I4:
727 case OP_ATOMIC_STORE_I4:
728 case OP_ATOMIC_LOAD_U4:
729 case OP_ATOMIC_STORE_U4:
731 return LLVMInt32Type ();
732 case OP_LOADI8_MEMBASE:
734 case OP_STOREI8_MEMBASE_REG:
735 case OP_STOREI8_MEMBASE_IMM:
736 case OP_ATOMIC_LOAD_I8:
737 case OP_ATOMIC_STORE_I8:
738 case OP_ATOMIC_LOAD_U8:
739 case OP_ATOMIC_STORE_U8:
741 return LLVMInt64Type ();
742 case OP_LOADR4_MEMBASE:
743 case OP_STORER4_MEMBASE_REG:
744 case OP_ATOMIC_LOAD_R4:
745 case OP_ATOMIC_STORE_R4:
747 return LLVMFloatType ();
748 case OP_LOADR8_MEMBASE:
749 case OP_STORER8_MEMBASE_REG:
750 case OP_ATOMIC_LOAD_R8:
751 case OP_ATOMIC_STORE_R8:
753 return LLVMDoubleType ();
754 case OP_LOAD_MEMBASE:
756 case OP_STORE_MEMBASE_REG:
757 case OP_STORE_MEMBASE_IMM:
758 *size = sizeof (gpointer);
759 return IntPtrType ();
761 g_assert_not_reached ();
769 * Return the LLVM intrinsics corresponding to the overflow opcode OPCODE.
772 ovf_op_to_intrins (int opcode)
776 return "llvm.sadd.with.overflow.i32";
778 return "llvm.uadd.with.overflow.i32";
780 return "llvm.ssub.with.overflow.i32";
782 return "llvm.usub.with.overflow.i32";
784 return "llvm.smul.with.overflow.i32";
786 return "llvm.umul.with.overflow.i32";
788 return "llvm.sadd.with.overflow.i64";
790 return "llvm.uadd.with.overflow.i64";
792 return "llvm.ssub.with.overflow.i64";
794 return "llvm.usub.with.overflow.i64";
796 return "llvm.smul.with.overflow.i64";
798 return "llvm.umul.with.overflow.i64";
800 g_assert_not_reached ();
806 simd_op_to_intrins (int opcode)
809 #if defined(TARGET_X86) || defined(TARGET_AMD64)
811 return "llvm.x86.sse2.min.pd";
813 return "llvm.x86.sse.min.ps";
815 return "llvm.x86.sse41.pminud";
817 return "llvm.x86.sse41.pminuw";
819 return "llvm.x86.sse2.pminu.b";
821 return "llvm.x86.sse2.pmins.w";
823 return "llvm.x86.sse2.max.pd";
825 return "llvm.x86.sse.max.ps";
827 return "llvm.x86.sse3.hadd.pd";
829 return "llvm.x86.sse3.hadd.ps";
831 return "llvm.x86.sse3.hsub.pd";
833 return "llvm.x86.sse3.hsub.ps";
835 return "llvm.x86.sse41.pmaxud";
837 return "llvm.x86.sse41.pmaxuw";
839 return "llvm.x86.sse2.pmaxu.b";
841 return "llvm.x86.sse3.addsub.ps";
843 return "llvm.x86.sse3.addsub.pd";
844 case OP_EXTRACT_MASK:
845 return "llvm.x86.sse2.pmovmskb.128";
848 return "llvm.x86.sse2.psrli.w";
851 return "llvm.x86.sse2.psrli.d";
854 return "llvm.x86.sse2.psrli.q";
857 return "llvm.x86.sse2.pslli.w";
860 return "llvm.x86.sse2.pslli.d";
863 return "llvm.x86.sse2.pslli.q";
866 return "llvm.x86.sse2.psrai.w";
869 return "llvm.x86.sse2.psrai.d";
871 return "llvm.x86.sse2.padds.b";
873 return "llvm.x86.sse2.padds.w";
875 return "llvm.x86.sse2.psubs.b";
877 return "llvm.x86.sse2.psubs.w";
878 case OP_PADDB_SAT_UN:
879 return "llvm.x86.sse2.paddus.b";
880 case OP_PADDW_SAT_UN:
881 return "llvm.x86.sse2.paddus.w";
882 case OP_PSUBB_SAT_UN:
883 return "llvm.x86.sse2.psubus.b";
884 case OP_PSUBW_SAT_UN:
885 return "llvm.x86.sse2.psubus.w";
887 return "llvm.x86.sse2.pavg.b";
889 return "llvm.x86.sse2.pavg.w";
891 return "llvm.x86.sse.sqrt.ps";
893 return "llvm.x86.sse2.sqrt.pd";
895 return "llvm.x86.sse.rsqrt.ps";
897 return "llvm.x86.sse.rcp.ps";
899 return "llvm.x86.sse2.cvtdq2pd";
901 return "llvm.x86.sse2.cvtdq2ps";
903 return "llvm.x86.sse2.cvtpd2dq";
905 return "llvm.x86.sse2.cvtps2dq";
907 return "llvm.x86.sse2.cvtpd2ps";
909 return "llvm.x86.sse2.cvtps2pd";
911 return "llvm.x86.sse2.cvttpd2dq";
913 return "llvm.x86.sse2.cvttps2dq";
915 return "llvm.x86.sse.cmp.ps";
917 return "llvm.x86.sse2.cmp.pd";
919 return "llvm.x86.sse2.packsswb.128";
921 return "llvm.x86.sse2.packssdw.128";
923 return "llvm.x86.sse2.packuswb.128";
925 return "llvm.x86.sse41.packusdw";
927 return "llvm.x86.sse2.pmulh.w";
928 case OP_PMULW_HIGH_UN:
929 return "llvm.x86.sse2.pmulhu.w";
932 g_assert_not_reached ();
938 simd_op_to_llvm_type (int opcode)
940 #if defined(TARGET_X86) || defined(TARGET_AMD64)
944 return type_to_simd_type (MONO_TYPE_R8);
947 return type_to_simd_type (MONO_TYPE_I8);
950 return type_to_simd_type (MONO_TYPE_I4);
955 return type_to_simd_type (MONO_TYPE_I2);
959 return type_to_simd_type (MONO_TYPE_I1);
961 return type_to_simd_type (MONO_TYPE_R4);
964 return type_to_simd_type (MONO_TYPE_I4);
968 return type_to_simd_type (MONO_TYPE_R8);
972 return type_to_simd_type (MONO_TYPE_R4);
973 case OP_EXTRACT_MASK:
974 return type_to_simd_type (MONO_TYPE_I1);
980 return type_to_simd_type (MONO_TYPE_R4);
983 return type_to_simd_type (MONO_TYPE_R8);
985 g_assert_not_reached ();
996 * Return the LLVM basic block corresponding to BB.
998 static LLVMBasicBlockRef
999 get_bb (EmitContext *ctx, MonoBasicBlock *bb)
1001 char bb_name_buf [128];
1004 if (ctx->bblocks [bb->block_num].bblock == NULL) {
1005 if (bb->flags & BB_EXCEPTION_HANDLER) {
1006 int clause_index = (mono_get_block_region_notry (ctx->cfg, bb->region) >> 8) - 1;
1007 sprintf (bb_name_buf, "EH_CLAUSE%d_BB%d", clause_index, bb->block_num);
1008 bb_name = bb_name_buf;
1009 } else if (bb->block_num < 256) {
1010 if (!ctx->module->bb_names) {
1011 ctx->module->bb_names_len = 256;
1012 ctx->module->bb_names = g_new0 (char*, ctx->module->bb_names_len);
1014 if (!ctx->module->bb_names [bb->block_num]) {
1017 n = g_strdup_printf ("BB%d", bb->block_num);
1018 mono_memory_barrier ();
1019 ctx->module->bb_names [bb->block_num] = n;
1021 bb_name = ctx->module->bb_names [bb->block_num];
1023 sprintf (bb_name_buf, "BB%d", bb->block_num);
1024 bb_name = bb_name_buf;
1027 ctx->bblocks [bb->block_num].bblock = LLVMAppendBasicBlock (ctx->lmethod, bb_name);
1028 ctx->bblocks [bb->block_num].end_bblock = ctx->bblocks [bb->block_num].bblock;
1031 return ctx->bblocks [bb->block_num].bblock;
1037 * Return the last LLVM bblock corresponding to BB.
1038 * This might not be equal to the bb returned by get_bb () since we need to generate
1039 * multiple LLVM bblocks for a mono bblock to handle throwing exceptions.
1041 static LLVMBasicBlockRef
1042 get_end_bb (EmitContext *ctx, MonoBasicBlock *bb)
1045 return ctx->bblocks [bb->block_num].end_bblock;
1048 static LLVMBasicBlockRef
1049 gen_bb (EmitContext *ctx, const char *prefix)
1053 sprintf (bb_name, "%s%d", prefix, ++ ctx->ex_index);
1054 return LLVMAppendBasicBlock (ctx->lmethod, bb_name);
1060 * Return the target of the patch identified by TYPE and TARGET.
1063 resolve_patch (MonoCompile *cfg, MonoJumpInfoType type, gconstpointer target)
1069 memset (&ji, 0, sizeof (ji));
1071 ji.data.target = target;
1073 res = mono_resolve_patch_target (cfg->method, cfg->domain, NULL, &ji, FALSE, &error);
1074 mono_error_assert_ok (&error);
1082 * Emit code to convert the LLVM value V to DTYPE.
1085 convert_full (EmitContext *ctx, LLVMValueRef v, LLVMTypeRef dtype, gboolean is_unsigned)
1087 LLVMTypeRef stype = LLVMTypeOf (v);
1089 if (stype != dtype) {
1090 gboolean ext = FALSE;
1093 if (dtype == LLVMInt64Type () && (stype == LLVMInt32Type () || stype == LLVMInt16Type () || stype == LLVMInt8Type ()))
1095 else if (dtype == LLVMInt32Type () && (stype == LLVMInt16Type () || stype == LLVMInt8Type ()))
1097 else if (dtype == LLVMInt16Type () && (stype == LLVMInt8Type ()))
1101 return is_unsigned ? LLVMBuildZExt (ctx->builder, v, dtype, "") : LLVMBuildSExt (ctx->builder, v, dtype, "");
1103 if (dtype == LLVMDoubleType () && stype == LLVMFloatType ())
1104 return LLVMBuildFPExt (ctx->builder, v, dtype, "");
1107 if (stype == LLVMInt64Type () && (dtype == LLVMInt32Type () || dtype == LLVMInt16Type () || dtype == LLVMInt8Type ()))
1108 return LLVMBuildTrunc (ctx->builder, v, dtype, "");
1109 if (stype == LLVMInt32Type () && (dtype == LLVMInt16Type () || dtype == LLVMInt8Type ()))
1110 return LLVMBuildTrunc (ctx->builder, v, dtype, "");
1111 if (stype == LLVMInt16Type () && dtype == LLVMInt8Type ())
1112 return LLVMBuildTrunc (ctx->builder, v, dtype, "");
1113 if (stype == LLVMDoubleType () && dtype == LLVMFloatType ())
1114 return LLVMBuildFPTrunc (ctx->builder, v, dtype, "");
1116 if (LLVMGetTypeKind (stype) == LLVMPointerTypeKind && LLVMGetTypeKind (dtype) == LLVMPointerTypeKind)
1117 return LLVMBuildBitCast (ctx->builder, v, dtype, "");
1118 if (LLVMGetTypeKind (dtype) == LLVMPointerTypeKind)
1119 return LLVMBuildIntToPtr (ctx->builder, v, dtype, "");
1120 if (LLVMGetTypeKind (stype) == LLVMPointerTypeKind)
1121 return LLVMBuildPtrToInt (ctx->builder, v, dtype, "");
1123 if (mono_arch_is_soft_float ()) {
1124 if (stype == LLVMInt32Type () && dtype == LLVMFloatType ())
1125 return LLVMBuildBitCast (ctx->builder, v, dtype, "");
1126 if (stype == LLVMInt32Type () && dtype == LLVMDoubleType ())
1127 return LLVMBuildBitCast (ctx->builder, LLVMBuildZExt (ctx->builder, v, LLVMInt64Type (), ""), dtype, "");
1130 if (LLVMGetTypeKind (stype) == LLVMVectorTypeKind && LLVMGetTypeKind (dtype) == LLVMVectorTypeKind)
1131 return LLVMBuildBitCast (ctx->builder, v, dtype, "");
1134 LLVMDumpValue (LLVMConstNull (dtype));
1135 g_assert_not_reached ();
1143 convert (EmitContext *ctx, LLVMValueRef v, LLVMTypeRef dtype)
1145 return convert_full (ctx, v, dtype, FALSE);
1149 * emit_volatile_load:
1151 * If vreg is volatile, emit a load from its address.
1154 emit_volatile_load (EmitContext *ctx, int vreg)
1158 LLVMValueRef v = LLVMBuildLoad (ctx->builder, ctx->addresses [vreg], "");
1159 t = ctx->vreg_cli_types [vreg];
1160 if (t && !t->byref) {
1162 * Might have to zero extend since llvm doesn't have
1165 if (t->type == MONO_TYPE_U1 || t->type == MONO_TYPE_U2 || t->type == MONO_TYPE_CHAR || t->type == MONO_TYPE_BOOLEAN)
1166 v = LLVMBuildZExt (ctx->builder, v, LLVMInt32Type (), "");
1167 else if (t->type == MONO_TYPE_I1 || t->type == MONO_TYPE_I2)
1168 v = LLVMBuildSExt (ctx->builder, v, LLVMInt32Type (), "");
1169 else if (t->type == MONO_TYPE_U8)
1170 v = LLVMBuildZExt (ctx->builder, v, LLVMInt64Type (), "");
1177 * emit_volatile_store:
1179 * If VREG is volatile, emit a store from its value to its address.
1182 emit_volatile_store (EmitContext *ctx, int vreg)
1184 MonoInst *var = get_vreg_to_inst (ctx->cfg, vreg);
1186 if (var && var->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT)) {
1187 g_assert (ctx->addresses [vreg]);
1188 LLVMBuildStore (ctx->builder, convert (ctx, ctx->values [vreg], type_to_llvm_type (ctx, var->inst_vtype)), ctx->addresses [vreg]);
1193 sig_to_llvm_sig_no_cinfo (EmitContext *ctx, MonoMethodSignature *sig)
1195 LLVMTypeRef ret_type;
1196 LLVMTypeRef *param_types = NULL;
1201 rtype = mini_get_underlying_type (sig->ret);
1202 ret_type = type_to_llvm_type (ctx, rtype);
1206 param_types = g_new0 (LLVMTypeRef, (sig->param_count * 8) + 3);
1210 param_types [pindex ++] = ThisType ();
1211 for (i = 0; i < sig->param_count; ++i)
1212 param_types [pindex ++] = type_to_llvm_arg_type (ctx, sig->params [i]);
1214 if (!ctx_ok (ctx)) {
1215 g_free (param_types);
1219 res = LLVMFunctionType (ret_type, param_types, pindex, FALSE);
1220 g_free (param_types);
1226 * sig_to_llvm_sig_full:
1228 * Return the LLVM signature corresponding to the mono signature SIG using the
1229 * calling convention information in CINFO. Fill out the parameter mapping information in CINFO.
1232 sig_to_llvm_sig_full (EmitContext *ctx, MonoMethodSignature *sig, LLVMCallInfo *cinfo)
1234 LLVMTypeRef ret_type;
1235 LLVMTypeRef *param_types = NULL;
1237 int i, j, pindex, vret_arg_pindex = 0;
1238 gboolean vretaddr = FALSE;
1242 return sig_to_llvm_sig_no_cinfo (ctx, sig);
1244 rtype = mini_get_underlying_type (sig->ret);
1245 ret_type = type_to_llvm_type (ctx, rtype);
1249 switch (cinfo->ret.storage) {
1250 case LLVMArgVtypeInReg:
1251 /* LLVM models this by returning an aggregate value */
1252 if (cinfo->ret.pair_storage [0] == LLVMArgInIReg && cinfo->ret.pair_storage [1] == LLVMArgNone) {
1253 LLVMTypeRef members [2];
1255 members [0] = IntPtrType ();
1256 ret_type = LLVMStructType (members, 1, FALSE);
1257 } else if (cinfo->ret.pair_storage [0] == LLVMArgNone && cinfo->ret.pair_storage [1] == LLVMArgNone) {
1259 ret_type = LLVMVoidType ();
1260 } else if (cinfo->ret.pair_storage [0] == LLVMArgInIReg && cinfo->ret.pair_storage [1] == LLVMArgInIReg) {
1261 LLVMTypeRef members [2];
1263 members [0] = IntPtrType ();
1264 members [1] = IntPtrType ();
1265 ret_type = LLVMStructType (members, 2, FALSE);
1267 g_assert_not_reached ();
1270 case LLVMArgVtypeByVal:
1271 /* Vtype returned normally by val */
1273 case LLVMArgVtypeAsScalar: {
1274 int size = mono_class_value_size (mono_class_from_mono_type (rtype), NULL);
1275 /* LLVM models this by returning an int */
1276 if (size < SIZEOF_VOID_P) {
1277 g_assert (cinfo->ret.nslots == 1);
1278 ret_type = LLVMIntType (size * 8);
1280 g_assert (cinfo->ret.nslots == 1 || cinfo->ret.nslots == 2);
1281 ret_type = LLVMIntType (cinfo->ret.nslots * sizeof (mgreg_t) * 8);
1285 case LLVMArgFpStruct: {
1286 /* Vtype returned as a fp struct */
1287 LLVMTypeRef members [16];
1289 /* Have to create our own structure since we don't map fp structures to LLVM fp structures yet */
1290 for (i = 0; i < cinfo->ret.nslots; ++i)
1291 members [i] = cinfo->ret.esize == 8 ? LLVMDoubleType () : LLVMFloatType ();
1292 ret_type = LLVMStructType (members, cinfo->ret.nslots, FALSE);
1295 case LLVMArgVtypeByRef:
1296 /* Vtype returned using a hidden argument */
1297 ret_type = LLVMVoidType ();
1299 case LLVMArgVtypeRetAddr:
1300 case LLVMArgGsharedvtFixed:
1301 case LLVMArgGsharedvtFixedVtype:
1302 case LLVMArgGsharedvtVariable:
1304 ret_type = LLVMVoidType ();
1310 param_types = g_new0 (LLVMTypeRef, (sig->param_count * 8) + 3);
1312 if (cinfo->ret.storage == LLVMArgVtypeByRef) {
1314 * Has to be the first argument because of the sret argument attribute
1315 * FIXME: This might conflict with passing 'this' as the first argument, but
1316 * this is only used on arm64 which has a dedicated struct return register.
1318 cinfo->vret_arg_pindex = pindex;
1319 param_types [pindex] = type_to_llvm_arg_type (ctx, sig->ret);
1320 if (!ctx_ok (ctx)) {
1321 g_free (param_types);
1324 param_types [pindex] = LLVMPointerType (param_types [pindex], 0);
1327 if (!ctx->llvm_only && cinfo->rgctx_arg) {
1328 cinfo->rgctx_arg_pindex = pindex;
1329 param_types [pindex] = ctx->module->ptr_type;
1332 if (cinfo->imt_arg) {
1333 cinfo->imt_arg_pindex = pindex;
1334 param_types [pindex] = ctx->module->ptr_type;
1338 /* Compute the index in the LLVM signature where the vret arg needs to be passed */
1339 vret_arg_pindex = pindex;
1340 if (cinfo->vret_arg_index == 1) {
1341 /* Add the slots consumed by the first argument */
1342 LLVMArgInfo *ainfo = &cinfo->args [0];
1343 switch (ainfo->storage) {
1344 case LLVMArgVtypeInReg:
1345 for (j = 0; j < 2; ++j) {
1346 if (ainfo->pair_storage [j] == LLVMArgInIReg)
1355 cinfo->vret_arg_pindex = vret_arg_pindex;
1358 if (vretaddr && vret_arg_pindex == pindex)
1359 param_types [pindex ++] = IntPtrType ();
1361 cinfo->this_arg_pindex = pindex;
1362 param_types [pindex ++] = ThisType ();
1363 cinfo->args [0].pindex = cinfo->this_arg_pindex;
1365 if (vretaddr && vret_arg_pindex == pindex)
1366 param_types [pindex ++] = IntPtrType ();
1367 for (i = 0; i < sig->param_count; ++i) {
1368 LLVMArgInfo *ainfo = &cinfo->args [i + sig->hasthis];
1370 if (vretaddr && vret_arg_pindex == pindex)
1371 param_types [pindex ++] = IntPtrType ();
1372 ainfo->pindex = pindex;
1374 switch (ainfo->storage) {
1375 case LLVMArgVtypeInReg:
1376 for (j = 0; j < 2; ++j) {
1377 switch (ainfo->pair_storage [j]) {
1379 param_types [pindex ++] = LLVMIntType (sizeof (gpointer) * 8);
1384 g_assert_not_reached ();
1388 case LLVMArgVtypeByVal:
1389 param_types [pindex] = type_to_llvm_arg_type (ctx, ainfo->type);
1392 param_types [pindex] = LLVMPointerType (param_types [pindex], 0);
1395 case LLVMArgAsIArgs:
1396 param_types [pindex] = LLVMArrayType (IntPtrType (), ainfo->nslots);
1399 case LLVMArgVtypeByRef:
1400 param_types [pindex] = type_to_llvm_arg_type (ctx, ainfo->type);
1403 param_types [pindex] = LLVMPointerType (param_types [pindex], 0);
1406 case LLVMArgAsFpArgs: {
1409 /* Emit dummy fp arguments if needed so the rest is passed on the stack */
1410 for (j = 0; j < ainfo->ndummy_fpargs; ++j)
1411 param_types [pindex ++] = LLVMDoubleType ();
1412 for (j = 0; j < ainfo->nslots; ++j)
1413 param_types [pindex ++] = ainfo->esize == 8 ? LLVMDoubleType () : LLVMFloatType ();
1416 case LLVMArgVtypeAsScalar:
1417 g_assert_not_reached ();
1419 case LLVMArgGsharedvtFixed:
1420 case LLVMArgGsharedvtFixedVtype:
1421 param_types [pindex ++] = LLVMPointerType (type_to_llvm_arg_type (ctx, ainfo->type), 0);
1423 case LLVMArgGsharedvtVariable:
1424 param_types [pindex ++] = LLVMPointerType (IntPtrType (), 0);
1427 param_types [pindex ++] = type_to_llvm_arg_type (ctx, ainfo->type);
1431 if (!ctx_ok (ctx)) {
1432 g_free (param_types);
1435 if (vretaddr && vret_arg_pindex == pindex)
1436 param_types [pindex ++] = IntPtrType ();
1437 if (ctx->llvm_only && cinfo->rgctx_arg) {
1438 /* Pass the rgctx as the last argument */
1439 cinfo->rgctx_arg_pindex = pindex;
1440 param_types [pindex] = ctx->module->ptr_type;
1444 res = LLVMFunctionType (ret_type, param_types, pindex, FALSE);
1445 g_free (param_types);
1451 sig_to_llvm_sig (EmitContext *ctx, MonoMethodSignature *sig)
1453 return sig_to_llvm_sig_full (ctx, sig, NULL);
1457 * LLVMFunctionType1:
1459 * Create an LLVM function type from the arguments.
1461 static G_GNUC_UNUSED LLVMTypeRef
1462 LLVMFunctionType0 (LLVMTypeRef ReturnType,
1465 return LLVMFunctionType (ReturnType, NULL, 0, IsVarArg);
1469 * LLVMFunctionType1:
1471 * Create an LLVM function type from the arguments.
1473 static G_GNUC_UNUSED LLVMTypeRef
1474 LLVMFunctionType1 (LLVMTypeRef ReturnType,
1475 LLVMTypeRef ParamType1,
1478 LLVMTypeRef param_types [1];
1480 param_types [0] = ParamType1;
1482 return LLVMFunctionType (ReturnType, param_types, 1, IsVarArg);
1486 * LLVMFunctionType2:
1488 * Create an LLVM function type from the arguments.
1490 static G_GNUC_UNUSED LLVMTypeRef
1491 LLVMFunctionType2 (LLVMTypeRef ReturnType,
1492 LLVMTypeRef ParamType1,
1493 LLVMTypeRef ParamType2,
1496 LLVMTypeRef param_types [2];
1498 param_types [0] = ParamType1;
1499 param_types [1] = ParamType2;
1501 return LLVMFunctionType (ReturnType, param_types, 2, IsVarArg);
1505 * LLVMFunctionType3:
1507 * Create an LLVM function type from the arguments.
1509 static G_GNUC_UNUSED LLVMTypeRef
1510 LLVMFunctionType3 (LLVMTypeRef ReturnType,
1511 LLVMTypeRef ParamType1,
1512 LLVMTypeRef ParamType2,
1513 LLVMTypeRef ParamType3,
1516 LLVMTypeRef param_types [3];
1518 param_types [0] = ParamType1;
1519 param_types [1] = ParamType2;
1520 param_types [2] = ParamType3;
1522 return LLVMFunctionType (ReturnType, param_types, 3, IsVarArg);
1525 static G_GNUC_UNUSED LLVMTypeRef
1526 LLVMFunctionType5 (LLVMTypeRef ReturnType,
1527 LLVMTypeRef ParamType1,
1528 LLVMTypeRef ParamType2,
1529 LLVMTypeRef ParamType3,
1530 LLVMTypeRef ParamType4,
1531 LLVMTypeRef ParamType5,
1534 LLVMTypeRef param_types [5];
1536 param_types [0] = ParamType1;
1537 param_types [1] = ParamType2;
1538 param_types [2] = ParamType3;
1539 param_types [3] = ParamType4;
1540 param_types [4] = ParamType5;
1542 return LLVMFunctionType (ReturnType, param_types, 5, IsVarArg);
1548 * Create an LLVM builder and remember it so it can be freed later.
1550 static LLVMBuilderRef
1551 create_builder (EmitContext *ctx)
1553 LLVMBuilderRef builder = LLVMCreateBuilder ();
1555 ctx->builders = g_slist_prepend_mempool (ctx->cfg->mempool, ctx->builders, builder);
1561 get_aotconst_name (MonoJumpInfoType type, gconstpointer data, int got_offset)
1566 case MONO_PATCH_INFO_INTERNAL_METHOD:
1567 name = g_strdup_printf ("jit_icall_%s", data);
1569 case MONO_PATCH_INFO_RGCTX_SLOT_INDEX: {
1570 MonoJumpInfoRgctxEntry *entry = (MonoJumpInfoRgctxEntry*)data;
1571 name = g_strdup_printf ("RGCTX_SLOT_INDEX_%s", mono_rgctx_info_type_to_str (entry->info_type));
1575 name = g_strdup_printf ("%s_%d", mono_ji_type_to_string (type), got_offset);
1583 get_aotconst_typed (EmitContext *ctx, MonoJumpInfoType type, gconstpointer data, LLVMTypeRef llvm_type)
1587 LLVMValueRef indexes [2];
1589 LLVMValueRef got_entry_addr, load;
1590 LLVMBuilderRef builder = ctx->builder;
1595 ji = g_new0 (MonoJumpInfo, 1);
1597 ji->data.target = data;
1599 ji = mono_aot_patch_info_dup (ji);
1601 ji->next = cfg->patch_info;
1602 cfg->patch_info = ji;
1604 got_offset = mono_aot_get_got_offset (cfg->patch_info);
1605 ctx->module->max_got_offset = MAX (ctx->module->max_got_offset, got_offset);
1607 * If the got slot is shared, it means its initialized when the aot image is loaded, so we don't need to
1608 * explicitly initialize it.
1610 if (!mono_aot_is_shared_got_offset (got_offset)) {
1611 //mono_print_ji (ji);
1613 ctx->has_got_access = TRUE;
1616 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
1617 indexes [1] = LLVMConstInt (LLVMInt32Type (), (gssize)got_offset, FALSE);
1618 got_entry_addr = LLVMBuildGEP (builder, ctx->module->got_var, indexes, 2, "");
1620 name = get_aotconst_name (type, data, got_offset);
1622 load = LLVMBuildLoad (builder, got_entry_addr, "");
1623 load = convert (ctx, load, llvm_type);
1624 LLVMSetValueName (load, name ? name : "");
1626 load = LLVMBuildLoad (builder, got_entry_addr, name ? name : "");
1629 //set_invariant_load_flag (load);
1635 get_aotconst (EmitContext *ctx, MonoJumpInfoType type, gconstpointer data)
1637 return get_aotconst_typed (ctx, type, data, NULL);
1641 get_callee (EmitContext *ctx, LLVMTypeRef llvm_sig, MonoJumpInfoType type, gconstpointer data)
1643 LLVMValueRef callee;
1645 if (ctx->llvm_only) {
1646 callee_name = mono_aot_get_direct_call_symbol (type, data);
1648 /* Directly callable */
1650 callee = (LLVMValueRef)g_hash_table_lookup (ctx->module->direct_callables, callee_name);
1652 callee = LLVMAddFunction (ctx->lmodule, callee_name, llvm_sig);
1654 LLVMSetVisibility (callee, LLVMHiddenVisibility);
1656 g_hash_table_insert (ctx->module->direct_callables, (char*)callee_name, callee);
1658 /* LLVMTypeRef's are uniqued */
1659 if (LLVMGetElementType (LLVMTypeOf (callee)) != llvm_sig)
1660 return LLVMConstBitCast (callee, LLVMPointerType (llvm_sig, 0));
1662 g_free (callee_name);
1668 * Calls are made through the GOT.
1670 return get_aotconst_typed (ctx, type, data, LLVMPointerType (llvm_sig, 0));
1672 MonoJumpInfo *ji = NULL;
1674 callee_name = mono_aot_get_plt_symbol (type, data);
1678 if (ctx->cfg->compile_aot)
1679 /* Add a patch so referenced wrappers can be compiled in full aot mode */
1680 mono_add_patch_info (ctx->cfg, 0, type, data);
1683 callee = (LLVMValueRef)g_hash_table_lookup (ctx->module->plt_entries, callee_name);
1685 callee = LLVMAddFunction (ctx->lmodule, callee_name, llvm_sig);
1687 LLVMSetVisibility (callee, LLVMHiddenVisibility);
1689 g_hash_table_insert (ctx->module->plt_entries, (char*)callee_name, callee);
1692 if (ctx->cfg->compile_aot) {
1693 ji = g_new0 (MonoJumpInfo, 1);
1695 ji->data.target = data;
1697 g_hash_table_insert (ctx->module->plt_entries_ji, ji, callee);
1705 emit_jit_callee (EmitContext *ctx, const char *name, LLVMTypeRef llvm_sig, gpointer target)
1707 #if LLVM_API_VERSION > 100
1708 LLVMValueRef tramp_var = LLVMAddGlobal (ctx->lmodule, LLVMPointerType (llvm_sig, 0), name);
1709 LLVMSetInitializer (tramp_var, LLVMConstIntToPtr (LLVMConstInt (LLVMInt64Type (), (guint64)(size_t)target, FALSE), LLVMPointerType (llvm_sig, 0)));
1710 LLVMSetLinkage (tramp_var, LLVMExternalLinkage);
1711 LLVMValueRef callee = LLVMBuildLoad (ctx->builder, tramp_var, "");
1714 LLVMValueRef callee = LLVMAddFunction (ctx->lmodule, "", llvm_sig);
1715 LLVMAddGlobalMapping (ctx->module->ee, callee, target);
1721 get_handler_clause (MonoCompile *cfg, MonoBasicBlock *bb)
1723 MonoMethodHeader *header = cfg->header;
1724 MonoExceptionClause *clause;
1728 if (bb->region != -1 && MONO_BBLOCK_IS_IN_REGION (bb, MONO_REGION_TRY))
1729 return (bb->region >> 8) - 1;
1732 for (i = 0; i < header->num_clauses; ++i) {
1733 clause = &header->clauses [i];
1735 if (MONO_OFFSET_IN_CLAUSE (clause, bb->real_offset) && clause->flags == MONO_EXCEPTION_CLAUSE_NONE)
1742 static MonoExceptionClause *
1743 get_most_deep_clause (MonoCompile *cfg, EmitContext *ctx, MonoBasicBlock *bb)
1745 // Since they're sorted by nesting we just need
1746 // the first one that the bb is a member of
1747 for (int i = 0; i < cfg->header->num_clauses; i++) {
1748 MonoExceptionClause *curr = &cfg->header->clauses [i];
1750 if (MONO_OFFSET_IN_CLAUSE (curr, bb->real_offset))
1758 set_metadata_flag (LLVMValueRef v, const char *flag_name)
1760 LLVMValueRef md_arg;
1763 md_kind = LLVMGetMDKindID (flag_name, strlen (flag_name));
1764 md_arg = LLVMMDString ("mono", 4);
1765 LLVMSetMetadata (v, md_kind, LLVMMDNode (&md_arg, 1));
1769 set_invariant_load_flag (LLVMValueRef v)
1771 LLVMValueRef md_arg;
1773 const char *flag_name;
1775 // FIXME: Cache this
1776 flag_name = "invariant.load";
1777 md_kind = LLVMGetMDKindID (flag_name, strlen (flag_name));
1778 md_arg = LLVMMDString ("<index>", strlen ("<index>"));
1779 LLVMSetMetadata (v, md_kind, LLVMMDNode (&md_arg, 1));
1785 * Emit an LLVM call or invoke instruction depending on whenever the call is inside
1789 emit_call (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, LLVMValueRef callee, LLVMValueRef *args, int pindex)
1791 MonoCompile *cfg = ctx->cfg;
1792 LLVMValueRef lcall = NULL;
1793 LLVMBuilderRef builder = *builder_ref;
1794 MonoExceptionClause *clause;
1796 if (ctx->llvm_only) {
1797 clause = get_most_deep_clause (cfg, ctx, bb);
1800 g_assert (clause->flags == MONO_EXCEPTION_CLAUSE_NONE || clause->flags == MONO_EXCEPTION_CLAUSE_FINALLY);
1803 * Have to use an invoke instead of a call, branching to the
1804 * handler bblock of the clause containing this bblock.
1806 intptr_t key = CLAUSE_END(clause);
1808 LLVMBasicBlockRef lpad_bb = (LLVMBasicBlockRef)g_hash_table_lookup (ctx->exc_meta, (gconstpointer)key);
1810 // FIXME: Find the one that has the lowest end bound for the right start address
1811 // FIXME: Finally + nesting
1814 LLVMBasicBlockRef noex_bb = gen_bb (ctx, "CALL_NOEX_BB");
1817 lcall = LLVMBuildInvoke (builder, callee, args, pindex, noex_bb, lpad_bb, "");
1819 builder = ctx->builder = create_builder (ctx);
1820 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
1822 ctx->bblocks [bb->block_num].end_bblock = noex_bb;
1826 int clause_index = get_handler_clause (cfg, bb);
1828 if (clause_index != -1) {
1829 MonoMethodHeader *header = cfg->header;
1830 MonoExceptionClause *ec = &header->clauses [clause_index];
1831 MonoBasicBlock *tblock;
1832 LLVMBasicBlockRef ex_bb, noex_bb;
1835 * Have to use an invoke instead of a call, branching to the
1836 * handler bblock of the clause containing this bblock.
1839 g_assert (ec->flags == MONO_EXCEPTION_CLAUSE_NONE || ec->flags == MONO_EXCEPTION_CLAUSE_FINALLY);
1841 tblock = cfg->cil_offset_to_bb [ec->handler_offset];
1844 ctx->bblocks [tblock->block_num].invoke_target = TRUE;
1846 ex_bb = get_bb (ctx, tblock);
1848 noex_bb = gen_bb (ctx, "NOEX_BB");
1851 lcall = LLVMBuildInvoke (builder, callee, args, pindex, noex_bb, ex_bb, "");
1853 builder = ctx->builder = create_builder (ctx);
1854 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
1856 ctx->bblocks [bb->block_num].end_bblock = noex_bb;
1861 lcall = LLVMBuildCall (builder, callee, args, pindex, "");
1862 ctx->builder = builder;
1866 *builder_ref = ctx->builder;
1872 emit_load_general (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, int size, LLVMValueRef addr, const char *name, gboolean is_faulting, BarrierKind barrier)
1874 const char *intrins_name;
1875 LLVMValueRef args [16], res;
1876 LLVMTypeRef addr_type;
1877 gboolean use_intrinsics = TRUE;
1879 #if LLVM_API_VERSION > 100
1880 if (is_faulting && bb->region != -1 && !ctx->cfg->llvm_only) {
1881 /* The llvm.mono.load/store intrinsics are not supported by this llvm version, emit an explicit null check instead */
1882 LLVMValueRef cmp = LLVMBuildICmp (*builder_ref, LLVMIntEQ, addr, LLVMConstNull (LLVMTypeOf (addr)), "");
1883 emit_cond_system_exception (ctx, bb, "NullReferenceException", cmp);
1884 *builder_ref = ctx->builder;
1885 use_intrinsics = FALSE;
1889 if (is_faulting && bb->region != -1 && !ctx->cfg->llvm_only && use_intrinsics) {
1890 LLVMAtomicOrdering ordering;
1893 case LLVM_BARRIER_NONE:
1894 ordering = LLVMAtomicOrderingNotAtomic;
1896 case LLVM_BARRIER_ACQ:
1897 ordering = LLVMAtomicOrderingAcquire;
1899 case LLVM_BARRIER_SEQ:
1900 ordering = LLVMAtomicOrderingSequentiallyConsistent;
1903 g_assert_not_reached ();
1908 * We handle loads which can fault by calling a mono specific intrinsic
1909 * using an invoke, so they are handled properly inside try blocks.
1910 * We can't use this outside clauses, since LLVM optimizes intrinsics which
1911 * are marked with IntrReadArgMem.
1915 intrins_name = "llvm.mono.load.i8.p0i8";
1918 intrins_name = "llvm.mono.load.i16.p0i16";
1921 intrins_name = "llvm.mono.load.i32.p0i32";
1924 intrins_name = "llvm.mono.load.i64.p0i64";
1927 g_assert_not_reached ();
1930 addr_type = LLVMTypeOf (addr);
1931 if (addr_type == LLVMPointerType (LLVMDoubleType (), 0) || addr_type == LLVMPointerType (LLVMFloatType (), 0))
1932 addr = LLVMBuildBitCast (*builder_ref, addr, LLVMPointerType (LLVMIntType (size * 8), 0), "");
1935 args [1] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
1936 args [2] = LLVMConstInt (LLVMInt1Type (), TRUE, FALSE);
1937 args [3] = LLVMConstInt (LLVMInt32Type (), ordering, FALSE);
1938 res = emit_call (ctx, bb, builder_ref, get_intrinsic (ctx, intrins_name), args, 4);
1940 if (addr_type == LLVMPointerType (LLVMDoubleType (), 0))
1941 res = LLVMBuildBitCast (*builder_ref, res, LLVMDoubleType (), "");
1942 else if (addr_type == LLVMPointerType (LLVMFloatType (), 0))
1943 res = LLVMBuildBitCast (*builder_ref, res, LLVMFloatType (), "");
1950 * We emit volatile loads for loads which can fault, because otherwise
1951 * LLVM will generate invalid code when encountering a load from a
1954 res = mono_llvm_build_load (*builder_ref, addr, name, is_faulting, barrier);
1956 /* Mark it with a custom metadata */
1959 set_metadata_flag (res, "mono.faulting.load");
1967 emit_load (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, int size, LLVMValueRef addr, const char *name, gboolean is_faulting)
1969 return emit_load_general (ctx, bb, builder_ref, size, addr, name, is_faulting, LLVM_BARRIER_NONE);
1973 emit_store_general (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, int size, LLVMValueRef value, LLVMValueRef addr, gboolean is_faulting, BarrierKind barrier)
1975 const char *intrins_name;
1976 LLVMValueRef args [16];
1977 gboolean use_intrinsics = TRUE;
1979 #if LLVM_API_VERSION > 100
1980 if (is_faulting && bb->region != -1 && !ctx->cfg->llvm_only) {
1981 /* The llvm.mono.load/store intrinsics are not supported by this llvm version, emit an explicit null check instead */
1982 LLVMValueRef cmp = LLVMBuildICmp (*builder_ref, LLVMIntEQ, addr, LLVMConstNull (LLVMTypeOf (addr)), "");
1983 emit_cond_system_exception (ctx, bb, "NullReferenceException", cmp);
1984 *builder_ref = ctx->builder;
1985 use_intrinsics = FALSE;
1989 if (is_faulting && bb->region != -1 && !ctx->cfg->llvm_only && use_intrinsics) {
1990 LLVMAtomicOrdering ordering;
1993 case LLVM_BARRIER_NONE:
1994 ordering = LLVMAtomicOrderingNotAtomic;
1996 case LLVM_BARRIER_REL:
1997 ordering = LLVMAtomicOrderingRelease;
1999 case LLVM_BARRIER_SEQ:
2000 ordering = LLVMAtomicOrderingSequentiallyConsistent;
2003 g_assert_not_reached ();
2009 intrins_name = "llvm.mono.store.i8.p0i8";
2012 intrins_name = "llvm.mono.store.i16.p0i16";
2015 intrins_name = "llvm.mono.store.i32.p0i32";
2018 intrins_name = "llvm.mono.store.i64.p0i64";
2021 g_assert_not_reached ();
2024 if (LLVMTypeOf (value) == LLVMDoubleType () || LLVMTypeOf (value) == LLVMFloatType ()) {
2025 value = LLVMBuildBitCast (*builder_ref, value, LLVMIntType (size * 8), "");
2026 addr = LLVMBuildBitCast (*builder_ref, addr, LLVMPointerType (LLVMIntType (size * 8), 0), "");
2031 args [2] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
2032 args [3] = LLVMConstInt (LLVMInt1Type (), TRUE, FALSE);
2033 args [4] = LLVMConstInt (LLVMInt32Type (), ordering, FALSE);
2034 emit_call (ctx, bb, builder_ref, get_intrinsic (ctx, intrins_name), args, 5);
2036 mono_llvm_build_store (*builder_ref, value, addr, is_faulting, barrier);
2041 emit_store (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, int size, LLVMValueRef value, LLVMValueRef addr, gboolean is_faulting)
2043 emit_store_general (ctx, bb, builder_ref, size, value, addr, is_faulting, LLVM_BARRIER_NONE);
2047 * emit_cond_system_exception:
2049 * Emit code to throw the exception EXC_TYPE if the condition CMP is false.
2050 * Might set the ctx exception.
2053 emit_cond_system_exception (EmitContext *ctx, MonoBasicBlock *bb, const char *exc_type, LLVMValueRef cmp)
2055 LLVMBasicBlockRef ex_bb, ex2_bb = NULL, noex_bb;
2056 LLVMBuilderRef builder;
2057 MonoClass *exc_class;
2058 LLVMValueRef args [2];
2059 LLVMValueRef callee;
2060 gboolean no_pc = FALSE;
2062 if (IS_TARGET_AMD64)
2063 /* Some platforms don't require the pc argument */
2066 ex_bb = gen_bb (ctx, "EX_BB");
2068 ex2_bb = gen_bb (ctx, "EX2_BB");
2069 noex_bb = gen_bb (ctx, "NOEX_BB");
2071 LLVMBuildCondBr (ctx->builder, cmp, ex_bb, noex_bb);
2073 exc_class = mono_class_load_from_name (mono_get_corlib (), "System", exc_type);
2075 /* Emit exception throwing code */
2076 ctx->builder = builder = create_builder (ctx);
2077 LLVMPositionBuilderAtEnd (builder, ex_bb);
2079 if (ctx->cfg->llvm_only) {
2080 static LLVMTypeRef sig;
2083 sig = LLVMFunctionType1 (LLVMVoidType (), LLVMInt32Type (), FALSE);
2084 callee = get_callee (ctx, sig, MONO_PATCH_INFO_JIT_ICALL_ADDR, "mono_llvm_throw_corlib_exception");
2086 LLVMBuildBr (builder, ex2_bb);
2088 ctx->builder = builder = create_builder (ctx);
2089 LLVMPositionBuilderAtEnd (ctx->builder, ex2_bb);
2091 args [0] = LLVMConstInt (LLVMInt32Type (), exc_class->type_token - MONO_TOKEN_TYPE_DEF, FALSE);
2092 emit_call (ctx, bb, &builder, callee, args, 1);
2093 LLVMBuildUnreachable (builder);
2095 ctx->builder = builder = create_builder (ctx);
2096 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
2098 ctx->bblocks [bb->block_num].end_bblock = noex_bb;
2104 callee = ctx->module->throw_corlib_exception;
2107 const char *icall_name;
2110 sig = LLVMFunctionType1 (LLVMVoidType (), LLVMInt32Type (), FALSE);
2112 sig = LLVMFunctionType2 (LLVMVoidType (), LLVMInt32Type (), LLVMPointerType (LLVMInt8Type (), 0), FALSE);
2113 icall_name = "llvm_throw_corlib_exception_abs_trampoline";
2115 if (ctx->cfg->compile_aot) {
2116 callee = get_callee (ctx, sig, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
2119 * Differences between the LLVM/non-LLVM throw corlib exception trampoline:
2120 * - On x86, LLVM generated code doesn't push the arguments
2121 * - The trampoline takes the throw address as an arguments, not a pc offset.
2123 gpointer target = resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
2124 callee = emit_jit_callee (ctx, "llvm_throw_corlib_exception_trampoline", sig, target);
2126 #if LLVM_API_VERSION > 100
2128 * Make sure that ex_bb starts with the invoke, so the block address points to it, and not to the load
2129 * added by emit_jit_callee ().
2131 ex2_bb = gen_bb (ctx, "EX2_BB");
2132 LLVMBuildBr (builder, ex2_bb);
2135 ctx->builder = builder = create_builder (ctx);
2136 LLVMPositionBuilderAtEnd (ctx->builder, ex2_bb);
2138 mono_memory_barrier ();
2139 ctx->module->throw_corlib_exception = callee;
2144 args [0] = LLVMConstInt (LLVMInt32Type (), exc_class->type_token - MONO_TOKEN_TYPE_DEF, FALSE);
2147 * The LLVM mono branch contains changes so a block address can be passed as an
2148 * argument to a call.
2151 emit_call (ctx, bb, &builder, callee, args, 1);
2153 args [1] = LLVMBlockAddress (ctx->lmethod, ex_bb);
2154 emit_call (ctx, bb, &builder, callee, args, 2);
2157 LLVMBuildUnreachable (builder);
2159 ctx->builder = builder = create_builder (ctx);
2160 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
2162 ctx->bblocks [bb->block_num].end_bblock = noex_bb;
2169 * emit_args_to_vtype:
2171 * Emit code to store the vtype in the arguments args to the address ADDRESS.
2174 emit_args_to_vtype (EmitContext *ctx, LLVMBuilderRef builder, MonoType *t, LLVMValueRef address, LLVMArgInfo *ainfo, LLVMValueRef *args)
2176 int j, size, nslots;
2178 size = mono_class_value_size (mono_class_from_mono_type (t), NULL);
2180 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (t))) {
2181 address = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (LLVMInt8Type (), 0), "");
2184 if (ainfo->storage == LLVMArgAsFpArgs)
2185 nslots = ainfo->nslots;
2189 for (j = 0; j < nslots; ++j) {
2190 LLVMValueRef index [2], addr, daddr;
2191 int part_size = size > sizeof (gpointer) ? sizeof (gpointer) : size;
2192 LLVMTypeRef part_type;
2194 while (part_size != 1 && part_size != 2 && part_size != 4 && part_size < 8)
2197 if (ainfo->pair_storage [j] == LLVMArgNone)
2200 switch (ainfo->pair_storage [j]) {
2201 case LLVMArgInIReg: {
2202 part_type = LLVMIntType (part_size * 8);
2203 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (t))) {
2204 index [0] = LLVMConstInt (LLVMInt32Type (), j * sizeof (gpointer), FALSE);
2205 addr = LLVMBuildGEP (builder, address, index, 1, "");
2207 daddr = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (IntPtrType (), 0), "");
2208 index [0] = LLVMConstInt (LLVMInt32Type (), j, FALSE);
2209 addr = LLVMBuildGEP (builder, daddr, index, 1, "");
2211 LLVMBuildStore (builder, convert (ctx, args [j], part_type), LLVMBuildBitCast (ctx->builder, addr, LLVMPointerType (part_type, 0), ""));
2214 case LLVMArgInFPReg: {
2215 LLVMTypeRef arg_type;
2217 if (ainfo->esize == 8)
2218 arg_type = LLVMDoubleType ();
2220 arg_type = LLVMFloatType ();
2222 index [0] = LLVMConstInt (LLVMInt32Type (), j, FALSE);
2223 daddr = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (arg_type, 0), "");
2224 addr = LLVMBuildGEP (builder, daddr, index, 1, "");
2225 LLVMBuildStore (builder, args [j], addr);
2231 g_assert_not_reached ();
2234 size -= sizeof (gpointer);
2239 * emit_vtype_to_args:
2241 * Emit code to load a vtype at address ADDRESS into scalar arguments. Store the arguments
2242 * into ARGS, and the number of arguments into NARGS.
2245 emit_vtype_to_args (EmitContext *ctx, LLVMBuilderRef builder, MonoType *t, LLVMValueRef address, LLVMArgInfo *ainfo, LLVMValueRef *args, guint32 *nargs)
2248 int j, size, nslots;
2249 LLVMTypeRef arg_type;
2251 size = get_vtype_size (t);
2253 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (t)))
2254 address = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (LLVMInt8Type (), 0), "");
2256 if (ainfo->storage == LLVMArgAsFpArgs)
2257 nslots = ainfo->nslots;
2260 for (j = 0; j < nslots; ++j) {
2261 LLVMValueRef index [2], addr, daddr;
2262 int partsize = size > sizeof (gpointer) ? sizeof (gpointer) : size;
2264 if (ainfo->pair_storage [j] == LLVMArgNone)
2267 switch (ainfo->pair_storage [j]) {
2269 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (t))) {
2270 index [0] = LLVMConstInt (LLVMInt32Type (), j * sizeof (gpointer), FALSE);
2271 addr = LLVMBuildGEP (builder, address, index, 1, "");
2273 daddr = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (IntPtrType (), 0), "");
2274 index [0] = LLVMConstInt (LLVMInt32Type (), j, FALSE);
2275 addr = LLVMBuildGEP (builder, daddr, index, 1, "");
2277 args [pindex ++] = convert (ctx, LLVMBuildLoad (builder, LLVMBuildBitCast (ctx->builder, addr, LLVMPointerType (LLVMIntType (partsize * 8), 0), ""), ""), IntPtrType ());
2279 case LLVMArgInFPReg:
2280 if (ainfo->esize == 8)
2281 arg_type = LLVMDoubleType ();
2283 arg_type = LLVMFloatType ();
2284 daddr = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (arg_type, 0), "");
2285 index [0] = LLVMConstInt (LLVMInt32Type (), j, FALSE);
2286 addr = LLVMBuildGEP (builder, daddr, index, 1, "");
2287 args [pindex ++] = LLVMBuildLoad (builder, addr, "");
2292 g_assert_not_reached ();
2294 size -= sizeof (gpointer);
2301 build_alloca_llvm_type_name (EmitContext *ctx, LLVMTypeRef t, int align, const char *name)
2304 * Have to place all alloca's at the end of the entry bb, since otherwise they would
2305 * get executed every time control reaches them.
2307 LLVMPositionBuilder (ctx->alloca_builder, get_bb (ctx, ctx->cfg->bb_entry), ctx->last_alloca);
2309 ctx->last_alloca = mono_llvm_build_alloca (ctx->alloca_builder, t, NULL, align, name);
2310 return ctx->last_alloca;
2314 build_alloca_llvm_type (EmitContext *ctx, LLVMTypeRef t, int align)
2316 return build_alloca_llvm_type_name (ctx, t, align, "");
2320 build_alloca (EmitContext *ctx, MonoType *t)
2322 MonoClass *k = mono_class_from_mono_type (t);
2325 g_assert (!mini_is_gsharedvt_variable_type (t));
2327 if (MONO_CLASS_IS_SIMD (ctx->cfg, k))
2330 align = mono_class_min_align (k);
2332 /* Sometimes align is not a power of 2 */
2333 while (mono_is_power_of_two (align) == -1)
2336 return build_alloca_llvm_type (ctx, type_to_llvm_type (ctx, t), align);
2340 emit_gsharedvt_ldaddr (EmitContext *ctx, int vreg)
2344 * Compute the address of the local as gsharedvt_locals_var + gsharedvt_info_var->locals_offsets [idx].
2346 MonoCompile *cfg = ctx->cfg;
2347 LLVMBuilderRef builder = ctx->builder;
2348 LLVMValueRef offset, offset_var;
2349 LLVMValueRef info_var = ctx->values [cfg->gsharedvt_info_var->dreg];
2350 LLVMValueRef locals_var = ctx->values [cfg->gsharedvt_locals_var->dreg];
2354 g_assert (info_var);
2355 g_assert (locals_var);
2357 int idx = cfg->gsharedvt_vreg_to_idx [vreg] - 1;
2359 offset = LLVMConstInt (LLVMInt32Type (), MONO_STRUCT_OFFSET (MonoGSharedVtMethodRuntimeInfo, entries) + (idx * sizeof (gpointer)), FALSE);
2360 ptr = LLVMBuildAdd (builder, convert (ctx, info_var, IntPtrType ()), convert (ctx, offset, IntPtrType ()), "");
2362 name = g_strdup_printf ("gsharedvt_local_%d_offset", vreg);
2363 offset_var = LLVMBuildLoad (builder, convert (ctx, ptr, LLVMPointerType (LLVMInt32Type (), 0)), name);
2365 return LLVMBuildAdd (builder, convert (ctx, locals_var, IntPtrType ()), convert (ctx, offset_var, IntPtrType ()), "");
2369 * Put the global into the 'llvm.used' array to prevent it from being optimized away.
2372 mark_as_used (MonoLLVMModule *module, LLVMValueRef global)
2375 module->used = g_ptr_array_sized_new (16);
2376 g_ptr_array_add (module->used, global);
2380 emit_llvm_used (MonoLLVMModule *module)
2382 LLVMModuleRef lmodule = module->lmodule;
2383 LLVMTypeRef used_type;
2384 LLVMValueRef used, *used_elem;
2390 used_type = LLVMArrayType (LLVMPointerType (LLVMInt8Type (), 0), module->used->len);
2391 used = LLVMAddGlobal (lmodule, used_type, "llvm.used");
2392 used_elem = g_new0 (LLVMValueRef, module->used->len);
2393 for (i = 0; i < module->used->len; ++i)
2394 used_elem [i] = LLVMConstBitCast ((LLVMValueRef)g_ptr_array_index (module->used, i), LLVMPointerType (LLVMInt8Type (), 0));
2395 LLVMSetInitializer (used, LLVMConstArray (LLVMPointerType (LLVMInt8Type (), 0), used_elem, module->used->len));
2396 LLVMSetLinkage (used, LLVMAppendingLinkage);
2397 LLVMSetSection (used, "llvm.metadata");
2403 * Emit a function mapping method indexes to their code
2406 emit_get_method (MonoLLVMModule *module)
2408 LLVMModuleRef lmodule = module->lmodule;
2409 LLVMValueRef func, switch_ins, m;
2410 LLVMBasicBlockRef entry_bb, fail_bb, bb, code_start_bb, code_end_bb;
2411 LLVMBasicBlockRef *bbs;
2413 LLVMBuilderRef builder;
2418 * Emit a switch statement. Emitting a table of function addresses is smaller/faster,
2419 * but generating code seems safer.
2421 rtype = LLVMPointerType (LLVMInt8Type (), 0);
2422 func = LLVMAddFunction (lmodule, module->get_method_symbol, LLVMFunctionType1 (rtype, LLVMInt32Type (), FALSE));
2423 LLVMSetLinkage (func, LLVMExternalLinkage);
2424 LLVMSetVisibility (func, LLVMHiddenVisibility);
2425 LLVMAddFunctionAttr (func, LLVMNoUnwindAttribute);
2426 module->get_method = func;
2428 entry_bb = LLVMAppendBasicBlock (func, "ENTRY");
2431 * Return llvm_code_start/llvm_code_end when called with -1/-2.
2432 * Hopefully, the toolchain doesn't reorder these functions. If it does,
2433 * then we will have to find another solution.
2436 name = g_strdup_printf ("BB_CODE_START");
2437 code_start_bb = LLVMAppendBasicBlock (func, name);
2439 builder = LLVMCreateBuilder ();
2440 LLVMPositionBuilderAtEnd (builder, code_start_bb);
2441 LLVMBuildRet (builder, LLVMBuildBitCast (builder, module->code_start, rtype, ""));
2443 name = g_strdup_printf ("BB_CODE_END");
2444 code_end_bb = LLVMAppendBasicBlock (func, name);
2446 builder = LLVMCreateBuilder ();
2447 LLVMPositionBuilderAtEnd (builder, code_end_bb);
2448 LLVMBuildRet (builder, LLVMBuildBitCast (builder, module->code_end, rtype, ""));
2450 bbs = g_new0 (LLVMBasicBlockRef, module->max_method_idx + 1);
2451 for (i = 0; i < module->max_method_idx + 1; ++i) {
2452 name = g_strdup_printf ("BB_%d", i);
2453 bb = LLVMAppendBasicBlock (func, name);
2457 builder = LLVMCreateBuilder ();
2458 LLVMPositionBuilderAtEnd (builder, bb);
2460 m = (LLVMValueRef)g_hash_table_lookup (module->idx_to_lmethod, GINT_TO_POINTER (i));
2462 LLVMBuildRet (builder, LLVMBuildBitCast (builder, m, rtype, ""));
2464 LLVMBuildRet (builder, LLVMConstNull (rtype));
2467 fail_bb = LLVMAppendBasicBlock (func, "FAIL");
2468 builder = LLVMCreateBuilder ();
2469 LLVMPositionBuilderAtEnd (builder, fail_bb);
2470 LLVMBuildRet (builder, LLVMConstNull (rtype));
2472 builder = LLVMCreateBuilder ();
2473 LLVMPositionBuilderAtEnd (builder, entry_bb);
2475 switch_ins = LLVMBuildSwitch (builder, LLVMGetParam (func, 0), fail_bb, 0);
2476 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), -1, FALSE), code_start_bb);
2477 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), -2, FALSE), code_end_bb);
2478 for (i = 0; i < module->max_method_idx + 1; ++i) {
2479 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), i, FALSE), bbs [i]);
2482 mark_as_used (module, func);
2486 * emit_get_unbox_tramp:
2488 * Emit a function mapping method indexes to their unbox trampoline
2491 emit_get_unbox_tramp (MonoLLVMModule *module)
2493 LLVMModuleRef lmodule = module->lmodule;
2494 LLVMValueRef func, switch_ins, m;
2495 LLVMBasicBlockRef entry_bb, fail_bb, bb;
2496 LLVMBasicBlockRef *bbs;
2498 LLVMBuilderRef builder;
2502 /* Similar to emit_get_method () */
2504 rtype = LLVMPointerType (LLVMInt8Type (), 0);
2505 func = LLVMAddFunction (lmodule, module->get_unbox_tramp_symbol, LLVMFunctionType1 (rtype, LLVMInt32Type (), FALSE));
2506 LLVMSetLinkage (func, LLVMExternalLinkage);
2507 LLVMSetVisibility (func, LLVMHiddenVisibility);
2508 LLVMAddFunctionAttr (func, LLVMNoUnwindAttribute);
2509 module->get_unbox_tramp = func;
2511 entry_bb = LLVMAppendBasicBlock (func, "ENTRY");
2513 bbs = g_new0 (LLVMBasicBlockRef, module->max_method_idx + 1);
2514 for (i = 0; i < module->max_method_idx + 1; ++i) {
2515 m = (LLVMValueRef)g_hash_table_lookup (module->idx_to_unbox_tramp, GINT_TO_POINTER (i));
2519 name = g_strdup_printf ("BB_%d", i);
2520 bb = LLVMAppendBasicBlock (func, name);
2524 builder = LLVMCreateBuilder ();
2525 LLVMPositionBuilderAtEnd (builder, bb);
2527 LLVMBuildRet (builder, LLVMBuildBitCast (builder, m, rtype, ""));
2530 fail_bb = LLVMAppendBasicBlock (func, "FAIL");
2531 builder = LLVMCreateBuilder ();
2532 LLVMPositionBuilderAtEnd (builder, fail_bb);
2533 LLVMBuildRet (builder, LLVMConstNull (rtype));
2535 builder = LLVMCreateBuilder ();
2536 LLVMPositionBuilderAtEnd (builder, entry_bb);
2538 switch_ins = LLVMBuildSwitch (builder, LLVMGetParam (func, 0), fail_bb, 0);
2539 for (i = 0; i < module->max_method_idx + 1; ++i) {
2540 m = (LLVMValueRef)g_hash_table_lookup (module->idx_to_unbox_tramp, GINT_TO_POINTER (i));
2544 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), i, FALSE), bbs [i]);
2547 mark_as_used (module, func);
2550 /* Add a function to mark the beginning of LLVM code */
2552 emit_llvm_code_start (MonoLLVMModule *module)
2554 LLVMModuleRef lmodule = module->lmodule;
2556 LLVMBasicBlockRef entry_bb;
2557 LLVMBuilderRef builder;
2559 func = LLVMAddFunction (lmodule, "llvm_code_start", LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE));
2560 LLVMSetLinkage (func, LLVMInternalLinkage);
2561 LLVMAddFunctionAttr (func, LLVMNoUnwindAttribute);
2562 module->code_start = func;
2563 entry_bb = LLVMAppendBasicBlock (func, "ENTRY");
2564 builder = LLVMCreateBuilder ();
2565 LLVMPositionBuilderAtEnd (builder, entry_bb);
2566 LLVMBuildRetVoid (builder);
2570 emit_init_icall_wrapper (MonoLLVMModule *module, const char *name, const char *icall_name, int subtype)
2572 LLVMModuleRef lmodule = module->lmodule;
2573 LLVMValueRef func, indexes [2], got_entry_addr, args [16], callee;
2574 LLVMBasicBlockRef entry_bb;
2575 LLVMBuilderRef builder;
2582 func = LLVMAddFunction (lmodule, name, LLVMFunctionType1 (LLVMVoidType (), LLVMInt32Type (), FALSE));
2583 sig = LLVMFunctionType2 (LLVMVoidType (), IntPtrType (), LLVMInt32Type (), FALSE);
2588 func = LLVMAddFunction (lmodule, name, LLVMFunctionType2 (LLVMVoidType (), LLVMInt32Type (), IntPtrType (), FALSE));
2589 sig = LLVMFunctionType3 (LLVMVoidType (), IntPtrType (), LLVMInt32Type (), IntPtrType (), FALSE);
2592 func = LLVMAddFunction (lmodule, name, LLVMFunctionType2 (LLVMVoidType (), LLVMInt32Type (), ObjRefType (), FALSE));
2593 sig = LLVMFunctionType3 (LLVMVoidType (), IntPtrType (), LLVMInt32Type (), ObjRefType (), FALSE);
2596 g_assert_not_reached ();
2598 LLVMSetLinkage (func, LLVMInternalLinkage);
2599 LLVMAddFunctionAttr (func, LLVMNoInlineAttribute);
2600 mono_llvm_set_preserveall_cc (func);
2601 entry_bb = LLVMAppendBasicBlock (func, "ENTRY");
2602 builder = LLVMCreateBuilder ();
2603 LLVMPositionBuilderAtEnd (builder, entry_bb);
2606 ji = g_new0 (MonoJumpInfo, 1);
2607 ji->type = MONO_PATCH_INFO_AOT_MODULE;
2608 ji = mono_aot_patch_info_dup (ji);
2609 got_offset = mono_aot_get_got_offset (ji);
2610 module->max_got_offset = MAX (module->max_got_offset, got_offset);
2611 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
2612 indexes [1] = LLVMConstInt (LLVMInt32Type (), got_offset, FALSE);
2613 got_entry_addr = LLVMBuildGEP (builder, module->got_var, indexes, 2, "");
2614 args [0] = LLVMBuildPtrToInt (builder, LLVMBuildLoad (builder, got_entry_addr, ""), IntPtrType (), "");
2615 args [1] = LLVMGetParam (func, 0);
2617 args [2] = LLVMGetParam (func, 1);
2619 ji = g_new0 (MonoJumpInfo, 1);
2620 ji->type = MONO_PATCH_INFO_INTERNAL_METHOD;
2621 ji->data.name = icall_name;
2622 ji = mono_aot_patch_info_dup (ji);
2623 got_offset = mono_aot_get_got_offset (ji);
2624 module->max_got_offset = MAX (module->max_got_offset, got_offset);
2625 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
2626 indexes [1] = LLVMConstInt (LLVMInt32Type (), got_offset, FALSE);
2627 got_entry_addr = LLVMBuildGEP (builder, module->got_var, indexes, 2, "");
2628 callee = LLVMBuildLoad (builder, got_entry_addr, "");
2629 callee = LLVMBuildBitCast (builder, callee, LLVMPointerType (sig, 0), "");
2630 LLVMBuildCall (builder, callee, args, LLVMCountParamTypes (sig), "");
2632 // Set the inited flag
2633 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
2634 indexes [1] = LLVMGetParam (func, 0);
2635 LLVMBuildStore (builder, LLVMConstInt (LLVMInt8Type (), 1, FALSE), LLVMBuildGEP (builder, module->inited_var, indexes, 2, ""));
2637 LLVMBuildRetVoid (builder);
2639 LLVMVerifyFunction(func, LLVMAbortProcessAction);
2644 * Emit wrappers around the C icalls used to initialize llvm methods, to
2645 * make the calling code smaller and to enable usage of the llvm
2646 * PreserveAll calling convention.
2649 emit_init_icall_wrappers (MonoLLVMModule *module)
2651 module->init_method = emit_init_icall_wrapper (module, "init_method", "mono_aot_init_llvm_method", 0);
2652 module->init_method_gshared_mrgctx = emit_init_icall_wrapper (module, "init_method_gshared_mrgctx", "mono_aot_init_gshared_method_mrgctx", 1);
2653 module->init_method_gshared_this = emit_init_icall_wrapper (module, "init_method_gshared_this", "mono_aot_init_gshared_method_this", 2);
2654 module->init_method_gshared_vtable = emit_init_icall_wrapper (module, "init_method_gshared_vtable", "mono_aot_init_gshared_method_vtable", 3);
2658 emit_llvm_code_end (MonoLLVMModule *module)
2660 LLVMModuleRef lmodule = module->lmodule;
2662 LLVMBasicBlockRef entry_bb;
2663 LLVMBuilderRef builder;
2665 func = LLVMAddFunction (lmodule, "llvm_code_end", LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE));
2666 LLVMSetLinkage (func, LLVMInternalLinkage);
2667 LLVMAddFunctionAttr (func, LLVMNoUnwindAttribute);
2668 module->code_end = func;
2669 entry_bb = LLVMAppendBasicBlock (func, "ENTRY");
2670 builder = LLVMCreateBuilder ();
2671 LLVMPositionBuilderAtEnd (builder, entry_bb);
2672 LLVMBuildRetVoid (builder);
2676 emit_div_check (EmitContext *ctx, LLVMBuilderRef builder, MonoBasicBlock *bb, MonoInst *ins, LLVMValueRef lhs, LLVMValueRef rhs)
2678 gboolean need_div_check = ctx->cfg->backend->need_div_check;
2681 /* LLVM doesn't know that these can throw an exception since they are not called through an intrinsic */
2682 need_div_check = TRUE;
2684 if (!need_div_check)
2687 switch (ins->opcode) {
2700 case OP_IDIV_UN_IMM:
2701 case OP_LDIV_UN_IMM:
2702 case OP_IREM_UN_IMM:
2703 case OP_LREM_UN_IMM: {
2705 gboolean is_signed = (ins->opcode == OP_IDIV || ins->opcode == OP_LDIV || ins->opcode == OP_IREM || ins->opcode == OP_LREM ||
2706 ins->opcode == OP_IDIV_IMM || ins->opcode == OP_LDIV_IMM || ins->opcode == OP_IREM_IMM || ins->opcode == OP_LREM_IMM);
2708 cmp = LLVMBuildICmp (builder, LLVMIntEQ, rhs, LLVMConstInt (LLVMTypeOf (rhs), 0, FALSE), "");
2709 emit_cond_system_exception (ctx, bb, "DivideByZeroException", cmp);
2712 builder = ctx->builder;
2714 /* b == -1 && a == 0x80000000 */
2716 LLVMValueRef c = (LLVMTypeOf (lhs) == LLVMInt32Type ()) ? LLVMConstInt (LLVMTypeOf (lhs), 0x80000000, FALSE) : LLVMConstInt (LLVMTypeOf (lhs), 0x8000000000000000LL, FALSE);
2717 LLVMValueRef cond1 = LLVMBuildICmp (builder, LLVMIntEQ, rhs, LLVMConstInt (LLVMTypeOf (rhs), -1, FALSE), "");
2718 LLVMValueRef cond2 = LLVMBuildICmp (builder, LLVMIntEQ, lhs, c, "");
2720 cmp = LLVMBuildICmp (builder, LLVMIntEQ, LLVMBuildAnd (builder, cond1, cond2, ""), LLVMConstInt (LLVMInt1Type (), 1, FALSE), "");
2721 emit_cond_system_exception (ctx, bb, "OverflowException", cmp);
2724 builder = ctx->builder;
2736 * Emit code to initialize the GOT slots used by the method.
2739 emit_init_method (EmitContext *ctx)
2741 LLVMValueRef indexes [16], args [16], callee;
2742 LLVMValueRef inited_var, cmp, call;
2743 LLVMBasicBlockRef inited_bb, notinited_bb;
2744 LLVMBuilderRef builder = ctx->builder;
2745 MonoCompile *cfg = ctx->cfg;
2747 ctx->module->max_inited_idx = MAX (ctx->module->max_inited_idx, cfg->method_index);
2749 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
2750 indexes [1] = LLVMConstInt (LLVMInt32Type (), cfg->method_index, FALSE);
2751 inited_var = LLVMBuildLoad (builder, LLVMBuildGEP (builder, ctx->module->inited_var, indexes, 2, ""), "is_inited");
2753 args [0] = inited_var;
2754 args [1] = LLVMConstInt (LLVMInt8Type (), 1, FALSE);
2755 inited_var = LLVMBuildCall (ctx->builder, get_intrinsic (ctx, "llvm.expect.i8"), args, 2, "");
2757 cmp = LLVMBuildICmp (builder, LLVMIntEQ, inited_var, LLVMConstInt (LLVMTypeOf (inited_var), 0, FALSE), "");
2759 inited_bb = ctx->inited_bb;
2760 notinited_bb = gen_bb (ctx, "NOTINITED_BB");
2762 LLVMBuildCondBr (ctx->builder, cmp, notinited_bb, inited_bb);
2764 builder = ctx->builder = create_builder (ctx);
2765 LLVMPositionBuilderAtEnd (ctx->builder, notinited_bb);
2768 if (ctx->rgctx_arg && cfg->method->is_inflated && mono_method_get_context (cfg->method)->method_inst) {
2769 args [0] = LLVMConstInt (LLVMInt32Type (), cfg->method_index, 0);
2770 args [1] = convert (ctx, ctx->rgctx_arg, IntPtrType ());
2771 callee = ctx->module->init_method_gshared_mrgctx;
2772 call = LLVMBuildCall (builder, callee, args, 2, "");
2773 } else if (ctx->rgctx_arg) {
2774 /* A vtable is passed as the rgctx argument */
2775 args [0] = LLVMConstInt (LLVMInt32Type (), cfg->method_index, 0);
2776 args [1] = convert (ctx, ctx->rgctx_arg, IntPtrType ());
2777 callee = ctx->module->init_method_gshared_vtable;
2778 call = LLVMBuildCall (builder, callee, args, 2, "");
2779 } else if (cfg->gshared) {
2780 args [0] = LLVMConstInt (LLVMInt32Type (), cfg->method_index, 0);
2781 args [1] = convert (ctx, ctx->this_arg, ObjRefType ());
2782 callee = ctx->module->init_method_gshared_this;
2783 call = LLVMBuildCall (builder, callee, args, 2, "");
2785 args [0] = LLVMConstInt (LLVMInt32Type (), cfg->method_index, 0);
2786 callee = ctx->module->init_method;
2787 call = LLVMBuildCall (builder, callee, args, 1, "");
2791 * This enables llvm to keep arguments in their original registers/
2792 * scratch registers, since the call will not clobber them.
2794 mono_llvm_set_call_preserveall_cc (call);
2796 LLVMBuildBr (builder, inited_bb);
2797 ctx->bblocks [cfg->bb_entry->block_num].end_bblock = inited_bb;
2799 builder = ctx->builder = create_builder (ctx);
2800 LLVMPositionBuilderAtEnd (ctx->builder, inited_bb);
2804 emit_unbox_tramp (EmitContext *ctx, const char *method_name, LLVMTypeRef method_type, LLVMValueRef method, int method_index)
2807 * Emit unbox trampoline using a tail call
2809 LLVMValueRef tramp, call, *args;
2810 LLVMBuilderRef builder;
2811 LLVMBasicBlockRef lbb;
2812 LLVMCallInfo *linfo;
2816 tramp_name = g_strdup_printf ("ut_%s", method_name);
2817 tramp = LLVMAddFunction (ctx->module->lmodule, tramp_name, method_type);
2818 LLVMSetLinkage (tramp, LLVMInternalLinkage);
2819 LLVMAddFunctionAttr (tramp, LLVMOptimizeForSizeAttribute);
2820 //LLVMAddFunctionAttr (tramp, LLVMNoUnwindAttribute);
2822 // FIXME: Reduce code duplication with mono_llvm_compile_method () etc.
2823 if (!ctx->llvm_only && ctx->rgctx_arg_pindex != -1)
2824 LLVMAddAttribute (LLVMGetParam (tramp, ctx->rgctx_arg_pindex), LLVMInRegAttribute);
2825 if (ctx->cfg->vret_addr) {
2826 LLVMSetValueName (LLVMGetParam (tramp, linfo->vret_arg_pindex), "vret");
2827 if (linfo->ret.storage == LLVMArgVtypeByRef) {
2828 LLVMAddAttribute (LLVMGetParam (tramp, linfo->vret_arg_pindex), LLVMStructRetAttribute);
2829 LLVMAddAttribute (LLVMGetParam (tramp, linfo->vret_arg_pindex), LLVMNoAliasAttribute);
2833 lbb = LLVMAppendBasicBlock (tramp, "");
2834 builder = LLVMCreateBuilder ();
2835 LLVMPositionBuilderAtEnd (builder, lbb);
2837 nargs = LLVMCountParamTypes (method_type);
2838 args = g_new0 (LLVMValueRef, nargs);
2839 for (i = 0; i < nargs; ++i) {
2840 args [i] = LLVMGetParam (tramp, i);
2841 if (i == ctx->this_arg_pindex) {
2842 LLVMTypeRef arg_type = LLVMTypeOf (args [i]);
2844 args [i] = LLVMBuildPtrToInt (builder, args [i], IntPtrType (), "");
2845 args [i] = LLVMBuildAdd (builder, args [i], LLVMConstInt (IntPtrType (), sizeof (MonoObject), FALSE), "");
2846 args [i] = LLVMBuildIntToPtr (builder, args [i], arg_type, "");
2849 call = LLVMBuildCall (builder, method, args, nargs, "");
2850 if (!ctx->llvm_only && ctx->rgctx_arg_pindex != -1)
2851 LLVMAddInstrAttribute (call, 1 + ctx->rgctx_arg_pindex, LLVMInRegAttribute);
2852 if (linfo->ret.storage == LLVMArgVtypeByRef)
2853 LLVMAddInstrAttribute (call, 1 + linfo->vret_arg_pindex, LLVMStructRetAttribute);
2855 // FIXME: This causes assertions in clang
2856 //mono_llvm_set_must_tail (call);
2857 if (LLVMGetReturnType (method_type) == LLVMVoidType ())
2858 LLVMBuildRetVoid (builder);
2860 LLVMBuildRet (builder, call);
2862 g_hash_table_insert (ctx->module->idx_to_unbox_tramp, GINT_TO_POINTER (method_index), tramp);
2868 * Emit code to load/convert arguments.
2871 emit_entry_bb (EmitContext *ctx, LLVMBuilderRef builder)
2874 MonoCompile *cfg = ctx->cfg;
2875 MonoMethodSignature *sig = ctx->sig;
2876 LLVMCallInfo *linfo = ctx->linfo;
2880 LLVMBuilderRef old_builder = ctx->builder;
2881 ctx->builder = builder;
2883 ctx->alloca_builder = create_builder (ctx);
2886 * Handle indirect/volatile variables by allocating memory for them
2887 * using 'alloca', and storing their address in a temporary.
2889 for (i = 0; i < cfg->num_varinfo; ++i) {
2890 MonoInst *var = cfg->varinfo [i];
2893 if (var->opcode == OP_GSHAREDVT_LOCAL || var->opcode == OP_GSHAREDVT_ARG_REGOFFSET) {
2894 } else if (var->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT) || (mini_type_is_vtype (var->inst_vtype) && !MONO_CLASS_IS_SIMD (ctx->cfg, var->klass))) {
2895 vtype = type_to_llvm_type (ctx, var->inst_vtype);
2898 /* Could be already created by an OP_VPHI */
2899 if (!ctx->addresses [var->dreg]) {
2900 ctx->addresses [var->dreg] = build_alloca (ctx, var->inst_vtype);
2901 //LLVMSetValueName (ctx->addresses [var->dreg], g_strdup_printf ("vreg_loc_%d", var->dreg));
2903 ctx->vreg_cli_types [var->dreg] = var->inst_vtype;
2907 names = g_new (char *, sig->param_count);
2908 mono_method_get_param_names (cfg->method, (const char **) names);
2910 for (i = 0; i < sig->param_count; ++i) {
2911 LLVMArgInfo *ainfo = &linfo->args [i + sig->hasthis];
2912 int reg = cfg->args [i + sig->hasthis]->dreg;
2915 pindex = ainfo->pindex;
2917 switch (ainfo->storage) {
2918 case LLVMArgVtypeInReg:
2919 case LLVMArgAsFpArgs: {
2920 LLVMValueRef args [8];
2923 pindex += ainfo->ndummy_fpargs;
2925 /* The argument is received as a set of int/fp arguments, store them into the real argument */
2926 memset (args, 0, sizeof (args));
2927 if (ainfo->storage == LLVMArgVtypeInReg) {
2928 args [0] = LLVMGetParam (ctx->lmethod, pindex);
2929 if (ainfo->pair_storage [1] != LLVMArgNone)
2930 args [1] = LLVMGetParam (ctx->lmethod, pindex + 1);
2932 g_assert (ainfo->nslots <= 8);
2933 for (j = 0; j < ainfo->nslots; ++j)
2934 args [j] = LLVMGetParam (ctx->lmethod, pindex + j);
2936 ctx->addresses [reg] = build_alloca (ctx, ainfo->type);
2938 emit_args_to_vtype (ctx, builder, ainfo->type, ctx->addresses [reg], ainfo, args);
2940 if (ainfo->storage == LLVMArgVtypeInReg && MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (ainfo->type))) {
2941 /* Treat these as normal values */
2942 ctx->values [reg] = LLVMBuildLoad (builder, ctx->addresses [reg], "");
2946 case LLVMArgVtypeByVal: {
2947 ctx->addresses [reg] = LLVMGetParam (ctx->lmethod, pindex);
2949 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (ainfo->type))) {
2950 /* Treat these as normal values */
2951 ctx->values [reg] = LLVMBuildLoad (builder, ctx->addresses [reg], "");
2955 case LLVMArgVtypeByRef: {
2956 /* The argument is passed by ref */
2957 ctx->addresses [reg] = LLVMGetParam (ctx->lmethod, pindex);
2960 case LLVMArgAsIArgs: {
2961 LLVMValueRef arg = LLVMGetParam (ctx->lmethod, pindex);
2964 /* The argument is received as an array of ints, store it into the real argument */
2965 ctx->addresses [reg] = build_alloca (ctx, ainfo->type);
2967 size = mono_class_value_size (mono_class_from_mono_type (ainfo->type), NULL);
2968 if (size < SIZEOF_VOID_P) {
2969 /* The upper bits of the registers might not be valid */
2970 LLVMValueRef val = LLVMBuildExtractValue (builder, arg, 0, "");
2971 LLVMValueRef dest = convert (ctx, ctx->addresses [reg], LLVMPointerType (LLVMIntType (size * 8), 0));
2972 LLVMBuildStore (ctx->builder, LLVMBuildTrunc (builder, val, LLVMIntType (size * 8), ""), dest);
2974 LLVMBuildStore (ctx->builder, arg, convert (ctx, ctx->addresses [reg], LLVMPointerType (LLVMTypeOf (arg), 0)));
2978 case LLVMArgVtypeAsScalar:
2979 g_assert_not_reached ();
2981 case LLVMArgGsharedvtFixed: {
2982 /* These are non-gsharedvt arguments passed by ref, the rest of the IR treats them as scalars */
2983 LLVMValueRef arg = LLVMGetParam (ctx->lmethod, pindex);
2986 name = g_strdup_printf ("arg_%s", names [i]);
2988 name = g_strdup_printf ("arg_%d", i);
2990 ctx->values [reg] = LLVMBuildLoad (builder, convert (ctx, arg, LLVMPointerType (type_to_llvm_type (ctx, ainfo->type), 0)), name);
2993 case LLVMArgGsharedvtFixedVtype: {
2994 LLVMValueRef arg = LLVMGetParam (ctx->lmethod, pindex);
2997 name = g_strdup_printf ("vtype_arg_%s", names [i]);
2999 name = g_strdup_printf ("vtype_arg_%d", i);
3001 /* Non-gsharedvt vtype argument passed by ref, the rest of the IR treats it as a vtype */
3002 g_assert (ctx->addresses [reg]);
3003 LLVMSetValueName (ctx->addresses [reg], name);
3004 LLVMBuildStore (builder, LLVMBuildLoad (builder, convert (ctx, arg, LLVMPointerType (type_to_llvm_type (ctx, ainfo->type), 0)), ""), ctx->addresses [reg]);
3007 case LLVMArgGsharedvtVariable:
3008 /* The IR treats these as variables with addresses */
3009 ctx->addresses [reg] = LLVMGetParam (ctx->lmethod, pindex);
3012 ctx->values [reg] = convert_full (ctx, ctx->values [reg], llvm_type_to_stack_type (cfg, type_to_llvm_type (ctx, ainfo->type)), type_is_unsigned (ctx, ainfo->type));
3019 emit_volatile_store (ctx, cfg->vret_addr->dreg);
3021 emit_volatile_store (ctx, cfg->args [0]->dreg);
3022 for (i = 0; i < sig->param_count; ++i)
3023 if (!mini_type_is_vtype (sig->params [i]))
3024 emit_volatile_store (ctx, cfg->args [i + sig->hasthis]->dreg);
3026 if (sig->hasthis && !cfg->rgctx_var && cfg->gshared) {
3027 LLVMValueRef this_alloc;
3030 * The exception handling code needs the location where the this argument was
3031 * stored for gshared methods. We create a separate alloca to hold it, and mark it
3032 * with the "mono.this" custom metadata to tell llvm that it needs to save its
3033 * location into the LSDA.
3035 this_alloc = mono_llvm_build_alloca (builder, ThisType (), LLVMConstInt (LLVMInt32Type (), 1, FALSE), 0, "");
3036 /* This volatile store will keep the alloca alive */
3037 mono_llvm_build_store (builder, ctx->values [cfg->args [0]->dreg], this_alloc, TRUE, LLVM_BARRIER_NONE);
3039 set_metadata_flag (this_alloc, "mono.this");
3042 if (cfg->rgctx_var) {
3043 LLVMValueRef rgctx_alloc, store;
3046 * We handle the rgctx arg similarly to the this pointer.
3048 g_assert (ctx->addresses [cfg->rgctx_var->dreg]);
3049 rgctx_alloc = ctx->addresses [cfg->rgctx_var->dreg];
3050 /* This volatile store will keep the alloca alive */
3051 store = mono_llvm_build_store (builder, convert (ctx, ctx->rgctx_arg, IntPtrType ()), rgctx_alloc, TRUE, LLVM_BARRIER_NONE);
3053 set_metadata_flag (rgctx_alloc, "mono.this");
3056 /* Initialize the method if needed */
3057 if (cfg->compile_aot && ctx->llvm_only) {
3058 /* Emit a location for the initialization code */
3059 ctx->init_bb = gen_bb (ctx, "INIT_BB");
3060 ctx->inited_bb = gen_bb (ctx, "INITED_BB");
3062 LLVMBuildBr (ctx->builder, ctx->init_bb);
3063 builder = ctx->builder = create_builder (ctx);
3064 LLVMPositionBuilderAtEnd (ctx->builder, ctx->inited_bb);
3065 ctx->bblocks [cfg->bb_entry->block_num].end_bblock = ctx->inited_bb;
3068 /* Compute nesting between clauses */
3069 ctx->nested_in = (GSList**)mono_mempool_alloc0 (cfg->mempool, sizeof (GSList*) * cfg->header->num_clauses);
3070 for (i = 0; i < cfg->header->num_clauses; ++i) {
3071 for (j = 0; j < cfg->header->num_clauses; ++j) {
3072 MonoExceptionClause *clause1 = &cfg->header->clauses [i];
3073 MonoExceptionClause *clause2 = &cfg->header->clauses [j];
3075 if (i != j && clause1->try_offset >= clause2->try_offset && clause1->handler_offset <= clause2->handler_offset)
3076 ctx->nested_in [i] = g_slist_prepend_mempool (cfg->mempool, ctx->nested_in [i], GINT_TO_POINTER (j));
3081 * For finally clauses, create an indicator variable telling OP_ENDFINALLY whenever
3082 * it needs to continue normally, or return back to the exception handling system.
3084 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
3088 if (!(bb->region != -1 && (bb->flags & BB_EXCEPTION_HANDLER)))
3091 clause_index = MONO_REGION_CLAUSE_INDEX (bb->region);
3092 g_hash_table_insert (ctx->region_to_handler, GUINT_TO_POINTER (mono_get_block_region_notry (cfg, bb->region)), bb);
3093 g_hash_table_insert (ctx->clause_to_handler, GINT_TO_POINTER (clause_index), bb);
3095 if (bb->in_scount == 0) {
3098 sprintf (name, "finally_ind_bb%d", bb->block_num);
3099 val = LLVMBuildAlloca (builder, LLVMInt32Type (), name);
3100 LLVMBuildStore (builder, LLVMConstInt (LLVMInt32Type (), 0, FALSE), val);
3102 ctx->bblocks [bb->block_num].finally_ind = val;
3104 /* Create a variable to hold the exception var */
3106 ctx->ex_var = LLVMBuildAlloca (builder, ObjRefType (), "exvar");
3110 * Create a new bblock which CALL_HANDLER/landing pads can branch to, because branching to the
3111 * LLVM bblock containing a landing pad causes problems for the
3112 * LLVM optimizer passes.
3114 sprintf (name, "BB%d_CALL_HANDLER_TARGET", bb->block_num);
3115 ctx->bblocks [bb->block_num].call_handler_target_bb = LLVMAppendBasicBlock (ctx->lmethod, name);
3117 ctx->builder = old_builder;
3121 process_call (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, MonoInst *ins)
3123 MonoCompile *cfg = ctx->cfg;
3124 LLVMValueRef *values = ctx->values;
3125 LLVMValueRef *addresses = ctx->addresses;
3126 MonoCallInst *call = (MonoCallInst*)ins;
3127 MonoMethodSignature *sig = call->signature;
3128 LLVMValueRef callee = NULL, lcall;
3130 LLVMCallInfo *cinfo;
3134 LLVMTypeRef llvm_sig;
3136 gboolean is_virtual, calli, preserveall;
3137 LLVMBuilderRef builder = *builder_ref;
3139 if ((call->signature->call_convention != MONO_CALL_DEFAULT) && !((call->signature->call_convention == MONO_CALL_C) && ctx->llvm_only)) {
3140 set_failure (ctx, "non-default callconv");
3144 cinfo = call->cinfo;
3146 if (call->rgctx_arg_reg)
3147 cinfo->rgctx_arg = TRUE;
3148 if (call->imt_arg_reg)
3149 cinfo->imt_arg = TRUE;
3151 vretaddr = (cinfo->ret.storage == LLVMArgVtypeRetAddr || cinfo->ret.storage == LLVMArgVtypeByRef || cinfo->ret.storage == LLVMArgGsharedvtFixed || cinfo->ret.storage == LLVMArgGsharedvtVariable || cinfo->ret.storage == LLVMArgGsharedvtFixedVtype);
3153 llvm_sig = sig_to_llvm_sig_full (ctx, sig, cinfo);
3157 is_virtual = (ins->opcode == OP_VOIDCALL_MEMBASE || ins->opcode == OP_CALL_MEMBASE || ins->opcode == OP_VCALL_MEMBASE || ins->opcode == OP_LCALL_MEMBASE || ins->opcode == OP_FCALL_MEMBASE || ins->opcode == OP_RCALL_MEMBASE);
3158 calli = !call->fptr_is_patch && (ins->opcode == OP_VOIDCALL_REG || ins->opcode == OP_CALL_REG || ins->opcode == OP_VCALL_REG || ins->opcode == OP_LCALL_REG || ins->opcode == OP_FCALL_REG || ins->opcode == OP_RCALL_REG);
3160 preserveall = FALSE;
3162 /* FIXME: Avoid creating duplicate methods */
3164 if (ins->flags & MONO_INST_HAS_METHOD) {
3168 if (cfg->compile_aot) {
3169 callee = get_callee (ctx, llvm_sig, MONO_PATCH_INFO_METHOD, call->method);
3171 set_failure (ctx, "can't encode patch");
3174 if (cfg->llvm_only && call->method->klass->image->assembly == ctx->module->assembly) {
3176 * Collect instructions representing the callee into a hash so they can be replaced
3177 * by the llvm method for the callee if the callee turns out to be direct
3178 * callable. Currently this only requires it to not fail llvm compilation.
3180 GSList *l = (GSList*)g_hash_table_lookup (ctx->method_to_callers, call->method);
3181 l = g_slist_prepend (l, callee);
3182 g_hash_table_insert (ctx->method_to_callers, call->method, l);
3186 static int tramp_index;
3189 name = g_strdup_printf ("tramp_%d", tramp_index);
3192 #if LLVM_API_VERSION > 100
3194 * Use our trampoline infrastructure for lazy compilation instead of llvm's.
3195 * Make all calls through a global. The address of the global will be saved in
3196 * MonoJitDomainInfo.llvm_jit_callees and updated when the method it refers to is
3199 LLVMValueRef tramp_var = g_hash_table_lookup (ctx->jit_callees, call->method);
3202 mono_create_jit_trampoline (mono_domain_get (),
3203 call->method, &error);
3204 if (!mono_error_ok (&error))
3205 mono_error_raise_exception (&error); /* FIXME: Don't raise here */
3206 tramp_var = LLVMAddGlobal (ctx->lmodule, LLVMPointerType (llvm_sig, 0), name);
3207 LLVMSetInitializer (tramp_var, LLVMConstIntToPtr (LLVMConstInt (LLVMInt64Type (), (guint64)(size_t)target, FALSE), LLVMPointerType (llvm_sig, 0)));
3208 LLVMSetLinkage (tramp_var, LLVMExternalLinkage);
3209 g_hash_table_insert (ctx->jit_callees, call->method, tramp_var);
3211 callee = LLVMBuildLoad (builder, tramp_var, "");
3214 mono_create_jit_trampoline (mono_domain_get (),
3215 call->method, &error);
3216 if (!mono_error_ok (&error))
3217 mono_error_raise_exception (&error); /* FIXME: Don't raise here */
3219 callee = LLVMAddFunction (ctx->lmodule, name, llvm_sig);
3222 if (!mono_error_ok (&error))
3223 mono_error_raise_exception (&error); /* FIXME: Don't raise here */
3224 LLVMAddGlobalMapping (ctx->module->ee, callee, target);
3229 if (!cfg->llvm_only && call->method && strstr (call->method->klass->name, "AsyncVoidMethodBuilder")) {
3230 /* LLVM miscompiles async methods */
3231 set_failure (ctx, "#13734");
3236 MonoJitICallInfo *info = mono_find_jit_icall_by_addr (call->fptr);
3242 memset (&ji, 0, sizeof (ji));
3243 ji.type = MONO_PATCH_INFO_JIT_ICALL_ADDR;
3244 ji.data.target = info->name;
3246 target = mono_resolve_patch_target (cfg->method, cfg->domain, NULL, &ji, FALSE);
3248 if (cfg->compile_aot) {
3249 callee = get_callee (ctx, llvm_sig, MONO_PATCH_INFO_INTERNAL_METHOD, (char*)info->name);
3251 set_failure (ctx, "can't encode patch");
3255 target = (gpointer)mono_icall_get_wrapper (info);
3256 callee = emit_jit_callee (ctx, "", llvm_sig, target);
3259 if (cfg->compile_aot) {
3261 if (cfg->abs_patches) {
3262 MonoJumpInfo *abs_ji = (MonoJumpInfo*)g_hash_table_lookup (cfg->abs_patches, call->fptr);
3264 callee = get_callee (ctx, llvm_sig, abs_ji->type, abs_ji->data.target);
3266 set_failure (ctx, "can't encode patch");
3272 set_failure (ctx, "aot");
3276 #if LLVM_API_VERSION > 100
3277 if (cfg->abs_patches) {
3278 MonoJumpInfo *abs_ji = (MonoJumpInfo*)g_hash_table_lookup (cfg->abs_patches, call->fptr);
3282 target = mono_resolve_patch_target (cfg->method, cfg->domain, NULL, abs_ji, FALSE, &error);
3283 mono_error_assert_ok (&error);
3284 callee = emit_jit_callee (ctx, "", llvm_sig, target);
3286 g_assert_not_reached ();
3289 g_assert_not_reached ();
3292 callee = LLVMAddFunction (ctx->lmodule, "", llvm_sig);
3294 if (cfg->abs_patches) {
3295 MonoJumpInfo *abs_ji = (MonoJumpInfo*)g_hash_table_lookup (cfg->abs_patches, call->fptr);
3300 * FIXME: Some trampolines might have
3301 * their own calling convention on some platforms.
3303 target = mono_resolve_patch_target (cfg->method, cfg->domain, NULL, abs_ji, FALSE, &error);
3304 mono_error_assert_ok (&error);
3305 LLVMAddGlobalMapping (ctx->module->ee, callee, target);
3309 LLVMAddGlobalMapping (ctx->module->ee, callee, (gpointer)call->fptr);
3316 int size = sizeof (gpointer);
3319 g_assert (ins->inst_offset % size == 0);
3320 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
3322 callee = convert (ctx, LLVMBuildLoad (builder, LLVMBuildGEP (builder, convert (ctx, values [ins->inst_basereg], LLVMPointerType (LLVMPointerType (IntPtrType (), 0), 0)), &index, 1, ""), ""), LLVMPointerType (llvm_sig, 0));
3324 callee = convert (ctx, values [ins->sreg1], LLVMPointerType (llvm_sig, 0));
3326 if (ins->flags & MONO_INST_HAS_METHOD) {
3331 * Collect and convert arguments
3333 nargs = (sig->param_count * 16) + sig->hasthis + vretaddr + call->rgctx_reg + call->imt_arg_reg;
3334 len = sizeof (LLVMValueRef) * nargs;
3335 args = (LLVMValueRef*)alloca (len);
3336 memset (args, 0, len);
3337 l = call->out_ireg_args;
3339 if (call->rgctx_arg_reg) {
3340 g_assert (values [call->rgctx_arg_reg]);
3341 g_assert (cinfo->rgctx_arg_pindex < nargs);
3343 * On ARM, the imt/rgctx argument is passed in a caller save register, but some of our trampolines etc. clobber it, leading to
3344 * problems is LLVM moves the arg assignment earlier. To work around this, save the argument into a stack slot and load
3345 * it using a volatile load.
3348 if (!ctx->imt_rgctx_loc)
3349 ctx->imt_rgctx_loc = build_alloca_llvm_type (ctx, ctx->module->ptr_type, sizeof (gpointer));
3350 LLVMBuildStore (builder, convert (ctx, ctx->values [call->rgctx_arg_reg], ctx->module->ptr_type), ctx->imt_rgctx_loc);
3351 args [cinfo->rgctx_arg_pindex] = mono_llvm_build_load (builder, ctx->imt_rgctx_loc, "", TRUE, LLVM_BARRIER_NONE);
3353 args [cinfo->rgctx_arg_pindex] = convert (ctx, values [call->rgctx_arg_reg], ctx->module->ptr_type);
3356 if (call->imt_arg_reg) {
3357 g_assert (!ctx->llvm_only);
3358 g_assert (values [call->imt_arg_reg]);
3359 g_assert (cinfo->imt_arg_pindex < nargs);
3361 if (!ctx->imt_rgctx_loc)
3362 ctx->imt_rgctx_loc = build_alloca_llvm_type (ctx, ctx->module->ptr_type, sizeof (gpointer));
3363 LLVMBuildStore (builder, convert (ctx, ctx->values [call->imt_arg_reg], ctx->module->ptr_type), ctx->imt_rgctx_loc);
3364 args [cinfo->imt_arg_pindex] = mono_llvm_build_load (builder, ctx->imt_rgctx_loc, "", TRUE, LLVM_BARRIER_NONE);
3366 args [cinfo->imt_arg_pindex] = convert (ctx, values [call->imt_arg_reg], ctx->module->ptr_type);
3369 switch (cinfo->ret.storage) {
3370 case LLVMArgGsharedvtVariable: {
3371 MonoInst *var = get_vreg_to_inst (cfg, call->inst.dreg);
3373 if (var && var->opcode == OP_GSHAREDVT_LOCAL) {
3374 args [cinfo->vret_arg_pindex] = convert (ctx, emit_gsharedvt_ldaddr (ctx, var->dreg), IntPtrType ());
3376 g_assert (addresses [call->inst.dreg]);
3377 args [cinfo->vret_arg_pindex] = addresses [call->inst.dreg];
3383 if (!addresses [call->inst.dreg])
3384 addresses [call->inst.dreg] = build_alloca (ctx, sig->ret);
3385 g_assert (cinfo->vret_arg_pindex < nargs);
3386 if (cinfo->ret.storage == LLVMArgVtypeByRef)
3387 args [cinfo->vret_arg_pindex] = addresses [call->inst.dreg];
3389 args [cinfo->vret_arg_pindex] = LLVMBuildPtrToInt (builder, addresses [call->inst.dreg], IntPtrType (), "");
3395 * Sometimes the same method is called with two different signatures (i.e. with and without 'this'), so
3396 * use the real callee for argument type conversion.
3398 LLVMTypeRef callee_type = LLVMGetElementType (LLVMTypeOf (callee));
3399 LLVMTypeRef *param_types = (LLVMTypeRef*)g_alloca (sizeof (LLVMTypeRef) * LLVMCountParamTypes (callee_type));
3400 LLVMGetParamTypes (callee_type, param_types);
3402 for (i = 0; i < sig->param_count + sig->hasthis; ++i) {
3405 LLVMArgInfo *ainfo = &call->cinfo->args [i];
3407 pindex = ainfo->pindex;
3409 regpair = (guint32)(gssize)(l->data);
3410 reg = regpair & 0xffffff;
3411 args [pindex] = values [reg];
3412 switch (ainfo->storage) {
3413 case LLVMArgVtypeInReg:
3414 case LLVMArgAsFpArgs: {
3418 for (j = 0; j < ainfo->ndummy_fpargs; ++j)
3419 args [pindex + j] = LLVMConstNull (LLVMDoubleType ());
3420 pindex += ainfo->ndummy_fpargs;
3422 g_assert (addresses [reg]);
3423 emit_vtype_to_args (ctx, builder, ainfo->type, addresses [reg], ainfo, args + pindex, &nargs);
3427 // FIXME: Get rid of the VMOVE
3430 case LLVMArgVtypeByVal:
3431 g_assert (addresses [reg]);
3432 args [pindex] = addresses [reg];
3434 case LLVMArgVtypeByRef: {
3435 g_assert (addresses [reg]);
3436 args [pindex] = convert (ctx, addresses [reg], LLVMPointerType (type_to_llvm_arg_type (ctx, ainfo->type), 0));
3439 case LLVMArgAsIArgs:
3440 g_assert (addresses [reg]);
3441 args [pindex] = LLVMBuildLoad (ctx->builder, convert (ctx, addresses [reg], LLVMPointerType (LLVMArrayType (IntPtrType (), ainfo->nslots), 0)), "");
3443 case LLVMArgVtypeAsScalar:
3444 g_assert_not_reached ();
3446 case LLVMArgGsharedvtFixed:
3447 case LLVMArgGsharedvtFixedVtype:
3448 g_assert (addresses [reg]);
3449 args [pindex] = convert (ctx, addresses [reg], LLVMPointerType (type_to_llvm_arg_type (ctx, ainfo->type), 0));
3451 case LLVMArgGsharedvtVariable:
3452 g_assert (addresses [reg]);
3453 args [pindex] = convert (ctx, addresses [reg], LLVMPointerType (IntPtrType (), 0));
3456 g_assert (args [pindex]);
3457 if (i == 0 && sig->hasthis)
3458 args [pindex] = convert (ctx, args [pindex], param_types [pindex]);
3460 args [pindex] = convert (ctx, args [pindex], type_to_llvm_arg_type (ctx, ainfo->type));
3463 g_assert (pindex <= nargs);
3468 // FIXME: Align call sites
3474 lcall = emit_call (ctx, bb, &builder, callee, args, LLVMCountParamTypes (llvm_sig));
3477 * Modify cconv and parameter attributes to pass rgctx/imt correctly.
3479 #if defined(MONO_ARCH_IMT_REG) && defined(MONO_ARCH_RGCTX_REG)
3480 g_assert (MONO_ARCH_IMT_REG == MONO_ARCH_RGCTX_REG);
3482 /* The two can't be used together, so use only one LLVM calling conv to pass them */
3483 g_assert (!(call->rgctx_arg_reg && call->imt_arg_reg));
3484 if (!sig->pinvoke && !cfg->llvm_only)
3485 LLVMSetInstructionCallConv (lcall, LLVMMono1CallConv);
3487 mono_llvm_set_call_preserveall_cc (lcall);
3489 if (cinfo->ret.storage == LLVMArgVtypeByRef)
3490 LLVMAddInstrAttribute (lcall, 1 + cinfo->vret_arg_pindex, LLVMStructRetAttribute);
3491 if (!ctx->llvm_only && call->rgctx_arg_reg)
3492 LLVMAddInstrAttribute (lcall, 1 + cinfo->rgctx_arg_pindex, LLVMInRegAttribute);
3493 if (call->imt_arg_reg)
3494 LLVMAddInstrAttribute (lcall, 1 + cinfo->imt_arg_pindex, LLVMInRegAttribute);
3496 /* Add byval attributes if needed */
3497 for (i = 0; i < sig->param_count; ++i) {
3498 LLVMArgInfo *ainfo = &call->cinfo->args [i + sig->hasthis];
3500 if (ainfo && ainfo->storage == LLVMArgVtypeByVal)
3501 LLVMAddInstrAttribute (lcall, 1 + ainfo->pindex, LLVMByValAttribute);
3505 * Convert the result
3507 switch (cinfo->ret.storage) {
3508 case LLVMArgVtypeInReg: {
3509 LLVMValueRef regs [2];
3511 if (LLVMTypeOf (lcall) == LLVMVoidType ())
3515 if (!addresses [ins->dreg])
3516 addresses [ins->dreg] = build_alloca (ctx, sig->ret);
3518 regs [0] = LLVMBuildExtractValue (builder, lcall, 0, "");
3519 if (cinfo->ret.pair_storage [1] != LLVMArgNone)
3520 regs [1] = LLVMBuildExtractValue (builder, lcall, 1, "");
3521 emit_args_to_vtype (ctx, builder, sig->ret, addresses [ins->dreg], &cinfo->ret, regs);
3524 case LLVMArgVtypeByVal:
3525 if (!addresses [call->inst.dreg])
3526 addresses [call->inst.dreg] = build_alloca (ctx, sig->ret);
3527 LLVMBuildStore (builder, lcall, addresses [call->inst.dreg]);
3529 case LLVMArgFpStruct:
3530 if (!addresses [call->inst.dreg])
3531 addresses [call->inst.dreg] = build_alloca (ctx, sig->ret);
3532 LLVMBuildStore (builder, lcall, convert_full (ctx, addresses [call->inst.dreg], LLVMPointerType (LLVMTypeOf (lcall), 0), FALSE));
3534 case LLVMArgVtypeAsScalar:
3535 if (!addresses [call->inst.dreg])
3536 addresses [call->inst.dreg] = build_alloca (ctx, sig->ret);
3537 LLVMBuildStore (builder, lcall, convert_full (ctx, addresses [call->inst.dreg], LLVMPointerType (LLVMTypeOf (lcall), 0), FALSE));
3539 case LLVMArgVtypeRetAddr:
3540 case LLVMArgVtypeByRef:
3541 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (sig->ret))) {
3542 /* Some opcodes like STOREX_MEMBASE access these by value */
3543 g_assert (addresses [call->inst.dreg]);
3544 values [ins->dreg] = LLVMBuildLoad (builder, convert_full (ctx, addresses [call->inst.dreg], LLVMPointerType (type_to_llvm_type (ctx, sig->ret), 0), FALSE), "");
3547 case LLVMArgGsharedvtVariable:
3549 case LLVMArgGsharedvtFixed:
3550 case LLVMArgGsharedvtFixedVtype:
3551 values [ins->dreg] = LLVMBuildLoad (builder, convert_full (ctx, addresses [call->inst.dreg], LLVMPointerType (type_to_llvm_type (ctx, sig->ret), 0), FALSE), "");
3554 if (sig->ret->type != MONO_TYPE_VOID)
3555 /* If the method returns an unsigned value, need to zext it */
3556 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));
3560 *builder_ref = ctx->builder;
3564 emit_llvmonly_throw (EmitContext *ctx, MonoBasicBlock *bb, gboolean rethrow, LLVMValueRef exc)
3566 const char *icall_name = rethrow ? "mono_llvm_rethrow_exception" : "mono_llvm_throw_exception";
3567 LLVMValueRef callee = rethrow ? ctx->module->rethrow : ctx->module->throw_icall;
3569 LLVMTypeRef exc_type = type_to_llvm_type (ctx, &mono_get_exception_class ()->byval_arg);
3572 LLVMTypeRef fun_sig = LLVMFunctionType1 (LLVMVoidType (), exc_type, FALSE);
3574 if (ctx->cfg->compile_aot) {
3575 callee = get_callee (ctx, fun_sig, MONO_PATCH_INFO_JIT_ICALL_ADDR, icall_name);
3577 callee = LLVMAddFunction (ctx->lmodule, icall_name, fun_sig);
3578 LLVMAddGlobalMapping (ctx->module->ee, callee, resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name));
3579 mono_memory_barrier ();
3582 ctx->module->rethrow = callee;
3584 ctx->module->throw_icall = callee;
3588 LLVMValueRef args [2];
3590 args [0] = convert (ctx, exc, exc_type);
3591 emit_call (ctx, bb, &ctx->builder, callee, args, 1);
3593 LLVMBuildUnreachable (ctx->builder);
3595 ctx->builder = create_builder (ctx);
3599 emit_throw (EmitContext *ctx, MonoBasicBlock *bb, gboolean rethrow, LLVMValueRef exc)
3601 MonoMethodSignature *throw_sig;
3602 LLVMValueRef callee, arg;
3603 const char *icall_name;
3605 callee = rethrow ? ctx->module->rethrow : ctx->module->throw_icall;
3606 icall_name = rethrow ? "mono_arch_rethrow_exception" : "mono_arch_throw_exception";
3609 throw_sig = mono_metadata_signature_alloc (mono_get_corlib (), 1);
3610 throw_sig->ret = &mono_get_void_class ()->byval_arg;
3611 throw_sig->params [0] = &mono_get_object_class ()->byval_arg;
3612 if (ctx->cfg->compile_aot) {
3613 callee = get_callee (ctx, sig_to_llvm_sig (ctx, throw_sig), MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
3618 * LLVM doesn't push the exception argument, so we need a different
3621 target = resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, rethrow ? "llvm_rethrow_exception_trampoline" : "llvm_throw_exception_trampoline");
3623 target = resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
3625 callee = emit_jit_callee (ctx, icall_name, sig_to_llvm_sig (ctx, throw_sig), target);
3628 mono_memory_barrier ();
3629 #if LLVM_API_VERSION < 100
3631 ctx->module->rethrow = callee;
3633 ctx->module->throw_icall = callee;
3636 arg = convert (ctx, exc, type_to_llvm_type (ctx, &mono_get_object_class ()->byval_arg));
3637 emit_call (ctx, bb, &ctx->builder, callee, &arg, 1);
3641 emit_resume_eh (EmitContext *ctx, MonoBasicBlock *bb)
3643 const char *icall_name = "mono_llvm_resume_exception";
3644 LLVMValueRef callee = ctx->module->resume_eh;
3646 LLVMTypeRef fun_sig = LLVMFunctionType0 (LLVMVoidType (), FALSE);
3649 if (ctx->cfg->compile_aot) {
3650 callee = get_callee (ctx, fun_sig, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
3652 callee = LLVMAddFunction (ctx->lmodule, icall_name, fun_sig);
3653 LLVMAddGlobalMapping (ctx->module->ee, callee, resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name));
3654 mono_memory_barrier ();
3656 ctx->module->resume_eh = callee;
3660 emit_call (ctx, bb, &ctx->builder, callee, NULL, 0);
3662 LLVMBuildUnreachable (ctx->builder);
3664 ctx->builder = create_builder (ctx);
3668 mono_llvm_emit_clear_exception_call (EmitContext *ctx, LLVMBuilderRef builder)
3670 const char *icall_name = "mono_llvm_clear_exception";
3672 LLVMTypeRef call_sig = LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE);
3673 LLVMValueRef callee = NULL;
3676 if (ctx->cfg->compile_aot) {
3677 callee = get_callee (ctx, call_sig, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
3679 // FIXME: This is broken.
3680 callee = LLVMAddFunction (ctx->lmodule, icall_name, call_sig);
3684 g_assert (builder && callee);
3686 return LLVMBuildCall (builder, callee, NULL, 0, "");
3690 mono_llvm_emit_load_exception_call (EmitContext *ctx, LLVMBuilderRef builder)
3692 const char *icall_name = "mono_llvm_load_exception";
3694 LLVMTypeRef call_sig = LLVMFunctionType (ObjRefType (), NULL, 0, FALSE);
3695 LLVMValueRef callee = NULL;
3698 if (ctx->cfg->compile_aot) {
3699 callee = get_callee (ctx, call_sig, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
3701 // FIXME: This is broken.
3702 callee = LLVMAddFunction (ctx->lmodule, icall_name, call_sig);
3706 g_assert (builder && callee);
3708 return LLVMBuildCall (builder, callee, NULL, 0, icall_name);
3713 mono_llvm_emit_match_exception_call (EmitContext *ctx, LLVMBuilderRef builder, gint32 region_start, gint32 region_end)
3715 const char *icall_name = "mono_llvm_match_exception";
3717 ctx->builder = builder;
3719 const int num_args = 5;
3720 LLVMValueRef args [num_args];
3721 args [0] = convert (ctx, get_aotconst (ctx, MONO_PATCH_INFO_AOT_JIT_INFO, GINT_TO_POINTER (ctx->cfg->method_index)), IntPtrType ());
3722 args [1] = LLVMConstInt (LLVMInt32Type (), region_start, 0);
3723 args [2] = LLVMConstInt (LLVMInt32Type (), region_end, 0);
3724 if (ctx->cfg->rgctx_var) {
3725 LLVMValueRef rgctx_alloc = ctx->addresses [ctx->cfg->rgctx_var->dreg];
3726 g_assert (rgctx_alloc);
3727 args [3] = LLVMBuildLoad (builder, convert (ctx, rgctx_alloc, LLVMPointerType (IntPtrType (), 0)), "");
3729 args [3] = LLVMConstInt (IntPtrType (), 0, 0);
3732 args [4] = convert (ctx, ctx->this_arg, IntPtrType ());
3734 args [4] = LLVMConstInt (IntPtrType (), 0, 0);
3736 LLVMTypeRef match_sig = LLVMFunctionType5 (LLVMInt32Type (), IntPtrType (), LLVMInt32Type (), LLVMInt32Type (), IntPtrType (), IntPtrType (), FALSE);
3737 LLVMValueRef callee = ctx->module->match_exc;
3740 if (ctx->cfg->compile_aot) {
3741 ctx->builder = builder;
3742 // get_callee expects ctx->builder to be the emitting builder
3743 callee = get_callee (ctx, match_sig, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
3745 callee = ctx->module->match_exc = LLVMAddFunction (ctx->lmodule, icall_name, match_sig);
3746 LLVMAddGlobalMapping (ctx->module->ee, ctx->module->match_exc, resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name));
3747 ctx->module->match_exc = callee;
3748 mono_memory_barrier ();
3752 g_assert (builder && callee);
3754 g_assert (ctx->ex_var);
3756 return LLVMBuildCall (builder, callee, args, num_args, icall_name);
3759 // FIXME: This won't work because the code-finding makes this
3761 /*#define MONO_PERSONALITY_DEBUG*/
3763 #ifdef MONO_PERSONALITY_DEBUG
3764 static const gboolean use_debug_personality = TRUE;
3765 static const char *default_personality_name = "mono_debug_personality";
3767 static const gboolean use_debug_personality = FALSE;
3768 static const char *default_personality_name = "__gxx_personality_v0";
3772 default_cpp_lpad_exc_signature (void)
3774 static gboolean inited = FALSE;
3775 static LLVMTypeRef sig;
3778 LLVMTypeRef signature [2];
3779 signature [0] = LLVMPointerType (LLVMInt8Type (), 0);
3780 signature [1] = LLVMInt32Type ();
3781 sig = LLVMStructType (signature, 2, FALSE);
3789 get_mono_personality (EmitContext *ctx)
3791 LLVMValueRef personality = NULL;
3792 static gint32 mapping_inited = FALSE;
3793 LLVMTypeRef personality_type = LLVMFunctionType (LLVMInt32Type (), NULL, 0, TRUE);
3795 if (!use_debug_personality) {
3796 if (ctx->cfg->compile_aot) {
3797 personality = get_intrinsic (ctx, default_personality_name);
3798 } else if (InterlockedCompareExchange (&mapping_inited, 1, 0) == 0) {
3799 personality = LLVMAddFunction (ctx->lmodule, default_personality_name, personality_type);
3800 LLVMAddGlobalMapping (ctx->module->ee, personality, personality);
3803 if (ctx->cfg->compile_aot) {
3804 personality = get_callee (ctx, personality_type, MONO_PATCH_INFO_INTERNAL_METHOD, default_personality_name);
3806 personality = LLVMAddFunction (ctx->lmodule, default_personality_name, personality_type);
3807 LLVMAddGlobalMapping (ctx->module->ee, personality, resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, default_personality_name));
3808 mono_memory_barrier ();
3812 g_assert (personality);
3816 static LLVMBasicBlockRef
3817 emit_landing_pad (EmitContext *ctx, int group_index, int group_size)
3819 MonoCompile *cfg = ctx->cfg;
3820 LLVMBuilderRef old_builder = ctx->builder;
3821 MonoExceptionClause *group_start = cfg->header->clauses + group_index;
3823 LLVMBuilderRef lpadBuilder = create_builder (ctx);
3824 ctx->builder = lpadBuilder;
3826 MonoBasicBlock *handler_bb = cfg->cil_offset_to_bb [CLAUSE_START (group_start)];
3827 g_assert (handler_bb);
3829 // <resultval> = landingpad <somety> personality <type> <pers_fn> <clause>+
3830 LLVMValueRef personality = get_mono_personality (ctx);
3831 g_assert (personality);
3833 char *bb_name = g_strdup_printf ("LPAD%d_BB", group_index);
3834 LLVMBasicBlockRef lpad_bb = gen_bb (ctx, bb_name);
3836 LLVMPositionBuilderAtEnd (lpadBuilder, lpad_bb);
3837 LLVMValueRef landing_pad = LLVMBuildLandingPad (lpadBuilder, default_cpp_lpad_exc_signature (), personality, 0, "");
3838 g_assert (landing_pad);
3840 LLVMValueRef cast = LLVMBuildBitCast (lpadBuilder, ctx->module->sentinel_exception, LLVMPointerType (LLVMInt8Type (), 0), "int8TypeInfo");
3841 LLVMAddClause (landing_pad, cast);
3843 LLVMBasicBlockRef resume_bb = gen_bb (ctx, "RESUME_BB");
3844 LLVMBuilderRef resume_builder = create_builder (ctx);
3845 ctx->builder = resume_builder;
3846 LLVMPositionBuilderAtEnd (resume_builder, resume_bb);
3848 emit_resume_eh (ctx, handler_bb);
3851 ctx->builder = lpadBuilder;
3852 LLVMPositionBuilderAtEnd (lpadBuilder, lpad_bb);
3854 gboolean finally_only = TRUE;
3856 MonoExceptionClause *group_cursor = group_start;
3858 for (int i = 0; i < group_size; i ++) {
3859 if (!(group_cursor->flags & MONO_EXCEPTION_CLAUSE_FINALLY))
3860 finally_only = FALSE;
3866 // Handle landing pad inlining
3868 if (!finally_only) {
3869 // So at each level of the exception stack we will match the exception again.
3870 // During that match, we need to compare against the handler types for the current
3871 // protected region. We send the try start and end so that we can only check against
3872 // handlers for this lexical protected region.
3873 LLVMValueRef match = mono_llvm_emit_match_exception_call (ctx, lpadBuilder, group_start->try_offset, group_start->try_offset + group_start->try_len);
3875 // if returns -1, resume
3876 LLVMValueRef switch_ins = LLVMBuildSwitch (lpadBuilder, match, resume_bb, group_size);
3878 // else move to that target bb
3879 for (int i=0; i < group_size; i++) {
3880 MonoExceptionClause *clause = group_start + i;
3881 int clause_index = clause - cfg->header->clauses;
3882 MonoBasicBlock *handler_bb = (MonoBasicBlock*)g_hash_table_lookup (ctx->clause_to_handler, GINT_TO_POINTER (clause_index));
3883 g_assert (handler_bb);
3884 g_assert (ctx->bblocks [handler_bb->block_num].call_handler_target_bb);
3885 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), clause_index, FALSE), ctx->bblocks [handler_bb->block_num].call_handler_target_bb);
3888 int clause_index = group_start - cfg->header->clauses;
3889 MonoBasicBlock *finally_bb = (MonoBasicBlock*)g_hash_table_lookup (ctx->clause_to_handler, GINT_TO_POINTER (clause_index));
3890 g_assert (finally_bb);
3892 LLVMBuildBr (ctx->builder, ctx->bblocks [finally_bb->block_num].call_handler_target_bb);
3895 ctx->builder = old_builder;
3902 emit_llvmonly_handler_start (EmitContext *ctx, MonoBasicBlock *bb, LLVMBasicBlockRef cbb)
3904 int clause_index = MONO_REGION_CLAUSE_INDEX (bb->region);
3905 MonoExceptionClause *clause = &ctx->cfg->header->clauses [clause_index];
3907 // Make exception available to catch blocks
3908 if (!(clause->flags & MONO_EXCEPTION_CLAUSE_FINALLY)) {
3909 LLVMValueRef mono_exc = mono_llvm_emit_load_exception_call (ctx, ctx->builder);
3911 g_assert (ctx->ex_var);
3912 LLVMBuildStore (ctx->builder, LLVMBuildBitCast (ctx->builder, mono_exc, ObjRefType (), ""), ctx->ex_var);
3914 if (bb->in_scount == 1) {
3915 MonoInst *exvar = bb->in_stack [0];
3916 g_assert (!ctx->values [exvar->dreg]);
3917 g_assert (ctx->ex_var);
3918 ctx->values [exvar->dreg] = LLVMBuildLoad (ctx->builder, ctx->ex_var, "save_exception");
3919 emit_volatile_store (ctx, exvar->dreg);
3922 mono_llvm_emit_clear_exception_call (ctx, ctx->builder);
3925 LLVMBuilderRef handler_builder = create_builder (ctx);
3926 LLVMBasicBlockRef target_bb = ctx->bblocks [bb->block_num].call_handler_target_bb;
3927 LLVMPositionBuilderAtEnd (handler_builder, target_bb);
3929 // Make the handler code end with a jump to cbb
3930 LLVMBuildBr (handler_builder, cbb);
3934 emit_handler_start (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef builder)
3936 MonoCompile *cfg = ctx->cfg;
3937 LLVMValueRef *values = ctx->values;
3938 LLVMModuleRef lmodule = ctx->lmodule;
3939 BBInfo *bblocks = ctx->bblocks;
3941 LLVMValueRef personality;
3942 LLVMValueRef landing_pad;
3943 LLVMBasicBlockRef target_bb;
3945 static int ti_generator;
3947 LLVMValueRef type_info;
3951 // <resultval> = landingpad <somety> personality <type> <pers_fn> <clause>+
3953 if (cfg->compile_aot) {
3954 /* Use a dummy personality function */
3955 personality = LLVMGetNamedFunction (lmodule, "mono_personality");
3956 g_assert (personality);
3958 #if LLVM_API_VERSION > 100
3959 LLVMTypeRef personality_type = LLVMFunctionType (LLVMInt32Type (), NULL, 0, TRUE);
3960 personality = LLVMAddFunction (ctx->lmodule, "mono_personality", personality_type);
3961 LLVMAddFunctionAttr (personality, LLVMNoUnwindAttribute);
3962 LLVMBasicBlockRef entry_bb = LLVMAppendBasicBlock (personality, "ENTRY");
3963 LLVMBuilderRef builder2 = LLVMCreateBuilder ();
3964 LLVMPositionBuilderAtEnd (builder2, entry_bb);
3965 LLVMBuildRet (builder2, LLVMConstInt (LLVMInt32Type (), 0, FALSE));
3967 static gint32 mapping_inited;
3969 personality = LLVMGetNamedFunction (lmodule, "mono_personality");
3971 if (InterlockedCompareExchange (&mapping_inited, 1, 0) == 0)
3972 LLVMAddGlobalMapping (ctx->module->ee, personality, (gpointer)mono_personality);
3976 i8ptr = LLVMPointerType (LLVMInt8Type (), 0);
3978 clause_index = (mono_get_block_region_notry (cfg, bb->region) >> 8) - 1;
3981 * Create the type info
3983 sprintf (ti_name, "type_info_%d", ti_generator);
3986 if (cfg->compile_aot) {
3987 /* decode_eh_frame () in aot-runtime.c will decode this */
3988 type_info = LLVMAddGlobal (lmodule, LLVMInt32Type (), ti_name);
3989 LLVMSetInitializer (type_info, LLVMConstInt (LLVMInt32Type (), clause_index, FALSE));
3992 * These symbols are not really used, the clause_index is embedded into the EH tables generated by DwarfMonoException in LLVM.
3994 LLVMSetLinkage (type_info, LLVMInternalLinkage);
3996 #if LLVM_API_VERSION > 100
3997 type_info = LLVMAddGlobal (lmodule, LLVMInt32Type (), ti_name);
3998 LLVMSetInitializer (type_info, LLVMConstInt (LLVMInt32Type (), clause_index, FALSE));
4003 * After the cfg mempool is freed, the type info will point to stale memory,
4004 * but this is not a problem, since we decode it once in exception_cb during
4007 ti = (gint32*)mono_mempool_alloc (cfg->mempool, sizeof (gint32));
4008 *(gint32*)ti = clause_index;
4010 type_info = LLVMAddGlobal (lmodule, i8ptr, ti_name);
4012 LLVMAddGlobalMapping (ctx->module->ee, type_info, ti);
4017 LLVMTypeRef members [2], ret_type;
4019 members [0] = i8ptr;
4020 members [1] = LLVMInt32Type ();
4021 ret_type = LLVMStructType (members, 2, FALSE);
4023 landing_pad = LLVMBuildLandingPad (builder, ret_type, personality, 1, "");
4024 LLVMAddClause (landing_pad, type_info);
4026 /* Store the exception into the exvar */
4028 LLVMBuildStore (builder, convert (ctx, LLVMBuildExtractValue (builder, landing_pad, 0, "ex_obj"), ObjRefType ()), ctx->ex_var);
4032 * LLVM throw sites are associated with a one landing pad, and LLVM generated
4033 * code expects control to be transferred to this landing pad even in the
4034 * presence of nested clauses. The landing pad needs to branch to the landing
4035 * pads belonging to nested clauses based on the selector value returned by
4036 * the landing pad instruction, which is passed to the landing pad in a
4037 * register by the EH code.
4039 target_bb = bblocks [bb->block_num].call_handler_target_bb;
4040 g_assert (target_bb);
4043 * Branch to the correct landing pad
4045 LLVMValueRef ex_selector = LLVMBuildExtractValue (builder, landing_pad, 1, "ex_selector");
4046 LLVMValueRef switch_ins = LLVMBuildSwitch (builder, ex_selector, target_bb, 0);
4048 for (l = ctx->nested_in [clause_index]; l; l = l->next) {
4049 int nesting_clause_index = GPOINTER_TO_INT (l->data);
4050 MonoBasicBlock *handler_bb;
4052 handler_bb = (MonoBasicBlock*)g_hash_table_lookup (ctx->clause_to_handler, GINT_TO_POINTER (nesting_clause_index));
4053 g_assert (handler_bb);
4055 g_assert (ctx->bblocks [handler_bb->block_num].call_handler_target_bb);
4056 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), nesting_clause_index, FALSE), ctx->bblocks [handler_bb->block_num].call_handler_target_bb);
4059 /* Start a new bblock which CALL_HANDLER can branch to */
4060 target_bb = bblocks [bb->block_num].call_handler_target_bb;
4062 ctx->builder = builder = create_builder (ctx);
4063 LLVMPositionBuilderAtEnd (ctx->builder, target_bb);
4065 ctx->bblocks [bb->block_num].end_bblock = target_bb;
4067 /* Store the exception into the IL level exvar */
4068 if (bb->in_scount == 1) {
4069 g_assert (bb->in_scount == 1);
4070 exvar = bb->in_stack [0];
4072 // FIXME: This is shared with filter clauses ?
4073 g_assert (!values [exvar->dreg]);
4075 g_assert (ctx->ex_var);
4076 values [exvar->dreg] = LLVMBuildLoad (builder, ctx->ex_var, "");
4077 emit_volatile_store (ctx, exvar->dreg);
4083 process_bb (EmitContext *ctx, MonoBasicBlock *bb)
4085 MonoCompile *cfg = ctx->cfg;
4086 MonoMethodSignature *sig = ctx->sig;
4087 LLVMValueRef method = ctx->lmethod;
4088 LLVMValueRef *values = ctx->values;
4089 LLVMValueRef *addresses = ctx->addresses;
4090 LLVMCallInfo *linfo = ctx->linfo;
4091 BBInfo *bblocks = ctx->bblocks;
4093 LLVMBasicBlockRef cbb;
4094 LLVMBuilderRef builder, starting_builder;
4095 gboolean has_terminator;
4097 LLVMValueRef lhs, rhs;
4100 cbb = get_end_bb (ctx, bb);
4102 builder = create_builder (ctx);
4103 ctx->builder = builder;
4104 LLVMPositionBuilderAtEnd (builder, cbb);
4109 if (bb->flags & BB_EXCEPTION_HANDLER) {
4110 if (!ctx->llvm_only && !bblocks [bb->block_num].invoke_target) {
4111 set_failure (ctx, "handler without invokes");
4116 emit_llvmonly_handler_start (ctx, bb, cbb);
4118 emit_handler_start (ctx, bb, builder);
4121 builder = ctx->builder;
4124 has_terminator = FALSE;
4125 starting_builder = builder;
4126 for (ins = bb->code; ins; ins = ins->next) {
4127 const char *spec = LLVM_INS_INFO (ins->opcode);
4129 char dname_buf [128];
4131 emit_dbg_loc (ctx, builder, ins->cil_code);
4136 * Some steps in llc are non-linear in the size of basic blocks, see #5714.
4137 * Start a new bblock. If the llvm optimization passes merge these, we
4138 * can work around that by doing a volatile load + cond branch from
4139 * localloc-ed memory.
4141 //set_failure (ctx, "basic block too long");
4142 cbb = gen_bb (ctx, "CONT_LONG_BB");
4143 LLVMBuildBr (ctx->builder, cbb);
4144 ctx->builder = builder = create_builder (ctx);
4145 LLVMPositionBuilderAtEnd (builder, cbb);
4146 ctx->bblocks [bb->block_num].end_bblock = cbb;
4151 /* There could be instructions after a terminator, skip them */
4154 if (spec [MONO_INST_DEST] != ' ' && !MONO_IS_STORE_MEMBASE (ins)) {
4155 sprintf (dname_buf, "t%d", ins->dreg);
4159 if (spec [MONO_INST_SRC1] != ' ' && spec [MONO_INST_SRC1] != 'v') {
4160 MonoInst *var = get_vreg_to_inst (cfg, ins->sreg1);
4162 if (var && var->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT) && var->opcode != OP_GSHAREDVT_ARG_REGOFFSET) {
4163 lhs = emit_volatile_load (ctx, ins->sreg1);
4165 /* It is ok for SETRET to have an uninitialized argument */
4166 if (!values [ins->sreg1] && ins->opcode != OP_SETRET) {
4167 set_failure (ctx, "sreg1");
4170 lhs = values [ins->sreg1];
4176 if (spec [MONO_INST_SRC2] != ' ' && spec [MONO_INST_SRC2] != ' ') {
4177 MonoInst *var = get_vreg_to_inst (cfg, ins->sreg2);
4178 if (var && var->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT)) {
4179 rhs = emit_volatile_load (ctx, ins->sreg2);
4181 if (!values [ins->sreg2]) {
4182 set_failure (ctx, "sreg2");
4185 rhs = values [ins->sreg2];
4191 //mono_print_ins (ins);
4192 switch (ins->opcode) {
4195 case OP_LIVERANGE_START:
4196 case OP_LIVERANGE_END:
4199 values [ins->dreg] = LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE);
4202 #if SIZEOF_VOID_P == 4
4203 values [ins->dreg] = LLVMConstInt (LLVMInt64Type (), GET_LONG_IMM (ins), FALSE);
4205 values [ins->dreg] = LLVMConstInt (LLVMInt64Type (), (gint64)ins->inst_c0, FALSE);
4209 values [ins->dreg] = LLVMConstReal (LLVMDoubleType (), *(double*)ins->inst_p0);
4213 values [ins->dreg] = LLVMConstReal (LLVMFloatType (), *(float*)ins->inst_p0);
4215 values [ins->dreg] = LLVMConstFPExt (LLVMConstReal (LLVMFloatType (), *(float*)ins->inst_p0), LLVMDoubleType ());
4217 case OP_DUMMY_ICONST:
4218 values [ins->dreg] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
4220 case OP_DUMMY_I8CONST:
4221 values [ins->dreg] = LLVMConstInt (LLVMInt64Type (), 0, FALSE);
4223 case OP_DUMMY_R8CONST:
4224 values [ins->dreg] = LLVMConstReal (LLVMDoubleType (), 0.0f);
4227 LLVMBasicBlockRef target_bb = get_bb (ctx, ins->inst_target_bb);
4228 LLVMBuildBr (builder, target_bb);
4229 has_terminator = TRUE;
4236 LLVMBasicBlockRef new_bb;
4237 LLVMBuilderRef new_builder;
4239 // The default branch is already handled
4240 // FIXME: Handle it here
4242 /* Start new bblock */
4243 sprintf (bb_name, "SWITCH_DEFAULT_BB%d", ctx->default_index ++);
4244 new_bb = LLVMAppendBasicBlock (ctx->lmethod, bb_name);
4246 lhs = convert (ctx, lhs, LLVMInt32Type ());
4247 v = LLVMBuildSwitch (builder, lhs, new_bb, GPOINTER_TO_UINT (ins->klass));
4248 for (i = 0; i < GPOINTER_TO_UINT (ins->klass); ++i) {
4249 MonoBasicBlock *target_bb = ins->inst_many_bb [i];
4251 LLVMAddCase (v, LLVMConstInt (LLVMInt32Type (), i, FALSE), get_bb (ctx, target_bb));
4254 new_builder = create_builder (ctx);
4255 LLVMPositionBuilderAtEnd (new_builder, new_bb);
4256 LLVMBuildUnreachable (new_builder);
4258 has_terminator = TRUE;
4259 g_assert (!ins->next);
4265 switch (linfo->ret.storage) {
4266 case LLVMArgVtypeInReg: {
4267 LLVMTypeRef ret_type = LLVMGetReturnType (LLVMGetElementType (LLVMTypeOf (method)));
4268 LLVMValueRef val, addr, retval;
4271 retval = LLVMGetUndef (ret_type);
4273 if (!addresses [ins->sreg1]) {
4275 * The return type is an LLVM vector type, have to convert between it and the
4276 * real return type which is a struct type.
4278 g_assert (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (sig->ret)));
4279 /* Convert to 2xi64 first */
4280 val = LLVMBuildBitCast (builder, values [ins->sreg1], LLVMVectorType (IntPtrType (), 2), "");
4282 for (i = 0; i < 2; ++i) {
4283 if (linfo->ret.pair_storage [i] == LLVMArgInIReg) {
4284 retval = LLVMBuildInsertValue (builder, retval, LLVMBuildExtractElement (builder, val, LLVMConstInt (LLVMInt32Type (), i, FALSE), ""), i, "");
4286 g_assert (linfo->ret.pair_storage [i] == LLVMArgNone);
4290 addr = LLVMBuildBitCast (builder, addresses [ins->sreg1], LLVMPointerType (ret_type, 0), "");
4291 for (i = 0; i < 2; ++i) {
4292 if (linfo->ret.pair_storage [i] == LLVMArgInIReg) {
4293 LLVMValueRef indexes [2], part_addr;
4295 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
4296 indexes [1] = LLVMConstInt (LLVMInt32Type (), i, FALSE);
4297 part_addr = LLVMBuildGEP (builder, addr, indexes, 2, "");
4299 retval = LLVMBuildInsertValue (builder, retval, LLVMBuildLoad (builder, part_addr, ""), i, "");
4301 g_assert (linfo->ret.pair_storage [i] == LLVMArgNone);
4305 LLVMBuildRet (builder, retval);
4308 case LLVMArgVtypeAsScalar: {
4309 LLVMTypeRef ret_type = LLVMGetReturnType (LLVMGetElementType (LLVMTypeOf (method)));
4310 LLVMValueRef retval;
4312 g_assert (addresses [ins->sreg1]);
4314 retval = LLVMBuildLoad (builder, LLVMBuildBitCast (builder, addresses [ins->sreg1], LLVMPointerType (ret_type, 0), ""), "");
4315 LLVMBuildRet (builder, retval);
4318 case LLVMArgVtypeByVal: {
4319 LLVMValueRef retval;
4321 g_assert (addresses [ins->sreg1]);
4322 retval = LLVMBuildLoad (builder, addresses [ins->sreg1], "");
4323 LLVMBuildRet (builder, retval);
4326 case LLVMArgVtypeByRef: {
4327 LLVMBuildRetVoid (builder);
4330 case LLVMArgGsharedvtFixed: {
4331 LLVMTypeRef ret_type = type_to_llvm_type (ctx, sig->ret);
4332 /* The return value is in lhs, need to store to the vret argument */
4333 /* sreg1 might not be set */
4335 g_assert (cfg->vret_addr);
4336 g_assert (values [cfg->vret_addr->dreg]);
4337 LLVMBuildStore (builder, convert (ctx, lhs, ret_type), convert (ctx, values [cfg->vret_addr->dreg], LLVMPointerType (ret_type, 0)));
4339 LLVMBuildRetVoid (builder);
4342 case LLVMArgGsharedvtFixedVtype: {
4344 LLVMBuildRetVoid (builder);
4347 case LLVMArgGsharedvtVariable: {
4349 LLVMBuildRetVoid (builder);
4352 case LLVMArgVtypeRetAddr: {
4353 LLVMBuildRetVoid (builder);
4356 case LLVMArgFpStruct: {
4357 LLVMTypeRef ret_type = LLVMGetReturnType (LLVMGetElementType (LLVMTypeOf (method)));
4358 LLVMValueRef retval;
4360 g_assert (addresses [ins->sreg1]);
4361 retval = LLVMBuildLoad (builder, convert (ctx, addresses [ins->sreg1], LLVMPointerType (ret_type, 0)), "");
4362 LLVMBuildRet (builder, retval);
4366 case LLVMArgNormal: {
4367 if (!lhs || ctx->is_dead [ins->sreg1]) {
4369 * The method did not set its return value, probably because it
4370 * ends with a throw.
4373 LLVMBuildRetVoid (builder);
4375 LLVMBuildRet (builder, LLVMConstNull (type_to_llvm_type (ctx, sig->ret)));
4377 LLVMBuildRet (builder, convert (ctx, lhs, type_to_llvm_type (ctx, sig->ret)));
4379 has_terminator = TRUE;
4383 g_assert_not_reached ();
4392 case OP_ICOMPARE_IMM:
4393 case OP_LCOMPARE_IMM:
4394 case OP_COMPARE_IMM: {
4396 LLVMValueRef cmp, args [16];
4397 gboolean likely = (ins->flags & MONO_INST_LIKELY) != 0;
4399 if (ins->next->opcode == OP_NOP)
4402 if (ins->next->opcode == OP_BR)
4403 /* The comparison result is not needed */
4406 rel = mono_opcode_to_cond (ins->next->opcode);
4408 if (ins->opcode == OP_ICOMPARE_IMM) {
4409 lhs = convert (ctx, lhs, LLVMInt32Type ());
4410 rhs = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
4412 if (ins->opcode == OP_LCOMPARE_IMM) {
4413 lhs = convert (ctx, lhs, LLVMInt64Type ());
4414 rhs = LLVMConstInt (LLVMInt64Type (), GET_LONG_IMM (ins), FALSE);
4416 if (ins->opcode == OP_LCOMPARE) {
4417 lhs = convert (ctx, lhs, LLVMInt64Type ());
4418 rhs = convert (ctx, rhs, LLVMInt64Type ());
4420 if (ins->opcode == OP_ICOMPARE) {
4421 lhs = convert (ctx, lhs, LLVMInt32Type ());
4422 rhs = convert (ctx, rhs, LLVMInt32Type ());
4426 if (LLVMGetTypeKind (LLVMTypeOf (lhs)) == LLVMPointerTypeKind)
4427 rhs = convert (ctx, rhs, LLVMTypeOf (lhs));
4428 else if (LLVMGetTypeKind (LLVMTypeOf (rhs)) == LLVMPointerTypeKind)
4429 lhs = convert (ctx, lhs, LLVMTypeOf (rhs));
4432 /* We use COMPARE+SETcc/Bcc, llvm uses SETcc+br cond */
4433 if (ins->opcode == OP_FCOMPARE) {
4434 cmp = LLVMBuildFCmp (builder, fpcond_to_llvm_cond [rel], convert (ctx, lhs, LLVMDoubleType ()), convert (ctx, rhs, LLVMDoubleType ()), "");
4435 } else if (ins->opcode == OP_RCOMPARE) {
4436 cmp = LLVMBuildFCmp (builder, fpcond_to_llvm_cond [rel], convert (ctx, lhs, LLVMFloatType ()), convert (ctx, rhs, LLVMFloatType ()), "");
4437 } else if (ins->opcode == OP_COMPARE_IMM) {
4438 if (LLVMGetTypeKind (LLVMTypeOf (lhs)) == LLVMPointerTypeKind && ins->inst_imm == 0)
4439 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], lhs, LLVMConstNull (LLVMTypeOf (lhs)), "");
4441 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE), "");
4442 } else if (ins->opcode == OP_LCOMPARE_IMM) {
4443 if (SIZEOF_REGISTER == 4 && COMPILE_LLVM (cfg)) {
4444 /* The immediate is encoded in two fields */
4445 guint64 l = ((guint64)(guint32)ins->inst_offset << 32) | ((guint32)ins->inst_imm);
4446 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, LLVMInt64Type ()), LLVMConstInt (LLVMInt64Type (), l, FALSE), "");
4448 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, LLVMInt64Type ()), LLVMConstInt (LLVMInt64Type (), ins->inst_imm, FALSE), "");
4451 else if (ins->opcode == OP_COMPARE) {
4452 if (LLVMGetTypeKind (LLVMTypeOf (lhs)) == LLVMPointerTypeKind && LLVMTypeOf (lhs) == LLVMTypeOf (rhs))
4453 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], lhs, rhs, "");
4455 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, IntPtrType ()), convert (ctx, rhs, IntPtrType ()), "");
4457 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], lhs, rhs, "");
4461 args [1] = LLVMConstInt (LLVMInt1Type (), 1, FALSE);
4462 cmp = LLVMBuildCall (ctx->builder, get_intrinsic (ctx, "llvm.expect.i1"), args, 2, "");
4465 if (MONO_IS_COND_BRANCH_OP (ins->next)) {
4466 if (ins->next->inst_true_bb == ins->next->inst_false_bb) {
4468 * If the target bb contains PHI instructions, LLVM requires
4469 * two PHI entries for this bblock, while we only generate one.
4470 * So convert this to an unconditional bblock. (bxc #171).
4472 LLVMBuildBr (builder, get_bb (ctx, ins->next->inst_true_bb));
4474 LLVMBuildCondBr (builder, cmp, get_bb (ctx, ins->next->inst_true_bb), get_bb (ctx, ins->next->inst_false_bb));
4476 has_terminator = TRUE;
4477 } else if (MONO_IS_SETCC (ins->next)) {
4478 sprintf (dname_buf, "t%d", ins->next->dreg);
4480 values [ins->next->dreg] = LLVMBuildZExt (builder, cmp, LLVMInt32Type (), dname);
4482 /* Add stores for volatile variables */
4483 emit_volatile_store (ctx, ins->next->dreg);
4484 } else if (MONO_IS_COND_EXC (ins->next)) {
4485 emit_cond_system_exception (ctx, bb, (const char*)ins->next->inst_p1, cmp);
4488 builder = ctx->builder;
4490 set_failure (ctx, "next");
4508 rel = mono_opcode_to_cond (ins->opcode);
4510 cmp = LLVMBuildFCmp (builder, fpcond_to_llvm_cond [rel], convert (ctx, lhs, LLVMDoubleType ()), convert (ctx, rhs, LLVMDoubleType ()), "");
4511 values [ins->dreg] = LLVMBuildZExt (builder, cmp, LLVMInt32Type (), dname);
4522 rel = mono_opcode_to_cond (ins->opcode);
4524 cmp = LLVMBuildFCmp (builder, fpcond_to_llvm_cond [rel], convert (ctx, lhs, LLVMFloatType ()), convert (ctx, rhs, LLVMFloatType ()), "");
4525 values [ins->dreg] = LLVMBuildZExt (builder, cmp, LLVMInt32Type (), dname);
4533 gboolean empty = TRUE;
4535 /* Check that all input bblocks really branch to us */
4536 for (i = 0; i < bb->in_count; ++i) {
4537 if (bb->in_bb [i]->last_ins && bb->in_bb [i]->last_ins->opcode == OP_NOT_REACHED)
4538 ins->inst_phi_args [i + 1] = -1;
4544 /* LLVM doesn't like phi instructions with zero operands */
4545 ctx->is_dead [ins->dreg] = TRUE;
4549 /* Created earlier, insert it now */
4550 LLVMInsertIntoBuilder (builder, values [ins->dreg]);
4552 for (i = 0; i < ins->inst_phi_args [0]; i++) {
4553 int sreg1 = ins->inst_phi_args [i + 1];
4557 * Count the number of times the incoming bblock branches to us,
4558 * since llvm requires a separate entry for each.
4560 if (bb->in_bb [i]->last_ins && bb->in_bb [i]->last_ins->opcode == OP_SWITCH) {
4561 MonoInst *switch_ins = bb->in_bb [i]->last_ins;
4564 for (j = 0; j < GPOINTER_TO_UINT (switch_ins->klass); ++j) {
4565 if (switch_ins->inst_many_bb [j] == bb)
4572 /* Remember for later */
4573 for (j = 0; j < count; ++j) {
4574 PhiNode *node = (PhiNode*)mono_mempool_alloc0 (ctx->mempool, sizeof (PhiNode));
4577 node->in_bb = bb->in_bb [i];
4579 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);
4589 values [ins->dreg] = lhs;
4593 MonoInst *var = get_vreg_to_inst (cfg, ins->dreg);
4596 values [ins->dreg] = lhs;
4598 if (var && var->klass->byval_arg.type == MONO_TYPE_R4) {
4600 * This is added by the spilling pass in case of the JIT,
4601 * but we have to do it ourselves.
4603 values [ins->dreg] = convert (ctx, values [ins->dreg], LLVMFloatType ());
4607 case OP_MOVE_F_TO_I4: {
4608 values [ins->dreg] = LLVMBuildBitCast (builder, LLVMBuildFPTrunc (builder, lhs, LLVMFloatType (), ""), LLVMInt32Type (), "");
4611 case OP_MOVE_I4_TO_F: {
4612 values [ins->dreg] = LLVMBuildFPExt (builder, LLVMBuildBitCast (builder, lhs, LLVMFloatType (), ""), LLVMDoubleType (), "");
4615 case OP_MOVE_F_TO_I8: {
4616 values [ins->dreg] = LLVMBuildBitCast (builder, lhs, LLVMInt64Type (), "");
4619 case OP_MOVE_I8_TO_F: {
4620 values [ins->dreg] = LLVMBuildBitCast (builder, lhs, LLVMDoubleType (), "");
4653 lhs = convert (ctx, lhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
4654 rhs = convert (ctx, rhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
4656 emit_div_check (ctx, builder, bb, ins, lhs, rhs);
4659 builder = ctx->builder;
4661 switch (ins->opcode) {
4664 values [ins->dreg] = LLVMBuildAdd (builder, lhs, rhs, dname);
4668 values [ins->dreg] = LLVMBuildSub (builder, lhs, rhs, dname);
4672 values [ins->dreg] = LLVMBuildMul (builder, lhs, rhs, dname);
4676 values [ins->dreg] = LLVMBuildSRem (builder, lhs, rhs, dname);
4680 values [ins->dreg] = LLVMBuildURem (builder, lhs, rhs, dname);
4684 values [ins->dreg] = LLVMBuildSDiv (builder, lhs, rhs, dname);
4688 values [ins->dreg] = LLVMBuildUDiv (builder, lhs, rhs, dname);
4692 values [ins->dreg] = LLVMBuildFDiv (builder, lhs, rhs, dname);
4696 values [ins->dreg] = LLVMBuildAnd (builder, lhs, rhs, dname);
4700 values [ins->dreg] = LLVMBuildOr (builder, lhs, rhs, dname);
4704 values [ins->dreg] = LLVMBuildXor (builder, lhs, rhs, dname);
4708 values [ins->dreg] = LLVMBuildShl (builder, lhs, rhs, dname);
4712 values [ins->dreg] = LLVMBuildAShr (builder, lhs, rhs, dname);
4716 values [ins->dreg] = LLVMBuildLShr (builder, lhs, rhs, dname);
4720 values [ins->dreg] = LLVMBuildFAdd (builder, lhs, rhs, dname);
4723 values [ins->dreg] = LLVMBuildFSub (builder, lhs, rhs, dname);
4726 values [ins->dreg] = LLVMBuildFMul (builder, lhs, rhs, dname);
4730 g_assert_not_reached ();
4737 lhs = convert (ctx, lhs, LLVMFloatType ());
4738 rhs = convert (ctx, rhs, LLVMFloatType ());
4739 switch (ins->opcode) {
4741 values [ins->dreg] = LLVMBuildFAdd (builder, lhs, rhs, dname);
4744 values [ins->dreg] = LLVMBuildFSub (builder, lhs, rhs, dname);
4747 values [ins->dreg] = LLVMBuildFMul (builder, lhs, rhs, dname);
4750 values [ins->dreg] = LLVMBuildFDiv (builder, lhs, rhs, dname);
4753 g_assert_not_reached ();
4762 case OP_IREM_UN_IMM:
4764 case OP_IDIV_UN_IMM:
4770 case OP_ISHR_UN_IMM:
4780 case OP_LSHR_UN_IMM:
4786 case OP_SHR_UN_IMM: {
4789 if (spec [MONO_INST_SRC1] == 'l') {
4790 imm = LLVMConstInt (LLVMInt64Type (), GET_LONG_IMM (ins), FALSE);
4792 imm = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
4795 emit_div_check (ctx, builder, bb, ins, lhs, imm);
4798 builder = ctx->builder;
4800 #if SIZEOF_VOID_P == 4
4801 if (ins->opcode == OP_LSHL_IMM || ins->opcode == OP_LSHR_IMM || ins->opcode == OP_LSHR_UN_IMM)
4802 imm = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
4805 if (LLVMGetTypeKind (LLVMTypeOf (lhs)) == LLVMPointerTypeKind)
4806 lhs = convert (ctx, lhs, IntPtrType ());
4807 imm = convert (ctx, imm, LLVMTypeOf (lhs));
4808 switch (ins->opcode) {
4812 values [ins->dreg] = LLVMBuildAdd (builder, lhs, imm, dname);
4816 values [ins->dreg] = LLVMBuildSub (builder, lhs, imm, dname);
4821 values [ins->dreg] = LLVMBuildMul (builder, lhs, imm, dname);
4825 values [ins->dreg] = LLVMBuildSDiv (builder, lhs, imm, dname);
4827 case OP_IDIV_UN_IMM:
4828 case OP_LDIV_UN_IMM:
4829 values [ins->dreg] = LLVMBuildUDiv (builder, lhs, imm, dname);
4833 values [ins->dreg] = LLVMBuildSRem (builder, lhs, imm, dname);
4835 case OP_IREM_UN_IMM:
4836 values [ins->dreg] = LLVMBuildURem (builder, lhs, imm, dname);
4841 values [ins->dreg] = LLVMBuildAnd (builder, lhs, imm, dname);
4845 values [ins->dreg] = LLVMBuildOr (builder, lhs, imm, dname);
4849 values [ins->dreg] = LLVMBuildXor (builder, lhs, imm, dname);
4854 values [ins->dreg] = LLVMBuildShl (builder, lhs, imm, dname);
4859 values [ins->dreg] = LLVMBuildAShr (builder, lhs, imm, dname);
4861 case OP_ISHR_UN_IMM:
4862 /* This is used to implement conv.u4, so the lhs could be an i8 */
4863 lhs = convert (ctx, lhs, LLVMInt32Type ());
4864 imm = convert (ctx, imm, LLVMInt32Type ());
4865 values [ins->dreg] = LLVMBuildLShr (builder, lhs, imm, dname);
4867 case OP_LSHR_UN_IMM:
4869 values [ins->dreg] = LLVMBuildLShr (builder, lhs, imm, dname);
4872 g_assert_not_reached ();
4877 values [ins->dreg] = LLVMBuildSub (builder, LLVMConstInt (LLVMInt32Type (), 0, FALSE), convert (ctx, lhs, LLVMInt32Type ()), dname);
4880 values [ins->dreg] = LLVMBuildSub (builder, LLVMConstInt (LLVMInt64Type (), 0, FALSE), lhs, dname);
4883 lhs = convert (ctx, lhs, LLVMDoubleType ());
4884 values [ins->dreg] = LLVMBuildFSub (builder, LLVMConstReal (LLVMDoubleType (), 0.0), lhs, dname);
4887 lhs = convert (ctx, lhs, LLVMFloatType ());
4888 values [ins->dreg] = LLVMBuildFSub (builder, LLVMConstReal (LLVMFloatType (), 0.0), lhs, dname);
4891 guint32 v = 0xffffffff;
4892 values [ins->dreg] = LLVMBuildXor (builder, LLVMConstInt (LLVMInt32Type (), v, FALSE), convert (ctx, lhs, LLVMInt32Type ()), dname);
4896 guint64 v = 0xffffffffffffffffLL;
4897 values [ins->dreg] = LLVMBuildXor (builder, LLVMConstInt (LLVMInt64Type (), v, FALSE), lhs, dname);
4900 #if defined(TARGET_X86) || defined(TARGET_AMD64)
4902 LLVMValueRef v1, v2;
4904 v1 = LLVMBuildMul (builder, convert (ctx, rhs, IntPtrType ()), LLVMConstInt (IntPtrType (), (1 << ins->backend.shift_amount), FALSE), "");
4905 v2 = LLVMBuildAdd (builder, convert (ctx, lhs, IntPtrType ()), v1, "");
4906 values [ins->dreg] = LLVMBuildAdd (builder, v2, LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE), dname);
4911 case OP_ICONV_TO_I1:
4912 case OP_ICONV_TO_I2:
4913 case OP_ICONV_TO_I4:
4914 case OP_ICONV_TO_U1:
4915 case OP_ICONV_TO_U2:
4916 case OP_ICONV_TO_U4:
4917 case OP_LCONV_TO_I1:
4918 case OP_LCONV_TO_I2:
4919 case OP_LCONV_TO_U1:
4920 case OP_LCONV_TO_U2:
4921 case OP_LCONV_TO_U4: {
4924 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);
4926 /* Have to do two casts since our vregs have type int */
4927 v = LLVMBuildTrunc (builder, lhs, op_to_llvm_type (ins->opcode), "");
4929 values [ins->dreg] = LLVMBuildSExt (builder, v, LLVMInt32Type (), dname);
4931 values [ins->dreg] = LLVMBuildZExt (builder, v, LLVMInt32Type (), dname);
4934 case OP_ICONV_TO_I8:
4935 values [ins->dreg] = LLVMBuildSExt (builder, lhs, LLVMInt64Type (), dname);
4937 case OP_ICONV_TO_U8:
4938 values [ins->dreg] = LLVMBuildZExt (builder, lhs, LLVMInt64Type (), dname);
4940 case OP_FCONV_TO_I4:
4941 case OP_RCONV_TO_I4:
4942 values [ins->dreg] = LLVMBuildFPToSI (builder, lhs, LLVMInt32Type (), dname);
4944 case OP_FCONV_TO_I1:
4945 case OP_RCONV_TO_I1:
4946 values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildFPToSI (builder, lhs, LLVMInt8Type (), dname), LLVMInt32Type (), "");
4948 case OP_FCONV_TO_U1:
4949 case OP_RCONV_TO_U1:
4950 values [ins->dreg] = LLVMBuildZExt (builder, LLVMBuildTrunc (builder, LLVMBuildFPToUI (builder, lhs, IntPtrType (), dname), LLVMInt8Type (), ""), LLVMInt32Type (), "");
4952 case OP_FCONV_TO_I2:
4953 case OP_RCONV_TO_I2:
4954 values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildFPToSI (builder, lhs, LLVMInt16Type (), dname), LLVMInt32Type (), "");
4956 case OP_FCONV_TO_U2:
4957 case OP_RCONV_TO_U2:
4958 values [ins->dreg] = LLVMBuildZExt (builder, LLVMBuildFPToUI (builder, lhs, LLVMInt16Type (), dname), LLVMInt32Type (), "");
4960 case OP_RCONV_TO_U4:
4961 values [ins->dreg] = LLVMBuildFPToUI (builder, lhs, LLVMInt32Type (), dname);
4963 case OP_FCONV_TO_I8:
4964 case OP_RCONV_TO_I8:
4965 values [ins->dreg] = LLVMBuildFPToSI (builder, lhs, LLVMInt64Type (), dname);
4968 values [ins->dreg] = LLVMBuildFPToSI (builder, lhs, IntPtrType (), dname);
4970 case OP_ICONV_TO_R8:
4971 case OP_LCONV_TO_R8:
4972 values [ins->dreg] = LLVMBuildSIToFP (builder, lhs, LLVMDoubleType (), dname);
4974 case OP_ICONV_TO_R_UN:
4975 case OP_LCONV_TO_R_UN:
4976 values [ins->dreg] = LLVMBuildUIToFP (builder, lhs, LLVMDoubleType (), dname);
4978 #if SIZEOF_VOID_P == 4
4981 case OP_LCONV_TO_I4:
4982 values [ins->dreg] = LLVMBuildTrunc (builder, lhs, LLVMInt32Type (), dname);
4984 case OP_ICONV_TO_R4:
4985 case OP_LCONV_TO_R4:
4986 v = LLVMBuildSIToFP (builder, lhs, LLVMFloatType (), "");
4988 values [ins->dreg] = v;
4990 values [ins->dreg] = LLVMBuildFPExt (builder, v, LLVMDoubleType (), dname);
4992 case OP_FCONV_TO_R4:
4993 v = LLVMBuildFPTrunc (builder, lhs, LLVMFloatType (), "");
4995 values [ins->dreg] = v;
4997 values [ins->dreg] = LLVMBuildFPExt (builder, v, LLVMDoubleType (), dname);
4999 case OP_RCONV_TO_R8:
5000 values [ins->dreg] = LLVMBuildFPExt (builder, lhs, LLVMDoubleType (), dname);
5002 case OP_RCONV_TO_R4:
5003 values [ins->dreg] = lhs;
5006 values [ins->dreg] = LLVMBuildSExt (builder, convert (ctx, lhs, LLVMInt32Type ()), LLVMInt64Type (), dname);
5009 values [ins->dreg] = LLVMBuildZExt (builder, convert (ctx, lhs, LLVMInt32Type ()), LLVMInt64Type (), dname);
5012 values [ins->dreg] = LLVMBuildTrunc (builder, lhs, LLVMInt32Type (), dname);
5014 case OP_LOCALLOC_IMM: {
5017 guint32 size = ins->inst_imm;
5018 size = (size + (MONO_ARCH_FRAME_ALIGNMENT - 1)) & ~ (MONO_ARCH_FRAME_ALIGNMENT - 1);
5020 v = mono_llvm_build_alloca (builder, LLVMInt8Type (), LLVMConstInt (LLVMInt32Type (), size, FALSE), MONO_ARCH_FRAME_ALIGNMENT, "");
5022 if (ins->flags & MONO_INST_INIT) {
5023 LLVMValueRef args [5];
5026 args [1] = LLVMConstInt (LLVMInt8Type (), 0, FALSE);
5027 args [2] = LLVMConstInt (LLVMInt32Type (), size, FALSE);
5028 args [3] = LLVMConstInt (LLVMInt32Type (), MONO_ARCH_FRAME_ALIGNMENT, FALSE);
5029 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
5030 LLVMBuildCall (builder, get_intrinsic (ctx, "llvm.memset.p0i8.i32"), args, 5, "");
5033 values [ins->dreg] = v;
5037 LLVMValueRef v, size;
5039 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), "");
5041 v = mono_llvm_build_alloca (builder, LLVMInt8Type (), size, MONO_ARCH_FRAME_ALIGNMENT, "");
5043 if (ins->flags & MONO_INST_INIT) {
5044 LLVMValueRef args [5];
5047 args [1] = LLVMConstInt (LLVMInt8Type (), 0, FALSE);
5049 args [3] = LLVMConstInt (LLVMInt32Type (), MONO_ARCH_FRAME_ALIGNMENT, FALSE);
5050 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
5051 LLVMBuildCall (builder, get_intrinsic (ctx, "llvm.memset.p0i8.i32"), args, 5, "");
5053 values [ins->dreg] = v;
5057 case OP_LOADI1_MEMBASE:
5058 case OP_LOADU1_MEMBASE:
5059 case OP_LOADI2_MEMBASE:
5060 case OP_LOADU2_MEMBASE:
5061 case OP_LOADI4_MEMBASE:
5062 case OP_LOADU4_MEMBASE:
5063 case OP_LOADI8_MEMBASE:
5064 case OP_LOADR4_MEMBASE:
5065 case OP_LOADR8_MEMBASE:
5066 case OP_LOAD_MEMBASE:
5074 LLVMValueRef base, index, addr;
5076 gboolean sext = FALSE, zext = FALSE;
5077 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
5079 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
5084 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)) {
5085 addr = LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE);
5090 if (ins->inst_offset == 0) {
5092 } else if (ins->inst_offset % size != 0) {
5093 /* Unaligned load */
5094 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset, FALSE);
5095 addr = LLVMBuildGEP (builder, convert (ctx, base, LLVMPointerType (LLVMInt8Type (), 0)), &index, 1, "");
5097 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
5098 addr = LLVMBuildGEP (builder, convert (ctx, base, LLVMPointerType (t, 0)), &index, 1, "");
5102 addr = convert (ctx, addr, LLVMPointerType (t, 0));
5104 values [ins->dreg] = emit_load (ctx, bb, &builder, size, addr, dname, is_volatile);
5106 if (!is_volatile && (ins->flags & MONO_INST_INVARIANT_LOAD)) {
5108 * These will signal LLVM that these loads do not alias any stores, and
5109 * they can't fail, allowing them to be hoisted out of loops.
5111 set_invariant_load_flag (values [ins->dreg]);
5112 #if LLVM_API_VERSION < 100
5113 set_metadata_flag (values [ins->dreg], "mono.nofail.load");
5118 values [ins->dreg] = LLVMBuildSExt (builder, values [ins->dreg], LLVMInt32Type (), dname);
5120 values [ins->dreg] = LLVMBuildZExt (builder, values [ins->dreg], LLVMInt32Type (), dname);
5121 else if (!cfg->r4fp && ins->opcode == OP_LOADR4_MEMBASE)
5122 values [ins->dreg] = LLVMBuildFPExt (builder, values [ins->dreg], LLVMDoubleType (), dname);
5126 case OP_STOREI1_MEMBASE_REG:
5127 case OP_STOREI2_MEMBASE_REG:
5128 case OP_STOREI4_MEMBASE_REG:
5129 case OP_STOREI8_MEMBASE_REG:
5130 case OP_STORER4_MEMBASE_REG:
5131 case OP_STORER8_MEMBASE_REG:
5132 case OP_STORE_MEMBASE_REG: {
5134 LLVMValueRef index, addr;
5136 gboolean sext = FALSE, zext = FALSE;
5137 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
5139 if (!values [ins->inst_destbasereg]) {
5140 set_failure (ctx, "inst_destbasereg");
5144 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
5146 if (ins->inst_offset % size != 0) {
5147 /* Unaligned store */
5148 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset, FALSE);
5149 addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (LLVMInt8Type (), 0)), &index, 1, "");
5151 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
5152 addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (t, 0)), &index, 1, "");
5154 emit_store (ctx, bb, &builder, size, convert (ctx, values [ins->sreg1], t), convert (ctx, addr, LLVMPointerType (t, 0)), is_volatile);
5158 case OP_STOREI1_MEMBASE_IMM:
5159 case OP_STOREI2_MEMBASE_IMM:
5160 case OP_STOREI4_MEMBASE_IMM:
5161 case OP_STOREI8_MEMBASE_IMM:
5162 case OP_STORE_MEMBASE_IMM: {
5164 LLVMValueRef index, addr;
5166 gboolean sext = FALSE, zext = FALSE;
5167 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
5169 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
5171 if (ins->inst_offset % size != 0) {
5172 /* Unaligned store */
5173 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset, FALSE);
5174 addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (LLVMInt8Type (), 0)), &index, 1, "");
5176 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
5177 addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (t, 0)), &index, 1, "");
5179 emit_store (ctx, bb, &builder, size, convert (ctx, LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE), t), convert (ctx, addr, LLVMPointerType (t, 0)), is_volatile);
5184 emit_load (ctx, bb, &builder, sizeof (gpointer), convert (ctx, lhs, LLVMPointerType (IntPtrType (), 0)), "", TRUE);
5186 case OP_OUTARG_VTRETADDR:
5194 case OP_VOIDCALL_MEMBASE:
5195 case OP_CALL_MEMBASE:
5196 case OP_LCALL_MEMBASE:
5197 case OP_FCALL_MEMBASE:
5198 case OP_RCALL_MEMBASE:
5199 case OP_VCALL_MEMBASE:
5200 case OP_VOIDCALL_REG:
5205 case OP_VCALL_REG: {
5206 process_call (ctx, bb, &builder, ins);
5211 LLVMValueRef indexes [2];
5212 MonoJumpInfo *tmp_ji, *ji;
5213 LLVMValueRef got_entry_addr;
5217 * FIXME: Can't allocate from the cfg mempool since that is freed if
5218 * the LLVM compile fails.
5220 tmp_ji = g_new0 (MonoJumpInfo, 1);
5221 tmp_ji->type = (MonoJumpInfoType)ins->inst_c1;
5222 tmp_ji->data.target = ins->inst_p0;
5224 ji = mono_aot_patch_info_dup (tmp_ji);
5227 if (ji->type == MONO_PATCH_INFO_ICALL_ADDR) {
5228 char *symbol = mono_aot_get_direct_call_symbol (MONO_PATCH_INFO_ICALL_ADDR_CALL, ji->data.target);
5231 * Avoid emitting a got entry for these since the method is directly called, and it might not be
5232 * resolvable at runtime using dlsym ().
5235 values [ins->dreg] = LLVMConstInt (IntPtrType (), 0, FALSE);
5240 ji->next = cfg->patch_info;
5241 cfg->patch_info = ji;
5243 //mono_add_patch_info (cfg, 0, (MonoJumpInfoType)ins->inst_i1, ins->inst_p0);
5244 got_offset = mono_aot_get_got_offset (cfg->patch_info);
5245 ctx->module->max_got_offset = MAX (ctx->module->max_got_offset, got_offset);
5246 if (!mono_aot_is_shared_got_offset (got_offset)) {
5247 //mono_print_ji (ji);
5249 ctx->has_got_access = TRUE;
5252 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
5253 indexes [1] = LLVMConstInt (LLVMInt32Type (), (gssize)got_offset, FALSE);
5254 got_entry_addr = LLVMBuildGEP (builder, ctx->module->got_var, indexes, 2, "");
5256 name = get_aotconst_name (ji->type, ji->data.target, got_offset);
5257 values [ins->dreg] = LLVMBuildLoad (builder, got_entry_addr, name);
5259 /* Can't use this in llvmonly mode since the got slots are initialized by the methods themselves */
5260 if (!cfg->llvm_only)
5261 set_invariant_load_flag (values [ins->dreg]);
5264 case OP_NOT_REACHED:
5265 LLVMBuildUnreachable (builder);
5266 has_terminator = TRUE;
5267 g_assert (bb->block_num < cfg->max_block_num);
5268 ctx->unreachable [bb->block_num] = TRUE;
5269 /* Might have instructions after this */
5271 MonoInst *next = ins->next;
5273 * FIXME: If later code uses the regs defined by these instructions,
5274 * compilation will fail.
5276 MONO_DELETE_INS (bb, next);
5280 MonoInst *var = ins->inst_i0;
5282 if (var->opcode == OP_VTARG_ADDR) {
5283 /* The variable contains the vtype address */
5284 values [ins->dreg] = values [var->dreg];
5285 } else if (var->opcode == OP_GSHAREDVT_LOCAL) {
5286 values [ins->dreg] = emit_gsharedvt_ldaddr (ctx, var->dreg);
5288 values [ins->dreg] = addresses [var->dreg];
5293 LLVMValueRef args [1];
5295 args [0] = convert (ctx, lhs, LLVMDoubleType ());
5296 values [ins->dreg] = LLVMBuildCall (builder, get_intrinsic (ctx, "llvm.sin.f64"), args, 1, dname);
5300 LLVMValueRef args [1];
5302 args [0] = convert (ctx, lhs, LLVMDoubleType ());
5303 values [ins->dreg] = LLVMBuildCall (builder, get_intrinsic (ctx, "llvm.cos.f64"), args, 1, dname);
5307 LLVMValueRef args [1];
5309 args [0] = convert (ctx, lhs, LLVMDoubleType ());
5310 values [ins->dreg] = LLVMBuildCall (builder, get_intrinsic (ctx, "llvm.sqrt.f64"), args, 1, dname);
5314 LLVMValueRef args [1];
5316 args [0] = convert (ctx, lhs, LLVMDoubleType ());
5317 values [ins->dreg] = LLVMBuildCall (builder, get_intrinsic (ctx, "fabs"), args, 1, dname);
5331 lhs = convert (ctx, lhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
5332 rhs = convert (ctx, rhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
5334 switch (ins->opcode) {
5337 v = LLVMBuildICmp (builder, LLVMIntSLE, lhs, rhs, "");
5341 v = LLVMBuildICmp (builder, LLVMIntSGE, lhs, rhs, "");
5345 v = LLVMBuildICmp (builder, LLVMIntULE, lhs, rhs, "");
5349 v = LLVMBuildICmp (builder, LLVMIntUGE, lhs, rhs, "");
5352 g_assert_not_reached ();
5355 values [ins->dreg] = LLVMBuildSelect (builder, v, lhs, rhs, dname);
5358 case OP_ATOMIC_EXCHANGE_I4:
5359 case OP_ATOMIC_EXCHANGE_I8: {
5360 LLVMValueRef args [2];
5363 if (ins->opcode == OP_ATOMIC_EXCHANGE_I4)
5364 t = LLVMInt32Type ();
5366 t = LLVMInt64Type ();
5368 g_assert (ins->inst_offset == 0);
5370 args [0] = convert (ctx, lhs, LLVMPointerType (t, 0));
5371 args [1] = convert (ctx, rhs, t);
5373 values [ins->dreg] = mono_llvm_build_atomic_rmw (builder, LLVM_ATOMICRMW_OP_XCHG, args [0], args [1]);
5376 case OP_ATOMIC_ADD_I4:
5377 case OP_ATOMIC_ADD_I8: {
5378 LLVMValueRef args [2];
5381 if (ins->opcode == OP_ATOMIC_ADD_I4)
5382 t = LLVMInt32Type ();
5384 t = LLVMInt64Type ();
5386 g_assert (ins->inst_offset == 0);
5388 args [0] = convert (ctx, lhs, LLVMPointerType (t, 0));
5389 args [1] = convert (ctx, rhs, t);
5390 values [ins->dreg] = LLVMBuildAdd (builder, mono_llvm_build_atomic_rmw (builder, LLVM_ATOMICRMW_OP_ADD, args [0], args [1]), args [1], dname);
5393 case OP_ATOMIC_CAS_I4:
5394 case OP_ATOMIC_CAS_I8: {
5395 LLVMValueRef args [3], val;
5398 if (ins->opcode == OP_ATOMIC_CAS_I4)
5399 t = LLVMInt32Type ();
5401 t = LLVMInt64Type ();
5403 args [0] = convert (ctx, lhs, LLVMPointerType (t, 0));
5405 args [1] = convert (ctx, values [ins->sreg3], t);
5407 args [2] = convert (ctx, values [ins->sreg2], t);
5408 val = mono_llvm_build_cmpxchg (builder, args [0], args [1], args [2]);
5409 /* cmpxchg returns a pair */
5410 values [ins->dreg] = LLVMBuildExtractValue (builder, val, 0, "");
5413 case OP_MEMORY_BARRIER: {
5414 mono_llvm_build_fence (builder, (BarrierKind) ins->backend.memory_barrier_kind);
5417 case OP_ATOMIC_LOAD_I1:
5418 case OP_ATOMIC_LOAD_I2:
5419 case OP_ATOMIC_LOAD_I4:
5420 case OP_ATOMIC_LOAD_I8:
5421 case OP_ATOMIC_LOAD_U1:
5422 case OP_ATOMIC_LOAD_U2:
5423 case OP_ATOMIC_LOAD_U4:
5424 case OP_ATOMIC_LOAD_U8:
5425 case OP_ATOMIC_LOAD_R4:
5426 case OP_ATOMIC_LOAD_R8: {
5427 set_failure (ctx, "atomic mono.load intrinsic");
5431 gboolean sext, zext;
5433 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
5434 BarrierKind barrier = (BarrierKind) ins->backend.memory_barrier_kind;
5435 LLVMValueRef index, addr;
5437 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
5442 if (ins->inst_offset != 0) {
5443 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
5444 addr = LLVMBuildGEP (builder, convert (ctx, lhs, LLVMPointerType (t, 0)), &index, 1, "");
5449 addr = convert (ctx, addr, LLVMPointerType (t, 0));
5451 values [ins->dreg] = emit_load_general (ctx, bb, &builder, size, addr, dname, is_volatile, barrier);
5454 values [ins->dreg] = LLVMBuildSExt (builder, values [ins->dreg], LLVMInt32Type (), dname);
5456 values [ins->dreg] = LLVMBuildZExt (builder, values [ins->dreg], LLVMInt32Type (), dname);
5460 case OP_ATOMIC_STORE_I1:
5461 case OP_ATOMIC_STORE_I2:
5462 case OP_ATOMIC_STORE_I4:
5463 case OP_ATOMIC_STORE_I8:
5464 case OP_ATOMIC_STORE_U1:
5465 case OP_ATOMIC_STORE_U2:
5466 case OP_ATOMIC_STORE_U4:
5467 case OP_ATOMIC_STORE_U8:
5468 case OP_ATOMIC_STORE_R4:
5469 case OP_ATOMIC_STORE_R8: {
5470 set_failure (ctx, "atomic mono.store intrinsic");
5474 gboolean sext, zext;
5476 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
5477 BarrierKind barrier = (BarrierKind) ins->backend.memory_barrier_kind;
5478 LLVMValueRef index, addr, value;
5480 if (!values [ins->inst_destbasereg]) {
5481 set_failure (ctx, "inst_destbasereg");
5485 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
5487 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
5488 addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (t, 0)), &index, 1, "");
5489 value = convert (ctx, values [ins->sreg1], t);
5491 emit_store_general (ctx, bb, &builder, size, value, addr, is_volatile, barrier);
5495 case OP_RELAXED_NOP: {
5496 #if defined(TARGET_AMD64) || defined(TARGET_X86)
5497 emit_call (ctx, bb, &builder, get_intrinsic (ctx, "llvm.x86.sse2.pause"), NULL, 0);
5504 #if (defined(TARGET_AMD64) || defined(TARGET_X86)) && defined(__linux__)
5506 // 257 == FS segment register
5507 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 257);
5509 // 256 == GS segment register
5510 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 256);
5513 values [ins->dreg] = LLVMBuildLoad (builder, LLVMBuildIntToPtr (builder, LLVMConstInt (IntPtrType (), ins->inst_offset, TRUE), ptrtype, ""), "");
5514 #elif defined(TARGET_AMD64) && defined(TARGET_OSX)
5515 /* See mono_amd64_emit_tls_get () */
5516 int offset = mono_amd64_get_tls_gs_offset () + (ins->inst_offset * 8);
5518 // 256 == GS segment register
5519 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 256);
5520 values [ins->dreg] = LLVMBuildLoad (builder, LLVMBuildIntToPtr (builder, LLVMConstInt (IntPtrType (), offset, TRUE), ptrtype, ""), "");
5522 set_failure (ctx, "opcode tls-get");
5528 case OP_TLS_GET_REG: {
5529 #if defined(TARGET_AMD64) && defined(TARGET_OSX)
5530 /* See emit_tls_get_reg () */
5531 // 256 == GS segment register
5532 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 256);
5533 values [ins->dreg] = LLVMBuildLoad (builder, LLVMBuildIntToPtr (builder, convert (ctx, lhs, LLVMInt32Type ()), ptrtype, ""), "");
5535 set_failure (ctx, "opcode tls-get");
5541 case OP_TLS_SET_REG: {
5542 #if defined(TARGET_AMD64) && defined(TARGET_OSX)
5543 /* See emit_tls_get_reg () */
5544 // 256 == GS segment register
5545 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 256);
5546 LLVMBuildStore (builder, convert (ctx, lhs, IntPtrType ()), LLVMBuildIntToPtr (builder, convert (ctx, rhs, LLVMInt32Type ()), ptrtype, ""));
5548 set_failure (ctx, "opcode tls-set-reg");
5553 case OP_GC_SAFE_POINT: {
5554 LLVMValueRef val, cmp, callee;
5555 LLVMBasicBlockRef poll_bb, cont_bb;
5556 static LLVMTypeRef sig;
5557 const char *icall_name = "mono_threads_state_poll";
5560 sig = LLVMFunctionType0 (LLVMVoidType (), FALSE);
5564 * mono_threads_state_poll ();
5565 * FIXME: Use a preserveall wrapper
5567 val = mono_llvm_build_load (builder, convert (ctx, lhs, LLVMPointerType (IntPtrType (), 0)), "", TRUE, LLVM_BARRIER_NONE);
5568 cmp = LLVMBuildICmp (builder, LLVMIntEQ, val, LLVMConstNull (LLVMTypeOf (val)), "");
5569 poll_bb = gen_bb (ctx, "POLL_BB");
5570 cont_bb = gen_bb (ctx, "CONT_BB");
5571 LLVMBuildCondBr (builder, cmp, cont_bb, poll_bb);
5573 ctx->builder = builder = create_builder (ctx);
5574 LLVMPositionBuilderAtEnd (builder, poll_bb);
5576 if (ctx->cfg->compile_aot) {
5577 callee = get_callee (ctx, sig, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
5579 gpointer target = resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
5580 callee = emit_jit_callee (ctx, icall_name, sig, target);
5582 LLVMBuildCall (builder, callee, NULL, 0, "");
5583 LLVMBuildBr (builder, cont_bb);
5585 ctx->builder = builder = create_builder (ctx);
5586 LLVMPositionBuilderAtEnd (builder, cont_bb);
5587 ctx->bblocks [bb->block_num].end_bblock = cont_bb;
5595 case OP_IADD_OVF_UN:
5597 case OP_ISUB_OVF_UN:
5599 case OP_IMUL_OVF_UN:
5601 case OP_LADD_OVF_UN:
5603 case OP_LSUB_OVF_UN:
5605 case OP_LMUL_OVF_UN:
5607 LLVMValueRef args [2], val, ovf, func;
5609 args [0] = convert (ctx, lhs, op_to_llvm_type (ins->opcode));
5610 args [1] = convert (ctx, rhs, op_to_llvm_type (ins->opcode));
5611 func = get_intrinsic (ctx, ovf_op_to_intrins (ins->opcode));
5613 val = LLVMBuildCall (builder, func, args, 2, "");
5614 values [ins->dreg] = LLVMBuildExtractValue (builder, val, 0, dname);
5615 ovf = LLVMBuildExtractValue (builder, val, 1, "");
5616 emit_cond_system_exception (ctx, bb, "OverflowException", ovf);
5619 builder = ctx->builder;
5625 * We currently model them using arrays. Promotion to local vregs is
5626 * disabled for them in mono_handle_global_vregs () in the LLVM case,
5627 * so we always have an entry in cfg->varinfo for them.
5628 * FIXME: Is this needed ?
5631 MonoClass *klass = ins->klass;
5632 LLVMValueRef args [5];
5636 set_failure (ctx, "!klass");
5640 if (!addresses [ins->dreg])
5641 addresses [ins->dreg] = build_alloca (ctx, &klass->byval_arg);
5642 args [0] = LLVMBuildBitCast (builder, addresses [ins->dreg], LLVMPointerType (LLVMInt8Type (), 0), "");
5643 args [1] = LLVMConstInt (LLVMInt8Type (), 0, FALSE);
5644 args [2] = LLVMConstInt (LLVMInt32Type (), mono_class_value_size (klass, NULL), FALSE);
5646 args [3] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
5647 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
5648 LLVMBuildCall (builder, get_intrinsic (ctx, "llvm.memset.p0i8.i32"), args, 5, "");
5651 case OP_DUMMY_VZERO:
5654 case OP_STOREV_MEMBASE:
5655 case OP_LOADV_MEMBASE:
5657 MonoClass *klass = ins->klass;
5658 LLVMValueRef src = NULL, dst, args [5];
5659 gboolean done = FALSE;
5663 set_failure (ctx, "!klass");
5667 if (mini_is_gsharedvt_klass (klass)) {
5669 set_failure (ctx, "gsharedvt");
5673 switch (ins->opcode) {
5674 case OP_STOREV_MEMBASE:
5675 if (cfg->gen_write_barriers && klass->has_references && ins->inst_destbasereg != cfg->frame_reg &&
5676 LLVMGetInstructionOpcode (values [ins->inst_destbasereg]) != LLVMAlloca) {
5677 /* Decomposed earlier */
5678 g_assert_not_reached ();
5681 if (!addresses [ins->sreg1]) {
5683 g_assert (values [ins->sreg1]);
5684 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));
5685 LLVMBuildStore (builder, values [ins->sreg1], dst);
5688 src = LLVMBuildBitCast (builder, addresses [ins->sreg1], LLVMPointerType (LLVMInt8Type (), 0), "");
5689 dst = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_destbasereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (LLVMInt8Type (), 0));
5692 case OP_LOADV_MEMBASE:
5693 if (!addresses [ins->dreg])
5694 addresses [ins->dreg] = build_alloca (ctx, &klass->byval_arg);
5695 src = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_basereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (LLVMInt8Type (), 0));
5696 dst = LLVMBuildBitCast (builder, addresses [ins->dreg], LLVMPointerType (LLVMInt8Type (), 0), "");
5699 if (!addresses [ins->sreg1])
5700 addresses [ins->sreg1] = build_alloca (ctx, &klass->byval_arg);
5701 if (!addresses [ins->dreg])
5702 addresses [ins->dreg] = build_alloca (ctx, &klass->byval_arg);
5703 src = LLVMBuildBitCast (builder, addresses [ins->sreg1], LLVMPointerType (LLVMInt8Type (), 0), "");
5704 dst = LLVMBuildBitCast (builder, addresses [ins->dreg], LLVMPointerType (LLVMInt8Type (), 0), "");
5707 g_assert_not_reached ();
5717 args [2] = LLVMConstInt (LLVMInt32Type (), mono_class_value_size (klass, NULL), FALSE);
5718 args [3] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
5720 args [3] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
5721 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
5722 LLVMBuildCall (builder, get_intrinsic (ctx, "llvm.memcpy.p0i8.p0i8.i32"), args, 5, "");
5725 case OP_LLVM_OUTARG_VT: {
5726 LLVMArgInfo *ainfo = (LLVMArgInfo*)ins->inst_p0;
5727 MonoType *t = mini_get_underlying_type (ins->inst_vtype);
5729 if (ainfo->storage == LLVMArgGsharedvtVariable) {
5730 MonoInst *var = get_vreg_to_inst (cfg, ins->sreg1);
5732 if (var && var->opcode == OP_GSHAREDVT_LOCAL) {
5733 addresses [ins->dreg] = convert (ctx, emit_gsharedvt_ldaddr (ctx, var->dreg), LLVMPointerType (IntPtrType (), 0));
5735 g_assert (addresses [ins->sreg1]);
5736 addresses [ins->dreg] = addresses [ins->sreg1];
5738 } else if (ainfo->storage == LLVMArgGsharedvtFixed) {
5739 if (!addresses [ins->sreg1]) {
5740 addresses [ins->sreg1] = build_alloca (ctx, t);
5741 g_assert (values [ins->sreg1]);
5743 LLVMBuildStore (builder, convert (ctx, values [ins->sreg1], LLVMGetElementType (LLVMTypeOf (addresses [ins->sreg1]))), addresses [ins->sreg1]);
5744 addresses [ins->dreg] = addresses [ins->sreg1];
5746 if (!addresses [ins->sreg1]) {
5747 addresses [ins->sreg1] = build_alloca (ctx, t);
5748 g_assert (values [ins->sreg1]);
5749 LLVMBuildStore (builder, convert (ctx, values [ins->sreg1], type_to_llvm_type (ctx, t)), addresses [ins->sreg1]);
5751 addresses [ins->dreg] = addresses [ins->sreg1];
5759 #if defined(TARGET_X86) || defined(TARGET_AMD64)
5761 values [ins->dreg] = LLVMConstNull (type_to_llvm_type (ctx, &ins->klass->byval_arg));
5764 case OP_LOADX_MEMBASE: {
5765 LLVMTypeRef t = type_to_llvm_type (ctx, &ins->klass->byval_arg);
5768 src = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_basereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (t, 0));
5769 values [ins->dreg] = mono_llvm_build_aligned_load (builder, src, "", FALSE, 1);
5772 case OP_STOREX_MEMBASE: {
5773 LLVMTypeRef t = LLVMTypeOf (values [ins->sreg1]);
5776 dest = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_destbasereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (t, 0));
5777 mono_llvm_build_aligned_store (builder, values [ins->sreg1], dest, FALSE, 1);
5784 values [ins->dreg] = LLVMBuildAdd (builder, lhs, rhs, "");
5788 values [ins->dreg] = LLVMBuildFAdd (builder, lhs, rhs, "");
5794 values [ins->dreg] = LLVMBuildSub (builder, lhs, rhs, "");
5798 values [ins->dreg] = LLVMBuildFSub (builder, lhs, rhs, "");
5802 values [ins->dreg] = LLVMBuildFMul (builder, lhs, rhs, "");
5806 values [ins->dreg] = LLVMBuildFDiv (builder, lhs, rhs, "");
5809 values [ins->dreg] = LLVMBuildAnd (builder, lhs, rhs, "");
5812 values [ins->dreg] = LLVMBuildOr (builder, lhs, rhs, "");
5815 values [ins->dreg] = LLVMBuildXor (builder, lhs, rhs, "");
5819 values [ins->dreg] = LLVMBuildMul (builder, lhs, rhs, "");
5830 LLVMValueRef v = NULL;
5832 switch (ins->opcode) {
5837 t = LLVMVectorType (LLVMInt32Type (), 4);
5838 rt = LLVMVectorType (LLVMFloatType (), 4);
5844 t = LLVMVectorType (LLVMInt64Type (), 2);
5845 rt = LLVMVectorType (LLVMDoubleType (), 2);
5848 t = LLVMInt32Type ();
5849 rt = LLVMInt32Type ();
5850 g_assert_not_reached ();
5853 lhs = LLVMBuildBitCast (builder, lhs, t, "");
5854 rhs = LLVMBuildBitCast (builder, rhs, t, "");
5855 switch (ins->opcode) {
5858 v = LLVMBuildAnd (builder, lhs, rhs, "");
5862 v = LLVMBuildOr (builder, lhs, rhs, "");
5866 v = LLVMBuildXor (builder, lhs, rhs, "");
5870 v = LLVMBuildAnd (builder, rhs, LLVMBuildNot (builder, lhs, ""), "");
5873 values [ins->dreg] = LLVMBuildBitCast (builder, v, rt, "");
5897 case OP_PADDB_SAT_UN:
5898 case OP_PADDW_SAT_UN:
5899 case OP_PSUBB_SAT_UN:
5900 case OP_PSUBW_SAT_UN:
5908 case OP_PMULW_HIGH_UN: {
5909 LLVMValueRef args [2];
5914 values [ins->dreg] = LLVMBuildCall (builder, get_intrinsic (ctx, simd_op_to_intrins (ins->opcode)), args, 2, dname);
5921 values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildICmp (builder, LLVMIntEQ, lhs, rhs, ""), LLVMTypeOf (lhs), "");
5925 values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildICmp (builder, LLVMIntSGT, lhs, rhs, ""), LLVMTypeOf (lhs), "");
5933 case OP_EXTRACTX_U2:
5935 case OP_EXTRACT_U1: {
5937 gboolean zext = FALSE;
5939 t = simd_op_to_llvm_type (ins->opcode);
5941 switch (ins->opcode) {
5949 case OP_EXTRACTX_U2:
5954 t = LLVMInt32Type ();
5955 g_assert_not_reached ();
5958 lhs = LLVMBuildBitCast (builder, lhs, t, "");
5959 values [ins->dreg] = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), "");
5961 values [ins->dreg] = LLVMBuildZExt (builder, values [ins->dreg], LLVMInt32Type (), "");
5970 case OP_EXPAND_R8: {
5971 LLVMTypeRef t = simd_op_to_llvm_type (ins->opcode);
5972 LLVMValueRef mask [16], v;
5975 for (i = 0; i < 16; ++i)
5976 mask [i] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
5978 v = convert (ctx, values [ins->sreg1], LLVMGetElementType (t));
5980 values [ins->dreg] = LLVMBuildInsertElement (builder, LLVMConstNull (t), v, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
5981 values [ins->dreg] = LLVMBuildShuffleVector (builder, values [ins->dreg], LLVMGetUndef (t), LLVMConstVector (mask, LLVMGetVectorSize (t)), "");
5986 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt8Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
5989 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt16Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
5992 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt32Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
5995 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt64Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
5998 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMFloatType ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
6001 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMDoubleType ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
6012 case OP_EXTRACT_MASK:
6019 v = convert (ctx, values [ins->sreg1], simd_op_to_llvm_type (ins->opcode));
6021 values [ins->dreg] = LLVMBuildCall (builder, get_intrinsic (ctx, simd_op_to_intrins (ins->opcode)), &v, 1, dname);
6027 LLVMValueRef args [3];
6031 args [2] = LLVMConstInt (LLVMInt8Type (), ins->inst_c0, FALSE);
6033 values [ins->dreg] = LLVMBuildCall (builder, get_intrinsic (ctx, simd_op_to_intrins (ins->opcode)), args, 3, dname);
6038 /* This is only used for implementing shifts by non-immediate */
6039 values [ins->dreg] = lhs;
6050 LLVMValueRef args [3];
6053 args [1] = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
6055 values [ins->dreg] = LLVMBuildCall (builder, get_intrinsic (ctx, simd_op_to_intrins (ins->opcode)), args, 2, dname);
6066 case OP_PSHLQ_REG: {
6067 LLVMValueRef args [3];
6070 args [1] = values [ins->sreg2];
6072 values [ins->dreg] = LLVMBuildCall (builder, get_intrinsic (ctx, simd_op_to_intrins (ins->opcode)), args, 2, dname);
6079 case OP_PSHUFLEW_LOW:
6080 case OP_PSHUFLEW_HIGH: {
6082 LLVMValueRef v1 = NULL, v2 = NULL, mask_values [16];
6083 int i, mask_size = 0;
6084 int imask = ins->inst_c0;
6086 /* Convert the x86 shuffle mask to LLVM's */
6087 switch (ins->opcode) {
6090 mask [0] = ((imask >> 0) & 3);
6091 mask [1] = ((imask >> 2) & 3);
6092 mask [2] = ((imask >> 4) & 3) + 4;
6093 mask [3] = ((imask >> 6) & 3) + 4;
6094 v1 = values [ins->sreg1];
6095 v2 = values [ins->sreg2];
6099 mask [0] = ((imask >> 0) & 1);
6100 mask [1] = ((imask >> 1) & 1) + 2;
6101 v1 = values [ins->sreg1];
6102 v2 = values [ins->sreg2];
6104 case OP_PSHUFLEW_LOW:
6106 mask [0] = ((imask >> 0) & 3);
6107 mask [1] = ((imask >> 2) & 3);
6108 mask [2] = ((imask >> 4) & 3);
6109 mask [3] = ((imask >> 6) & 3);
6114 v1 = values [ins->sreg1];
6115 v2 = LLVMGetUndef (LLVMTypeOf (v1));
6117 case OP_PSHUFLEW_HIGH:
6123 mask [4] = 4 + ((imask >> 0) & 3);
6124 mask [5] = 4 + ((imask >> 2) & 3);
6125 mask [6] = 4 + ((imask >> 4) & 3);
6126 mask [7] = 4 + ((imask >> 6) & 3);
6127 v1 = values [ins->sreg1];
6128 v2 = LLVMGetUndef (LLVMTypeOf (v1));
6132 mask [0] = ((imask >> 0) & 3);
6133 mask [1] = ((imask >> 2) & 3);
6134 mask [2] = ((imask >> 4) & 3);
6135 mask [3] = ((imask >> 6) & 3);
6136 v1 = values [ins->sreg1];
6137 v2 = LLVMGetUndef (LLVMTypeOf (v1));
6140 g_assert_not_reached ();
6142 for (i = 0; i < mask_size; ++i)
6143 mask_values [i] = LLVMConstInt (LLVMInt32Type (), mask [i], FALSE);
6145 values [ins->dreg] =
6146 LLVMBuildShuffleVector (builder, v1, v2,
6147 LLVMConstVector (mask_values, mask_size), dname);
6151 case OP_UNPACK_LOWB:
6152 case OP_UNPACK_LOWW:
6153 case OP_UNPACK_LOWD:
6154 case OP_UNPACK_LOWQ:
6155 case OP_UNPACK_LOWPS:
6156 case OP_UNPACK_LOWPD:
6157 case OP_UNPACK_HIGHB:
6158 case OP_UNPACK_HIGHW:
6159 case OP_UNPACK_HIGHD:
6160 case OP_UNPACK_HIGHQ:
6161 case OP_UNPACK_HIGHPS:
6162 case OP_UNPACK_HIGHPD: {
6164 LLVMValueRef mask_values [16];
6165 int i, mask_size = 0;
6166 gboolean low = FALSE;
6168 switch (ins->opcode) {
6169 case OP_UNPACK_LOWB:
6173 case OP_UNPACK_LOWW:
6177 case OP_UNPACK_LOWD:
6178 case OP_UNPACK_LOWPS:
6182 case OP_UNPACK_LOWQ:
6183 case OP_UNPACK_LOWPD:
6187 case OP_UNPACK_HIGHB:
6190 case OP_UNPACK_HIGHW:
6193 case OP_UNPACK_HIGHD:
6194 case OP_UNPACK_HIGHPS:
6197 case OP_UNPACK_HIGHQ:
6198 case OP_UNPACK_HIGHPD:
6202 g_assert_not_reached ();
6206 for (i = 0; i < (mask_size / 2); ++i) {
6208 mask [(i * 2) + 1] = mask_size + i;
6211 for (i = 0; i < (mask_size / 2); ++i) {
6212 mask [(i * 2)] = (mask_size / 2) + i;
6213 mask [(i * 2) + 1] = mask_size + (mask_size / 2) + i;
6217 for (i = 0; i < mask_size; ++i)
6218 mask_values [i] = LLVMConstInt (LLVMInt32Type (), mask [i], FALSE);
6220 values [ins->dreg] =
6221 LLVMBuildShuffleVector (builder, values [ins->sreg1], values [ins->sreg2],
6222 LLVMConstVector (mask_values, mask_size), dname);
6227 LLVMTypeRef t = simd_op_to_llvm_type (ins->opcode);
6228 LLVMValueRef v, val;
6230 v = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
6231 val = LLVMConstNull (t);
6232 val = LLVMBuildInsertElement (builder, val, v, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
6233 val = LLVMBuildInsertElement (builder, val, v, LLVMConstInt (LLVMInt32Type (), 1, FALSE), dname);
6235 values [ins->dreg] = val;
6239 case OP_DUPPS_HIGH: {
6240 LLVMTypeRef t = simd_op_to_llvm_type (ins->opcode);
6241 LLVMValueRef v1, v2, val;
6244 if (ins->opcode == OP_DUPPS_LOW) {
6245 v1 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
6246 v2 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 2, FALSE), "");
6248 v1 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 1, FALSE), "");
6249 v2 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 3, FALSE), "");
6251 val = LLVMConstNull (t);
6252 val = LLVMBuildInsertElement (builder, val, v1, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
6253 val = LLVMBuildInsertElement (builder, val, v1, LLVMConstInt (LLVMInt32Type (), 1, FALSE), "");
6254 val = LLVMBuildInsertElement (builder, val, v2, LLVMConstInt (LLVMInt32Type (), 2, FALSE), "");
6255 val = LLVMBuildInsertElement (builder, val, v2, LLVMConstInt (LLVMInt32Type (), 3, FALSE), "");
6257 values [ins->dreg] = val;
6267 * EXCEPTION HANDLING
6269 case OP_IMPLICIT_EXCEPTION:
6270 /* This marks a place where an implicit exception can happen */
6271 if (bb->region != -1)
6272 set_failure (ctx, "implicit-exception");
6276 gboolean rethrow = (ins->opcode == OP_RETHROW);
6277 if (ctx->llvm_only) {
6278 emit_llvmonly_throw (ctx, bb, rethrow, lhs);
6279 has_terminator = TRUE;
6280 ctx->unreachable [bb->block_num] = TRUE;
6282 emit_throw (ctx, bb, rethrow, lhs);
6283 builder = ctx->builder;
6287 case OP_CALL_HANDLER: {
6289 * We don't 'call' handlers, but instead simply branch to them.
6290 * The code generated by ENDFINALLY will branch back to us.
6292 LLVMBasicBlockRef noex_bb;
6294 BBInfo *info = &bblocks [ins->inst_target_bb->block_num];
6296 bb_list = info->call_handler_return_bbs;
6299 * Set the indicator variable for the finally clause.
6301 lhs = info->finally_ind;
6303 LLVMBuildStore (builder, LLVMConstInt (LLVMInt32Type (), g_slist_length (bb_list) + 1, FALSE), lhs);
6305 /* Branch to the finally clause */
6306 LLVMBuildBr (builder, info->call_handler_target_bb);
6308 noex_bb = gen_bb (ctx, "CALL_HANDLER_CONT_BB");
6309 info->call_handler_return_bbs = g_slist_append_mempool (cfg->mempool, info->call_handler_return_bbs, noex_bb);
6311 builder = ctx->builder = create_builder (ctx);
6312 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
6314 bblocks [bb->block_num].end_bblock = noex_bb;
6317 case OP_START_HANDLER: {
6320 case OP_ENDFINALLY: {
6321 LLVMBasicBlockRef resume_bb;
6322 MonoBasicBlock *handler_bb;
6323 LLVMValueRef val, switch_ins, callee;
6327 handler_bb = (MonoBasicBlock*)g_hash_table_lookup (ctx->region_to_handler, GUINT_TO_POINTER (mono_get_block_region_notry (cfg, bb->region)));
6328 g_assert (handler_bb);
6329 info = &bblocks [handler_bb->block_num];
6330 lhs = info->finally_ind;
6333 bb_list = info->call_handler_return_bbs;
6335 resume_bb = gen_bb (ctx, "ENDFINALLY_RESUME_BB");
6337 /* Load the finally variable */
6338 val = LLVMBuildLoad (builder, lhs, "");
6340 /* Reset the variable */
6341 LLVMBuildStore (builder, LLVMConstInt (LLVMInt32Type (), 0, FALSE), lhs);
6343 /* Branch to either resume_bb, or to the bblocks in bb_list */
6344 switch_ins = LLVMBuildSwitch (builder, val, resume_bb, g_slist_length (bb_list));
6346 * The other targets are added at the end to handle OP_CALL_HANDLER
6347 * opcodes processed later.
6349 info->endfinally_switch_ins_list = g_slist_append_mempool (cfg->mempool, info->endfinally_switch_ins_list, switch_ins);
6351 builder = ctx->builder = create_builder (ctx);
6352 LLVMPositionBuilderAtEnd (ctx->builder, resume_bb);
6354 if (ctx->llvm_only) {
6355 emit_resume_eh (ctx, bb);
6357 if (ctx->cfg->compile_aot) {
6358 callee = get_callee (ctx, LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE), MONO_PATCH_INFO_INTERNAL_METHOD, "llvm_resume_unwind_trampoline");
6360 #if LLVM_API_VERSION > 100
6361 MonoJitICallInfo *info;
6363 info = mono_find_jit_icall_by_name ("llvm_resume_unwind_trampoline");
6365 gpointer target = (void*)info->func;
6366 LLVMTypeRef icall_sig = LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE);
6367 callee = emit_jit_callee (ctx, "llvm_resume_unwind_trampoline", icall_sig, target);
6369 callee = LLVMGetNamedFunction (ctx->lmodule, "llvm_resume_unwind_trampoline");
6372 LLVMBuildCall (builder, callee, NULL, 0, "");
6373 LLVMBuildUnreachable (builder);
6376 has_terminator = TRUE;
6379 case OP_IL_SEQ_POINT:
6384 sprintf (reason, "opcode %s", mono_inst_name (ins->opcode));
6385 set_failure (ctx, reason);
6393 /* Convert the value to the type required by phi nodes */
6394 if (spec [MONO_INST_DEST] != ' ' && !MONO_IS_STORE_MEMBASE (ins) && ctx->vreg_types [ins->dreg]) {
6395 if (!values [ins->dreg])
6397 values [ins->dreg] = addresses [ins->dreg];
6399 values [ins->dreg] = convert (ctx, values [ins->dreg], ctx->vreg_types [ins->dreg]);
6402 /* Add stores for volatile variables */
6403 if (spec [MONO_INST_DEST] != ' ' && spec [MONO_INST_DEST] != 'v' && !MONO_IS_STORE_MEMBASE (ins))
6404 emit_volatile_store (ctx, ins->dreg);
6410 if (!has_terminator && bb->next_bb && (bb == cfg->bb_entry || bb->in_count > 0)) {
6411 LLVMBuildBr (builder, get_bb (ctx, bb->next_bb));
6414 if (bb == cfg->bb_exit && sig->ret->type == MONO_TYPE_VOID) {
6415 emit_dbg_loc (ctx, builder, cfg->header->code + cfg->header->code_size - 1);
6416 LLVMBuildRetVoid (builder);
6419 if (bb == cfg->bb_entry)
6420 ctx->last_alloca = LLVMGetLastInstruction (get_bb (ctx, cfg->bb_entry));
6424 * mono_llvm_check_method_supported:
6426 * Do some quick checks to decide whenever cfg->method can be compiled by LLVM, to avoid
6427 * compiling a method twice.
6430 mono_llvm_check_method_supported (MonoCompile *cfg)
6437 if (cfg->method->save_lmf) {
6438 cfg->exception_message = g_strdup ("lmf");
6439 cfg->disable_llvm = TRUE;
6441 if (cfg->disable_llvm)
6445 * Nested clauses where one of the clauses is a finally clause is
6446 * not supported, because LLVM can't figure out the control flow,
6447 * probably because we resume exception handling by calling our
6448 * own function instead of using the 'resume' llvm instruction.
6450 for (i = 0; i < cfg->header->num_clauses; ++i) {
6451 for (j = 0; j < cfg->header->num_clauses; ++j) {
6452 MonoExceptionClause *clause1 = &cfg->header->clauses [i];
6453 MonoExceptionClause *clause2 = &cfg->header->clauses [j];
6455 // FIXME: Nested try clauses fail in some cases too, i.e. #37273
6456 if (i != j && clause1->try_offset >= clause2->try_offset && clause1->handler_offset <= clause2->handler_offset) {
6457 //(clause1->flags == MONO_EXCEPTION_CLAUSE_FINALLY || clause2->flags == MONO_EXCEPTION_CLAUSE_FINALLY)) {
6458 cfg->exception_message = g_strdup ("nested clauses");
6459 cfg->disable_llvm = TRUE;
6464 if (cfg->disable_llvm)
6468 if (cfg->method->dynamic) {
6469 cfg->exception_message = g_strdup ("dynamic.");
6470 cfg->disable_llvm = TRUE;
6472 if (cfg->disable_llvm)
6476 static LLVMCallInfo*
6477 get_llvm_call_info (MonoCompile *cfg, MonoMethodSignature *sig)
6479 LLVMCallInfo *linfo;
6482 if (cfg->gsharedvt && cfg->llvm_only && mini_is_gsharedvt_variable_signature (sig)) {
6486 * Gsharedvt methods have the following calling convention:
6487 * - all arguments are passed by ref, even non generic ones
6488 * - the return value is returned by ref too, using a vret
6489 * argument passed after 'this'.
6491 n = sig->param_count + sig->hasthis;
6492 linfo = (LLVMCallInfo*)mono_mempool_alloc0 (cfg->mempool, sizeof (LLVMCallInfo) + (sizeof (LLVMArgInfo) * n));
6496 linfo->args [pindex ++].storage = LLVMArgNormal;
6498 if (sig->ret->type != MONO_TYPE_VOID) {
6499 if (mini_is_gsharedvt_variable_type (sig->ret))
6500 linfo->ret.storage = LLVMArgGsharedvtVariable;
6501 else if (mini_type_is_vtype (sig->ret))
6502 linfo->ret.storage = LLVMArgGsharedvtFixedVtype;
6504 linfo->ret.storage = LLVMArgGsharedvtFixed;
6505 linfo->vret_arg_index = pindex;
6507 linfo->ret.storage = LLVMArgNone;
6510 for (i = 0; i < sig->param_count; ++i) {
6511 if (sig->params [i]->byref)
6512 linfo->args [pindex].storage = LLVMArgNormal;
6513 else if (mini_is_gsharedvt_variable_type (sig->params [i]))
6514 linfo->args [pindex].storage = LLVMArgGsharedvtVariable;
6515 else if (mini_type_is_vtype (sig->params [i]))
6516 linfo->args [pindex].storage = LLVMArgGsharedvtFixedVtype;
6518 linfo->args [pindex].storage = LLVMArgGsharedvtFixed;
6519 linfo->args [pindex].type = sig->params [i];
6526 linfo = mono_arch_get_llvm_call_info (cfg, sig);
6527 for (i = 0; i < sig->param_count; ++i)
6528 linfo->args [i + sig->hasthis].type = sig->params [i];
6534 emit_method_inner (EmitContext *ctx);
6537 free_ctx (EmitContext *ctx)
6541 g_free (ctx->values);
6542 g_free (ctx->addresses);
6543 g_free (ctx->vreg_types);
6544 g_free (ctx->vreg_cli_types);
6545 g_free (ctx->is_dead);
6546 g_free (ctx->unreachable);
6547 g_ptr_array_free (ctx->phi_values, TRUE);
6548 g_free (ctx->bblocks);
6549 g_hash_table_destroy (ctx->region_to_handler);
6550 g_hash_table_destroy (ctx->clause_to_handler);
6551 g_hash_table_destroy (ctx->jit_callees);
6552 g_free (ctx->method_name);
6553 g_ptr_array_free (ctx->bblock_list, TRUE);
6555 for (l = ctx->builders; l; l = l->next) {
6556 LLVMBuilderRef builder = (LLVMBuilderRef)l->data;
6557 LLVMDisposeBuilder (builder);
6564 * mono_llvm_emit_method:
6566 * Emit LLVM IL from the mono IL, and compile it to native code using LLVM.
6569 mono_llvm_emit_method (MonoCompile *cfg)
6573 gboolean is_linkonce = FALSE;
6576 /* The code below might acquire the loader lock, so use it for global locking */
6577 mono_loader_lock ();
6579 /* Used to communicate with the callbacks */
6580 mono_native_tls_set_value (current_cfg_tls_id, cfg);
6582 ctx = g_new0 (EmitContext, 1);
6584 ctx->mempool = cfg->mempool;
6587 * This maps vregs to the LLVM instruction defining them
6589 ctx->values = g_new0 (LLVMValueRef, cfg->next_vreg);
6591 * This maps vregs for volatile variables to the LLVM instruction defining their
6594 ctx->addresses = g_new0 (LLVMValueRef, cfg->next_vreg);
6595 ctx->vreg_types = g_new0 (LLVMTypeRef, cfg->next_vreg);
6596 ctx->vreg_cli_types = g_new0 (MonoType*, cfg->next_vreg);
6597 ctx->phi_values = g_ptr_array_sized_new (256);
6599 * This signals whenever the vreg was defined by a phi node with no input vars
6600 * (i.e. all its input bblocks end with NOT_REACHABLE).
6602 ctx->is_dead = g_new0 (gboolean, cfg->next_vreg);
6603 /* Whenever the bblock is unreachable */
6604 ctx->unreachable = g_new0 (gboolean, cfg->max_block_num);
6605 ctx->bblock_list = g_ptr_array_sized_new (256);
6607 ctx->region_to_handler = g_hash_table_new (NULL, NULL);
6608 ctx->clause_to_handler = g_hash_table_new (NULL, NULL);
6609 ctx->method_to_callers = g_hash_table_new (NULL, NULL);
6610 ctx->jit_callees = g_hash_table_new (NULL, NULL);
6611 if (cfg->compile_aot) {
6612 ctx->module = &aot_module;
6616 * Allow the linker to discard duplicate copies of wrappers, generic instances etc. by using the 'linkonce'
6617 * linkage for them. This requires the following:
6618 * - the method needs to have a unique mangled name
6619 * - llvmonly mode, since the code in aot-runtime.c would initialize got slots in the wrong aot image etc.
6621 is_linkonce = ctx->module->llvm_only && ctx->module->static_link && mono_aot_is_linkonce_method (cfg->method);
6623 method_name = mono_aot_get_mangled_method_name (cfg->method);
6625 is_linkonce = FALSE;
6628 printf ("%s %s\n", mono_method_full_name (cfg->method, 1), method_name);
6630 printf ("%s\n", mono_method_full_name (cfg->method, 1));
6634 method_name = mono_aot_get_method_name (cfg);
6635 cfg->llvm_method_name = g_strdup (method_name);
6637 init_jit_module (cfg->domain);
6638 ctx->module = (MonoLLVMModule*)domain_jit_info (cfg->domain)->llvm_module;
6639 method_name = mono_method_full_name (cfg->method, TRUE);
6641 ctx->method_name = method_name;
6642 ctx->is_linkonce = is_linkonce;
6644 #if LLVM_API_VERSION > 100
6645 ctx->lmodule = LLVMModuleCreateWithName ("jit-module");
6647 ctx->lmodule = ctx->module->lmodule;
6649 ctx->llvm_only = ctx->module->llvm_only;
6651 emit_method_inner (ctx);
6653 if (!ctx_ok (ctx)) {
6655 /* Need to add unused phi nodes as they can be referenced by other values */
6656 LLVMBasicBlockRef phi_bb = LLVMAppendBasicBlock (ctx->lmethod, "PHI_BB");
6657 LLVMBuilderRef builder;
6659 builder = create_builder (ctx);
6660 LLVMPositionBuilderAtEnd (builder, phi_bb);
6662 for (i = 0; i < ctx->phi_values->len; ++i) {
6663 LLVMValueRef v = (LLVMValueRef)g_ptr_array_index (ctx->phi_values, i);
6664 if (LLVMGetInstructionParent (v) == NULL)
6665 LLVMInsertIntoBuilder (builder, v);
6668 LLVMDeleteFunction (ctx->lmethod);
6674 mono_native_tls_set_value (current_cfg_tls_id, NULL);
6676 mono_loader_unlock ();
6680 emit_method_inner (EmitContext *ctx)
6682 MonoCompile *cfg = ctx->cfg;
6683 MonoMethodSignature *sig;
6685 LLVMTypeRef method_type;
6686 LLVMValueRef method = NULL;
6687 LLVMValueRef *values = ctx->values;
6688 int i, max_block_num, bb_index;
6689 gboolean last = FALSE;
6690 LLVMCallInfo *linfo;
6691 LLVMModuleRef lmodule = ctx->lmodule;
6693 GPtrArray *bblock_list = ctx->bblock_list;
6694 MonoMethodHeader *header;
6695 MonoExceptionClause *clause;
6698 if (cfg->gsharedvt && !cfg->llvm_only) {
6699 set_failure (ctx, "gsharedvt");
6705 static int count = 0;
6708 if (g_getenv ("LLVM_COUNT")) {
6709 if (count == atoi (g_getenv ("LLVM_COUNT"))) {
6710 printf ("LAST: %s\n", mono_method_full_name (cfg->method, TRUE));
6714 if (count > atoi (g_getenv ("LLVM_COUNT"))) {
6715 set_failure (ctx, "count");
6722 sig = mono_method_signature (cfg->method);
6725 linfo = get_llvm_call_info (cfg, sig);
6731 linfo->rgctx_arg = TRUE;
6732 ctx->method_type = method_type = sig_to_llvm_sig_full (ctx, sig, linfo);
6736 method = LLVMAddFunction (lmodule, ctx->method_name, method_type);
6737 ctx->lmethod = method;
6739 if (!cfg->llvm_only)
6740 LLVMSetFunctionCallConv (method, LLVMMono1CallConv);
6741 LLVMSetLinkage (method, LLVMPrivateLinkage);
6743 LLVMAddFunctionAttr (method, LLVMUWTable);
6745 if (cfg->compile_aot) {
6746 LLVMSetLinkage (method, LLVMInternalLinkage);
6747 if (ctx->module->external_symbols) {
6748 LLVMSetLinkage (method, LLVMExternalLinkage);
6749 LLVMSetVisibility (method, LLVMHiddenVisibility);
6751 if (ctx->is_linkonce) {
6752 LLVMSetLinkage (method, LLVMLinkOnceAnyLinkage);
6753 LLVMSetVisibility (method, LLVMDefaultVisibility);
6756 #if LLVM_API_VERSION > 100
6757 LLVMSetLinkage (method, LLVMExternalLinkage);
6759 LLVMSetLinkage (method, LLVMPrivateLinkage);
6763 if (cfg->method->save_lmf && !cfg->llvm_only) {
6764 set_failure (ctx, "lmf");
6768 if (sig->pinvoke && cfg->method->wrapper_type != MONO_WRAPPER_RUNTIME_INVOKE && !cfg->llvm_only) {
6769 set_failure (ctx, "pinvoke signature");
6773 header = cfg->header;
6774 for (i = 0; i < header->num_clauses; ++i) {
6775 clause = &header->clauses [i];
6776 if (clause->flags != MONO_EXCEPTION_CLAUSE_FINALLY && clause->flags != MONO_EXCEPTION_CLAUSE_NONE) {
6777 set_failure (ctx, "non-finally/catch clause.");
6781 if (header->num_clauses || (cfg->method->iflags & METHOD_IMPL_ATTRIBUTE_NOINLINING) || cfg->no_inline)
6782 /* We can't handle inlined methods with clauses */
6783 LLVMAddFunctionAttr (method, LLVMNoInlineAttribute);
6785 if (linfo->rgctx_arg) {
6786 ctx->rgctx_arg = LLVMGetParam (method, linfo->rgctx_arg_pindex);
6787 ctx->rgctx_arg_pindex = linfo->rgctx_arg_pindex;
6789 * We mark the rgctx parameter with the inreg attribute, which is mapped to
6790 * MONO_ARCH_RGCTX_REG in the Mono calling convention in llvm, i.e.
6791 * CC_X86_64_Mono in X86CallingConv.td.
6793 if (!ctx->llvm_only)
6794 LLVMAddAttribute (ctx->rgctx_arg, LLVMInRegAttribute);
6795 LLVMSetValueName (ctx->rgctx_arg, "rgctx");
6797 ctx->rgctx_arg_pindex = -1;
6799 if (cfg->vret_addr) {
6800 values [cfg->vret_addr->dreg] = LLVMGetParam (method, linfo->vret_arg_pindex);
6801 LLVMSetValueName (values [cfg->vret_addr->dreg], "vret");
6802 if (linfo->ret.storage == LLVMArgVtypeByRef) {
6803 LLVMAddAttribute (LLVMGetParam (method, linfo->vret_arg_pindex), LLVMStructRetAttribute);
6804 LLVMAddAttribute (LLVMGetParam (method, linfo->vret_arg_pindex), LLVMNoAliasAttribute);
6809 ctx->this_arg_pindex = linfo->this_arg_pindex;
6810 ctx->this_arg = LLVMGetParam (method, linfo->this_arg_pindex);
6811 values [cfg->args [0]->dreg] = ctx->this_arg;
6812 LLVMSetValueName (values [cfg->args [0]->dreg], "this");
6815 names = g_new (char *, sig->param_count);
6816 mono_method_get_param_names (cfg->method, (const char **) names);
6818 for (i = 0; i < sig->param_count; ++i) {
6819 LLVMArgInfo *ainfo = &linfo->args [i + sig->hasthis];
6821 int pindex = ainfo->pindex + ainfo->ndummy_fpargs;
6824 for (j = 0; j < ainfo->ndummy_fpargs; ++j) {
6825 name = g_strdup_printf ("dummy_%d_%d", i, j);
6826 LLVMSetValueName (LLVMGetParam (method, ainfo->pindex + j), name);
6830 values [cfg->args [i + sig->hasthis]->dreg] = LLVMGetParam (method, pindex);
6831 if (ainfo->storage == LLVMArgGsharedvtFixed || ainfo->storage == LLVMArgGsharedvtFixedVtype) {
6832 if (names [i] && names [i][0] != '\0')
6833 name = g_strdup_printf ("p_arg_%s", names [i]);
6835 name = g_strdup_printf ("p_arg_%d", i);
6837 if (names [i] && names [i][0] != '\0')
6838 name = g_strdup_printf ("arg_%s", names [i]);
6840 name = g_strdup_printf ("arg_%d", i);
6842 LLVMSetValueName (values [cfg->args [i + sig->hasthis]->dreg], name);
6844 if (ainfo->storage == LLVMArgVtypeByVal)
6845 LLVMAddAttribute (LLVMGetParam (method, pindex), LLVMByValAttribute);
6847 if (ainfo->storage == LLVMArgVtypeByRef) {
6849 cfg->args [i + sig->hasthis]->opcode = OP_VTARG_ADDR;
6854 if (ctx->module->emit_dwarf && cfg->compile_aot && mono_debug_enabled ()) {
6855 ctx->minfo = mono_debug_lookup_method (cfg->method);
6856 ctx->dbg_md = emit_dbg_subprogram (ctx, cfg, method, ctx->method_name);
6860 for (bb = cfg->bb_entry; bb; bb = bb->next_bb)
6861 max_block_num = MAX (max_block_num, bb->block_num);
6862 ctx->bblocks = bblocks = g_new0 (BBInfo, max_block_num + 1);
6864 /* Add branches between non-consecutive bblocks */
6865 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
6866 if (bb->last_ins && MONO_IS_COND_BRANCH_OP (bb->last_ins) &&
6867 bb->next_bb != bb->last_ins->inst_false_bb) {
6869 MonoInst *inst = (MonoInst*)mono_mempool_alloc0 (cfg->mempool, sizeof (MonoInst));
6870 inst->opcode = OP_BR;
6871 inst->inst_target_bb = bb->last_ins->inst_false_bb;
6872 mono_bblock_add_inst (bb, inst);
6877 * The INDIRECT flag added by OP_LDADDR inhibits optimizations, even if the LDADDR
6878 * was later optimized away, so clear these flags, and add them back for the still
6879 * present OP_LDADDR instructions.
6881 for (i = 0; i < cfg->next_vreg; ++i) {
6884 ins = get_vreg_to_inst (cfg, i);
6885 if (ins && ins != cfg->rgctx_var)
6886 ins->flags &= ~MONO_INST_INDIRECT;
6890 * Make a first pass over the code to precreate PHI nodes/set INDIRECT flags.
6892 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
6894 LLVMBuilderRef builder;
6896 char dname_buf[128];
6898 builder = create_builder (ctx);
6900 for (ins = bb->code; ins; ins = ins->next) {
6901 switch (ins->opcode) {
6906 LLVMTypeRef phi_type = llvm_type_to_stack_type (cfg, type_to_llvm_type (ctx, &ins->klass->byval_arg));
6911 if (ins->opcode == OP_VPHI) {
6912 /* Treat valuetype PHI nodes as operating on the address itself */
6913 g_assert (ins->klass);
6914 phi_type = LLVMPointerType (type_to_llvm_type (ctx, &ins->klass->byval_arg), 0);
6918 * Have to precreate these, as they can be referenced by
6919 * earlier instructions.
6921 sprintf (dname_buf, "t%d", ins->dreg);
6923 values [ins->dreg] = LLVMBuildPhi (builder, phi_type, dname);
6925 if (ins->opcode == OP_VPHI)
6926 ctx->addresses [ins->dreg] = values [ins->dreg];
6928 g_ptr_array_add (ctx->phi_values, values [ins->dreg]);
6931 * Set the expected type of the incoming arguments since these have
6932 * to have the same type.
6934 for (i = 0; i < ins->inst_phi_args [0]; i++) {
6935 int sreg1 = ins->inst_phi_args [i + 1];
6938 ctx->vreg_types [sreg1] = phi_type;
6943 ((MonoInst*)ins->inst_p0)->flags |= MONO_INST_INDIRECT;
6952 * Create an ordering for bblocks, use the depth first order first, then
6953 * put the exception handling bblocks last.
6955 for (bb_index = 0; bb_index < cfg->num_bblocks; ++bb_index) {
6956 bb = cfg->bblocks [bb_index];
6957 if (!(bb->region != -1 && !MONO_BBLOCK_IS_IN_REGION (bb, MONO_REGION_TRY))) {
6958 g_ptr_array_add (bblock_list, bb);
6959 bblocks [bb->block_num].added = TRUE;
6963 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
6964 if (!bblocks [bb->block_num].added)
6965 g_ptr_array_add (bblock_list, bb);
6969 * Second pass: generate code.
6972 LLVMBuilderRef entry_builder = create_builder (ctx);
6973 LLVMBasicBlockRef entry_bb = get_bb (ctx, cfg->bb_entry);
6974 LLVMPositionBuilderAtEnd (entry_builder, entry_bb);
6975 emit_entry_bb (ctx, entry_builder);
6977 // Make landing pads first
6978 ctx->exc_meta = g_hash_table_new_full (NULL, NULL, NULL, NULL);
6980 if (ctx->llvm_only) {
6981 size_t group_index = 0;
6982 while (group_index < cfg->header->num_clauses) {
6984 size_t cursor = group_index;
6985 while (cursor < cfg->header->num_clauses &&
6986 CLAUSE_START (&cfg->header->clauses [cursor]) == CLAUSE_START (&cfg->header->clauses [group_index]) &&
6987 CLAUSE_END (&cfg->header->clauses [cursor]) == CLAUSE_END (&cfg->header->clauses [group_index])) {
6992 LLVMBasicBlockRef lpad_bb = emit_landing_pad (ctx, group_index, count);
6993 intptr_t key = CLAUSE_END (&cfg->header->clauses [group_index]);
6994 g_hash_table_insert (ctx->exc_meta, (gpointer)key, lpad_bb);
6996 group_index = cursor;
7000 for (bb_index = 0; bb_index < bblock_list->len; ++bb_index) {
7001 bb = (MonoBasicBlock*)g_ptr_array_index (bblock_list, bb_index);
7003 // Prune unreachable mono BBs.
7004 if (!(bb == cfg->bb_entry || bb->in_count > 0))
7007 process_bb (ctx, bb);
7011 g_hash_table_destroy (ctx->exc_meta);
7013 mono_memory_barrier ();
7015 /* Add incoming phi values */
7016 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
7017 GSList *l, *ins_list;
7019 ins_list = bblocks [bb->block_num].phi_nodes;
7021 for (l = ins_list; l; l = l->next) {
7022 PhiNode *node = (PhiNode*)l->data;
7023 MonoInst *phi = node->phi;
7024 int sreg1 = node->sreg;
7025 LLVMBasicBlockRef in_bb;
7030 in_bb = get_end_bb (ctx, node->in_bb);
7032 if (ctx->unreachable [node->in_bb->block_num])
7035 if (!values [sreg1]) {
7036 /* Can happen with values in EH clauses */
7037 set_failure (ctx, "incoming phi sreg1");
7041 if (phi->opcode == OP_VPHI) {
7042 g_assert (LLVMTypeOf (ctx->addresses [sreg1]) == LLVMTypeOf (values [phi->dreg]));
7043 LLVMAddIncoming (values [phi->dreg], &ctx->addresses [sreg1], &in_bb, 1);
7045 if (LLVMTypeOf (values [sreg1]) != LLVMTypeOf (values [phi->dreg])) {
7046 set_failure (ctx, "incoming phi arg type mismatch");
7049 g_assert (LLVMTypeOf (values [sreg1]) == LLVMTypeOf (values [phi->dreg]));
7050 LLVMAddIncoming (values [phi->dreg], &values [sreg1], &in_bb, 1);
7055 /* Nullify empty phi instructions */
7056 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
7057 GSList *l, *ins_list;
7059 ins_list = bblocks [bb->block_num].phi_nodes;
7061 for (l = ins_list; l; l = l->next) {
7062 PhiNode *node = (PhiNode*)l->data;
7063 MonoInst *phi = node->phi;
7064 LLVMValueRef phi_ins = values [phi->dreg];
7067 /* Already removed */
7070 if (LLVMCountIncoming (phi_ins) == 0) {
7071 mono_llvm_replace_uses_of (phi_ins, LLVMConstNull (LLVMTypeOf (phi_ins)));
7072 LLVMInstructionEraseFromParent (phi_ins);
7073 values [phi->dreg] = NULL;
7078 /* Create the SWITCH statements for ENDFINALLY instructions */
7079 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
7080 BBInfo *info = &bblocks [bb->block_num];
7082 for (l = info->endfinally_switch_ins_list; l; l = l->next) {
7083 LLVMValueRef switch_ins = (LLVMValueRef)l->data;
7084 GSList *bb_list = info->call_handler_return_bbs;
7086 for (i = 0; i < g_slist_length (bb_list); ++i)
7087 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), i + 1, FALSE), (LLVMBasicBlockRef)(g_slist_nth (bb_list, i)->data));
7091 /* Initialize the method if needed */
7092 if (cfg->compile_aot && ctx->llvm_only) {
7093 // FIXME: Add more shared got entries
7094 ctx->builder = create_builder (ctx);
7095 LLVMPositionBuilderAtEnd (ctx->builder, ctx->init_bb);
7097 ctx->module->max_method_idx = MAX (ctx->module->max_method_idx, cfg->method_index);
7099 // FIXME: beforefieldinit
7100 if (ctx->has_got_access || mono_class_get_cctor (cfg->method->klass)) {
7102 * linkonce methods shouldn't have initialization,
7103 * because they might belong to assemblies which
7104 * haven't been loaded yet.
7106 g_assert (!ctx->is_linkonce);
7107 emit_init_method (ctx);
7109 LLVMBuildBr (ctx->builder, ctx->inited_bb);
7113 if (cfg->llvm_only) {
7114 GHashTableIter iter;
7116 GSList *callers, *l, *l2;
7119 * Add the contents of ctx->method_to_callers to module->method_to_callers.
7120 * We can't do this earlier, as it contains llvm instructions which can be
7121 * freed if compilation fails.
7122 * FIXME: Get rid of this when all methods can be llvm compiled.
7124 g_hash_table_iter_init (&iter, ctx->method_to_callers);
7125 while (g_hash_table_iter_next (&iter, (void**)&method, (void**)&callers)) {
7126 for (l = callers; l; l = l->next) {
7127 l2 = (GSList*)g_hash_table_lookup (ctx->module->method_to_callers, method);
7128 l2 = g_slist_prepend (l2, l->data);
7129 g_hash_table_insert (ctx->module->method_to_callers, method, l2);
7134 if (cfg->verbose_level > 1)
7135 mono_llvm_dump_value (method);
7137 if (cfg->compile_aot && !cfg->llvm_only)
7138 mark_as_used (ctx->module, method);
7140 if (cfg->compile_aot && !cfg->llvm_only) {
7141 LLVMValueRef md_args [16];
7142 LLVMValueRef md_node;
7145 method_index = mono_aot_get_method_index (cfg->orig_method);
7146 md_args [0] = LLVMMDString (ctx->method_name, strlen (ctx->method_name));
7147 md_args [1] = LLVMConstInt (LLVMInt32Type (), method_index, FALSE);
7148 md_node = LLVMMDNode (md_args, 2);
7149 LLVMAddNamedMetadataOperand (lmodule, "mono.function_indexes", md_node);
7150 //LLVMSetMetadata (method, md_kind, LLVMMDNode (&md_arg, 1));
7153 if (cfg->compile_aot) {
7154 /* Don't generate native code, keep the LLVM IR */
7155 if (cfg->verbose_level)
7156 printf ("%s emitted as %s\n", mono_method_full_name (cfg->method, TRUE), ctx->method_name);
7158 #if LLVM_API_VERSION < 100
7159 /* VerifyFunction can't handle some of the debug info created by DIBuilder in llvm 3.9 */
7160 int err = LLVMVerifyFunction(ctx->lmethod, LLVMPrintMessageAction);
7161 g_assert (err == 0);
7164 //LLVMVerifyFunction(method, 0);
7165 #if LLVM_API_VERSION > 100
7166 MonoDomain *domain = mono_domain_get ();
7167 MonoJitDomainInfo *domain_info;
7168 int nvars = g_hash_table_size (ctx->jit_callees);
7169 LLVMValueRef *callee_vars = g_new0 (LLVMValueRef, nvars);
7170 gpointer *callee_addrs = g_new0 (gpointer, nvars);
7171 GHashTableIter iter;
7177 * Compute the addresses of the LLVM globals pointing to the
7178 * methods called by the current method. Pass it to the trampoline
7179 * code so it can update them after their corresponding method was
7182 g_hash_table_iter_init (&iter, ctx->jit_callees);
7184 while (g_hash_table_iter_next (&iter, NULL, (void**)&var))
7185 callee_vars [i ++] = var;
7187 cfg->native_code = mono_llvm_compile_method (ctx->module->mono_ee, ctx->lmethod, nvars, callee_vars, callee_addrs, &eh_frame);
7189 decode_llvm_eh_info (ctx, eh_frame);
7191 mono_domain_lock (domain);
7192 domain_info = domain_jit_info (domain);
7193 if (!domain_info->llvm_jit_callees)
7194 domain_info->llvm_jit_callees = g_hash_table_new (NULL, NULL);
7195 g_hash_table_iter_init (&iter, ctx->jit_callees);
7197 while (g_hash_table_iter_next (&iter, (void**)&callee, (void**)&var)) {
7198 GSList *addrs = g_hash_table_lookup (domain_info->llvm_jit_callees, callee);
7199 addrs = g_slist_prepend (addrs, callee_addrs [i]);
7200 g_hash_table_insert (domain_info->llvm_jit_callees, callee, addrs);
7203 mono_domain_unlock (domain);
7205 mono_llvm_optimize_method (ctx->module->mono_ee, ctx->lmethod);
7207 if (cfg->verbose_level > 1)
7208 mono_llvm_dump_value (ctx->lmethod);
7210 cfg->native_code = (unsigned char*)LLVMGetPointerToGlobal (ctx->module->ee, ctx->lmethod);
7212 /* Set by emit_cb */
7213 g_assert (cfg->code_len);
7217 if (ctx->module->method_to_lmethod)
7218 g_hash_table_insert (ctx->module->method_to_lmethod, cfg->method, ctx->lmethod);
7219 if (ctx->module->idx_to_lmethod)
7220 g_hash_table_insert (ctx->module->idx_to_lmethod, GINT_TO_POINTER (cfg->method_index), ctx->lmethod);
7222 if (ctx->llvm_only && cfg->orig_method->klass->valuetype && !(cfg->orig_method->flags & METHOD_ATTRIBUTE_STATIC))
7223 emit_unbox_tramp (ctx, ctx->method_name, ctx->method_type, ctx->lmethod, cfg->method_index);
7227 * mono_llvm_create_vars:
7229 * Same as mono_arch_create_vars () for LLVM.
7232 mono_llvm_create_vars (MonoCompile *cfg)
7234 MonoMethodSignature *sig;
7236 sig = mono_method_signature (cfg->method);
7237 if (cfg->gsharedvt && cfg->llvm_only) {
7238 if (mini_is_gsharedvt_variable_signature (sig) && sig->ret->type != MONO_TYPE_VOID) {
7239 cfg->vret_addr = mono_compile_create_var (cfg, &mono_get_intptr_class ()->byval_arg, OP_ARG);
7240 if (G_UNLIKELY (cfg->verbose_level > 1)) {
7241 printf ("vret_addr = ");
7242 mono_print_ins (cfg->vret_addr);
7246 mono_arch_create_vars (cfg);
7251 * mono_llvm_emit_call:
7253 * Same as mono_arch_emit_call () for LLVM.
7256 mono_llvm_emit_call (MonoCompile *cfg, MonoCallInst *call)
7259 MonoMethodSignature *sig;
7260 int i, n, stack_size;
7265 sig = call->signature;
7266 n = sig->param_count + sig->hasthis;
7268 call->cinfo = get_llvm_call_info (cfg, sig);
7270 if (cfg->disable_llvm)
7273 if (sig->call_convention == MONO_CALL_VARARG) {
7274 cfg->exception_message = g_strdup ("varargs");
7275 cfg->disable_llvm = TRUE;
7278 for (i = 0; i < n; ++i) {
7281 ainfo = call->cinfo->args + i;
7283 in = call->args [i];
7285 /* Simply remember the arguments */
7286 switch (ainfo->storage) {
7287 case LLVMArgNormal: {
7288 MonoType *t = (sig->hasthis && i == 0) ? &mono_get_intptr_class ()->byval_arg : ainfo->type;
7291 opcode = mono_type_to_regmove (cfg, t);
7292 if (opcode == OP_FMOVE) {
7293 MONO_INST_NEW (cfg, ins, OP_FMOVE);
7294 ins->dreg = mono_alloc_freg (cfg);
7295 } else if (opcode == OP_LMOVE) {
7296 MONO_INST_NEW (cfg, ins, OP_LMOVE);
7297 ins->dreg = mono_alloc_lreg (cfg);
7298 } else if (opcode == OP_RMOVE) {
7299 MONO_INST_NEW (cfg, ins, OP_RMOVE);
7300 ins->dreg = mono_alloc_freg (cfg);
7302 MONO_INST_NEW (cfg, ins, OP_MOVE);
7303 ins->dreg = mono_alloc_ireg (cfg);
7305 ins->sreg1 = in->dreg;
7308 case LLVMArgVtypeByVal:
7309 case LLVMArgVtypeByRef:
7310 case LLVMArgVtypeInReg:
7311 case LLVMArgVtypeAsScalar:
7312 case LLVMArgAsIArgs:
7313 case LLVMArgAsFpArgs:
7314 case LLVMArgGsharedvtVariable:
7315 case LLVMArgGsharedvtFixed:
7316 case LLVMArgGsharedvtFixedVtype:
7317 MONO_INST_NEW (cfg, ins, OP_LLVM_OUTARG_VT);
7318 ins->dreg = mono_alloc_ireg (cfg);
7319 ins->sreg1 = in->dreg;
7320 ins->inst_p0 = mono_mempool_alloc0 (cfg->mempool, sizeof (LLVMArgInfo));
7321 memcpy (ins->inst_p0, ainfo, sizeof (LLVMArgInfo));
7322 ins->inst_vtype = ainfo->type;
7323 ins->klass = mono_class_from_mono_type (ainfo->type);
7326 cfg->exception_message = g_strdup ("ainfo->storage");
7327 cfg->disable_llvm = TRUE;
7331 if (!cfg->disable_llvm) {
7332 MONO_ADD_INS (cfg->cbb, ins);
7333 mono_call_inst_add_outarg_reg (cfg, call, ins->dreg, 0, FALSE);
7338 static unsigned char*
7339 alloc_cb (LLVMValueRef function, int size)
7343 cfg = (MonoCompile*)mono_native_tls_get_value (current_cfg_tls_id);
7347 return (unsigned char*)mono_domain_code_reserve (cfg->domain, size);
7349 return (unsigned char*)mono_domain_code_reserve (mono_domain_get (), size);
7354 emitted_cb (LLVMValueRef function, void *start, void *end)
7358 cfg = (MonoCompile*)mono_native_tls_get_value (current_cfg_tls_id);
7360 cfg->code_len = (guint8*)end - (guint8*)start;
7364 exception_cb (void *data)
7367 MonoJitExceptionInfo *ei;
7368 guint32 ei_len, i, j, nested_len, nindex;
7369 gpointer *type_info;
7370 int this_reg, this_offset;
7372 cfg = (MonoCompile*)mono_native_tls_get_value (current_cfg_tls_id);
7376 * data points to a DWARF FDE structure, convert it to our unwind format and
7378 * An alternative would be to save it directly, and modify our unwinder to work
7381 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);
7382 if (cfg->verbose_level > 1)
7383 mono_print_unwind_info (cfg->encoded_unwind_ops, cfg->encoded_unwind_ops_len);
7385 /* Count nested clauses */
7387 for (i = 0; i < ei_len; ++i) {
7388 gint32 cindex1 = *(gint32*)type_info [i];
7389 MonoExceptionClause *clause1 = &cfg->header->clauses [cindex1];
7391 for (j = 0; j < cfg->header->num_clauses; ++j) {
7393 MonoExceptionClause *clause2 = &cfg->header->clauses [cindex2];
7395 if (cindex1 != cindex2 && clause1->try_offset >= clause2->try_offset && clause1->handler_offset <= clause2->handler_offset) {
7401 cfg->llvm_ex_info = (MonoJitExceptionInfo*)mono_mempool_alloc0 (cfg->mempool, (ei_len + nested_len) * sizeof (MonoJitExceptionInfo));
7402 cfg->llvm_ex_info_len = ei_len + nested_len;
7403 memcpy (cfg->llvm_ex_info, ei, ei_len * sizeof (MonoJitExceptionInfo));
7404 /* Fill the rest of the information from the type info */
7405 for (i = 0; i < ei_len; ++i) {
7406 gint32 clause_index = *(gint32*)type_info [i];
7407 MonoExceptionClause *clause = &cfg->header->clauses [clause_index];
7409 cfg->llvm_ex_info [i].flags = clause->flags;
7410 cfg->llvm_ex_info [i].data.catch_class = clause->data.catch_class;
7411 cfg->llvm_ex_info [i].clause_index = clause_index;
7415 * For nested clauses, the LLVM produced exception info associates the try interval with
7416 * the innermost handler, while mono expects it to be associated with all nesting clauses.
7417 * So add new clauses which use the IL info (catch class etc.) from the nesting clause,
7418 * and everything else from the nested clause.
7421 for (i = 0; i < ei_len; ++i) {
7422 gint32 cindex1 = *(gint32*)type_info [i];
7423 MonoExceptionClause *clause1 = &cfg->header->clauses [cindex1];
7425 for (j = 0; j < cfg->header->num_clauses; ++j) {
7427 MonoExceptionClause *clause2 = &cfg->header->clauses [cindex2];
7428 MonoJitExceptionInfo *nesting_ei, *nested_ei;
7430 if (cindex1 != cindex2 && clause1->try_offset >= clause2->try_offset && clause1->handler_offset <= clause2->handler_offset) {
7431 /* clause1 is the nested clause */
7432 nested_ei = &cfg->llvm_ex_info [i];
7433 nesting_ei = &cfg->llvm_ex_info [nindex];
7436 memcpy (nesting_ei, nested_ei, sizeof (MonoJitExceptionInfo));
7438 nesting_ei->flags = clause2->flags;
7439 nesting_ei->data.catch_class = clause2->data.catch_class;
7440 nesting_ei->clause_index = cindex2;
7444 g_assert (nindex == ei_len + nested_len);
7445 cfg->llvm_this_reg = this_reg;
7446 cfg->llvm_this_offset = this_offset;
7448 /* type_info [i] is cfg mempool allocated, no need to free it */
7454 #if LLVM_API_VERSION > 100
7456 * decode_llvm_eh_info:
7458 * Decode the EH table emitted by llvm in jit mode, and store
7459 * the result into cfg.
7462 decode_llvm_eh_info (EmitContext *ctx, gpointer eh_frame)
7464 MonoCompile *cfg = ctx->cfg;
7467 MonoLLVMFDEInfo info;
7468 MonoJitExceptionInfo *ei;
7469 guint8 *p = eh_frame;
7470 int version, fde_count, fde_offset;
7471 guint32 ei_len, i, nested_len;
7472 gpointer *type_info;
7476 * Decode the one element EH table emitted by the MonoException class
7480 /* Similar to decode_llvm_mono_eh_frame () in aot-runtime.c */
7483 g_assert (version == 3);
7486 p = (guint8 *)ALIGN_PTR_TO (p, 4);
7488 fde_count = *(guint32*)p;
7492 g_assert (fde_count == 1);
7494 /* The only table entry */
7495 fde_offset = table [1];
7498 cfg->code_len = table [0];
7499 fde_len = table [1] - fde_offset;
7502 fde = (guint8*)eh_frame + fde_offset;
7503 cie = (guint8*)table;
7505 mono_unwind_decode_llvm_mono_fde (fde, fde_len, cie, cfg->native_code, &info);
7507 cfg->encoded_unwind_ops = info.unw_info;
7508 cfg->encoded_unwind_ops_len = info.unw_info_len;
7509 if (cfg->verbose_level > 1)
7510 mono_print_unwind_info (cfg->encoded_unwind_ops, cfg->encoded_unwind_ops_len);
7511 if (info.this_reg != -1) {
7512 cfg->llvm_this_reg = info.this_reg;
7513 cfg->llvm_this_offset = info.this_offset;
7517 ei_len = info.ex_info_len;
7518 type_info = info.type_info;
7520 // Nested clauses are currently disabled
7523 cfg->llvm_ex_info = (MonoJitExceptionInfo*)mono_mempool_alloc0 (cfg->mempool, (ei_len + nested_len) * sizeof (MonoJitExceptionInfo));
7524 cfg->llvm_ex_info_len = ei_len + nested_len;
7525 memcpy (cfg->llvm_ex_info, ei, ei_len * sizeof (MonoJitExceptionInfo));
7526 /* Fill the rest of the information from the type info */
7527 for (i = 0; i < ei_len; ++i) {
7528 gint32 clause_index = *(gint32*)type_info [i];
7529 MonoExceptionClause *clause = &cfg->header->clauses [clause_index];
7531 cfg->llvm_ex_info [i].flags = clause->flags;
7532 cfg->llvm_ex_info [i].data.catch_class = clause->data.catch_class;
7533 cfg->llvm_ex_info [i].clause_index = clause_index;
7539 dlsym_cb (const char *name, void **symbol)
7545 if (!strcmp (name, "__bzero")) {
7546 *symbol = (void*)bzero;
7548 current = mono_dl_open (NULL, 0, NULL);
7551 err = mono_dl_symbol (current, name, symbol);
7553 mono_dl_close (current);
7555 #ifdef MONO_ARCH_HAVE_CREATE_LLVM_NATIVE_THUNK
7556 *symbol = (char*)mono_arch_create_llvm_native_thunk (mono_domain_get (), (guint8*)(*symbol));
7562 AddFunc (LLVMModuleRef module, const char *name, LLVMTypeRef ret_type, LLVMTypeRef *param_types, int nparams)
7564 LLVMAddFunction (module, name, LLVMFunctionType (ret_type, param_types, nparams, FALSE));
7568 AddFunc2 (LLVMModuleRef module, const char *name, LLVMTypeRef ret_type, LLVMTypeRef param_type1, LLVMTypeRef param_type2)
7570 LLVMTypeRef param_types [4];
7572 param_types [0] = param_type1;
7573 param_types [1] = param_type2;
7575 AddFunc (module, name, ret_type, param_types, 2);
7581 INTRINS_SADD_OVF_I32,
7582 INTRINS_UADD_OVF_I32,
7583 INTRINS_SSUB_OVF_I32,
7584 INTRINS_USUB_OVF_I32,
7585 INTRINS_SMUL_OVF_I32,
7586 INTRINS_UMUL_OVF_I32,
7587 INTRINS_SADD_OVF_I64,
7588 INTRINS_UADD_OVF_I64,
7589 INTRINS_SSUB_OVF_I64,
7590 INTRINS_USUB_OVF_I64,
7591 INTRINS_SMUL_OVF_I64,
7592 INTRINS_UMUL_OVF_I64,
7599 #if defined(TARGET_AMD64) || defined(TARGET_X86)
7600 INTRINS_SSE_PMOVMSKB,
7601 INTRINS_SSE_PSRLI_W,
7602 INTRINS_SSE_PSRAI_W,
7603 INTRINS_SSE_PSLLI_W,
7604 INTRINS_SSE_PSRLI_D,
7605 INTRINS_SSE_PSRAI_D,
7606 INTRINS_SSE_PSLLI_D,
7607 INTRINS_SSE_PSRLI_Q,
7608 INTRINS_SSE_PSLLI_Q,
7609 INTRINS_SSE_SQRT_PD,
7610 INTRINS_SSE_SQRT_PS,
7611 INTRINS_SSE_RSQRT_PS,
7613 INTRINS_SSE_CVTTPD2DQ,
7614 INTRINS_SSE_CVTTPS2DQ,
7615 INTRINS_SSE_CVTDQ2PD,
7616 INTRINS_SSE_CVTDQ2PS,
7617 INTRINS_SSE_CVTPD2DQ,
7618 INTRINS_SSE_CVTPS2DQ,
7619 INTRINS_SSE_CVTPD2PS,
7620 INTRINS_SSE_CVTPS2PD,
7623 INTRINS_SSE_PACKSSWB,
7624 INTRINS_SSE_PACKUSWB,
7625 INTRINS_SSE_PACKSSDW,
7626 INTRINS_SSE_PACKUSDW,
7631 INTRINS_SSE_ADDSUBPS,
7636 INTRINS_SSE_ADDSUBPD,
7644 INTRINS_SSE_PADDUSW,
7645 INTRINS_SSE_PSUBUSW,
7653 INTRINS_SSE_PADDUSB,
7654 INTRINS_SSE_PSUBUSB,
7666 static IntrinsicDesc intrinsics[] = {
7667 {INTRINS_MEMSET, "llvm.memset.p0i8.i32"},
7668 {INTRINS_MEMCPY, "llvm.memcpy.p0i8.p0i8.i32"},
7669 {INTRINS_SADD_OVF_I32, "llvm.sadd.with.overflow.i32"},
7670 {INTRINS_UADD_OVF_I32, "llvm.uadd.with.overflow.i32"},
7671 {INTRINS_SSUB_OVF_I32, "llvm.ssub.with.overflow.i32"},
7672 {INTRINS_USUB_OVF_I32, "llvm.usub.with.overflow.i32"},
7673 {INTRINS_SMUL_OVF_I32, "llvm.smul.with.overflow.i32"},
7674 {INTRINS_UMUL_OVF_I32, "llvm.umul.with.overflow.i32"},
7675 {INTRINS_SADD_OVF_I64, "llvm.sadd.with.overflow.i64"},
7676 {INTRINS_UADD_OVF_I64, "llvm.uadd.with.overflow.i64"},
7677 {INTRINS_SSUB_OVF_I64, "llvm.ssub.with.overflow.i64"},
7678 {INTRINS_USUB_OVF_I64, "llvm.usub.with.overflow.i64"},
7679 {INTRINS_SMUL_OVF_I64, "llvm.smul.with.overflow.i64"},
7680 {INTRINS_UMUL_OVF_I64, "llvm.umul.with.overflow.i64"},
7681 {INTRINS_SIN, "llvm.sin.f64"},
7682 {INTRINS_COS, "llvm.cos.f64"},
7683 {INTRINS_SQRT, "llvm.sqrt.f64"},
7684 /* This isn't an intrinsic, instead llvm seems to special case it by name */
7685 {INTRINS_FABS, "fabs"},
7686 {INTRINS_EXPECT_I8, "llvm.expect.i8"},
7687 {INTRINS_EXPECT_I1, "llvm.expect.i1"},
7688 #if defined(TARGET_AMD64) || defined(TARGET_X86)
7689 {INTRINS_SSE_PMOVMSKB, "llvm.x86.sse2.pmovmskb.128"},
7690 {INTRINS_SSE_PSRLI_W, "llvm.x86.sse2.psrli.w"},
7691 {INTRINS_SSE_PSRAI_W, "llvm.x86.sse2.psrai.w"},
7692 {INTRINS_SSE_PSLLI_W, "llvm.x86.sse2.pslli.w"},
7693 {INTRINS_SSE_PSRLI_D, "llvm.x86.sse2.psrli.d"},
7694 {INTRINS_SSE_PSRAI_D, "llvm.x86.sse2.psrai.d"},
7695 {INTRINS_SSE_PSLLI_D, "llvm.x86.sse2.pslli.d"},
7696 {INTRINS_SSE_PSRLI_Q, "llvm.x86.sse2.psrli.q"},
7697 {INTRINS_SSE_PSLLI_Q, "llvm.x86.sse2.pslli.q"},
7698 {INTRINS_SSE_SQRT_PD, "llvm.x86.sse2.sqrt.pd"},
7699 {INTRINS_SSE_SQRT_PS, "llvm.x86.sse.sqrt.ps"},
7700 {INTRINS_SSE_RSQRT_PS, "llvm.x86.sse.rsqrt.ps"},
7701 {INTRINS_SSE_RCP_PS, "llvm.x86.sse.rcp.ps"},
7702 {INTRINS_SSE_CVTTPD2DQ, "llvm.x86.sse2.cvttpd2dq"},
7703 {INTRINS_SSE_CVTTPS2DQ, "llvm.x86.sse2.cvttps2dq"},
7704 {INTRINS_SSE_CVTDQ2PD, "llvm.x86.sse2.cvtdq2pd"},
7705 {INTRINS_SSE_CVTDQ2PS, "llvm.x86.sse2.cvtdq2ps"},
7706 {INTRINS_SSE_CVTPD2DQ, "llvm.x86.sse2.cvtpd2dq"},
7707 {INTRINS_SSE_CVTPS2DQ, "llvm.x86.sse2.cvtps2dq"},
7708 {INTRINS_SSE_CVTPD2PS, "llvm.x86.sse2.cvtpd2ps"},
7709 {INTRINS_SSE_CVTPS2PD, "llvm.x86.sse2.cvtps2pd"},
7710 {INTRINS_SSE_CMPPD, "llvm.x86.sse2.cmp.pd"},
7711 {INTRINS_SSE_CMPPS, "llvm.x86.sse.cmp.ps"},
7712 {INTRINS_SSE_PACKSSWB, "llvm.x86.sse2.packsswb.128"},
7713 {INTRINS_SSE_PACKUSWB, "llvm.x86.sse2.packuswb.128"},
7714 {INTRINS_SSE_PACKSSDW, "llvm.x86.sse2.packssdw.128"},
7715 {INTRINS_SSE_PACKUSDW, "llvm.x86.sse41.packusdw"},
7716 {INTRINS_SSE_MINPS, "llvm.x86.sse.min.ps"},
7717 {INTRINS_SSE_MAXPS, "llvm.x86.sse.max.ps"},
7718 {INTRINS_SSE_HADDPS, "llvm.x86.sse3.hadd.ps"},
7719 {INTRINS_SSE_HSUBPS, "llvm.x86.sse3.hsub.ps"},
7720 {INTRINS_SSE_ADDSUBPS, "llvm.x86.sse3.addsub.ps"},
7721 {INTRINS_SSE_MINPD, "llvm.x86.sse2.min.pd"},
7722 {INTRINS_SSE_MAXPD, "llvm.x86.sse2.max.pd"},
7723 {INTRINS_SSE_HADDPD, "llvm.x86.sse3.hadd.pd"},
7724 {INTRINS_SSE_HSUBPD, "llvm.x86.sse3.hsub.pd"},
7725 {INTRINS_SSE_ADDSUBPD, "llvm.x86.sse3.addsub.pd"},
7726 {INTRINS_SSE_PMINUD, "llvm.x86.sse41.pminud"},
7727 {INTRINS_SSE_PMAXUD, "llvm.x86.sse41.pmaxud"},
7728 {INTRINS_SSE_PMINUW, "llvm.x86.sse41.pminuw"},
7729 {INTRINS_SSE_PMINSW, "llvm.x86.sse2.pmins.w"},
7730 {INTRINS_SSE_PMAXUW, "llvm.x86.sse41.pmaxuw"},
7731 {INTRINS_SSE_PADDSW, "llvm.x86.sse2.padds.w"},
7732 {INTRINS_SSE_PSUBSW, "llvm.x86.sse2.psubs.w"},
7733 {INTRINS_SSE_PADDUSW, "llvm.x86.sse2.paddus.w"},
7734 {INTRINS_SSE_PSUBUSW, "llvm.x86.sse2.psubus.w"},
7735 {INTRINS_SSE_PAVGW, "llvm.x86.sse2.pavg.w"},
7736 {INTRINS_SSE_PMULHW, "llvm.x86.sse2.pmulh.w"},
7737 {INTRINS_SSE_PMULHU, "llvm.x86.sse2.pmulhu.w"},
7738 {INTRINS_SSE_PMINUB, "llvm.x86.sse2.pminu.b"},
7739 {INTRINS_SSE_PMAXUB, "llvm.x86.sse2.pmaxu.b"},
7740 {INTRINS_SE_PADDSB, "llvm.x86.sse2.padds.b"},
7741 {INTRINS_SSE_PSUBSB, "llvm.x86.sse2.psubs.b"},
7742 {INTRINS_SSE_PADDUSB, "llvm.x86.sse2.paddus.b"},
7743 {INTRINS_SSE_PSUBUSB, "llvm.x86.sse2.psubus.b"},
7744 {INTRINS_SSE_PAVGB, "llvm.x86.sse2.pavg.b"},
7745 {INTRINS_SSE_PAUSE, "llvm.x86.sse2.pause"}
7750 add_sse_binary (LLVMModuleRef module, const char *name, int type)
7752 LLVMTypeRef ret_type = type_to_simd_type (type);
7753 AddFunc2 (module, name, ret_type, ret_type, ret_type);
7757 add_intrinsic (LLVMModuleRef module, int id)
7760 #if defined(TARGET_AMD64) || defined(TARGET_X86)
7761 LLVMTypeRef ret_type, arg_types [16];
7764 name = g_hash_table_lookup (intrins_id_to_name, GINT_TO_POINTER (id));
7768 case INTRINS_MEMSET: {
7769 LLVMTypeRef params [] = { LLVMPointerType (LLVMInt8Type (), 0), LLVMInt8Type (), LLVMInt32Type (), LLVMInt32Type (), LLVMInt1Type () };
7771 AddFunc (module, name, LLVMVoidType (), params, 5);
7774 case INTRINS_MEMCPY: {
7775 LLVMTypeRef params [] = { LLVMPointerType (LLVMInt8Type (), 0), LLVMPointerType (LLVMInt8Type (), 0), LLVMInt32Type (), LLVMInt32Type (), LLVMInt1Type () };
7777 AddFunc (module, name, LLVMVoidType (), params, 5);
7780 case INTRINS_SADD_OVF_I32:
7781 case INTRINS_UADD_OVF_I32:
7782 case INTRINS_SSUB_OVF_I32:
7783 case INTRINS_USUB_OVF_I32:
7784 case INTRINS_SMUL_OVF_I32:
7785 case INTRINS_UMUL_OVF_I32: {
7786 LLVMTypeRef ovf_res_i32 [] = { LLVMInt32Type (), LLVMInt1Type () };
7787 LLVMTypeRef params [] = { LLVMInt32Type (), LLVMInt32Type () };
7788 LLVMTypeRef ret_type = LLVMStructType (ovf_res_i32, 2, FALSE);
7790 AddFunc (module, name, ret_type, params, 2);
7793 case INTRINS_SADD_OVF_I64:
7794 case INTRINS_UADD_OVF_I64:
7795 case INTRINS_SSUB_OVF_I64:
7796 case INTRINS_USUB_OVF_I64:
7797 case INTRINS_SMUL_OVF_I64:
7798 case INTRINS_UMUL_OVF_I64: {
7799 LLVMTypeRef ovf_res_i64 [] = { LLVMInt64Type (), LLVMInt1Type () };
7800 LLVMTypeRef params [] = { LLVMInt64Type (), LLVMInt64Type () };
7801 LLVMTypeRef ret_type = LLVMStructType (ovf_res_i64, 2, FALSE);
7803 AddFunc (module, name, ret_type, params, 2);
7809 case INTRINS_FABS: {
7810 LLVMTypeRef params [] = { LLVMDoubleType () };
7812 AddFunc (module, name, LLVMDoubleType (), params, 1);
7815 case INTRINS_EXPECT_I8:
7816 AddFunc2 (module, name, LLVMInt8Type (), LLVMInt8Type (), LLVMInt8Type ());
7818 case INTRINS_EXPECT_I1:
7819 AddFunc2 (module, name, LLVMInt1Type (), LLVMInt1Type (), LLVMInt1Type ());
7821 #if defined(TARGET_AMD64) || defined(TARGET_X86)
7822 case INTRINS_SSE_PMOVMSKB:
7824 ret_type = LLVMInt32Type ();
7825 arg_types [0] = type_to_simd_type (MONO_TYPE_I1);
7826 AddFunc (module, name, ret_type, arg_types, 1);
7828 case INTRINS_SSE_PSRLI_W:
7829 case INTRINS_SSE_PSRAI_W:
7830 case INTRINS_SSE_PSLLI_W:
7832 ret_type = type_to_simd_type (MONO_TYPE_I2);
7833 arg_types [0] = ret_type;
7834 arg_types [1] = LLVMInt32Type ();
7835 AddFunc (module, name, ret_type, arg_types, 2);
7837 case INTRINS_SSE_PSRLI_D:
7838 case INTRINS_SSE_PSRAI_D:
7839 case INTRINS_SSE_PSLLI_D:
7840 ret_type = type_to_simd_type (MONO_TYPE_I4);
7841 arg_types [0] = ret_type;
7842 arg_types [1] = LLVMInt32Type ();
7843 AddFunc (module, name, ret_type, arg_types, 2);
7845 case INTRINS_SSE_PSRLI_Q:
7846 case INTRINS_SSE_PSLLI_Q:
7847 ret_type = type_to_simd_type (MONO_TYPE_I8);
7848 arg_types [0] = ret_type;
7849 arg_types [1] = LLVMInt32Type ();
7850 AddFunc (module, name, ret_type, arg_types, 2);
7852 case INTRINS_SSE_SQRT_PD:
7854 ret_type = type_to_simd_type (MONO_TYPE_R8);
7855 arg_types [0] = ret_type;
7856 AddFunc (module, name, ret_type, arg_types, 1);
7858 case INTRINS_SSE_SQRT_PS:
7859 ret_type = type_to_simd_type (MONO_TYPE_R4);
7860 arg_types [0] = ret_type;
7861 AddFunc (module, name, ret_type, arg_types, 1);
7863 case INTRINS_SSE_RSQRT_PS:
7864 ret_type = type_to_simd_type (MONO_TYPE_R4);
7865 arg_types [0] = ret_type;
7866 AddFunc (module, name, ret_type, arg_types, 1);
7868 case INTRINS_SSE_RCP_PS:
7869 ret_type = type_to_simd_type (MONO_TYPE_R4);
7870 arg_types [0] = ret_type;
7871 AddFunc (module, name, ret_type, arg_types, 1);
7873 case INTRINS_SSE_CVTTPD2DQ:
7874 ret_type = type_to_simd_type (MONO_TYPE_I4);
7875 arg_types [0] = type_to_simd_type (MONO_TYPE_R8);
7876 AddFunc (module, name, ret_type, arg_types, 1);
7878 case INTRINS_SSE_CVTTPS2DQ:
7879 ret_type = type_to_simd_type (MONO_TYPE_I4);
7880 arg_types [0] = type_to_simd_type (MONO_TYPE_R4);
7881 AddFunc (module, name, ret_type, arg_types, 1);
7883 case INTRINS_SSE_CVTDQ2PD:
7884 /* Conversion ops */
7885 ret_type = type_to_simd_type (MONO_TYPE_R8);
7886 arg_types [0] = type_to_simd_type (MONO_TYPE_I4);
7887 AddFunc (module, name, ret_type, arg_types, 1);
7889 case INTRINS_SSE_CVTDQ2PS:
7890 ret_type = type_to_simd_type (MONO_TYPE_R4);
7891 arg_types [0] = type_to_simd_type (MONO_TYPE_I4);
7892 AddFunc (module, name, ret_type, arg_types, 1);
7894 case INTRINS_SSE_CVTPD2DQ:
7895 ret_type = type_to_simd_type (MONO_TYPE_I4);
7896 arg_types [0] = type_to_simd_type (MONO_TYPE_R8);
7897 AddFunc (module, name, ret_type, arg_types, 1);
7899 case INTRINS_SSE_CVTPS2DQ:
7900 ret_type = type_to_simd_type (MONO_TYPE_I4);
7901 arg_types [0] = type_to_simd_type (MONO_TYPE_R4);
7902 AddFunc (module, name, ret_type, arg_types, 1);
7904 case INTRINS_SSE_CVTPD2PS:
7905 ret_type = type_to_simd_type (MONO_TYPE_R4);
7906 arg_types [0] = type_to_simd_type (MONO_TYPE_R8);
7907 AddFunc (module, name, ret_type, arg_types, 1);
7909 case INTRINS_SSE_CVTPS2PD:
7910 ret_type = type_to_simd_type (MONO_TYPE_R8);
7911 arg_types [0] = type_to_simd_type (MONO_TYPE_R4);
7912 AddFunc (module, name, ret_type, arg_types, 1);
7914 case INTRINS_SSE_CMPPD:
7916 ret_type = type_to_simd_type (MONO_TYPE_R8);
7917 arg_types [0] = ret_type;
7918 arg_types [1] = ret_type;
7919 arg_types [2] = LLVMInt8Type ();
7920 AddFunc (module, name, ret_type, arg_types, 3);
7922 case INTRINS_SSE_CMPPS:
7923 ret_type = type_to_simd_type (MONO_TYPE_R4);
7924 arg_types [0] = ret_type;
7925 arg_types [1] = ret_type;
7926 arg_types [2] = LLVMInt8Type ();
7927 AddFunc (module, name, ret_type, arg_types, 3);
7929 case INTRINS_SSE_PACKSSWB:
7930 case INTRINS_SSE_PACKUSWB:
7931 case INTRINS_SSE_PACKSSDW:
7933 ret_type = type_to_simd_type (MONO_TYPE_I1);
7934 arg_types [0] = type_to_simd_type (MONO_TYPE_I2);
7935 arg_types [1] = type_to_simd_type (MONO_TYPE_I2);
7936 AddFunc (module, name, ret_type, arg_types, 2);
7938 case INTRINS_SSE_PACKUSDW:
7939 ret_type = type_to_simd_type (MONO_TYPE_I2);
7940 arg_types [0] = type_to_simd_type (MONO_TYPE_I4);
7941 arg_types [1] = type_to_simd_type (MONO_TYPE_I4);
7942 AddFunc (module, name, ret_type, arg_types, 2);
7944 /* SSE Binary ops */
7945 case INTRINS_SSE_PMINUD:
7946 case INTRINS_SSE_PMAXUD:
7947 add_sse_binary (module, name, MONO_TYPE_I4);
7949 case INTRINS_SSE_PMINUW:
7950 case INTRINS_SSE_PMINSW:
7951 case INTRINS_SSE_PMAXUW:
7952 case INTRINS_SSE_PADDSW:
7953 case INTRINS_SSE_PSUBSW:
7954 case INTRINS_SSE_PADDUSW:
7955 case INTRINS_SSE_PSUBUSW:
7956 case INTRINS_SSE_PAVGW:
7957 case INTRINS_SSE_PMULHW:
7958 case INTRINS_SSE_PMULHU:
7959 add_sse_binary (module, name, MONO_TYPE_I2);
7961 case INTRINS_SSE_MINPS:
7962 case INTRINS_SSE_MAXPS:
7963 case INTRINS_SSE_HADDPS:
7964 case INTRINS_SSE_HSUBPS:
7965 case INTRINS_SSE_ADDSUBPS:
7966 add_sse_binary (module, name, MONO_TYPE_R4);
7968 case INTRINS_SSE_MINPD:
7969 case INTRINS_SSE_MAXPD:
7970 case INTRINS_SSE_HADDPD:
7971 case INTRINS_SSE_HSUBPD:
7972 case INTRINS_SSE_ADDSUBPD:
7973 add_sse_binary (module, name, MONO_TYPE_R8);
7975 case INTRINS_SSE_PMINUB:
7976 case INTRINS_SSE_PMAXUB:
7977 case INTRINS_SE_PADDSB:
7978 case INTRINS_SSE_PSUBSB:
7979 case INTRINS_SSE_PADDUSB:
7980 case INTRINS_SSE_PSUBUSB:
7981 case INTRINS_SSE_PAVGB:
7982 add_sse_binary (module, name, MONO_TYPE_I1);
7984 case INTRINS_SSE_PAUSE:
7985 AddFunc (module, "llvm.x86.sse2.pause", LLVMVoidType (), NULL, 0);
7989 g_assert_not_reached ();
7995 get_intrinsic (EmitContext *ctx, const char *name)
7997 #if LLVM_API_VERSION > 100
8001 * Every method is emitted into its own module so
8002 * we can add intrinsics on demand.
8004 res = LLVMGetNamedFunction (ctx->lmodule, name);
8008 /* No locking needed */
8009 id = GPOINTER_TO_INT (g_hash_table_lookup (intrins_name_to_id, name));
8012 printf ("%s\n", name);
8013 g_assert (id != -1);
8014 add_intrinsic (ctx->lmodule, id);
8015 res = LLVMGetNamedFunction (ctx->lmodule, name);
8023 res = LLVMGetNamedFunction (ctx->lmodule, name);
8030 add_intrinsics (LLVMModuleRef module)
8034 /* Emit declarations of instrinsics */
8036 * It would be nicer to emit only the intrinsics actually used, but LLVM's Module
8037 * type doesn't seem to do any locking.
8039 for (i = 0; i < INTRINS_NUM; ++i)
8040 add_intrinsic (module, i);
8044 AddFunc (module, "mono_personality", LLVMVoidType (), NULL, 0);
8046 AddFunc (module, "llvm_resume_unwind_trampoline", LLVMVoidType (), NULL, 0);
8049 /* SSE intrinsics */
8050 #if defined(TARGET_X86) || defined(TARGET_AMD64)
8054 /* Load/Store intrinsics */
8056 LLVMTypeRef arg_types [5];
8060 for (i = 1; i <= 8; i *= 2) {
8061 arg_types [0] = LLVMPointerType (LLVMIntType (i * 8), 0);
8062 arg_types [1] = LLVMInt32Type ();
8063 arg_types [2] = LLVMInt1Type ();
8064 arg_types [3] = LLVMInt32Type ();
8065 sprintf (name, "llvm.mono.load.i%d.p0i%d", i * 8, i * 8);
8066 AddFunc (module, name, LLVMIntType (i * 8), arg_types, 4);
8068 arg_types [0] = LLVMIntType (i * 8);
8069 arg_types [1] = LLVMPointerType (LLVMIntType (i * 8), 0);
8070 arg_types [2] = LLVMInt32Type ();
8071 arg_types [3] = LLVMInt1Type ();
8072 arg_types [4] = LLVMInt32Type ();
8073 sprintf (name, "llvm.mono.store.i%d.p0i%d", i * 8, i * 8);
8074 AddFunc (module, name, LLVMVoidType (), arg_types, 5);
8080 add_types (MonoLLVMModule *module)
8082 module->ptr_type = LLVMPointerType (sizeof (gpointer) == 8 ? LLVMInt64Type () : LLVMInt32Type (), 0);
8086 mono_llvm_init (void)
8091 mono_native_tls_alloc (¤t_cfg_tls_id, NULL);
8093 h = g_hash_table_new (NULL, NULL);
8094 for (i = 0; i < INTRINS_NUM; ++i)
8095 g_hash_table_insert (h, GINT_TO_POINTER (intrinsics [i].id), (gpointer)intrinsics [i].name);
8096 intrins_id_to_name = h;
8098 h = g_hash_table_new (g_str_hash, g_str_equal);
8099 for (i = 0; i < INTRINS_NUM; ++i)
8100 g_hash_table_insert (h, (gpointer)intrinsics [i].name, GINT_TO_POINTER (intrinsics [i].id + 1));
8101 intrins_name_to_id = h;
8105 init_jit_module (MonoDomain *domain)
8107 MonoJitDomainInfo *dinfo;
8108 MonoLLVMModule *module;
8111 dinfo = domain_jit_info (domain);
8112 if (dinfo->llvm_module)
8115 mono_loader_lock ();
8117 if (dinfo->llvm_module) {
8118 mono_loader_unlock ();
8122 module = g_new0 (MonoLLVMModule, 1);
8124 name = g_strdup_printf ("mono-%s", domain->friendly_name);
8125 module->lmodule = LLVMModuleCreateWithName (name);
8126 module->context = LLVMGetGlobalContext ();
8128 module->mono_ee = (MonoEERef*)mono_llvm_create_ee (LLVMCreateModuleProviderForExistingModule (module->lmodule), alloc_cb, emitted_cb, exception_cb, dlsym_cb, &module->ee);
8130 add_intrinsics (module->lmodule);
8133 module->llvm_types = g_hash_table_new (NULL, NULL);
8135 #if LLVM_API_VERSION < 100
8136 MonoJitICallInfo *info;
8138 info = mono_find_jit_icall_by_name ("llvm_resume_unwind_trampoline");
8140 LLVMAddGlobalMapping (module->ee, LLVMGetNamedFunction (module->lmodule, "llvm_resume_unwind_trampoline"), (void*)info->func);
8143 mono_memory_barrier ();
8145 dinfo->llvm_module = module;
8147 mono_loader_unlock ();
8151 mono_llvm_cleanup (void)
8153 MonoLLVMModule *module = &aot_module;
8155 if (module->lmodule)
8156 LLVMDisposeModule (module->lmodule);
8158 if (module->context)
8159 LLVMContextDispose (module->context);
8163 mono_llvm_free_domain_info (MonoDomain *domain)
8165 MonoJitDomainInfo *info = domain_jit_info (domain);
8166 MonoLLVMModule *module = (MonoLLVMModule*)info->llvm_module;
8172 if (module->llvm_types)
8173 g_hash_table_destroy (module->llvm_types);
8175 mono_llvm_dispose_ee (module->mono_ee);
8177 if (module->bb_names) {
8178 for (i = 0; i < module->bb_names_len; ++i)
8179 g_free (module->bb_names [i]);
8180 g_free (module->bb_names);
8182 //LLVMDisposeModule (module->module);
8186 info->llvm_module = NULL;
8190 mono_llvm_create_aot_module (MonoAssembly *assembly, const char *global_prefix, gboolean emit_dwarf, gboolean static_link, gboolean llvm_only)
8192 MonoLLVMModule *module = &aot_module;
8194 /* Delete previous module */
8195 if (module->plt_entries)
8196 g_hash_table_destroy (module->plt_entries);
8197 if (module->lmodule)
8198 LLVMDisposeModule (module->lmodule);
8200 memset (module, 0, sizeof (aot_module));
8202 module->lmodule = LLVMModuleCreateWithName ("aot");
8203 module->assembly = assembly;
8204 module->global_prefix = g_strdup (global_prefix);
8205 module->got_symbol = g_strdup_printf ("%s_llvm_got", global_prefix);
8206 module->eh_frame_symbol = g_strdup_printf ("%s_eh_frame", global_prefix);
8207 module->get_method_symbol = g_strdup_printf ("%s_get_method", global_prefix);
8208 module->get_unbox_tramp_symbol = g_strdup_printf ("%s_get_unbox_tramp", global_prefix);
8209 module->external_symbols = TRUE;
8210 module->emit_dwarf = emit_dwarf;
8211 module->static_link = static_link;
8212 module->llvm_only = llvm_only;
8213 /* The first few entries are reserved */
8214 module->max_got_offset = 16;
8215 module->context = LLVMContextCreate ();
8218 /* clang ignores our debug info because it has an invalid version */
8219 module->emit_dwarf = FALSE;
8221 #if LLVM_API_VERSION > 100
8222 module->emit_dwarf = FALSE;
8225 add_intrinsics (module->lmodule);
8228 #if LLVM_API_VERSION > 100
8229 if (module->emit_dwarf) {
8230 char *dir, *build_info, *s, *cu_name;
8232 module->di_builder = mono_llvm_create_di_builder (module->lmodule);
8235 dir = g_strdup (".");
8236 build_info = mono_get_runtime_build_info ();
8237 s = g_strdup_printf ("Mono AOT Compiler %s (LLVM)", build_info);
8238 cu_name = g_path_get_basename (assembly->image->name);
8239 module->cu = mono_llvm_di_create_compile_unit (module->di_builder, cu_name, dir, s);
8241 g_free (build_info);
8248 * We couldn't compute the type of the LLVM global representing the got because
8249 * its size is only known after all the methods have been emitted. So create
8250 * a dummy variable, and replace all uses it with the real got variable when
8251 * its size is known in mono_llvm_emit_aot_module ().
8254 LLVMTypeRef got_type = LLVMArrayType (module->ptr_type, 0);
8256 module->got_var = LLVMAddGlobal (module->lmodule, got_type, "mono_dummy_got");
8257 LLVMSetInitializer (module->got_var, LLVMConstNull (got_type));
8260 /* Add initialization array */
8262 LLVMTypeRef inited_type = LLVMArrayType (LLVMInt8Type (), 0);
8264 module->inited_var = LLVMAddGlobal (aot_module.lmodule, inited_type, "mono_inited_tmp");
8265 LLVMSetInitializer (module->inited_var, LLVMConstNull (inited_type));
8269 emit_init_icall_wrappers (module);
8271 emit_llvm_code_start (module);
8273 /* Add a dummy personality function */
8274 if (!use_debug_personality) {
8275 LLVMValueRef personality = LLVMAddFunction (module->lmodule, default_personality_name, LLVMFunctionType (LLVMInt32Type (), NULL, 0, TRUE));
8276 LLVMSetLinkage (personality, LLVMExternalLinkage);
8277 mark_as_used (module, personality);
8280 /* Add a reference to the c++ exception we throw/catch */
8282 LLVMTypeRef exc = LLVMPointerType (LLVMInt8Type (), 0);
8283 module->sentinel_exception = LLVMAddGlobal (module->lmodule, exc, "_ZTIPi");
8284 LLVMSetLinkage (module->sentinel_exception, LLVMExternalLinkage);
8285 mono_llvm_set_is_constant (module->sentinel_exception);
8288 module->llvm_types = g_hash_table_new (NULL, NULL);
8289 module->plt_entries = g_hash_table_new (g_str_hash, g_str_equal);
8290 module->plt_entries_ji = g_hash_table_new (NULL, NULL);
8291 module->direct_callables = g_hash_table_new (g_str_hash, g_str_equal);
8292 module->method_to_lmethod = g_hash_table_new (NULL, NULL);
8293 module->idx_to_lmethod = g_hash_table_new (NULL, NULL);
8294 module->idx_to_unbox_tramp = g_hash_table_new (NULL, NULL);
8295 module->method_to_callers = g_hash_table_new (NULL, NULL);
8299 llvm_array_from_uints (LLVMTypeRef el_type, guint32 *values, int nvalues)
8302 LLVMValueRef res, *vals;
8304 vals = g_new0 (LLVMValueRef, nvalues);
8305 for (i = 0; i < nvalues; ++i)
8306 vals [i] = LLVMConstInt (LLVMInt32Type (), values [i], FALSE);
8307 res = LLVMConstArray (LLVMInt32Type (), vals, nvalues);
8313 * mono_llvm_emit_aot_file_info:
8315 * Emit the MonoAotFileInfo structure.
8316 * Same as emit_aot_file_info () in aot-compiler.c.
8319 mono_llvm_emit_aot_file_info (MonoAotFileInfo *info, gboolean has_jitted_code)
8321 MonoLLVMModule *module = &aot_module;
8323 /* Save these for later */
8324 memcpy (&module->aot_info, info, sizeof (MonoAotFileInfo));
8325 module->has_jitted_code = has_jitted_code;
8329 * mono_llvm_emit_aot_data:
8331 * Emit the binary data DATA pointed to by symbol SYMBOL.
8334 mono_llvm_emit_aot_data (const char *symbol, guint8 *data, int data_len)
8336 MonoLLVMModule *module = &aot_module;
8340 type = LLVMArrayType (LLVMInt8Type (), data_len);
8341 d = LLVMAddGlobal (module->lmodule, type, symbol);
8342 LLVMSetVisibility (d, LLVMHiddenVisibility);
8343 LLVMSetLinkage (d, LLVMInternalLinkage);
8344 LLVMSetInitializer (d, mono_llvm_create_constant_data_array (data, data_len));
8345 mono_llvm_set_is_constant (d);
8348 /* Add a reference to a global defined in JITted code */
8350 AddJitGlobal (MonoLLVMModule *module, LLVMTypeRef type, const char *name)
8355 s = g_strdup_printf ("%s%s", module->global_prefix, name);
8356 v = LLVMAddGlobal (module->lmodule, LLVMInt8Type (), s);
8362 emit_aot_file_info (MonoLLVMModule *module)
8364 LLVMTypeRef file_info_type;
8365 LLVMTypeRef *eltypes, eltype;
8366 LLVMValueRef info_var;
8367 LLVMValueRef *fields;
8368 int i, nfields, tindex;
8369 MonoAotFileInfo *info;
8370 LLVMModuleRef lmodule = module->lmodule;
8372 info = &module->aot_info;
8374 /* Create an LLVM type to represent MonoAotFileInfo */
8375 nfields = 2 + MONO_AOT_FILE_INFO_NUM_SYMBOLS + 15 + 5;
8376 eltypes = g_new (LLVMTypeRef, nfields);
8378 eltypes [tindex ++] = LLVMInt32Type ();
8379 eltypes [tindex ++] = LLVMInt32Type ();
8381 for (i = 0; i < MONO_AOT_FILE_INFO_NUM_SYMBOLS; ++i)
8382 eltypes [tindex ++] = LLVMPointerType (LLVMInt8Type (), 0);
8384 for (i = 0; i < 15; ++i)
8385 eltypes [tindex ++] = LLVMInt32Type ();
8387 eltypes [tindex ++] = LLVMArrayType (LLVMInt32Type (), MONO_AOT_TABLE_NUM);
8388 for (i = 0; i < 4; ++i)
8389 eltypes [tindex ++] = LLVMArrayType (LLVMInt32Type (), MONO_AOT_TRAMP_NUM);
8390 g_assert (tindex == nfields);
8391 file_info_type = LLVMStructCreateNamed (module->context, "MonoAotFileInfo");
8392 LLVMStructSetBody (file_info_type, eltypes, nfields, FALSE);
8394 info_var = LLVMAddGlobal (lmodule, file_info_type, "mono_aot_file_info");
8395 if (module->static_link) {
8396 LLVMSetVisibility (info_var, LLVMHiddenVisibility);
8397 LLVMSetLinkage (info_var, LLVMInternalLinkage);
8399 fields = g_new (LLVMValueRef, nfields);
8401 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->version, FALSE);
8402 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->dummy, FALSE);
8406 * We use LLVMGetNamedGlobal () for symbol which are defined in LLVM code, and LLVMAddGlobal ()
8407 * for symbols defined in the .s file emitted by the aot compiler.
8409 eltype = eltypes [tindex];
8410 if (module->llvm_only)
8411 fields [tindex ++] = LLVMConstNull (eltype);
8413 fields [tindex ++] = AddJitGlobal (module, eltype, "jit_got");
8414 fields [tindex ++] = module->got_var;
8415 /* llc defines this directly */
8416 if (!module->llvm_only) {
8417 fields [tindex ++] = LLVMAddGlobal (lmodule, eltype, module->eh_frame_symbol);
8418 fields [tindex ++] = LLVMConstNull (eltype);
8419 fields [tindex ++] = LLVMConstNull (eltype);
8421 fields [tindex ++] = LLVMConstNull (eltype);
8422 fields [tindex ++] = module->get_method;
8423 fields [tindex ++] = module->get_unbox_tramp;
8425 if (module->has_jitted_code) {
8426 fields [tindex ++] = AddJitGlobal (module, eltype, "jit_code_start");
8427 fields [tindex ++] = AddJitGlobal (module, eltype, "jit_code_end");
8429 fields [tindex ++] = LLVMConstNull (eltype);
8430 fields [tindex ++] = LLVMConstNull (eltype);
8432 if (!module->llvm_only)
8433 fields [tindex ++] = AddJitGlobal (module, eltype, "method_addresses");
8435 fields [tindex ++] = LLVMConstNull (eltype);
8436 if (info->flags & MONO_AOT_FILE_FLAG_SEPARATE_DATA) {
8437 for (i = 0; i < MONO_AOT_TABLE_NUM; ++i)
8438 fields [tindex ++] = LLVMConstNull (eltype);
8440 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "blob");
8441 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "class_name_table");
8442 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "class_info_offsets");
8443 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "method_info_offsets");
8444 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "ex_info_offsets");
8445 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "extra_method_info_offsets");
8446 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "extra_method_table");
8447 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "got_info_offsets");
8448 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "llvm_got_info_offsets");
8449 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "image_table");
8451 /* Not needed (mem_end) */
8452 fields [tindex ++] = LLVMConstNull (eltype);
8453 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "assembly_guid");
8454 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "runtime_version");
8455 if (info->trampoline_size [0]) {
8456 fields [tindex ++] = AddJitGlobal (module, eltype, "specific_trampolines");
8457 fields [tindex ++] = AddJitGlobal (module, eltype, "static_rgctx_trampolines");
8458 fields [tindex ++] = AddJitGlobal (module, eltype, "imt_thunks");
8459 fields [tindex ++] = AddJitGlobal (module, eltype, "gsharedvt_arg_trampolines");
8461 fields [tindex ++] = LLVMConstNull (eltype);
8462 fields [tindex ++] = LLVMConstNull (eltype);
8463 fields [tindex ++] = LLVMConstNull (eltype);
8464 fields [tindex ++] = LLVMConstNull (eltype);
8466 if (module->static_link && !module->llvm_only)
8467 fields [tindex ++] = AddJitGlobal (module, eltype, "globals");
8469 fields [tindex ++] = LLVMConstNull (eltype);
8470 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "assembly_name");
8471 if (!module->llvm_only) {
8472 fields [tindex ++] = AddJitGlobal (module, eltype, "plt");
8473 fields [tindex ++] = AddJitGlobal (module, eltype, "plt_end");
8474 fields [tindex ++] = AddJitGlobal (module, eltype, "unwind_info");
8475 fields [tindex ++] = AddJitGlobal (module, eltype, "unbox_trampolines");
8476 fields [tindex ++] = AddJitGlobal (module, eltype, "unbox_trampolines_end");
8477 fields [tindex ++] = AddJitGlobal (module, eltype, "unbox_trampoline_addresses");
8479 fields [tindex ++] = LLVMConstNull (eltype);
8480 fields [tindex ++] = LLVMConstNull (eltype);
8481 fields [tindex ++] = LLVMConstNull (eltype);
8482 fields [tindex ++] = LLVMConstNull (eltype);
8483 fields [tindex ++] = LLVMConstNull (eltype);
8484 fields [tindex ++] = LLVMConstNull (eltype);
8487 for (i = 0; i < MONO_AOT_FILE_INFO_NUM_SYMBOLS; ++i)
8488 fields [2 + i] = LLVMConstBitCast (fields [2 + i], eltype);
8491 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->plt_got_offset_base, FALSE);
8492 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->got_size, FALSE);
8493 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->plt_size, FALSE);
8494 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->nmethods, FALSE);
8495 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->flags, FALSE);
8496 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->opts, FALSE);
8497 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->simd_opts, FALSE);
8498 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->gc_name_index, FALSE);
8499 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->num_rgctx_fetch_trampolines, FALSE);
8500 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->double_align, FALSE);
8501 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->long_align, FALSE);
8502 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->generic_tramp_num, FALSE);
8503 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->tramp_page_size, FALSE);
8504 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->nshared_got_entries, FALSE);
8505 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->datafile_size, FALSE);
8507 fields [tindex ++] = llvm_array_from_uints (LLVMInt32Type (), info->table_offsets, MONO_AOT_TABLE_NUM);
8508 fields [tindex ++] = llvm_array_from_uints (LLVMInt32Type (), info->num_trampolines, MONO_AOT_TRAMP_NUM);
8509 fields [tindex ++] = llvm_array_from_uints (LLVMInt32Type (), info->trampoline_got_offset_base, MONO_AOT_TRAMP_NUM);
8510 fields [tindex ++] = llvm_array_from_uints (LLVMInt32Type (), info->trampoline_size, MONO_AOT_TRAMP_NUM);
8511 fields [tindex ++] = llvm_array_from_uints (LLVMInt32Type (), info->tramp_page_code_offsets, MONO_AOT_TRAMP_NUM);
8512 g_assert (tindex == nfields);
8514 LLVMSetInitializer (info_var, LLVMConstNamedStruct (file_info_type, fields, nfields));
8516 if (module->static_link) {
8520 s = g_strdup_printf ("mono_aot_module_%s_info", module->assembly->aname.name);
8521 /* Get rid of characters which cannot occur in symbols */
8523 for (p = s; *p; ++p) {
8524 if (!(isalnum (*p) || *p == '_'))
8527 var = LLVMAddGlobal (module->lmodule, LLVMPointerType (LLVMInt8Type (), 0), s);
8529 LLVMSetInitializer (var, LLVMConstBitCast (LLVMGetNamedGlobal (module->lmodule, "mono_aot_file_info"), LLVMPointerType (LLVMInt8Type (), 0)));
8530 LLVMSetLinkage (var, LLVMExternalLinkage);
8535 * Emit the aot module into the LLVM bitcode file FILENAME.
8538 mono_llvm_emit_aot_module (const char *filename, const char *cu_name)
8540 LLVMTypeRef got_type, inited_type;
8541 LLVMValueRef real_got, real_inited;
8542 MonoLLVMModule *module = &aot_module;
8544 emit_llvm_code_end (module);
8547 * Create the real got variable and replace all uses of the dummy variable with
8550 got_type = LLVMArrayType (module->ptr_type, module->max_got_offset + 1);
8551 real_got = LLVMAddGlobal (module->lmodule, got_type, module->got_symbol);
8552 LLVMSetInitializer (real_got, LLVMConstNull (got_type));
8553 if (module->external_symbols) {
8554 LLVMSetLinkage (real_got, LLVMExternalLinkage);
8555 LLVMSetVisibility (real_got, LLVMHiddenVisibility);
8557 LLVMSetLinkage (real_got, LLVMInternalLinkage);
8559 mono_llvm_replace_uses_of (module->got_var, real_got);
8561 mark_as_used (&aot_module, real_got);
8563 /* Delete the dummy got so it doesn't become a global */
8564 LLVMDeleteGlobal (module->got_var);
8565 module->got_var = real_got;
8568 * Same for the init_var
8570 if (module->llvm_only) {
8571 inited_type = LLVMArrayType (LLVMInt8Type (), module->max_inited_idx + 1);
8572 real_inited = LLVMAddGlobal (module->lmodule, inited_type, "mono_inited");
8573 LLVMSetInitializer (real_inited, LLVMConstNull (inited_type));
8574 LLVMSetLinkage (real_inited, LLVMInternalLinkage);
8575 mono_llvm_replace_uses_of (module->inited_var, real_inited);
8576 LLVMDeleteGlobal (module->inited_var);
8579 if (module->llvm_only) {
8580 emit_get_method (&aot_module);
8581 emit_get_unbox_tramp (&aot_module);
8584 emit_llvm_used (&aot_module);
8585 emit_dbg_info (&aot_module, filename, cu_name);
8586 emit_aot_file_info (&aot_module);
8589 * Replace GOT entries for directly callable methods with the methods themselves.
8590 * It would be easier to implement this by predefining all methods before compiling
8591 * their bodies, but that couldn't handle the case when a method fails to compile
8594 if (module->llvm_only) {
8595 GHashTableIter iter;
8597 GSList *callers, *l;
8599 g_hash_table_iter_init (&iter, module->method_to_callers);
8600 while (g_hash_table_iter_next (&iter, (void**)&method, (void**)&callers)) {
8601 LLVMValueRef lmethod;
8603 lmethod = (LLVMValueRef)g_hash_table_lookup (module->method_to_lmethod, method);
8605 for (l = callers; l; l = l->next) {
8606 LLVMValueRef caller = (LLVMValueRef)l->data;
8608 mono_llvm_replace_uses_of (caller, lmethod);
8614 /* Replace PLT entries for directly callable methods with the methods themselves */
8616 GHashTableIter iter;
8618 LLVMValueRef callee;
8620 g_hash_table_iter_init (&iter, module->plt_entries_ji);
8621 while (g_hash_table_iter_next (&iter, (void**)&ji, (void**)&callee)) {
8622 if (mono_aot_is_direct_callable (ji)) {
8623 LLVMValueRef lmethod;
8625 lmethod = (LLVMValueRef)g_hash_table_lookup (module->method_to_lmethod, ji->data.method);
8626 /* The types might not match because the caller might pass an rgctx */
8627 if (lmethod && LLVMTypeOf (callee) == LLVMTypeOf (lmethod)) {
8628 mono_llvm_replace_uses_of (callee, lmethod);
8629 mono_aot_mark_unused_llvm_plt_entry (ji);
8639 if (LLVMVerifyModule (module->lmodule, LLVMReturnStatusAction, &verifier_err)) {
8640 g_assert_not_reached ();
8645 LLVMWriteBitcodeToFile (module->lmodule, filename);
8650 md_string (const char *s)
8652 return LLVMMDString (s, strlen (s));
8655 /* Debugging support */
8658 emit_dbg_info (MonoLLVMModule *module, const char *filename, const char *cu_name)
8660 LLVMModuleRef lmodule = module->lmodule;
8661 LLVMValueRef args [16], ver;
8664 * This can only be enabled when LLVM code is emitted into a separate object
8665 * file, since the AOT compiler also emits dwarf info,
8666 * and the abbrev indexes will not be correct since llvm has added its own
8669 if (!module->emit_dwarf)
8672 #if LLVM_API_VERSION > 100
8673 mono_llvm_di_builder_finalize (module->di_builder);
8675 LLVMValueRef cu_args [16], cu;
8677 char *build_info, *s, *dir;
8680 * Emit dwarf info in the form of LLVM metadata. There is some
8681 * out-of-date documentation at:
8682 * http://llvm.org/docs/SourceLevelDebugging.html
8683 * but most of this was gathered from the llvm and
8688 cu_args [n_cuargs ++] = LLVMConstInt (LLVMInt32Type (), DW_TAG_compile_unit, FALSE);
8689 /* CU name/compilation dir */
8690 dir = g_path_get_dirname (filename);
8691 args [0] = LLVMMDString (cu_name, strlen (cu_name));
8692 args [1] = LLVMMDString (dir, strlen (dir));
8693 cu_args [n_cuargs ++] = LLVMMDNode (args, 2);
8696 cu_args [n_cuargs ++] = LLVMConstInt (LLVMInt32Type (), DW_LANG_C99, FALSE);
8698 build_info = mono_get_runtime_build_info ();
8699 s = g_strdup_printf ("Mono AOT Compiler %s (LLVM)", build_info);
8700 cu_args [n_cuargs ++] = LLVMMDString (s, strlen (s));
8701 g_free (build_info);
8703 cu_args [n_cuargs ++] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
8705 cu_args [n_cuargs ++] = LLVMMDString ("", strlen (""));
8706 /* Runtime version */
8707 cu_args [n_cuargs ++] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
8709 cu_args [n_cuargs ++] = LLVMMDNode (args, 0);
8710 cu_args [n_cuargs ++] = LLVMMDNode (args, 0);
8712 if (module->subprogram_mds) {
8716 mds = g_new0 (LLVMValueRef, module->subprogram_mds->len);
8717 for (i = 0; i < module->subprogram_mds->len; ++i)
8718 mds [i] = (LLVMValueRef)g_ptr_array_index (module->subprogram_mds, i);
8719 cu_args [n_cuargs ++] = LLVMMDNode (mds, module->subprogram_mds->len);
8721 cu_args [n_cuargs ++] = LLVMMDNode (args, 0);
8724 cu_args [n_cuargs ++] = LLVMMDNode (args, 0);
8725 /* Imported modules */
8726 cu_args [n_cuargs ++] = LLVMMDNode (args, 0);
8728 cu_args [n_cuargs ++] = LLVMMDString ("", strlen (""));
8729 /* DebugEmissionKind = FullDebug */
8730 cu_args [n_cuargs ++] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
8731 cu = LLVMMDNode (cu_args, n_cuargs);
8732 LLVMAddNamedMetadataOperand (lmodule, "llvm.dbg.cu", cu);
8735 #if LLVM_API_VERSION > 100
8736 args [0] = LLVMConstInt (LLVMInt32Type (), 2, FALSE);
8737 args [1] = LLVMMDString ("Dwarf Version", strlen ("Dwarf Version"));
8738 args [2] = LLVMConstInt (LLVMInt32Type (), 2, FALSE);
8739 ver = LLVMMDNode (args, 3);
8740 LLVMAddNamedMetadataOperand (lmodule, "llvm.module.flags", ver);
8742 args [0] = LLVMConstInt (LLVMInt32Type (), 2, FALSE);
8743 args [1] = LLVMMDString ("Debug Info Version", strlen ("Debug Info Version"));
8744 args [2] = LLVMConstInt (LLVMInt64Type (), 3, FALSE);
8745 ver = LLVMMDNode (args, 3);
8746 LLVMAddNamedMetadataOperand (lmodule, "llvm.module.flags", ver);
8748 args [0] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
8749 args [1] = LLVMMDString ("Dwarf Version", strlen ("Dwarf Version"));
8750 args [2] = LLVMConstInt (LLVMInt32Type (), 2, FALSE);
8751 ver = LLVMMDNode (args, 3);
8752 LLVMAddNamedMetadataOperand (lmodule, "llvm.module.flags", ver);
8754 args [0] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
8755 args [1] = LLVMMDString ("Debug Info Version", strlen ("Debug Info Version"));
8756 args [2] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
8757 ver = LLVMMDNode (args, 3);
8758 LLVMAddNamedMetadataOperand (lmodule, "llvm.module.flags", ver);
8763 emit_dbg_subprogram (EmitContext *ctx, MonoCompile *cfg, LLVMValueRef method, const char *name)
8765 MonoLLVMModule *module = ctx->module;
8766 MonoDebugMethodInfo *minfo = ctx->minfo;
8767 char *source_file, *dir, *filename;
8768 LLVMValueRef md, args [16], ctx_args [16], md_args [64], type_args [16], ctx_md, type_md;
8769 MonoSymSeqPoint *sym_seq_points;
8775 mono_debug_symfile_get_seq_points (minfo, &source_file, NULL, NULL, &sym_seq_points, &n_seq_points);
8777 source_file = g_strdup ("<unknown>");
8778 dir = g_path_get_dirname (source_file);
8779 filename = g_path_get_basename (source_file);
8781 #if LLVM_API_VERSION > 100
8782 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);
8785 ctx_args [0] = LLVMConstInt (LLVMInt32Type (), 0x29, FALSE);
8786 args [0] = md_string (filename);
8787 args [1] = md_string (dir);
8788 ctx_args [1] = LLVMMDNode (args, 2);
8789 ctx_md = LLVMMDNode (ctx_args, 2);
8791 type_args [0] = LLVMConstInt (LLVMInt32Type (), DW_TAG_subroutine_type, FALSE);
8792 type_args [1] = NULL;
8793 type_args [2] = NULL;
8794 type_args [3] = LLVMMDString ("", 0);
8795 type_args [4] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
8796 type_args [5] = LLVMConstInt (LLVMInt64Type (), 0, FALSE);
8797 type_args [6] = LLVMConstInt (LLVMInt64Type (), 0, FALSE);
8798 type_args [7] = LLVMConstInt (LLVMInt64Type (), 0, FALSE);
8799 type_args [8] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
8800 type_args [9] = NULL;
8801 type_args [10] = NULL;
8802 type_args [11] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
8803 type_args [12] = NULL;
8804 type_args [13] = NULL;
8805 type_args [14] = NULL;
8806 type_md = LLVMMDNode (type_args, 14);
8808 /* http://llvm.org/docs/SourceLevelDebugging.html#subprogram-descriptors */
8809 md_args [0] = LLVMConstInt (LLVMInt32Type (), DW_TAG_subprogram, FALSE);
8810 /* Source directory + file pair */
8811 args [0] = md_string (filename);
8812 args [1] = md_string (dir);
8813 md_args [1] = LLVMMDNode (args ,2);
8814 md_args [2] = ctx_md;
8815 md_args [3] = md_string (cfg->method->name);
8816 md_args [4] = md_string (name);
8817 md_args [5] = md_string (name);
8820 md_args [6] = LLVMConstInt (LLVMInt32Type (), sym_seq_points [0].line, FALSE);
8822 md_args [6] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
8824 md_args [7] = type_md;
8826 md_args [8] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
8828 md_args [9] = LLVMConstInt (LLVMInt1Type (), 1, FALSE);
8830 md_args [10] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
8831 /* Index into a virtual function */
8832 md_args [11] = NULL;
8833 md_args [12] = NULL;
8835 md_args [13] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
8837 md_args [14] = LLVMConstInt (LLVMInt1Type (), 1, FALSE);
8838 /* Pointer to LLVM function */
8839 md_args [15] = method;
8840 /* Function template parameter */
8841 md_args [16] = NULL;
8842 /* Function declaration descriptor */
8843 md_args [17] = NULL;
8844 /* List of function variables */
8845 md_args [18] = LLVMMDNode (args, 0);
8847 md_args [19] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
8848 md = LLVMMDNode (md_args, 20);
8850 if (!module->subprogram_mds)
8851 module->subprogram_mds = g_ptr_array_new ();
8852 g_ptr_array_add (module->subprogram_mds, md);
8856 g_free (source_file);
8857 g_free (sym_seq_points);
8863 emit_dbg_loc (EmitContext *ctx, LLVMBuilderRef builder, const unsigned char *cil_code)
8865 MonoCompile *cfg = ctx->cfg;
8867 if (ctx->minfo && cil_code && cil_code >= cfg->header->code && cil_code < cfg->header->code + cfg->header->code_size) {
8868 MonoDebugSourceLocation *loc;
8869 LLVMValueRef loc_md;
8871 loc = mono_debug_symfile_lookup_location (ctx->minfo, cil_code - cfg->header->code);
8874 #if LLVM_API_VERSION > 100
8875 loc_md = mono_llvm_di_create_location (ctx->module->di_builder, ctx->dbg_md, loc->row, loc->column);
8876 mono_llvm_di_set_location (builder, loc_md);
8878 LLVMValueRef md_args [16];
8882 md_args [nmd_args ++] = LLVMConstInt (LLVMInt32Type (), loc->row, FALSE);
8883 md_args [nmd_args ++] = LLVMConstInt (LLVMInt32Type (), loc->column, FALSE);
8884 md_args [nmd_args ++] = ctx->dbg_md;
8885 md_args [nmd_args ++] = NULL;
8886 loc_md = LLVMMDNode (md_args, nmd_args);
8887 LLVMSetCurrentDebugLocation (builder, loc_md);
8889 mono_debug_symfile_free_location (loc);
8895 default_mono_llvm_unhandled_exception (void)
8897 MonoJitTlsData *jit_tls = mono_get_jit_tls ();
8898 MonoObject *target = mono_gchandle_get_target (jit_tls->thrown_exc);
8900 mono_unhandled_exception (target);
8901 exit (mono_environment_exitcode_get ());
8906 - Emit LLVM IR from the mono IR using the LLVM C API.
8907 - The original arch specific code remains, so we can fall back to it if we run
8908 into something we can't handle.
8912 A partial list of issues:
8913 - Handling of opcodes which can throw exceptions.
8915 In the mono JIT, these are implemented using code like this:
8922 push throw_pos - method
8923 call <exception trampoline>
8925 The problematic part is push throw_pos - method, which cannot be represented
8926 in the LLVM IR, since it does not support label values.
8927 -> this can be implemented in AOT mode using inline asm + labels, but cannot
8928 be implemented in JIT mode ?
8929 -> a possible but slower implementation would use the normal exception
8930 throwing code but it would need to control the placement of the throw code
8931 (it needs to be exactly after the compare+branch).
8932 -> perhaps add a PC offset intrinsics ?
8934 - efficient implementation of .ovf opcodes.
8936 These are currently implemented as:
8937 <ins which sets the condition codes>
8940 Some overflow opcodes are now supported by LLVM SVN.
8942 - exception handling, unwinding.
8943 - SSA is disabled for methods with exception handlers
8944 - How to obtain unwind info for LLVM compiled methods ?
8945 -> this is now solved by converting the unwind info generated by LLVM
8947 - LLVM uses the c++ exception handling framework, while we use our home grown
8948 code, and couldn't use the c++ one:
8949 - its not supported under VC++, other exotic platforms.
8950 - it might be impossible to support filter clauses with it.
8954 The trampolines need a predictable call sequence, since they need to disasm
8955 the calling code to obtain register numbers / offsets.
8957 LLVM currently generates this code in non-JIT mode:
8958 mov -0x98(%rax),%eax
8960 Here, the vtable pointer is lost.
8961 -> solution: use one vtable trampoline per class.
8963 - passing/receiving the IMT pointer/RGCTX.
8964 -> solution: pass them as normal arguments ?
8968 LLVM does not allow the specification of argument registers etc. This means
8969 that all calls are made according to the platform ABI.
8971 - passing/receiving vtypes.
8973 Vtypes passed/received in registers are handled by the front end by using
8974 a signature with scalar arguments, and loading the parts of the vtype into those
8977 Vtypes passed on the stack are handled using the 'byval' attribute.
8981 Supported though alloca, we need to emit the load/store code.
8985 The mono JIT uses pointer sized iregs/double fregs, while LLVM uses precisely
8986 typed registers, so we have to keep track of the precise LLVM type of each vreg.
8987 This is made easier because the IR is already in SSA form.
8988 An additional problem is that our IR is not consistent with types, i.e. i32/ia64
8989 types are frequently used incorrectly.
8994 Emit LLVM bytecode into a .bc file, compile it using llc into a .s file, then link
8995 it with the file containing the methods emitted by the JIT and the AOT data
8999 /* FIXME: Normalize some aspects of the mono IR to allow easier translation, like:
9000 * - each bblock should end with a branch
9001 * - setting the return value, making cfg->ret non-volatile
9002 * - avoid some transformations in the JIT which make it harder for us to generate
9004 * - use pointer types to help optimizations.