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;
75 LLVMValueRef personality;
78 MonoAssembly *assembly;
80 MonoAotFileInfo aot_info;
81 const char *jit_got_symbol;
82 const char *eh_frame_symbol;
83 LLVMValueRef get_method, get_unbox_tramp;
84 LLVMValueRef init_method, init_method_gshared_mrgctx, init_method_gshared_this, init_method_gshared_vtable;
85 LLVMValueRef code_start, code_end;
86 LLVMValueRef inited_var;
87 int max_inited_idx, max_method_idx;
88 gboolean has_jitted_code;
91 GHashTable *idx_to_lmethod;
92 GHashTable *idx_to_unbox_tramp;
93 /* Maps a MonoMethod to LLVM instructions representing it */
94 GHashTable *method_to_callers;
95 LLVMContextRef context;
96 LLVMValueRef sentinel_exception;
97 void *di_builder, *cu;
98 GHashTable *objc_selector_to_var;
102 * Information associated by the backend with mono basic blocks.
105 LLVMBasicBlockRef bblock, end_bblock;
106 LLVMValueRef finally_ind;
107 gboolean added, invoke_target;
109 * If this bblock is the start of a finally clause, this is a list of bblocks it
110 * needs to branch to in ENDFINALLY.
112 GSList *call_handler_return_bbs;
114 * If this bblock is the start of a finally clause, this is the bblock that
115 * CALL_HANDLER needs to branch to.
117 LLVMBasicBlockRef call_handler_target_bb;
118 /* The list of switch statements generated by ENDFINALLY instructions */
119 GSList *endfinally_switch_ins_list;
124 * Structure containing emit state
127 MonoMemPool *mempool;
129 /* Maps method names to the corresponding LLVMValueRef */
130 GHashTable *emitted_method_decls;
133 LLVMValueRef lmethod;
134 MonoLLVMModule *module;
135 LLVMModuleRef lmodule;
137 int sindex, default_index, ex_index;
138 LLVMBuilderRef builder;
139 LLVMValueRef *values, *addresses;
140 MonoType **vreg_cli_types;
142 MonoMethodSignature *sig;
144 GHashTable *region_to_handler;
145 GHashTable *clause_to_handler;
146 LLVMBuilderRef alloca_builder;
147 LLVMValueRef last_alloca;
148 LLVMValueRef rgctx_arg;
149 LLVMValueRef this_arg;
150 LLVMTypeRef *vreg_types;
151 LLVMTypeRef method_type;
152 LLVMBasicBlockRef init_bb, inited_bb;
154 gboolean *unreachable;
156 gboolean has_got_access;
157 gboolean is_linkonce;
158 int this_arg_pindex, rgctx_arg_pindex;
159 LLVMValueRef imt_rgctx_loc;
160 GHashTable *llvm_types;
162 MonoDebugMethodInfo *minfo;
164 /* For every clause, the clauses it is nested in */
167 GHashTable *exc_meta;
168 GHashTable *method_to_callers;
169 GPtrArray *phi_values;
170 GPtrArray *bblock_list;
172 GHashTable *jit_callees;
178 MonoBasicBlock *in_bb;
183 * Instruction metadata
184 * This is the same as ins_info, but LREG != IREG.
192 #define MINI_OP(a,b,dest,src1,src2) dest, src1, src2, ' ',
193 #define MINI_OP3(a,b,dest,src1,src2,src3) dest, src1, src2, src3,
200 /* keep in sync with the enum in mini.h */
203 #include "mini-ops.h"
208 #if SIZEOF_VOID_P == 4
209 #define GET_LONG_IMM(ins) (((guint64)(ins)->inst_ms_word << 32) | (guint64)(guint32)(ins)->inst_ls_word)
211 #define GET_LONG_IMM(ins) ((ins)->inst_imm)
214 #define LLVM_INS_INFO(opcode) (&llvm_ins_info [((opcode) - OP_START - 1) * 4])
217 #define TRACE_FAILURE(msg) do { printf ("%s\n", msg); } while (0)
219 #define TRACE_FAILURE(msg)
223 #define IS_TARGET_X86 1
225 #define IS_TARGET_X86 0
229 #define IS_TARGET_AMD64 1
231 #define IS_TARGET_AMD64 0
234 #define ctx_ok(ctx) (!(ctx)->cfg->disable_llvm)
236 static LLVMIntPredicate cond_to_llvm_cond [] = {
249 static LLVMRealPredicate fpcond_to_llvm_cond [] = {
262 static MonoNativeTlsKey current_cfg_tls_id;
264 static MonoLLVMModule aot_module;
266 static GHashTable *intrins_id_to_name;
267 static GHashTable *intrins_name_to_id;
269 static void init_jit_module (MonoDomain *domain);
271 static void emit_dbg_loc (EmitContext *ctx, LLVMBuilderRef builder, const unsigned char *cil_code);
272 static LLVMValueRef emit_dbg_subprogram (EmitContext *ctx, MonoCompile *cfg, LLVMValueRef method, const char *name);
273 static void emit_dbg_info (MonoLLVMModule *module, const char *filename, const char *cu_name);
274 static void emit_cond_system_exception (EmitContext *ctx, MonoBasicBlock *bb, const char *exc_type, LLVMValueRef cmp);
275 static LLVMValueRef get_intrinsic (EmitContext *ctx, const char *name);
276 static void decode_llvm_eh_info (EmitContext *ctx, gpointer eh_frame);
279 set_failure (EmitContext *ctx, const char *message)
281 TRACE_FAILURE (reason);
282 ctx->cfg->exception_message = g_strdup (message);
283 ctx->cfg->disable_llvm = TRUE;
289 * The LLVM type with width == sizeof (gpointer)
294 return sizeof (gpointer) == 8 ? LLVMInt64Type () : LLVMInt32Type ();
300 return sizeof (gpointer) == 8 ? LLVMPointerType (LLVMInt64Type (), 0) : LLVMPointerType (LLVMInt32Type (), 0);
306 return sizeof (gpointer) == 8 ? LLVMPointerType (LLVMInt64Type (), 0) : LLVMPointerType (LLVMInt32Type (), 0);
312 * Return the size of the LLVM representation of the vtype T.
315 get_vtype_size (MonoType *t)
319 size = mono_class_value_size (mono_class_from_mono_type (t), NULL);
321 /* LLVMArgAsIArgs depends on this since it stores whole words */
322 while (size < 2 * sizeof (gpointer) && mono_is_power_of_two (size) == -1)
329 * simd_class_to_llvm_type:
331 * Return the LLVM type corresponding to the Mono.SIMD class KLASS
334 simd_class_to_llvm_type (EmitContext *ctx, MonoClass *klass)
336 if (!strcmp (klass->name, "Vector2d")) {
337 return LLVMVectorType (LLVMDoubleType (), 2);
338 } else if (!strcmp (klass->name, "Vector2l")) {
339 return LLVMVectorType (LLVMInt64Type (), 2);
340 } else if (!strcmp (klass->name, "Vector2ul")) {
341 return LLVMVectorType (LLVMInt64Type (), 2);
342 } else if (!strcmp (klass->name, "Vector4i")) {
343 return LLVMVectorType (LLVMInt32Type (), 4);
344 } else if (!strcmp (klass->name, "Vector4ui")) {
345 return LLVMVectorType (LLVMInt32Type (), 4);
346 } else if (!strcmp (klass->name, "Vector4f")) {
347 return LLVMVectorType (LLVMFloatType (), 4);
348 } else if (!strcmp (klass->name, "Vector8s")) {
349 return LLVMVectorType (LLVMInt16Type (), 8);
350 } else if (!strcmp (klass->name, "Vector8us")) {
351 return LLVMVectorType (LLVMInt16Type (), 8);
352 } else if (!strcmp (klass->name, "Vector16sb")) {
353 return LLVMVectorType (LLVMInt8Type (), 16);
354 } else if (!strcmp (klass->name, "Vector16b")) {
355 return LLVMVectorType (LLVMInt8Type (), 16);
357 printf ("%s\n", klass->name);
363 /* Return the 128 bit SIMD type corresponding to the mono type TYPE */
364 static inline G_GNUC_UNUSED LLVMTypeRef
365 type_to_simd_type (int type)
369 return LLVMVectorType (LLVMInt8Type (), 16);
371 return LLVMVectorType (LLVMInt16Type (), 8);
373 return LLVMVectorType (LLVMInt32Type (), 4);
375 return LLVMVectorType (LLVMInt64Type (), 2);
377 return LLVMVectorType (LLVMDoubleType (), 2);
379 return LLVMVectorType (LLVMFloatType (), 4);
381 g_assert_not_reached ();
387 create_llvm_type_for_type (MonoLLVMModule *module, MonoClass *klass)
389 int i, size, nfields, esize;
390 LLVMTypeRef *eltypes;
395 t = &klass->byval_arg;
397 if (mini_type_is_hfa (t, &nfields, &esize)) {
399 * This is needed on arm64 where HFAs are returned in
403 eltypes = g_new (LLVMTypeRef, size);
404 for (i = 0; i < size; ++i)
405 eltypes [i] = esize == 4 ? LLVMFloatType () : LLVMDoubleType ();
407 size = get_vtype_size (t);
409 eltypes = g_new (LLVMTypeRef, size);
410 for (i = 0; i < size; ++i)
411 eltypes [i] = LLVMInt8Type ();
414 name = mono_type_full_name (&klass->byval_arg);
415 ltype = LLVMStructCreateNamed (module->context, name);
416 LLVMStructSetBody (ltype, eltypes, size, FALSE);
426 * Return the LLVM type corresponding to T.
429 type_to_llvm_type (EmitContext *ctx, MonoType *t)
431 t = mini_get_underlying_type (t);
435 return LLVMVoidType ();
437 return LLVMInt8Type ();
439 return LLVMInt16Type ();
441 return LLVMInt32Type ();
443 return LLVMInt8Type ();
445 return LLVMInt16Type ();
447 return LLVMInt32Type ();
448 case MONO_TYPE_BOOLEAN:
449 return LLVMInt8Type ();
452 return LLVMInt64Type ();
454 return LLVMInt16Type ();
456 return LLVMFloatType ();
458 return LLVMDoubleType ();
461 return IntPtrType ();
462 case MONO_TYPE_OBJECT:
463 case MONO_TYPE_CLASS:
464 case MONO_TYPE_ARRAY:
465 case MONO_TYPE_SZARRAY:
466 case MONO_TYPE_STRING:
468 return ObjRefType ();
471 /* Because of generic sharing */
472 return ObjRefType ();
473 case MONO_TYPE_GENERICINST:
474 if (!mono_type_generic_inst_is_valuetype (t))
475 return ObjRefType ();
477 case MONO_TYPE_VALUETYPE:
478 case MONO_TYPE_TYPEDBYREF: {
482 klass = mono_class_from_mono_type (t);
484 if (MONO_CLASS_IS_SIMD (ctx->cfg, klass))
485 return simd_class_to_llvm_type (ctx, klass);
488 return type_to_llvm_type (ctx, mono_class_enum_basetype (klass));
490 ltype = (LLVMTypeRef)g_hash_table_lookup (ctx->module->llvm_types, klass);
492 ltype = create_llvm_type_for_type (ctx->module, klass);
493 g_hash_table_insert (ctx->module->llvm_types, klass, ltype);
499 printf ("X: %d\n", t->type);
500 ctx->cfg->exception_message = g_strdup_printf ("type %s", mono_type_full_name (t));
501 ctx->cfg->disable_llvm = TRUE;
509 * Return whenever T is an unsigned int type.
512 type_is_unsigned (EmitContext *ctx, MonoType *t)
514 t = mini_get_underlying_type (t);
530 * type_to_llvm_arg_type:
532 * Same as type_to_llvm_type, but treat i8/i16 as i32.
535 type_to_llvm_arg_type (EmitContext *ctx, MonoType *t)
537 LLVMTypeRef ptype = type_to_llvm_type (ctx, t);
539 if (ctx->cfg->llvm_only)
543 * This works on all abis except arm64/ios which passes multiple
544 * arguments in one stack slot.
547 if (ptype == LLVMInt8Type () || ptype == LLVMInt16Type ()) {
549 * LLVM generates code which only sets the lower bits, while JITted
550 * code expects all the bits to be set.
552 ptype = LLVMInt32Type ();
560 * llvm_type_to_stack_type:
562 * Return the LLVM type which needs to be used when a value of type TYPE is pushed
565 static G_GNUC_UNUSED LLVMTypeRef
566 llvm_type_to_stack_type (MonoCompile *cfg, LLVMTypeRef type)
570 if (type == LLVMInt8Type ())
571 return LLVMInt32Type ();
572 else if (type == LLVMInt16Type ())
573 return LLVMInt32Type ();
574 else if (!cfg->r4fp && type == LLVMFloatType ())
575 return LLVMDoubleType ();
581 * regtype_to_llvm_type:
583 * Return the LLVM type corresponding to the regtype C used in instruction
587 regtype_to_llvm_type (char c)
591 return LLVMInt32Type ();
593 return LLVMInt64Type ();
595 return LLVMDoubleType ();
604 * Return the LLVM type corresponding to the unary/binary opcode OPCODE.
607 op_to_llvm_type (int opcode)
612 return LLVMInt8Type ();
615 return LLVMInt8Type ();
618 return LLVMInt16Type ();
621 return LLVMInt16Type ();
624 return LLVMInt32Type ();
627 return LLVMInt32Type ();
629 return LLVMInt64Type ();
631 return LLVMFloatType ();
633 return LLVMDoubleType ();
635 return LLVMInt64Type ();
637 return LLVMInt32Type ();
639 return LLVMInt64Type ();
644 return LLVMInt8Type ();
649 return LLVMInt16Type ();
651 return LLVMInt32Type ();
654 return sizeof (gpointer) == 8 ? LLVMInt64Type () : LLVMInt32Type ();
661 return LLVMInt32Type ();
668 return LLVMInt64Type ();
670 printf ("%s\n", mono_inst_name (opcode));
671 g_assert_not_reached ();
676 #define CLAUSE_START(clause) ((clause)->try_offset)
677 #define CLAUSE_END(clause) (((clause))->try_offset + ((clause))->try_len)
680 * load_store_to_llvm_type:
682 * Return the size/sign/zero extension corresponding to the load/store opcode
686 load_store_to_llvm_type (int opcode, int *size, gboolean *sext, gboolean *zext)
692 case OP_LOADI1_MEMBASE:
693 case OP_STOREI1_MEMBASE_REG:
694 case OP_STOREI1_MEMBASE_IMM:
695 case OP_ATOMIC_LOAD_I1:
696 case OP_ATOMIC_STORE_I1:
699 return LLVMInt8Type ();
700 case OP_LOADU1_MEMBASE:
702 case OP_ATOMIC_LOAD_U1:
703 case OP_ATOMIC_STORE_U1:
706 return LLVMInt8Type ();
707 case OP_LOADI2_MEMBASE:
708 case OP_STOREI2_MEMBASE_REG:
709 case OP_STOREI2_MEMBASE_IMM:
710 case OP_ATOMIC_LOAD_I2:
711 case OP_ATOMIC_STORE_I2:
714 return LLVMInt16Type ();
715 case OP_LOADU2_MEMBASE:
717 case OP_ATOMIC_LOAD_U2:
718 case OP_ATOMIC_STORE_U2:
721 return LLVMInt16Type ();
722 case OP_LOADI4_MEMBASE:
723 case OP_LOADU4_MEMBASE:
726 case OP_STOREI4_MEMBASE_REG:
727 case OP_STOREI4_MEMBASE_IMM:
728 case OP_ATOMIC_LOAD_I4:
729 case OP_ATOMIC_STORE_I4:
730 case OP_ATOMIC_LOAD_U4:
731 case OP_ATOMIC_STORE_U4:
733 return LLVMInt32Type ();
734 case OP_LOADI8_MEMBASE:
736 case OP_STOREI8_MEMBASE_REG:
737 case OP_STOREI8_MEMBASE_IMM:
738 case OP_ATOMIC_LOAD_I8:
739 case OP_ATOMIC_STORE_I8:
740 case OP_ATOMIC_LOAD_U8:
741 case OP_ATOMIC_STORE_U8:
743 return LLVMInt64Type ();
744 case OP_LOADR4_MEMBASE:
745 case OP_STORER4_MEMBASE_REG:
746 case OP_ATOMIC_LOAD_R4:
747 case OP_ATOMIC_STORE_R4:
749 return LLVMFloatType ();
750 case OP_LOADR8_MEMBASE:
751 case OP_STORER8_MEMBASE_REG:
752 case OP_ATOMIC_LOAD_R8:
753 case OP_ATOMIC_STORE_R8:
755 return LLVMDoubleType ();
756 case OP_LOAD_MEMBASE:
758 case OP_STORE_MEMBASE_REG:
759 case OP_STORE_MEMBASE_IMM:
760 *size = sizeof (gpointer);
761 return IntPtrType ();
763 g_assert_not_reached ();
771 * Return the LLVM intrinsics corresponding to the overflow opcode OPCODE.
774 ovf_op_to_intrins (int opcode)
778 return "llvm.sadd.with.overflow.i32";
780 return "llvm.uadd.with.overflow.i32";
782 return "llvm.ssub.with.overflow.i32";
784 return "llvm.usub.with.overflow.i32";
786 return "llvm.smul.with.overflow.i32";
788 return "llvm.umul.with.overflow.i32";
790 return "llvm.sadd.with.overflow.i64";
792 return "llvm.uadd.with.overflow.i64";
794 return "llvm.ssub.with.overflow.i64";
796 return "llvm.usub.with.overflow.i64";
798 return "llvm.smul.with.overflow.i64";
800 return "llvm.umul.with.overflow.i64";
802 g_assert_not_reached ();
808 simd_op_to_intrins (int opcode)
811 #if defined(TARGET_X86) || defined(TARGET_AMD64)
813 return "llvm.x86.sse2.min.pd";
815 return "llvm.x86.sse.min.ps";
817 return "llvm.x86.sse41.pminud";
819 return "llvm.x86.sse41.pminuw";
821 return "llvm.x86.sse2.pminu.b";
823 return "llvm.x86.sse2.pmins.w";
825 return "llvm.x86.sse2.max.pd";
827 return "llvm.x86.sse.max.ps";
829 return "llvm.x86.sse3.hadd.pd";
831 return "llvm.x86.sse3.hadd.ps";
833 return "llvm.x86.sse3.hsub.pd";
835 return "llvm.x86.sse3.hsub.ps";
837 return "llvm.x86.sse41.pmaxud";
839 return "llvm.x86.sse41.pmaxuw";
841 return "llvm.x86.sse2.pmaxu.b";
843 return "llvm.x86.sse3.addsub.ps";
845 return "llvm.x86.sse3.addsub.pd";
846 case OP_EXTRACT_MASK:
847 return "llvm.x86.sse2.pmovmskb.128";
850 return "llvm.x86.sse2.psrli.w";
853 return "llvm.x86.sse2.psrli.d";
856 return "llvm.x86.sse2.psrli.q";
859 return "llvm.x86.sse2.pslli.w";
862 return "llvm.x86.sse2.pslli.d";
865 return "llvm.x86.sse2.pslli.q";
868 return "llvm.x86.sse2.psrai.w";
871 return "llvm.x86.sse2.psrai.d";
873 return "llvm.x86.sse2.padds.b";
875 return "llvm.x86.sse2.padds.w";
877 return "llvm.x86.sse2.psubs.b";
879 return "llvm.x86.sse2.psubs.w";
880 case OP_PADDB_SAT_UN:
881 return "llvm.x86.sse2.paddus.b";
882 case OP_PADDW_SAT_UN:
883 return "llvm.x86.sse2.paddus.w";
884 case OP_PSUBB_SAT_UN:
885 return "llvm.x86.sse2.psubus.b";
886 case OP_PSUBW_SAT_UN:
887 return "llvm.x86.sse2.psubus.w";
889 return "llvm.x86.sse2.pavg.b";
891 return "llvm.x86.sse2.pavg.w";
893 return "llvm.x86.sse.sqrt.ps";
895 return "llvm.x86.sse2.sqrt.pd";
897 return "llvm.x86.sse.rsqrt.ps";
899 return "llvm.x86.sse.rcp.ps";
901 return "llvm.x86.sse2.cvtdq2pd";
903 return "llvm.x86.sse2.cvtdq2ps";
905 return "llvm.x86.sse2.cvtpd2dq";
907 return "llvm.x86.sse2.cvtps2dq";
909 return "llvm.x86.sse2.cvtpd2ps";
911 return "llvm.x86.sse2.cvtps2pd";
913 return "llvm.x86.sse2.cvttpd2dq";
915 return "llvm.x86.sse2.cvttps2dq";
917 return "llvm.x86.sse.cmp.ps";
919 return "llvm.x86.sse2.cmp.pd";
921 return "llvm.x86.sse2.packsswb.128";
923 return "llvm.x86.sse2.packssdw.128";
925 return "llvm.x86.sse2.packuswb.128";
927 return "llvm.x86.sse41.packusdw";
929 return "llvm.x86.sse2.pmulh.w";
930 case OP_PMULW_HIGH_UN:
931 return "llvm.x86.sse2.pmulhu.w";
934 g_assert_not_reached ();
940 simd_op_to_llvm_type (int opcode)
942 #if defined(TARGET_X86) || defined(TARGET_AMD64)
946 return type_to_simd_type (MONO_TYPE_R8);
949 return type_to_simd_type (MONO_TYPE_I8);
952 return type_to_simd_type (MONO_TYPE_I4);
957 return type_to_simd_type (MONO_TYPE_I2);
961 return type_to_simd_type (MONO_TYPE_I1);
963 return type_to_simd_type (MONO_TYPE_R4);
966 return type_to_simd_type (MONO_TYPE_I4);
970 return type_to_simd_type (MONO_TYPE_R8);
974 return type_to_simd_type (MONO_TYPE_R4);
975 case OP_EXTRACT_MASK:
976 return type_to_simd_type (MONO_TYPE_I1);
982 return type_to_simd_type (MONO_TYPE_R4);
985 return type_to_simd_type (MONO_TYPE_R8);
987 g_assert_not_reached ();
998 * Return the LLVM basic block corresponding to BB.
1000 static LLVMBasicBlockRef
1001 get_bb (EmitContext *ctx, MonoBasicBlock *bb)
1003 char bb_name_buf [128];
1006 if (ctx->bblocks [bb->block_num].bblock == NULL) {
1007 if (bb->flags & BB_EXCEPTION_HANDLER) {
1008 int clause_index = (mono_get_block_region_notry (ctx->cfg, bb->region) >> 8) - 1;
1009 sprintf (bb_name_buf, "EH_CLAUSE%d_BB%d", clause_index, bb->block_num);
1010 bb_name = bb_name_buf;
1011 } else if (bb->block_num < 256) {
1012 if (!ctx->module->bb_names) {
1013 ctx->module->bb_names_len = 256;
1014 ctx->module->bb_names = g_new0 (char*, ctx->module->bb_names_len);
1016 if (!ctx->module->bb_names [bb->block_num]) {
1019 n = g_strdup_printf ("BB%d", bb->block_num);
1020 mono_memory_barrier ();
1021 ctx->module->bb_names [bb->block_num] = n;
1023 bb_name = ctx->module->bb_names [bb->block_num];
1025 sprintf (bb_name_buf, "BB%d", bb->block_num);
1026 bb_name = bb_name_buf;
1029 ctx->bblocks [bb->block_num].bblock = LLVMAppendBasicBlock (ctx->lmethod, bb_name);
1030 ctx->bblocks [bb->block_num].end_bblock = ctx->bblocks [bb->block_num].bblock;
1033 return ctx->bblocks [bb->block_num].bblock;
1039 * Return the last LLVM bblock corresponding to BB.
1040 * This might not be equal to the bb returned by get_bb () since we need to generate
1041 * multiple LLVM bblocks for a mono bblock to handle throwing exceptions.
1043 static LLVMBasicBlockRef
1044 get_end_bb (EmitContext *ctx, MonoBasicBlock *bb)
1047 return ctx->bblocks [bb->block_num].end_bblock;
1050 static LLVMBasicBlockRef
1051 gen_bb (EmitContext *ctx, const char *prefix)
1055 sprintf (bb_name, "%s%d", prefix, ++ ctx->ex_index);
1056 return LLVMAppendBasicBlock (ctx->lmethod, bb_name);
1062 * Return the target of the patch identified by TYPE and TARGET.
1065 resolve_patch (MonoCompile *cfg, MonoJumpInfoType type, gconstpointer target)
1071 memset (&ji, 0, sizeof (ji));
1073 ji.data.target = target;
1075 res = mono_resolve_patch_target (cfg->method, cfg->domain, NULL, &ji, FALSE, &error);
1076 mono_error_assert_ok (&error);
1084 * Emit code to convert the LLVM value V to DTYPE.
1087 convert_full (EmitContext *ctx, LLVMValueRef v, LLVMTypeRef dtype, gboolean is_unsigned)
1089 LLVMTypeRef stype = LLVMTypeOf (v);
1091 if (stype != dtype) {
1092 gboolean ext = FALSE;
1095 if (dtype == LLVMInt64Type () && (stype == LLVMInt32Type () || stype == LLVMInt16Type () || stype == LLVMInt8Type ()))
1097 else if (dtype == LLVMInt32Type () && (stype == LLVMInt16Type () || stype == LLVMInt8Type ()))
1099 else if (dtype == LLVMInt16Type () && (stype == LLVMInt8Type ()))
1103 return is_unsigned ? LLVMBuildZExt (ctx->builder, v, dtype, "") : LLVMBuildSExt (ctx->builder, v, dtype, "");
1105 if (dtype == LLVMDoubleType () && stype == LLVMFloatType ())
1106 return LLVMBuildFPExt (ctx->builder, v, dtype, "");
1109 if (stype == LLVMInt64Type () && (dtype == LLVMInt32Type () || dtype == LLVMInt16Type () || dtype == LLVMInt8Type ()))
1110 return LLVMBuildTrunc (ctx->builder, v, dtype, "");
1111 if (stype == LLVMInt32Type () && (dtype == LLVMInt16Type () || dtype == LLVMInt8Type ()))
1112 return LLVMBuildTrunc (ctx->builder, v, dtype, "");
1113 if (stype == LLVMInt16Type () && dtype == LLVMInt8Type ())
1114 return LLVMBuildTrunc (ctx->builder, v, dtype, "");
1115 if (stype == LLVMDoubleType () && dtype == LLVMFloatType ())
1116 return LLVMBuildFPTrunc (ctx->builder, v, dtype, "");
1118 if (LLVMGetTypeKind (stype) == LLVMPointerTypeKind && LLVMGetTypeKind (dtype) == LLVMPointerTypeKind)
1119 return LLVMBuildBitCast (ctx->builder, v, dtype, "");
1120 if (LLVMGetTypeKind (dtype) == LLVMPointerTypeKind)
1121 return LLVMBuildIntToPtr (ctx->builder, v, dtype, "");
1122 if (LLVMGetTypeKind (stype) == LLVMPointerTypeKind)
1123 return LLVMBuildPtrToInt (ctx->builder, v, dtype, "");
1125 if (mono_arch_is_soft_float ()) {
1126 if (stype == LLVMInt32Type () && dtype == LLVMFloatType ())
1127 return LLVMBuildBitCast (ctx->builder, v, dtype, "");
1128 if (stype == LLVMInt32Type () && dtype == LLVMDoubleType ())
1129 return LLVMBuildBitCast (ctx->builder, LLVMBuildZExt (ctx->builder, v, LLVMInt64Type (), ""), dtype, "");
1132 if (LLVMGetTypeKind (stype) == LLVMVectorTypeKind && LLVMGetTypeKind (dtype) == LLVMVectorTypeKind)
1133 return LLVMBuildBitCast (ctx->builder, v, dtype, "");
1136 LLVMDumpValue (LLVMConstNull (dtype));
1137 g_assert_not_reached ();
1145 convert (EmitContext *ctx, LLVMValueRef v, LLVMTypeRef dtype)
1147 return convert_full (ctx, v, dtype, FALSE);
1151 * emit_volatile_load:
1153 * If vreg is volatile, emit a load from its address.
1156 emit_volatile_load (EmitContext *ctx, int vreg)
1160 LLVMValueRef v = LLVMBuildLoad (ctx->builder, ctx->addresses [vreg], "");
1161 t = ctx->vreg_cli_types [vreg];
1162 if (t && !t->byref) {
1164 * Might have to zero extend since llvm doesn't have
1167 if (t->type == MONO_TYPE_U1 || t->type == MONO_TYPE_U2 || t->type == MONO_TYPE_CHAR || t->type == MONO_TYPE_BOOLEAN)
1168 v = LLVMBuildZExt (ctx->builder, v, LLVMInt32Type (), "");
1169 else if (t->type == MONO_TYPE_I1 || t->type == MONO_TYPE_I2)
1170 v = LLVMBuildSExt (ctx->builder, v, LLVMInt32Type (), "");
1171 else if (t->type == MONO_TYPE_U8)
1172 v = LLVMBuildZExt (ctx->builder, v, LLVMInt64Type (), "");
1179 * emit_volatile_store:
1181 * If VREG is volatile, emit a store from its value to its address.
1184 emit_volatile_store (EmitContext *ctx, int vreg)
1186 MonoInst *var = get_vreg_to_inst (ctx->cfg, vreg);
1188 if (var && var->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT)) {
1189 g_assert (ctx->addresses [vreg]);
1190 LLVMBuildStore (ctx->builder, convert (ctx, ctx->values [vreg], type_to_llvm_type (ctx, var->inst_vtype)), ctx->addresses [vreg]);
1195 sig_to_llvm_sig_no_cinfo (EmitContext *ctx, MonoMethodSignature *sig)
1197 LLVMTypeRef ret_type;
1198 LLVMTypeRef *param_types = NULL;
1203 rtype = mini_get_underlying_type (sig->ret);
1204 ret_type = type_to_llvm_type (ctx, rtype);
1208 param_types = g_new0 (LLVMTypeRef, (sig->param_count * 8) + 3);
1212 param_types [pindex ++] = ThisType ();
1213 for (i = 0; i < sig->param_count; ++i)
1214 param_types [pindex ++] = type_to_llvm_arg_type (ctx, sig->params [i]);
1216 if (!ctx_ok (ctx)) {
1217 g_free (param_types);
1221 res = LLVMFunctionType (ret_type, param_types, pindex, FALSE);
1222 g_free (param_types);
1228 * sig_to_llvm_sig_full:
1230 * Return the LLVM signature corresponding to the mono signature SIG using the
1231 * calling convention information in CINFO. Fill out the parameter mapping information in CINFO.
1234 sig_to_llvm_sig_full (EmitContext *ctx, MonoMethodSignature *sig, LLVMCallInfo *cinfo)
1236 LLVMTypeRef ret_type;
1237 LLVMTypeRef *param_types = NULL;
1239 int i, j, pindex, vret_arg_pindex = 0;
1240 gboolean vretaddr = FALSE;
1244 return sig_to_llvm_sig_no_cinfo (ctx, sig);
1246 rtype = mini_get_underlying_type (sig->ret);
1247 ret_type = type_to_llvm_type (ctx, rtype);
1251 switch (cinfo->ret.storage) {
1252 case LLVMArgVtypeInReg:
1253 /* LLVM models this by returning an aggregate value */
1254 if (cinfo->ret.pair_storage [0] == LLVMArgInIReg && cinfo->ret.pair_storage [1] == LLVMArgNone) {
1255 LLVMTypeRef members [2];
1257 members [0] = IntPtrType ();
1258 ret_type = LLVMStructType (members, 1, FALSE);
1259 } else if (cinfo->ret.pair_storage [0] == LLVMArgNone && cinfo->ret.pair_storage [1] == LLVMArgNone) {
1261 ret_type = LLVMVoidType ();
1262 } else if (cinfo->ret.pair_storage [0] == LLVMArgInIReg && cinfo->ret.pair_storage [1] == LLVMArgInIReg) {
1263 LLVMTypeRef members [2];
1265 members [0] = IntPtrType ();
1266 members [1] = IntPtrType ();
1267 ret_type = LLVMStructType (members, 2, FALSE);
1269 g_assert_not_reached ();
1272 case LLVMArgVtypeByVal:
1273 /* Vtype returned normally by val */
1275 case LLVMArgVtypeAsScalar: {
1276 int size = mono_class_value_size (mono_class_from_mono_type (rtype), NULL);
1277 /* LLVM models this by returning an int */
1278 if (size < SIZEOF_VOID_P) {
1279 g_assert (cinfo->ret.nslots == 1);
1280 ret_type = LLVMIntType (size * 8);
1282 g_assert (cinfo->ret.nslots == 1 || cinfo->ret.nslots == 2);
1283 ret_type = LLVMIntType (cinfo->ret.nslots * sizeof (mgreg_t) * 8);
1287 case LLVMArgAsIArgs:
1288 ret_type = LLVMArrayType (IntPtrType (), cinfo->ret.nslots);
1290 case LLVMArgFpStruct: {
1291 /* Vtype returned as a fp struct */
1292 LLVMTypeRef members [16];
1294 /* Have to create our own structure since we don't map fp structures to LLVM fp structures yet */
1295 for (i = 0; i < cinfo->ret.nslots; ++i)
1296 members [i] = cinfo->ret.esize == 8 ? LLVMDoubleType () : LLVMFloatType ();
1297 ret_type = LLVMStructType (members, cinfo->ret.nslots, FALSE);
1300 case LLVMArgVtypeByRef:
1301 /* Vtype returned using a hidden argument */
1302 ret_type = LLVMVoidType ();
1304 case LLVMArgVtypeRetAddr:
1305 case LLVMArgGsharedvtFixed:
1306 case LLVMArgGsharedvtFixedVtype:
1307 case LLVMArgGsharedvtVariable:
1309 ret_type = LLVMVoidType ();
1315 param_types = g_new0 (LLVMTypeRef, (sig->param_count * 8) + 3);
1317 if (cinfo->ret.storage == LLVMArgVtypeByRef) {
1319 * Has to be the first argument because of the sret argument attribute
1320 * FIXME: This might conflict with passing 'this' as the first argument, but
1321 * this is only used on arm64 which has a dedicated struct return register.
1323 cinfo->vret_arg_pindex = pindex;
1324 param_types [pindex] = type_to_llvm_arg_type (ctx, sig->ret);
1325 if (!ctx_ok (ctx)) {
1326 g_free (param_types);
1329 param_types [pindex] = LLVMPointerType (param_types [pindex], 0);
1332 if (!ctx->llvm_only && cinfo->rgctx_arg) {
1333 cinfo->rgctx_arg_pindex = pindex;
1334 param_types [pindex] = ctx->module->ptr_type;
1337 if (cinfo->imt_arg) {
1338 cinfo->imt_arg_pindex = pindex;
1339 param_types [pindex] = ctx->module->ptr_type;
1343 /* Compute the index in the LLVM signature where the vret arg needs to be passed */
1344 vret_arg_pindex = pindex;
1345 if (cinfo->vret_arg_index == 1) {
1346 /* Add the slots consumed by the first argument */
1347 LLVMArgInfo *ainfo = &cinfo->args [0];
1348 switch (ainfo->storage) {
1349 case LLVMArgVtypeInReg:
1350 for (j = 0; j < 2; ++j) {
1351 if (ainfo->pair_storage [j] == LLVMArgInIReg)
1360 cinfo->vret_arg_pindex = vret_arg_pindex;
1363 if (vretaddr && vret_arg_pindex == pindex)
1364 param_types [pindex ++] = IntPtrType ();
1366 cinfo->this_arg_pindex = pindex;
1367 param_types [pindex ++] = ThisType ();
1368 cinfo->args [0].pindex = cinfo->this_arg_pindex;
1370 if (vretaddr && vret_arg_pindex == pindex)
1371 param_types [pindex ++] = IntPtrType ();
1372 for (i = 0; i < sig->param_count; ++i) {
1373 LLVMArgInfo *ainfo = &cinfo->args [i + sig->hasthis];
1375 if (vretaddr && vret_arg_pindex == pindex)
1376 param_types [pindex ++] = IntPtrType ();
1377 ainfo->pindex = pindex;
1379 switch (ainfo->storage) {
1380 case LLVMArgVtypeInReg:
1381 for (j = 0; j < 2; ++j) {
1382 switch (ainfo->pair_storage [j]) {
1384 param_types [pindex ++] = LLVMIntType (sizeof (gpointer) * 8);
1389 g_assert_not_reached ();
1393 case LLVMArgVtypeByVal:
1394 param_types [pindex] = type_to_llvm_arg_type (ctx, ainfo->type);
1397 param_types [pindex] = LLVMPointerType (param_types [pindex], 0);
1400 case LLVMArgAsIArgs:
1401 param_types [pindex] = LLVMArrayType (IntPtrType (), ainfo->nslots);
1404 case LLVMArgVtypeByRef:
1405 param_types [pindex] = type_to_llvm_arg_type (ctx, ainfo->type);
1408 param_types [pindex] = LLVMPointerType (param_types [pindex], 0);
1411 case LLVMArgAsFpArgs: {
1414 /* Emit dummy fp arguments if needed so the rest is passed on the stack */
1415 for (j = 0; j < ainfo->ndummy_fpargs; ++j)
1416 param_types [pindex ++] = LLVMDoubleType ();
1417 for (j = 0; j < ainfo->nslots; ++j)
1418 param_types [pindex ++] = ainfo->esize == 8 ? LLVMDoubleType () : LLVMFloatType ();
1421 case LLVMArgVtypeAsScalar:
1422 g_assert_not_reached ();
1424 case LLVMArgGsharedvtFixed:
1425 case LLVMArgGsharedvtFixedVtype:
1426 param_types [pindex ++] = LLVMPointerType (type_to_llvm_arg_type (ctx, ainfo->type), 0);
1428 case LLVMArgGsharedvtVariable:
1429 param_types [pindex ++] = LLVMPointerType (IntPtrType (), 0);
1432 param_types [pindex ++] = type_to_llvm_arg_type (ctx, ainfo->type);
1436 if (!ctx_ok (ctx)) {
1437 g_free (param_types);
1440 if (vretaddr && vret_arg_pindex == pindex)
1441 param_types [pindex ++] = IntPtrType ();
1442 if (ctx->llvm_only && cinfo->rgctx_arg) {
1443 /* Pass the rgctx as the last argument */
1444 cinfo->rgctx_arg_pindex = pindex;
1445 param_types [pindex] = ctx->module->ptr_type;
1449 res = LLVMFunctionType (ret_type, param_types, pindex, FALSE);
1450 g_free (param_types);
1456 sig_to_llvm_sig (EmitContext *ctx, MonoMethodSignature *sig)
1458 return sig_to_llvm_sig_full (ctx, sig, NULL);
1462 * LLVMFunctionType1:
1464 * Create an LLVM function type from the arguments.
1466 static G_GNUC_UNUSED LLVMTypeRef
1467 LLVMFunctionType0 (LLVMTypeRef ReturnType,
1470 return LLVMFunctionType (ReturnType, NULL, 0, IsVarArg);
1474 * LLVMFunctionType1:
1476 * Create an LLVM function type from the arguments.
1478 static G_GNUC_UNUSED LLVMTypeRef
1479 LLVMFunctionType1 (LLVMTypeRef ReturnType,
1480 LLVMTypeRef ParamType1,
1483 LLVMTypeRef param_types [1];
1485 param_types [0] = ParamType1;
1487 return LLVMFunctionType (ReturnType, param_types, 1, IsVarArg);
1491 * LLVMFunctionType2:
1493 * Create an LLVM function type from the arguments.
1495 static G_GNUC_UNUSED LLVMTypeRef
1496 LLVMFunctionType2 (LLVMTypeRef ReturnType,
1497 LLVMTypeRef ParamType1,
1498 LLVMTypeRef ParamType2,
1501 LLVMTypeRef param_types [2];
1503 param_types [0] = ParamType1;
1504 param_types [1] = ParamType2;
1506 return LLVMFunctionType (ReturnType, param_types, 2, IsVarArg);
1510 * LLVMFunctionType3:
1512 * Create an LLVM function type from the arguments.
1514 static G_GNUC_UNUSED LLVMTypeRef
1515 LLVMFunctionType3 (LLVMTypeRef ReturnType,
1516 LLVMTypeRef ParamType1,
1517 LLVMTypeRef ParamType2,
1518 LLVMTypeRef ParamType3,
1521 LLVMTypeRef param_types [3];
1523 param_types [0] = ParamType1;
1524 param_types [1] = ParamType2;
1525 param_types [2] = ParamType3;
1527 return LLVMFunctionType (ReturnType, param_types, 3, IsVarArg);
1530 static G_GNUC_UNUSED LLVMTypeRef
1531 LLVMFunctionType5 (LLVMTypeRef ReturnType,
1532 LLVMTypeRef ParamType1,
1533 LLVMTypeRef ParamType2,
1534 LLVMTypeRef ParamType3,
1535 LLVMTypeRef ParamType4,
1536 LLVMTypeRef ParamType5,
1539 LLVMTypeRef param_types [5];
1541 param_types [0] = ParamType1;
1542 param_types [1] = ParamType2;
1543 param_types [2] = ParamType3;
1544 param_types [3] = ParamType4;
1545 param_types [4] = ParamType5;
1547 return LLVMFunctionType (ReturnType, param_types, 5, IsVarArg);
1553 * Create an LLVM builder and remember it so it can be freed later.
1555 static LLVMBuilderRef
1556 create_builder (EmitContext *ctx)
1558 LLVMBuilderRef builder = LLVMCreateBuilder ();
1560 ctx->builders = g_slist_prepend_mempool (ctx->cfg->mempool, ctx->builders, builder);
1566 get_aotconst_name (MonoJumpInfoType type, gconstpointer data, int got_offset)
1571 case MONO_PATCH_INFO_INTERNAL_METHOD:
1572 name = g_strdup_printf ("jit_icall_%s", data);
1574 case MONO_PATCH_INFO_RGCTX_SLOT_INDEX: {
1575 MonoJumpInfoRgctxEntry *entry = (MonoJumpInfoRgctxEntry*)data;
1576 name = g_strdup_printf ("RGCTX_SLOT_INDEX_%s", mono_rgctx_info_type_to_str (entry->info_type));
1580 name = g_strdup_printf ("%s_%d", mono_ji_type_to_string (type), got_offset);
1588 get_aotconst_typed (EmitContext *ctx, MonoJumpInfoType type, gconstpointer data, LLVMTypeRef llvm_type)
1592 LLVMValueRef indexes [2];
1594 LLVMValueRef got_entry_addr, load;
1595 LLVMBuilderRef builder = ctx->builder;
1600 ji = g_new0 (MonoJumpInfo, 1);
1602 ji->data.target = data;
1604 ji = mono_aot_patch_info_dup (ji);
1606 ji->next = cfg->patch_info;
1607 cfg->patch_info = ji;
1609 got_offset = mono_aot_get_got_offset (cfg->patch_info);
1610 ctx->module->max_got_offset = MAX (ctx->module->max_got_offset, got_offset);
1612 * If the got slot is shared, it means its initialized when the aot image is loaded, so we don't need to
1613 * explicitly initialize it.
1615 if (!mono_aot_is_shared_got_offset (got_offset)) {
1616 //mono_print_ji (ji);
1618 ctx->has_got_access = TRUE;
1621 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
1622 indexes [1] = LLVMConstInt (LLVMInt32Type (), (gssize)got_offset, FALSE);
1623 got_entry_addr = LLVMBuildGEP (builder, ctx->module->got_var, indexes, 2, "");
1625 name = get_aotconst_name (type, data, got_offset);
1627 load = LLVMBuildLoad (builder, got_entry_addr, "");
1628 load = convert (ctx, load, llvm_type);
1629 LLVMSetValueName (load, name ? name : "");
1631 load = LLVMBuildLoad (builder, got_entry_addr, name ? name : "");
1634 //set_invariant_load_flag (load);
1640 get_aotconst (EmitContext *ctx, MonoJumpInfoType type, gconstpointer data)
1642 return get_aotconst_typed (ctx, type, data, NULL);
1646 get_callee (EmitContext *ctx, LLVMTypeRef llvm_sig, MonoJumpInfoType type, gconstpointer data)
1648 LLVMValueRef callee;
1650 if (ctx->llvm_only) {
1651 callee_name = mono_aot_get_direct_call_symbol (type, data);
1653 /* Directly callable */
1655 callee = (LLVMValueRef)g_hash_table_lookup (ctx->module->direct_callables, callee_name);
1657 callee = LLVMAddFunction (ctx->lmodule, callee_name, llvm_sig);
1659 LLVMSetVisibility (callee, LLVMHiddenVisibility);
1661 g_hash_table_insert (ctx->module->direct_callables, (char*)callee_name, callee);
1663 /* LLVMTypeRef's are uniqued */
1664 if (LLVMGetElementType (LLVMTypeOf (callee)) != llvm_sig)
1665 return LLVMConstBitCast (callee, LLVMPointerType (llvm_sig, 0));
1667 g_free (callee_name);
1673 * Calls are made through the GOT.
1675 return get_aotconst_typed (ctx, type, data, LLVMPointerType (llvm_sig, 0));
1677 MonoJumpInfo *ji = NULL;
1679 callee_name = mono_aot_get_plt_symbol (type, data);
1683 if (ctx->cfg->compile_aot)
1684 /* Add a patch so referenced wrappers can be compiled in full aot mode */
1685 mono_add_patch_info (ctx->cfg, 0, type, data);
1688 callee = (LLVMValueRef)g_hash_table_lookup (ctx->module->plt_entries, callee_name);
1690 callee = LLVMAddFunction (ctx->lmodule, callee_name, llvm_sig);
1692 LLVMSetVisibility (callee, LLVMHiddenVisibility);
1694 g_hash_table_insert (ctx->module->plt_entries, (char*)callee_name, callee);
1697 if (ctx->cfg->compile_aot) {
1698 ji = g_new0 (MonoJumpInfo, 1);
1700 ji->data.target = data;
1702 g_hash_table_insert (ctx->module->plt_entries_ji, ji, callee);
1710 emit_jit_callee (EmitContext *ctx, const char *name, LLVMTypeRef llvm_sig, gpointer target)
1712 #if LLVM_API_VERSION > 100
1713 LLVMValueRef tramp_var = LLVMAddGlobal (ctx->lmodule, LLVMPointerType (llvm_sig, 0), name);
1714 LLVMSetInitializer (tramp_var, LLVMConstIntToPtr (LLVMConstInt (LLVMInt64Type (), (guint64)(size_t)target, FALSE), LLVMPointerType (llvm_sig, 0)));
1715 LLVMSetLinkage (tramp_var, LLVMExternalLinkage);
1716 LLVMValueRef callee = LLVMBuildLoad (ctx->builder, tramp_var, "");
1719 LLVMValueRef callee = LLVMAddFunction (ctx->lmodule, "", llvm_sig);
1720 LLVMAddGlobalMapping (ctx->module->ee, callee, target);
1726 get_handler_clause (MonoCompile *cfg, MonoBasicBlock *bb)
1728 MonoMethodHeader *header = cfg->header;
1729 MonoExceptionClause *clause;
1733 if (bb->region != -1 && MONO_BBLOCK_IS_IN_REGION (bb, MONO_REGION_TRY))
1734 return (bb->region >> 8) - 1;
1737 for (i = 0; i < header->num_clauses; ++i) {
1738 clause = &header->clauses [i];
1740 if (MONO_OFFSET_IN_CLAUSE (clause, bb->real_offset) && clause->flags == MONO_EXCEPTION_CLAUSE_NONE)
1747 static MonoExceptionClause *
1748 get_most_deep_clause (MonoCompile *cfg, EmitContext *ctx, MonoBasicBlock *bb)
1750 // Since they're sorted by nesting we just need
1751 // the first one that the bb is a member of
1752 for (int i = 0; i < cfg->header->num_clauses; i++) {
1753 MonoExceptionClause *curr = &cfg->header->clauses [i];
1755 if (MONO_OFFSET_IN_CLAUSE (curr, bb->real_offset))
1763 set_metadata_flag (LLVMValueRef v, const char *flag_name)
1765 LLVMValueRef md_arg;
1768 md_kind = LLVMGetMDKindID (flag_name, strlen (flag_name));
1769 md_arg = LLVMMDString ("mono", 4);
1770 LLVMSetMetadata (v, md_kind, LLVMMDNode (&md_arg, 1));
1774 set_invariant_load_flag (LLVMValueRef v)
1776 LLVMValueRef md_arg;
1778 const char *flag_name;
1780 // FIXME: Cache this
1781 flag_name = "invariant.load";
1782 md_kind = LLVMGetMDKindID (flag_name, strlen (flag_name));
1783 md_arg = LLVMMDString ("<index>", strlen ("<index>"));
1784 LLVMSetMetadata (v, md_kind, LLVMMDNode (&md_arg, 1));
1790 * Emit an LLVM call or invoke instruction depending on whenever the call is inside
1794 emit_call (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, LLVMValueRef callee, LLVMValueRef *args, int pindex)
1796 MonoCompile *cfg = ctx->cfg;
1797 LLVMValueRef lcall = NULL;
1798 LLVMBuilderRef builder = *builder_ref;
1799 MonoExceptionClause *clause;
1801 if (ctx->llvm_only) {
1802 clause = get_most_deep_clause (cfg, ctx, bb);
1805 g_assert (clause->flags == MONO_EXCEPTION_CLAUSE_NONE || clause->flags == MONO_EXCEPTION_CLAUSE_FINALLY);
1808 * Have to use an invoke instead of a call, branching to the
1809 * handler bblock of the clause containing this bblock.
1811 intptr_t key = CLAUSE_END(clause);
1813 LLVMBasicBlockRef lpad_bb = (LLVMBasicBlockRef)g_hash_table_lookup (ctx->exc_meta, (gconstpointer)key);
1815 // FIXME: Find the one that has the lowest end bound for the right start address
1816 // FIXME: Finally + nesting
1819 LLVMBasicBlockRef noex_bb = gen_bb (ctx, "CALL_NOEX_BB");
1822 lcall = LLVMBuildInvoke (builder, callee, args, pindex, noex_bb, lpad_bb, "");
1824 builder = ctx->builder = create_builder (ctx);
1825 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
1827 ctx->bblocks [bb->block_num].end_bblock = noex_bb;
1831 int clause_index = get_handler_clause (cfg, bb);
1833 if (clause_index != -1) {
1834 MonoMethodHeader *header = cfg->header;
1835 MonoExceptionClause *ec = &header->clauses [clause_index];
1836 MonoBasicBlock *tblock;
1837 LLVMBasicBlockRef ex_bb, noex_bb;
1840 * Have to use an invoke instead of a call, branching to the
1841 * handler bblock of the clause containing this bblock.
1844 g_assert (ec->flags == MONO_EXCEPTION_CLAUSE_NONE || ec->flags == MONO_EXCEPTION_CLAUSE_FINALLY);
1846 tblock = cfg->cil_offset_to_bb [ec->handler_offset];
1849 ctx->bblocks [tblock->block_num].invoke_target = TRUE;
1851 ex_bb = get_bb (ctx, tblock);
1853 noex_bb = gen_bb (ctx, "NOEX_BB");
1856 lcall = LLVMBuildInvoke (builder, callee, args, pindex, noex_bb, ex_bb, "");
1858 builder = ctx->builder = create_builder (ctx);
1859 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
1861 ctx->bblocks [bb->block_num].end_bblock = noex_bb;
1866 lcall = LLVMBuildCall (builder, callee, args, pindex, "");
1867 ctx->builder = builder;
1871 *builder_ref = ctx->builder;
1877 emit_load_general (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, int size, LLVMValueRef addr, LLVMValueRef base, const char *name, gboolean is_faulting, BarrierKind barrier)
1879 const char *intrins_name;
1880 LLVMValueRef args [16], res;
1881 LLVMTypeRef addr_type;
1882 gboolean use_intrinsics = TRUE;
1884 #if LLVM_API_VERSION > 100
1885 if (is_faulting && bb->region != -1 && !ctx->cfg->llvm_only) {
1886 /* The llvm.mono.load/store intrinsics are not supported by this llvm version, emit an explicit null check instead */
1889 cmp = LLVMBuildICmp (*builder_ref, LLVMIntEQ, base, LLVMConstNull (LLVMTypeOf (base)), "");
1890 emit_cond_system_exception (ctx, bb, "NullReferenceException", cmp);
1891 *builder_ref = ctx->builder;
1892 use_intrinsics = FALSE;
1896 if (is_faulting && bb->region != -1 && !ctx->cfg->llvm_only && use_intrinsics) {
1897 LLVMAtomicOrdering ordering;
1900 case LLVM_BARRIER_NONE:
1901 ordering = LLVMAtomicOrderingNotAtomic;
1903 case LLVM_BARRIER_ACQ:
1904 ordering = LLVMAtomicOrderingAcquire;
1906 case LLVM_BARRIER_SEQ:
1907 ordering = LLVMAtomicOrderingSequentiallyConsistent;
1910 g_assert_not_reached ();
1915 * We handle loads which can fault by calling a mono specific intrinsic
1916 * using an invoke, so they are handled properly inside try blocks.
1917 * We can't use this outside clauses, since LLVM optimizes intrinsics which
1918 * are marked with IntrReadArgMem.
1922 intrins_name = "llvm.mono.load.i8.p0i8";
1925 intrins_name = "llvm.mono.load.i16.p0i16";
1928 intrins_name = "llvm.mono.load.i32.p0i32";
1931 intrins_name = "llvm.mono.load.i64.p0i64";
1934 g_assert_not_reached ();
1937 addr_type = LLVMTypeOf (addr);
1938 if (addr_type == LLVMPointerType (LLVMDoubleType (), 0) || addr_type == LLVMPointerType (LLVMFloatType (), 0))
1939 addr = LLVMBuildBitCast (*builder_ref, addr, LLVMPointerType (LLVMIntType (size * 8), 0), "");
1942 args [1] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
1943 args [2] = LLVMConstInt (LLVMInt1Type (), TRUE, FALSE);
1944 args [3] = LLVMConstInt (LLVMInt32Type (), ordering, FALSE);
1945 res = emit_call (ctx, bb, builder_ref, get_intrinsic (ctx, intrins_name), args, 4);
1947 if (addr_type == LLVMPointerType (LLVMDoubleType (), 0))
1948 res = LLVMBuildBitCast (*builder_ref, res, LLVMDoubleType (), "");
1949 else if (addr_type == LLVMPointerType (LLVMFloatType (), 0))
1950 res = LLVMBuildBitCast (*builder_ref, res, LLVMFloatType (), "");
1957 * We emit volatile loads for loads which can fault, because otherwise
1958 * LLVM will generate invalid code when encountering a load from a
1961 if (barrier != LLVM_BARRIER_NONE)
1962 res = mono_llvm_build_atomic_load (*builder_ref, addr, name, is_faulting, size, barrier);
1964 res = mono_llvm_build_load (*builder_ref, addr, name, is_faulting);
1966 /* Mark it with a custom metadata */
1969 set_metadata_flag (res, "mono.faulting.load");
1977 emit_load (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, int size, LLVMValueRef addr, const char *name, gboolean is_faulting)
1979 return emit_load_general (ctx, bb, builder_ref, size, addr, addr, name, is_faulting, LLVM_BARRIER_NONE);
1983 emit_store_general (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, int size, LLVMValueRef value, LLVMValueRef addr, LLVMValueRef base, gboolean is_faulting, BarrierKind barrier)
1985 const char *intrins_name;
1986 LLVMValueRef args [16];
1987 gboolean use_intrinsics = TRUE;
1989 #if LLVM_API_VERSION > 100
1990 if (is_faulting && bb->region != -1 && !ctx->cfg->llvm_only) {
1991 /* The llvm.mono.load/store intrinsics are not supported by this llvm version, emit an explicit null check instead */
1992 LLVMValueRef cmp = LLVMBuildICmp (*builder_ref, LLVMIntEQ, base, LLVMConstNull (LLVMTypeOf (base)), "");
1993 emit_cond_system_exception (ctx, bb, "NullReferenceException", cmp);
1994 *builder_ref = ctx->builder;
1995 use_intrinsics = FALSE;
1999 if (is_faulting && bb->region != -1 && !ctx->cfg->llvm_only && use_intrinsics) {
2000 LLVMAtomicOrdering ordering;
2003 case LLVM_BARRIER_NONE:
2004 ordering = LLVMAtomicOrderingNotAtomic;
2006 case LLVM_BARRIER_REL:
2007 ordering = LLVMAtomicOrderingRelease;
2009 case LLVM_BARRIER_SEQ:
2010 ordering = LLVMAtomicOrderingSequentiallyConsistent;
2013 g_assert_not_reached ();
2019 intrins_name = "llvm.mono.store.i8.p0i8";
2022 intrins_name = "llvm.mono.store.i16.p0i16";
2025 intrins_name = "llvm.mono.store.i32.p0i32";
2028 intrins_name = "llvm.mono.store.i64.p0i64";
2031 g_assert_not_reached ();
2034 if (LLVMTypeOf (value) == LLVMDoubleType () || LLVMTypeOf (value) == LLVMFloatType ()) {
2035 value = LLVMBuildBitCast (*builder_ref, value, LLVMIntType (size * 8), "");
2036 addr = LLVMBuildBitCast (*builder_ref, addr, LLVMPointerType (LLVMIntType (size * 8), 0), "");
2041 args [2] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
2042 args [3] = LLVMConstInt (LLVMInt1Type (), TRUE, FALSE);
2043 args [4] = LLVMConstInt (LLVMInt32Type (), ordering, FALSE);
2044 emit_call (ctx, bb, builder_ref, get_intrinsic (ctx, intrins_name), args, 5);
2046 if (barrier != LLVM_BARRIER_NONE)
2047 mono_llvm_build_aligned_store (*builder_ref, value, addr, barrier, size);
2049 mono_llvm_build_store (*builder_ref, value, addr, is_faulting, barrier);
2054 emit_store (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, int size, LLVMValueRef value, LLVMValueRef addr, LLVMValueRef base, gboolean is_faulting)
2056 emit_store_general (ctx, bb, builder_ref, size, value, addr, base, is_faulting, LLVM_BARRIER_NONE);
2060 * emit_cond_system_exception:
2062 * Emit code to throw the exception EXC_TYPE if the condition CMP is false.
2063 * Might set the ctx exception.
2066 emit_cond_system_exception (EmitContext *ctx, MonoBasicBlock *bb, const char *exc_type, LLVMValueRef cmp)
2068 LLVMBasicBlockRef ex_bb, ex2_bb = NULL, noex_bb;
2069 LLVMBuilderRef builder;
2070 MonoClass *exc_class;
2071 LLVMValueRef args [2];
2072 LLVMValueRef callee;
2073 gboolean no_pc = FALSE;
2075 if (IS_TARGET_AMD64)
2076 /* Some platforms don't require the pc argument */
2079 ex_bb = gen_bb (ctx, "EX_BB");
2081 ex2_bb = gen_bb (ctx, "EX2_BB");
2082 noex_bb = gen_bb (ctx, "NOEX_BB");
2084 LLVMBuildCondBr (ctx->builder, cmp, ex_bb, noex_bb);
2086 exc_class = mono_class_load_from_name (mono_get_corlib (), "System", exc_type);
2088 /* Emit exception throwing code */
2089 ctx->builder = builder = create_builder (ctx);
2090 LLVMPositionBuilderAtEnd (builder, ex_bb);
2092 if (ctx->cfg->llvm_only) {
2093 static LLVMTypeRef sig;
2096 sig = LLVMFunctionType1 (LLVMVoidType (), LLVMInt32Type (), FALSE);
2097 callee = get_callee (ctx, sig, MONO_PATCH_INFO_JIT_ICALL_ADDR, "mono_llvm_throw_corlib_exception");
2099 LLVMBuildBr (builder, ex2_bb);
2101 ctx->builder = builder = create_builder (ctx);
2102 LLVMPositionBuilderAtEnd (ctx->builder, ex2_bb);
2104 args [0] = LLVMConstInt (LLVMInt32Type (), exc_class->type_token - MONO_TOKEN_TYPE_DEF, FALSE);
2105 emit_call (ctx, bb, &builder, callee, args, 1);
2106 LLVMBuildUnreachable (builder);
2108 ctx->builder = builder = create_builder (ctx);
2109 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
2111 ctx->bblocks [bb->block_num].end_bblock = noex_bb;
2117 callee = ctx->module->throw_corlib_exception;
2120 const char *icall_name;
2123 sig = LLVMFunctionType1 (LLVMVoidType (), LLVMInt32Type (), FALSE);
2125 sig = LLVMFunctionType2 (LLVMVoidType (), LLVMInt32Type (), LLVMPointerType (LLVMInt8Type (), 0), FALSE);
2126 icall_name = "llvm_throw_corlib_exception_abs_trampoline";
2128 if (ctx->cfg->compile_aot) {
2129 callee = get_callee (ctx, sig, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
2132 * Differences between the LLVM/non-LLVM throw corlib exception trampoline:
2133 * - On x86, LLVM generated code doesn't push the arguments
2134 * - The trampoline takes the throw address as an arguments, not a pc offset.
2136 gpointer target = resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
2137 callee = emit_jit_callee (ctx, "llvm_throw_corlib_exception_trampoline", sig, target);
2139 #if LLVM_API_VERSION > 100
2141 * Make sure that ex_bb starts with the invoke, so the block address points to it, and not to the load
2142 * added by emit_jit_callee ().
2144 ex2_bb = gen_bb (ctx, "EX2_BB");
2145 LLVMBuildBr (builder, ex2_bb);
2148 ctx->builder = builder = create_builder (ctx);
2149 LLVMPositionBuilderAtEnd (ctx->builder, ex2_bb);
2151 mono_memory_barrier ();
2152 ctx->module->throw_corlib_exception = callee;
2157 args [0] = LLVMConstInt (LLVMInt32Type (), exc_class->type_token - MONO_TOKEN_TYPE_DEF, FALSE);
2160 * The LLVM mono branch contains changes so a block address can be passed as an
2161 * argument to a call.
2164 emit_call (ctx, bb, &builder, callee, args, 1);
2166 args [1] = LLVMBlockAddress (ctx->lmethod, ex_bb);
2167 emit_call (ctx, bb, &builder, callee, args, 2);
2170 LLVMBuildUnreachable (builder);
2172 ctx->builder = builder = create_builder (ctx);
2173 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
2175 ctx->bblocks [bb->block_num].end_bblock = noex_bb;
2182 * emit_args_to_vtype:
2184 * Emit code to store the vtype in the arguments args to the address ADDRESS.
2187 emit_args_to_vtype (EmitContext *ctx, LLVMBuilderRef builder, MonoType *t, LLVMValueRef address, LLVMArgInfo *ainfo, LLVMValueRef *args)
2189 int j, size, nslots;
2191 size = mono_class_value_size (mono_class_from_mono_type (t), NULL);
2193 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (t))) {
2194 address = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (LLVMInt8Type (), 0), "");
2197 if (ainfo->storage == LLVMArgAsFpArgs)
2198 nslots = ainfo->nslots;
2202 for (j = 0; j < nslots; ++j) {
2203 LLVMValueRef index [2], addr, daddr;
2204 int part_size = size > sizeof (gpointer) ? sizeof (gpointer) : size;
2205 LLVMTypeRef part_type;
2207 while (part_size != 1 && part_size != 2 && part_size != 4 && part_size < 8)
2210 if (ainfo->pair_storage [j] == LLVMArgNone)
2213 switch (ainfo->pair_storage [j]) {
2214 case LLVMArgInIReg: {
2215 part_type = LLVMIntType (part_size * 8);
2216 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (t))) {
2217 index [0] = LLVMConstInt (LLVMInt32Type (), j * sizeof (gpointer), FALSE);
2218 addr = LLVMBuildGEP (builder, address, index, 1, "");
2220 daddr = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (IntPtrType (), 0), "");
2221 index [0] = LLVMConstInt (LLVMInt32Type (), j, FALSE);
2222 addr = LLVMBuildGEP (builder, daddr, index, 1, "");
2224 LLVMBuildStore (builder, convert (ctx, args [j], part_type), LLVMBuildBitCast (ctx->builder, addr, LLVMPointerType (part_type, 0), ""));
2227 case LLVMArgInFPReg: {
2228 LLVMTypeRef arg_type;
2230 if (ainfo->esize == 8)
2231 arg_type = LLVMDoubleType ();
2233 arg_type = LLVMFloatType ();
2235 index [0] = LLVMConstInt (LLVMInt32Type (), j, FALSE);
2236 daddr = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (arg_type, 0), "");
2237 addr = LLVMBuildGEP (builder, daddr, index, 1, "");
2238 LLVMBuildStore (builder, args [j], addr);
2244 g_assert_not_reached ();
2247 size -= sizeof (gpointer);
2252 * emit_vtype_to_args:
2254 * Emit code to load a vtype at address ADDRESS into scalar arguments. Store the arguments
2255 * into ARGS, and the number of arguments into NARGS.
2258 emit_vtype_to_args (EmitContext *ctx, LLVMBuilderRef builder, MonoType *t, LLVMValueRef address, LLVMArgInfo *ainfo, LLVMValueRef *args, guint32 *nargs)
2261 int j, size, nslots;
2262 LLVMTypeRef arg_type;
2264 size = get_vtype_size (t);
2266 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (t)))
2267 address = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (LLVMInt8Type (), 0), "");
2269 if (ainfo->storage == LLVMArgAsFpArgs)
2270 nslots = ainfo->nslots;
2273 for (j = 0; j < nslots; ++j) {
2274 LLVMValueRef index [2], addr, daddr;
2275 int partsize = size > sizeof (gpointer) ? sizeof (gpointer) : size;
2277 if (ainfo->pair_storage [j] == LLVMArgNone)
2280 switch (ainfo->pair_storage [j]) {
2282 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (t))) {
2283 index [0] = LLVMConstInt (LLVMInt32Type (), j * sizeof (gpointer), FALSE);
2284 addr = LLVMBuildGEP (builder, address, index, 1, "");
2286 daddr = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (IntPtrType (), 0), "");
2287 index [0] = LLVMConstInt (LLVMInt32Type (), j, FALSE);
2288 addr = LLVMBuildGEP (builder, daddr, index, 1, "");
2290 args [pindex ++] = convert (ctx, LLVMBuildLoad (builder, LLVMBuildBitCast (ctx->builder, addr, LLVMPointerType (LLVMIntType (partsize * 8), 0), ""), ""), IntPtrType ());
2292 case LLVMArgInFPReg:
2293 if (ainfo->esize == 8)
2294 arg_type = LLVMDoubleType ();
2296 arg_type = LLVMFloatType ();
2297 daddr = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (arg_type, 0), "");
2298 index [0] = LLVMConstInt (LLVMInt32Type (), j, FALSE);
2299 addr = LLVMBuildGEP (builder, daddr, index, 1, "");
2300 args [pindex ++] = LLVMBuildLoad (builder, addr, "");
2305 g_assert_not_reached ();
2307 size -= sizeof (gpointer);
2314 build_alloca_llvm_type_name (EmitContext *ctx, LLVMTypeRef t, int align, const char *name)
2317 * Have to place all alloca's at the end of the entry bb, since otherwise they would
2318 * get executed every time control reaches them.
2320 LLVMPositionBuilder (ctx->alloca_builder, get_bb (ctx, ctx->cfg->bb_entry), ctx->last_alloca);
2322 ctx->last_alloca = mono_llvm_build_alloca (ctx->alloca_builder, t, NULL, align, name);
2323 return ctx->last_alloca;
2327 build_alloca_llvm_type (EmitContext *ctx, LLVMTypeRef t, int align)
2329 return build_alloca_llvm_type_name (ctx, t, align, "");
2333 build_alloca (EmitContext *ctx, MonoType *t)
2335 MonoClass *k = mono_class_from_mono_type (t);
2338 g_assert (!mini_is_gsharedvt_variable_type (t));
2340 if (MONO_CLASS_IS_SIMD (ctx->cfg, k))
2343 align = mono_class_min_align (k);
2345 /* Sometimes align is not a power of 2 */
2346 while (mono_is_power_of_two (align) == -1)
2349 return build_alloca_llvm_type (ctx, type_to_llvm_type (ctx, t), align);
2353 emit_gsharedvt_ldaddr (EmitContext *ctx, int vreg)
2357 * Compute the address of the local as gsharedvt_locals_var + gsharedvt_info_var->locals_offsets [idx].
2359 MonoCompile *cfg = ctx->cfg;
2360 LLVMBuilderRef builder = ctx->builder;
2361 LLVMValueRef offset, offset_var;
2362 LLVMValueRef info_var = ctx->values [cfg->gsharedvt_info_var->dreg];
2363 LLVMValueRef locals_var = ctx->values [cfg->gsharedvt_locals_var->dreg];
2367 g_assert (info_var);
2368 g_assert (locals_var);
2370 int idx = cfg->gsharedvt_vreg_to_idx [vreg] - 1;
2372 offset = LLVMConstInt (LLVMInt32Type (), MONO_STRUCT_OFFSET (MonoGSharedVtMethodRuntimeInfo, entries) + (idx * sizeof (gpointer)), FALSE);
2373 ptr = LLVMBuildAdd (builder, convert (ctx, info_var, IntPtrType ()), convert (ctx, offset, IntPtrType ()), "");
2375 name = g_strdup_printf ("gsharedvt_local_%d_offset", vreg);
2376 offset_var = LLVMBuildLoad (builder, convert (ctx, ptr, LLVMPointerType (LLVMInt32Type (), 0)), name);
2378 return LLVMBuildAdd (builder, convert (ctx, locals_var, IntPtrType ()), convert (ctx, offset_var, IntPtrType ()), "");
2382 * Put the global into the 'llvm.used' array to prevent it from being optimized away.
2385 mark_as_used (MonoLLVMModule *module, LLVMValueRef global)
2388 module->used = g_ptr_array_sized_new (16);
2389 g_ptr_array_add (module->used, global);
2393 emit_llvm_used (MonoLLVMModule *module)
2395 LLVMModuleRef lmodule = module->lmodule;
2396 LLVMTypeRef used_type;
2397 LLVMValueRef used, *used_elem;
2403 used_type = LLVMArrayType (LLVMPointerType (LLVMInt8Type (), 0), module->used->len);
2404 used = LLVMAddGlobal (lmodule, used_type, "llvm.used");
2405 used_elem = g_new0 (LLVMValueRef, module->used->len);
2406 for (i = 0; i < module->used->len; ++i)
2407 used_elem [i] = LLVMConstBitCast ((LLVMValueRef)g_ptr_array_index (module->used, i), LLVMPointerType (LLVMInt8Type (), 0));
2408 LLVMSetInitializer (used, LLVMConstArray (LLVMPointerType (LLVMInt8Type (), 0), used_elem, module->used->len));
2409 LLVMSetLinkage (used, LLVMAppendingLinkage);
2410 LLVMSetSection (used, "llvm.metadata");
2416 * Emit a function mapping method indexes to their code
2419 emit_get_method (MonoLLVMModule *module)
2421 LLVMModuleRef lmodule = module->lmodule;
2422 LLVMValueRef func, switch_ins, m;
2423 LLVMBasicBlockRef entry_bb, fail_bb, bb, code_start_bb, code_end_bb;
2424 LLVMBasicBlockRef *bbs;
2426 LLVMBuilderRef builder;
2431 * Emit a switch statement. Emitting a table of function addresses is smaller/faster,
2432 * but generating code seems safer.
2434 rtype = LLVMPointerType (LLVMInt8Type (), 0);
2435 func = LLVMAddFunction (lmodule, module->get_method_symbol, LLVMFunctionType1 (rtype, LLVMInt32Type (), FALSE));
2436 LLVMSetLinkage (func, LLVMExternalLinkage);
2437 LLVMSetVisibility (func, LLVMHiddenVisibility);
2438 LLVMAddFunctionAttr (func, LLVMNoUnwindAttribute);
2439 module->get_method = func;
2441 entry_bb = LLVMAppendBasicBlock (func, "ENTRY");
2444 * Return llvm_code_start/llvm_code_end when called with -1/-2.
2445 * Hopefully, the toolchain doesn't reorder these functions. If it does,
2446 * then we will have to find another solution.
2449 name = g_strdup_printf ("BB_CODE_START");
2450 code_start_bb = LLVMAppendBasicBlock (func, name);
2452 builder = LLVMCreateBuilder ();
2453 LLVMPositionBuilderAtEnd (builder, code_start_bb);
2454 LLVMBuildRet (builder, LLVMBuildBitCast (builder, module->code_start, rtype, ""));
2456 name = g_strdup_printf ("BB_CODE_END");
2457 code_end_bb = LLVMAppendBasicBlock (func, name);
2459 builder = LLVMCreateBuilder ();
2460 LLVMPositionBuilderAtEnd (builder, code_end_bb);
2461 LLVMBuildRet (builder, LLVMBuildBitCast (builder, module->code_end, rtype, ""));
2463 bbs = g_new0 (LLVMBasicBlockRef, module->max_method_idx + 1);
2464 for (i = 0; i < module->max_method_idx + 1; ++i) {
2465 name = g_strdup_printf ("BB_%d", i);
2466 bb = LLVMAppendBasicBlock (func, name);
2470 builder = LLVMCreateBuilder ();
2471 LLVMPositionBuilderAtEnd (builder, bb);
2473 m = (LLVMValueRef)g_hash_table_lookup (module->idx_to_lmethod, GINT_TO_POINTER (i));
2475 LLVMBuildRet (builder, LLVMBuildBitCast (builder, m, rtype, ""));
2477 LLVMBuildRet (builder, LLVMConstNull (rtype));
2480 fail_bb = LLVMAppendBasicBlock (func, "FAIL");
2481 builder = LLVMCreateBuilder ();
2482 LLVMPositionBuilderAtEnd (builder, fail_bb);
2483 LLVMBuildRet (builder, LLVMConstNull (rtype));
2485 builder = LLVMCreateBuilder ();
2486 LLVMPositionBuilderAtEnd (builder, entry_bb);
2488 switch_ins = LLVMBuildSwitch (builder, LLVMGetParam (func, 0), fail_bb, 0);
2489 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), -1, FALSE), code_start_bb);
2490 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), -2, FALSE), code_end_bb);
2491 for (i = 0; i < module->max_method_idx + 1; ++i) {
2492 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), i, FALSE), bbs [i]);
2495 mark_as_used (module, func);
2499 * emit_get_unbox_tramp:
2501 * Emit a function mapping method indexes to their unbox trampoline
2504 emit_get_unbox_tramp (MonoLLVMModule *module)
2506 LLVMModuleRef lmodule = module->lmodule;
2507 LLVMValueRef func, switch_ins, m;
2508 LLVMBasicBlockRef entry_bb, fail_bb, bb;
2509 LLVMBasicBlockRef *bbs;
2511 LLVMBuilderRef builder;
2515 /* Similar to emit_get_method () */
2517 rtype = LLVMPointerType (LLVMInt8Type (), 0);
2518 func = LLVMAddFunction (lmodule, module->get_unbox_tramp_symbol, LLVMFunctionType1 (rtype, LLVMInt32Type (), FALSE));
2519 LLVMSetLinkage (func, LLVMExternalLinkage);
2520 LLVMSetVisibility (func, LLVMHiddenVisibility);
2521 LLVMAddFunctionAttr (func, LLVMNoUnwindAttribute);
2522 module->get_unbox_tramp = func;
2524 entry_bb = LLVMAppendBasicBlock (func, "ENTRY");
2526 bbs = g_new0 (LLVMBasicBlockRef, module->max_method_idx + 1);
2527 for (i = 0; i < module->max_method_idx + 1; ++i) {
2528 m = (LLVMValueRef)g_hash_table_lookup (module->idx_to_unbox_tramp, GINT_TO_POINTER (i));
2532 name = g_strdup_printf ("BB_%d", i);
2533 bb = LLVMAppendBasicBlock (func, name);
2537 builder = LLVMCreateBuilder ();
2538 LLVMPositionBuilderAtEnd (builder, bb);
2540 LLVMBuildRet (builder, LLVMBuildBitCast (builder, m, rtype, ""));
2543 fail_bb = LLVMAppendBasicBlock (func, "FAIL");
2544 builder = LLVMCreateBuilder ();
2545 LLVMPositionBuilderAtEnd (builder, fail_bb);
2546 LLVMBuildRet (builder, LLVMConstNull (rtype));
2548 builder = LLVMCreateBuilder ();
2549 LLVMPositionBuilderAtEnd (builder, entry_bb);
2551 switch_ins = LLVMBuildSwitch (builder, LLVMGetParam (func, 0), fail_bb, 0);
2552 for (i = 0; i < module->max_method_idx + 1; ++i) {
2553 m = (LLVMValueRef)g_hash_table_lookup (module->idx_to_unbox_tramp, GINT_TO_POINTER (i));
2557 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), i, FALSE), bbs [i]);
2560 mark_as_used (module, func);
2563 /* Add a function to mark the beginning of LLVM code */
2565 emit_llvm_code_start (MonoLLVMModule *module)
2567 LLVMModuleRef lmodule = module->lmodule;
2569 LLVMBasicBlockRef entry_bb;
2570 LLVMBuilderRef builder;
2572 func = LLVMAddFunction (lmodule, "llvm_code_start", LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE));
2573 LLVMSetLinkage (func, LLVMInternalLinkage);
2574 LLVMAddFunctionAttr (func, LLVMNoUnwindAttribute);
2575 module->code_start = func;
2576 entry_bb = LLVMAppendBasicBlock (func, "ENTRY");
2577 builder = LLVMCreateBuilder ();
2578 LLVMPositionBuilderAtEnd (builder, entry_bb);
2579 LLVMBuildRetVoid (builder);
2583 emit_init_icall_wrapper (MonoLLVMModule *module, const char *name, const char *icall_name, int subtype)
2585 LLVMModuleRef lmodule = module->lmodule;
2586 LLVMValueRef func, indexes [2], got_entry_addr, args [16], callee;
2587 LLVMBasicBlockRef entry_bb;
2588 LLVMBuilderRef builder;
2595 func = LLVMAddFunction (lmodule, name, LLVMFunctionType1 (LLVMVoidType (), LLVMInt32Type (), FALSE));
2596 sig = LLVMFunctionType2 (LLVMVoidType (), IntPtrType (), LLVMInt32Type (), FALSE);
2601 func = LLVMAddFunction (lmodule, name, LLVMFunctionType2 (LLVMVoidType (), LLVMInt32Type (), IntPtrType (), FALSE));
2602 sig = LLVMFunctionType3 (LLVMVoidType (), IntPtrType (), LLVMInt32Type (), IntPtrType (), FALSE);
2605 func = LLVMAddFunction (lmodule, name, LLVMFunctionType2 (LLVMVoidType (), LLVMInt32Type (), ObjRefType (), FALSE));
2606 sig = LLVMFunctionType3 (LLVMVoidType (), IntPtrType (), LLVMInt32Type (), ObjRefType (), FALSE);
2609 g_assert_not_reached ();
2611 LLVMSetLinkage (func, LLVMInternalLinkage);
2612 LLVMAddFunctionAttr (func, LLVMNoInlineAttribute);
2613 mono_llvm_set_preserveall_cc (func);
2614 entry_bb = LLVMAppendBasicBlock (func, "ENTRY");
2615 builder = LLVMCreateBuilder ();
2616 LLVMPositionBuilderAtEnd (builder, entry_bb);
2619 ji = g_new0 (MonoJumpInfo, 1);
2620 ji->type = MONO_PATCH_INFO_AOT_MODULE;
2621 ji = mono_aot_patch_info_dup (ji);
2622 got_offset = mono_aot_get_got_offset (ji);
2623 module->max_got_offset = MAX (module->max_got_offset, got_offset);
2624 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
2625 indexes [1] = LLVMConstInt (LLVMInt32Type (), got_offset, FALSE);
2626 got_entry_addr = LLVMBuildGEP (builder, module->got_var, indexes, 2, "");
2627 args [0] = LLVMBuildPtrToInt (builder, LLVMBuildLoad (builder, got_entry_addr, ""), IntPtrType (), "");
2628 args [1] = LLVMGetParam (func, 0);
2630 args [2] = LLVMGetParam (func, 1);
2632 ji = g_new0 (MonoJumpInfo, 1);
2633 ji->type = MONO_PATCH_INFO_INTERNAL_METHOD;
2634 ji->data.name = icall_name;
2635 ji = mono_aot_patch_info_dup (ji);
2636 got_offset = mono_aot_get_got_offset (ji);
2637 module->max_got_offset = MAX (module->max_got_offset, got_offset);
2638 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
2639 indexes [1] = LLVMConstInt (LLVMInt32Type (), got_offset, FALSE);
2640 got_entry_addr = LLVMBuildGEP (builder, module->got_var, indexes, 2, "");
2641 callee = LLVMBuildLoad (builder, got_entry_addr, "");
2642 callee = LLVMBuildBitCast (builder, callee, LLVMPointerType (sig, 0), "");
2643 LLVMBuildCall (builder, callee, args, LLVMCountParamTypes (sig), "");
2645 // Set the inited flag
2646 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
2647 indexes [1] = LLVMGetParam (func, 0);
2648 LLVMBuildStore (builder, LLVMConstInt (LLVMInt8Type (), 1, FALSE), LLVMBuildGEP (builder, module->inited_var, indexes, 2, ""));
2650 LLVMBuildRetVoid (builder);
2652 LLVMVerifyFunction(func, LLVMAbortProcessAction);
2657 * Emit wrappers around the C icalls used to initialize llvm methods, to
2658 * make the calling code smaller and to enable usage of the llvm
2659 * PreserveAll calling convention.
2662 emit_init_icall_wrappers (MonoLLVMModule *module)
2664 module->init_method = emit_init_icall_wrapper (module, "init_method", "mono_aot_init_llvm_method", 0);
2665 module->init_method_gshared_mrgctx = emit_init_icall_wrapper (module, "init_method_gshared_mrgctx", "mono_aot_init_gshared_method_mrgctx", 1);
2666 module->init_method_gshared_this = emit_init_icall_wrapper (module, "init_method_gshared_this", "mono_aot_init_gshared_method_this", 2);
2667 module->init_method_gshared_vtable = emit_init_icall_wrapper (module, "init_method_gshared_vtable", "mono_aot_init_gshared_method_vtable", 3);
2671 emit_llvm_code_end (MonoLLVMModule *module)
2673 LLVMModuleRef lmodule = module->lmodule;
2675 LLVMBasicBlockRef entry_bb;
2676 LLVMBuilderRef builder;
2678 func = LLVMAddFunction (lmodule, "llvm_code_end", LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE));
2679 LLVMSetLinkage (func, LLVMInternalLinkage);
2680 LLVMAddFunctionAttr (func, LLVMNoUnwindAttribute);
2681 module->code_end = func;
2682 entry_bb = LLVMAppendBasicBlock (func, "ENTRY");
2683 builder = LLVMCreateBuilder ();
2684 LLVMPositionBuilderAtEnd (builder, entry_bb);
2685 LLVMBuildRetVoid (builder);
2689 emit_div_check (EmitContext *ctx, LLVMBuilderRef builder, MonoBasicBlock *bb, MonoInst *ins, LLVMValueRef lhs, LLVMValueRef rhs)
2691 gboolean need_div_check = ctx->cfg->backend->need_div_check;
2694 /* LLVM doesn't know that these can throw an exception since they are not called through an intrinsic */
2695 need_div_check = TRUE;
2697 if (!need_div_check)
2700 switch (ins->opcode) {
2713 case OP_IDIV_UN_IMM:
2714 case OP_LDIV_UN_IMM:
2715 case OP_IREM_UN_IMM:
2716 case OP_LREM_UN_IMM: {
2718 gboolean is_signed = (ins->opcode == OP_IDIV || ins->opcode == OP_LDIV || ins->opcode == OP_IREM || ins->opcode == OP_LREM ||
2719 ins->opcode == OP_IDIV_IMM || ins->opcode == OP_LDIV_IMM || ins->opcode == OP_IREM_IMM || ins->opcode == OP_LREM_IMM);
2721 cmp = LLVMBuildICmp (builder, LLVMIntEQ, rhs, LLVMConstInt (LLVMTypeOf (rhs), 0, FALSE), "");
2722 emit_cond_system_exception (ctx, bb, "DivideByZeroException", cmp);
2725 builder = ctx->builder;
2727 /* b == -1 && a == 0x80000000 */
2729 LLVMValueRef c = (LLVMTypeOf (lhs) == LLVMInt32Type ()) ? LLVMConstInt (LLVMTypeOf (lhs), 0x80000000, FALSE) : LLVMConstInt (LLVMTypeOf (lhs), 0x8000000000000000LL, FALSE);
2730 LLVMValueRef cond1 = LLVMBuildICmp (builder, LLVMIntEQ, rhs, LLVMConstInt (LLVMTypeOf (rhs), -1, FALSE), "");
2731 LLVMValueRef cond2 = LLVMBuildICmp (builder, LLVMIntEQ, lhs, c, "");
2733 cmp = LLVMBuildICmp (builder, LLVMIntEQ, LLVMBuildAnd (builder, cond1, cond2, ""), LLVMConstInt (LLVMInt1Type (), 1, FALSE), "");
2734 emit_cond_system_exception (ctx, bb, "OverflowException", cmp);
2737 builder = ctx->builder;
2749 * Emit code to initialize the GOT slots used by the method.
2752 emit_init_method (EmitContext *ctx)
2754 LLVMValueRef indexes [16], args [16], callee;
2755 LLVMValueRef inited_var, cmp, call;
2756 LLVMBasicBlockRef inited_bb, notinited_bb;
2757 LLVMBuilderRef builder = ctx->builder;
2758 MonoCompile *cfg = ctx->cfg;
2760 ctx->module->max_inited_idx = MAX (ctx->module->max_inited_idx, cfg->method_index);
2762 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
2763 indexes [1] = LLVMConstInt (LLVMInt32Type (), cfg->method_index, FALSE);
2764 inited_var = LLVMBuildLoad (builder, LLVMBuildGEP (builder, ctx->module->inited_var, indexes, 2, ""), "is_inited");
2766 args [0] = inited_var;
2767 args [1] = LLVMConstInt (LLVMInt8Type (), 1, FALSE);
2768 inited_var = LLVMBuildCall (ctx->builder, get_intrinsic (ctx, "llvm.expect.i8"), args, 2, "");
2770 cmp = LLVMBuildICmp (builder, LLVMIntEQ, inited_var, LLVMConstInt (LLVMTypeOf (inited_var), 0, FALSE), "");
2772 inited_bb = ctx->inited_bb;
2773 notinited_bb = gen_bb (ctx, "NOTINITED_BB");
2775 LLVMBuildCondBr (ctx->builder, cmp, notinited_bb, inited_bb);
2777 builder = ctx->builder = create_builder (ctx);
2778 LLVMPositionBuilderAtEnd (ctx->builder, notinited_bb);
2781 if (ctx->rgctx_arg && cfg->method->is_inflated && mono_method_get_context (cfg->method)->method_inst) {
2782 args [0] = LLVMConstInt (LLVMInt32Type (), cfg->method_index, 0);
2783 args [1] = convert (ctx, ctx->rgctx_arg, IntPtrType ());
2784 callee = ctx->module->init_method_gshared_mrgctx;
2785 call = LLVMBuildCall (builder, callee, args, 2, "");
2786 } else if (ctx->rgctx_arg) {
2787 /* A vtable is passed as the rgctx argument */
2788 args [0] = LLVMConstInt (LLVMInt32Type (), cfg->method_index, 0);
2789 args [1] = convert (ctx, ctx->rgctx_arg, IntPtrType ());
2790 callee = ctx->module->init_method_gshared_vtable;
2791 call = LLVMBuildCall (builder, callee, args, 2, "");
2792 } else if (cfg->gshared) {
2793 args [0] = LLVMConstInt (LLVMInt32Type (), cfg->method_index, 0);
2794 args [1] = convert (ctx, ctx->this_arg, ObjRefType ());
2795 callee = ctx->module->init_method_gshared_this;
2796 call = LLVMBuildCall (builder, callee, args, 2, "");
2798 args [0] = LLVMConstInt (LLVMInt32Type (), cfg->method_index, 0);
2799 callee = ctx->module->init_method;
2800 call = LLVMBuildCall (builder, callee, args, 1, "");
2804 * This enables llvm to keep arguments in their original registers/
2805 * scratch registers, since the call will not clobber them.
2807 mono_llvm_set_call_preserveall_cc (call);
2809 LLVMBuildBr (builder, inited_bb);
2810 ctx->bblocks [cfg->bb_entry->block_num].end_bblock = inited_bb;
2812 builder = ctx->builder = create_builder (ctx);
2813 LLVMPositionBuilderAtEnd (ctx->builder, inited_bb);
2817 emit_unbox_tramp (EmitContext *ctx, const char *method_name, LLVMTypeRef method_type, LLVMValueRef method, int method_index)
2820 * Emit unbox trampoline using a tail call
2822 LLVMValueRef tramp, call, *args;
2823 LLVMBuilderRef builder;
2824 LLVMBasicBlockRef lbb;
2825 LLVMCallInfo *linfo;
2829 tramp_name = g_strdup_printf ("ut_%s", method_name);
2830 tramp = LLVMAddFunction (ctx->module->lmodule, tramp_name, method_type);
2831 LLVMSetLinkage (tramp, LLVMInternalLinkage);
2832 LLVMAddFunctionAttr (tramp, LLVMOptimizeForSizeAttribute);
2833 //LLVMAddFunctionAttr (tramp, LLVMNoUnwindAttribute);
2835 // FIXME: Reduce code duplication with mono_llvm_compile_method () etc.
2836 if (!ctx->llvm_only && ctx->rgctx_arg_pindex != -1)
2837 LLVMAddAttribute (LLVMGetParam (tramp, ctx->rgctx_arg_pindex), LLVMInRegAttribute);
2838 if (ctx->cfg->vret_addr) {
2839 LLVMSetValueName (LLVMGetParam (tramp, linfo->vret_arg_pindex), "vret");
2840 if (linfo->ret.storage == LLVMArgVtypeByRef) {
2841 LLVMAddAttribute (LLVMGetParam (tramp, linfo->vret_arg_pindex), LLVMStructRetAttribute);
2842 LLVMAddAttribute (LLVMGetParam (tramp, linfo->vret_arg_pindex), LLVMNoAliasAttribute);
2846 lbb = LLVMAppendBasicBlock (tramp, "");
2847 builder = LLVMCreateBuilder ();
2848 LLVMPositionBuilderAtEnd (builder, lbb);
2850 nargs = LLVMCountParamTypes (method_type);
2851 args = g_new0 (LLVMValueRef, nargs);
2852 for (i = 0; i < nargs; ++i) {
2853 args [i] = LLVMGetParam (tramp, i);
2854 if (i == ctx->this_arg_pindex) {
2855 LLVMTypeRef arg_type = LLVMTypeOf (args [i]);
2857 args [i] = LLVMBuildPtrToInt (builder, args [i], IntPtrType (), "");
2858 args [i] = LLVMBuildAdd (builder, args [i], LLVMConstInt (IntPtrType (), sizeof (MonoObject), FALSE), "");
2859 args [i] = LLVMBuildIntToPtr (builder, args [i], arg_type, "");
2862 call = LLVMBuildCall (builder, method, args, nargs, "");
2863 if (!ctx->llvm_only && ctx->rgctx_arg_pindex != -1)
2864 LLVMAddInstrAttribute (call, 1 + ctx->rgctx_arg_pindex, LLVMInRegAttribute);
2865 if (linfo->ret.storage == LLVMArgVtypeByRef)
2866 LLVMAddInstrAttribute (call, 1 + linfo->vret_arg_pindex, LLVMStructRetAttribute);
2868 // FIXME: This causes assertions in clang
2869 //mono_llvm_set_must_tail (call);
2870 if (LLVMGetReturnType (method_type) == LLVMVoidType ())
2871 LLVMBuildRetVoid (builder);
2873 LLVMBuildRet (builder, call);
2875 g_hash_table_insert (ctx->module->idx_to_unbox_tramp, GINT_TO_POINTER (method_index), tramp);
2881 * Emit code to load/convert arguments.
2884 emit_entry_bb (EmitContext *ctx, LLVMBuilderRef builder)
2887 MonoCompile *cfg = ctx->cfg;
2888 MonoMethodSignature *sig = ctx->sig;
2889 LLVMCallInfo *linfo = ctx->linfo;
2893 LLVMBuilderRef old_builder = ctx->builder;
2894 ctx->builder = builder;
2896 ctx->alloca_builder = create_builder (ctx);
2899 * Handle indirect/volatile variables by allocating memory for them
2900 * using 'alloca', and storing their address in a temporary.
2902 for (i = 0; i < cfg->num_varinfo; ++i) {
2903 MonoInst *var = cfg->varinfo [i];
2906 if (var->opcode == OP_GSHAREDVT_LOCAL || var->opcode == OP_GSHAREDVT_ARG_REGOFFSET) {
2907 } 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))) {
2908 vtype = type_to_llvm_type (ctx, var->inst_vtype);
2911 /* Could be already created by an OP_VPHI */
2912 if (!ctx->addresses [var->dreg]) {
2913 ctx->addresses [var->dreg] = build_alloca (ctx, var->inst_vtype);
2914 //LLVMSetValueName (ctx->addresses [var->dreg], g_strdup_printf ("vreg_loc_%d", var->dreg));
2916 ctx->vreg_cli_types [var->dreg] = var->inst_vtype;
2920 names = g_new (char *, sig->param_count);
2921 mono_method_get_param_names (cfg->method, (const char **) names);
2923 for (i = 0; i < sig->param_count; ++i) {
2924 LLVMArgInfo *ainfo = &linfo->args [i + sig->hasthis];
2925 int reg = cfg->args [i + sig->hasthis]->dreg;
2928 pindex = ainfo->pindex;
2930 switch (ainfo->storage) {
2931 case LLVMArgVtypeInReg:
2932 case LLVMArgAsFpArgs: {
2933 LLVMValueRef args [8];
2936 pindex += ainfo->ndummy_fpargs;
2938 /* The argument is received as a set of int/fp arguments, store them into the real argument */
2939 memset (args, 0, sizeof (args));
2940 if (ainfo->storage == LLVMArgVtypeInReg) {
2941 args [0] = LLVMGetParam (ctx->lmethod, pindex);
2942 if (ainfo->pair_storage [1] != LLVMArgNone)
2943 args [1] = LLVMGetParam (ctx->lmethod, pindex + 1);
2945 g_assert (ainfo->nslots <= 8);
2946 for (j = 0; j < ainfo->nslots; ++j)
2947 args [j] = LLVMGetParam (ctx->lmethod, pindex + j);
2949 ctx->addresses [reg] = build_alloca (ctx, ainfo->type);
2951 emit_args_to_vtype (ctx, builder, ainfo->type, ctx->addresses [reg], ainfo, args);
2953 if (ainfo->storage == LLVMArgVtypeInReg && MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (ainfo->type))) {
2954 /* Treat these as normal values */
2955 ctx->values [reg] = LLVMBuildLoad (builder, ctx->addresses [reg], "");
2959 case LLVMArgVtypeByVal: {
2960 ctx->addresses [reg] = LLVMGetParam (ctx->lmethod, pindex);
2962 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (ainfo->type))) {
2963 /* Treat these as normal values */
2964 ctx->values [reg] = LLVMBuildLoad (builder, ctx->addresses [reg], "");
2968 case LLVMArgVtypeByRef: {
2969 /* The argument is passed by ref */
2970 ctx->addresses [reg] = LLVMGetParam (ctx->lmethod, pindex);
2973 case LLVMArgAsIArgs: {
2974 LLVMValueRef arg = LLVMGetParam (ctx->lmethod, pindex);
2977 /* The argument is received as an array of ints, store it into the real argument */
2978 ctx->addresses [reg] = build_alloca (ctx, ainfo->type);
2980 size = mono_class_value_size (mono_class_from_mono_type (ainfo->type), NULL);
2981 if (size < SIZEOF_VOID_P) {
2982 /* The upper bits of the registers might not be valid */
2983 LLVMValueRef val = LLVMBuildExtractValue (builder, arg, 0, "");
2984 LLVMValueRef dest = convert (ctx, ctx->addresses [reg], LLVMPointerType (LLVMIntType (size * 8), 0));
2985 LLVMBuildStore (ctx->builder, LLVMBuildTrunc (builder, val, LLVMIntType (size * 8), ""), dest);
2987 LLVMBuildStore (ctx->builder, arg, convert (ctx, ctx->addresses [reg], LLVMPointerType (LLVMTypeOf (arg), 0)));
2991 case LLVMArgVtypeAsScalar:
2992 g_assert_not_reached ();
2994 case LLVMArgGsharedvtFixed: {
2995 /* These are non-gsharedvt arguments passed by ref, the rest of the IR treats them as scalars */
2996 LLVMValueRef arg = LLVMGetParam (ctx->lmethod, pindex);
2999 name = g_strdup_printf ("arg_%s", names [i]);
3001 name = g_strdup_printf ("arg_%d", i);
3003 ctx->values [reg] = LLVMBuildLoad (builder, convert (ctx, arg, LLVMPointerType (type_to_llvm_type (ctx, ainfo->type), 0)), name);
3006 case LLVMArgGsharedvtFixedVtype: {
3007 LLVMValueRef arg = LLVMGetParam (ctx->lmethod, pindex);
3010 name = g_strdup_printf ("vtype_arg_%s", names [i]);
3012 name = g_strdup_printf ("vtype_arg_%d", i);
3014 /* Non-gsharedvt vtype argument passed by ref, the rest of the IR treats it as a vtype */
3015 g_assert (ctx->addresses [reg]);
3016 LLVMSetValueName (ctx->addresses [reg], name);
3017 LLVMBuildStore (builder, LLVMBuildLoad (builder, convert (ctx, arg, LLVMPointerType (type_to_llvm_type (ctx, ainfo->type), 0)), ""), ctx->addresses [reg]);
3020 case LLVMArgGsharedvtVariable:
3021 /* The IR treats these as variables with addresses */
3022 ctx->addresses [reg] = LLVMGetParam (ctx->lmethod, pindex);
3025 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));
3032 emit_volatile_store (ctx, cfg->vret_addr->dreg);
3034 emit_volatile_store (ctx, cfg->args [0]->dreg);
3035 for (i = 0; i < sig->param_count; ++i)
3036 if (!mini_type_is_vtype (sig->params [i]))
3037 emit_volatile_store (ctx, cfg->args [i + sig->hasthis]->dreg);
3039 if (sig->hasthis && !cfg->rgctx_var && cfg->gshared) {
3040 LLVMValueRef this_alloc;
3043 * The exception handling code needs the location where the this argument was
3044 * stored for gshared methods. We create a separate alloca to hold it, and mark it
3045 * with the "mono.this" custom metadata to tell llvm that it needs to save its
3046 * location into the LSDA.
3048 this_alloc = mono_llvm_build_alloca (builder, ThisType (), LLVMConstInt (LLVMInt32Type (), 1, FALSE), 0, "");
3049 /* This volatile store will keep the alloca alive */
3050 mono_llvm_build_store (builder, ctx->values [cfg->args [0]->dreg], this_alloc, TRUE, LLVM_BARRIER_NONE);
3052 set_metadata_flag (this_alloc, "mono.this");
3055 if (cfg->rgctx_var) {
3056 LLVMValueRef rgctx_alloc, store;
3059 * We handle the rgctx arg similarly to the this pointer.
3061 g_assert (ctx->addresses [cfg->rgctx_var->dreg]);
3062 rgctx_alloc = ctx->addresses [cfg->rgctx_var->dreg];
3063 /* This volatile store will keep the alloca alive */
3064 store = mono_llvm_build_store (builder, convert (ctx, ctx->rgctx_arg, IntPtrType ()), rgctx_alloc, TRUE, LLVM_BARRIER_NONE);
3066 set_metadata_flag (rgctx_alloc, "mono.this");
3069 /* Initialize the method if needed */
3070 if (cfg->compile_aot && ctx->llvm_only) {
3071 /* Emit a location for the initialization code */
3072 ctx->init_bb = gen_bb (ctx, "INIT_BB");
3073 ctx->inited_bb = gen_bb (ctx, "INITED_BB");
3075 LLVMBuildBr (ctx->builder, ctx->init_bb);
3076 builder = ctx->builder = create_builder (ctx);
3077 LLVMPositionBuilderAtEnd (ctx->builder, ctx->inited_bb);
3078 ctx->bblocks [cfg->bb_entry->block_num].end_bblock = ctx->inited_bb;
3081 /* Compute nesting between clauses */
3082 ctx->nested_in = (GSList**)mono_mempool_alloc0 (cfg->mempool, sizeof (GSList*) * cfg->header->num_clauses);
3083 for (i = 0; i < cfg->header->num_clauses; ++i) {
3084 for (j = 0; j < cfg->header->num_clauses; ++j) {
3085 MonoExceptionClause *clause1 = &cfg->header->clauses [i];
3086 MonoExceptionClause *clause2 = &cfg->header->clauses [j];
3088 if (i != j && clause1->try_offset >= clause2->try_offset && clause1->handler_offset <= clause2->handler_offset)
3089 ctx->nested_in [i] = g_slist_prepend_mempool (cfg->mempool, ctx->nested_in [i], GINT_TO_POINTER (j));
3094 * For finally clauses, create an indicator variable telling OP_ENDFINALLY whenever
3095 * it needs to continue normally, or return back to the exception handling system.
3097 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
3101 if (!(bb->region != -1 && (bb->flags & BB_EXCEPTION_HANDLER)))
3104 clause_index = MONO_REGION_CLAUSE_INDEX (bb->region);
3105 g_hash_table_insert (ctx->region_to_handler, GUINT_TO_POINTER (mono_get_block_region_notry (cfg, bb->region)), bb);
3106 g_hash_table_insert (ctx->clause_to_handler, GINT_TO_POINTER (clause_index), bb);
3108 if (bb->in_scount == 0) {
3111 sprintf (name, "finally_ind_bb%d", bb->block_num);
3112 val = LLVMBuildAlloca (builder, LLVMInt32Type (), name);
3113 LLVMBuildStore (builder, LLVMConstInt (LLVMInt32Type (), 0, FALSE), val);
3115 ctx->bblocks [bb->block_num].finally_ind = val;
3117 /* Create a variable to hold the exception var */
3119 ctx->ex_var = LLVMBuildAlloca (builder, ObjRefType (), "exvar");
3123 * Create a new bblock which CALL_HANDLER/landing pads can branch to, because branching to the
3124 * LLVM bblock containing a landing pad causes problems for the
3125 * LLVM optimizer passes.
3127 sprintf (name, "BB%d_CALL_HANDLER_TARGET", bb->block_num);
3128 ctx->bblocks [bb->block_num].call_handler_target_bb = LLVMAppendBasicBlock (ctx->lmethod, name);
3130 ctx->builder = old_builder;
3134 process_call (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, MonoInst *ins)
3136 MonoCompile *cfg = ctx->cfg;
3137 LLVMValueRef *values = ctx->values;
3138 LLVMValueRef *addresses = ctx->addresses;
3139 MonoCallInst *call = (MonoCallInst*)ins;
3140 MonoMethodSignature *sig = call->signature;
3141 LLVMValueRef callee = NULL, lcall;
3143 LLVMCallInfo *cinfo;
3147 LLVMTypeRef llvm_sig;
3149 gboolean is_virtual, calli, preserveall;
3150 LLVMBuilderRef builder = *builder_ref;
3152 if ((call->signature->call_convention != MONO_CALL_DEFAULT) && !((call->signature->call_convention == MONO_CALL_C) && ctx->llvm_only)) {
3153 set_failure (ctx, "non-default callconv");
3157 cinfo = call->cinfo;
3159 if (call->rgctx_arg_reg)
3160 cinfo->rgctx_arg = TRUE;
3161 if (call->imt_arg_reg)
3162 cinfo->imt_arg = TRUE;
3164 vretaddr = (cinfo->ret.storage == LLVMArgVtypeRetAddr || cinfo->ret.storage == LLVMArgVtypeByRef || cinfo->ret.storage == LLVMArgGsharedvtFixed || cinfo->ret.storage == LLVMArgGsharedvtVariable || cinfo->ret.storage == LLVMArgGsharedvtFixedVtype);
3166 llvm_sig = sig_to_llvm_sig_full (ctx, sig, cinfo);
3170 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);
3171 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);
3173 preserveall = FALSE;
3175 /* FIXME: Avoid creating duplicate methods */
3177 if (ins->flags & MONO_INST_HAS_METHOD) {
3181 if (cfg->compile_aot) {
3182 callee = get_callee (ctx, llvm_sig, MONO_PATCH_INFO_METHOD, call->method);
3184 set_failure (ctx, "can't encode patch");
3187 if (cfg->llvm_only && call->method->klass->image->assembly == ctx->module->assembly) {
3189 * Collect instructions representing the callee into a hash so they can be replaced
3190 * by the llvm method for the callee if the callee turns out to be direct
3191 * callable. Currently this only requires it to not fail llvm compilation.
3193 GSList *l = (GSList*)g_hash_table_lookup (ctx->method_to_callers, call->method);
3194 l = g_slist_prepend (l, callee);
3195 g_hash_table_insert (ctx->method_to_callers, call->method, l);
3199 static int tramp_index;
3202 name = g_strdup_printf ("tramp_%d", tramp_index);
3205 #if LLVM_API_VERSION > 100
3207 * Use our trampoline infrastructure for lazy compilation instead of llvm's.
3208 * Make all calls through a global. The address of the global will be saved in
3209 * MonoJitDomainInfo.llvm_jit_callees and updated when the method it refers to is
3212 LLVMValueRef tramp_var = g_hash_table_lookup (ctx->jit_callees, call->method);
3215 mono_create_jit_trampoline (mono_domain_get (),
3216 call->method, &error);
3217 if (!is_ok (&error)) {
3218 set_failure (ctx, mono_error_get_message (&error));
3219 mono_error_cleanup (&error);
3223 tramp_var = LLVMAddGlobal (ctx->lmodule, LLVMPointerType (llvm_sig, 0), name);
3224 LLVMSetInitializer (tramp_var, LLVMConstIntToPtr (LLVMConstInt (LLVMInt64Type (), (guint64)(size_t)target, FALSE), LLVMPointerType (llvm_sig, 0)));
3225 LLVMSetLinkage (tramp_var, LLVMExternalLinkage);
3226 g_hash_table_insert (ctx->jit_callees, call->method, tramp_var);
3228 callee = LLVMBuildLoad (builder, tramp_var, "");
3231 mono_create_jit_trampoline (mono_domain_get (),
3232 call->method, &error);
3233 if (!is_ok (&error)) {
3235 set_failure (ctx, mono_error_get_message (&error));
3236 mono_error_cleanup (&error);
3240 callee = LLVMAddFunction (ctx->lmodule, name, llvm_sig);
3243 LLVMAddGlobalMapping (ctx->module->ee, callee, target);
3248 if (!cfg->llvm_only && call->method && strstr (call->method->klass->name, "AsyncVoidMethodBuilder")) {
3249 /* LLVM miscompiles async methods */
3250 set_failure (ctx, "#13734");
3255 MonoJitICallInfo *info = mono_find_jit_icall_by_addr (call->fptr);
3261 memset (&ji, 0, sizeof (ji));
3262 ji.type = MONO_PATCH_INFO_JIT_ICALL_ADDR;
3263 ji.data.target = info->name;
3265 target = mono_resolve_patch_target (cfg->method, cfg->domain, NULL, &ji, FALSE);
3267 if (cfg->compile_aot) {
3268 callee = get_callee (ctx, llvm_sig, MONO_PATCH_INFO_INTERNAL_METHOD, (char*)info->name);
3270 set_failure (ctx, "can't encode patch");
3274 target = (gpointer)mono_icall_get_wrapper (info);
3275 callee = emit_jit_callee (ctx, "", llvm_sig, target);
3278 if (cfg->compile_aot) {
3280 if (cfg->abs_patches) {
3281 MonoJumpInfo *abs_ji = (MonoJumpInfo*)g_hash_table_lookup (cfg->abs_patches, call->fptr);
3283 callee = get_callee (ctx, llvm_sig, abs_ji->type, abs_ji->data.target);
3285 set_failure (ctx, "can't encode patch");
3291 set_failure (ctx, "aot");
3295 #if LLVM_API_VERSION > 100
3296 if (cfg->abs_patches) {
3297 MonoJumpInfo *abs_ji = (MonoJumpInfo*)g_hash_table_lookup (cfg->abs_patches, call->fptr);
3301 target = mono_resolve_patch_target (cfg->method, cfg->domain, NULL, abs_ji, FALSE, &error);
3302 mono_error_assert_ok (&error);
3303 callee = emit_jit_callee (ctx, "", llvm_sig, target);
3305 g_assert_not_reached ();
3308 g_assert_not_reached ();
3311 callee = LLVMAddFunction (ctx->lmodule, "", llvm_sig);
3313 if (cfg->abs_patches) {
3314 MonoJumpInfo *abs_ji = (MonoJumpInfo*)g_hash_table_lookup (cfg->abs_patches, call->fptr);
3319 * FIXME: Some trampolines might have
3320 * their own calling convention on some platforms.
3322 target = mono_resolve_patch_target (cfg->method, cfg->domain, NULL, abs_ji, FALSE, &error);
3323 mono_error_assert_ok (&error);
3324 LLVMAddGlobalMapping (ctx->module->ee, callee, target);
3328 LLVMAddGlobalMapping (ctx->module->ee, callee, (gpointer)call->fptr);
3335 int size = sizeof (gpointer);
3338 g_assert (ins->inst_offset % size == 0);
3339 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
3341 callee = convert (ctx, LLVMBuildLoad (builder, LLVMBuildGEP (builder, convert (ctx, values [ins->inst_basereg], LLVMPointerType (LLVMPointerType (IntPtrType (), 0), 0)), &index, 1, ""), ""), LLVMPointerType (llvm_sig, 0));
3343 callee = convert (ctx, values [ins->sreg1], LLVMPointerType (llvm_sig, 0));
3345 if (ins->flags & MONO_INST_HAS_METHOD) {
3350 * Collect and convert arguments
3352 nargs = (sig->param_count * 16) + sig->hasthis + vretaddr + call->rgctx_reg + call->imt_arg_reg;
3353 len = sizeof (LLVMValueRef) * nargs;
3354 args = (LLVMValueRef*)alloca (len);
3355 memset (args, 0, len);
3356 l = call->out_ireg_args;
3358 if (call->rgctx_arg_reg) {
3359 g_assert (values [call->rgctx_arg_reg]);
3360 g_assert (cinfo->rgctx_arg_pindex < nargs);
3362 * On ARM, the imt/rgctx argument is passed in a caller save register, but some of our trampolines etc. clobber it, leading to
3363 * problems is LLVM moves the arg assignment earlier. To work around this, save the argument into a stack slot and load
3364 * it using a volatile load.
3367 if (!ctx->imt_rgctx_loc)
3368 ctx->imt_rgctx_loc = build_alloca_llvm_type (ctx, ctx->module->ptr_type, sizeof (gpointer));
3369 LLVMBuildStore (builder, convert (ctx, ctx->values [call->rgctx_arg_reg], ctx->module->ptr_type), ctx->imt_rgctx_loc);
3370 args [cinfo->rgctx_arg_pindex] = mono_llvm_build_load (builder, ctx->imt_rgctx_loc, "", TRUE);
3372 args [cinfo->rgctx_arg_pindex] = convert (ctx, values [call->rgctx_arg_reg], ctx->module->ptr_type);
3375 if (call->imt_arg_reg) {
3376 g_assert (!ctx->llvm_only);
3377 g_assert (values [call->imt_arg_reg]);
3378 g_assert (cinfo->imt_arg_pindex < nargs);
3380 if (!ctx->imt_rgctx_loc)
3381 ctx->imt_rgctx_loc = build_alloca_llvm_type (ctx, ctx->module->ptr_type, sizeof (gpointer));
3382 LLVMBuildStore (builder, convert (ctx, ctx->values [call->imt_arg_reg], ctx->module->ptr_type), ctx->imt_rgctx_loc);
3383 args [cinfo->imt_arg_pindex] = mono_llvm_build_load (builder, ctx->imt_rgctx_loc, "", TRUE);
3385 args [cinfo->imt_arg_pindex] = convert (ctx, values [call->imt_arg_reg], ctx->module->ptr_type);
3388 switch (cinfo->ret.storage) {
3389 case LLVMArgGsharedvtVariable: {
3390 MonoInst *var = get_vreg_to_inst (cfg, call->inst.dreg);
3392 if (var && var->opcode == OP_GSHAREDVT_LOCAL) {
3393 args [cinfo->vret_arg_pindex] = convert (ctx, emit_gsharedvt_ldaddr (ctx, var->dreg), IntPtrType ());
3395 g_assert (addresses [call->inst.dreg]);
3396 args [cinfo->vret_arg_pindex] = addresses [call->inst.dreg];
3402 if (!addresses [call->inst.dreg])
3403 addresses [call->inst.dreg] = build_alloca (ctx, sig->ret);
3404 g_assert (cinfo->vret_arg_pindex < nargs);
3405 if (cinfo->ret.storage == LLVMArgVtypeByRef)
3406 args [cinfo->vret_arg_pindex] = addresses [call->inst.dreg];
3408 args [cinfo->vret_arg_pindex] = LLVMBuildPtrToInt (builder, addresses [call->inst.dreg], IntPtrType (), "");
3414 * Sometimes the same method is called with two different signatures (i.e. with and without 'this'), so
3415 * use the real callee for argument type conversion.
3417 LLVMTypeRef callee_type = LLVMGetElementType (LLVMTypeOf (callee));
3418 LLVMTypeRef *param_types = (LLVMTypeRef*)g_alloca (sizeof (LLVMTypeRef) * LLVMCountParamTypes (callee_type));
3419 LLVMGetParamTypes (callee_type, param_types);
3421 for (i = 0; i < sig->param_count + sig->hasthis; ++i) {
3424 LLVMArgInfo *ainfo = &call->cinfo->args [i];
3426 pindex = ainfo->pindex;
3428 regpair = (guint32)(gssize)(l->data);
3429 reg = regpair & 0xffffff;
3430 args [pindex] = values [reg];
3431 switch (ainfo->storage) {
3432 case LLVMArgVtypeInReg:
3433 case LLVMArgAsFpArgs: {
3437 for (j = 0; j < ainfo->ndummy_fpargs; ++j)
3438 args [pindex + j] = LLVMConstNull (LLVMDoubleType ());
3439 pindex += ainfo->ndummy_fpargs;
3441 g_assert (addresses [reg]);
3442 emit_vtype_to_args (ctx, builder, ainfo->type, addresses [reg], ainfo, args + pindex, &nargs);
3446 // FIXME: Get rid of the VMOVE
3449 case LLVMArgVtypeByVal:
3450 g_assert (addresses [reg]);
3451 args [pindex] = addresses [reg];
3453 case LLVMArgVtypeByRef: {
3454 g_assert (addresses [reg]);
3455 args [pindex] = convert (ctx, addresses [reg], LLVMPointerType (type_to_llvm_arg_type (ctx, ainfo->type), 0));
3458 case LLVMArgAsIArgs:
3459 g_assert (addresses [reg]);
3460 args [pindex] = LLVMBuildLoad (ctx->builder, convert (ctx, addresses [reg], LLVMPointerType (LLVMArrayType (IntPtrType (), ainfo->nslots), 0)), "");
3462 case LLVMArgVtypeAsScalar:
3463 g_assert_not_reached ();
3465 case LLVMArgGsharedvtFixed:
3466 case LLVMArgGsharedvtFixedVtype:
3467 g_assert (addresses [reg]);
3468 args [pindex] = convert (ctx, addresses [reg], LLVMPointerType (type_to_llvm_arg_type (ctx, ainfo->type), 0));
3470 case LLVMArgGsharedvtVariable:
3471 g_assert (addresses [reg]);
3472 args [pindex] = convert (ctx, addresses [reg], LLVMPointerType (IntPtrType (), 0));
3475 g_assert (args [pindex]);
3476 if (i == 0 && sig->hasthis)
3477 args [pindex] = convert (ctx, args [pindex], param_types [pindex]);
3479 args [pindex] = convert (ctx, args [pindex], type_to_llvm_arg_type (ctx, ainfo->type));
3482 g_assert (pindex <= nargs);
3487 // FIXME: Align call sites
3493 lcall = emit_call (ctx, bb, &builder, callee, args, LLVMCountParamTypes (llvm_sig));
3496 * Modify cconv and parameter attributes to pass rgctx/imt correctly.
3498 #if defined(MONO_ARCH_IMT_REG) && defined(MONO_ARCH_RGCTX_REG)
3499 g_assert (MONO_ARCH_IMT_REG == MONO_ARCH_RGCTX_REG);
3501 /* The two can't be used together, so use only one LLVM calling conv to pass them */
3502 g_assert (!(call->rgctx_arg_reg && call->imt_arg_reg));
3503 if (!sig->pinvoke && !cfg->llvm_only)
3504 LLVMSetInstructionCallConv (lcall, LLVMMono1CallConv);
3506 mono_llvm_set_call_preserveall_cc (lcall);
3508 if (cinfo->ret.storage == LLVMArgVtypeByRef)
3509 LLVMAddInstrAttribute (lcall, 1 + cinfo->vret_arg_pindex, LLVMStructRetAttribute);
3510 if (!ctx->llvm_only && call->rgctx_arg_reg)
3511 LLVMAddInstrAttribute (lcall, 1 + cinfo->rgctx_arg_pindex, LLVMInRegAttribute);
3512 if (call->imt_arg_reg)
3513 LLVMAddInstrAttribute (lcall, 1 + cinfo->imt_arg_pindex, LLVMInRegAttribute);
3515 /* Add byval attributes if needed */
3516 for (i = 0; i < sig->param_count; ++i) {
3517 LLVMArgInfo *ainfo = &call->cinfo->args [i + sig->hasthis];
3519 if (ainfo && ainfo->storage == LLVMArgVtypeByVal)
3520 LLVMAddInstrAttribute (lcall, 1 + ainfo->pindex, LLVMByValAttribute);
3524 * Convert the result
3526 switch (cinfo->ret.storage) {
3527 case LLVMArgVtypeInReg: {
3528 LLVMValueRef regs [2];
3530 if (LLVMTypeOf (lcall) == LLVMVoidType ())
3534 if (!addresses [ins->dreg])
3535 addresses [ins->dreg] = build_alloca (ctx, sig->ret);
3537 regs [0] = LLVMBuildExtractValue (builder, lcall, 0, "");
3538 if (cinfo->ret.pair_storage [1] != LLVMArgNone)
3539 regs [1] = LLVMBuildExtractValue (builder, lcall, 1, "");
3540 emit_args_to_vtype (ctx, builder, sig->ret, addresses [ins->dreg], &cinfo->ret, regs);
3543 case LLVMArgVtypeByVal:
3544 if (!addresses [call->inst.dreg])
3545 addresses [call->inst.dreg] = build_alloca (ctx, sig->ret);
3546 LLVMBuildStore (builder, lcall, addresses [call->inst.dreg]);
3548 case LLVMArgAsIArgs:
3549 case LLVMArgFpStruct:
3550 if (!addresses [call->inst.dreg])
3551 addresses [call->inst.dreg] = build_alloca (ctx, sig->ret);
3552 LLVMBuildStore (builder, lcall, convert_full (ctx, addresses [call->inst.dreg], LLVMPointerType (LLVMTypeOf (lcall), 0), FALSE));
3554 case LLVMArgVtypeAsScalar:
3555 if (!addresses [call->inst.dreg])
3556 addresses [call->inst.dreg] = build_alloca (ctx, sig->ret);
3557 LLVMBuildStore (builder, lcall, convert_full (ctx, addresses [call->inst.dreg], LLVMPointerType (LLVMTypeOf (lcall), 0), FALSE));
3559 case LLVMArgVtypeRetAddr:
3560 case LLVMArgVtypeByRef:
3561 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (sig->ret))) {
3562 /* Some opcodes like STOREX_MEMBASE access these by value */
3563 g_assert (addresses [call->inst.dreg]);
3564 values [ins->dreg] = LLVMBuildLoad (builder, convert_full (ctx, addresses [call->inst.dreg], LLVMPointerType (type_to_llvm_type (ctx, sig->ret), 0), FALSE), "");
3567 case LLVMArgGsharedvtVariable:
3569 case LLVMArgGsharedvtFixed:
3570 case LLVMArgGsharedvtFixedVtype:
3571 values [ins->dreg] = LLVMBuildLoad (builder, convert_full (ctx, addresses [call->inst.dreg], LLVMPointerType (type_to_llvm_type (ctx, sig->ret), 0), FALSE), "");
3574 if (sig->ret->type != MONO_TYPE_VOID)
3575 /* If the method returns an unsigned value, need to zext it */
3576 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));
3580 *builder_ref = ctx->builder;
3584 emit_llvmonly_throw (EmitContext *ctx, MonoBasicBlock *bb, gboolean rethrow, LLVMValueRef exc)
3586 const char *icall_name = rethrow ? "mono_llvm_rethrow_exception" : "mono_llvm_throw_exception";
3587 LLVMValueRef callee = rethrow ? ctx->module->rethrow : ctx->module->throw_icall;
3589 LLVMTypeRef exc_type = type_to_llvm_type (ctx, &mono_get_exception_class ()->byval_arg);
3592 LLVMTypeRef fun_sig = LLVMFunctionType1 (LLVMVoidType (), exc_type, FALSE);
3594 if (ctx->cfg->compile_aot) {
3595 callee = get_callee (ctx, fun_sig, MONO_PATCH_INFO_JIT_ICALL_ADDR, icall_name);
3597 callee = LLVMAddFunction (ctx->lmodule, icall_name, fun_sig);
3598 LLVMAddGlobalMapping (ctx->module->ee, callee, resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name));
3599 mono_memory_barrier ();
3602 ctx->module->rethrow = callee;
3604 ctx->module->throw_icall = callee;
3608 LLVMValueRef args [2];
3610 args [0] = convert (ctx, exc, exc_type);
3611 emit_call (ctx, bb, &ctx->builder, callee, args, 1);
3613 LLVMBuildUnreachable (ctx->builder);
3615 ctx->builder = create_builder (ctx);
3619 emit_throw (EmitContext *ctx, MonoBasicBlock *bb, gboolean rethrow, LLVMValueRef exc)
3621 MonoMethodSignature *throw_sig;
3622 LLVMValueRef callee, arg;
3623 const char *icall_name;
3625 callee = rethrow ? ctx->module->rethrow : ctx->module->throw_icall;
3626 icall_name = rethrow ? "mono_arch_rethrow_exception" : "mono_arch_throw_exception";
3629 throw_sig = mono_metadata_signature_alloc (mono_get_corlib (), 1);
3630 throw_sig->ret = &mono_get_void_class ()->byval_arg;
3631 throw_sig->params [0] = &mono_get_object_class ()->byval_arg;
3632 if (ctx->cfg->compile_aot) {
3633 callee = get_callee (ctx, sig_to_llvm_sig (ctx, throw_sig), MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
3638 * LLVM doesn't push the exception argument, so we need a different
3641 target = resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, rethrow ? "llvm_rethrow_exception_trampoline" : "llvm_throw_exception_trampoline");
3643 target = resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
3645 callee = emit_jit_callee (ctx, icall_name, sig_to_llvm_sig (ctx, throw_sig), target);
3648 mono_memory_barrier ();
3649 #if LLVM_API_VERSION < 100
3651 ctx->module->rethrow = callee;
3653 ctx->module->throw_icall = callee;
3656 arg = convert (ctx, exc, type_to_llvm_type (ctx, &mono_get_object_class ()->byval_arg));
3657 emit_call (ctx, bb, &ctx->builder, callee, &arg, 1);
3661 emit_resume_eh (EmitContext *ctx, MonoBasicBlock *bb)
3663 const char *icall_name = "mono_llvm_resume_exception";
3664 LLVMValueRef callee = ctx->module->resume_eh;
3666 LLVMTypeRef fun_sig = LLVMFunctionType0 (LLVMVoidType (), FALSE);
3669 if (ctx->cfg->compile_aot) {
3670 callee = get_callee (ctx, fun_sig, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
3672 callee = LLVMAddFunction (ctx->lmodule, icall_name, fun_sig);
3673 LLVMAddGlobalMapping (ctx->module->ee, callee, resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name));
3674 mono_memory_barrier ();
3676 ctx->module->resume_eh = callee;
3680 emit_call (ctx, bb, &ctx->builder, callee, NULL, 0);
3682 LLVMBuildUnreachable (ctx->builder);
3684 ctx->builder = create_builder (ctx);
3688 mono_llvm_emit_clear_exception_call (EmitContext *ctx, LLVMBuilderRef builder)
3690 const char *icall_name = "mono_llvm_clear_exception";
3692 LLVMTypeRef call_sig = LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE);
3693 LLVMValueRef callee = NULL;
3696 if (ctx->cfg->compile_aot) {
3697 callee = get_callee (ctx, call_sig, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
3699 // FIXME: This is broken.
3700 callee = LLVMAddFunction (ctx->lmodule, icall_name, call_sig);
3704 g_assert (builder && callee);
3706 return LLVMBuildCall (builder, callee, NULL, 0, "");
3710 mono_llvm_emit_load_exception_call (EmitContext *ctx, LLVMBuilderRef builder)
3712 const char *icall_name = "mono_llvm_load_exception";
3714 LLVMTypeRef call_sig = LLVMFunctionType (ObjRefType (), NULL, 0, FALSE);
3715 LLVMValueRef callee = NULL;
3718 if (ctx->cfg->compile_aot) {
3719 callee = get_callee (ctx, call_sig, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
3721 // FIXME: This is broken.
3722 callee = LLVMAddFunction (ctx->lmodule, icall_name, call_sig);
3726 g_assert (builder && callee);
3728 return LLVMBuildCall (builder, callee, NULL, 0, icall_name);
3733 mono_llvm_emit_match_exception_call (EmitContext *ctx, LLVMBuilderRef builder, gint32 region_start, gint32 region_end)
3735 const char *icall_name = "mono_llvm_match_exception";
3737 ctx->builder = builder;
3739 const int num_args = 5;
3740 LLVMValueRef args [num_args];
3741 args [0] = convert (ctx, get_aotconst (ctx, MONO_PATCH_INFO_AOT_JIT_INFO, GINT_TO_POINTER (ctx->cfg->method_index)), IntPtrType ());
3742 args [1] = LLVMConstInt (LLVMInt32Type (), region_start, 0);
3743 args [2] = LLVMConstInt (LLVMInt32Type (), region_end, 0);
3744 if (ctx->cfg->rgctx_var) {
3745 LLVMValueRef rgctx_alloc = ctx->addresses [ctx->cfg->rgctx_var->dreg];
3746 g_assert (rgctx_alloc);
3747 args [3] = LLVMBuildLoad (builder, convert (ctx, rgctx_alloc, LLVMPointerType (IntPtrType (), 0)), "");
3749 args [3] = LLVMConstInt (IntPtrType (), 0, 0);
3752 args [4] = convert (ctx, ctx->this_arg, IntPtrType ());
3754 args [4] = LLVMConstInt (IntPtrType (), 0, 0);
3756 LLVMTypeRef match_sig = LLVMFunctionType5 (LLVMInt32Type (), IntPtrType (), LLVMInt32Type (), LLVMInt32Type (), IntPtrType (), IntPtrType (), FALSE);
3757 LLVMValueRef callee = ctx->module->match_exc;
3760 if (ctx->cfg->compile_aot) {
3761 ctx->builder = builder;
3762 // get_callee expects ctx->builder to be the emitting builder
3763 callee = get_callee (ctx, match_sig, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
3765 callee = ctx->module->match_exc = LLVMAddFunction (ctx->lmodule, icall_name, match_sig);
3766 LLVMAddGlobalMapping (ctx->module->ee, ctx->module->match_exc, resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name));
3767 ctx->module->match_exc = callee;
3768 mono_memory_barrier ();
3772 g_assert (builder && callee);
3774 g_assert (ctx->ex_var);
3776 return LLVMBuildCall (builder, callee, args, num_args, icall_name);
3779 // FIXME: This won't work because the code-finding makes this
3781 /*#define MONO_PERSONALITY_DEBUG*/
3783 #ifdef MONO_PERSONALITY_DEBUG
3784 static const gboolean use_debug_personality = TRUE;
3785 static const char *default_personality_name = "mono_debug_personality";
3787 static const gboolean use_debug_personality = FALSE;
3788 static const char *default_personality_name = "__gxx_personality_v0";
3792 default_cpp_lpad_exc_signature (void)
3794 static gboolean inited = FALSE;
3795 static LLVMTypeRef sig;
3798 LLVMTypeRef signature [2];
3799 signature [0] = LLVMPointerType (LLVMInt8Type (), 0);
3800 signature [1] = LLVMInt32Type ();
3801 sig = LLVMStructType (signature, 2, FALSE);
3809 get_mono_personality (EmitContext *ctx)
3811 LLVMValueRef personality = NULL;
3812 static gint32 mapping_inited = FALSE;
3813 LLVMTypeRef personality_type = LLVMFunctionType (LLVMInt32Type (), NULL, 0, TRUE);
3815 if (!use_debug_personality) {
3816 if (ctx->cfg->compile_aot) {
3817 personality = get_intrinsic (ctx, default_personality_name);
3818 } else if (InterlockedCompareExchange (&mapping_inited, 1, 0) == 0) {
3819 personality = LLVMAddFunction (ctx->lmodule, default_personality_name, personality_type);
3820 LLVMAddGlobalMapping (ctx->module->ee, personality, personality);
3823 if (ctx->cfg->compile_aot) {
3824 personality = get_callee (ctx, personality_type, MONO_PATCH_INFO_INTERNAL_METHOD, default_personality_name);
3826 personality = LLVMAddFunction (ctx->lmodule, default_personality_name, personality_type);
3827 LLVMAddGlobalMapping (ctx->module->ee, personality, resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, default_personality_name));
3828 mono_memory_barrier ();
3832 g_assert (personality);
3836 static LLVMBasicBlockRef
3837 emit_landing_pad (EmitContext *ctx, int group_index, int group_size)
3839 MonoCompile *cfg = ctx->cfg;
3840 LLVMBuilderRef old_builder = ctx->builder;
3841 MonoExceptionClause *group_start = cfg->header->clauses + group_index;
3843 LLVMBuilderRef lpadBuilder = create_builder (ctx);
3844 ctx->builder = lpadBuilder;
3846 MonoBasicBlock *handler_bb = cfg->cil_offset_to_bb [CLAUSE_START (group_start)];
3847 g_assert (handler_bb);
3849 // <resultval> = landingpad <somety> personality <type> <pers_fn> <clause>+
3850 LLVMValueRef personality = get_mono_personality (ctx);
3851 g_assert (personality);
3853 char *bb_name = g_strdup_printf ("LPAD%d_BB", group_index);
3854 LLVMBasicBlockRef lpad_bb = gen_bb (ctx, bb_name);
3856 LLVMPositionBuilderAtEnd (lpadBuilder, lpad_bb);
3857 LLVMValueRef landing_pad = LLVMBuildLandingPad (lpadBuilder, default_cpp_lpad_exc_signature (), personality, 0, "");
3858 g_assert (landing_pad);
3860 LLVMValueRef cast = LLVMBuildBitCast (lpadBuilder, ctx->module->sentinel_exception, LLVMPointerType (LLVMInt8Type (), 0), "int8TypeInfo");
3861 LLVMAddClause (landing_pad, cast);
3863 LLVMBasicBlockRef resume_bb = gen_bb (ctx, "RESUME_BB");
3864 LLVMBuilderRef resume_builder = create_builder (ctx);
3865 ctx->builder = resume_builder;
3866 LLVMPositionBuilderAtEnd (resume_builder, resume_bb);
3868 emit_resume_eh (ctx, handler_bb);
3871 ctx->builder = lpadBuilder;
3872 LLVMPositionBuilderAtEnd (lpadBuilder, lpad_bb);
3874 gboolean finally_only = TRUE;
3876 MonoExceptionClause *group_cursor = group_start;
3878 for (int i = 0; i < group_size; i ++) {
3879 if (!(group_cursor->flags & MONO_EXCEPTION_CLAUSE_FINALLY))
3880 finally_only = FALSE;
3886 // Handle landing pad inlining
3888 if (!finally_only) {
3889 // So at each level of the exception stack we will match the exception again.
3890 // During that match, we need to compare against the handler types for the current
3891 // protected region. We send the try start and end so that we can only check against
3892 // handlers for this lexical protected region.
3893 LLVMValueRef match = mono_llvm_emit_match_exception_call (ctx, lpadBuilder, group_start->try_offset, group_start->try_offset + group_start->try_len);
3895 // if returns -1, resume
3896 LLVMValueRef switch_ins = LLVMBuildSwitch (lpadBuilder, match, resume_bb, group_size);
3898 // else move to that target bb
3899 for (int i=0; i < group_size; i++) {
3900 MonoExceptionClause *clause = group_start + i;
3901 int clause_index = clause - cfg->header->clauses;
3902 MonoBasicBlock *handler_bb = (MonoBasicBlock*)g_hash_table_lookup (ctx->clause_to_handler, GINT_TO_POINTER (clause_index));
3903 g_assert (handler_bb);
3904 g_assert (ctx->bblocks [handler_bb->block_num].call_handler_target_bb);
3905 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), clause_index, FALSE), ctx->bblocks [handler_bb->block_num].call_handler_target_bb);
3908 int clause_index = group_start - cfg->header->clauses;
3909 MonoBasicBlock *finally_bb = (MonoBasicBlock*)g_hash_table_lookup (ctx->clause_to_handler, GINT_TO_POINTER (clause_index));
3910 g_assert (finally_bb);
3912 LLVMBuildBr (ctx->builder, ctx->bblocks [finally_bb->block_num].call_handler_target_bb);
3915 ctx->builder = old_builder;
3922 emit_llvmonly_handler_start (EmitContext *ctx, MonoBasicBlock *bb, LLVMBasicBlockRef cbb)
3924 int clause_index = MONO_REGION_CLAUSE_INDEX (bb->region);
3925 MonoExceptionClause *clause = &ctx->cfg->header->clauses [clause_index];
3927 // Make exception available to catch blocks
3928 if (!(clause->flags & MONO_EXCEPTION_CLAUSE_FINALLY)) {
3929 LLVMValueRef mono_exc = mono_llvm_emit_load_exception_call (ctx, ctx->builder);
3931 g_assert (ctx->ex_var);
3932 LLVMBuildStore (ctx->builder, LLVMBuildBitCast (ctx->builder, mono_exc, ObjRefType (), ""), ctx->ex_var);
3934 if (bb->in_scount == 1) {
3935 MonoInst *exvar = bb->in_stack [0];
3936 g_assert (!ctx->values [exvar->dreg]);
3937 g_assert (ctx->ex_var);
3938 ctx->values [exvar->dreg] = LLVMBuildLoad (ctx->builder, ctx->ex_var, "save_exception");
3939 emit_volatile_store (ctx, exvar->dreg);
3942 mono_llvm_emit_clear_exception_call (ctx, ctx->builder);
3945 LLVMBuilderRef handler_builder = create_builder (ctx);
3946 LLVMBasicBlockRef target_bb = ctx->bblocks [bb->block_num].call_handler_target_bb;
3947 LLVMPositionBuilderAtEnd (handler_builder, target_bb);
3949 // Make the handler code end with a jump to cbb
3950 LLVMBuildBr (handler_builder, cbb);
3954 emit_handler_start (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef builder)
3956 MonoCompile *cfg = ctx->cfg;
3957 LLVMValueRef *values = ctx->values;
3958 LLVMModuleRef lmodule = ctx->lmodule;
3959 BBInfo *bblocks = ctx->bblocks;
3961 LLVMValueRef personality;
3962 LLVMValueRef landing_pad;
3963 LLVMBasicBlockRef target_bb;
3965 static int ti_generator;
3967 LLVMValueRef type_info;
3971 // <resultval> = landingpad <somety> personality <type> <pers_fn> <clause>+
3973 if (cfg->compile_aot) {
3974 /* Use a dummy personality function */
3975 personality = LLVMGetNamedFunction (lmodule, "mono_personality");
3976 g_assert (personality);
3978 #if LLVM_API_VERSION > 100
3979 personality = ctx->module->personality;
3981 LLVMTypeRef personality_type = LLVMFunctionType (LLVMInt32Type (), NULL, 0, TRUE);
3982 personality = LLVMAddFunction (ctx->lmodule, "mono_personality", personality_type);
3983 LLVMAddFunctionAttr (personality, LLVMNoUnwindAttribute);
3984 LLVMBasicBlockRef entry_bb = LLVMAppendBasicBlock (personality, "ENTRY");
3985 LLVMBuilderRef builder2 = LLVMCreateBuilder ();
3986 LLVMPositionBuilderAtEnd (builder2, entry_bb);
3987 LLVMBuildRet (builder2, LLVMConstInt (LLVMInt32Type (), 0, FALSE));
3988 ctx->module->personality = personality;
3991 static gint32 mapping_inited;
3993 personality = LLVMGetNamedFunction (lmodule, "mono_personality");
3995 if (InterlockedCompareExchange (&mapping_inited, 1, 0) == 0)
3996 LLVMAddGlobalMapping (ctx->module->ee, personality, (gpointer)mono_personality);
4000 i8ptr = LLVMPointerType (LLVMInt8Type (), 0);
4002 clause_index = (mono_get_block_region_notry (cfg, bb->region) >> 8) - 1;
4005 * Create the type info
4007 sprintf (ti_name, "type_info_%d", ti_generator);
4010 if (cfg->compile_aot) {
4011 /* decode_eh_frame () in aot-runtime.c will decode this */
4012 type_info = LLVMAddGlobal (lmodule, LLVMInt32Type (), ti_name);
4013 LLVMSetInitializer (type_info, LLVMConstInt (LLVMInt32Type (), clause_index, FALSE));
4016 * These symbols are not really used, the clause_index is embedded into the EH tables generated by DwarfMonoException in LLVM.
4018 LLVMSetLinkage (type_info, LLVMInternalLinkage);
4020 #if LLVM_API_VERSION > 100
4021 type_info = LLVMAddGlobal (lmodule, LLVMInt32Type (), ti_name);
4022 LLVMSetInitializer (type_info, LLVMConstInt (LLVMInt32Type (), clause_index, FALSE));
4027 * After the cfg mempool is freed, the type info will point to stale memory,
4028 * but this is not a problem, since we decode it once in exception_cb during
4031 ti = (gint32*)mono_mempool_alloc (cfg->mempool, sizeof (gint32));
4032 *(gint32*)ti = clause_index;
4034 type_info = LLVMAddGlobal (lmodule, i8ptr, ti_name);
4036 LLVMAddGlobalMapping (ctx->module->ee, type_info, ti);
4041 LLVMTypeRef members [2], ret_type;
4043 members [0] = i8ptr;
4044 members [1] = LLVMInt32Type ();
4045 ret_type = LLVMStructType (members, 2, FALSE);
4047 landing_pad = LLVMBuildLandingPad (builder, ret_type, personality, 1, "");
4048 LLVMAddClause (landing_pad, type_info);
4050 /* Store the exception into the exvar */
4052 LLVMBuildStore (builder, convert (ctx, LLVMBuildExtractValue (builder, landing_pad, 0, "ex_obj"), ObjRefType ()), ctx->ex_var);
4056 * LLVM throw sites are associated with a one landing pad, and LLVM generated
4057 * code expects control to be transferred to this landing pad even in the
4058 * presence of nested clauses. The landing pad needs to branch to the landing
4059 * pads belonging to nested clauses based on the selector value returned by
4060 * the landing pad instruction, which is passed to the landing pad in a
4061 * register by the EH code.
4063 target_bb = bblocks [bb->block_num].call_handler_target_bb;
4064 g_assert (target_bb);
4067 * Branch to the correct landing pad
4069 LLVMValueRef ex_selector = LLVMBuildExtractValue (builder, landing_pad, 1, "ex_selector");
4070 LLVMValueRef switch_ins = LLVMBuildSwitch (builder, ex_selector, target_bb, 0);
4072 for (l = ctx->nested_in [clause_index]; l; l = l->next) {
4073 int nesting_clause_index = GPOINTER_TO_INT (l->data);
4074 MonoBasicBlock *handler_bb;
4076 handler_bb = (MonoBasicBlock*)g_hash_table_lookup (ctx->clause_to_handler, GINT_TO_POINTER (nesting_clause_index));
4077 g_assert (handler_bb);
4079 g_assert (ctx->bblocks [handler_bb->block_num].call_handler_target_bb);
4080 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), nesting_clause_index, FALSE), ctx->bblocks [handler_bb->block_num].call_handler_target_bb);
4083 /* Start a new bblock which CALL_HANDLER can branch to */
4084 target_bb = bblocks [bb->block_num].call_handler_target_bb;
4086 ctx->builder = builder = create_builder (ctx);
4087 LLVMPositionBuilderAtEnd (ctx->builder, target_bb);
4089 ctx->bblocks [bb->block_num].end_bblock = target_bb;
4091 /* Store the exception into the IL level exvar */
4092 if (bb->in_scount == 1) {
4093 g_assert (bb->in_scount == 1);
4094 exvar = bb->in_stack [0];
4096 // FIXME: This is shared with filter clauses ?
4097 g_assert (!values [exvar->dreg]);
4099 g_assert (ctx->ex_var);
4100 values [exvar->dreg] = LLVMBuildLoad (builder, ctx->ex_var, "");
4101 emit_volatile_store (ctx, exvar->dreg);
4107 process_bb (EmitContext *ctx, MonoBasicBlock *bb)
4109 MonoCompile *cfg = ctx->cfg;
4110 MonoMethodSignature *sig = ctx->sig;
4111 LLVMValueRef method = ctx->lmethod;
4112 LLVMValueRef *values = ctx->values;
4113 LLVMValueRef *addresses = ctx->addresses;
4114 LLVMCallInfo *linfo = ctx->linfo;
4115 BBInfo *bblocks = ctx->bblocks;
4117 LLVMBasicBlockRef cbb;
4118 LLVMBuilderRef builder, starting_builder;
4119 gboolean has_terminator;
4121 LLVMValueRef lhs, rhs;
4124 cbb = get_end_bb (ctx, bb);
4126 builder = create_builder (ctx);
4127 ctx->builder = builder;
4128 LLVMPositionBuilderAtEnd (builder, cbb);
4133 if (bb->flags & BB_EXCEPTION_HANDLER) {
4134 if (!ctx->llvm_only && !bblocks [bb->block_num].invoke_target) {
4135 set_failure (ctx, "handler without invokes");
4140 emit_llvmonly_handler_start (ctx, bb, cbb);
4142 emit_handler_start (ctx, bb, builder);
4145 builder = ctx->builder;
4148 has_terminator = FALSE;
4149 starting_builder = builder;
4150 for (ins = bb->code; ins; ins = ins->next) {
4151 const char *spec = LLVM_INS_INFO (ins->opcode);
4153 char dname_buf [128];
4155 emit_dbg_loc (ctx, builder, ins->cil_code);
4160 * Some steps in llc are non-linear in the size of basic blocks, see #5714.
4161 * Start a new bblock. If the llvm optimization passes merge these, we
4162 * can work around that by doing a volatile load + cond branch from
4163 * localloc-ed memory.
4165 //set_failure (ctx, "basic block too long");
4166 cbb = gen_bb (ctx, "CONT_LONG_BB");
4167 LLVMBuildBr (ctx->builder, cbb);
4168 ctx->builder = builder = create_builder (ctx);
4169 LLVMPositionBuilderAtEnd (builder, cbb);
4170 ctx->bblocks [bb->block_num].end_bblock = cbb;
4175 /* There could be instructions after a terminator, skip them */
4178 if (spec [MONO_INST_DEST] != ' ' && !MONO_IS_STORE_MEMBASE (ins)) {
4179 sprintf (dname_buf, "t%d", ins->dreg);
4183 if (spec [MONO_INST_SRC1] != ' ' && spec [MONO_INST_SRC1] != 'v') {
4184 MonoInst *var = get_vreg_to_inst (cfg, ins->sreg1);
4186 if (var && var->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT) && var->opcode != OP_GSHAREDVT_ARG_REGOFFSET) {
4187 lhs = emit_volatile_load (ctx, ins->sreg1);
4189 /* It is ok for SETRET to have an uninitialized argument */
4190 if (!values [ins->sreg1] && ins->opcode != OP_SETRET) {
4191 set_failure (ctx, "sreg1");
4194 lhs = values [ins->sreg1];
4200 if (spec [MONO_INST_SRC2] != ' ' && spec [MONO_INST_SRC2] != ' ') {
4201 MonoInst *var = get_vreg_to_inst (cfg, ins->sreg2);
4202 if (var && var->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT)) {
4203 rhs = emit_volatile_load (ctx, ins->sreg2);
4205 if (!values [ins->sreg2]) {
4206 set_failure (ctx, "sreg2");
4209 rhs = values [ins->sreg2];
4215 //mono_print_ins (ins);
4216 switch (ins->opcode) {
4219 case OP_LIVERANGE_START:
4220 case OP_LIVERANGE_END:
4223 values [ins->dreg] = LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE);
4226 #if SIZEOF_VOID_P == 4
4227 values [ins->dreg] = LLVMConstInt (LLVMInt64Type (), GET_LONG_IMM (ins), FALSE);
4229 values [ins->dreg] = LLVMConstInt (LLVMInt64Type (), (gint64)ins->inst_c0, FALSE);
4233 values [ins->dreg] = LLVMConstReal (LLVMDoubleType (), *(double*)ins->inst_p0);
4237 values [ins->dreg] = LLVMConstReal (LLVMFloatType (), *(float*)ins->inst_p0);
4239 values [ins->dreg] = LLVMConstFPExt (LLVMConstReal (LLVMFloatType (), *(float*)ins->inst_p0), LLVMDoubleType ());
4241 case OP_DUMMY_ICONST:
4242 values [ins->dreg] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
4244 case OP_DUMMY_I8CONST:
4245 values [ins->dreg] = LLVMConstInt (LLVMInt64Type (), 0, FALSE);
4247 case OP_DUMMY_R8CONST:
4248 values [ins->dreg] = LLVMConstReal (LLVMDoubleType (), 0.0f);
4251 LLVMBasicBlockRef target_bb = get_bb (ctx, ins->inst_target_bb);
4252 LLVMBuildBr (builder, target_bb);
4253 has_terminator = TRUE;
4260 LLVMBasicBlockRef new_bb;
4261 LLVMBuilderRef new_builder;
4263 // The default branch is already handled
4264 // FIXME: Handle it here
4266 /* Start new bblock */
4267 sprintf (bb_name, "SWITCH_DEFAULT_BB%d", ctx->default_index ++);
4268 new_bb = LLVMAppendBasicBlock (ctx->lmethod, bb_name);
4270 lhs = convert (ctx, lhs, LLVMInt32Type ());
4271 v = LLVMBuildSwitch (builder, lhs, new_bb, GPOINTER_TO_UINT (ins->klass));
4272 for (i = 0; i < GPOINTER_TO_UINT (ins->klass); ++i) {
4273 MonoBasicBlock *target_bb = ins->inst_many_bb [i];
4275 LLVMAddCase (v, LLVMConstInt (LLVMInt32Type (), i, FALSE), get_bb (ctx, target_bb));
4278 new_builder = create_builder (ctx);
4279 LLVMPositionBuilderAtEnd (new_builder, new_bb);
4280 LLVMBuildUnreachable (new_builder);
4282 has_terminator = TRUE;
4283 g_assert (!ins->next);
4289 switch (linfo->ret.storage) {
4290 case LLVMArgVtypeInReg: {
4291 LLVMTypeRef ret_type = LLVMGetReturnType (LLVMGetElementType (LLVMTypeOf (method)));
4292 LLVMValueRef val, addr, retval;
4295 retval = LLVMGetUndef (ret_type);
4297 if (!addresses [ins->sreg1]) {
4299 * The return type is an LLVM vector type, have to convert between it and the
4300 * real return type which is a struct type.
4302 g_assert (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (sig->ret)));
4303 /* Convert to 2xi64 first */
4304 val = LLVMBuildBitCast (builder, values [ins->sreg1], LLVMVectorType (IntPtrType (), 2), "");
4306 for (i = 0; i < 2; ++i) {
4307 if (linfo->ret.pair_storage [i] == LLVMArgInIReg) {
4308 retval = LLVMBuildInsertValue (builder, retval, LLVMBuildExtractElement (builder, val, LLVMConstInt (LLVMInt32Type (), i, FALSE), ""), i, "");
4310 g_assert (linfo->ret.pair_storage [i] == LLVMArgNone);
4314 addr = LLVMBuildBitCast (builder, addresses [ins->sreg1], LLVMPointerType (ret_type, 0), "");
4315 for (i = 0; i < 2; ++i) {
4316 if (linfo->ret.pair_storage [i] == LLVMArgInIReg) {
4317 LLVMValueRef indexes [2], part_addr;
4319 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
4320 indexes [1] = LLVMConstInt (LLVMInt32Type (), i, FALSE);
4321 part_addr = LLVMBuildGEP (builder, addr, indexes, 2, "");
4323 retval = LLVMBuildInsertValue (builder, retval, LLVMBuildLoad (builder, part_addr, ""), i, "");
4325 g_assert (linfo->ret.pair_storage [i] == LLVMArgNone);
4329 LLVMBuildRet (builder, retval);
4332 case LLVMArgVtypeAsScalar: {
4333 LLVMTypeRef ret_type = LLVMGetReturnType (LLVMGetElementType (LLVMTypeOf (method)));
4334 LLVMValueRef retval;
4336 g_assert (addresses [ins->sreg1]);
4338 retval = LLVMBuildLoad (builder, LLVMBuildBitCast (builder, addresses [ins->sreg1], LLVMPointerType (ret_type, 0), ""), "");
4339 LLVMBuildRet (builder, retval);
4342 case LLVMArgVtypeByVal: {
4343 LLVMValueRef retval;
4345 g_assert (addresses [ins->sreg1]);
4346 retval = LLVMBuildLoad (builder, addresses [ins->sreg1], "");
4347 LLVMBuildRet (builder, retval);
4350 case LLVMArgVtypeByRef: {
4351 LLVMBuildRetVoid (builder);
4354 case LLVMArgGsharedvtFixed: {
4355 LLVMTypeRef ret_type = type_to_llvm_type (ctx, sig->ret);
4356 /* The return value is in lhs, need to store to the vret argument */
4357 /* sreg1 might not be set */
4359 g_assert (cfg->vret_addr);
4360 g_assert (values [cfg->vret_addr->dreg]);
4361 LLVMBuildStore (builder, convert (ctx, lhs, ret_type), convert (ctx, values [cfg->vret_addr->dreg], LLVMPointerType (ret_type, 0)));
4363 LLVMBuildRetVoid (builder);
4366 case LLVMArgGsharedvtFixedVtype: {
4368 LLVMBuildRetVoid (builder);
4371 case LLVMArgGsharedvtVariable: {
4373 LLVMBuildRetVoid (builder);
4376 case LLVMArgVtypeRetAddr: {
4377 LLVMBuildRetVoid (builder);
4380 case LLVMArgAsIArgs:
4381 case LLVMArgFpStruct: {
4382 LLVMTypeRef ret_type = LLVMGetReturnType (LLVMGetElementType (LLVMTypeOf (method)));
4383 LLVMValueRef retval;
4385 g_assert (addresses [ins->sreg1]);
4386 retval = LLVMBuildLoad (builder, convert (ctx, addresses [ins->sreg1], LLVMPointerType (ret_type, 0)), "");
4387 LLVMBuildRet (builder, retval);
4391 case LLVMArgNormal: {
4392 if (!lhs || ctx->is_dead [ins->sreg1]) {
4394 * The method did not set its return value, probably because it
4395 * ends with a throw.
4398 LLVMBuildRetVoid (builder);
4400 LLVMBuildRet (builder, LLVMConstNull (type_to_llvm_type (ctx, sig->ret)));
4402 LLVMBuildRet (builder, convert (ctx, lhs, type_to_llvm_type (ctx, sig->ret)));
4404 has_terminator = TRUE;
4408 g_assert_not_reached ();
4417 case OP_ICOMPARE_IMM:
4418 case OP_LCOMPARE_IMM:
4419 case OP_COMPARE_IMM: {
4421 LLVMValueRef cmp, args [16];
4422 gboolean likely = (ins->flags & MONO_INST_LIKELY) != 0;
4424 if (ins->next->opcode == OP_NOP)
4427 if (ins->next->opcode == OP_BR)
4428 /* The comparison result is not needed */
4431 rel = mono_opcode_to_cond (ins->next->opcode);
4433 if (ins->opcode == OP_ICOMPARE_IMM) {
4434 lhs = convert (ctx, lhs, LLVMInt32Type ());
4435 rhs = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
4437 if (ins->opcode == OP_LCOMPARE_IMM) {
4438 lhs = convert (ctx, lhs, LLVMInt64Type ());
4439 rhs = LLVMConstInt (LLVMInt64Type (), GET_LONG_IMM (ins), FALSE);
4441 if (ins->opcode == OP_LCOMPARE) {
4442 lhs = convert (ctx, lhs, LLVMInt64Type ());
4443 rhs = convert (ctx, rhs, LLVMInt64Type ());
4445 if (ins->opcode == OP_ICOMPARE) {
4446 lhs = convert (ctx, lhs, LLVMInt32Type ());
4447 rhs = convert (ctx, rhs, LLVMInt32Type ());
4451 if (LLVMGetTypeKind (LLVMTypeOf (lhs)) == LLVMPointerTypeKind)
4452 rhs = convert (ctx, rhs, LLVMTypeOf (lhs));
4453 else if (LLVMGetTypeKind (LLVMTypeOf (rhs)) == LLVMPointerTypeKind)
4454 lhs = convert (ctx, lhs, LLVMTypeOf (rhs));
4457 /* We use COMPARE+SETcc/Bcc, llvm uses SETcc+br cond */
4458 if (ins->opcode == OP_FCOMPARE) {
4459 cmp = LLVMBuildFCmp (builder, fpcond_to_llvm_cond [rel], convert (ctx, lhs, LLVMDoubleType ()), convert (ctx, rhs, LLVMDoubleType ()), "");
4460 } else if (ins->opcode == OP_RCOMPARE) {
4461 cmp = LLVMBuildFCmp (builder, fpcond_to_llvm_cond [rel], convert (ctx, lhs, LLVMFloatType ()), convert (ctx, rhs, LLVMFloatType ()), "");
4462 } else if (ins->opcode == OP_COMPARE_IMM) {
4463 if (LLVMGetTypeKind (LLVMTypeOf (lhs)) == LLVMPointerTypeKind && ins->inst_imm == 0)
4464 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], lhs, LLVMConstNull (LLVMTypeOf (lhs)), "");
4466 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE), "");
4467 } else if (ins->opcode == OP_LCOMPARE_IMM) {
4468 if (SIZEOF_REGISTER == 4 && COMPILE_LLVM (cfg)) {
4469 /* The immediate is encoded in two fields */
4470 guint64 l = ((guint64)(guint32)ins->inst_offset << 32) | ((guint32)ins->inst_imm);
4471 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, LLVMInt64Type ()), LLVMConstInt (LLVMInt64Type (), l, FALSE), "");
4473 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, LLVMInt64Type ()), LLVMConstInt (LLVMInt64Type (), ins->inst_imm, FALSE), "");
4476 else if (ins->opcode == OP_COMPARE) {
4477 if (LLVMGetTypeKind (LLVMTypeOf (lhs)) == LLVMPointerTypeKind && LLVMTypeOf (lhs) == LLVMTypeOf (rhs))
4478 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], lhs, rhs, "");
4480 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, IntPtrType ()), convert (ctx, rhs, IntPtrType ()), "");
4482 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], lhs, rhs, "");
4486 args [1] = LLVMConstInt (LLVMInt1Type (), 1, FALSE);
4487 cmp = LLVMBuildCall (ctx->builder, get_intrinsic (ctx, "llvm.expect.i1"), args, 2, "");
4490 if (MONO_IS_COND_BRANCH_OP (ins->next)) {
4491 if (ins->next->inst_true_bb == ins->next->inst_false_bb) {
4493 * If the target bb contains PHI instructions, LLVM requires
4494 * two PHI entries for this bblock, while we only generate one.
4495 * So convert this to an unconditional bblock. (bxc #171).
4497 LLVMBuildBr (builder, get_bb (ctx, ins->next->inst_true_bb));
4499 LLVMBuildCondBr (builder, cmp, get_bb (ctx, ins->next->inst_true_bb), get_bb (ctx, ins->next->inst_false_bb));
4501 has_terminator = TRUE;
4502 } else if (MONO_IS_SETCC (ins->next)) {
4503 sprintf (dname_buf, "t%d", ins->next->dreg);
4505 values [ins->next->dreg] = LLVMBuildZExt (builder, cmp, LLVMInt32Type (), dname);
4507 /* Add stores for volatile variables */
4508 emit_volatile_store (ctx, ins->next->dreg);
4509 } else if (MONO_IS_COND_EXC (ins->next)) {
4510 emit_cond_system_exception (ctx, bb, (const char*)ins->next->inst_p1, cmp);
4513 builder = ctx->builder;
4515 set_failure (ctx, "next");
4533 rel = mono_opcode_to_cond (ins->opcode);
4535 cmp = LLVMBuildFCmp (builder, fpcond_to_llvm_cond [rel], convert (ctx, lhs, LLVMDoubleType ()), convert (ctx, rhs, LLVMDoubleType ()), "");
4536 values [ins->dreg] = LLVMBuildZExt (builder, cmp, LLVMInt32Type (), dname);
4547 rel = mono_opcode_to_cond (ins->opcode);
4549 cmp = LLVMBuildFCmp (builder, fpcond_to_llvm_cond [rel], convert (ctx, lhs, LLVMFloatType ()), convert (ctx, rhs, LLVMFloatType ()), "");
4550 values [ins->dreg] = LLVMBuildZExt (builder, cmp, LLVMInt32Type (), dname);
4558 gboolean empty = TRUE;
4560 /* Check that all input bblocks really branch to us */
4561 for (i = 0; i < bb->in_count; ++i) {
4562 if (bb->in_bb [i]->last_ins && bb->in_bb [i]->last_ins->opcode == OP_NOT_REACHED)
4563 ins->inst_phi_args [i + 1] = -1;
4569 /* LLVM doesn't like phi instructions with zero operands */
4570 ctx->is_dead [ins->dreg] = TRUE;
4574 /* Created earlier, insert it now */
4575 LLVMInsertIntoBuilder (builder, values [ins->dreg]);
4577 for (i = 0; i < ins->inst_phi_args [0]; i++) {
4578 int sreg1 = ins->inst_phi_args [i + 1];
4582 * Count the number of times the incoming bblock branches to us,
4583 * since llvm requires a separate entry for each.
4585 if (bb->in_bb [i]->last_ins && bb->in_bb [i]->last_ins->opcode == OP_SWITCH) {
4586 MonoInst *switch_ins = bb->in_bb [i]->last_ins;
4589 for (j = 0; j < GPOINTER_TO_UINT (switch_ins->klass); ++j) {
4590 if (switch_ins->inst_many_bb [j] == bb)
4597 /* Remember for later */
4598 for (j = 0; j < count; ++j) {
4599 PhiNode *node = (PhiNode*)mono_mempool_alloc0 (ctx->mempool, sizeof (PhiNode));
4602 node->in_bb = bb->in_bb [i];
4604 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);
4614 values [ins->dreg] = lhs;
4618 MonoInst *var = get_vreg_to_inst (cfg, ins->dreg);
4621 values [ins->dreg] = lhs;
4623 if (var && var->klass->byval_arg.type == MONO_TYPE_R4) {
4625 * This is added by the spilling pass in case of the JIT,
4626 * but we have to do it ourselves.
4628 values [ins->dreg] = convert (ctx, values [ins->dreg], LLVMFloatType ());
4632 case OP_MOVE_F_TO_I4: {
4633 values [ins->dreg] = LLVMBuildBitCast (builder, LLVMBuildFPTrunc (builder, lhs, LLVMFloatType (), ""), LLVMInt32Type (), "");
4636 case OP_MOVE_I4_TO_F: {
4637 values [ins->dreg] = LLVMBuildFPExt (builder, LLVMBuildBitCast (builder, lhs, LLVMFloatType (), ""), LLVMDoubleType (), "");
4640 case OP_MOVE_F_TO_I8: {
4641 values [ins->dreg] = LLVMBuildBitCast (builder, lhs, LLVMInt64Type (), "");
4644 case OP_MOVE_I8_TO_F: {
4645 values [ins->dreg] = LLVMBuildBitCast (builder, lhs, LLVMDoubleType (), "");
4678 lhs = convert (ctx, lhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
4679 rhs = convert (ctx, rhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
4681 emit_div_check (ctx, builder, bb, ins, lhs, rhs);
4684 builder = ctx->builder;
4686 switch (ins->opcode) {
4689 values [ins->dreg] = LLVMBuildAdd (builder, lhs, rhs, dname);
4693 values [ins->dreg] = LLVMBuildSub (builder, lhs, rhs, dname);
4697 values [ins->dreg] = LLVMBuildMul (builder, lhs, rhs, dname);
4701 values [ins->dreg] = LLVMBuildSRem (builder, lhs, rhs, dname);
4705 values [ins->dreg] = LLVMBuildURem (builder, lhs, rhs, dname);
4709 values [ins->dreg] = LLVMBuildSDiv (builder, lhs, rhs, dname);
4713 values [ins->dreg] = LLVMBuildUDiv (builder, lhs, rhs, dname);
4717 values [ins->dreg] = LLVMBuildFDiv (builder, lhs, rhs, dname);
4721 values [ins->dreg] = LLVMBuildAnd (builder, lhs, rhs, dname);
4725 values [ins->dreg] = LLVMBuildOr (builder, lhs, rhs, dname);
4729 values [ins->dreg] = LLVMBuildXor (builder, lhs, rhs, dname);
4733 values [ins->dreg] = LLVMBuildShl (builder, lhs, rhs, dname);
4737 values [ins->dreg] = LLVMBuildAShr (builder, lhs, rhs, dname);
4741 values [ins->dreg] = LLVMBuildLShr (builder, lhs, rhs, dname);
4745 values [ins->dreg] = LLVMBuildFAdd (builder, lhs, rhs, dname);
4748 values [ins->dreg] = LLVMBuildFSub (builder, lhs, rhs, dname);
4751 values [ins->dreg] = LLVMBuildFMul (builder, lhs, rhs, dname);
4755 g_assert_not_reached ();
4762 lhs = convert (ctx, lhs, LLVMFloatType ());
4763 rhs = convert (ctx, rhs, LLVMFloatType ());
4764 switch (ins->opcode) {
4766 values [ins->dreg] = LLVMBuildFAdd (builder, lhs, rhs, dname);
4769 values [ins->dreg] = LLVMBuildFSub (builder, lhs, rhs, dname);
4772 values [ins->dreg] = LLVMBuildFMul (builder, lhs, rhs, dname);
4775 values [ins->dreg] = LLVMBuildFDiv (builder, lhs, rhs, dname);
4778 g_assert_not_reached ();
4787 case OP_IREM_UN_IMM:
4789 case OP_IDIV_UN_IMM:
4795 case OP_ISHR_UN_IMM:
4805 case OP_LSHR_UN_IMM:
4811 case OP_SHR_UN_IMM: {
4814 if (spec [MONO_INST_SRC1] == 'l') {
4815 imm = LLVMConstInt (LLVMInt64Type (), GET_LONG_IMM (ins), FALSE);
4817 imm = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
4820 emit_div_check (ctx, builder, bb, ins, lhs, imm);
4823 builder = ctx->builder;
4825 #if SIZEOF_VOID_P == 4
4826 if (ins->opcode == OP_LSHL_IMM || ins->opcode == OP_LSHR_IMM || ins->opcode == OP_LSHR_UN_IMM)
4827 imm = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
4830 if (LLVMGetTypeKind (LLVMTypeOf (lhs)) == LLVMPointerTypeKind)
4831 lhs = convert (ctx, lhs, IntPtrType ());
4832 imm = convert (ctx, imm, LLVMTypeOf (lhs));
4833 switch (ins->opcode) {
4837 values [ins->dreg] = LLVMBuildAdd (builder, lhs, imm, dname);
4841 values [ins->dreg] = LLVMBuildSub (builder, lhs, imm, dname);
4846 values [ins->dreg] = LLVMBuildMul (builder, lhs, imm, dname);
4850 values [ins->dreg] = LLVMBuildSDiv (builder, lhs, imm, dname);
4852 case OP_IDIV_UN_IMM:
4853 case OP_LDIV_UN_IMM:
4854 values [ins->dreg] = LLVMBuildUDiv (builder, lhs, imm, dname);
4858 values [ins->dreg] = LLVMBuildSRem (builder, lhs, imm, dname);
4860 case OP_IREM_UN_IMM:
4861 values [ins->dreg] = LLVMBuildURem (builder, lhs, imm, dname);
4866 values [ins->dreg] = LLVMBuildAnd (builder, lhs, imm, dname);
4870 values [ins->dreg] = LLVMBuildOr (builder, lhs, imm, dname);
4874 values [ins->dreg] = LLVMBuildXor (builder, lhs, imm, dname);
4879 values [ins->dreg] = LLVMBuildShl (builder, lhs, imm, dname);
4884 values [ins->dreg] = LLVMBuildAShr (builder, lhs, imm, dname);
4886 case OP_ISHR_UN_IMM:
4887 /* This is used to implement conv.u4, so the lhs could be an i8 */
4888 lhs = convert (ctx, lhs, LLVMInt32Type ());
4889 imm = convert (ctx, imm, LLVMInt32Type ());
4890 values [ins->dreg] = LLVMBuildLShr (builder, lhs, imm, dname);
4892 case OP_LSHR_UN_IMM:
4894 values [ins->dreg] = LLVMBuildLShr (builder, lhs, imm, dname);
4897 g_assert_not_reached ();
4902 values [ins->dreg] = LLVMBuildSub (builder, LLVMConstInt (LLVMInt32Type (), 0, FALSE), convert (ctx, lhs, LLVMInt32Type ()), dname);
4905 values [ins->dreg] = LLVMBuildSub (builder, LLVMConstInt (LLVMInt64Type (), 0, FALSE), lhs, dname);
4908 lhs = convert (ctx, lhs, LLVMDoubleType ());
4909 values [ins->dreg] = LLVMBuildFSub (builder, LLVMConstReal (LLVMDoubleType (), 0.0), lhs, dname);
4912 lhs = convert (ctx, lhs, LLVMFloatType ());
4913 values [ins->dreg] = LLVMBuildFSub (builder, LLVMConstReal (LLVMFloatType (), 0.0), lhs, dname);
4916 guint32 v = 0xffffffff;
4917 values [ins->dreg] = LLVMBuildXor (builder, LLVMConstInt (LLVMInt32Type (), v, FALSE), convert (ctx, lhs, LLVMInt32Type ()), dname);
4921 guint64 v = 0xffffffffffffffffLL;
4922 values [ins->dreg] = LLVMBuildXor (builder, LLVMConstInt (LLVMInt64Type (), v, FALSE), lhs, dname);
4925 #if defined(TARGET_X86) || defined(TARGET_AMD64)
4927 LLVMValueRef v1, v2;
4929 v1 = LLVMBuildMul (builder, convert (ctx, rhs, IntPtrType ()), LLVMConstInt (IntPtrType (), (1 << ins->backend.shift_amount), FALSE), "");
4930 v2 = LLVMBuildAdd (builder, convert (ctx, lhs, IntPtrType ()), v1, "");
4931 values [ins->dreg] = LLVMBuildAdd (builder, v2, LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE), dname);
4936 case OP_ICONV_TO_I1:
4937 case OP_ICONV_TO_I2:
4938 case OP_ICONV_TO_I4:
4939 case OP_ICONV_TO_U1:
4940 case OP_ICONV_TO_U2:
4941 case OP_ICONV_TO_U4:
4942 case OP_LCONV_TO_I1:
4943 case OP_LCONV_TO_I2:
4944 case OP_LCONV_TO_U1:
4945 case OP_LCONV_TO_U2:
4946 case OP_LCONV_TO_U4: {
4949 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);
4951 /* Have to do two casts since our vregs have type int */
4952 v = LLVMBuildTrunc (builder, lhs, op_to_llvm_type (ins->opcode), "");
4954 values [ins->dreg] = LLVMBuildSExt (builder, v, LLVMInt32Type (), dname);
4956 values [ins->dreg] = LLVMBuildZExt (builder, v, LLVMInt32Type (), dname);
4959 case OP_ICONV_TO_I8:
4960 values [ins->dreg] = LLVMBuildSExt (builder, lhs, LLVMInt64Type (), dname);
4962 case OP_ICONV_TO_U8:
4963 values [ins->dreg] = LLVMBuildZExt (builder, lhs, LLVMInt64Type (), dname);
4965 case OP_FCONV_TO_I4:
4966 case OP_RCONV_TO_I4:
4967 values [ins->dreg] = LLVMBuildFPToSI (builder, lhs, LLVMInt32Type (), dname);
4969 case OP_FCONV_TO_I1:
4970 case OP_RCONV_TO_I1:
4971 values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildFPToSI (builder, lhs, LLVMInt8Type (), dname), LLVMInt32Type (), "");
4973 case OP_FCONV_TO_U1:
4974 case OP_RCONV_TO_U1:
4975 values [ins->dreg] = LLVMBuildZExt (builder, LLVMBuildTrunc (builder, LLVMBuildFPToUI (builder, lhs, IntPtrType (), dname), LLVMInt8Type (), ""), LLVMInt32Type (), "");
4977 case OP_FCONV_TO_I2:
4978 case OP_RCONV_TO_I2:
4979 values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildFPToSI (builder, lhs, LLVMInt16Type (), dname), LLVMInt32Type (), "");
4981 case OP_FCONV_TO_U2:
4982 case OP_RCONV_TO_U2:
4983 values [ins->dreg] = LLVMBuildZExt (builder, LLVMBuildFPToUI (builder, lhs, LLVMInt16Type (), dname), LLVMInt32Type (), "");
4985 case OP_RCONV_TO_U4:
4986 values [ins->dreg] = LLVMBuildFPToUI (builder, lhs, LLVMInt32Type (), dname);
4988 case OP_FCONV_TO_I8:
4989 case OP_RCONV_TO_I8:
4990 values [ins->dreg] = LLVMBuildFPToSI (builder, lhs, LLVMInt64Type (), dname);
4993 values [ins->dreg] = LLVMBuildFPToSI (builder, lhs, IntPtrType (), dname);
4995 case OP_ICONV_TO_R8:
4996 case OP_LCONV_TO_R8:
4997 values [ins->dreg] = LLVMBuildSIToFP (builder, lhs, LLVMDoubleType (), dname);
4999 case OP_ICONV_TO_R_UN:
5000 case OP_LCONV_TO_R_UN:
5001 values [ins->dreg] = LLVMBuildUIToFP (builder, lhs, LLVMDoubleType (), dname);
5003 #if SIZEOF_VOID_P == 4
5006 case OP_LCONV_TO_I4:
5007 values [ins->dreg] = LLVMBuildTrunc (builder, lhs, LLVMInt32Type (), dname);
5009 case OP_ICONV_TO_R4:
5010 case OP_LCONV_TO_R4:
5011 v = LLVMBuildSIToFP (builder, lhs, LLVMFloatType (), "");
5013 values [ins->dreg] = v;
5015 values [ins->dreg] = LLVMBuildFPExt (builder, v, LLVMDoubleType (), dname);
5017 case OP_FCONV_TO_R4:
5018 v = LLVMBuildFPTrunc (builder, lhs, LLVMFloatType (), "");
5020 values [ins->dreg] = v;
5022 values [ins->dreg] = LLVMBuildFPExt (builder, v, LLVMDoubleType (), dname);
5024 case OP_RCONV_TO_R8:
5025 values [ins->dreg] = LLVMBuildFPExt (builder, lhs, LLVMDoubleType (), dname);
5027 case OP_RCONV_TO_R4:
5028 values [ins->dreg] = lhs;
5031 values [ins->dreg] = LLVMBuildSExt (builder, convert (ctx, lhs, LLVMInt32Type ()), LLVMInt64Type (), dname);
5034 values [ins->dreg] = LLVMBuildZExt (builder, convert (ctx, lhs, LLVMInt32Type ()), LLVMInt64Type (), dname);
5037 values [ins->dreg] = LLVMBuildTrunc (builder, lhs, LLVMInt32Type (), dname);
5039 case OP_LOCALLOC_IMM: {
5042 guint32 size = ins->inst_imm;
5043 size = (size + (MONO_ARCH_FRAME_ALIGNMENT - 1)) & ~ (MONO_ARCH_FRAME_ALIGNMENT - 1);
5045 v = mono_llvm_build_alloca (builder, LLVMInt8Type (), LLVMConstInt (LLVMInt32Type (), size, FALSE), MONO_ARCH_FRAME_ALIGNMENT, "");
5047 if (ins->flags & MONO_INST_INIT) {
5048 LLVMValueRef args [5];
5051 args [1] = LLVMConstInt (LLVMInt8Type (), 0, FALSE);
5052 args [2] = LLVMConstInt (LLVMInt32Type (), size, FALSE);
5053 args [3] = LLVMConstInt (LLVMInt32Type (), MONO_ARCH_FRAME_ALIGNMENT, FALSE);
5054 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
5055 LLVMBuildCall (builder, get_intrinsic (ctx, "llvm.memset.p0i8.i32"), args, 5, "");
5058 values [ins->dreg] = v;
5062 LLVMValueRef v, size;
5064 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), "");
5066 v = mono_llvm_build_alloca (builder, LLVMInt8Type (), size, MONO_ARCH_FRAME_ALIGNMENT, "");
5068 if (ins->flags & MONO_INST_INIT) {
5069 LLVMValueRef args [5];
5072 args [1] = LLVMConstInt (LLVMInt8Type (), 0, FALSE);
5074 args [3] = LLVMConstInt (LLVMInt32Type (), MONO_ARCH_FRAME_ALIGNMENT, FALSE);
5075 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
5076 LLVMBuildCall (builder, get_intrinsic (ctx, "llvm.memset.p0i8.i32"), args, 5, "");
5078 values [ins->dreg] = v;
5082 case OP_LOADI1_MEMBASE:
5083 case OP_LOADU1_MEMBASE:
5084 case OP_LOADI2_MEMBASE:
5085 case OP_LOADU2_MEMBASE:
5086 case OP_LOADI4_MEMBASE:
5087 case OP_LOADU4_MEMBASE:
5088 case OP_LOADI8_MEMBASE:
5089 case OP_LOADR4_MEMBASE:
5090 case OP_LOADR8_MEMBASE:
5091 case OP_LOAD_MEMBASE:
5099 LLVMValueRef base, index, addr;
5101 gboolean sext = FALSE, zext = FALSE;
5102 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
5104 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
5109 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)) {
5110 addr = LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE);
5116 if (ins->inst_offset == 0) {
5118 } else if (ins->inst_offset % size != 0) {
5119 /* Unaligned load */
5120 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset, FALSE);
5121 addr = LLVMBuildGEP (builder, convert (ctx, base, LLVMPointerType (LLVMInt8Type (), 0)), &index, 1, "");
5123 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
5124 addr = LLVMBuildGEP (builder, convert (ctx, base, LLVMPointerType (t, 0)), &index, 1, "");
5128 addr = convert (ctx, addr, LLVMPointerType (t, 0));
5130 values [ins->dreg] = emit_load_general (ctx, bb, &builder, size, addr, base, dname, is_volatile, LLVM_BARRIER_NONE);
5132 if (!is_volatile && (ins->flags & MONO_INST_INVARIANT_LOAD)) {
5134 * These will signal LLVM that these loads do not alias any stores, and
5135 * they can't fail, allowing them to be hoisted out of loops.
5137 set_invariant_load_flag (values [ins->dreg]);
5138 #if LLVM_API_VERSION < 100
5139 set_metadata_flag (values [ins->dreg], "mono.nofail.load");
5144 values [ins->dreg] = LLVMBuildSExt (builder, values [ins->dreg], LLVMInt32Type (), dname);
5146 values [ins->dreg] = LLVMBuildZExt (builder, values [ins->dreg], LLVMInt32Type (), dname);
5147 else if (!cfg->r4fp && ins->opcode == OP_LOADR4_MEMBASE)
5148 values [ins->dreg] = LLVMBuildFPExt (builder, values [ins->dreg], LLVMDoubleType (), dname);
5152 case OP_STOREI1_MEMBASE_REG:
5153 case OP_STOREI2_MEMBASE_REG:
5154 case OP_STOREI4_MEMBASE_REG:
5155 case OP_STOREI8_MEMBASE_REG:
5156 case OP_STORER4_MEMBASE_REG:
5157 case OP_STORER8_MEMBASE_REG:
5158 case OP_STORE_MEMBASE_REG: {
5160 LLVMValueRef index, addr, base;
5162 gboolean sext = FALSE, zext = FALSE;
5163 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
5165 if (!values [ins->inst_destbasereg]) {
5166 set_failure (ctx, "inst_destbasereg");
5170 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
5172 base = values [ins->inst_destbasereg];
5173 if (ins->inst_offset % size != 0) {
5174 /* Unaligned store */
5175 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset, FALSE);
5176 addr = LLVMBuildGEP (builder, convert (ctx, base, LLVMPointerType (LLVMInt8Type (), 0)), &index, 1, "");
5178 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
5179 addr = LLVMBuildGEP (builder, convert (ctx, base, LLVMPointerType (t, 0)), &index, 1, "");
5181 emit_store (ctx, bb, &builder, size, convert (ctx, values [ins->sreg1], t), convert (ctx, addr, LLVMPointerType (t, 0)), base, is_volatile);
5185 case OP_STOREI1_MEMBASE_IMM:
5186 case OP_STOREI2_MEMBASE_IMM:
5187 case OP_STOREI4_MEMBASE_IMM:
5188 case OP_STOREI8_MEMBASE_IMM:
5189 case OP_STORE_MEMBASE_IMM: {
5191 LLVMValueRef index, addr, base;
5193 gboolean sext = FALSE, zext = FALSE;
5194 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
5196 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
5198 base = values [ins->inst_destbasereg];
5199 if (ins->inst_offset % size != 0) {
5200 /* Unaligned store */
5201 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset, FALSE);
5202 addr = LLVMBuildGEP (builder, convert (ctx, base, LLVMPointerType (LLVMInt8Type (), 0)), &index, 1, "");
5204 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
5205 addr = LLVMBuildGEP (builder, convert (ctx, base, LLVMPointerType (t, 0)), &index, 1, "");
5207 emit_store (ctx, bb, &builder, size, convert (ctx, LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE), t), convert (ctx, addr, LLVMPointerType (t, 0)), base, is_volatile);
5212 emit_load_general (ctx, bb, &builder, sizeof (gpointer), convert (ctx, lhs, LLVMPointerType (IntPtrType (), 0)), lhs, "", TRUE, LLVM_BARRIER_NONE);
5214 case OP_OUTARG_VTRETADDR:
5222 case OP_VOIDCALL_MEMBASE:
5223 case OP_CALL_MEMBASE:
5224 case OP_LCALL_MEMBASE:
5225 case OP_FCALL_MEMBASE:
5226 case OP_RCALL_MEMBASE:
5227 case OP_VCALL_MEMBASE:
5228 case OP_VOIDCALL_REG:
5233 case OP_VCALL_REG: {
5234 process_call (ctx, bb, &builder, ins);
5239 LLVMValueRef indexes [2];
5240 MonoJumpInfo *tmp_ji, *ji;
5241 LLVMValueRef got_entry_addr;
5245 * FIXME: Can't allocate from the cfg mempool since that is freed if
5246 * the LLVM compile fails.
5248 tmp_ji = g_new0 (MonoJumpInfo, 1);
5249 tmp_ji->type = (MonoJumpInfoType)ins->inst_c1;
5250 tmp_ji->data.target = ins->inst_p0;
5252 ji = mono_aot_patch_info_dup (tmp_ji);
5255 if (ji->type == MONO_PATCH_INFO_ICALL_ADDR) {
5256 char *symbol = mono_aot_get_direct_call_symbol (MONO_PATCH_INFO_ICALL_ADDR_CALL, ji->data.target);
5259 * Avoid emitting a got entry for these since the method is directly called, and it might not be
5260 * resolvable at runtime using dlsym ().
5263 values [ins->dreg] = LLVMConstInt (IntPtrType (), 0, FALSE);
5268 ji->next = cfg->patch_info;
5269 cfg->patch_info = ji;
5271 //mono_add_patch_info (cfg, 0, (MonoJumpInfoType)ins->inst_i1, ins->inst_p0);
5272 got_offset = mono_aot_get_got_offset (cfg->patch_info);
5273 ctx->module->max_got_offset = MAX (ctx->module->max_got_offset, got_offset);
5274 if (!mono_aot_is_shared_got_offset (got_offset)) {
5275 //mono_print_ji (ji);
5277 ctx->has_got_access = TRUE;
5280 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
5281 indexes [1] = LLVMConstInt (LLVMInt32Type (), (gssize)got_offset, FALSE);
5282 got_entry_addr = LLVMBuildGEP (builder, ctx->module->got_var, indexes, 2, "");
5284 name = get_aotconst_name (ji->type, ji->data.target, got_offset);
5285 values [ins->dreg] = LLVMBuildLoad (builder, got_entry_addr, name);
5287 /* Can't use this in llvmonly mode since the got slots are initialized by the methods themselves */
5288 if (!cfg->llvm_only)
5289 set_invariant_load_flag (values [ins->dreg]);
5292 case OP_NOT_REACHED:
5293 LLVMBuildUnreachable (builder);
5294 has_terminator = TRUE;
5295 g_assert (bb->block_num < cfg->max_block_num);
5296 ctx->unreachable [bb->block_num] = TRUE;
5297 /* Might have instructions after this */
5299 MonoInst *next = ins->next;
5301 * FIXME: If later code uses the regs defined by these instructions,
5302 * compilation will fail.
5304 MONO_DELETE_INS (bb, next);
5308 MonoInst *var = ins->inst_i0;
5310 if (var->opcode == OP_VTARG_ADDR) {
5311 /* The variable contains the vtype address */
5312 values [ins->dreg] = values [var->dreg];
5313 } else if (var->opcode == OP_GSHAREDVT_LOCAL) {
5314 values [ins->dreg] = emit_gsharedvt_ldaddr (ctx, var->dreg);
5316 values [ins->dreg] = addresses [var->dreg];
5321 LLVMValueRef args [1];
5323 args [0] = convert (ctx, lhs, LLVMDoubleType ());
5324 values [ins->dreg] = LLVMBuildCall (builder, get_intrinsic (ctx, "llvm.sin.f64"), args, 1, dname);
5328 LLVMValueRef args [1];
5330 args [0] = convert (ctx, lhs, LLVMDoubleType ());
5331 values [ins->dreg] = LLVMBuildCall (builder, get_intrinsic (ctx, "llvm.cos.f64"), args, 1, dname);
5335 LLVMValueRef args [1];
5337 args [0] = convert (ctx, lhs, LLVMDoubleType ());
5338 values [ins->dreg] = LLVMBuildCall (builder, get_intrinsic (ctx, "llvm.sqrt.f64"), args, 1, dname);
5342 LLVMValueRef args [1];
5344 args [0] = convert (ctx, lhs, LLVMDoubleType ());
5345 values [ins->dreg] = LLVMBuildCall (builder, get_intrinsic (ctx, "fabs"), args, 1, dname);
5359 lhs = convert (ctx, lhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
5360 rhs = convert (ctx, rhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
5362 switch (ins->opcode) {
5365 v = LLVMBuildICmp (builder, LLVMIntSLE, lhs, rhs, "");
5369 v = LLVMBuildICmp (builder, LLVMIntSGE, lhs, rhs, "");
5373 v = LLVMBuildICmp (builder, LLVMIntULE, lhs, rhs, "");
5377 v = LLVMBuildICmp (builder, LLVMIntUGE, lhs, rhs, "");
5380 g_assert_not_reached ();
5383 values [ins->dreg] = LLVMBuildSelect (builder, v, lhs, rhs, dname);
5386 case OP_ATOMIC_EXCHANGE_I4:
5387 case OP_ATOMIC_EXCHANGE_I8: {
5388 LLVMValueRef args [2];
5391 if (ins->opcode == OP_ATOMIC_EXCHANGE_I4)
5392 t = LLVMInt32Type ();
5394 t = LLVMInt64Type ();
5396 g_assert (ins->inst_offset == 0);
5398 args [0] = convert (ctx, lhs, LLVMPointerType (t, 0));
5399 args [1] = convert (ctx, rhs, t);
5401 values [ins->dreg] = mono_llvm_build_atomic_rmw (builder, LLVM_ATOMICRMW_OP_XCHG, args [0], args [1]);
5404 case OP_ATOMIC_ADD_I4:
5405 case OP_ATOMIC_ADD_I8: {
5406 LLVMValueRef args [2];
5409 if (ins->opcode == OP_ATOMIC_ADD_I4)
5410 t = LLVMInt32Type ();
5412 t = LLVMInt64Type ();
5414 g_assert (ins->inst_offset == 0);
5416 args [0] = convert (ctx, lhs, LLVMPointerType (t, 0));
5417 args [1] = convert (ctx, rhs, t);
5418 values [ins->dreg] = LLVMBuildAdd (builder, mono_llvm_build_atomic_rmw (builder, LLVM_ATOMICRMW_OP_ADD, args [0], args [1]), args [1], dname);
5421 case OP_ATOMIC_CAS_I4:
5422 case OP_ATOMIC_CAS_I8: {
5423 LLVMValueRef args [3], val;
5426 if (ins->opcode == OP_ATOMIC_CAS_I4)
5427 t = LLVMInt32Type ();
5429 t = LLVMInt64Type ();
5431 args [0] = convert (ctx, lhs, LLVMPointerType (t, 0));
5433 args [1] = convert (ctx, values [ins->sreg3], t);
5435 args [2] = convert (ctx, values [ins->sreg2], t);
5436 val = mono_llvm_build_cmpxchg (builder, args [0], args [1], args [2]);
5437 /* cmpxchg returns a pair */
5438 values [ins->dreg] = LLVMBuildExtractValue (builder, val, 0, "");
5441 case OP_MEMORY_BARRIER: {
5442 mono_llvm_build_fence (builder, (BarrierKind) ins->backend.memory_barrier_kind);
5445 case OP_ATOMIC_LOAD_I1:
5446 case OP_ATOMIC_LOAD_I2:
5447 case OP_ATOMIC_LOAD_I4:
5448 case OP_ATOMIC_LOAD_I8:
5449 case OP_ATOMIC_LOAD_U1:
5450 case OP_ATOMIC_LOAD_U2:
5451 case OP_ATOMIC_LOAD_U4:
5452 case OP_ATOMIC_LOAD_U8:
5453 case OP_ATOMIC_LOAD_R4:
5454 case OP_ATOMIC_LOAD_R8: {
5455 #if LLVM_API_VERSION > 100
5457 gboolean sext, zext;
5459 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
5460 BarrierKind barrier = (BarrierKind) ins->backend.memory_barrier_kind;
5461 LLVMValueRef index, addr;
5463 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
5468 if (ins->inst_offset != 0) {
5469 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
5470 addr = LLVMBuildGEP (builder, convert (ctx, lhs, LLVMPointerType (t, 0)), &index, 1, "");
5475 addr = convert (ctx, addr, LLVMPointerType (t, 0));
5477 values [ins->dreg] = emit_load_general (ctx, bb, &builder, size, addr, lhs, dname, is_volatile, barrier);
5480 values [ins->dreg] = LLVMBuildSExt (builder, values [ins->dreg], LLVMInt32Type (), dname);
5482 values [ins->dreg] = LLVMBuildZExt (builder, values [ins->dreg], LLVMInt32Type (), dname);
5485 set_failure (ctx, "atomic mono.load intrinsic");
5489 case OP_ATOMIC_STORE_I1:
5490 case OP_ATOMIC_STORE_I2:
5491 case OP_ATOMIC_STORE_I4:
5492 case OP_ATOMIC_STORE_I8:
5493 case OP_ATOMIC_STORE_U1:
5494 case OP_ATOMIC_STORE_U2:
5495 case OP_ATOMIC_STORE_U4:
5496 case OP_ATOMIC_STORE_U8:
5497 case OP_ATOMIC_STORE_R4:
5498 case OP_ATOMIC_STORE_R8: {
5500 gboolean sext, zext;
5502 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
5503 BarrierKind barrier = (BarrierKind) ins->backend.memory_barrier_kind;
5504 LLVMValueRef index, addr, value, base;
5506 #if LLVM_API_VERSION < 100
5507 if (!cfg->llvm_only) {
5508 set_failure (ctx, "atomic mono.store intrinsic");
5513 if (!values [ins->inst_destbasereg]) {
5514 set_failure (ctx, "inst_destbasereg");
5518 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
5520 base = values [ins->inst_destbasereg];
5521 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
5522 addr = LLVMBuildGEP (builder, convert (ctx, base, LLVMPointerType (t, 0)), &index, 1, "");
5523 value = convert (ctx, values [ins->sreg1], t);
5525 emit_store_general (ctx, bb, &builder, size, value, addr, base, is_volatile, barrier);
5528 case OP_RELAXED_NOP: {
5529 #if defined(TARGET_AMD64) || defined(TARGET_X86)
5530 emit_call (ctx, bb, &builder, get_intrinsic (ctx, "llvm.x86.sse2.pause"), NULL, 0);
5537 #if (defined(TARGET_AMD64) || defined(TARGET_X86)) && defined(__linux__)
5539 // 257 == FS segment register
5540 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 257);
5542 // 256 == GS segment register
5543 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 256);
5546 values [ins->dreg] = LLVMBuildLoad (builder, LLVMBuildIntToPtr (builder, LLVMConstInt (IntPtrType (), ins->inst_offset, TRUE), ptrtype, ""), "");
5547 #elif defined(TARGET_AMD64) && defined(TARGET_OSX)
5548 /* See mono_amd64_emit_tls_get () */
5549 int offset = mono_amd64_get_tls_gs_offset () + (ins->inst_offset * 8);
5551 // 256 == GS segment register
5552 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 256);
5553 values [ins->dreg] = LLVMBuildLoad (builder, LLVMBuildIntToPtr (builder, LLVMConstInt (IntPtrType (), offset, TRUE), ptrtype, ""), "");
5555 set_failure (ctx, "opcode tls-get");
5561 case OP_TLS_GET_REG: {
5562 #if defined(TARGET_AMD64) && defined(__linux__)
5563 // 257 == FS segment register
5564 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 257);
5565 values [ins->dreg] = LLVMBuildLoad (builder, LLVMBuildIntToPtr (builder, convert (ctx, lhs, LLVMInt64Type ()), ptrtype, ""), "");
5566 #elif defined(TARGET_AMD64) && defined(TARGET_OSX)
5567 /* See emit_tls_get_reg () */
5568 // 256 == GS segment register
5569 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 256);
5570 values [ins->dreg] = LLVMBuildLoad (builder, LLVMBuildIntToPtr (builder, convert (ctx, lhs, LLVMInt32Type ()), ptrtype, ""), "");
5572 set_failure (ctx, "opcode tls-get");
5578 case OP_TLS_SET_REG: {
5579 #if defined(TARGET_AMD64) && defined(TARGET_OSX)
5580 /* See emit_tls_get_reg () */
5581 // 256 == GS segment register
5582 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 256);
5583 LLVMBuildStore (builder, convert (ctx, lhs, IntPtrType ()), LLVMBuildIntToPtr (builder, convert (ctx, rhs, LLVMInt32Type ()), ptrtype, ""));
5585 set_failure (ctx, "opcode tls-set-reg");
5590 case OP_GC_SAFE_POINT: {
5591 LLVMValueRef val, cmp, callee;
5592 LLVMBasicBlockRef poll_bb, cont_bb;
5593 static LLVMTypeRef sig;
5594 const char *icall_name = "mono_threads_state_poll";
5597 sig = LLVMFunctionType0 (LLVMVoidType (), FALSE);
5601 * mono_threads_state_poll ();
5602 * FIXME: Use a preserveall wrapper
5604 val = mono_llvm_build_load (builder, convert (ctx, lhs, LLVMPointerType (IntPtrType (), 0)), "", TRUE);
5605 cmp = LLVMBuildICmp (builder, LLVMIntEQ, val, LLVMConstNull (LLVMTypeOf (val)), "");
5606 poll_bb = gen_bb (ctx, "POLL_BB");
5607 cont_bb = gen_bb (ctx, "CONT_BB");
5608 LLVMBuildCondBr (builder, cmp, cont_bb, poll_bb);
5610 ctx->builder = builder = create_builder (ctx);
5611 LLVMPositionBuilderAtEnd (builder, poll_bb);
5613 if (ctx->cfg->compile_aot) {
5614 callee = get_callee (ctx, sig, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
5616 gpointer target = resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
5617 callee = emit_jit_callee (ctx, icall_name, sig, target);
5619 LLVMBuildCall (builder, callee, NULL, 0, "");
5620 LLVMBuildBr (builder, cont_bb);
5622 ctx->builder = builder = create_builder (ctx);
5623 LLVMPositionBuilderAtEnd (builder, cont_bb);
5624 ctx->bblocks [bb->block_num].end_bblock = cont_bb;
5632 case OP_IADD_OVF_UN:
5634 case OP_ISUB_OVF_UN:
5636 case OP_IMUL_OVF_UN:
5638 case OP_LADD_OVF_UN:
5640 case OP_LSUB_OVF_UN:
5642 case OP_LMUL_OVF_UN:
5644 LLVMValueRef args [2], val, ovf, func;
5646 args [0] = convert (ctx, lhs, op_to_llvm_type (ins->opcode));
5647 args [1] = convert (ctx, rhs, op_to_llvm_type (ins->opcode));
5648 func = get_intrinsic (ctx, ovf_op_to_intrins (ins->opcode));
5650 val = LLVMBuildCall (builder, func, args, 2, "");
5651 values [ins->dreg] = LLVMBuildExtractValue (builder, val, 0, dname);
5652 ovf = LLVMBuildExtractValue (builder, val, 1, "");
5653 emit_cond_system_exception (ctx, bb, "OverflowException", ovf);
5656 builder = ctx->builder;
5662 * We currently model them using arrays. Promotion to local vregs is
5663 * disabled for them in mono_handle_global_vregs () in the LLVM case,
5664 * so we always have an entry in cfg->varinfo for them.
5665 * FIXME: Is this needed ?
5668 MonoClass *klass = ins->klass;
5669 LLVMValueRef args [5];
5673 set_failure (ctx, "!klass");
5677 if (!addresses [ins->dreg])
5678 addresses [ins->dreg] = build_alloca (ctx, &klass->byval_arg);
5679 args [0] = LLVMBuildBitCast (builder, addresses [ins->dreg], LLVMPointerType (LLVMInt8Type (), 0), "");
5680 args [1] = LLVMConstInt (LLVMInt8Type (), 0, FALSE);
5681 args [2] = LLVMConstInt (LLVMInt32Type (), mono_class_value_size (klass, NULL), FALSE);
5683 args [3] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
5684 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
5685 LLVMBuildCall (builder, get_intrinsic (ctx, "llvm.memset.p0i8.i32"), args, 5, "");
5688 case OP_DUMMY_VZERO:
5691 case OP_STOREV_MEMBASE:
5692 case OP_LOADV_MEMBASE:
5694 MonoClass *klass = ins->klass;
5695 LLVMValueRef src = NULL, dst, args [5];
5696 gboolean done = FALSE;
5700 set_failure (ctx, "!klass");
5704 if (mini_is_gsharedvt_klass (klass)) {
5706 set_failure (ctx, "gsharedvt");
5710 switch (ins->opcode) {
5711 case OP_STOREV_MEMBASE:
5712 if (cfg->gen_write_barriers && klass->has_references && ins->inst_destbasereg != cfg->frame_reg &&
5713 LLVMGetInstructionOpcode (values [ins->inst_destbasereg]) != LLVMAlloca) {
5714 /* Decomposed earlier */
5715 g_assert_not_reached ();
5718 if (!addresses [ins->sreg1]) {
5720 g_assert (values [ins->sreg1]);
5721 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));
5722 LLVMBuildStore (builder, values [ins->sreg1], dst);
5725 src = LLVMBuildBitCast (builder, addresses [ins->sreg1], LLVMPointerType (LLVMInt8Type (), 0), "");
5726 dst = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_destbasereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (LLVMInt8Type (), 0));
5729 case OP_LOADV_MEMBASE:
5730 if (!addresses [ins->dreg])
5731 addresses [ins->dreg] = build_alloca (ctx, &klass->byval_arg);
5732 src = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_basereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (LLVMInt8Type (), 0));
5733 dst = LLVMBuildBitCast (builder, addresses [ins->dreg], LLVMPointerType (LLVMInt8Type (), 0), "");
5736 if (!addresses [ins->sreg1])
5737 addresses [ins->sreg1] = build_alloca (ctx, &klass->byval_arg);
5738 if (!addresses [ins->dreg])
5739 addresses [ins->dreg] = build_alloca (ctx, &klass->byval_arg);
5740 src = LLVMBuildBitCast (builder, addresses [ins->sreg1], LLVMPointerType (LLVMInt8Type (), 0), "");
5741 dst = LLVMBuildBitCast (builder, addresses [ins->dreg], LLVMPointerType (LLVMInt8Type (), 0), "");
5744 g_assert_not_reached ();
5754 args [2] = LLVMConstInt (LLVMInt32Type (), mono_class_value_size (klass, NULL), FALSE);
5755 args [3] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
5757 args [3] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
5758 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
5759 LLVMBuildCall (builder, get_intrinsic (ctx, "llvm.memcpy.p0i8.p0i8.i32"), args, 5, "");
5762 case OP_LLVM_OUTARG_VT: {
5763 LLVMArgInfo *ainfo = (LLVMArgInfo*)ins->inst_p0;
5764 MonoType *t = mini_get_underlying_type (ins->inst_vtype);
5766 if (ainfo->storage == LLVMArgGsharedvtVariable) {
5767 MonoInst *var = get_vreg_to_inst (cfg, ins->sreg1);
5769 if (var && var->opcode == OP_GSHAREDVT_LOCAL) {
5770 addresses [ins->dreg] = convert (ctx, emit_gsharedvt_ldaddr (ctx, var->dreg), LLVMPointerType (IntPtrType (), 0));
5772 g_assert (addresses [ins->sreg1]);
5773 addresses [ins->dreg] = addresses [ins->sreg1];
5775 } else if (ainfo->storage == LLVMArgGsharedvtFixed) {
5776 if (!addresses [ins->sreg1]) {
5777 addresses [ins->sreg1] = build_alloca (ctx, t);
5778 g_assert (values [ins->sreg1]);
5780 LLVMBuildStore (builder, convert (ctx, values [ins->sreg1], LLVMGetElementType (LLVMTypeOf (addresses [ins->sreg1]))), addresses [ins->sreg1]);
5781 addresses [ins->dreg] = addresses [ins->sreg1];
5783 if (!addresses [ins->sreg1]) {
5784 addresses [ins->sreg1] = build_alloca (ctx, t);
5785 g_assert (values [ins->sreg1]);
5786 LLVMBuildStore (builder, convert (ctx, values [ins->sreg1], type_to_llvm_type (ctx, t)), addresses [ins->sreg1]);
5788 addresses [ins->dreg] = addresses [ins->sreg1];
5792 case OP_OBJC_GET_SELECTOR: {
5793 const char *name = (const char*)ins->inst_p0;
5796 if (!ctx->module->objc_selector_to_var)
5797 ctx->module->objc_selector_to_var = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
5798 var = g_hash_table_lookup (ctx->module->objc_selector_to_var, name);
5800 LLVMValueRef indexes [16];
5802 LLVMValueRef name_var = LLVMAddGlobal (ctx->lmodule, LLVMArrayType (LLVMInt8Type (), strlen (name) + 1), "@OBJC_METH_VAR_NAME");
5803 LLVMSetInitializer (name_var, mono_llvm_create_constant_data_array ((const uint8_t*)name, strlen (name) + 1));
5804 LLVMSetLinkage (name_var, LLVMPrivateLinkage);
5805 LLVMSetSection (name_var, "__TEXT,__objc_methname,cstring_literals");
5807 LLVMValueRef ref_var = LLVMAddGlobal (ctx->lmodule, LLVMPointerType (LLVMInt8Type (), 0), "@OBJC_SELECTOR_REFERENCES");
5809 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, 0);
5810 indexes [1] = LLVMConstInt (LLVMInt32Type (), 0, 0);
5811 LLVMSetInitializer (ref_var, LLVMConstGEP (name_var, indexes, 2));
5812 LLVMSetLinkage (ref_var, LLVMPrivateLinkage);
5813 LLVMSetExternallyInitialized (ref_var, TRUE);
5814 LLVMSetSection (ref_var, "__DATA, __objc_selrefs, literal_pointers, no_dead_strip");
5815 LLVMSetAlignment (ref_var, sizeof (mgreg_t));
5817 g_hash_table_insert (ctx->module->objc_selector_to_var, g_strdup (name), ref_var);
5821 values [ins->dreg] = LLVMBuildLoad (builder, var, "");
5828 #if defined(TARGET_X86) || defined(TARGET_AMD64)
5830 values [ins->dreg] = LLVMConstNull (type_to_llvm_type (ctx, &ins->klass->byval_arg));
5833 case OP_LOADX_MEMBASE: {
5834 LLVMTypeRef t = type_to_llvm_type (ctx, &ins->klass->byval_arg);
5837 src = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_basereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (t, 0));
5838 values [ins->dreg] = mono_llvm_build_aligned_load (builder, src, "", FALSE, 1);
5841 case OP_STOREX_MEMBASE: {
5842 LLVMTypeRef t = LLVMTypeOf (values [ins->sreg1]);
5845 dest = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_destbasereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (t, 0));
5846 mono_llvm_build_aligned_store (builder, values [ins->sreg1], dest, FALSE, 1);
5853 values [ins->dreg] = LLVMBuildAdd (builder, lhs, rhs, "");
5857 values [ins->dreg] = LLVMBuildFAdd (builder, lhs, rhs, "");
5863 values [ins->dreg] = LLVMBuildSub (builder, lhs, rhs, "");
5867 values [ins->dreg] = LLVMBuildFSub (builder, lhs, rhs, "");
5871 values [ins->dreg] = LLVMBuildFMul (builder, lhs, rhs, "");
5875 values [ins->dreg] = LLVMBuildFDiv (builder, lhs, rhs, "");
5878 values [ins->dreg] = LLVMBuildAnd (builder, lhs, rhs, "");
5881 values [ins->dreg] = LLVMBuildOr (builder, lhs, rhs, "");
5884 values [ins->dreg] = LLVMBuildXor (builder, lhs, rhs, "");
5888 values [ins->dreg] = LLVMBuildMul (builder, lhs, rhs, "");
5899 LLVMValueRef v = NULL;
5901 switch (ins->opcode) {
5906 t = LLVMVectorType (LLVMInt32Type (), 4);
5907 rt = LLVMVectorType (LLVMFloatType (), 4);
5913 t = LLVMVectorType (LLVMInt64Type (), 2);
5914 rt = LLVMVectorType (LLVMDoubleType (), 2);
5917 t = LLVMInt32Type ();
5918 rt = LLVMInt32Type ();
5919 g_assert_not_reached ();
5922 lhs = LLVMBuildBitCast (builder, lhs, t, "");
5923 rhs = LLVMBuildBitCast (builder, rhs, t, "");
5924 switch (ins->opcode) {
5927 v = LLVMBuildAnd (builder, lhs, rhs, "");
5931 v = LLVMBuildOr (builder, lhs, rhs, "");
5935 v = LLVMBuildXor (builder, lhs, rhs, "");
5939 v = LLVMBuildAnd (builder, rhs, LLVMBuildNot (builder, lhs, ""), "");
5942 values [ins->dreg] = LLVMBuildBitCast (builder, v, rt, "");
5966 case OP_PADDB_SAT_UN:
5967 case OP_PADDW_SAT_UN:
5968 case OP_PSUBB_SAT_UN:
5969 case OP_PSUBW_SAT_UN:
5977 case OP_PMULW_HIGH_UN: {
5978 LLVMValueRef args [2];
5983 values [ins->dreg] = LLVMBuildCall (builder, get_intrinsic (ctx, simd_op_to_intrins (ins->opcode)), args, 2, dname);
5990 values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildICmp (builder, LLVMIntEQ, lhs, rhs, ""), LLVMTypeOf (lhs), "");
5994 values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildICmp (builder, LLVMIntSGT, lhs, rhs, ""), LLVMTypeOf (lhs), "");
6002 case OP_EXTRACTX_U2:
6004 case OP_EXTRACT_U1: {
6006 gboolean zext = FALSE;
6008 t = simd_op_to_llvm_type (ins->opcode);
6010 switch (ins->opcode) {
6018 case OP_EXTRACTX_U2:
6023 t = LLVMInt32Type ();
6024 g_assert_not_reached ();
6027 lhs = LLVMBuildBitCast (builder, lhs, t, "");
6028 values [ins->dreg] = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), "");
6030 values [ins->dreg] = LLVMBuildZExt (builder, values [ins->dreg], LLVMInt32Type (), "");
6039 case OP_EXPAND_R8: {
6040 LLVMTypeRef t = simd_op_to_llvm_type (ins->opcode);
6041 LLVMValueRef mask [16], v;
6044 for (i = 0; i < 16; ++i)
6045 mask [i] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
6047 v = convert (ctx, values [ins->sreg1], LLVMGetElementType (t));
6049 values [ins->dreg] = LLVMBuildInsertElement (builder, LLVMConstNull (t), v, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
6050 values [ins->dreg] = LLVMBuildShuffleVector (builder, values [ins->dreg], LLVMGetUndef (t), LLVMConstVector (mask, LLVMGetVectorSize (t)), "");
6055 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt8Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
6058 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt16Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
6061 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt32Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
6064 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt64Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
6067 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMFloatType ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
6070 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMDoubleType ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
6081 case OP_EXTRACT_MASK:
6088 v = convert (ctx, values [ins->sreg1], simd_op_to_llvm_type (ins->opcode));
6090 values [ins->dreg] = LLVMBuildCall (builder, get_intrinsic (ctx, simd_op_to_intrins (ins->opcode)), &v, 1, dname);
6096 LLVMValueRef args [3];
6100 args [2] = LLVMConstInt (LLVMInt8Type (), ins->inst_c0, FALSE);
6102 values [ins->dreg] = LLVMBuildCall (builder, get_intrinsic (ctx, simd_op_to_intrins (ins->opcode)), args, 3, dname);
6107 /* This is only used for implementing shifts by non-immediate */
6108 values [ins->dreg] = lhs;
6119 LLVMValueRef args [3];
6122 args [1] = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
6124 values [ins->dreg] = LLVMBuildCall (builder, get_intrinsic (ctx, simd_op_to_intrins (ins->opcode)), args, 2, dname);
6135 case OP_PSHLQ_REG: {
6136 LLVMValueRef args [3];
6139 args [1] = values [ins->sreg2];
6141 values [ins->dreg] = LLVMBuildCall (builder, get_intrinsic (ctx, simd_op_to_intrins (ins->opcode)), args, 2, dname);
6148 case OP_PSHUFLEW_LOW:
6149 case OP_PSHUFLEW_HIGH: {
6151 LLVMValueRef v1 = NULL, v2 = NULL, mask_values [16];
6152 int i, mask_size = 0;
6153 int imask = ins->inst_c0;
6155 /* Convert the x86 shuffle mask to LLVM's */
6156 switch (ins->opcode) {
6159 mask [0] = ((imask >> 0) & 3);
6160 mask [1] = ((imask >> 2) & 3);
6161 mask [2] = ((imask >> 4) & 3) + 4;
6162 mask [3] = ((imask >> 6) & 3) + 4;
6163 v1 = values [ins->sreg1];
6164 v2 = values [ins->sreg2];
6168 mask [0] = ((imask >> 0) & 1);
6169 mask [1] = ((imask >> 1) & 1) + 2;
6170 v1 = values [ins->sreg1];
6171 v2 = values [ins->sreg2];
6173 case OP_PSHUFLEW_LOW:
6175 mask [0] = ((imask >> 0) & 3);
6176 mask [1] = ((imask >> 2) & 3);
6177 mask [2] = ((imask >> 4) & 3);
6178 mask [3] = ((imask >> 6) & 3);
6183 v1 = values [ins->sreg1];
6184 v2 = LLVMGetUndef (LLVMTypeOf (v1));
6186 case OP_PSHUFLEW_HIGH:
6192 mask [4] = 4 + ((imask >> 0) & 3);
6193 mask [5] = 4 + ((imask >> 2) & 3);
6194 mask [6] = 4 + ((imask >> 4) & 3);
6195 mask [7] = 4 + ((imask >> 6) & 3);
6196 v1 = values [ins->sreg1];
6197 v2 = LLVMGetUndef (LLVMTypeOf (v1));
6201 mask [0] = ((imask >> 0) & 3);
6202 mask [1] = ((imask >> 2) & 3);
6203 mask [2] = ((imask >> 4) & 3);
6204 mask [3] = ((imask >> 6) & 3);
6205 v1 = values [ins->sreg1];
6206 v2 = LLVMGetUndef (LLVMTypeOf (v1));
6209 g_assert_not_reached ();
6211 for (i = 0; i < mask_size; ++i)
6212 mask_values [i] = LLVMConstInt (LLVMInt32Type (), mask [i], FALSE);
6214 values [ins->dreg] =
6215 LLVMBuildShuffleVector (builder, v1, v2,
6216 LLVMConstVector (mask_values, mask_size), dname);
6220 case OP_UNPACK_LOWB:
6221 case OP_UNPACK_LOWW:
6222 case OP_UNPACK_LOWD:
6223 case OP_UNPACK_LOWQ:
6224 case OP_UNPACK_LOWPS:
6225 case OP_UNPACK_LOWPD:
6226 case OP_UNPACK_HIGHB:
6227 case OP_UNPACK_HIGHW:
6228 case OP_UNPACK_HIGHD:
6229 case OP_UNPACK_HIGHQ:
6230 case OP_UNPACK_HIGHPS:
6231 case OP_UNPACK_HIGHPD: {
6233 LLVMValueRef mask_values [16];
6234 int i, mask_size = 0;
6235 gboolean low = FALSE;
6237 switch (ins->opcode) {
6238 case OP_UNPACK_LOWB:
6242 case OP_UNPACK_LOWW:
6246 case OP_UNPACK_LOWD:
6247 case OP_UNPACK_LOWPS:
6251 case OP_UNPACK_LOWQ:
6252 case OP_UNPACK_LOWPD:
6256 case OP_UNPACK_HIGHB:
6259 case OP_UNPACK_HIGHW:
6262 case OP_UNPACK_HIGHD:
6263 case OP_UNPACK_HIGHPS:
6266 case OP_UNPACK_HIGHQ:
6267 case OP_UNPACK_HIGHPD:
6271 g_assert_not_reached ();
6275 for (i = 0; i < (mask_size / 2); ++i) {
6277 mask [(i * 2) + 1] = mask_size + i;
6280 for (i = 0; i < (mask_size / 2); ++i) {
6281 mask [(i * 2)] = (mask_size / 2) + i;
6282 mask [(i * 2) + 1] = mask_size + (mask_size / 2) + i;
6286 for (i = 0; i < mask_size; ++i)
6287 mask_values [i] = LLVMConstInt (LLVMInt32Type (), mask [i], FALSE);
6289 values [ins->dreg] =
6290 LLVMBuildShuffleVector (builder, values [ins->sreg1], values [ins->sreg2],
6291 LLVMConstVector (mask_values, mask_size), dname);
6296 LLVMTypeRef t = simd_op_to_llvm_type (ins->opcode);
6297 LLVMValueRef v, val;
6299 v = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
6300 val = LLVMConstNull (t);
6301 val = LLVMBuildInsertElement (builder, val, v, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
6302 val = LLVMBuildInsertElement (builder, val, v, LLVMConstInt (LLVMInt32Type (), 1, FALSE), dname);
6304 values [ins->dreg] = val;
6308 case OP_DUPPS_HIGH: {
6309 LLVMTypeRef t = simd_op_to_llvm_type (ins->opcode);
6310 LLVMValueRef v1, v2, val;
6313 if (ins->opcode == OP_DUPPS_LOW) {
6314 v1 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
6315 v2 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 2, FALSE), "");
6317 v1 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 1, FALSE), "");
6318 v2 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 3, FALSE), "");
6320 val = LLVMConstNull (t);
6321 val = LLVMBuildInsertElement (builder, val, v1, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
6322 val = LLVMBuildInsertElement (builder, val, v1, LLVMConstInt (LLVMInt32Type (), 1, FALSE), "");
6323 val = LLVMBuildInsertElement (builder, val, v2, LLVMConstInt (LLVMInt32Type (), 2, FALSE), "");
6324 val = LLVMBuildInsertElement (builder, val, v2, LLVMConstInt (LLVMInt32Type (), 3, FALSE), "");
6326 values [ins->dreg] = val;
6336 * EXCEPTION HANDLING
6338 case OP_IMPLICIT_EXCEPTION:
6339 /* This marks a place where an implicit exception can happen */
6340 if (bb->region != -1)
6341 set_failure (ctx, "implicit-exception");
6345 gboolean rethrow = (ins->opcode == OP_RETHROW);
6346 if (ctx->llvm_only) {
6347 emit_llvmonly_throw (ctx, bb, rethrow, lhs);
6348 has_terminator = TRUE;
6349 ctx->unreachable [bb->block_num] = TRUE;
6351 emit_throw (ctx, bb, rethrow, lhs);
6352 builder = ctx->builder;
6356 case OP_CALL_HANDLER: {
6358 * We don't 'call' handlers, but instead simply branch to them.
6359 * The code generated by ENDFINALLY will branch back to us.
6361 LLVMBasicBlockRef noex_bb;
6363 BBInfo *info = &bblocks [ins->inst_target_bb->block_num];
6365 bb_list = info->call_handler_return_bbs;
6368 * Set the indicator variable for the finally clause.
6370 lhs = info->finally_ind;
6372 LLVMBuildStore (builder, LLVMConstInt (LLVMInt32Type (), g_slist_length (bb_list) + 1, FALSE), lhs);
6374 /* Branch to the finally clause */
6375 LLVMBuildBr (builder, info->call_handler_target_bb);
6377 noex_bb = gen_bb (ctx, "CALL_HANDLER_CONT_BB");
6378 info->call_handler_return_bbs = g_slist_append_mempool (cfg->mempool, info->call_handler_return_bbs, noex_bb);
6380 builder = ctx->builder = create_builder (ctx);
6381 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
6383 bblocks [bb->block_num].end_bblock = noex_bb;
6386 case OP_START_HANDLER: {
6389 case OP_ENDFINALLY: {
6390 LLVMBasicBlockRef resume_bb;
6391 MonoBasicBlock *handler_bb;
6392 LLVMValueRef val, switch_ins, callee;
6396 handler_bb = (MonoBasicBlock*)g_hash_table_lookup (ctx->region_to_handler, GUINT_TO_POINTER (mono_get_block_region_notry (cfg, bb->region)));
6397 g_assert (handler_bb);
6398 info = &bblocks [handler_bb->block_num];
6399 lhs = info->finally_ind;
6402 bb_list = info->call_handler_return_bbs;
6404 resume_bb = gen_bb (ctx, "ENDFINALLY_RESUME_BB");
6406 /* Load the finally variable */
6407 val = LLVMBuildLoad (builder, lhs, "");
6409 /* Reset the variable */
6410 LLVMBuildStore (builder, LLVMConstInt (LLVMInt32Type (), 0, FALSE), lhs);
6412 /* Branch to either resume_bb, or to the bblocks in bb_list */
6413 switch_ins = LLVMBuildSwitch (builder, val, resume_bb, g_slist_length (bb_list));
6415 * The other targets are added at the end to handle OP_CALL_HANDLER
6416 * opcodes processed later.
6418 info->endfinally_switch_ins_list = g_slist_append_mempool (cfg->mempool, info->endfinally_switch_ins_list, switch_ins);
6420 builder = ctx->builder = create_builder (ctx);
6421 LLVMPositionBuilderAtEnd (ctx->builder, resume_bb);
6423 if (ctx->llvm_only) {
6424 emit_resume_eh (ctx, bb);
6426 if (ctx->cfg->compile_aot) {
6427 callee = get_callee (ctx, LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE), MONO_PATCH_INFO_INTERNAL_METHOD, "llvm_resume_unwind_trampoline");
6429 #if LLVM_API_VERSION > 100
6430 MonoJitICallInfo *info;
6432 info = mono_find_jit_icall_by_name ("llvm_resume_unwind_trampoline");
6434 gpointer target = (void*)info->func;
6435 LLVMTypeRef icall_sig = LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE);
6436 callee = emit_jit_callee (ctx, "llvm_resume_unwind_trampoline", icall_sig, target);
6438 callee = LLVMGetNamedFunction (ctx->lmodule, "llvm_resume_unwind_trampoline");
6441 LLVMBuildCall (builder, callee, NULL, 0, "");
6442 LLVMBuildUnreachable (builder);
6445 has_terminator = TRUE;
6448 case OP_IL_SEQ_POINT:
6453 sprintf (reason, "opcode %s", mono_inst_name (ins->opcode));
6454 set_failure (ctx, reason);
6462 /* Convert the value to the type required by phi nodes */
6463 if (spec [MONO_INST_DEST] != ' ' && !MONO_IS_STORE_MEMBASE (ins) && ctx->vreg_types [ins->dreg]) {
6464 if (!values [ins->dreg])
6466 values [ins->dreg] = addresses [ins->dreg];
6468 values [ins->dreg] = convert (ctx, values [ins->dreg], ctx->vreg_types [ins->dreg]);
6471 /* Add stores for volatile variables */
6472 if (spec [MONO_INST_DEST] != ' ' && spec [MONO_INST_DEST] != 'v' && !MONO_IS_STORE_MEMBASE (ins))
6473 emit_volatile_store (ctx, ins->dreg);
6479 if (!has_terminator && bb->next_bb && (bb == cfg->bb_entry || bb->in_count > 0)) {
6480 LLVMBuildBr (builder, get_bb (ctx, bb->next_bb));
6483 if (bb == cfg->bb_exit && sig->ret->type == MONO_TYPE_VOID) {
6484 emit_dbg_loc (ctx, builder, cfg->header->code + cfg->header->code_size - 1);
6485 LLVMBuildRetVoid (builder);
6488 if (bb == cfg->bb_entry)
6489 ctx->last_alloca = LLVMGetLastInstruction (get_bb (ctx, cfg->bb_entry));
6493 * mono_llvm_check_method_supported:
6495 * Do some quick checks to decide whenever cfg->method can be compiled by LLVM, to avoid
6496 * compiling a method twice.
6499 mono_llvm_check_method_supported (MonoCompile *cfg)
6506 if (cfg->method->save_lmf) {
6507 cfg->exception_message = g_strdup ("lmf");
6508 cfg->disable_llvm = TRUE;
6510 if (cfg->disable_llvm)
6514 * Nested clauses where one of the clauses is a finally clause is
6515 * not supported, because LLVM can't figure out the control flow,
6516 * probably because we resume exception handling by calling our
6517 * own function instead of using the 'resume' llvm instruction.
6519 for (i = 0; i < cfg->header->num_clauses; ++i) {
6520 for (j = 0; j < cfg->header->num_clauses; ++j) {
6521 MonoExceptionClause *clause1 = &cfg->header->clauses [i];
6522 MonoExceptionClause *clause2 = &cfg->header->clauses [j];
6524 // FIXME: Nested try clauses fail in some cases too, i.e. #37273
6525 if (i != j && clause1->try_offset >= clause2->try_offset && clause1->handler_offset <= clause2->handler_offset) {
6526 //(clause1->flags == MONO_EXCEPTION_CLAUSE_FINALLY || clause2->flags == MONO_EXCEPTION_CLAUSE_FINALLY)) {
6527 cfg->exception_message = g_strdup ("nested clauses");
6528 cfg->disable_llvm = TRUE;
6533 if (cfg->disable_llvm)
6537 if (cfg->method->dynamic) {
6538 cfg->exception_message = g_strdup ("dynamic.");
6539 cfg->disable_llvm = TRUE;
6541 if (cfg->disable_llvm)
6545 static LLVMCallInfo*
6546 get_llvm_call_info (MonoCompile *cfg, MonoMethodSignature *sig)
6548 LLVMCallInfo *linfo;
6551 if (cfg->gsharedvt && cfg->llvm_only && mini_is_gsharedvt_variable_signature (sig)) {
6555 * Gsharedvt methods have the following calling convention:
6556 * - all arguments are passed by ref, even non generic ones
6557 * - the return value is returned by ref too, using a vret
6558 * argument passed after 'this'.
6560 n = sig->param_count + sig->hasthis;
6561 linfo = (LLVMCallInfo*)mono_mempool_alloc0 (cfg->mempool, sizeof (LLVMCallInfo) + (sizeof (LLVMArgInfo) * n));
6565 linfo->args [pindex ++].storage = LLVMArgNormal;
6567 if (sig->ret->type != MONO_TYPE_VOID) {
6568 if (mini_is_gsharedvt_variable_type (sig->ret))
6569 linfo->ret.storage = LLVMArgGsharedvtVariable;
6570 else if (mini_type_is_vtype (sig->ret))
6571 linfo->ret.storage = LLVMArgGsharedvtFixedVtype;
6573 linfo->ret.storage = LLVMArgGsharedvtFixed;
6574 linfo->vret_arg_index = pindex;
6576 linfo->ret.storage = LLVMArgNone;
6579 for (i = 0; i < sig->param_count; ++i) {
6580 if (sig->params [i]->byref)
6581 linfo->args [pindex].storage = LLVMArgNormal;
6582 else if (mini_is_gsharedvt_variable_type (sig->params [i]))
6583 linfo->args [pindex].storage = LLVMArgGsharedvtVariable;
6584 else if (mini_type_is_vtype (sig->params [i]))
6585 linfo->args [pindex].storage = LLVMArgGsharedvtFixedVtype;
6587 linfo->args [pindex].storage = LLVMArgGsharedvtFixed;
6588 linfo->args [pindex].type = sig->params [i];
6595 linfo = mono_arch_get_llvm_call_info (cfg, sig);
6596 for (i = 0; i < sig->param_count; ++i)
6597 linfo->args [i + sig->hasthis].type = sig->params [i];
6603 emit_method_inner (EmitContext *ctx);
6606 free_ctx (EmitContext *ctx)
6610 g_free (ctx->values);
6611 g_free (ctx->addresses);
6612 g_free (ctx->vreg_types);
6613 g_free (ctx->vreg_cli_types);
6614 g_free (ctx->is_dead);
6615 g_free (ctx->unreachable);
6616 g_ptr_array_free (ctx->phi_values, TRUE);
6617 g_free (ctx->bblocks);
6618 g_hash_table_destroy (ctx->region_to_handler);
6619 g_hash_table_destroy (ctx->clause_to_handler);
6620 g_hash_table_destroy (ctx->jit_callees);
6621 g_free (ctx->method_name);
6622 g_ptr_array_free (ctx->bblock_list, TRUE);
6624 for (l = ctx->builders; l; l = l->next) {
6625 LLVMBuilderRef builder = (LLVMBuilderRef)l->data;
6626 LLVMDisposeBuilder (builder);
6633 * mono_llvm_emit_method:
6635 * Emit LLVM IL from the mono IL, and compile it to native code using LLVM.
6638 mono_llvm_emit_method (MonoCompile *cfg)
6642 gboolean is_linkonce = FALSE;
6645 /* The code below might acquire the loader lock, so use it for global locking */
6646 mono_loader_lock ();
6648 /* Used to communicate with the callbacks */
6649 mono_native_tls_set_value (current_cfg_tls_id, cfg);
6651 ctx = g_new0 (EmitContext, 1);
6653 ctx->mempool = cfg->mempool;
6656 * This maps vregs to the LLVM instruction defining them
6658 ctx->values = g_new0 (LLVMValueRef, cfg->next_vreg);
6660 * This maps vregs for volatile variables to the LLVM instruction defining their
6663 ctx->addresses = g_new0 (LLVMValueRef, cfg->next_vreg);
6664 ctx->vreg_types = g_new0 (LLVMTypeRef, cfg->next_vreg);
6665 ctx->vreg_cli_types = g_new0 (MonoType*, cfg->next_vreg);
6666 ctx->phi_values = g_ptr_array_sized_new (256);
6668 * This signals whenever the vreg was defined by a phi node with no input vars
6669 * (i.e. all its input bblocks end with NOT_REACHABLE).
6671 ctx->is_dead = g_new0 (gboolean, cfg->next_vreg);
6672 /* Whenever the bblock is unreachable */
6673 ctx->unreachable = g_new0 (gboolean, cfg->max_block_num);
6674 ctx->bblock_list = g_ptr_array_sized_new (256);
6676 ctx->region_to_handler = g_hash_table_new (NULL, NULL);
6677 ctx->clause_to_handler = g_hash_table_new (NULL, NULL);
6678 ctx->method_to_callers = g_hash_table_new (NULL, NULL);
6679 ctx->jit_callees = g_hash_table_new (NULL, NULL);
6680 if (cfg->compile_aot) {
6681 ctx->module = &aot_module;
6685 * Allow the linker to discard duplicate copies of wrappers, generic instances etc. by using the 'linkonce'
6686 * linkage for them. This requires the following:
6687 * - the method needs to have a unique mangled name
6688 * - llvmonly mode, since the code in aot-runtime.c would initialize got slots in the wrong aot image etc.
6690 is_linkonce = ctx->module->llvm_only && ctx->module->static_link && mono_aot_is_linkonce_method (cfg->method);
6692 method_name = mono_aot_get_mangled_method_name (cfg->method);
6694 is_linkonce = FALSE;
6697 printf ("%s %s\n", mono_method_full_name (cfg->method, 1), method_name);
6699 printf ("%s\n", mono_method_full_name (cfg->method, 1));
6703 method_name = mono_aot_get_method_name (cfg);
6704 cfg->llvm_method_name = g_strdup (method_name);
6706 init_jit_module (cfg->domain);
6707 ctx->module = (MonoLLVMModule*)domain_jit_info (cfg->domain)->llvm_module;
6708 method_name = mono_method_full_name (cfg->method, TRUE);
6710 ctx->method_name = method_name;
6711 ctx->is_linkonce = is_linkonce;
6713 #if LLVM_API_VERSION > 100
6714 if (cfg->compile_aot)
6715 ctx->lmodule = ctx->module->lmodule;
6717 ctx->lmodule = LLVMModuleCreateWithName ("jit-module");
6719 ctx->lmodule = ctx->module->lmodule;
6721 ctx->llvm_only = ctx->module->llvm_only;
6723 emit_method_inner (ctx);
6725 if (!ctx_ok (ctx)) {
6727 /* Need to add unused phi nodes as they can be referenced by other values */
6728 LLVMBasicBlockRef phi_bb = LLVMAppendBasicBlock (ctx->lmethod, "PHI_BB");
6729 LLVMBuilderRef builder;
6731 builder = create_builder (ctx);
6732 LLVMPositionBuilderAtEnd (builder, phi_bb);
6734 for (i = 0; i < ctx->phi_values->len; ++i) {
6735 LLVMValueRef v = (LLVMValueRef)g_ptr_array_index (ctx->phi_values, i);
6736 if (LLVMGetInstructionParent (v) == NULL)
6737 LLVMInsertIntoBuilder (builder, v);
6740 LLVMDeleteFunction (ctx->lmethod);
6746 mono_native_tls_set_value (current_cfg_tls_id, NULL);
6748 mono_loader_unlock ();
6752 emit_method_inner (EmitContext *ctx)
6754 MonoCompile *cfg = ctx->cfg;
6755 MonoMethodSignature *sig;
6757 LLVMTypeRef method_type;
6758 LLVMValueRef method = NULL;
6759 LLVMValueRef *values = ctx->values;
6760 int i, max_block_num, bb_index;
6761 gboolean last = FALSE;
6762 LLVMCallInfo *linfo;
6763 LLVMModuleRef lmodule = ctx->lmodule;
6765 GPtrArray *bblock_list = ctx->bblock_list;
6766 MonoMethodHeader *header;
6767 MonoExceptionClause *clause;
6770 if (cfg->gsharedvt && !cfg->llvm_only) {
6771 set_failure (ctx, "gsharedvt");
6777 static int count = 0;
6780 if (g_getenv ("LLVM_COUNT")) {
6781 if (count == atoi (g_getenv ("LLVM_COUNT"))) {
6782 printf ("LAST: %s\n", mono_method_full_name (cfg->method, TRUE));
6786 if (count > atoi (g_getenv ("LLVM_COUNT"))) {
6787 set_failure (ctx, "count");
6794 sig = mono_method_signature (cfg->method);
6797 linfo = get_llvm_call_info (cfg, sig);
6803 linfo->rgctx_arg = TRUE;
6804 ctx->method_type = method_type = sig_to_llvm_sig_full (ctx, sig, linfo);
6808 method = LLVMAddFunction (lmodule, ctx->method_name, method_type);
6809 ctx->lmethod = method;
6811 if (!cfg->llvm_only)
6812 LLVMSetFunctionCallConv (method, LLVMMono1CallConv);
6813 LLVMSetLinkage (method, LLVMPrivateLinkage);
6815 LLVMAddFunctionAttr (method, LLVMUWTable);
6817 if (cfg->compile_aot) {
6818 LLVMSetLinkage (method, LLVMInternalLinkage);
6819 if (ctx->module->external_symbols) {
6820 LLVMSetLinkage (method, LLVMExternalLinkage);
6821 LLVMSetVisibility (method, LLVMHiddenVisibility);
6823 if (ctx->is_linkonce) {
6824 LLVMSetLinkage (method, LLVMLinkOnceAnyLinkage);
6825 LLVMSetVisibility (method, LLVMDefaultVisibility);
6828 #if LLVM_API_VERSION > 100
6829 LLVMSetLinkage (method, LLVMExternalLinkage);
6831 LLVMSetLinkage (method, LLVMPrivateLinkage);
6835 if (cfg->method->save_lmf && !cfg->llvm_only) {
6836 set_failure (ctx, "lmf");
6840 if (sig->pinvoke && cfg->method->wrapper_type != MONO_WRAPPER_RUNTIME_INVOKE && !cfg->llvm_only) {
6841 set_failure (ctx, "pinvoke signature");
6845 header = cfg->header;
6846 for (i = 0; i < header->num_clauses; ++i) {
6847 clause = &header->clauses [i];
6848 if (clause->flags != MONO_EXCEPTION_CLAUSE_FINALLY && clause->flags != MONO_EXCEPTION_CLAUSE_NONE) {
6849 set_failure (ctx, "non-finally/catch clause.");
6853 if (header->num_clauses || (cfg->method->iflags & METHOD_IMPL_ATTRIBUTE_NOINLINING) || cfg->no_inline)
6854 /* We can't handle inlined methods with clauses */
6855 LLVMAddFunctionAttr (method, LLVMNoInlineAttribute);
6857 if (linfo->rgctx_arg) {
6858 ctx->rgctx_arg = LLVMGetParam (method, linfo->rgctx_arg_pindex);
6859 ctx->rgctx_arg_pindex = linfo->rgctx_arg_pindex;
6861 * We mark the rgctx parameter with the inreg attribute, which is mapped to
6862 * MONO_ARCH_RGCTX_REG in the Mono calling convention in llvm, i.e.
6863 * CC_X86_64_Mono in X86CallingConv.td.
6865 if (!ctx->llvm_only)
6866 LLVMAddAttribute (ctx->rgctx_arg, LLVMInRegAttribute);
6867 LLVMSetValueName (ctx->rgctx_arg, "rgctx");
6869 ctx->rgctx_arg_pindex = -1;
6871 if (cfg->vret_addr) {
6872 values [cfg->vret_addr->dreg] = LLVMGetParam (method, linfo->vret_arg_pindex);
6873 LLVMSetValueName (values [cfg->vret_addr->dreg], "vret");
6874 if (linfo->ret.storage == LLVMArgVtypeByRef) {
6875 LLVMAddAttribute (LLVMGetParam (method, linfo->vret_arg_pindex), LLVMStructRetAttribute);
6876 LLVMAddAttribute (LLVMGetParam (method, linfo->vret_arg_pindex), LLVMNoAliasAttribute);
6881 ctx->this_arg_pindex = linfo->this_arg_pindex;
6882 ctx->this_arg = LLVMGetParam (method, linfo->this_arg_pindex);
6883 values [cfg->args [0]->dreg] = ctx->this_arg;
6884 LLVMSetValueName (values [cfg->args [0]->dreg], "this");
6887 names = g_new (char *, sig->param_count);
6888 mono_method_get_param_names (cfg->method, (const char **) names);
6890 /* Set parameter names/attributes */
6891 for (i = 0; i < sig->param_count; ++i) {
6892 LLVMArgInfo *ainfo = &linfo->args [i + sig->hasthis];
6894 int pindex = ainfo->pindex + ainfo->ndummy_fpargs;
6897 for (j = 0; j < ainfo->ndummy_fpargs; ++j) {
6898 name = g_strdup_printf ("dummy_%d_%d", i, j);
6899 LLVMSetValueName (LLVMGetParam (method, ainfo->pindex + j), name);
6903 if (ainfo->storage == LLVMArgVtypeInReg && ainfo->pair_storage [0] == LLVMArgNone && ainfo->pair_storage [1] == LLVMArgNone)
6906 values [cfg->args [i + sig->hasthis]->dreg] = LLVMGetParam (method, pindex);
6907 if (ainfo->storage == LLVMArgGsharedvtFixed || ainfo->storage == LLVMArgGsharedvtFixedVtype) {
6908 if (names [i] && names [i][0] != '\0')
6909 name = g_strdup_printf ("p_arg_%s", names [i]);
6911 name = g_strdup_printf ("p_arg_%d", i);
6913 if (names [i] && names [i][0] != '\0')
6914 name = g_strdup_printf ("arg_%s", names [i]);
6916 name = g_strdup_printf ("arg_%d", i);
6918 LLVMSetValueName (values [cfg->args [i + sig->hasthis]->dreg], name);
6920 if (ainfo->storage == LLVMArgVtypeByVal)
6921 LLVMAddAttribute (LLVMGetParam (method, pindex), LLVMByValAttribute);
6923 if (ainfo->storage == LLVMArgVtypeByRef) {
6925 cfg->args [i + sig->hasthis]->opcode = OP_VTARG_ADDR;
6930 if (ctx->module->emit_dwarf && cfg->compile_aot && mono_debug_enabled ()) {
6931 ctx->minfo = mono_debug_lookup_method (cfg->method);
6932 ctx->dbg_md = emit_dbg_subprogram (ctx, cfg, method, ctx->method_name);
6936 for (bb = cfg->bb_entry; bb; bb = bb->next_bb)
6937 max_block_num = MAX (max_block_num, bb->block_num);
6938 ctx->bblocks = bblocks = g_new0 (BBInfo, max_block_num + 1);
6940 /* Add branches between non-consecutive bblocks */
6941 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
6942 if (bb->last_ins && MONO_IS_COND_BRANCH_OP (bb->last_ins) &&
6943 bb->next_bb != bb->last_ins->inst_false_bb) {
6945 MonoInst *inst = (MonoInst*)mono_mempool_alloc0 (cfg->mempool, sizeof (MonoInst));
6946 inst->opcode = OP_BR;
6947 inst->inst_target_bb = bb->last_ins->inst_false_bb;
6948 mono_bblock_add_inst (bb, inst);
6953 * The INDIRECT flag added by OP_LDADDR inhibits optimizations, even if the LDADDR
6954 * was later optimized away, so clear these flags, and add them back for the still
6955 * present OP_LDADDR instructions.
6957 for (i = 0; i < cfg->next_vreg; ++i) {
6960 ins = get_vreg_to_inst (cfg, i);
6961 if (ins && ins != cfg->rgctx_var)
6962 ins->flags &= ~MONO_INST_INDIRECT;
6966 * Make a first pass over the code to precreate PHI nodes/set INDIRECT flags.
6968 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
6970 LLVMBuilderRef builder;
6972 char dname_buf[128];
6974 builder = create_builder (ctx);
6976 for (ins = bb->code; ins; ins = ins->next) {
6977 switch (ins->opcode) {
6982 LLVMTypeRef phi_type = llvm_type_to_stack_type (cfg, type_to_llvm_type (ctx, &ins->klass->byval_arg));
6987 if (ins->opcode == OP_VPHI) {
6988 /* Treat valuetype PHI nodes as operating on the address itself */
6989 g_assert (ins->klass);
6990 phi_type = LLVMPointerType (type_to_llvm_type (ctx, &ins->klass->byval_arg), 0);
6994 * Have to precreate these, as they can be referenced by
6995 * earlier instructions.
6997 sprintf (dname_buf, "t%d", ins->dreg);
6999 values [ins->dreg] = LLVMBuildPhi (builder, phi_type, dname);
7001 if (ins->opcode == OP_VPHI)
7002 ctx->addresses [ins->dreg] = values [ins->dreg];
7004 g_ptr_array_add (ctx->phi_values, values [ins->dreg]);
7007 * Set the expected type of the incoming arguments since these have
7008 * to have the same type.
7010 for (i = 0; i < ins->inst_phi_args [0]; i++) {
7011 int sreg1 = ins->inst_phi_args [i + 1];
7014 ctx->vreg_types [sreg1] = phi_type;
7019 ((MonoInst*)ins->inst_p0)->flags |= MONO_INST_INDIRECT;
7028 * Create an ordering for bblocks, use the depth first order first, then
7029 * put the exception handling bblocks last.
7031 for (bb_index = 0; bb_index < cfg->num_bblocks; ++bb_index) {
7032 bb = cfg->bblocks [bb_index];
7033 if (!(bb->region != -1 && !MONO_BBLOCK_IS_IN_REGION (bb, MONO_REGION_TRY))) {
7034 g_ptr_array_add (bblock_list, bb);
7035 bblocks [bb->block_num].added = TRUE;
7039 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
7040 if (!bblocks [bb->block_num].added)
7041 g_ptr_array_add (bblock_list, bb);
7045 * Second pass: generate code.
7048 LLVMBuilderRef entry_builder = create_builder (ctx);
7049 LLVMBasicBlockRef entry_bb = get_bb (ctx, cfg->bb_entry);
7050 LLVMPositionBuilderAtEnd (entry_builder, entry_bb);
7051 emit_entry_bb (ctx, entry_builder);
7053 // Make landing pads first
7054 ctx->exc_meta = g_hash_table_new_full (NULL, NULL, NULL, NULL);
7056 if (ctx->llvm_only) {
7057 size_t group_index = 0;
7058 while (group_index < cfg->header->num_clauses) {
7060 size_t cursor = group_index;
7061 while (cursor < cfg->header->num_clauses &&
7062 CLAUSE_START (&cfg->header->clauses [cursor]) == CLAUSE_START (&cfg->header->clauses [group_index]) &&
7063 CLAUSE_END (&cfg->header->clauses [cursor]) == CLAUSE_END (&cfg->header->clauses [group_index])) {
7068 LLVMBasicBlockRef lpad_bb = emit_landing_pad (ctx, group_index, count);
7069 intptr_t key = CLAUSE_END (&cfg->header->clauses [group_index]);
7070 g_hash_table_insert (ctx->exc_meta, (gpointer)key, lpad_bb);
7072 group_index = cursor;
7076 for (bb_index = 0; bb_index < bblock_list->len; ++bb_index) {
7077 bb = (MonoBasicBlock*)g_ptr_array_index (bblock_list, bb_index);
7079 // Prune unreachable mono BBs.
7080 if (!(bb == cfg->bb_entry || bb->in_count > 0))
7083 process_bb (ctx, bb);
7087 g_hash_table_destroy (ctx->exc_meta);
7089 mono_memory_barrier ();
7091 /* Add incoming phi values */
7092 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
7093 GSList *l, *ins_list;
7095 ins_list = bblocks [bb->block_num].phi_nodes;
7097 for (l = ins_list; l; l = l->next) {
7098 PhiNode *node = (PhiNode*)l->data;
7099 MonoInst *phi = node->phi;
7100 int sreg1 = node->sreg;
7101 LLVMBasicBlockRef in_bb;
7106 in_bb = get_end_bb (ctx, node->in_bb);
7108 if (ctx->unreachable [node->in_bb->block_num])
7111 if (!values [sreg1]) {
7112 /* Can happen with values in EH clauses */
7113 set_failure (ctx, "incoming phi sreg1");
7117 if (phi->opcode == OP_VPHI) {
7118 g_assert (LLVMTypeOf (ctx->addresses [sreg1]) == LLVMTypeOf (values [phi->dreg]));
7119 LLVMAddIncoming (values [phi->dreg], &ctx->addresses [sreg1], &in_bb, 1);
7121 if (LLVMTypeOf (values [sreg1]) != LLVMTypeOf (values [phi->dreg])) {
7122 set_failure (ctx, "incoming phi arg type mismatch");
7125 g_assert (LLVMTypeOf (values [sreg1]) == LLVMTypeOf (values [phi->dreg]));
7126 LLVMAddIncoming (values [phi->dreg], &values [sreg1], &in_bb, 1);
7131 /* Nullify empty phi instructions */
7132 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
7133 GSList *l, *ins_list;
7135 ins_list = bblocks [bb->block_num].phi_nodes;
7137 for (l = ins_list; l; l = l->next) {
7138 PhiNode *node = (PhiNode*)l->data;
7139 MonoInst *phi = node->phi;
7140 LLVMValueRef phi_ins = values [phi->dreg];
7143 /* Already removed */
7146 if (LLVMCountIncoming (phi_ins) == 0) {
7147 mono_llvm_replace_uses_of (phi_ins, LLVMConstNull (LLVMTypeOf (phi_ins)));
7148 LLVMInstructionEraseFromParent (phi_ins);
7149 values [phi->dreg] = NULL;
7154 /* Create the SWITCH statements for ENDFINALLY instructions */
7155 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
7156 BBInfo *info = &bblocks [bb->block_num];
7158 for (l = info->endfinally_switch_ins_list; l; l = l->next) {
7159 LLVMValueRef switch_ins = (LLVMValueRef)l->data;
7160 GSList *bb_list = info->call_handler_return_bbs;
7162 for (i = 0; i < g_slist_length (bb_list); ++i)
7163 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), i + 1, FALSE), (LLVMBasicBlockRef)(g_slist_nth (bb_list, i)->data));
7167 /* Initialize the method if needed */
7168 if (cfg->compile_aot && ctx->llvm_only) {
7169 // FIXME: Add more shared got entries
7170 ctx->builder = create_builder (ctx);
7171 LLVMPositionBuilderAtEnd (ctx->builder, ctx->init_bb);
7173 ctx->module->max_method_idx = MAX (ctx->module->max_method_idx, cfg->method_index);
7175 // FIXME: beforefieldinit
7176 if (ctx->has_got_access || mono_class_get_cctor (cfg->method->klass)) {
7178 * linkonce methods shouldn't have initialization,
7179 * because they might belong to assemblies which
7180 * haven't been loaded yet.
7182 g_assert (!ctx->is_linkonce);
7183 emit_init_method (ctx);
7185 LLVMBuildBr (ctx->builder, ctx->inited_bb);
7189 if (cfg->llvm_only) {
7190 GHashTableIter iter;
7192 GSList *callers, *l, *l2;
7195 * Add the contents of ctx->method_to_callers to module->method_to_callers.
7196 * We can't do this earlier, as it contains llvm instructions which can be
7197 * freed if compilation fails.
7198 * FIXME: Get rid of this when all methods can be llvm compiled.
7200 g_hash_table_iter_init (&iter, ctx->method_to_callers);
7201 while (g_hash_table_iter_next (&iter, (void**)&method, (void**)&callers)) {
7202 for (l = callers; l; l = l->next) {
7203 l2 = (GSList*)g_hash_table_lookup (ctx->module->method_to_callers, method);
7204 l2 = g_slist_prepend (l2, l->data);
7205 g_hash_table_insert (ctx->module->method_to_callers, method, l2);
7210 if (cfg->verbose_level > 1)
7211 mono_llvm_dump_value (method);
7213 if (cfg->compile_aot && !cfg->llvm_only)
7214 mark_as_used (ctx->module, method);
7216 if (!cfg->llvm_only) {
7217 LLVMValueRef md_args [16];
7218 LLVMValueRef md_node;
7221 if (cfg->compile_aot)
7222 method_index = mono_aot_get_method_index (cfg->orig_method);
7225 md_args [0] = LLVMMDString (ctx->method_name, strlen (ctx->method_name));
7226 md_args [1] = LLVMConstInt (LLVMInt32Type (), method_index, FALSE);
7227 md_node = LLVMMDNode (md_args, 2);
7228 LLVMAddNamedMetadataOperand (lmodule, "mono.function_indexes", md_node);
7229 //LLVMSetMetadata (method, md_kind, LLVMMDNode (&md_arg, 1));
7232 if (cfg->compile_aot) {
7233 /* Don't generate native code, keep the LLVM IR */
7234 if (cfg->verbose_level)
7235 printf ("%s emitted as %s\n", mono_method_full_name (cfg->method, TRUE), ctx->method_name);
7237 #if LLVM_API_VERSION < 100
7238 /* VerifyFunction can't handle some of the debug info created by DIBuilder in llvm 3.9 */
7239 int err = LLVMVerifyFunction(ctx->lmethod, LLVMPrintMessageAction);
7240 g_assert (err == 0);
7243 //LLVMVerifyFunction(method, 0);
7244 #if LLVM_API_VERSION > 100
7245 MonoDomain *domain = mono_domain_get ();
7246 MonoJitDomainInfo *domain_info;
7247 int nvars = g_hash_table_size (ctx->jit_callees);
7248 LLVMValueRef *callee_vars = g_new0 (LLVMValueRef, nvars);
7249 gpointer *callee_addrs = g_new0 (gpointer, nvars);
7250 GHashTableIter iter;
7256 * Compute the addresses of the LLVM globals pointing to the
7257 * methods called by the current method. Pass it to the trampoline
7258 * code so it can update them after their corresponding method was
7261 g_hash_table_iter_init (&iter, ctx->jit_callees);
7263 while (g_hash_table_iter_next (&iter, NULL, (void**)&var))
7264 callee_vars [i ++] = var;
7266 cfg->native_code = mono_llvm_compile_method (ctx->module->mono_ee, ctx->lmethod, nvars, callee_vars, callee_addrs, &eh_frame);
7268 decode_llvm_eh_info (ctx, eh_frame);
7270 mono_domain_lock (domain);
7271 domain_info = domain_jit_info (domain);
7272 if (!domain_info->llvm_jit_callees)
7273 domain_info->llvm_jit_callees = g_hash_table_new (NULL, NULL);
7274 g_hash_table_iter_init (&iter, ctx->jit_callees);
7276 while (g_hash_table_iter_next (&iter, (void**)&callee, (void**)&var)) {
7277 GSList *addrs = g_hash_table_lookup (domain_info->llvm_jit_callees, callee);
7278 addrs = g_slist_prepend (addrs, callee_addrs [i]);
7279 g_hash_table_insert (domain_info->llvm_jit_callees, callee, addrs);
7282 mono_domain_unlock (domain);
7284 mono_llvm_optimize_method (ctx->module->mono_ee, ctx->lmethod);
7286 if (cfg->verbose_level > 1)
7287 mono_llvm_dump_value (ctx->lmethod);
7289 cfg->native_code = (unsigned char*)LLVMGetPointerToGlobal (ctx->module->ee, ctx->lmethod);
7291 /* Set by emit_cb */
7292 g_assert (cfg->code_len);
7296 if (ctx->module->method_to_lmethod)
7297 g_hash_table_insert (ctx->module->method_to_lmethod, cfg->method, ctx->lmethod);
7298 if (ctx->module->idx_to_lmethod)
7299 g_hash_table_insert (ctx->module->idx_to_lmethod, GINT_TO_POINTER (cfg->method_index), ctx->lmethod);
7301 if (ctx->llvm_only && cfg->orig_method->klass->valuetype && !(cfg->orig_method->flags & METHOD_ATTRIBUTE_STATIC))
7302 emit_unbox_tramp (ctx, ctx->method_name, ctx->method_type, ctx->lmethod, cfg->method_index);
7306 * mono_llvm_create_vars:
7308 * Same as mono_arch_create_vars () for LLVM.
7311 mono_llvm_create_vars (MonoCompile *cfg)
7313 MonoMethodSignature *sig;
7315 sig = mono_method_signature (cfg->method);
7316 if (cfg->gsharedvt && cfg->llvm_only) {
7317 if (mini_is_gsharedvt_variable_signature (sig) && sig->ret->type != MONO_TYPE_VOID) {
7318 cfg->vret_addr = mono_compile_create_var (cfg, &mono_get_intptr_class ()->byval_arg, OP_ARG);
7319 if (G_UNLIKELY (cfg->verbose_level > 1)) {
7320 printf ("vret_addr = ");
7321 mono_print_ins (cfg->vret_addr);
7325 mono_arch_create_vars (cfg);
7330 * mono_llvm_emit_call:
7332 * Same as mono_arch_emit_call () for LLVM.
7335 mono_llvm_emit_call (MonoCompile *cfg, MonoCallInst *call)
7338 MonoMethodSignature *sig;
7339 int i, n, stack_size;
7344 sig = call->signature;
7345 n = sig->param_count + sig->hasthis;
7347 call->cinfo = get_llvm_call_info (cfg, sig);
7349 if (cfg->disable_llvm)
7352 if (sig->call_convention == MONO_CALL_VARARG) {
7353 cfg->exception_message = g_strdup ("varargs");
7354 cfg->disable_llvm = TRUE;
7357 for (i = 0; i < n; ++i) {
7360 ainfo = call->cinfo->args + i;
7362 in = call->args [i];
7364 /* Simply remember the arguments */
7365 switch (ainfo->storage) {
7366 case LLVMArgNormal: {
7367 MonoType *t = (sig->hasthis && i == 0) ? &mono_get_intptr_class ()->byval_arg : ainfo->type;
7370 opcode = mono_type_to_regmove (cfg, t);
7371 if (opcode == OP_FMOVE) {
7372 MONO_INST_NEW (cfg, ins, OP_FMOVE);
7373 ins->dreg = mono_alloc_freg (cfg);
7374 } else if (opcode == OP_LMOVE) {
7375 MONO_INST_NEW (cfg, ins, OP_LMOVE);
7376 ins->dreg = mono_alloc_lreg (cfg);
7377 } else if (opcode == OP_RMOVE) {
7378 MONO_INST_NEW (cfg, ins, OP_RMOVE);
7379 ins->dreg = mono_alloc_freg (cfg);
7381 MONO_INST_NEW (cfg, ins, OP_MOVE);
7382 ins->dreg = mono_alloc_ireg (cfg);
7384 ins->sreg1 = in->dreg;
7387 case LLVMArgVtypeByVal:
7388 case LLVMArgVtypeByRef:
7389 case LLVMArgVtypeInReg:
7390 case LLVMArgVtypeAsScalar:
7391 case LLVMArgAsIArgs:
7392 case LLVMArgAsFpArgs:
7393 case LLVMArgGsharedvtVariable:
7394 case LLVMArgGsharedvtFixed:
7395 case LLVMArgGsharedvtFixedVtype:
7396 MONO_INST_NEW (cfg, ins, OP_LLVM_OUTARG_VT);
7397 ins->dreg = mono_alloc_ireg (cfg);
7398 ins->sreg1 = in->dreg;
7399 ins->inst_p0 = mono_mempool_alloc0 (cfg->mempool, sizeof (LLVMArgInfo));
7400 memcpy (ins->inst_p0, ainfo, sizeof (LLVMArgInfo));
7401 ins->inst_vtype = ainfo->type;
7402 ins->klass = mono_class_from_mono_type (ainfo->type);
7405 cfg->exception_message = g_strdup ("ainfo->storage");
7406 cfg->disable_llvm = TRUE;
7410 if (!cfg->disable_llvm) {
7411 MONO_ADD_INS (cfg->cbb, ins);
7412 mono_call_inst_add_outarg_reg (cfg, call, ins->dreg, 0, FALSE);
7417 static unsigned char*
7418 alloc_cb (LLVMValueRef function, int size)
7422 cfg = (MonoCompile*)mono_native_tls_get_value (current_cfg_tls_id);
7426 return (unsigned char*)mono_domain_code_reserve (cfg->domain, size);
7428 return (unsigned char*)mono_domain_code_reserve (mono_domain_get (), size);
7433 emitted_cb (LLVMValueRef function, void *start, void *end)
7437 cfg = (MonoCompile*)mono_native_tls_get_value (current_cfg_tls_id);
7439 cfg->code_len = (guint8*)end - (guint8*)start;
7443 exception_cb (void *data)
7446 MonoJitExceptionInfo *ei;
7447 guint32 ei_len, i, j, nested_len, nindex;
7448 gpointer *type_info;
7449 int this_reg, this_offset;
7451 cfg = (MonoCompile*)mono_native_tls_get_value (current_cfg_tls_id);
7455 * data points to a DWARF FDE structure, convert it to our unwind format and
7457 * An alternative would be to save it directly, and modify our unwinder to work
7460 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);
7461 if (cfg->verbose_level > 1)
7462 mono_print_unwind_info (cfg->encoded_unwind_ops, cfg->encoded_unwind_ops_len);
7464 /* Count nested clauses */
7466 for (i = 0; i < ei_len; ++i) {
7467 gint32 cindex1 = *(gint32*)type_info [i];
7468 MonoExceptionClause *clause1 = &cfg->header->clauses [cindex1];
7470 for (j = 0; j < cfg->header->num_clauses; ++j) {
7472 MonoExceptionClause *clause2 = &cfg->header->clauses [cindex2];
7474 if (cindex1 != cindex2 && clause1->try_offset >= clause2->try_offset && clause1->handler_offset <= clause2->handler_offset) {
7480 cfg->llvm_ex_info = (MonoJitExceptionInfo*)mono_mempool_alloc0 (cfg->mempool, (ei_len + nested_len) * sizeof (MonoJitExceptionInfo));
7481 cfg->llvm_ex_info_len = ei_len + nested_len;
7482 memcpy (cfg->llvm_ex_info, ei, ei_len * sizeof (MonoJitExceptionInfo));
7483 /* Fill the rest of the information from the type info */
7484 for (i = 0; i < ei_len; ++i) {
7485 gint32 clause_index = *(gint32*)type_info [i];
7486 MonoExceptionClause *clause = &cfg->header->clauses [clause_index];
7488 cfg->llvm_ex_info [i].flags = clause->flags;
7489 cfg->llvm_ex_info [i].data.catch_class = clause->data.catch_class;
7490 cfg->llvm_ex_info [i].clause_index = clause_index;
7494 * For nested clauses, the LLVM produced exception info associates the try interval with
7495 * the innermost handler, while mono expects it to be associated with all nesting clauses.
7496 * So add new clauses which use the IL info (catch class etc.) from the nesting clause,
7497 * and everything else from the nested clause.
7500 for (i = 0; i < ei_len; ++i) {
7501 gint32 cindex1 = *(gint32*)type_info [i];
7502 MonoExceptionClause *clause1 = &cfg->header->clauses [cindex1];
7504 for (j = 0; j < cfg->header->num_clauses; ++j) {
7506 MonoExceptionClause *clause2 = &cfg->header->clauses [cindex2];
7507 MonoJitExceptionInfo *nesting_ei, *nested_ei;
7509 if (cindex1 != cindex2 && clause1->try_offset >= clause2->try_offset && clause1->handler_offset <= clause2->handler_offset) {
7510 /* clause1 is the nested clause */
7511 nested_ei = &cfg->llvm_ex_info [i];
7512 nesting_ei = &cfg->llvm_ex_info [nindex];
7515 memcpy (nesting_ei, nested_ei, sizeof (MonoJitExceptionInfo));
7517 nesting_ei->flags = clause2->flags;
7518 nesting_ei->data.catch_class = clause2->data.catch_class;
7519 nesting_ei->clause_index = cindex2;
7523 g_assert (nindex == ei_len + nested_len);
7524 cfg->llvm_this_reg = this_reg;
7525 cfg->llvm_this_offset = this_offset;
7527 /* type_info [i] is cfg mempool allocated, no need to free it */
7533 #if LLVM_API_VERSION > 100
7535 * decode_llvm_eh_info:
7537 * Decode the EH table emitted by llvm in jit mode, and store
7538 * the result into cfg.
7541 decode_llvm_eh_info (EmitContext *ctx, gpointer eh_frame)
7543 MonoCompile *cfg = ctx->cfg;
7546 MonoLLVMFDEInfo info;
7547 MonoJitExceptionInfo *ei;
7548 guint8 *p = eh_frame;
7549 int version, fde_count, fde_offset;
7550 guint32 ei_len, i, nested_len;
7551 gpointer *type_info;
7555 * Decode the one element EH table emitted by the MonoException class
7559 /* Similar to decode_llvm_mono_eh_frame () in aot-runtime.c */
7562 g_assert (version == 3);
7565 p = (guint8 *)ALIGN_PTR_TO (p, 4);
7567 fde_count = *(guint32*)p;
7571 g_assert (fde_count <= 2);
7573 /* The first entry is the real method */
7574 g_assert (table [0] == 1);
7575 fde_offset = table [1];
7576 table += fde_count * 2;
7578 cfg->code_len = table [0];
7579 fde_len = table [1] - fde_offset;
7582 fde = (guint8*)eh_frame + fde_offset;
7583 cie = (guint8*)table;
7585 mono_unwind_decode_llvm_mono_fde (fde, fde_len, cie, cfg->native_code, &info);
7587 cfg->encoded_unwind_ops = info.unw_info;
7588 cfg->encoded_unwind_ops_len = info.unw_info_len;
7589 if (cfg->verbose_level > 1)
7590 mono_print_unwind_info (cfg->encoded_unwind_ops, cfg->encoded_unwind_ops_len);
7591 if (info.this_reg != -1) {
7592 cfg->llvm_this_reg = info.this_reg;
7593 cfg->llvm_this_offset = info.this_offset;
7597 ei_len = info.ex_info_len;
7598 type_info = info.type_info;
7600 // Nested clauses are currently disabled
7603 cfg->llvm_ex_info = (MonoJitExceptionInfo*)mono_mempool_alloc0 (cfg->mempool, (ei_len + nested_len) * sizeof (MonoJitExceptionInfo));
7604 cfg->llvm_ex_info_len = ei_len + nested_len;
7605 memcpy (cfg->llvm_ex_info, ei, ei_len * sizeof (MonoJitExceptionInfo));
7606 /* Fill the rest of the information from the type info */
7607 for (i = 0; i < ei_len; ++i) {
7608 gint32 clause_index = *(gint32*)type_info [i];
7609 MonoExceptionClause *clause = &cfg->header->clauses [clause_index];
7611 cfg->llvm_ex_info [i].flags = clause->flags;
7612 cfg->llvm_ex_info [i].data.catch_class = clause->data.catch_class;
7613 cfg->llvm_ex_info [i].clause_index = clause_index;
7619 dlsym_cb (const char *name, void **symbol)
7625 if (!strcmp (name, "__bzero")) {
7626 *symbol = (void*)bzero;
7628 current = mono_dl_open (NULL, 0, NULL);
7631 err = mono_dl_symbol (current, name, symbol);
7633 mono_dl_close (current);
7635 #ifdef MONO_ARCH_HAVE_CREATE_LLVM_NATIVE_THUNK
7636 *symbol = (char*)mono_arch_create_llvm_native_thunk (mono_domain_get (), (guint8*)(*symbol));
7642 AddFunc (LLVMModuleRef module, const char *name, LLVMTypeRef ret_type, LLVMTypeRef *param_types, int nparams)
7644 LLVMAddFunction (module, name, LLVMFunctionType (ret_type, param_types, nparams, FALSE));
7648 AddFunc2 (LLVMModuleRef module, const char *name, LLVMTypeRef ret_type, LLVMTypeRef param_type1, LLVMTypeRef param_type2)
7650 LLVMTypeRef param_types [4];
7652 param_types [0] = param_type1;
7653 param_types [1] = param_type2;
7655 AddFunc (module, name, ret_type, param_types, 2);
7661 INTRINS_SADD_OVF_I32,
7662 INTRINS_UADD_OVF_I32,
7663 INTRINS_SSUB_OVF_I32,
7664 INTRINS_USUB_OVF_I32,
7665 INTRINS_SMUL_OVF_I32,
7666 INTRINS_UMUL_OVF_I32,
7667 INTRINS_SADD_OVF_I64,
7668 INTRINS_UADD_OVF_I64,
7669 INTRINS_SSUB_OVF_I64,
7670 INTRINS_USUB_OVF_I64,
7671 INTRINS_SMUL_OVF_I64,
7672 INTRINS_UMUL_OVF_I64,
7679 #if defined(TARGET_AMD64) || defined(TARGET_X86)
7680 INTRINS_SSE_PMOVMSKB,
7681 INTRINS_SSE_PSRLI_W,
7682 INTRINS_SSE_PSRAI_W,
7683 INTRINS_SSE_PSLLI_W,
7684 INTRINS_SSE_PSRLI_D,
7685 INTRINS_SSE_PSRAI_D,
7686 INTRINS_SSE_PSLLI_D,
7687 INTRINS_SSE_PSRLI_Q,
7688 INTRINS_SSE_PSLLI_Q,
7689 INTRINS_SSE_SQRT_PD,
7690 INTRINS_SSE_SQRT_PS,
7691 INTRINS_SSE_RSQRT_PS,
7693 INTRINS_SSE_CVTTPD2DQ,
7694 INTRINS_SSE_CVTTPS2DQ,
7695 INTRINS_SSE_CVTDQ2PD,
7696 INTRINS_SSE_CVTDQ2PS,
7697 INTRINS_SSE_CVTPD2DQ,
7698 INTRINS_SSE_CVTPS2DQ,
7699 INTRINS_SSE_CVTPD2PS,
7700 INTRINS_SSE_CVTPS2PD,
7703 INTRINS_SSE_PACKSSWB,
7704 INTRINS_SSE_PACKUSWB,
7705 INTRINS_SSE_PACKSSDW,
7706 INTRINS_SSE_PACKUSDW,
7711 INTRINS_SSE_ADDSUBPS,
7716 INTRINS_SSE_ADDSUBPD,
7724 INTRINS_SSE_PADDUSW,
7725 INTRINS_SSE_PSUBUSW,
7733 INTRINS_SSE_PADDUSB,
7734 INTRINS_SSE_PSUBUSB,
7746 static IntrinsicDesc intrinsics[] = {
7747 {INTRINS_MEMSET, "llvm.memset.p0i8.i32"},
7748 {INTRINS_MEMCPY, "llvm.memcpy.p0i8.p0i8.i32"},
7749 {INTRINS_SADD_OVF_I32, "llvm.sadd.with.overflow.i32"},
7750 {INTRINS_UADD_OVF_I32, "llvm.uadd.with.overflow.i32"},
7751 {INTRINS_SSUB_OVF_I32, "llvm.ssub.with.overflow.i32"},
7752 {INTRINS_USUB_OVF_I32, "llvm.usub.with.overflow.i32"},
7753 {INTRINS_SMUL_OVF_I32, "llvm.smul.with.overflow.i32"},
7754 {INTRINS_UMUL_OVF_I32, "llvm.umul.with.overflow.i32"},
7755 {INTRINS_SADD_OVF_I64, "llvm.sadd.with.overflow.i64"},
7756 {INTRINS_UADD_OVF_I64, "llvm.uadd.with.overflow.i64"},
7757 {INTRINS_SSUB_OVF_I64, "llvm.ssub.with.overflow.i64"},
7758 {INTRINS_USUB_OVF_I64, "llvm.usub.with.overflow.i64"},
7759 {INTRINS_SMUL_OVF_I64, "llvm.smul.with.overflow.i64"},
7760 {INTRINS_UMUL_OVF_I64, "llvm.umul.with.overflow.i64"},
7761 {INTRINS_SIN, "llvm.sin.f64"},
7762 {INTRINS_COS, "llvm.cos.f64"},
7763 {INTRINS_SQRT, "llvm.sqrt.f64"},
7764 /* This isn't an intrinsic, instead llvm seems to special case it by name */
7765 {INTRINS_FABS, "fabs"},
7766 {INTRINS_EXPECT_I8, "llvm.expect.i8"},
7767 {INTRINS_EXPECT_I1, "llvm.expect.i1"},
7768 #if defined(TARGET_AMD64) || defined(TARGET_X86)
7769 {INTRINS_SSE_PMOVMSKB, "llvm.x86.sse2.pmovmskb.128"},
7770 {INTRINS_SSE_PSRLI_W, "llvm.x86.sse2.psrli.w"},
7771 {INTRINS_SSE_PSRAI_W, "llvm.x86.sse2.psrai.w"},
7772 {INTRINS_SSE_PSLLI_W, "llvm.x86.sse2.pslli.w"},
7773 {INTRINS_SSE_PSRLI_D, "llvm.x86.sse2.psrli.d"},
7774 {INTRINS_SSE_PSRAI_D, "llvm.x86.sse2.psrai.d"},
7775 {INTRINS_SSE_PSLLI_D, "llvm.x86.sse2.pslli.d"},
7776 {INTRINS_SSE_PSRLI_Q, "llvm.x86.sse2.psrli.q"},
7777 {INTRINS_SSE_PSLLI_Q, "llvm.x86.sse2.pslli.q"},
7778 {INTRINS_SSE_SQRT_PD, "llvm.x86.sse2.sqrt.pd"},
7779 {INTRINS_SSE_SQRT_PS, "llvm.x86.sse.sqrt.ps"},
7780 {INTRINS_SSE_RSQRT_PS, "llvm.x86.sse.rsqrt.ps"},
7781 {INTRINS_SSE_RCP_PS, "llvm.x86.sse.rcp.ps"},
7782 {INTRINS_SSE_CVTTPD2DQ, "llvm.x86.sse2.cvttpd2dq"},
7783 {INTRINS_SSE_CVTTPS2DQ, "llvm.x86.sse2.cvttps2dq"},
7784 {INTRINS_SSE_CVTDQ2PD, "llvm.x86.sse2.cvtdq2pd"},
7785 {INTRINS_SSE_CVTDQ2PS, "llvm.x86.sse2.cvtdq2ps"},
7786 {INTRINS_SSE_CVTPD2DQ, "llvm.x86.sse2.cvtpd2dq"},
7787 {INTRINS_SSE_CVTPS2DQ, "llvm.x86.sse2.cvtps2dq"},
7788 {INTRINS_SSE_CVTPD2PS, "llvm.x86.sse2.cvtpd2ps"},
7789 {INTRINS_SSE_CVTPS2PD, "llvm.x86.sse2.cvtps2pd"},
7790 {INTRINS_SSE_CMPPD, "llvm.x86.sse2.cmp.pd"},
7791 {INTRINS_SSE_CMPPS, "llvm.x86.sse.cmp.ps"},
7792 {INTRINS_SSE_PACKSSWB, "llvm.x86.sse2.packsswb.128"},
7793 {INTRINS_SSE_PACKUSWB, "llvm.x86.sse2.packuswb.128"},
7794 {INTRINS_SSE_PACKSSDW, "llvm.x86.sse2.packssdw.128"},
7795 {INTRINS_SSE_PACKUSDW, "llvm.x86.sse41.packusdw"},
7796 {INTRINS_SSE_MINPS, "llvm.x86.sse.min.ps"},
7797 {INTRINS_SSE_MAXPS, "llvm.x86.sse.max.ps"},
7798 {INTRINS_SSE_HADDPS, "llvm.x86.sse3.hadd.ps"},
7799 {INTRINS_SSE_HSUBPS, "llvm.x86.sse3.hsub.ps"},
7800 {INTRINS_SSE_ADDSUBPS, "llvm.x86.sse3.addsub.ps"},
7801 {INTRINS_SSE_MINPD, "llvm.x86.sse2.min.pd"},
7802 {INTRINS_SSE_MAXPD, "llvm.x86.sse2.max.pd"},
7803 {INTRINS_SSE_HADDPD, "llvm.x86.sse3.hadd.pd"},
7804 {INTRINS_SSE_HSUBPD, "llvm.x86.sse3.hsub.pd"},
7805 {INTRINS_SSE_ADDSUBPD, "llvm.x86.sse3.addsub.pd"},
7806 {INTRINS_SSE_PMINUD, "llvm.x86.sse41.pminud"},
7807 {INTRINS_SSE_PMAXUD, "llvm.x86.sse41.pmaxud"},
7808 {INTRINS_SSE_PMINUW, "llvm.x86.sse41.pminuw"},
7809 {INTRINS_SSE_PMINSW, "llvm.x86.sse2.pmins.w"},
7810 {INTRINS_SSE_PMAXUW, "llvm.x86.sse41.pmaxuw"},
7811 {INTRINS_SSE_PADDSW, "llvm.x86.sse2.padds.w"},
7812 {INTRINS_SSE_PSUBSW, "llvm.x86.sse2.psubs.w"},
7813 {INTRINS_SSE_PADDUSW, "llvm.x86.sse2.paddus.w"},
7814 {INTRINS_SSE_PSUBUSW, "llvm.x86.sse2.psubus.w"},
7815 {INTRINS_SSE_PAVGW, "llvm.x86.sse2.pavg.w"},
7816 {INTRINS_SSE_PMULHW, "llvm.x86.sse2.pmulh.w"},
7817 {INTRINS_SSE_PMULHU, "llvm.x86.sse2.pmulhu.w"},
7818 {INTRINS_SSE_PMINUB, "llvm.x86.sse2.pminu.b"},
7819 {INTRINS_SSE_PMAXUB, "llvm.x86.sse2.pmaxu.b"},
7820 {INTRINS_SE_PADDSB, "llvm.x86.sse2.padds.b"},
7821 {INTRINS_SSE_PSUBSB, "llvm.x86.sse2.psubs.b"},
7822 {INTRINS_SSE_PADDUSB, "llvm.x86.sse2.paddus.b"},
7823 {INTRINS_SSE_PSUBUSB, "llvm.x86.sse2.psubus.b"},
7824 {INTRINS_SSE_PAVGB, "llvm.x86.sse2.pavg.b"},
7825 {INTRINS_SSE_PAUSE, "llvm.x86.sse2.pause"}
7830 add_sse_binary (LLVMModuleRef module, const char *name, int type)
7832 LLVMTypeRef ret_type = type_to_simd_type (type);
7833 AddFunc2 (module, name, ret_type, ret_type, ret_type);
7837 add_intrinsic (LLVMModuleRef module, int id)
7840 #if defined(TARGET_AMD64) || defined(TARGET_X86)
7841 LLVMTypeRef ret_type, arg_types [16];
7844 name = g_hash_table_lookup (intrins_id_to_name, GINT_TO_POINTER (id));
7848 case INTRINS_MEMSET: {
7849 LLVMTypeRef params [] = { LLVMPointerType (LLVMInt8Type (), 0), LLVMInt8Type (), LLVMInt32Type (), LLVMInt32Type (), LLVMInt1Type () };
7851 AddFunc (module, name, LLVMVoidType (), params, 5);
7854 case INTRINS_MEMCPY: {
7855 LLVMTypeRef params [] = { LLVMPointerType (LLVMInt8Type (), 0), LLVMPointerType (LLVMInt8Type (), 0), LLVMInt32Type (), LLVMInt32Type (), LLVMInt1Type () };
7857 AddFunc (module, name, LLVMVoidType (), params, 5);
7860 case INTRINS_SADD_OVF_I32:
7861 case INTRINS_UADD_OVF_I32:
7862 case INTRINS_SSUB_OVF_I32:
7863 case INTRINS_USUB_OVF_I32:
7864 case INTRINS_SMUL_OVF_I32:
7865 case INTRINS_UMUL_OVF_I32: {
7866 LLVMTypeRef ovf_res_i32 [] = { LLVMInt32Type (), LLVMInt1Type () };
7867 LLVMTypeRef params [] = { LLVMInt32Type (), LLVMInt32Type () };
7868 LLVMTypeRef ret_type = LLVMStructType (ovf_res_i32, 2, FALSE);
7870 AddFunc (module, name, ret_type, params, 2);
7873 case INTRINS_SADD_OVF_I64:
7874 case INTRINS_UADD_OVF_I64:
7875 case INTRINS_SSUB_OVF_I64:
7876 case INTRINS_USUB_OVF_I64:
7877 case INTRINS_SMUL_OVF_I64:
7878 case INTRINS_UMUL_OVF_I64: {
7879 LLVMTypeRef ovf_res_i64 [] = { LLVMInt64Type (), LLVMInt1Type () };
7880 LLVMTypeRef params [] = { LLVMInt64Type (), LLVMInt64Type () };
7881 LLVMTypeRef ret_type = LLVMStructType (ovf_res_i64, 2, FALSE);
7883 AddFunc (module, name, ret_type, params, 2);
7889 case INTRINS_FABS: {
7890 LLVMTypeRef params [] = { LLVMDoubleType () };
7892 AddFunc (module, name, LLVMDoubleType (), params, 1);
7895 case INTRINS_EXPECT_I8:
7896 AddFunc2 (module, name, LLVMInt8Type (), LLVMInt8Type (), LLVMInt8Type ());
7898 case INTRINS_EXPECT_I1:
7899 AddFunc2 (module, name, LLVMInt1Type (), LLVMInt1Type (), LLVMInt1Type ());
7901 #if defined(TARGET_AMD64) || defined(TARGET_X86)
7902 case INTRINS_SSE_PMOVMSKB:
7904 ret_type = LLVMInt32Type ();
7905 arg_types [0] = type_to_simd_type (MONO_TYPE_I1);
7906 AddFunc (module, name, ret_type, arg_types, 1);
7908 case INTRINS_SSE_PSRLI_W:
7909 case INTRINS_SSE_PSRAI_W:
7910 case INTRINS_SSE_PSLLI_W:
7912 ret_type = type_to_simd_type (MONO_TYPE_I2);
7913 arg_types [0] = ret_type;
7914 arg_types [1] = LLVMInt32Type ();
7915 AddFunc (module, name, ret_type, arg_types, 2);
7917 case INTRINS_SSE_PSRLI_D:
7918 case INTRINS_SSE_PSRAI_D:
7919 case INTRINS_SSE_PSLLI_D:
7920 ret_type = type_to_simd_type (MONO_TYPE_I4);
7921 arg_types [0] = ret_type;
7922 arg_types [1] = LLVMInt32Type ();
7923 AddFunc (module, name, ret_type, arg_types, 2);
7925 case INTRINS_SSE_PSRLI_Q:
7926 case INTRINS_SSE_PSLLI_Q:
7927 ret_type = type_to_simd_type (MONO_TYPE_I8);
7928 arg_types [0] = ret_type;
7929 arg_types [1] = LLVMInt32Type ();
7930 AddFunc (module, name, ret_type, arg_types, 2);
7932 case INTRINS_SSE_SQRT_PD:
7934 ret_type = type_to_simd_type (MONO_TYPE_R8);
7935 arg_types [0] = ret_type;
7936 AddFunc (module, name, ret_type, arg_types, 1);
7938 case INTRINS_SSE_SQRT_PS:
7939 ret_type = type_to_simd_type (MONO_TYPE_R4);
7940 arg_types [0] = ret_type;
7941 AddFunc (module, name, ret_type, arg_types, 1);
7943 case INTRINS_SSE_RSQRT_PS:
7944 ret_type = type_to_simd_type (MONO_TYPE_R4);
7945 arg_types [0] = ret_type;
7946 AddFunc (module, name, ret_type, arg_types, 1);
7948 case INTRINS_SSE_RCP_PS:
7949 ret_type = type_to_simd_type (MONO_TYPE_R4);
7950 arg_types [0] = ret_type;
7951 AddFunc (module, name, ret_type, arg_types, 1);
7953 case INTRINS_SSE_CVTTPD2DQ:
7954 ret_type = type_to_simd_type (MONO_TYPE_I4);
7955 arg_types [0] = type_to_simd_type (MONO_TYPE_R8);
7956 AddFunc (module, name, ret_type, arg_types, 1);
7958 case INTRINS_SSE_CVTTPS2DQ:
7959 ret_type = type_to_simd_type (MONO_TYPE_I4);
7960 arg_types [0] = type_to_simd_type (MONO_TYPE_R4);
7961 AddFunc (module, name, ret_type, arg_types, 1);
7963 case INTRINS_SSE_CVTDQ2PD:
7964 /* Conversion ops */
7965 ret_type = type_to_simd_type (MONO_TYPE_R8);
7966 arg_types [0] = type_to_simd_type (MONO_TYPE_I4);
7967 AddFunc (module, name, ret_type, arg_types, 1);
7969 case INTRINS_SSE_CVTDQ2PS:
7970 ret_type = type_to_simd_type (MONO_TYPE_R4);
7971 arg_types [0] = type_to_simd_type (MONO_TYPE_I4);
7972 AddFunc (module, name, ret_type, arg_types, 1);
7974 case INTRINS_SSE_CVTPD2DQ:
7975 ret_type = type_to_simd_type (MONO_TYPE_I4);
7976 arg_types [0] = type_to_simd_type (MONO_TYPE_R8);
7977 AddFunc (module, name, ret_type, arg_types, 1);
7979 case INTRINS_SSE_CVTPS2DQ:
7980 ret_type = type_to_simd_type (MONO_TYPE_I4);
7981 arg_types [0] = type_to_simd_type (MONO_TYPE_R4);
7982 AddFunc (module, name, ret_type, arg_types, 1);
7984 case INTRINS_SSE_CVTPD2PS:
7985 ret_type = type_to_simd_type (MONO_TYPE_R4);
7986 arg_types [0] = type_to_simd_type (MONO_TYPE_R8);
7987 AddFunc (module, name, ret_type, arg_types, 1);
7989 case INTRINS_SSE_CVTPS2PD:
7990 ret_type = type_to_simd_type (MONO_TYPE_R8);
7991 arg_types [0] = type_to_simd_type (MONO_TYPE_R4);
7992 AddFunc (module, name, ret_type, arg_types, 1);
7994 case INTRINS_SSE_CMPPD:
7996 ret_type = type_to_simd_type (MONO_TYPE_R8);
7997 arg_types [0] = ret_type;
7998 arg_types [1] = ret_type;
7999 arg_types [2] = LLVMInt8Type ();
8000 AddFunc (module, name, ret_type, arg_types, 3);
8002 case INTRINS_SSE_CMPPS:
8003 ret_type = type_to_simd_type (MONO_TYPE_R4);
8004 arg_types [0] = ret_type;
8005 arg_types [1] = ret_type;
8006 arg_types [2] = LLVMInt8Type ();
8007 AddFunc (module, name, ret_type, arg_types, 3);
8009 case INTRINS_SSE_PACKSSWB:
8010 case INTRINS_SSE_PACKUSWB:
8011 case INTRINS_SSE_PACKSSDW:
8013 ret_type = type_to_simd_type (MONO_TYPE_I1);
8014 arg_types [0] = type_to_simd_type (MONO_TYPE_I2);
8015 arg_types [1] = type_to_simd_type (MONO_TYPE_I2);
8016 AddFunc (module, name, ret_type, arg_types, 2);
8018 case INTRINS_SSE_PACKUSDW:
8019 ret_type = type_to_simd_type (MONO_TYPE_I2);
8020 arg_types [0] = type_to_simd_type (MONO_TYPE_I4);
8021 arg_types [1] = type_to_simd_type (MONO_TYPE_I4);
8022 AddFunc (module, name, ret_type, arg_types, 2);
8024 /* SSE Binary ops */
8025 case INTRINS_SSE_PMINUD:
8026 case INTRINS_SSE_PMAXUD:
8027 add_sse_binary (module, name, MONO_TYPE_I4);
8029 case INTRINS_SSE_PMINUW:
8030 case INTRINS_SSE_PMINSW:
8031 case INTRINS_SSE_PMAXUW:
8032 case INTRINS_SSE_PADDSW:
8033 case INTRINS_SSE_PSUBSW:
8034 case INTRINS_SSE_PADDUSW:
8035 case INTRINS_SSE_PSUBUSW:
8036 case INTRINS_SSE_PAVGW:
8037 case INTRINS_SSE_PMULHW:
8038 case INTRINS_SSE_PMULHU:
8039 add_sse_binary (module, name, MONO_TYPE_I2);
8041 case INTRINS_SSE_MINPS:
8042 case INTRINS_SSE_MAXPS:
8043 case INTRINS_SSE_HADDPS:
8044 case INTRINS_SSE_HSUBPS:
8045 case INTRINS_SSE_ADDSUBPS:
8046 add_sse_binary (module, name, MONO_TYPE_R4);
8048 case INTRINS_SSE_MINPD:
8049 case INTRINS_SSE_MAXPD:
8050 case INTRINS_SSE_HADDPD:
8051 case INTRINS_SSE_HSUBPD:
8052 case INTRINS_SSE_ADDSUBPD:
8053 add_sse_binary (module, name, MONO_TYPE_R8);
8055 case INTRINS_SSE_PMINUB:
8056 case INTRINS_SSE_PMAXUB:
8057 case INTRINS_SE_PADDSB:
8058 case INTRINS_SSE_PSUBSB:
8059 case INTRINS_SSE_PADDUSB:
8060 case INTRINS_SSE_PSUBUSB:
8061 case INTRINS_SSE_PAVGB:
8062 add_sse_binary (module, name, MONO_TYPE_I1);
8064 case INTRINS_SSE_PAUSE:
8065 AddFunc (module, "llvm.x86.sse2.pause", LLVMVoidType (), NULL, 0);
8069 g_assert_not_reached ();
8075 get_intrinsic (EmitContext *ctx, const char *name)
8077 #if LLVM_API_VERSION > 100
8081 * Every method is emitted into its own module so
8082 * we can add intrinsics on demand.
8084 res = LLVMGetNamedFunction (ctx->lmodule, name);
8088 /* No locking needed */
8089 id = GPOINTER_TO_INT (g_hash_table_lookup (intrins_name_to_id, name));
8092 printf ("%s\n", name);
8093 g_assert (id != -1);
8094 add_intrinsic (ctx->lmodule, id);
8095 res = LLVMGetNamedFunction (ctx->lmodule, name);
8103 res = LLVMGetNamedFunction (ctx->lmodule, name);
8110 add_intrinsics (LLVMModuleRef module)
8114 /* Emit declarations of instrinsics */
8116 * It would be nicer to emit only the intrinsics actually used, but LLVM's Module
8117 * type doesn't seem to do any locking.
8119 for (i = 0; i < INTRINS_NUM; ++i)
8120 add_intrinsic (module, i);
8124 AddFunc (module, "mono_personality", LLVMVoidType (), NULL, 0);
8126 AddFunc (module, "llvm_resume_unwind_trampoline", LLVMVoidType (), NULL, 0);
8129 /* SSE intrinsics */
8130 #if defined(TARGET_X86) || defined(TARGET_AMD64)
8134 /* Load/Store intrinsics */
8136 LLVMTypeRef arg_types [5];
8140 for (i = 1; i <= 8; i *= 2) {
8141 arg_types [0] = LLVMPointerType (LLVMIntType (i * 8), 0);
8142 arg_types [1] = LLVMInt32Type ();
8143 arg_types [2] = LLVMInt1Type ();
8144 arg_types [3] = LLVMInt32Type ();
8145 sprintf (name, "llvm.mono.load.i%d.p0i%d", i * 8, i * 8);
8146 AddFunc (module, name, LLVMIntType (i * 8), arg_types, 4);
8148 arg_types [0] = LLVMIntType (i * 8);
8149 arg_types [1] = LLVMPointerType (LLVMIntType (i * 8), 0);
8150 arg_types [2] = LLVMInt32Type ();
8151 arg_types [3] = LLVMInt1Type ();
8152 arg_types [4] = LLVMInt32Type ();
8153 sprintf (name, "llvm.mono.store.i%d.p0i%d", i * 8, i * 8);
8154 AddFunc (module, name, LLVMVoidType (), arg_types, 5);
8160 add_types (MonoLLVMModule *module)
8162 module->ptr_type = LLVMPointerType (sizeof (gpointer) == 8 ? LLVMInt64Type () : LLVMInt32Type (), 0);
8166 mono_llvm_init (void)
8171 mono_native_tls_alloc (¤t_cfg_tls_id, NULL);
8173 h = g_hash_table_new (NULL, NULL);
8174 for (i = 0; i < INTRINS_NUM; ++i)
8175 g_hash_table_insert (h, GINT_TO_POINTER (intrinsics [i].id), (gpointer)intrinsics [i].name);
8176 intrins_id_to_name = h;
8178 h = g_hash_table_new (g_str_hash, g_str_equal);
8179 for (i = 0; i < INTRINS_NUM; ++i)
8180 g_hash_table_insert (h, (gpointer)intrinsics [i].name, GINT_TO_POINTER (intrinsics [i].id + 1));
8181 intrins_name_to_id = h;
8185 init_jit_module (MonoDomain *domain)
8187 MonoJitDomainInfo *dinfo;
8188 MonoLLVMModule *module;
8191 dinfo = domain_jit_info (domain);
8192 if (dinfo->llvm_module)
8195 mono_loader_lock ();
8197 if (dinfo->llvm_module) {
8198 mono_loader_unlock ();
8202 module = g_new0 (MonoLLVMModule, 1);
8204 name = g_strdup_printf ("mono-%s", domain->friendly_name);
8205 module->lmodule = LLVMModuleCreateWithName (name);
8206 module->context = LLVMGetGlobalContext ();
8208 module->mono_ee = (MonoEERef*)mono_llvm_create_ee (LLVMCreateModuleProviderForExistingModule (module->lmodule), alloc_cb, emitted_cb, exception_cb, dlsym_cb, &module->ee);
8210 add_intrinsics (module->lmodule);
8213 module->llvm_types = g_hash_table_new (NULL, NULL);
8215 #if LLVM_API_VERSION < 100
8216 MonoJitICallInfo *info;
8218 info = mono_find_jit_icall_by_name ("llvm_resume_unwind_trampoline");
8220 LLVMAddGlobalMapping (module->ee, LLVMGetNamedFunction (module->lmodule, "llvm_resume_unwind_trampoline"), (void*)info->func);
8223 mono_memory_barrier ();
8225 dinfo->llvm_module = module;
8227 mono_loader_unlock ();
8231 mono_llvm_cleanup (void)
8233 MonoLLVMModule *module = &aot_module;
8235 if (module->lmodule)
8236 LLVMDisposeModule (module->lmodule);
8238 if (module->context)
8239 LLVMContextDispose (module->context);
8243 mono_llvm_free_domain_info (MonoDomain *domain)
8245 MonoJitDomainInfo *info = domain_jit_info (domain);
8246 MonoLLVMModule *module = (MonoLLVMModule*)info->llvm_module;
8252 if (module->llvm_types)
8253 g_hash_table_destroy (module->llvm_types);
8255 mono_llvm_dispose_ee (module->mono_ee);
8257 if (module->bb_names) {
8258 for (i = 0; i < module->bb_names_len; ++i)
8259 g_free (module->bb_names [i]);
8260 g_free (module->bb_names);
8262 //LLVMDisposeModule (module->module);
8266 info->llvm_module = NULL;
8270 mono_llvm_create_aot_module (MonoAssembly *assembly, const char *global_prefix, gboolean emit_dwarf, gboolean static_link, gboolean llvm_only)
8272 MonoLLVMModule *module = &aot_module;
8274 /* Delete previous module */
8275 if (module->plt_entries)
8276 g_hash_table_destroy (module->plt_entries);
8277 if (module->lmodule)
8278 LLVMDisposeModule (module->lmodule);
8280 memset (module, 0, sizeof (aot_module));
8282 module->lmodule = LLVMModuleCreateWithName ("aot");
8283 module->assembly = assembly;
8284 module->global_prefix = g_strdup (global_prefix);
8285 module->got_symbol = g_strdup_printf ("%s_llvm_got", global_prefix);
8286 module->eh_frame_symbol = g_strdup_printf ("%s_eh_frame", global_prefix);
8287 module->get_method_symbol = g_strdup_printf ("%s_get_method", global_prefix);
8288 module->get_unbox_tramp_symbol = g_strdup_printf ("%s_get_unbox_tramp", global_prefix);
8289 module->external_symbols = TRUE;
8290 module->emit_dwarf = emit_dwarf;
8291 module->static_link = static_link;
8292 module->llvm_only = llvm_only;
8293 /* The first few entries are reserved */
8294 module->max_got_offset = 16;
8295 module->context = LLVMContextCreate ();
8298 /* clang ignores our debug info because it has an invalid version */
8299 module->emit_dwarf = FALSE;
8301 #if LLVM_API_VERSION > 100
8302 module->emit_dwarf = FALSE;
8305 add_intrinsics (module->lmodule);
8308 #if LLVM_API_VERSION > 100
8309 if (module->emit_dwarf) {
8310 char *dir, *build_info, *s, *cu_name;
8312 module->di_builder = mono_llvm_create_di_builder (module->lmodule);
8315 dir = g_strdup (".");
8316 build_info = mono_get_runtime_build_info ();
8317 s = g_strdup_printf ("Mono AOT Compiler %s (LLVM)", build_info);
8318 cu_name = g_path_get_basename (assembly->image->name);
8319 module->cu = mono_llvm_di_create_compile_unit (module->di_builder, cu_name, dir, s);
8321 g_free (build_info);
8328 * We couldn't compute the type of the LLVM global representing the got because
8329 * its size is only known after all the methods have been emitted. So create
8330 * a dummy variable, and replace all uses it with the real got variable when
8331 * its size is known in mono_llvm_emit_aot_module ().
8334 LLVMTypeRef got_type = LLVMArrayType (module->ptr_type, 0);
8336 module->got_var = LLVMAddGlobal (module->lmodule, got_type, "mono_dummy_got");
8337 LLVMSetInitializer (module->got_var, LLVMConstNull (got_type));
8340 /* Add initialization array */
8342 LLVMTypeRef inited_type = LLVMArrayType (LLVMInt8Type (), 0);
8344 module->inited_var = LLVMAddGlobal (aot_module.lmodule, inited_type, "mono_inited_tmp");
8345 LLVMSetInitializer (module->inited_var, LLVMConstNull (inited_type));
8349 emit_init_icall_wrappers (module);
8351 emit_llvm_code_start (module);
8353 /* Add a dummy personality function */
8354 if (!use_debug_personality) {
8355 LLVMValueRef personality = LLVMAddFunction (module->lmodule, default_personality_name, LLVMFunctionType (LLVMInt32Type (), NULL, 0, TRUE));
8356 LLVMSetLinkage (personality, LLVMExternalLinkage);
8357 mark_as_used (module, personality);
8360 /* Add a reference to the c++ exception we throw/catch */
8362 LLVMTypeRef exc = LLVMPointerType (LLVMInt8Type (), 0);
8363 module->sentinel_exception = LLVMAddGlobal (module->lmodule, exc, "_ZTIPi");
8364 LLVMSetLinkage (module->sentinel_exception, LLVMExternalLinkage);
8365 mono_llvm_set_is_constant (module->sentinel_exception);
8368 module->llvm_types = g_hash_table_new (NULL, NULL);
8369 module->plt_entries = g_hash_table_new (g_str_hash, g_str_equal);
8370 module->plt_entries_ji = g_hash_table_new (NULL, NULL);
8371 module->direct_callables = g_hash_table_new (g_str_hash, g_str_equal);
8372 module->method_to_lmethod = g_hash_table_new (NULL, NULL);
8373 module->idx_to_lmethod = g_hash_table_new (NULL, NULL);
8374 module->idx_to_unbox_tramp = g_hash_table_new (NULL, NULL);
8375 module->method_to_callers = g_hash_table_new (NULL, NULL);
8379 llvm_array_from_uints (LLVMTypeRef el_type, guint32 *values, int nvalues)
8382 LLVMValueRef res, *vals;
8384 vals = g_new0 (LLVMValueRef, nvalues);
8385 for (i = 0; i < nvalues; ++i)
8386 vals [i] = LLVMConstInt (LLVMInt32Type (), values [i], FALSE);
8387 res = LLVMConstArray (LLVMInt32Type (), vals, nvalues);
8393 llvm_array_from_bytes (guint8 *values, int nvalues)
8396 LLVMValueRef res, *vals;
8398 vals = g_new0 (LLVMValueRef, nvalues);
8399 for (i = 0; i < nvalues; ++i)
8400 vals [i] = LLVMConstInt (LLVMInt8Type (), values [i], FALSE);
8401 res = LLVMConstArray (LLVMInt8Type (), vals, nvalues);
8406 * mono_llvm_emit_aot_file_info:
8408 * Emit the MonoAotFileInfo structure.
8409 * Same as emit_aot_file_info () in aot-compiler.c.
8412 mono_llvm_emit_aot_file_info (MonoAotFileInfo *info, gboolean has_jitted_code)
8414 MonoLLVMModule *module = &aot_module;
8416 /* Save these for later */
8417 memcpy (&module->aot_info, info, sizeof (MonoAotFileInfo));
8418 module->has_jitted_code = has_jitted_code;
8422 * mono_llvm_emit_aot_data:
8424 * Emit the binary data DATA pointed to by symbol SYMBOL.
8427 mono_llvm_emit_aot_data (const char *symbol, guint8 *data, int data_len)
8429 MonoLLVMModule *module = &aot_module;
8433 type = LLVMArrayType (LLVMInt8Type (), data_len);
8434 d = LLVMAddGlobal (module->lmodule, type, symbol);
8435 LLVMSetVisibility (d, LLVMHiddenVisibility);
8436 LLVMSetLinkage (d, LLVMInternalLinkage);
8437 LLVMSetInitializer (d, mono_llvm_create_constant_data_array (data, data_len));
8438 mono_llvm_set_is_constant (d);
8441 /* Add a reference to a global defined in JITted code */
8443 AddJitGlobal (MonoLLVMModule *module, LLVMTypeRef type, const char *name)
8448 s = g_strdup_printf ("%s%s", module->global_prefix, name);
8449 v = LLVMAddGlobal (module->lmodule, LLVMInt8Type (), s);
8455 emit_aot_file_info (MonoLLVMModule *module)
8457 LLVMTypeRef file_info_type;
8458 LLVMTypeRef *eltypes, eltype;
8459 LLVMValueRef info_var;
8460 LLVMValueRef *fields;
8461 int i, nfields, tindex;
8462 MonoAotFileInfo *info;
8463 LLVMModuleRef lmodule = module->lmodule;
8465 info = &module->aot_info;
8467 /* Create an LLVM type to represent MonoAotFileInfo */
8468 nfields = 2 + MONO_AOT_FILE_INFO_NUM_SYMBOLS + 16 + 5;
8469 eltypes = g_new (LLVMTypeRef, nfields);
8471 eltypes [tindex ++] = LLVMInt32Type ();
8472 eltypes [tindex ++] = LLVMInt32Type ();
8474 for (i = 0; i < MONO_AOT_FILE_INFO_NUM_SYMBOLS; ++i)
8475 eltypes [tindex ++] = LLVMPointerType (LLVMInt8Type (), 0);
8477 for (i = 0; i < 15; ++i)
8478 eltypes [tindex ++] = LLVMInt32Type ();
8480 eltypes [tindex ++] = LLVMArrayType (LLVMInt32Type (), MONO_AOT_TABLE_NUM);
8481 for (i = 0; i < 4; ++i)
8482 eltypes [tindex ++] = LLVMArrayType (LLVMInt32Type (), MONO_AOT_TRAMP_NUM);
8483 eltypes [tindex ++] = LLVMArrayType (LLVMInt8Type (), 16);
8484 g_assert (tindex == nfields);
8485 file_info_type = LLVMStructCreateNamed (module->context, "MonoAotFileInfo");
8486 LLVMStructSetBody (file_info_type, eltypes, nfields, FALSE);
8488 info_var = LLVMAddGlobal (lmodule, file_info_type, "mono_aot_file_info");
8489 if (module->static_link) {
8490 LLVMSetVisibility (info_var, LLVMHiddenVisibility);
8491 LLVMSetLinkage (info_var, LLVMInternalLinkage);
8493 fields = g_new (LLVMValueRef, nfields);
8495 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->version, FALSE);
8496 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->dummy, FALSE);
8500 * We use LLVMGetNamedGlobal () for symbol which are defined in LLVM code, and LLVMAddGlobal ()
8501 * for symbols defined in the .s file emitted by the aot compiler.
8503 eltype = eltypes [tindex];
8504 if (module->llvm_only)
8505 fields [tindex ++] = LLVMConstNull (eltype);
8507 fields [tindex ++] = AddJitGlobal (module, eltype, "jit_got");
8508 fields [tindex ++] = module->got_var;
8509 /* llc defines this directly */
8510 if (!module->llvm_only) {
8511 fields [tindex ++] = LLVMAddGlobal (lmodule, eltype, module->eh_frame_symbol);
8512 fields [tindex ++] = LLVMConstNull (eltype);
8513 fields [tindex ++] = LLVMConstNull (eltype);
8515 fields [tindex ++] = LLVMConstNull (eltype);
8516 fields [tindex ++] = module->get_method;
8517 fields [tindex ++] = module->get_unbox_tramp;
8519 if (module->has_jitted_code) {
8520 fields [tindex ++] = AddJitGlobal (module, eltype, "jit_code_start");
8521 fields [tindex ++] = AddJitGlobal (module, eltype, "jit_code_end");
8523 fields [tindex ++] = LLVMConstNull (eltype);
8524 fields [tindex ++] = LLVMConstNull (eltype);
8526 if (!module->llvm_only)
8527 fields [tindex ++] = AddJitGlobal (module, eltype, "method_addresses");
8529 fields [tindex ++] = LLVMConstNull (eltype);
8530 if (info->flags & MONO_AOT_FILE_FLAG_SEPARATE_DATA) {
8531 for (i = 0; i < MONO_AOT_TABLE_NUM; ++i)
8532 fields [tindex ++] = LLVMConstNull (eltype);
8534 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "blob");
8535 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "class_name_table");
8536 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "class_info_offsets");
8537 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "method_info_offsets");
8538 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "ex_info_offsets");
8539 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "extra_method_info_offsets");
8540 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "extra_method_table");
8541 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "got_info_offsets");
8542 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "llvm_got_info_offsets");
8543 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "image_table");
8545 /* Not needed (mem_end) */
8546 fields [tindex ++] = LLVMConstNull (eltype);
8547 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "assembly_guid");
8548 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "runtime_version");
8549 if (info->trampoline_size [0]) {
8550 fields [tindex ++] = AddJitGlobal (module, eltype, "specific_trampolines");
8551 fields [tindex ++] = AddJitGlobal (module, eltype, "static_rgctx_trampolines");
8552 fields [tindex ++] = AddJitGlobal (module, eltype, "imt_thunks");
8553 fields [tindex ++] = AddJitGlobal (module, eltype, "gsharedvt_arg_trampolines");
8555 fields [tindex ++] = LLVMConstNull (eltype);
8556 fields [tindex ++] = LLVMConstNull (eltype);
8557 fields [tindex ++] = LLVMConstNull (eltype);
8558 fields [tindex ++] = LLVMConstNull (eltype);
8560 if (module->static_link && !module->llvm_only)
8561 fields [tindex ++] = AddJitGlobal (module, eltype, "globals");
8563 fields [tindex ++] = LLVMConstNull (eltype);
8564 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "assembly_name");
8565 if (!module->llvm_only) {
8566 fields [tindex ++] = AddJitGlobal (module, eltype, "plt");
8567 fields [tindex ++] = AddJitGlobal (module, eltype, "plt_end");
8568 fields [tindex ++] = AddJitGlobal (module, eltype, "unwind_info");
8569 fields [tindex ++] = AddJitGlobal (module, eltype, "unbox_trampolines");
8570 fields [tindex ++] = AddJitGlobal (module, eltype, "unbox_trampolines_end");
8571 fields [tindex ++] = AddJitGlobal (module, eltype, "unbox_trampoline_addresses");
8573 fields [tindex ++] = LLVMConstNull (eltype);
8574 fields [tindex ++] = LLVMConstNull (eltype);
8575 fields [tindex ++] = LLVMConstNull (eltype);
8576 fields [tindex ++] = LLVMConstNull (eltype);
8577 fields [tindex ++] = LLVMConstNull (eltype);
8578 fields [tindex ++] = LLVMConstNull (eltype);
8581 for (i = 0; i < MONO_AOT_FILE_INFO_NUM_SYMBOLS; ++i)
8582 fields [2 + i] = LLVMConstBitCast (fields [2 + i], eltype);
8585 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->plt_got_offset_base, FALSE);
8586 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->got_size, FALSE);
8587 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->plt_size, FALSE);
8588 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->nmethods, FALSE);
8589 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->flags, FALSE);
8590 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->opts, FALSE);
8591 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->simd_opts, FALSE);
8592 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->gc_name_index, FALSE);
8593 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->num_rgctx_fetch_trampolines, FALSE);
8594 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->double_align, FALSE);
8595 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->long_align, FALSE);
8596 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->generic_tramp_num, FALSE);
8597 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->tramp_page_size, FALSE);
8598 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->nshared_got_entries, FALSE);
8599 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->datafile_size, FALSE);
8601 fields [tindex ++] = llvm_array_from_uints (LLVMInt32Type (), info->table_offsets, MONO_AOT_TABLE_NUM);
8602 fields [tindex ++] = llvm_array_from_uints (LLVMInt32Type (), info->num_trampolines, MONO_AOT_TRAMP_NUM);
8603 fields [tindex ++] = llvm_array_from_uints (LLVMInt32Type (), info->trampoline_got_offset_base, MONO_AOT_TRAMP_NUM);
8604 fields [tindex ++] = llvm_array_from_uints (LLVMInt32Type (), info->trampoline_size, MONO_AOT_TRAMP_NUM);
8605 fields [tindex ++] = llvm_array_from_uints (LLVMInt32Type (), info->tramp_page_code_offsets, MONO_AOT_TRAMP_NUM);
8607 fields [tindex ++] = llvm_array_from_bytes (info->aotid, 16);
8608 g_assert (tindex == nfields);
8610 LLVMSetInitializer (info_var, LLVMConstNamedStruct (file_info_type, fields, nfields));
8612 if (module->static_link) {
8616 s = g_strdup_printf ("mono_aot_module_%s_info", module->assembly->aname.name);
8617 /* Get rid of characters which cannot occur in symbols */
8619 for (p = s; *p; ++p) {
8620 if (!(isalnum (*p) || *p == '_'))
8623 var = LLVMAddGlobal (module->lmodule, LLVMPointerType (LLVMInt8Type (), 0), s);
8625 LLVMSetInitializer (var, LLVMConstBitCast (LLVMGetNamedGlobal (module->lmodule, "mono_aot_file_info"), LLVMPointerType (LLVMInt8Type (), 0)));
8626 LLVMSetLinkage (var, LLVMExternalLinkage);
8631 * Emit the aot module into the LLVM bitcode file FILENAME.
8634 mono_llvm_emit_aot_module (const char *filename, const char *cu_name)
8636 LLVMTypeRef got_type, inited_type;
8637 LLVMValueRef real_got, real_inited;
8638 MonoLLVMModule *module = &aot_module;
8640 emit_llvm_code_end (module);
8643 * Create the real got variable and replace all uses of the dummy variable with
8646 got_type = LLVMArrayType (module->ptr_type, module->max_got_offset + 1);
8647 real_got = LLVMAddGlobal (module->lmodule, got_type, module->got_symbol);
8648 LLVMSetInitializer (real_got, LLVMConstNull (got_type));
8649 if (module->external_symbols) {
8650 LLVMSetLinkage (real_got, LLVMExternalLinkage);
8651 LLVMSetVisibility (real_got, LLVMHiddenVisibility);
8653 LLVMSetLinkage (real_got, LLVMInternalLinkage);
8655 mono_llvm_replace_uses_of (module->got_var, real_got);
8657 mark_as_used (&aot_module, real_got);
8659 /* Delete the dummy got so it doesn't become a global */
8660 LLVMDeleteGlobal (module->got_var);
8661 module->got_var = real_got;
8664 * Same for the init_var
8666 if (module->llvm_only) {
8667 inited_type = LLVMArrayType (LLVMInt8Type (), module->max_inited_idx + 1);
8668 real_inited = LLVMAddGlobal (module->lmodule, inited_type, "mono_inited");
8669 LLVMSetInitializer (real_inited, LLVMConstNull (inited_type));
8670 LLVMSetLinkage (real_inited, LLVMInternalLinkage);
8671 mono_llvm_replace_uses_of (module->inited_var, real_inited);
8672 LLVMDeleteGlobal (module->inited_var);
8675 if (module->llvm_only) {
8676 emit_get_method (&aot_module);
8677 emit_get_unbox_tramp (&aot_module);
8680 emit_llvm_used (&aot_module);
8681 emit_dbg_info (&aot_module, filename, cu_name);
8682 emit_aot_file_info (&aot_module);
8685 * Replace GOT entries for directly callable methods with the methods themselves.
8686 * It would be easier to implement this by predefining all methods before compiling
8687 * their bodies, but that couldn't handle the case when a method fails to compile
8690 if (module->llvm_only) {
8691 GHashTableIter iter;
8693 GSList *callers, *l;
8695 g_hash_table_iter_init (&iter, module->method_to_callers);
8696 while (g_hash_table_iter_next (&iter, (void**)&method, (void**)&callers)) {
8697 LLVMValueRef lmethod;
8699 if (method->iflags & METHOD_IMPL_ATTRIBUTE_SYNCHRONIZED)
8702 lmethod = (LLVMValueRef)g_hash_table_lookup (module->method_to_lmethod, method);
8704 for (l = callers; l; l = l->next) {
8705 LLVMValueRef caller = (LLVMValueRef)l->data;
8707 mono_llvm_replace_uses_of (caller, lmethod);
8713 /* Replace PLT entries for directly callable methods with the methods themselves */
8715 GHashTableIter iter;
8717 LLVMValueRef callee;
8719 g_hash_table_iter_init (&iter, module->plt_entries_ji);
8720 while (g_hash_table_iter_next (&iter, (void**)&ji, (void**)&callee)) {
8721 if (mono_aot_is_direct_callable (ji)) {
8722 LLVMValueRef lmethod;
8724 lmethod = (LLVMValueRef)g_hash_table_lookup (module->method_to_lmethod, ji->data.method);
8725 /* The types might not match because the caller might pass an rgctx */
8726 if (lmethod && LLVMTypeOf (callee) == LLVMTypeOf (lmethod)) {
8727 mono_llvm_replace_uses_of (callee, lmethod);
8728 mono_aot_mark_unused_llvm_plt_entry (ji);
8738 if (LLVMVerifyModule (module->lmodule, LLVMReturnStatusAction, &verifier_err)) {
8739 printf ("%s\n", verifier_err);
8740 g_assert_not_reached ();
8745 LLVMWriteBitcodeToFile (module->lmodule, filename);
8750 md_string (const char *s)
8752 return LLVMMDString (s, strlen (s));
8755 /* Debugging support */
8758 emit_dbg_info (MonoLLVMModule *module, const char *filename, const char *cu_name)
8760 LLVMModuleRef lmodule = module->lmodule;
8761 LLVMValueRef args [16], ver;
8764 * This can only be enabled when LLVM code is emitted into a separate object
8765 * file, since the AOT compiler also emits dwarf info,
8766 * and the abbrev indexes will not be correct since llvm has added its own
8769 if (!module->emit_dwarf)
8772 #if LLVM_API_VERSION > 100
8773 mono_llvm_di_builder_finalize (module->di_builder);
8775 LLVMValueRef cu_args [16], cu;
8777 char *build_info, *s, *dir;
8780 * Emit dwarf info in the form of LLVM metadata. There is some
8781 * out-of-date documentation at:
8782 * http://llvm.org/docs/SourceLevelDebugging.html
8783 * but most of this was gathered from the llvm and
8788 cu_args [n_cuargs ++] = LLVMConstInt (LLVMInt32Type (), DW_TAG_compile_unit, FALSE);
8789 /* CU name/compilation dir */
8790 dir = g_path_get_dirname (filename);
8791 args [0] = LLVMMDString (cu_name, strlen (cu_name));
8792 args [1] = LLVMMDString (dir, strlen (dir));
8793 cu_args [n_cuargs ++] = LLVMMDNode (args, 2);
8796 cu_args [n_cuargs ++] = LLVMConstInt (LLVMInt32Type (), DW_LANG_C99, FALSE);
8798 build_info = mono_get_runtime_build_info ();
8799 s = g_strdup_printf ("Mono AOT Compiler %s (LLVM)", build_info);
8800 cu_args [n_cuargs ++] = LLVMMDString (s, strlen (s));
8801 g_free (build_info);
8803 cu_args [n_cuargs ++] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
8805 cu_args [n_cuargs ++] = LLVMMDString ("", strlen (""));
8806 /* Runtime version */
8807 cu_args [n_cuargs ++] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
8809 cu_args [n_cuargs ++] = LLVMMDNode (args, 0);
8810 cu_args [n_cuargs ++] = LLVMMDNode (args, 0);
8812 if (module->subprogram_mds) {
8816 mds = g_new0 (LLVMValueRef, module->subprogram_mds->len);
8817 for (i = 0; i < module->subprogram_mds->len; ++i)
8818 mds [i] = (LLVMValueRef)g_ptr_array_index (module->subprogram_mds, i);
8819 cu_args [n_cuargs ++] = LLVMMDNode (mds, module->subprogram_mds->len);
8821 cu_args [n_cuargs ++] = LLVMMDNode (args, 0);
8824 cu_args [n_cuargs ++] = LLVMMDNode (args, 0);
8825 /* Imported modules */
8826 cu_args [n_cuargs ++] = LLVMMDNode (args, 0);
8828 cu_args [n_cuargs ++] = LLVMMDString ("", strlen (""));
8829 /* DebugEmissionKind = FullDebug */
8830 cu_args [n_cuargs ++] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
8831 cu = LLVMMDNode (cu_args, n_cuargs);
8832 LLVMAddNamedMetadataOperand (lmodule, "llvm.dbg.cu", cu);
8835 #if LLVM_API_VERSION > 100
8836 args [0] = LLVMConstInt (LLVMInt32Type (), 2, FALSE);
8837 args [1] = LLVMMDString ("Dwarf Version", strlen ("Dwarf Version"));
8838 args [2] = LLVMConstInt (LLVMInt32Type (), 2, FALSE);
8839 ver = LLVMMDNode (args, 3);
8840 LLVMAddNamedMetadataOperand (lmodule, "llvm.module.flags", ver);
8842 args [0] = LLVMConstInt (LLVMInt32Type (), 2, FALSE);
8843 args [1] = LLVMMDString ("Debug Info Version", strlen ("Debug Info Version"));
8844 args [2] = LLVMConstInt (LLVMInt64Type (), 3, FALSE);
8845 ver = LLVMMDNode (args, 3);
8846 LLVMAddNamedMetadataOperand (lmodule, "llvm.module.flags", ver);
8848 args [0] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
8849 args [1] = LLVMMDString ("Dwarf Version", strlen ("Dwarf Version"));
8850 args [2] = LLVMConstInt (LLVMInt32Type (), 2, FALSE);
8851 ver = LLVMMDNode (args, 3);
8852 LLVMAddNamedMetadataOperand (lmodule, "llvm.module.flags", ver);
8854 args [0] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
8855 args [1] = LLVMMDString ("Debug Info Version", strlen ("Debug Info Version"));
8856 args [2] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
8857 ver = LLVMMDNode (args, 3);
8858 LLVMAddNamedMetadataOperand (lmodule, "llvm.module.flags", ver);
8863 emit_dbg_subprogram (EmitContext *ctx, MonoCompile *cfg, LLVMValueRef method, const char *name)
8865 MonoLLVMModule *module = ctx->module;
8866 MonoDebugMethodInfo *minfo = ctx->minfo;
8867 char *source_file, *dir, *filename;
8868 LLVMValueRef md, args [16], ctx_args [16], md_args [64], type_args [16], ctx_md, type_md;
8869 MonoSymSeqPoint *sym_seq_points;
8875 mono_debug_symfile_get_seq_points (minfo, &source_file, NULL, NULL, &sym_seq_points, &n_seq_points);
8877 source_file = g_strdup ("<unknown>");
8878 dir = g_path_get_dirname (source_file);
8879 filename = g_path_get_basename (source_file);
8881 #if LLVM_API_VERSION > 100
8882 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);
8885 ctx_args [0] = LLVMConstInt (LLVMInt32Type (), 0x29, FALSE);
8886 args [0] = md_string (filename);
8887 args [1] = md_string (dir);
8888 ctx_args [1] = LLVMMDNode (args, 2);
8889 ctx_md = LLVMMDNode (ctx_args, 2);
8891 type_args [0] = LLVMConstInt (LLVMInt32Type (), DW_TAG_subroutine_type, FALSE);
8892 type_args [1] = NULL;
8893 type_args [2] = NULL;
8894 type_args [3] = LLVMMDString ("", 0);
8895 type_args [4] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
8896 type_args [5] = LLVMConstInt (LLVMInt64Type (), 0, FALSE);
8897 type_args [6] = LLVMConstInt (LLVMInt64Type (), 0, FALSE);
8898 type_args [7] = LLVMConstInt (LLVMInt64Type (), 0, FALSE);
8899 type_args [8] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
8900 type_args [9] = NULL;
8901 type_args [10] = NULL;
8902 type_args [11] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
8903 type_args [12] = NULL;
8904 type_args [13] = NULL;
8905 type_args [14] = NULL;
8906 type_md = LLVMMDNode (type_args, 14);
8908 /* http://llvm.org/docs/SourceLevelDebugging.html#subprogram-descriptors */
8909 md_args [0] = LLVMConstInt (LLVMInt32Type (), DW_TAG_subprogram, FALSE);
8910 /* Source directory + file pair */
8911 args [0] = md_string (filename);
8912 args [1] = md_string (dir);
8913 md_args [1] = LLVMMDNode (args ,2);
8914 md_args [2] = ctx_md;
8915 md_args [3] = md_string (cfg->method->name);
8916 md_args [4] = md_string (name);
8917 md_args [5] = md_string (name);
8920 md_args [6] = LLVMConstInt (LLVMInt32Type (), sym_seq_points [0].line, FALSE);
8922 md_args [6] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
8924 md_args [7] = type_md;
8926 md_args [8] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
8928 md_args [9] = LLVMConstInt (LLVMInt1Type (), 1, FALSE);
8930 md_args [10] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
8931 /* Index into a virtual function */
8932 md_args [11] = NULL;
8933 md_args [12] = NULL;
8935 md_args [13] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
8937 md_args [14] = LLVMConstInt (LLVMInt1Type (), 1, FALSE);
8938 /* Pointer to LLVM function */
8939 md_args [15] = method;
8940 /* Function template parameter */
8941 md_args [16] = NULL;
8942 /* Function declaration descriptor */
8943 md_args [17] = NULL;
8944 /* List of function variables */
8945 md_args [18] = LLVMMDNode (args, 0);
8947 md_args [19] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
8948 md = LLVMMDNode (md_args, 20);
8950 if (!module->subprogram_mds)
8951 module->subprogram_mds = g_ptr_array_new ();
8952 g_ptr_array_add (module->subprogram_mds, md);
8956 g_free (source_file);
8957 g_free (sym_seq_points);
8963 emit_dbg_loc (EmitContext *ctx, LLVMBuilderRef builder, const unsigned char *cil_code)
8965 MonoCompile *cfg = ctx->cfg;
8967 if (ctx->minfo && cil_code && cil_code >= cfg->header->code && cil_code < cfg->header->code + cfg->header->code_size) {
8968 MonoDebugSourceLocation *loc;
8969 LLVMValueRef loc_md;
8971 loc = mono_debug_symfile_lookup_location (ctx->minfo, cil_code - cfg->header->code);
8974 #if LLVM_API_VERSION > 100
8975 loc_md = mono_llvm_di_create_location (ctx->module->di_builder, ctx->dbg_md, loc->row, loc->column);
8976 mono_llvm_di_set_location (builder, loc_md);
8978 LLVMValueRef md_args [16];
8982 md_args [nmd_args ++] = LLVMConstInt (LLVMInt32Type (), loc->row, FALSE);
8983 md_args [nmd_args ++] = LLVMConstInt (LLVMInt32Type (), loc->column, FALSE);
8984 md_args [nmd_args ++] = ctx->dbg_md;
8985 md_args [nmd_args ++] = NULL;
8986 loc_md = LLVMMDNode (md_args, nmd_args);
8987 LLVMSetCurrentDebugLocation (builder, loc_md);
8989 mono_debug_symfile_free_location (loc);
8995 default_mono_llvm_unhandled_exception (void)
8997 MonoJitTlsData *jit_tls = mono_get_jit_tls ();
8998 MonoObject *target = mono_gchandle_get_target (jit_tls->thrown_exc);
9000 mono_unhandled_exception (target);
9001 exit (mono_environment_exitcode_get ());
9006 - Emit LLVM IR from the mono IR using the LLVM C API.
9007 - The original arch specific code remains, so we can fall back to it if we run
9008 into something we can't handle.
9012 A partial list of issues:
9013 - Handling of opcodes which can throw exceptions.
9015 In the mono JIT, these are implemented using code like this:
9022 push throw_pos - method
9023 call <exception trampoline>
9025 The problematic part is push throw_pos - method, which cannot be represented
9026 in the LLVM IR, since it does not support label values.
9027 -> this can be implemented in AOT mode using inline asm + labels, but cannot
9028 be implemented in JIT mode ?
9029 -> a possible but slower implementation would use the normal exception
9030 throwing code but it would need to control the placement of the throw code
9031 (it needs to be exactly after the compare+branch).
9032 -> perhaps add a PC offset intrinsics ?
9034 - efficient implementation of .ovf opcodes.
9036 These are currently implemented as:
9037 <ins which sets the condition codes>
9040 Some overflow opcodes are now supported by LLVM SVN.
9042 - exception handling, unwinding.
9043 - SSA is disabled for methods with exception handlers
9044 - How to obtain unwind info for LLVM compiled methods ?
9045 -> this is now solved by converting the unwind info generated by LLVM
9047 - LLVM uses the c++ exception handling framework, while we use our home grown
9048 code, and couldn't use the c++ one:
9049 - its not supported under VC++, other exotic platforms.
9050 - it might be impossible to support filter clauses with it.
9054 The trampolines need a predictable call sequence, since they need to disasm
9055 the calling code to obtain register numbers / offsets.
9057 LLVM currently generates this code in non-JIT mode:
9058 mov -0x98(%rax),%eax
9060 Here, the vtable pointer is lost.
9061 -> solution: use one vtable trampoline per class.
9063 - passing/receiving the IMT pointer/RGCTX.
9064 -> solution: pass them as normal arguments ?
9068 LLVM does not allow the specification of argument registers etc. This means
9069 that all calls are made according to the platform ABI.
9071 - passing/receiving vtypes.
9073 Vtypes passed/received in registers are handled by the front end by using
9074 a signature with scalar arguments, and loading the parts of the vtype into those
9077 Vtypes passed on the stack are handled using the 'byval' attribute.
9081 Supported though alloca, we need to emit the load/store code.
9085 The mono JIT uses pointer sized iregs/double fregs, while LLVM uses precisely
9086 typed registers, so we have to keep track of the precise LLVM type of each vreg.
9087 This is made easier because the IR is already in SSA form.
9088 An additional problem is that our IR is not consistent with types, i.e. i32/ia64
9089 types are frequently used incorrectly.
9094 Emit LLVM bytecode into a .bc file, compile it using llc into a .s file, then link
9095 it with the file containing the methods emitted by the JIT and the AOT data
9099 /* FIXME: Normalize some aspects of the mono IR to allow easier translation, like:
9100 * - each bblock should end with a branch
9101 * - setting the return value, making cfg->ret non-volatile
9102 * - avoid some transformations in the JIT which make it harder for us to generate
9104 * - use pointer types to help optimizations.