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.
11 #include <mono/metadata/debug-helpers.h>
12 #include <mono/metadata/debug-internals.h>
13 #include <mono/metadata/mempool-internals.h>
14 #include <mono/metadata/environment.h>
15 #include <mono/metadata/object-internals.h>
16 #include <mono/metadata/abi-details.h>
17 #include <mono/utils/mono-tls.h>
18 #include <mono/utils/mono-dl.h>
19 #include <mono/utils/mono-time.h>
20 #include <mono/utils/freebsd-dwarf.h>
22 #ifndef __STDC_LIMIT_MACROS
23 #define __STDC_LIMIT_MACROS
25 #ifndef __STDC_CONSTANT_MACROS
26 #define __STDC_CONSTANT_MACROS
29 #include "llvm-c/BitWriter.h"
30 #include "llvm-c/Analysis.h"
32 #include "mini-llvm-cpp.h"
34 #include "aot-compiler.h"
35 #include "mini-llvm.h"
42 extern void *memset(void *, int, size_t);
43 void bzero (void *to, size_t count) { memset (to, 0, count); }
47 #if LLVM_API_VERSION < 4
48 #error "The version of the mono llvm repository is too old."
51 #define ALIGN_PTR_TO(ptr,align) (gpointer)((((gssize)(ptr)) + (align - 1)) & (~(align - 1)))
54 * Information associated by mono with LLVM modules.
57 LLVMModuleRef lmodule;
58 LLVMValueRef throw_icall, rethrow, match_exc, throw_corlib_exception, resume_eh;
59 GHashTable *llvm_types;
61 const char *got_symbol;
62 const char *get_method_symbol;
63 const char *get_unbox_tramp_symbol;
64 GHashTable *plt_entries;
65 GHashTable *plt_entries_ji;
66 GHashTable *method_to_lmethod;
67 GHashTable *direct_callables;
72 GPtrArray *subprogram_mds;
74 LLVMExecutionEngineRef ee;
75 gboolean external_symbols;
78 LLVMValueRef personality;
81 MonoAssembly *assembly;
83 MonoAotFileInfo aot_info;
84 const char *jit_got_symbol;
85 const char *eh_frame_symbol;
86 LLVMValueRef get_method, get_unbox_tramp;
87 LLVMValueRef init_method, init_method_gshared_mrgctx, init_method_gshared_this, init_method_gshared_vtable;
88 LLVMValueRef code_start, code_end;
89 LLVMValueRef inited_var;
90 int max_inited_idx, max_method_idx;
91 gboolean has_jitted_code;
94 GHashTable *idx_to_lmethod;
95 GHashTable *idx_to_unbox_tramp;
96 /* Maps a MonoMethod to LLVM instructions representing it */
97 GHashTable *method_to_callers;
98 LLVMContextRef context;
99 LLVMValueRef sentinel_exception;
100 void *di_builder, *cu;
101 GHashTable *objc_selector_to_var;
105 * Information associated by the backend with mono basic blocks.
108 LLVMBasicBlockRef bblock, end_bblock;
109 LLVMValueRef finally_ind;
110 gboolean added, invoke_target;
112 * If this bblock is the start of a finally clause, this is a list of bblocks it
113 * needs to branch to in ENDFINALLY.
115 GSList *call_handler_return_bbs;
117 * If this bblock is the start of a finally clause, this is the bblock that
118 * CALL_HANDLER needs to branch to.
120 LLVMBasicBlockRef call_handler_target_bb;
121 /* The list of switch statements generated by ENDFINALLY instructions */
122 GSList *endfinally_switch_ins_list;
127 * Structure containing emit state
130 MonoMemPool *mempool;
132 /* Maps method names to the corresponding LLVMValueRef */
133 GHashTable *emitted_method_decls;
136 LLVMValueRef lmethod;
137 MonoLLVMModule *module;
138 LLVMModuleRef lmodule;
140 int sindex, default_index, ex_index;
141 LLVMBuilderRef builder;
142 LLVMValueRef *values, *addresses;
143 MonoType **vreg_cli_types;
145 MonoMethodSignature *sig;
147 GHashTable *region_to_handler;
148 GHashTable *clause_to_handler;
149 LLVMBuilderRef alloca_builder;
150 LLVMValueRef last_alloca;
151 LLVMValueRef rgctx_arg;
152 LLVMValueRef this_arg;
153 LLVMTypeRef *vreg_types;
155 LLVMTypeRef method_type;
156 LLVMBasicBlockRef init_bb, inited_bb;
158 gboolean *unreachable;
160 gboolean has_got_access;
161 gboolean is_linkonce;
162 int this_arg_pindex, rgctx_arg_pindex;
163 LLVMValueRef imt_rgctx_loc;
164 GHashTable *llvm_types;
166 MonoDebugMethodInfo *minfo;
168 /* For every clause, the clauses it is nested in */
171 GHashTable *exc_meta;
172 GHashTable *method_to_callers;
173 GPtrArray *phi_values;
174 GPtrArray *bblock_list;
176 GHashTable *jit_callees;
177 LLVMValueRef long_bb_break_var;
183 MonoBasicBlock *in_bb;
188 * Instruction metadata
189 * This is the same as ins_info, but LREG != IREG.
197 #define MINI_OP(a,b,dest,src1,src2) dest, src1, src2, ' ',
198 #define MINI_OP3(a,b,dest,src1,src2,src3) dest, src1, src2, src3,
205 /* keep in sync with the enum in mini.h */
208 #include "mini-ops.h"
213 #if SIZEOF_VOID_P == 4
214 #define GET_LONG_IMM(ins) (((guint64)(ins)->inst_ms_word << 32) | (guint64)(guint32)(ins)->inst_ls_word)
216 #define GET_LONG_IMM(ins) ((ins)->inst_imm)
219 #define LLVM_INS_INFO(opcode) (&llvm_ins_info [((opcode) - OP_START - 1) * 4])
222 #define TRACE_FAILURE(msg) do { printf ("%s\n", msg); } while (0)
224 #define TRACE_FAILURE(msg)
228 #define IS_TARGET_X86 1
230 #define IS_TARGET_X86 0
234 #define IS_TARGET_AMD64 1
236 #define IS_TARGET_AMD64 0
239 #define ctx_ok(ctx) (!(ctx)->cfg->disable_llvm)
241 static LLVMIntPredicate cond_to_llvm_cond [] = {
254 static LLVMRealPredicate fpcond_to_llvm_cond [] = {
267 static MonoNativeTlsKey current_cfg_tls_id;
269 static MonoLLVMModule aot_module;
271 static GHashTable *intrins_id_to_name;
272 static GHashTable *intrins_name_to_id;
274 static void init_jit_module (MonoDomain *domain);
276 static void emit_dbg_loc (EmitContext *ctx, LLVMBuilderRef builder, const unsigned char *cil_code);
277 static LLVMValueRef emit_dbg_subprogram (EmitContext *ctx, MonoCompile *cfg, LLVMValueRef method, const char *name);
278 static void emit_dbg_info (MonoLLVMModule *module, const char *filename, const char *cu_name);
279 static void emit_cond_system_exception (EmitContext *ctx, MonoBasicBlock *bb, const char *exc_type, LLVMValueRef cmp);
280 static LLVMValueRef get_intrinsic (EmitContext *ctx, const char *name);
281 static void decode_llvm_eh_info (EmitContext *ctx, gpointer eh_frame);
284 set_failure (EmitContext *ctx, const char *message)
286 TRACE_FAILURE (reason);
287 ctx->cfg->exception_message = g_strdup (message);
288 ctx->cfg->disable_llvm = TRUE;
294 * The LLVM type with width == sizeof (gpointer)
299 return sizeof (gpointer) == 8 ? LLVMInt64Type () : LLVMInt32Type ();
305 return sizeof (gpointer) == 8 ? LLVMPointerType (LLVMInt64Type (), 0) : LLVMPointerType (LLVMInt32Type (), 0);
311 return sizeof (gpointer) == 8 ? LLVMPointerType (LLVMInt64Type (), 0) : LLVMPointerType (LLVMInt32Type (), 0);
317 * Return the size of the LLVM representation of the vtype T.
320 get_vtype_size (MonoType *t)
324 size = mono_class_value_size (mono_class_from_mono_type (t), NULL);
326 /* LLVMArgAsIArgs depends on this since it stores whole words */
327 while (size < 2 * sizeof (gpointer) && mono_is_power_of_two (size) == -1)
334 * simd_class_to_llvm_type:
336 * Return the LLVM type corresponding to the Mono.SIMD class KLASS
339 simd_class_to_llvm_type (EmitContext *ctx, MonoClass *klass)
341 if (!strcmp (klass->name, "Vector2d")) {
342 return LLVMVectorType (LLVMDoubleType (), 2);
343 } else if (!strcmp (klass->name, "Vector2l")) {
344 return LLVMVectorType (LLVMInt64Type (), 2);
345 } else if (!strcmp (klass->name, "Vector2ul")) {
346 return LLVMVectorType (LLVMInt64Type (), 2);
347 } else if (!strcmp (klass->name, "Vector4i")) {
348 return LLVMVectorType (LLVMInt32Type (), 4);
349 } else if (!strcmp (klass->name, "Vector4ui")) {
350 return LLVMVectorType (LLVMInt32Type (), 4);
351 } else if (!strcmp (klass->name, "Vector4f")) {
352 return LLVMVectorType (LLVMFloatType (), 4);
353 } else if (!strcmp (klass->name, "Vector8s")) {
354 return LLVMVectorType (LLVMInt16Type (), 8);
355 } else if (!strcmp (klass->name, "Vector8us")) {
356 return LLVMVectorType (LLVMInt16Type (), 8);
357 } else if (!strcmp (klass->name, "Vector16sb")) {
358 return LLVMVectorType (LLVMInt8Type (), 16);
359 } else if (!strcmp (klass->name, "Vector16b")) {
360 return LLVMVectorType (LLVMInt8Type (), 16);
361 } else if (!strcmp (klass->name, "Vector2")) {
362 /* System.Numerics */
363 return LLVMVectorType (LLVMFloatType (), 4);
364 } else if (!strcmp (klass->name, "Vector3")) {
365 return LLVMVectorType (LLVMFloatType (), 4);
366 } else if (!strcmp (klass->name, "Vector4")) {
367 return LLVMVectorType (LLVMFloatType (), 4);
368 } else if (!strcmp (klass->name, "Vector`1")) {
369 MonoType *etype = mono_class_get_generic_class (klass)->context.class_inst->type_argv [0];
370 switch (etype->type) {
373 return LLVMVectorType (LLVMInt8Type (), 16);
376 return LLVMVectorType (LLVMInt16Type (), 8);
379 return LLVMVectorType (LLVMInt32Type (), 4);
382 return LLVMVectorType (LLVMInt64Type (), 2);
384 return LLVMVectorType (LLVMFloatType (), 4);
386 return LLVMVectorType (LLVMDoubleType (), 2);
388 g_assert_not_reached ();
392 printf ("%s\n", klass->name);
398 /* Return the 128 bit SIMD type corresponding to the mono type TYPE */
399 static inline G_GNUC_UNUSED LLVMTypeRef
400 type_to_simd_type (int type)
404 return LLVMVectorType (LLVMInt8Type (), 16);
406 return LLVMVectorType (LLVMInt16Type (), 8);
408 return LLVMVectorType (LLVMInt32Type (), 4);
410 return LLVMVectorType (LLVMInt64Type (), 2);
412 return LLVMVectorType (LLVMDoubleType (), 2);
414 return LLVMVectorType (LLVMFloatType (), 4);
416 g_assert_not_reached ();
422 create_llvm_type_for_type (MonoLLVMModule *module, MonoClass *klass)
424 int i, size, nfields, esize;
425 LLVMTypeRef *eltypes;
430 t = &klass->byval_arg;
432 if (mini_type_is_hfa (t, &nfields, &esize)) {
434 * This is needed on arm64 where HFAs are returned in
437 /* SIMD types have size 16 in mono_class_value_size () */
438 if (klass->simd_type)
441 eltypes = g_new (LLVMTypeRef, size);
442 for (i = 0; i < size; ++i)
443 eltypes [i] = esize == 4 ? LLVMFloatType () : LLVMDoubleType ();
445 size = get_vtype_size (t);
447 eltypes = g_new (LLVMTypeRef, size);
448 for (i = 0; i < size; ++i)
449 eltypes [i] = LLVMInt8Type ();
452 name = mono_type_full_name (&klass->byval_arg);
453 ltype = LLVMStructCreateNamed (module->context, name);
454 LLVMStructSetBody (ltype, eltypes, size, FALSE);
464 * Return the LLVM type corresponding to T.
467 type_to_llvm_type (EmitContext *ctx, MonoType *t)
469 t = mini_get_underlying_type (t);
473 return LLVMVoidType ();
475 return LLVMInt8Type ();
477 return LLVMInt16Type ();
479 return LLVMInt32Type ();
481 return LLVMInt8Type ();
483 return LLVMInt16Type ();
485 return LLVMInt32Type ();
486 case MONO_TYPE_BOOLEAN:
487 return LLVMInt8Type ();
490 return LLVMInt64Type ();
492 return LLVMInt16Type ();
494 return LLVMFloatType ();
496 return LLVMDoubleType ();
499 return IntPtrType ();
500 case MONO_TYPE_OBJECT:
501 case MONO_TYPE_CLASS:
502 case MONO_TYPE_ARRAY:
503 case MONO_TYPE_SZARRAY:
504 case MONO_TYPE_STRING:
506 return ObjRefType ();
509 /* Because of generic sharing */
510 return ObjRefType ();
511 case MONO_TYPE_GENERICINST:
512 if (!mono_type_generic_inst_is_valuetype (t))
513 return ObjRefType ();
515 case MONO_TYPE_VALUETYPE:
516 case MONO_TYPE_TYPEDBYREF: {
520 klass = mono_class_from_mono_type (t);
522 if (MONO_CLASS_IS_SIMD (ctx->cfg, klass))
523 return simd_class_to_llvm_type (ctx, klass);
526 return type_to_llvm_type (ctx, mono_class_enum_basetype (klass));
528 ltype = (LLVMTypeRef)g_hash_table_lookup (ctx->module->llvm_types, klass);
530 ltype = create_llvm_type_for_type (ctx->module, klass);
531 g_hash_table_insert (ctx->module->llvm_types, klass, ltype);
537 printf ("X: %d\n", t->type);
538 ctx->cfg->exception_message = g_strdup_printf ("type %s", mono_type_full_name (t));
539 ctx->cfg->disable_llvm = TRUE;
547 * Return whenever T is an unsigned int type.
550 type_is_unsigned (EmitContext *ctx, MonoType *t)
552 t = mini_get_underlying_type (t);
568 * type_to_llvm_arg_type:
570 * Same as type_to_llvm_type, but treat i8/i16 as i32.
573 type_to_llvm_arg_type (EmitContext *ctx, MonoType *t)
575 LLVMTypeRef ptype = type_to_llvm_type (ctx, t);
577 if (ctx->cfg->llvm_only)
581 * This works on all abis except arm64/ios which passes multiple
582 * arguments in one stack slot.
585 if (ptype == LLVMInt8Type () || ptype == LLVMInt16Type ()) {
587 * LLVM generates code which only sets the lower bits, while JITted
588 * code expects all the bits to be set.
590 ptype = LLVMInt32Type ();
598 * llvm_type_to_stack_type:
600 * Return the LLVM type which needs to be used when a value of type TYPE is pushed
603 static G_GNUC_UNUSED LLVMTypeRef
604 llvm_type_to_stack_type (MonoCompile *cfg, LLVMTypeRef type)
608 if (type == LLVMInt8Type ())
609 return LLVMInt32Type ();
610 else if (type == LLVMInt16Type ())
611 return LLVMInt32Type ();
612 else if (!cfg->r4fp && type == LLVMFloatType ())
613 return LLVMDoubleType ();
619 * regtype_to_llvm_type:
621 * Return the LLVM type corresponding to the regtype C used in instruction
625 regtype_to_llvm_type (char c)
629 return LLVMInt32Type ();
631 return LLVMInt64Type ();
633 return LLVMDoubleType ();
642 * Return the LLVM type corresponding to the unary/binary opcode OPCODE.
645 op_to_llvm_type (int opcode)
650 return LLVMInt8Type ();
653 return LLVMInt8Type ();
656 return LLVMInt16Type ();
659 return LLVMInt16Type ();
662 return LLVMInt32Type ();
665 return LLVMInt32Type ();
667 return LLVMInt64Type ();
669 return LLVMFloatType ();
671 return LLVMDoubleType ();
673 return LLVMInt64Type ();
675 return LLVMInt32Type ();
677 return LLVMInt64Type ();
682 return LLVMInt8Type ();
687 return LLVMInt16Type ();
689 return LLVMInt32Type ();
692 return sizeof (gpointer) == 8 ? LLVMInt64Type () : LLVMInt32Type ();
699 return LLVMInt32Type ();
706 return LLVMInt64Type ();
708 printf ("%s\n", mono_inst_name (opcode));
709 g_assert_not_reached ();
714 #define CLAUSE_START(clause) ((clause)->try_offset)
715 #define CLAUSE_END(clause) (((clause))->try_offset + ((clause))->try_len)
718 * load_store_to_llvm_type:
720 * Return the size/sign/zero extension corresponding to the load/store opcode
724 load_store_to_llvm_type (int opcode, int *size, gboolean *sext, gboolean *zext)
730 case OP_LOADI1_MEMBASE:
731 case OP_STOREI1_MEMBASE_REG:
732 case OP_STOREI1_MEMBASE_IMM:
733 case OP_ATOMIC_LOAD_I1:
734 case OP_ATOMIC_STORE_I1:
737 return LLVMInt8Type ();
738 case OP_LOADU1_MEMBASE:
740 case OP_ATOMIC_LOAD_U1:
741 case OP_ATOMIC_STORE_U1:
744 return LLVMInt8Type ();
745 case OP_LOADI2_MEMBASE:
746 case OP_STOREI2_MEMBASE_REG:
747 case OP_STOREI2_MEMBASE_IMM:
748 case OP_ATOMIC_LOAD_I2:
749 case OP_ATOMIC_STORE_I2:
752 return LLVMInt16Type ();
753 case OP_LOADU2_MEMBASE:
755 case OP_ATOMIC_LOAD_U2:
756 case OP_ATOMIC_STORE_U2:
759 return LLVMInt16Type ();
760 case OP_LOADI4_MEMBASE:
761 case OP_LOADU4_MEMBASE:
764 case OP_STOREI4_MEMBASE_REG:
765 case OP_STOREI4_MEMBASE_IMM:
766 case OP_ATOMIC_LOAD_I4:
767 case OP_ATOMIC_STORE_I4:
768 case OP_ATOMIC_LOAD_U4:
769 case OP_ATOMIC_STORE_U4:
771 return LLVMInt32Type ();
772 case OP_LOADI8_MEMBASE:
774 case OP_STOREI8_MEMBASE_REG:
775 case OP_STOREI8_MEMBASE_IMM:
776 case OP_ATOMIC_LOAD_I8:
777 case OP_ATOMIC_STORE_I8:
778 case OP_ATOMIC_LOAD_U8:
779 case OP_ATOMIC_STORE_U8:
781 return LLVMInt64Type ();
782 case OP_LOADR4_MEMBASE:
783 case OP_STORER4_MEMBASE_REG:
784 case OP_ATOMIC_LOAD_R4:
785 case OP_ATOMIC_STORE_R4:
787 return LLVMFloatType ();
788 case OP_LOADR8_MEMBASE:
789 case OP_STORER8_MEMBASE_REG:
790 case OP_ATOMIC_LOAD_R8:
791 case OP_ATOMIC_STORE_R8:
793 return LLVMDoubleType ();
794 case OP_LOAD_MEMBASE:
796 case OP_STORE_MEMBASE_REG:
797 case OP_STORE_MEMBASE_IMM:
798 *size = sizeof (gpointer);
799 return IntPtrType ();
801 g_assert_not_reached ();
809 * Return the LLVM intrinsics corresponding to the overflow opcode OPCODE.
812 ovf_op_to_intrins (int opcode)
816 return "llvm.sadd.with.overflow.i32";
818 return "llvm.uadd.with.overflow.i32";
820 return "llvm.ssub.with.overflow.i32";
822 return "llvm.usub.with.overflow.i32";
824 return "llvm.smul.with.overflow.i32";
826 return "llvm.umul.with.overflow.i32";
828 return "llvm.sadd.with.overflow.i64";
830 return "llvm.uadd.with.overflow.i64";
832 return "llvm.ssub.with.overflow.i64";
834 return "llvm.usub.with.overflow.i64";
836 return "llvm.smul.with.overflow.i64";
838 return "llvm.umul.with.overflow.i64";
840 g_assert_not_reached ();
846 simd_op_to_intrins (int opcode)
849 #if defined(TARGET_X86) || defined(TARGET_AMD64)
851 return "llvm.x86.sse2.min.pd";
853 return "llvm.x86.sse.min.ps";
855 return "llvm.x86.sse2.max.pd";
857 return "llvm.x86.sse.max.ps";
859 return "llvm.x86.sse3.hadd.pd";
861 return "llvm.x86.sse3.hadd.ps";
863 return "llvm.x86.sse3.hsub.pd";
865 return "llvm.x86.sse3.hsub.ps";
867 return "llvm.x86.sse3.addsub.ps";
869 return "llvm.x86.sse3.addsub.pd";
870 case OP_EXTRACT_MASK:
871 return "llvm.x86.sse2.pmovmskb.128";
874 return "llvm.x86.sse2.psrli.w";
877 return "llvm.x86.sse2.psrli.d";
880 return "llvm.x86.sse2.psrli.q";
883 return "llvm.x86.sse2.pslli.w";
886 return "llvm.x86.sse2.pslli.d";
889 return "llvm.x86.sse2.pslli.q";
892 return "llvm.x86.sse2.psrai.w";
895 return "llvm.x86.sse2.psrai.d";
897 return "llvm.x86.sse2.padds.b";
899 return "llvm.x86.sse2.padds.w";
901 return "llvm.x86.sse2.psubs.b";
903 return "llvm.x86.sse2.psubs.w";
904 case OP_PADDB_SAT_UN:
905 return "llvm.x86.sse2.paddus.b";
906 case OP_PADDW_SAT_UN:
907 return "llvm.x86.sse2.paddus.w";
908 case OP_PSUBB_SAT_UN:
909 return "llvm.x86.sse2.psubus.b";
910 case OP_PSUBW_SAT_UN:
911 return "llvm.x86.sse2.psubus.w";
913 return "llvm.x86.sse2.pavg.b";
915 return "llvm.x86.sse2.pavg.w";
917 return "llvm.x86.sse.sqrt.ps";
919 return "llvm.x86.sse2.sqrt.pd";
921 return "llvm.x86.sse.rsqrt.ps";
923 return "llvm.x86.sse.rcp.ps";
925 return "llvm.x86.sse2.cvtdq2pd";
927 return "llvm.x86.sse2.cvtdq2ps";
929 return "llvm.x86.sse2.cvtpd2dq";
931 return "llvm.x86.sse2.cvtps2dq";
933 return "llvm.x86.sse2.cvtpd2ps";
935 return "llvm.x86.sse2.cvtps2pd";
937 return "llvm.x86.sse2.cvttpd2dq";
939 return "llvm.x86.sse2.cvttps2dq";
941 return "llvm.x86.sse2.packsswb.128";
943 return "llvm.x86.sse2.packssdw.128";
945 return "llvm.x86.sse2.packuswb.128";
947 return "llvm.x86.sse41.packusdw";
949 return "llvm.x86.sse2.pmulh.w";
950 case OP_PMULW_HIGH_UN:
951 return "llvm.x86.sse2.pmulhu.w";
953 return "llvm.x86.sse41.dpps";
956 g_assert_not_reached ();
962 simd_op_to_llvm_type (int opcode)
964 #if defined(TARGET_X86) || defined(TARGET_AMD64)
968 return type_to_simd_type (MONO_TYPE_R8);
971 return type_to_simd_type (MONO_TYPE_I8);
974 return type_to_simd_type (MONO_TYPE_I4);
979 return type_to_simd_type (MONO_TYPE_I2);
983 return type_to_simd_type (MONO_TYPE_I1);
985 return type_to_simd_type (MONO_TYPE_R4);
988 return type_to_simd_type (MONO_TYPE_I4);
992 return type_to_simd_type (MONO_TYPE_R8);
996 return type_to_simd_type (MONO_TYPE_R4);
997 case OP_EXTRACT_MASK:
998 return type_to_simd_type (MONO_TYPE_I1);
1004 return type_to_simd_type (MONO_TYPE_R4);
1007 return type_to_simd_type (MONO_TYPE_R8);
1009 g_assert_not_reached ();
1020 * Return the LLVM basic block corresponding to BB.
1022 static LLVMBasicBlockRef
1023 get_bb (EmitContext *ctx, MonoBasicBlock *bb)
1025 char bb_name_buf [128];
1028 if (ctx->bblocks [bb->block_num].bblock == NULL) {
1029 if (bb->flags & BB_EXCEPTION_HANDLER) {
1030 int clause_index = (mono_get_block_region_notry (ctx->cfg, bb->region) >> 8) - 1;
1031 sprintf (bb_name_buf, "EH_CLAUSE%d_BB%d", clause_index, bb->block_num);
1032 bb_name = bb_name_buf;
1033 } else if (bb->block_num < 256) {
1034 if (!ctx->module->bb_names) {
1035 ctx->module->bb_names_len = 256;
1036 ctx->module->bb_names = g_new0 (char*, ctx->module->bb_names_len);
1038 if (!ctx->module->bb_names [bb->block_num]) {
1041 n = g_strdup_printf ("BB%d", bb->block_num);
1042 mono_memory_barrier ();
1043 ctx->module->bb_names [bb->block_num] = n;
1045 bb_name = ctx->module->bb_names [bb->block_num];
1047 sprintf (bb_name_buf, "BB%d", bb->block_num);
1048 bb_name = bb_name_buf;
1051 ctx->bblocks [bb->block_num].bblock = LLVMAppendBasicBlock (ctx->lmethod, bb_name);
1052 ctx->bblocks [bb->block_num].end_bblock = ctx->bblocks [bb->block_num].bblock;
1055 return ctx->bblocks [bb->block_num].bblock;
1061 * Return the last LLVM bblock corresponding to BB.
1062 * This might not be equal to the bb returned by get_bb () since we need to generate
1063 * multiple LLVM bblocks for a mono bblock to handle throwing exceptions.
1065 static LLVMBasicBlockRef
1066 get_end_bb (EmitContext *ctx, MonoBasicBlock *bb)
1069 return ctx->bblocks [bb->block_num].end_bblock;
1072 static LLVMBasicBlockRef
1073 gen_bb (EmitContext *ctx, const char *prefix)
1077 sprintf (bb_name, "%s%d", prefix, ++ ctx->ex_index);
1078 return LLVMAppendBasicBlock (ctx->lmethod, bb_name);
1084 * Return the target of the patch identified by TYPE and TARGET.
1087 resolve_patch (MonoCompile *cfg, MonoJumpInfoType type, gconstpointer target)
1093 memset (&ji, 0, sizeof (ji));
1095 ji.data.target = target;
1097 res = mono_resolve_patch_target (cfg->method, cfg->domain, NULL, &ji, FALSE, &error);
1098 mono_error_assert_ok (&error);
1106 * Emit code to convert the LLVM value V to DTYPE.
1109 convert_full (EmitContext *ctx, LLVMValueRef v, LLVMTypeRef dtype, gboolean is_unsigned)
1111 LLVMTypeRef stype = LLVMTypeOf (v);
1113 if (stype != dtype) {
1114 gboolean ext = FALSE;
1117 if (dtype == LLVMInt64Type () && (stype == LLVMInt32Type () || stype == LLVMInt16Type () || stype == LLVMInt8Type ()))
1119 else if (dtype == LLVMInt32Type () && (stype == LLVMInt16Type () || stype == LLVMInt8Type ()))
1121 else if (dtype == LLVMInt16Type () && (stype == LLVMInt8Type ()))
1125 return is_unsigned ? LLVMBuildZExt (ctx->builder, v, dtype, "") : LLVMBuildSExt (ctx->builder, v, dtype, "");
1127 if (dtype == LLVMDoubleType () && stype == LLVMFloatType ())
1128 return LLVMBuildFPExt (ctx->builder, v, dtype, "");
1131 if (stype == LLVMInt64Type () && (dtype == LLVMInt32Type () || dtype == LLVMInt16Type () || dtype == LLVMInt8Type ()))
1132 return LLVMBuildTrunc (ctx->builder, v, dtype, "");
1133 if (stype == LLVMInt32Type () && (dtype == LLVMInt16Type () || dtype == LLVMInt8Type ()))
1134 return LLVMBuildTrunc (ctx->builder, v, dtype, "");
1135 if (stype == LLVMInt16Type () && dtype == LLVMInt8Type ())
1136 return LLVMBuildTrunc (ctx->builder, v, dtype, "");
1137 if (stype == LLVMDoubleType () && dtype == LLVMFloatType ())
1138 return LLVMBuildFPTrunc (ctx->builder, v, dtype, "");
1140 if (LLVMGetTypeKind (stype) == LLVMPointerTypeKind && LLVMGetTypeKind (dtype) == LLVMPointerTypeKind)
1141 return LLVMBuildBitCast (ctx->builder, v, dtype, "");
1142 if (LLVMGetTypeKind (dtype) == LLVMPointerTypeKind)
1143 return LLVMBuildIntToPtr (ctx->builder, v, dtype, "");
1144 if (LLVMGetTypeKind (stype) == LLVMPointerTypeKind)
1145 return LLVMBuildPtrToInt (ctx->builder, v, dtype, "");
1147 if (mono_arch_is_soft_float ()) {
1148 if (stype == LLVMInt32Type () && dtype == LLVMFloatType ())
1149 return LLVMBuildBitCast (ctx->builder, v, dtype, "");
1150 if (stype == LLVMInt32Type () && dtype == LLVMDoubleType ())
1151 return LLVMBuildBitCast (ctx->builder, LLVMBuildZExt (ctx->builder, v, LLVMInt64Type (), ""), dtype, "");
1154 if (LLVMGetTypeKind (stype) == LLVMVectorTypeKind && LLVMGetTypeKind (dtype) == LLVMVectorTypeKind)
1155 return LLVMBuildBitCast (ctx->builder, v, dtype, "");
1158 LLVMDumpValue (LLVMConstNull (dtype));
1159 g_assert_not_reached ();
1167 convert (EmitContext *ctx, LLVMValueRef v, LLVMTypeRef dtype)
1169 return convert_full (ctx, v, dtype, FALSE);
1173 * emit_volatile_load:
1175 * If vreg is volatile, emit a load from its address.
1178 emit_volatile_load (EmitContext *ctx, int vreg)
1184 // FIXME: This hack is required because we pass the rgctx in a callee saved
1185 // register on arm64 (x15), and llvm might keep the value in that register
1186 // even through the register is marked as 'reserved' inside llvm.
1187 if (ctx->cfg->rgctx_var && ctx->cfg->rgctx_var->dreg == vreg)
1188 v = mono_llvm_build_load (ctx->builder, ctx->addresses [vreg], "", TRUE);
1190 v = LLVMBuildLoad (ctx->builder, ctx->addresses [vreg], "");
1192 v = LLVMBuildLoad (ctx->builder, ctx->addresses [vreg], "");
1194 t = ctx->vreg_cli_types [vreg];
1195 if (t && !t->byref) {
1197 * Might have to zero extend since llvm doesn't have
1200 if (t->type == MONO_TYPE_U1 || t->type == MONO_TYPE_U2 || t->type == MONO_TYPE_CHAR || t->type == MONO_TYPE_BOOLEAN)
1201 v = LLVMBuildZExt (ctx->builder, v, LLVMInt32Type (), "");
1202 else if (t->type == MONO_TYPE_I1 || t->type == MONO_TYPE_I2)
1203 v = LLVMBuildSExt (ctx->builder, v, LLVMInt32Type (), "");
1204 else if (t->type == MONO_TYPE_U8)
1205 v = LLVMBuildZExt (ctx->builder, v, LLVMInt64Type (), "");
1212 * emit_volatile_store:
1214 * If VREG is volatile, emit a store from its value to its address.
1217 emit_volatile_store (EmitContext *ctx, int vreg)
1219 MonoInst *var = get_vreg_to_inst (ctx->cfg, vreg);
1221 if (var && var->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT)) {
1222 g_assert (ctx->addresses [vreg]);
1223 LLVMBuildStore (ctx->builder, convert (ctx, ctx->values [vreg], type_to_llvm_type (ctx, var->inst_vtype)), ctx->addresses [vreg]);
1228 sig_to_llvm_sig_no_cinfo (EmitContext *ctx, MonoMethodSignature *sig)
1230 LLVMTypeRef ret_type;
1231 LLVMTypeRef *param_types = NULL;
1236 rtype = mini_get_underlying_type (sig->ret);
1237 ret_type = type_to_llvm_type (ctx, rtype);
1241 param_types = g_new0 (LLVMTypeRef, (sig->param_count * 8) + 3);
1245 param_types [pindex ++] = ThisType ();
1246 for (i = 0; i < sig->param_count; ++i)
1247 param_types [pindex ++] = type_to_llvm_arg_type (ctx, sig->params [i]);
1249 if (!ctx_ok (ctx)) {
1250 g_free (param_types);
1254 res = LLVMFunctionType (ret_type, param_types, pindex, FALSE);
1255 g_free (param_types);
1261 * sig_to_llvm_sig_full:
1263 * Return the LLVM signature corresponding to the mono signature SIG using the
1264 * calling convention information in CINFO. Fill out the parameter mapping information in CINFO.
1267 sig_to_llvm_sig_full (EmitContext *ctx, MonoMethodSignature *sig, LLVMCallInfo *cinfo)
1269 LLVMTypeRef ret_type;
1270 LLVMTypeRef *param_types = NULL;
1272 int i, j, pindex, vret_arg_pindex = 0;
1273 gboolean vretaddr = FALSE;
1277 return sig_to_llvm_sig_no_cinfo (ctx, sig);
1279 rtype = mini_get_underlying_type (sig->ret);
1280 ret_type = type_to_llvm_type (ctx, rtype);
1284 switch (cinfo->ret.storage) {
1285 case LLVMArgVtypeInReg:
1286 /* LLVM models this by returning an aggregate value */
1287 if (cinfo->ret.pair_storage [0] == LLVMArgInIReg && cinfo->ret.pair_storage [1] == LLVMArgNone) {
1288 LLVMTypeRef members [2];
1290 members [0] = IntPtrType ();
1291 ret_type = LLVMStructType (members, 1, FALSE);
1292 } else if (cinfo->ret.pair_storage [0] == LLVMArgNone && cinfo->ret.pair_storage [1] == LLVMArgNone) {
1294 ret_type = LLVMVoidType ();
1295 } else if (cinfo->ret.pair_storage [0] == LLVMArgInIReg && cinfo->ret.pair_storage [1] == LLVMArgInIReg) {
1296 LLVMTypeRef members [2];
1298 members [0] = IntPtrType ();
1299 members [1] = IntPtrType ();
1300 ret_type = LLVMStructType (members, 2, FALSE);
1302 g_assert_not_reached ();
1305 case LLVMArgVtypeByVal:
1306 /* Vtype returned normally by val */
1308 case LLVMArgVtypeAsScalar: {
1309 int size = mono_class_value_size (mono_class_from_mono_type (rtype), NULL);
1310 /* LLVM models this by returning an int */
1311 if (size < SIZEOF_VOID_P) {
1312 g_assert (cinfo->ret.nslots == 1);
1313 ret_type = LLVMIntType (size * 8);
1315 g_assert (cinfo->ret.nslots == 1 || cinfo->ret.nslots == 2);
1316 ret_type = LLVMIntType (cinfo->ret.nslots * sizeof (mgreg_t) * 8);
1320 case LLVMArgAsIArgs:
1321 ret_type = LLVMArrayType (IntPtrType (), cinfo->ret.nslots);
1323 case LLVMArgFpStruct: {
1324 /* Vtype returned as a fp struct */
1325 LLVMTypeRef members [16];
1327 /* Have to create our own structure since we don't map fp structures to LLVM fp structures yet */
1328 for (i = 0; i < cinfo->ret.nslots; ++i)
1329 members [i] = cinfo->ret.esize == 8 ? LLVMDoubleType () : LLVMFloatType ();
1330 ret_type = LLVMStructType (members, cinfo->ret.nslots, FALSE);
1333 case LLVMArgVtypeByRef:
1334 /* Vtype returned using a hidden argument */
1335 ret_type = LLVMVoidType ();
1337 case LLVMArgVtypeRetAddr:
1338 case LLVMArgGsharedvtFixed:
1339 case LLVMArgGsharedvtFixedVtype:
1340 case LLVMArgGsharedvtVariable:
1342 ret_type = LLVMVoidType ();
1348 param_types = g_new0 (LLVMTypeRef, (sig->param_count * 8) + 3);
1350 if (cinfo->ret.storage == LLVMArgVtypeByRef) {
1352 * Has to be the first argument because of the sret argument attribute
1353 * FIXME: This might conflict with passing 'this' as the first argument, but
1354 * this is only used on arm64 which has a dedicated struct return register.
1356 cinfo->vret_arg_pindex = pindex;
1357 param_types [pindex] = type_to_llvm_arg_type (ctx, sig->ret);
1358 if (!ctx_ok (ctx)) {
1359 g_free (param_types);
1362 param_types [pindex] = LLVMPointerType (param_types [pindex], 0);
1365 if (!ctx->llvm_only && cinfo->rgctx_arg) {
1366 cinfo->rgctx_arg_pindex = pindex;
1367 param_types [pindex] = ctx->module->ptr_type;
1370 if (cinfo->imt_arg) {
1371 cinfo->imt_arg_pindex = pindex;
1372 param_types [pindex] = ctx->module->ptr_type;
1376 /* Compute the index in the LLVM signature where the vret arg needs to be passed */
1377 vret_arg_pindex = pindex;
1378 if (cinfo->vret_arg_index == 1) {
1379 /* Add the slots consumed by the first argument */
1380 LLVMArgInfo *ainfo = &cinfo->args [0];
1381 switch (ainfo->storage) {
1382 case LLVMArgVtypeInReg:
1383 for (j = 0; j < 2; ++j) {
1384 if (ainfo->pair_storage [j] == LLVMArgInIReg)
1393 cinfo->vret_arg_pindex = vret_arg_pindex;
1396 if (vretaddr && vret_arg_pindex == pindex)
1397 param_types [pindex ++] = IntPtrType ();
1399 cinfo->this_arg_pindex = pindex;
1400 param_types [pindex ++] = ThisType ();
1401 cinfo->args [0].pindex = cinfo->this_arg_pindex;
1403 if (vretaddr && vret_arg_pindex == pindex)
1404 param_types [pindex ++] = IntPtrType ();
1405 for (i = 0; i < sig->param_count; ++i) {
1406 LLVMArgInfo *ainfo = &cinfo->args [i + sig->hasthis];
1408 if (vretaddr && vret_arg_pindex == pindex)
1409 param_types [pindex ++] = IntPtrType ();
1410 ainfo->pindex = pindex;
1412 switch (ainfo->storage) {
1413 case LLVMArgVtypeInReg:
1414 for (j = 0; j < 2; ++j) {
1415 switch (ainfo->pair_storage [j]) {
1417 param_types [pindex ++] = LLVMIntType (sizeof (gpointer) * 8);
1422 g_assert_not_reached ();
1426 case LLVMArgVtypeByVal:
1427 param_types [pindex] = type_to_llvm_arg_type (ctx, ainfo->type);
1430 param_types [pindex] = LLVMPointerType (param_types [pindex], 0);
1433 case LLVMArgAsIArgs:
1434 if (ainfo->esize == 8)
1435 param_types [pindex] = LLVMArrayType (LLVMInt64Type (), ainfo->nslots);
1437 param_types [pindex] = LLVMArrayType (IntPtrType (), ainfo->nslots);
1440 case LLVMArgVtypeByRef:
1441 param_types [pindex] = type_to_llvm_arg_type (ctx, ainfo->type);
1444 param_types [pindex] = LLVMPointerType (param_types [pindex], 0);
1447 case LLVMArgAsFpArgs: {
1450 /* Emit dummy fp arguments if needed so the rest is passed on the stack */
1451 for (j = 0; j < ainfo->ndummy_fpargs; ++j)
1452 param_types [pindex ++] = LLVMDoubleType ();
1453 for (j = 0; j < ainfo->nslots; ++j)
1454 param_types [pindex ++] = ainfo->esize == 8 ? LLVMDoubleType () : LLVMFloatType ();
1457 case LLVMArgVtypeAsScalar:
1458 g_assert_not_reached ();
1460 case LLVMArgGsharedvtFixed:
1461 case LLVMArgGsharedvtFixedVtype:
1462 param_types [pindex ++] = LLVMPointerType (type_to_llvm_arg_type (ctx, ainfo->type), 0);
1464 case LLVMArgGsharedvtVariable:
1465 param_types [pindex ++] = LLVMPointerType (IntPtrType (), 0);
1468 param_types [pindex ++] = type_to_llvm_arg_type (ctx, ainfo->type);
1472 if (!ctx_ok (ctx)) {
1473 g_free (param_types);
1476 if (vretaddr && vret_arg_pindex == pindex)
1477 param_types [pindex ++] = IntPtrType ();
1478 if (ctx->llvm_only && cinfo->rgctx_arg) {
1479 /* Pass the rgctx as the last argument */
1480 cinfo->rgctx_arg_pindex = pindex;
1481 param_types [pindex] = ctx->module->ptr_type;
1485 res = LLVMFunctionType (ret_type, param_types, pindex, FALSE);
1486 g_free (param_types);
1492 sig_to_llvm_sig (EmitContext *ctx, MonoMethodSignature *sig)
1494 return sig_to_llvm_sig_full (ctx, sig, NULL);
1498 * LLVMFunctionType1:
1500 * Create an LLVM function type from the arguments.
1502 static G_GNUC_UNUSED LLVMTypeRef
1503 LLVMFunctionType0 (LLVMTypeRef ReturnType,
1506 return LLVMFunctionType (ReturnType, NULL, 0, IsVarArg);
1510 * LLVMFunctionType1:
1512 * Create an LLVM function type from the arguments.
1514 static G_GNUC_UNUSED LLVMTypeRef
1515 LLVMFunctionType1 (LLVMTypeRef ReturnType,
1516 LLVMTypeRef ParamType1,
1519 LLVMTypeRef param_types [1];
1521 param_types [0] = ParamType1;
1523 return LLVMFunctionType (ReturnType, param_types, 1, IsVarArg);
1527 * LLVMFunctionType2:
1529 * Create an LLVM function type from the arguments.
1531 static G_GNUC_UNUSED LLVMTypeRef
1532 LLVMFunctionType2 (LLVMTypeRef ReturnType,
1533 LLVMTypeRef ParamType1,
1534 LLVMTypeRef ParamType2,
1537 LLVMTypeRef param_types [2];
1539 param_types [0] = ParamType1;
1540 param_types [1] = ParamType2;
1542 return LLVMFunctionType (ReturnType, param_types, 2, IsVarArg);
1546 * LLVMFunctionType3:
1548 * Create an LLVM function type from the arguments.
1550 static G_GNUC_UNUSED LLVMTypeRef
1551 LLVMFunctionType3 (LLVMTypeRef ReturnType,
1552 LLVMTypeRef ParamType1,
1553 LLVMTypeRef ParamType2,
1554 LLVMTypeRef ParamType3,
1557 LLVMTypeRef param_types [3];
1559 param_types [0] = ParamType1;
1560 param_types [1] = ParamType2;
1561 param_types [2] = ParamType3;
1563 return LLVMFunctionType (ReturnType, param_types, 3, IsVarArg);
1566 static G_GNUC_UNUSED LLVMTypeRef
1567 LLVMFunctionType5 (LLVMTypeRef ReturnType,
1568 LLVMTypeRef ParamType1,
1569 LLVMTypeRef ParamType2,
1570 LLVMTypeRef ParamType3,
1571 LLVMTypeRef ParamType4,
1572 LLVMTypeRef ParamType5,
1575 LLVMTypeRef param_types [5];
1577 param_types [0] = ParamType1;
1578 param_types [1] = ParamType2;
1579 param_types [2] = ParamType3;
1580 param_types [3] = ParamType4;
1581 param_types [4] = ParamType5;
1583 return LLVMFunctionType (ReturnType, param_types, 5, IsVarArg);
1589 * Create an LLVM builder and remember it so it can be freed later.
1591 static LLVMBuilderRef
1592 create_builder (EmitContext *ctx)
1594 LLVMBuilderRef builder = LLVMCreateBuilder ();
1596 ctx->builders = g_slist_prepend_mempool (ctx->cfg->mempool, ctx->builders, builder);
1602 get_aotconst_name (MonoJumpInfoType type, gconstpointer data, int got_offset)
1607 case MONO_PATCH_INFO_INTERNAL_METHOD:
1608 name = g_strdup_printf ("jit_icall_%s", data);
1610 case MONO_PATCH_INFO_RGCTX_SLOT_INDEX: {
1611 MonoJumpInfoRgctxEntry *entry = (MonoJumpInfoRgctxEntry*)data;
1612 name = g_strdup_printf ("RGCTX_SLOT_INDEX_%s", mono_rgctx_info_type_to_str (entry->info_type));
1616 name = g_strdup_printf ("%s_%d", mono_ji_type_to_string (type), got_offset);
1624 get_aotconst_typed (EmitContext *ctx, MonoJumpInfoType type, gconstpointer data, LLVMTypeRef llvm_type)
1628 LLVMValueRef indexes [2];
1629 LLVMValueRef got_entry_addr, load;
1630 LLVMBuilderRef builder = ctx->builder;
1635 MonoJumpInfo tmp_ji;
1637 tmp_ji.data.target = data;
1639 MonoJumpInfo *ji = mono_aot_patch_info_dup (&tmp_ji);
1641 ji->next = cfg->patch_info;
1642 cfg->patch_info = ji;
1644 got_offset = mono_aot_get_got_offset (cfg->patch_info);
1645 ctx->module->max_got_offset = MAX (ctx->module->max_got_offset, got_offset);
1647 * If the got slot is shared, it means its initialized when the aot image is loaded, so we don't need to
1648 * explicitly initialize it.
1650 if (!mono_aot_is_shared_got_offset (got_offset)) {
1651 //mono_print_ji (ji);
1653 ctx->has_got_access = TRUE;
1656 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
1657 indexes [1] = LLVMConstInt (LLVMInt32Type (), (gssize)got_offset, FALSE);
1658 got_entry_addr = LLVMBuildGEP (builder, ctx->module->got_var, indexes, 2, "");
1660 name = get_aotconst_name (type, data, got_offset);
1662 load = LLVMBuildLoad (builder, got_entry_addr, "");
1663 load = convert (ctx, load, llvm_type);
1664 LLVMSetValueName (load, name ? name : "");
1666 load = LLVMBuildLoad (builder, got_entry_addr, name ? name : "");
1669 //set_invariant_load_flag (load);
1675 get_aotconst (EmitContext *ctx, MonoJumpInfoType type, gconstpointer data)
1677 return get_aotconst_typed (ctx, type, data, NULL);
1681 get_callee (EmitContext *ctx, LLVMTypeRef llvm_sig, MonoJumpInfoType type, gconstpointer data)
1683 LLVMValueRef callee;
1685 if (ctx->llvm_only) {
1686 callee_name = mono_aot_get_direct_call_symbol (type, data);
1688 /* Directly callable */
1690 callee = (LLVMValueRef)g_hash_table_lookup (ctx->module->direct_callables, callee_name);
1692 callee = LLVMAddFunction (ctx->lmodule, callee_name, llvm_sig);
1694 LLVMSetVisibility (callee, LLVMHiddenVisibility);
1696 g_hash_table_insert (ctx->module->direct_callables, (char*)callee_name, callee);
1698 /* LLVMTypeRef's are uniqued */
1699 if (LLVMGetElementType (LLVMTypeOf (callee)) != llvm_sig)
1700 return LLVMConstBitCast (callee, LLVMPointerType (llvm_sig, 0));
1702 g_free (callee_name);
1708 * Calls are made through the GOT.
1710 return get_aotconst_typed (ctx, type, data, LLVMPointerType (llvm_sig, 0));
1712 MonoJumpInfo *ji = NULL;
1714 callee_name = mono_aot_get_plt_symbol (type, data);
1718 if (ctx->cfg->compile_aot)
1719 /* Add a patch so referenced wrappers can be compiled in full aot mode */
1720 mono_add_patch_info (ctx->cfg, 0, type, data);
1723 callee = (LLVMValueRef)g_hash_table_lookup (ctx->module->plt_entries, callee_name);
1725 callee = LLVMAddFunction (ctx->lmodule, callee_name, llvm_sig);
1727 LLVMSetVisibility (callee, LLVMHiddenVisibility);
1729 g_hash_table_insert (ctx->module->plt_entries, (char*)callee_name, callee);
1732 if (ctx->cfg->compile_aot) {
1733 ji = g_new0 (MonoJumpInfo, 1);
1735 ji->data.target = data;
1737 g_hash_table_insert (ctx->module->plt_entries_ji, ji, callee);
1745 emit_jit_callee (EmitContext *ctx, const char *name, LLVMTypeRef llvm_sig, gpointer target)
1747 #if LLVM_API_VERSION > 100
1748 LLVMValueRef tramp_var = LLVMAddGlobal (ctx->lmodule, LLVMPointerType (llvm_sig, 0), name);
1749 LLVMSetInitializer (tramp_var, LLVMConstIntToPtr (LLVMConstInt (LLVMInt64Type (), (guint64)(size_t)target, FALSE), LLVMPointerType (llvm_sig, 0)));
1750 LLVMSetLinkage (tramp_var, LLVMExternalLinkage);
1751 LLVMValueRef callee = LLVMBuildLoad (ctx->builder, tramp_var, "");
1754 LLVMValueRef callee = LLVMAddFunction (ctx->lmodule, "", llvm_sig);
1755 LLVMAddGlobalMapping (ctx->module->ee, callee, target);
1761 get_handler_clause (MonoCompile *cfg, MonoBasicBlock *bb)
1763 MonoMethodHeader *header = cfg->header;
1764 MonoExceptionClause *clause;
1768 if (bb->region != -1 && MONO_BBLOCK_IS_IN_REGION (bb, MONO_REGION_TRY))
1769 return (bb->region >> 8) - 1;
1772 for (i = 0; i < header->num_clauses; ++i) {
1773 clause = &header->clauses [i];
1775 if (MONO_OFFSET_IN_CLAUSE (clause, bb->real_offset) && clause->flags == MONO_EXCEPTION_CLAUSE_NONE)
1782 static MonoExceptionClause *
1783 get_most_deep_clause (MonoCompile *cfg, EmitContext *ctx, MonoBasicBlock *bb)
1785 if (bb == cfg->bb_init)
1787 // Since they're sorted by nesting we just need
1788 // the first one that the bb is a member of
1789 for (int i = 0; i < cfg->header->num_clauses; i++) {
1790 MonoExceptionClause *curr = &cfg->header->clauses [i];
1792 if (MONO_OFFSET_IN_CLAUSE (curr, bb->real_offset))
1800 set_metadata_flag (LLVMValueRef v, const char *flag_name)
1802 LLVMValueRef md_arg;
1805 md_kind = LLVMGetMDKindID (flag_name, strlen (flag_name));
1806 md_arg = LLVMMDString ("mono", 4);
1807 LLVMSetMetadata (v, md_kind, LLVMMDNode (&md_arg, 1));
1811 set_invariant_load_flag (LLVMValueRef v)
1813 LLVMValueRef md_arg;
1815 const char *flag_name;
1817 // FIXME: Cache this
1818 flag_name = "invariant.load";
1819 md_kind = LLVMGetMDKindID (flag_name, strlen (flag_name));
1820 md_arg = LLVMMDString ("<index>", strlen ("<index>"));
1821 LLVMSetMetadata (v, md_kind, LLVMMDNode (&md_arg, 1));
1827 * Emit an LLVM call or invoke instruction depending on whenever the call is inside
1831 emit_call (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, LLVMValueRef callee, LLVMValueRef *args, int pindex)
1833 MonoCompile *cfg = ctx->cfg;
1834 LLVMValueRef lcall = NULL;
1835 LLVMBuilderRef builder = *builder_ref;
1836 MonoExceptionClause *clause;
1838 if (ctx->llvm_only) {
1839 clause = get_most_deep_clause (cfg, ctx, bb);
1842 g_assert (clause->flags == MONO_EXCEPTION_CLAUSE_NONE || clause->flags == MONO_EXCEPTION_CLAUSE_FINALLY);
1845 * Have to use an invoke instead of a call, branching to the
1846 * handler bblock of the clause containing this bblock.
1848 intptr_t key = CLAUSE_END(clause);
1850 LLVMBasicBlockRef lpad_bb = (LLVMBasicBlockRef)g_hash_table_lookup (ctx->exc_meta, (gconstpointer)key);
1852 // FIXME: Find the one that has the lowest end bound for the right start address
1853 // FIXME: Finally + nesting
1856 LLVMBasicBlockRef noex_bb = gen_bb (ctx, "CALL_NOEX_BB");
1859 lcall = LLVMBuildInvoke (builder, callee, args, pindex, noex_bb, lpad_bb, "");
1861 builder = ctx->builder = create_builder (ctx);
1862 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
1864 ctx->bblocks [bb->block_num].end_bblock = noex_bb;
1868 int clause_index = get_handler_clause (cfg, bb);
1870 if (clause_index != -1) {
1871 MonoMethodHeader *header = cfg->header;
1872 MonoExceptionClause *ec = &header->clauses [clause_index];
1873 MonoBasicBlock *tblock;
1874 LLVMBasicBlockRef ex_bb, noex_bb;
1877 * Have to use an invoke instead of a call, branching to the
1878 * handler bblock of the clause containing this bblock.
1881 g_assert (ec->flags == MONO_EXCEPTION_CLAUSE_NONE || ec->flags == MONO_EXCEPTION_CLAUSE_FINALLY);
1883 tblock = cfg->cil_offset_to_bb [ec->handler_offset];
1886 ctx->bblocks [tblock->block_num].invoke_target = TRUE;
1888 ex_bb = get_bb (ctx, tblock);
1890 noex_bb = gen_bb (ctx, "NOEX_BB");
1893 lcall = LLVMBuildInvoke (builder, callee, args, pindex, noex_bb, ex_bb, "");
1895 builder = ctx->builder = create_builder (ctx);
1896 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
1898 ctx->bblocks [bb->block_num].end_bblock = noex_bb;
1903 lcall = LLVMBuildCall (builder, callee, args, pindex, "");
1904 ctx->builder = builder;
1908 *builder_ref = ctx->builder;
1914 emit_load_general (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, int size, LLVMValueRef addr, LLVMValueRef base, const char *name, gboolean is_faulting, BarrierKind barrier)
1916 const char *intrins_name;
1917 LLVMValueRef args [16], res;
1918 LLVMTypeRef addr_type;
1919 gboolean use_intrinsics = TRUE;
1921 #if LLVM_API_VERSION > 100
1922 if (is_faulting && bb->region != -1 && !ctx->cfg->llvm_only) {
1923 /* The llvm.mono.load/store intrinsics are not supported by this llvm version, emit an explicit null check instead */
1926 cmp = LLVMBuildICmp (*builder_ref, LLVMIntEQ, base, LLVMConstNull (LLVMTypeOf (base)), "");
1927 emit_cond_system_exception (ctx, bb, "NullReferenceException", cmp);
1928 *builder_ref = ctx->builder;
1929 use_intrinsics = FALSE;
1933 if (is_faulting && bb->region != -1 && !ctx->cfg->llvm_only && use_intrinsics) {
1934 LLVMAtomicOrdering ordering;
1937 case LLVM_BARRIER_NONE:
1938 ordering = LLVMAtomicOrderingNotAtomic;
1940 case LLVM_BARRIER_ACQ:
1941 ordering = LLVMAtomicOrderingAcquire;
1943 case LLVM_BARRIER_SEQ:
1944 ordering = LLVMAtomicOrderingSequentiallyConsistent;
1947 g_assert_not_reached ();
1952 * We handle loads which can fault by calling a mono specific intrinsic
1953 * using an invoke, so they are handled properly inside try blocks.
1954 * We can't use this outside clauses, since LLVM optimizes intrinsics which
1955 * are marked with IntrReadArgMem.
1959 intrins_name = "llvm.mono.load.i8.p0i8";
1962 intrins_name = "llvm.mono.load.i16.p0i16";
1965 intrins_name = "llvm.mono.load.i32.p0i32";
1968 intrins_name = "llvm.mono.load.i64.p0i64";
1971 g_assert_not_reached ();
1974 addr_type = LLVMTypeOf (addr);
1975 if (addr_type == LLVMPointerType (LLVMDoubleType (), 0) || addr_type == LLVMPointerType (LLVMFloatType (), 0))
1976 addr = LLVMBuildBitCast (*builder_ref, addr, LLVMPointerType (LLVMIntType (size * 8), 0), "");
1979 args [1] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
1980 args [2] = LLVMConstInt (LLVMInt1Type (), TRUE, FALSE);
1981 args [3] = LLVMConstInt (LLVMInt32Type (), ordering, FALSE);
1982 res = emit_call (ctx, bb, builder_ref, get_intrinsic (ctx, intrins_name), args, 4);
1984 if (addr_type == LLVMPointerType (LLVMDoubleType (), 0))
1985 res = LLVMBuildBitCast (*builder_ref, res, LLVMDoubleType (), "");
1986 else if (addr_type == LLVMPointerType (LLVMFloatType (), 0))
1987 res = LLVMBuildBitCast (*builder_ref, res, LLVMFloatType (), "");
1994 * We emit volatile loads for loads which can fault, because otherwise
1995 * LLVM will generate invalid code when encountering a load from a
1998 if (barrier != LLVM_BARRIER_NONE)
1999 res = mono_llvm_build_atomic_load (*builder_ref, addr, name, is_faulting, size, barrier);
2001 res = mono_llvm_build_load (*builder_ref, addr, name, is_faulting);
2003 /* Mark it with a custom metadata */
2006 set_metadata_flag (res, "mono.faulting.load");
2014 emit_load (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, int size, LLVMValueRef addr, const char *name, gboolean is_faulting)
2016 return emit_load_general (ctx, bb, builder_ref, size, addr, addr, name, is_faulting, LLVM_BARRIER_NONE);
2020 emit_store_general (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, int size, LLVMValueRef value, LLVMValueRef addr, LLVMValueRef base, gboolean is_faulting, BarrierKind barrier)
2022 const char *intrins_name;
2023 LLVMValueRef args [16];
2024 gboolean use_intrinsics = TRUE;
2026 #if LLVM_API_VERSION > 100
2027 if (is_faulting && bb->region != -1 && !ctx->cfg->llvm_only) {
2028 /* The llvm.mono.load/store intrinsics are not supported by this llvm version, emit an explicit null check instead */
2029 LLVMValueRef cmp = LLVMBuildICmp (*builder_ref, LLVMIntEQ, base, LLVMConstNull (LLVMTypeOf (base)), "");
2030 emit_cond_system_exception (ctx, bb, "NullReferenceException", cmp);
2031 *builder_ref = ctx->builder;
2032 use_intrinsics = FALSE;
2036 if (is_faulting && bb->region != -1 && !ctx->cfg->llvm_only && use_intrinsics) {
2037 LLVMAtomicOrdering ordering;
2040 case LLVM_BARRIER_NONE:
2041 ordering = LLVMAtomicOrderingNotAtomic;
2043 case LLVM_BARRIER_REL:
2044 ordering = LLVMAtomicOrderingRelease;
2046 case LLVM_BARRIER_SEQ:
2047 ordering = LLVMAtomicOrderingSequentiallyConsistent;
2050 g_assert_not_reached ();
2056 intrins_name = "llvm.mono.store.i8.p0i8";
2059 intrins_name = "llvm.mono.store.i16.p0i16";
2062 intrins_name = "llvm.mono.store.i32.p0i32";
2065 intrins_name = "llvm.mono.store.i64.p0i64";
2068 g_assert_not_reached ();
2071 if (LLVMTypeOf (value) == LLVMDoubleType () || LLVMTypeOf (value) == LLVMFloatType ()) {
2072 value = LLVMBuildBitCast (*builder_ref, value, LLVMIntType (size * 8), "");
2073 addr = LLVMBuildBitCast (*builder_ref, addr, LLVMPointerType (LLVMIntType (size * 8), 0), "");
2078 args [2] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
2079 args [3] = LLVMConstInt (LLVMInt1Type (), TRUE, FALSE);
2080 args [4] = LLVMConstInt (LLVMInt32Type (), ordering, FALSE);
2081 emit_call (ctx, bb, builder_ref, get_intrinsic (ctx, intrins_name), args, 5);
2083 if (barrier != LLVM_BARRIER_NONE)
2084 mono_llvm_build_aligned_store (*builder_ref, value, addr, barrier, size);
2086 mono_llvm_build_store (*builder_ref, value, addr, is_faulting, barrier);
2091 emit_store (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, int size, LLVMValueRef value, LLVMValueRef addr, LLVMValueRef base, gboolean is_faulting)
2093 emit_store_general (ctx, bb, builder_ref, size, value, addr, base, is_faulting, LLVM_BARRIER_NONE);
2097 * emit_cond_system_exception:
2099 * Emit code to throw the exception EXC_TYPE if the condition CMP is false.
2100 * Might set the ctx exception.
2103 emit_cond_system_exception (EmitContext *ctx, MonoBasicBlock *bb, const char *exc_type, LLVMValueRef cmp)
2105 LLVMBasicBlockRef ex_bb, ex2_bb = NULL, noex_bb;
2106 LLVMBuilderRef builder;
2107 MonoClass *exc_class;
2108 LLVMValueRef args [2];
2109 LLVMValueRef callee;
2110 gboolean no_pc = FALSE;
2112 if (IS_TARGET_AMD64)
2113 /* Some platforms don't require the pc argument */
2116 ex_bb = gen_bb (ctx, "EX_BB");
2118 ex2_bb = gen_bb (ctx, "EX2_BB");
2119 noex_bb = gen_bb (ctx, "NOEX_BB");
2121 LLVMBuildCondBr (ctx->builder, cmp, ex_bb, noex_bb);
2123 exc_class = mono_class_load_from_name (mono_get_corlib (), "System", exc_type);
2125 /* Emit exception throwing code */
2126 ctx->builder = builder = create_builder (ctx);
2127 LLVMPositionBuilderAtEnd (builder, ex_bb);
2129 if (ctx->cfg->llvm_only) {
2130 static LLVMTypeRef sig;
2133 sig = LLVMFunctionType1 (LLVMVoidType (), LLVMInt32Type (), FALSE);
2134 callee = get_callee (ctx, sig, MONO_PATCH_INFO_JIT_ICALL_ADDR, "mono_llvm_throw_corlib_exception");
2136 LLVMBuildBr (builder, ex2_bb);
2138 ctx->builder = builder = create_builder (ctx);
2139 LLVMPositionBuilderAtEnd (ctx->builder, ex2_bb);
2141 args [0] = LLVMConstInt (LLVMInt32Type (), exc_class->type_token - MONO_TOKEN_TYPE_DEF, FALSE);
2142 emit_call (ctx, bb, &builder, callee, args, 1);
2143 LLVMBuildUnreachable (builder);
2145 ctx->builder = builder = create_builder (ctx);
2146 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
2148 ctx->bblocks [bb->block_num].end_bblock = noex_bb;
2154 callee = ctx->module->throw_corlib_exception;
2157 const char *icall_name;
2160 sig = LLVMFunctionType1 (LLVMVoidType (), LLVMInt32Type (), FALSE);
2162 sig = LLVMFunctionType2 (LLVMVoidType (), LLVMInt32Type (), LLVMPointerType (LLVMInt8Type (), 0), FALSE);
2163 icall_name = "llvm_throw_corlib_exception_abs_trampoline";
2165 if (ctx->cfg->compile_aot) {
2166 callee = get_callee (ctx, sig, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
2169 * Differences between the LLVM/non-LLVM throw corlib exception trampoline:
2170 * - On x86, LLVM generated code doesn't push the arguments
2171 * - The trampoline takes the throw address as an arguments, not a pc offset.
2173 gpointer target = resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
2174 callee = emit_jit_callee (ctx, "llvm_throw_corlib_exception_trampoline", sig, target);
2176 #if LLVM_API_VERSION > 100
2178 * Make sure that ex_bb starts with the invoke, so the block address points to it, and not to the load
2179 * added by emit_jit_callee ().
2181 ex2_bb = gen_bb (ctx, "EX2_BB");
2182 LLVMBuildBr (builder, ex2_bb);
2185 ctx->builder = builder = create_builder (ctx);
2186 LLVMPositionBuilderAtEnd (ctx->builder, ex2_bb);
2188 mono_memory_barrier ();
2189 ctx->module->throw_corlib_exception = callee;
2194 args [0] = LLVMConstInt (LLVMInt32Type (), exc_class->type_token - MONO_TOKEN_TYPE_DEF, FALSE);
2197 * The LLVM mono branch contains changes so a block address can be passed as an
2198 * argument to a call.
2201 emit_call (ctx, bb, &builder, callee, args, 1);
2203 args [1] = LLVMBlockAddress (ctx->lmethod, ex_bb);
2204 emit_call (ctx, bb, &builder, callee, args, 2);
2207 LLVMBuildUnreachable (builder);
2209 ctx->builder = builder = create_builder (ctx);
2210 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
2212 ctx->bblocks [bb->block_num].end_bblock = noex_bb;
2219 * emit_args_to_vtype:
2221 * Emit code to store the vtype in the arguments args to the address ADDRESS.
2224 emit_args_to_vtype (EmitContext *ctx, LLVMBuilderRef builder, MonoType *t, LLVMValueRef address, LLVMArgInfo *ainfo, LLVMValueRef *args)
2226 int j, size, nslots;
2228 size = mono_class_value_size (mono_class_from_mono_type (t), NULL);
2230 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (t))) {
2231 address = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (LLVMInt8Type (), 0), "");
2234 if (ainfo->storage == LLVMArgAsFpArgs)
2235 nslots = ainfo->nslots;
2239 for (j = 0; j < nslots; ++j) {
2240 LLVMValueRef index [2], addr, daddr;
2241 int part_size = size > sizeof (gpointer) ? sizeof (gpointer) : size;
2242 LLVMTypeRef part_type;
2244 while (part_size != 1 && part_size != 2 && part_size != 4 && part_size < 8)
2247 if (ainfo->pair_storage [j] == LLVMArgNone)
2250 switch (ainfo->pair_storage [j]) {
2251 case LLVMArgInIReg: {
2252 part_type = LLVMIntType (part_size * 8);
2253 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (t))) {
2254 index [0] = LLVMConstInt (LLVMInt32Type (), j * sizeof (gpointer), FALSE);
2255 addr = LLVMBuildGEP (builder, address, index, 1, "");
2257 daddr = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (IntPtrType (), 0), "");
2258 index [0] = LLVMConstInt (LLVMInt32Type (), j, FALSE);
2259 addr = LLVMBuildGEP (builder, daddr, index, 1, "");
2261 LLVMBuildStore (builder, convert (ctx, args [j], part_type), LLVMBuildBitCast (ctx->builder, addr, LLVMPointerType (part_type, 0), ""));
2264 case LLVMArgInFPReg: {
2265 LLVMTypeRef arg_type;
2267 if (ainfo->esize == 8)
2268 arg_type = LLVMDoubleType ();
2270 arg_type = LLVMFloatType ();
2272 index [0] = LLVMConstInt (LLVMInt32Type (), j, FALSE);
2273 daddr = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (arg_type, 0), "");
2274 addr = LLVMBuildGEP (builder, daddr, index, 1, "");
2275 LLVMBuildStore (builder, args [j], addr);
2281 g_assert_not_reached ();
2284 size -= sizeof (gpointer);
2289 * emit_vtype_to_args:
2291 * Emit code to load a vtype at address ADDRESS into scalar arguments. Store the arguments
2292 * into ARGS, and the number of arguments into NARGS.
2295 emit_vtype_to_args (EmitContext *ctx, LLVMBuilderRef builder, MonoType *t, LLVMValueRef address, LLVMArgInfo *ainfo, LLVMValueRef *args, guint32 *nargs)
2298 int j, size, nslots;
2299 LLVMTypeRef arg_type;
2301 size = get_vtype_size (t);
2303 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (t)))
2304 address = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (LLVMInt8Type (), 0), "");
2306 if (ainfo->storage == LLVMArgAsFpArgs)
2307 nslots = ainfo->nslots;
2310 for (j = 0; j < nslots; ++j) {
2311 LLVMValueRef index [2], addr, daddr;
2312 int partsize = size > sizeof (gpointer) ? sizeof (gpointer) : size;
2314 if (ainfo->pair_storage [j] == LLVMArgNone)
2317 switch (ainfo->pair_storage [j]) {
2319 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (t))) {
2320 index [0] = LLVMConstInt (LLVMInt32Type (), j * sizeof (gpointer), FALSE);
2321 addr = LLVMBuildGEP (builder, address, index, 1, "");
2323 daddr = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (IntPtrType (), 0), "");
2324 index [0] = LLVMConstInt (LLVMInt32Type (), j, FALSE);
2325 addr = LLVMBuildGEP (builder, daddr, index, 1, "");
2327 args [pindex ++] = convert (ctx, LLVMBuildLoad (builder, LLVMBuildBitCast (ctx->builder, addr, LLVMPointerType (LLVMIntType (partsize * 8), 0), ""), ""), IntPtrType ());
2329 case LLVMArgInFPReg:
2330 if (ainfo->esize == 8)
2331 arg_type = LLVMDoubleType ();
2333 arg_type = LLVMFloatType ();
2334 daddr = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (arg_type, 0), "");
2335 index [0] = LLVMConstInt (LLVMInt32Type (), j, FALSE);
2336 addr = LLVMBuildGEP (builder, daddr, index, 1, "");
2337 args [pindex ++] = LLVMBuildLoad (builder, addr, "");
2342 g_assert_not_reached ();
2344 size -= sizeof (gpointer);
2351 build_alloca_llvm_type_name (EmitContext *ctx, LLVMTypeRef t, int align, const char *name)
2354 * Have to place all alloca's at the end of the entry bb, since otherwise they would
2355 * get executed every time control reaches them.
2357 LLVMPositionBuilder (ctx->alloca_builder, get_bb (ctx, ctx->cfg->bb_entry), ctx->last_alloca);
2359 ctx->last_alloca = mono_llvm_build_alloca (ctx->alloca_builder, t, NULL, align, name);
2360 return ctx->last_alloca;
2364 build_alloca_llvm_type (EmitContext *ctx, LLVMTypeRef t, int align)
2366 return build_alloca_llvm_type_name (ctx, t, align, "");
2370 build_alloca (EmitContext *ctx, MonoType *t)
2372 MonoClass *k = mono_class_from_mono_type (t);
2375 g_assert (!mini_is_gsharedvt_variable_type (t));
2377 if (MONO_CLASS_IS_SIMD (ctx->cfg, k))
2380 align = mono_class_min_align (k);
2382 /* Sometimes align is not a power of 2 */
2383 while (mono_is_power_of_two (align) == -1)
2386 return build_alloca_llvm_type (ctx, type_to_llvm_type (ctx, t), align);
2390 emit_gsharedvt_ldaddr (EmitContext *ctx, int vreg)
2394 * Compute the address of the local as gsharedvt_locals_var + gsharedvt_info_var->locals_offsets [idx].
2396 MonoCompile *cfg = ctx->cfg;
2397 LLVMBuilderRef builder = ctx->builder;
2398 LLVMValueRef offset, offset_var;
2399 LLVMValueRef info_var = ctx->values [cfg->gsharedvt_info_var->dreg];
2400 LLVMValueRef locals_var = ctx->values [cfg->gsharedvt_locals_var->dreg];
2404 g_assert (info_var);
2405 g_assert (locals_var);
2407 int idx = cfg->gsharedvt_vreg_to_idx [vreg] - 1;
2409 offset = LLVMConstInt (LLVMInt32Type (), MONO_STRUCT_OFFSET (MonoGSharedVtMethodRuntimeInfo, entries) + (idx * sizeof (gpointer)), FALSE);
2410 ptr = LLVMBuildAdd (builder, convert (ctx, info_var, IntPtrType ()), convert (ctx, offset, IntPtrType ()), "");
2412 name = g_strdup_printf ("gsharedvt_local_%d_offset", vreg);
2413 offset_var = LLVMBuildLoad (builder, convert (ctx, ptr, LLVMPointerType (LLVMInt32Type (), 0)), name);
2415 return LLVMBuildAdd (builder, convert (ctx, locals_var, IntPtrType ()), convert (ctx, offset_var, IntPtrType ()), "");
2419 * Put the global into the 'llvm.used' array to prevent it from being optimized away.
2422 mark_as_used (MonoLLVMModule *module, LLVMValueRef global)
2425 module->used = g_ptr_array_sized_new (16);
2426 g_ptr_array_add (module->used, global);
2430 emit_llvm_used (MonoLLVMModule *module)
2432 LLVMModuleRef lmodule = module->lmodule;
2433 LLVMTypeRef used_type;
2434 LLVMValueRef used, *used_elem;
2440 used_type = LLVMArrayType (LLVMPointerType (LLVMInt8Type (), 0), module->used->len);
2441 used = LLVMAddGlobal (lmodule, used_type, "llvm.used");
2442 used_elem = g_new0 (LLVMValueRef, module->used->len);
2443 for (i = 0; i < module->used->len; ++i)
2444 used_elem [i] = LLVMConstBitCast ((LLVMValueRef)g_ptr_array_index (module->used, i), LLVMPointerType (LLVMInt8Type (), 0));
2445 LLVMSetInitializer (used, LLVMConstArray (LLVMPointerType (LLVMInt8Type (), 0), used_elem, module->used->len));
2446 LLVMSetLinkage (used, LLVMAppendingLinkage);
2447 LLVMSetSection (used, "llvm.metadata");
2453 * Emit a function mapping method indexes to their code
2456 emit_get_method (MonoLLVMModule *module)
2458 LLVMModuleRef lmodule = module->lmodule;
2459 LLVMValueRef func, switch_ins, m;
2460 LLVMBasicBlockRef entry_bb, fail_bb, bb, code_start_bb, code_end_bb;
2461 LLVMBasicBlockRef *bbs;
2463 LLVMBuilderRef builder = LLVMCreateBuilder ();
2468 * Emit a switch statement. Emitting a table of function addresses is smaller/faster,
2469 * but generating code seems safer.
2471 rtype = LLVMPointerType (LLVMInt8Type (), 0);
2472 func = LLVMAddFunction (lmodule, module->get_method_symbol, LLVMFunctionType1 (rtype, LLVMInt32Type (), FALSE));
2473 LLVMSetLinkage (func, LLVMExternalLinkage);
2474 LLVMSetVisibility (func, LLVMHiddenVisibility);
2475 LLVMAddFunctionAttr (func, LLVMNoUnwindAttribute);
2476 module->get_method = func;
2478 entry_bb = LLVMAppendBasicBlock (func, "ENTRY");
2481 * Return llvm_code_start/llvm_code_end when called with -1/-2.
2482 * Hopefully, the toolchain doesn't reorder these functions. If it does,
2483 * then we will have to find another solution.
2486 name = g_strdup_printf ("BB_CODE_START");
2487 code_start_bb = LLVMAppendBasicBlock (func, name);
2489 LLVMPositionBuilderAtEnd (builder, code_start_bb);
2490 LLVMBuildRet (builder, LLVMBuildBitCast (builder, module->code_start, rtype, ""));
2492 name = g_strdup_printf ("BB_CODE_END");
2493 code_end_bb = LLVMAppendBasicBlock (func, name);
2495 LLVMPositionBuilderAtEnd (builder, code_end_bb);
2496 LLVMBuildRet (builder, LLVMBuildBitCast (builder, module->code_end, rtype, ""));
2498 bbs = g_new0 (LLVMBasicBlockRef, module->max_method_idx + 1);
2499 for (i = 0; i < module->max_method_idx + 1; ++i) {
2500 name = g_strdup_printf ("BB_%d", i);
2501 bb = LLVMAppendBasicBlock (func, name);
2505 LLVMPositionBuilderAtEnd (builder, bb);
2507 m = (LLVMValueRef)g_hash_table_lookup (module->idx_to_lmethod, GINT_TO_POINTER (i));
2509 LLVMBuildRet (builder, LLVMBuildBitCast (builder, m, rtype, ""));
2511 LLVMBuildRet (builder, LLVMConstNull (rtype));
2514 fail_bb = LLVMAppendBasicBlock (func, "FAIL");
2515 LLVMPositionBuilderAtEnd (builder, fail_bb);
2516 LLVMBuildRet (builder, LLVMConstNull (rtype));
2518 LLVMPositionBuilderAtEnd (builder, entry_bb);
2520 switch_ins = LLVMBuildSwitch (builder, LLVMGetParam (func, 0), fail_bb, 0);
2521 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), -1, FALSE), code_start_bb);
2522 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), -2, FALSE), code_end_bb);
2523 for (i = 0; i < module->max_method_idx + 1; ++i) {
2524 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), i, FALSE), bbs [i]);
2527 mark_as_used (module, func);
2529 LLVMDisposeBuilder (builder);
2533 * emit_get_unbox_tramp:
2535 * Emit a function mapping method indexes to their unbox trampoline
2538 emit_get_unbox_tramp (MonoLLVMModule *module)
2540 LLVMModuleRef lmodule = module->lmodule;
2541 LLVMValueRef func, switch_ins, m;
2542 LLVMBasicBlockRef entry_bb, fail_bb, bb;
2543 LLVMBasicBlockRef *bbs;
2545 LLVMBuilderRef builder = LLVMCreateBuilder ();
2549 /* Similar to emit_get_method () */
2551 rtype = LLVMPointerType (LLVMInt8Type (), 0);
2552 func = LLVMAddFunction (lmodule, module->get_unbox_tramp_symbol, LLVMFunctionType1 (rtype, LLVMInt32Type (), FALSE));
2553 LLVMSetLinkage (func, LLVMExternalLinkage);
2554 LLVMSetVisibility (func, LLVMHiddenVisibility);
2555 LLVMAddFunctionAttr (func, LLVMNoUnwindAttribute);
2556 module->get_unbox_tramp = func;
2558 entry_bb = LLVMAppendBasicBlock (func, "ENTRY");
2560 bbs = g_new0 (LLVMBasicBlockRef, module->max_method_idx + 1);
2561 for (i = 0; i < module->max_method_idx + 1; ++i) {
2562 m = (LLVMValueRef)g_hash_table_lookup (module->idx_to_unbox_tramp, GINT_TO_POINTER (i));
2566 name = g_strdup_printf ("BB_%d", i);
2567 bb = LLVMAppendBasicBlock (func, name);
2571 LLVMPositionBuilderAtEnd (builder, bb);
2573 LLVMBuildRet (builder, LLVMBuildBitCast (builder, m, rtype, ""));
2576 fail_bb = LLVMAppendBasicBlock (func, "FAIL");
2577 LLVMPositionBuilderAtEnd (builder, fail_bb);
2578 LLVMBuildRet (builder, LLVMConstNull (rtype));
2580 LLVMPositionBuilderAtEnd (builder, entry_bb);
2582 switch_ins = LLVMBuildSwitch (builder, LLVMGetParam (func, 0), fail_bb, 0);
2583 for (i = 0; i < module->max_method_idx + 1; ++i) {
2584 m = (LLVMValueRef)g_hash_table_lookup (module->idx_to_unbox_tramp, GINT_TO_POINTER (i));
2588 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), i, FALSE), bbs [i]);
2591 mark_as_used (module, func);
2592 LLVMDisposeBuilder (builder);
2595 /* Add a function to mark the beginning of LLVM code */
2597 emit_llvm_code_start (MonoLLVMModule *module)
2599 LLVMModuleRef lmodule = module->lmodule;
2601 LLVMBasicBlockRef entry_bb;
2602 LLVMBuilderRef builder;
2604 func = LLVMAddFunction (lmodule, "llvm_code_start", LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE));
2605 LLVMSetLinkage (func, LLVMInternalLinkage);
2606 LLVMAddFunctionAttr (func, LLVMNoUnwindAttribute);
2607 module->code_start = func;
2608 entry_bb = LLVMAppendBasicBlock (func, "ENTRY");
2609 builder = LLVMCreateBuilder ();
2610 LLVMPositionBuilderAtEnd (builder, entry_bb);
2611 LLVMBuildRetVoid (builder);
2612 LLVMDisposeBuilder (builder);
2616 emit_init_icall_wrapper (MonoLLVMModule *module, const char *name, const char *icall_name, int subtype)
2618 LLVMModuleRef lmodule = module->lmodule;
2619 LLVMValueRef func, indexes [2], got_entry_addr, args [16], callee;
2620 LLVMBasicBlockRef entry_bb;
2621 LLVMBuilderRef builder;
2628 func = LLVMAddFunction (lmodule, name, LLVMFunctionType1 (LLVMVoidType (), LLVMInt32Type (), FALSE));
2629 sig = LLVMFunctionType2 (LLVMVoidType (), IntPtrType (), LLVMInt32Type (), FALSE);
2634 func = LLVMAddFunction (lmodule, name, LLVMFunctionType2 (LLVMVoidType (), LLVMInt32Type (), IntPtrType (), FALSE));
2635 sig = LLVMFunctionType3 (LLVMVoidType (), IntPtrType (), LLVMInt32Type (), IntPtrType (), FALSE);
2638 func = LLVMAddFunction (lmodule, name, LLVMFunctionType2 (LLVMVoidType (), LLVMInt32Type (), ObjRefType (), FALSE));
2639 sig = LLVMFunctionType3 (LLVMVoidType (), IntPtrType (), LLVMInt32Type (), ObjRefType (), FALSE);
2642 g_assert_not_reached ();
2644 LLVMSetLinkage (func, LLVMInternalLinkage);
2645 LLVMAddFunctionAttr (func, LLVMNoInlineAttribute);
2646 mono_llvm_set_preserveall_cc (func);
2647 entry_bb = LLVMAppendBasicBlock (func, "ENTRY");
2648 builder = LLVMCreateBuilder ();
2649 LLVMPositionBuilderAtEnd (builder, entry_bb);
2652 ji = g_new0 (MonoJumpInfo, 1);
2653 ji->type = MONO_PATCH_INFO_AOT_MODULE;
2654 ji = mono_aot_patch_info_dup (ji);
2655 got_offset = mono_aot_get_got_offset (ji);
2656 module->max_got_offset = MAX (module->max_got_offset, got_offset);
2657 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
2658 indexes [1] = LLVMConstInt (LLVMInt32Type (), got_offset, FALSE);
2659 got_entry_addr = LLVMBuildGEP (builder, module->got_var, indexes, 2, "");
2660 args [0] = LLVMBuildPtrToInt (builder, LLVMBuildLoad (builder, got_entry_addr, ""), IntPtrType (), "");
2661 args [1] = LLVMGetParam (func, 0);
2663 args [2] = LLVMGetParam (func, 1);
2665 ji = g_new0 (MonoJumpInfo, 1);
2666 ji->type = MONO_PATCH_INFO_INTERNAL_METHOD;
2667 ji->data.name = icall_name;
2668 ji = mono_aot_patch_info_dup (ji);
2669 got_offset = mono_aot_get_got_offset (ji);
2670 module->max_got_offset = MAX (module->max_got_offset, got_offset);
2671 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
2672 indexes [1] = LLVMConstInt (LLVMInt32Type (), got_offset, FALSE);
2673 got_entry_addr = LLVMBuildGEP (builder, module->got_var, indexes, 2, "");
2674 callee = LLVMBuildLoad (builder, got_entry_addr, "");
2675 callee = LLVMBuildBitCast (builder, callee, LLVMPointerType (sig, 0), "");
2676 LLVMBuildCall (builder, callee, args, LLVMCountParamTypes (sig), "");
2678 // Set the inited flag
2679 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
2680 indexes [1] = LLVMGetParam (func, 0);
2681 LLVMBuildStore (builder, LLVMConstInt (LLVMInt8Type (), 1, FALSE), LLVMBuildGEP (builder, module->inited_var, indexes, 2, ""));
2683 LLVMBuildRetVoid (builder);
2685 LLVMVerifyFunction(func, LLVMAbortProcessAction);
2686 LLVMDisposeBuilder (builder);
2691 * Emit wrappers around the C icalls used to initialize llvm methods, to
2692 * make the calling code smaller and to enable usage of the llvm
2693 * PreserveAll calling convention.
2696 emit_init_icall_wrappers (MonoLLVMModule *module)
2698 module->init_method = emit_init_icall_wrapper (module, "init_method", "mono_aot_init_llvm_method", 0);
2699 module->init_method_gshared_mrgctx = emit_init_icall_wrapper (module, "init_method_gshared_mrgctx", "mono_aot_init_gshared_method_mrgctx", 1);
2700 module->init_method_gshared_this = emit_init_icall_wrapper (module, "init_method_gshared_this", "mono_aot_init_gshared_method_this", 2);
2701 module->init_method_gshared_vtable = emit_init_icall_wrapper (module, "init_method_gshared_vtable", "mono_aot_init_gshared_method_vtable", 3);
2705 emit_llvm_code_end (MonoLLVMModule *module)
2707 LLVMModuleRef lmodule = module->lmodule;
2709 LLVMBasicBlockRef entry_bb;
2710 LLVMBuilderRef builder;
2712 func = LLVMAddFunction (lmodule, "llvm_code_end", LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE));
2713 LLVMSetLinkage (func, LLVMInternalLinkage);
2714 LLVMAddFunctionAttr (func, LLVMNoUnwindAttribute);
2715 module->code_end = func;
2716 entry_bb = LLVMAppendBasicBlock (func, "ENTRY");
2717 builder = LLVMCreateBuilder ();
2718 LLVMPositionBuilderAtEnd (builder, entry_bb);
2719 LLVMBuildRetVoid (builder);
2720 LLVMDisposeBuilder (builder);
2724 emit_div_check (EmitContext *ctx, LLVMBuilderRef builder, MonoBasicBlock *bb, MonoInst *ins, LLVMValueRef lhs, LLVMValueRef rhs)
2726 gboolean need_div_check = ctx->cfg->backend->need_div_check;
2729 /* LLVM doesn't know that these can throw an exception since they are not called through an intrinsic */
2730 need_div_check = TRUE;
2732 if (!need_div_check)
2735 switch (ins->opcode) {
2748 case OP_IDIV_UN_IMM:
2749 case OP_LDIV_UN_IMM:
2750 case OP_IREM_UN_IMM:
2751 case OP_LREM_UN_IMM: {
2753 gboolean is_signed = (ins->opcode == OP_IDIV || ins->opcode == OP_LDIV || ins->opcode == OP_IREM || ins->opcode == OP_LREM ||
2754 ins->opcode == OP_IDIV_IMM || ins->opcode == OP_LDIV_IMM || ins->opcode == OP_IREM_IMM || ins->opcode == OP_LREM_IMM);
2756 cmp = LLVMBuildICmp (builder, LLVMIntEQ, rhs, LLVMConstInt (LLVMTypeOf (rhs), 0, FALSE), "");
2757 emit_cond_system_exception (ctx, bb, "DivideByZeroException", cmp);
2760 builder = ctx->builder;
2762 /* b == -1 && a == 0x80000000 */
2764 LLVMValueRef c = (LLVMTypeOf (lhs) == LLVMInt32Type ()) ? LLVMConstInt (LLVMTypeOf (lhs), 0x80000000, FALSE) : LLVMConstInt (LLVMTypeOf (lhs), 0x8000000000000000LL, FALSE);
2765 LLVMValueRef cond1 = LLVMBuildICmp (builder, LLVMIntEQ, rhs, LLVMConstInt (LLVMTypeOf (rhs), -1, FALSE), "");
2766 LLVMValueRef cond2 = LLVMBuildICmp (builder, LLVMIntEQ, lhs, c, "");
2768 cmp = LLVMBuildICmp (builder, LLVMIntEQ, LLVMBuildAnd (builder, cond1, cond2, ""), LLVMConstInt (LLVMInt1Type (), 1, FALSE), "");
2769 emit_cond_system_exception (ctx, bb, "OverflowException", cmp);
2772 builder = ctx->builder;
2784 * Emit code to initialize the GOT slots used by the method.
2787 emit_init_method (EmitContext *ctx)
2789 LLVMValueRef indexes [16], args [16], callee;
2790 LLVMValueRef inited_var, cmp, call;
2791 LLVMBasicBlockRef inited_bb, notinited_bb;
2792 LLVMBuilderRef builder = ctx->builder;
2793 MonoCompile *cfg = ctx->cfg;
2795 ctx->module->max_inited_idx = MAX (ctx->module->max_inited_idx, cfg->method_index);
2797 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
2798 indexes [1] = LLVMConstInt (LLVMInt32Type (), cfg->method_index, FALSE);
2799 inited_var = LLVMBuildLoad (builder, LLVMBuildGEP (builder, ctx->module->inited_var, indexes, 2, ""), "is_inited");
2801 args [0] = inited_var;
2802 args [1] = LLVMConstInt (LLVMInt8Type (), 1, FALSE);
2803 inited_var = LLVMBuildCall (ctx->builder, get_intrinsic (ctx, "llvm.expect.i8"), args, 2, "");
2805 cmp = LLVMBuildICmp (builder, LLVMIntEQ, inited_var, LLVMConstInt (LLVMTypeOf (inited_var), 0, FALSE), "");
2807 inited_bb = ctx->inited_bb;
2808 notinited_bb = gen_bb (ctx, "NOTINITED_BB");
2810 LLVMBuildCondBr (ctx->builder, cmp, notinited_bb, inited_bb);
2812 builder = ctx->builder = create_builder (ctx);
2813 LLVMPositionBuilderAtEnd (ctx->builder, notinited_bb);
2816 if (ctx->rgctx_arg && cfg->method->is_inflated && mono_method_get_context (cfg->method)->method_inst) {
2817 args [0] = LLVMConstInt (LLVMInt32Type (), cfg->method_index, 0);
2818 args [1] = convert (ctx, ctx->rgctx_arg, IntPtrType ());
2819 callee = ctx->module->init_method_gshared_mrgctx;
2820 call = LLVMBuildCall (builder, callee, args, 2, "");
2821 } else if (ctx->rgctx_arg) {
2822 /* A vtable is passed as the rgctx argument */
2823 args [0] = LLVMConstInt (LLVMInt32Type (), cfg->method_index, 0);
2824 args [1] = convert (ctx, ctx->rgctx_arg, IntPtrType ());
2825 callee = ctx->module->init_method_gshared_vtable;
2826 call = LLVMBuildCall (builder, callee, args, 2, "");
2827 } else if (cfg->gshared) {
2828 args [0] = LLVMConstInt (LLVMInt32Type (), cfg->method_index, 0);
2829 args [1] = convert (ctx, ctx->this_arg, ObjRefType ());
2830 callee = ctx->module->init_method_gshared_this;
2831 call = LLVMBuildCall (builder, callee, args, 2, "");
2833 args [0] = LLVMConstInt (LLVMInt32Type (), cfg->method_index, 0);
2834 callee = ctx->module->init_method;
2835 call = LLVMBuildCall (builder, callee, args, 1, "");
2839 * This enables llvm to keep arguments in their original registers/
2840 * scratch registers, since the call will not clobber them.
2842 mono_llvm_set_call_preserveall_cc (call);
2844 LLVMBuildBr (builder, inited_bb);
2845 ctx->bblocks [cfg->bb_entry->block_num].end_bblock = inited_bb;
2847 builder = ctx->builder = create_builder (ctx);
2848 LLVMPositionBuilderAtEnd (ctx->builder, inited_bb);
2852 emit_unbox_tramp (EmitContext *ctx, const char *method_name, LLVMTypeRef method_type, LLVMValueRef method, int method_index)
2855 * Emit unbox trampoline using a tail call
2857 LLVMValueRef tramp, call, *args;
2858 LLVMBuilderRef builder;
2859 LLVMBasicBlockRef lbb;
2860 LLVMCallInfo *linfo;
2864 tramp_name = g_strdup_printf ("ut_%s", method_name);
2865 tramp = LLVMAddFunction (ctx->module->lmodule, tramp_name, method_type);
2866 LLVMSetLinkage (tramp, LLVMInternalLinkage);
2867 LLVMAddFunctionAttr (tramp, LLVMOptimizeForSizeAttribute);
2868 //LLVMAddFunctionAttr (tramp, LLVMNoUnwindAttribute);
2870 // FIXME: Reduce code duplication with mono_llvm_compile_method () etc.
2871 if (!ctx->llvm_only && ctx->rgctx_arg_pindex != -1)
2872 LLVMAddAttribute (LLVMGetParam (tramp, ctx->rgctx_arg_pindex), LLVMInRegAttribute);
2873 if (ctx->cfg->vret_addr) {
2874 LLVMSetValueName (LLVMGetParam (tramp, linfo->vret_arg_pindex), "vret");
2875 if (linfo->ret.storage == LLVMArgVtypeByRef) {
2876 LLVMAddAttribute (LLVMGetParam (tramp, linfo->vret_arg_pindex), LLVMStructRetAttribute);
2877 LLVMAddAttribute (LLVMGetParam (tramp, linfo->vret_arg_pindex), LLVMNoAliasAttribute);
2881 lbb = LLVMAppendBasicBlock (tramp, "");
2882 builder = LLVMCreateBuilder ();
2883 LLVMPositionBuilderAtEnd (builder, lbb);
2885 nargs = LLVMCountParamTypes (method_type);
2886 args = g_new0 (LLVMValueRef, nargs);
2887 for (i = 0; i < nargs; ++i) {
2888 args [i] = LLVMGetParam (tramp, i);
2889 if (i == ctx->this_arg_pindex) {
2890 LLVMTypeRef arg_type = LLVMTypeOf (args [i]);
2892 args [i] = LLVMBuildPtrToInt (builder, args [i], IntPtrType (), "");
2893 args [i] = LLVMBuildAdd (builder, args [i], LLVMConstInt (IntPtrType (), sizeof (MonoObject), FALSE), "");
2894 args [i] = LLVMBuildIntToPtr (builder, args [i], arg_type, "");
2897 call = LLVMBuildCall (builder, method, args, nargs, "");
2898 if (!ctx->llvm_only && ctx->rgctx_arg_pindex != -1)
2899 LLVMAddInstrAttribute (call, 1 + ctx->rgctx_arg_pindex, LLVMInRegAttribute);
2900 if (linfo->ret.storage == LLVMArgVtypeByRef)
2901 LLVMAddInstrAttribute (call, 1 + linfo->vret_arg_pindex, LLVMStructRetAttribute);
2903 // FIXME: This causes assertions in clang
2904 //mono_llvm_set_must_tail (call);
2905 if (LLVMGetReturnType (method_type) == LLVMVoidType ())
2906 LLVMBuildRetVoid (builder);
2908 LLVMBuildRet (builder, call);
2910 g_hash_table_insert (ctx->module->idx_to_unbox_tramp, GINT_TO_POINTER (method_index), tramp);
2911 LLVMDisposeBuilder (builder);
2917 * Emit code to load/convert arguments.
2920 emit_entry_bb (EmitContext *ctx, LLVMBuilderRef builder)
2923 MonoCompile *cfg = ctx->cfg;
2924 MonoMethodSignature *sig = ctx->sig;
2925 LLVMCallInfo *linfo = ctx->linfo;
2929 LLVMBuilderRef old_builder = ctx->builder;
2930 ctx->builder = builder;
2932 ctx->alloca_builder = create_builder (ctx);
2935 * Handle indirect/volatile variables by allocating memory for them
2936 * using 'alloca', and storing their address in a temporary.
2938 for (i = 0; i < cfg->num_varinfo; ++i) {
2939 MonoInst *var = cfg->varinfo [i];
2942 if (var->opcode == OP_GSHAREDVT_LOCAL || var->opcode == OP_GSHAREDVT_ARG_REGOFFSET) {
2943 } 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))) {
2944 vtype = type_to_llvm_type (ctx, var->inst_vtype);
2947 /* Could be already created by an OP_VPHI */
2948 if (!ctx->addresses [var->dreg]) {
2949 ctx->addresses [var->dreg] = build_alloca (ctx, var->inst_vtype);
2950 //LLVMSetValueName (ctx->addresses [var->dreg], g_strdup_printf ("vreg_loc_%d", var->dreg));
2952 ctx->vreg_cli_types [var->dreg] = var->inst_vtype;
2956 names = g_new (char *, sig->param_count);
2957 mono_method_get_param_names (cfg->method, (const char **) names);
2959 for (i = 0; i < sig->param_count; ++i) {
2960 LLVMArgInfo *ainfo = &linfo->args [i + sig->hasthis];
2961 int reg = cfg->args [i + sig->hasthis]->dreg;
2964 pindex = ainfo->pindex;
2966 switch (ainfo->storage) {
2967 case LLVMArgVtypeInReg:
2968 case LLVMArgAsFpArgs: {
2969 LLVMValueRef args [8];
2972 pindex += ainfo->ndummy_fpargs;
2974 /* The argument is received as a set of int/fp arguments, store them into the real argument */
2975 memset (args, 0, sizeof (args));
2976 if (ainfo->storage == LLVMArgVtypeInReg) {
2977 args [0] = LLVMGetParam (ctx->lmethod, pindex);
2978 if (ainfo->pair_storage [1] != LLVMArgNone)
2979 args [1] = LLVMGetParam (ctx->lmethod, pindex + 1);
2981 g_assert (ainfo->nslots <= 8);
2982 for (j = 0; j < ainfo->nslots; ++j)
2983 args [j] = LLVMGetParam (ctx->lmethod, pindex + j);
2985 ctx->addresses [reg] = build_alloca (ctx, ainfo->type);
2987 emit_args_to_vtype (ctx, builder, ainfo->type, ctx->addresses [reg], ainfo, args);
2989 if (ainfo->storage == LLVMArgVtypeInReg && MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (ainfo->type))) {
2990 /* Treat these as normal values */
2991 ctx->values [reg] = LLVMBuildLoad (builder, ctx->addresses [reg], "");
2995 case LLVMArgVtypeByVal: {
2996 ctx->addresses [reg] = LLVMGetParam (ctx->lmethod, pindex);
2998 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (ainfo->type))) {
2999 /* Treat these as normal values */
3000 ctx->values [reg] = LLVMBuildLoad (builder, ctx->addresses [reg], "");
3004 case LLVMArgVtypeByRef: {
3005 /* The argument is passed by ref */
3006 ctx->addresses [reg] = LLVMGetParam (ctx->lmethod, pindex);
3009 case LLVMArgAsIArgs: {
3010 LLVMValueRef arg = LLVMGetParam (ctx->lmethod, pindex);
3013 /* The argument is received as an array of ints, store it into the real argument */
3014 ctx->addresses [reg] = build_alloca (ctx, ainfo->type);
3016 size = mono_class_value_size (mono_class_from_mono_type (ainfo->type), NULL);
3017 if (size < SIZEOF_VOID_P) {
3018 /* The upper bits of the registers might not be valid */
3019 LLVMValueRef val = LLVMBuildExtractValue (builder, arg, 0, "");
3020 LLVMValueRef dest = convert (ctx, ctx->addresses [reg], LLVMPointerType (LLVMIntType (size * 8), 0));
3021 LLVMBuildStore (ctx->builder, LLVMBuildTrunc (builder, val, LLVMIntType (size * 8), ""), dest);
3023 LLVMBuildStore (ctx->builder, arg, convert (ctx, ctx->addresses [reg], LLVMPointerType (LLVMTypeOf (arg), 0)));
3027 case LLVMArgVtypeAsScalar:
3028 g_assert_not_reached ();
3030 case LLVMArgGsharedvtFixed: {
3031 /* These are non-gsharedvt arguments passed by ref, the rest of the IR treats them as scalars */
3032 LLVMValueRef arg = LLVMGetParam (ctx->lmethod, pindex);
3035 name = g_strdup_printf ("arg_%s", names [i]);
3037 name = g_strdup_printf ("arg_%d", i);
3039 ctx->values [reg] = LLVMBuildLoad (builder, convert (ctx, arg, LLVMPointerType (type_to_llvm_type (ctx, ainfo->type), 0)), name);
3042 case LLVMArgGsharedvtFixedVtype: {
3043 LLVMValueRef arg = LLVMGetParam (ctx->lmethod, pindex);
3046 name = g_strdup_printf ("vtype_arg_%s", names [i]);
3048 name = g_strdup_printf ("vtype_arg_%d", i);
3050 /* Non-gsharedvt vtype argument passed by ref, the rest of the IR treats it as a vtype */
3051 g_assert (ctx->addresses [reg]);
3052 LLVMSetValueName (ctx->addresses [reg], name);
3053 LLVMBuildStore (builder, LLVMBuildLoad (builder, convert (ctx, arg, LLVMPointerType (type_to_llvm_type (ctx, ainfo->type), 0)), ""), ctx->addresses [reg]);
3056 case LLVMArgGsharedvtVariable:
3057 /* The IR treats these as variables with addresses */
3058 ctx->addresses [reg] = LLVMGetParam (ctx->lmethod, pindex);
3061 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));
3068 emit_volatile_store (ctx, cfg->vret_addr->dreg);
3070 emit_volatile_store (ctx, cfg->args [0]->dreg);
3071 for (i = 0; i < sig->param_count; ++i)
3072 if (!mini_type_is_vtype (sig->params [i]))
3073 emit_volatile_store (ctx, cfg->args [i + sig->hasthis]->dreg);
3075 if (sig->hasthis && !cfg->rgctx_var && cfg->gshared) {
3076 LLVMValueRef this_alloc;
3079 * The exception handling code needs the location where the this argument was
3080 * stored for gshared methods. We create a separate alloca to hold it, and mark it
3081 * with the "mono.this" custom metadata to tell llvm that it needs to save its
3082 * location into the LSDA.
3084 this_alloc = mono_llvm_build_alloca (builder, ThisType (), LLVMConstInt (LLVMInt32Type (), 1, FALSE), 0, "");
3085 /* This volatile store will keep the alloca alive */
3086 mono_llvm_build_store (builder, ctx->values [cfg->args [0]->dreg], this_alloc, TRUE, LLVM_BARRIER_NONE);
3088 set_metadata_flag (this_alloc, "mono.this");
3091 if (cfg->rgctx_var) {
3092 LLVMValueRef rgctx_alloc, store;
3095 * We handle the rgctx arg similarly to the this pointer.
3097 g_assert (ctx->addresses [cfg->rgctx_var->dreg]);
3098 rgctx_alloc = ctx->addresses [cfg->rgctx_var->dreg];
3099 /* This volatile store will keep the alloca alive */
3100 store = mono_llvm_build_store (builder, convert (ctx, ctx->rgctx_arg, IntPtrType ()), rgctx_alloc, TRUE, LLVM_BARRIER_NONE);
3102 set_metadata_flag (rgctx_alloc, "mono.this");
3105 /* Initialize the method if needed */
3106 if (cfg->compile_aot && ctx->llvm_only) {
3107 /* Emit a location for the initialization code */
3108 ctx->init_bb = gen_bb (ctx, "INIT_BB");
3109 ctx->inited_bb = gen_bb (ctx, "INITED_BB");
3111 LLVMBuildBr (ctx->builder, ctx->init_bb);
3112 builder = ctx->builder = create_builder (ctx);
3113 LLVMPositionBuilderAtEnd (ctx->builder, ctx->inited_bb);
3114 ctx->bblocks [cfg->bb_entry->block_num].end_bblock = ctx->inited_bb;
3117 /* Compute nesting between clauses */
3118 ctx->nested_in = (GSList**)mono_mempool_alloc0 (cfg->mempool, sizeof (GSList*) * cfg->header->num_clauses);
3119 for (i = 0; i < cfg->header->num_clauses; ++i) {
3120 for (j = 0; j < cfg->header->num_clauses; ++j) {
3121 MonoExceptionClause *clause1 = &cfg->header->clauses [i];
3122 MonoExceptionClause *clause2 = &cfg->header->clauses [j];
3124 if (i != j && clause1->try_offset >= clause2->try_offset && clause1->handler_offset <= clause2->handler_offset)
3125 ctx->nested_in [i] = g_slist_prepend_mempool (cfg->mempool, ctx->nested_in [i], GINT_TO_POINTER (j));
3130 * For finally clauses, create an indicator variable telling OP_ENDFINALLY whenever
3131 * it needs to continue normally, or return back to the exception handling system.
3133 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
3137 if (!(bb->region != -1 && (bb->flags & BB_EXCEPTION_HANDLER)))
3140 clause_index = MONO_REGION_CLAUSE_INDEX (bb->region);
3141 g_hash_table_insert (ctx->region_to_handler, GUINT_TO_POINTER (mono_get_block_region_notry (cfg, bb->region)), bb);
3142 g_hash_table_insert (ctx->clause_to_handler, GINT_TO_POINTER (clause_index), bb);
3144 if (bb->in_scount == 0) {
3147 sprintf (name, "finally_ind_bb%d", bb->block_num);
3148 val = LLVMBuildAlloca (builder, LLVMInt32Type (), name);
3149 LLVMBuildStore (builder, LLVMConstInt (LLVMInt32Type (), 0, FALSE), val);
3151 ctx->bblocks [bb->block_num].finally_ind = val;
3153 /* Create a variable to hold the exception var */
3155 ctx->ex_var = LLVMBuildAlloca (builder, ObjRefType (), "exvar");
3159 * Create a new bblock which CALL_HANDLER/landing pads can branch to, because branching to the
3160 * LLVM bblock containing a landing pad causes problems for the
3161 * LLVM optimizer passes.
3163 sprintf (name, "BB%d_CALL_HANDLER_TARGET", bb->block_num);
3164 ctx->bblocks [bb->block_num].call_handler_target_bb = LLVMAppendBasicBlock (ctx->lmethod, name);
3166 ctx->builder = old_builder;
3170 process_call (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, MonoInst *ins)
3172 MonoCompile *cfg = ctx->cfg;
3173 LLVMValueRef *values = ctx->values;
3174 LLVMValueRef *addresses = ctx->addresses;
3175 MonoCallInst *call = (MonoCallInst*)ins;
3176 MonoMethodSignature *sig = call->signature;
3177 LLVMValueRef callee = NULL, lcall;
3179 LLVMCallInfo *cinfo;
3183 LLVMTypeRef llvm_sig;
3185 gboolean is_virtual, calli, preserveall;
3186 LLVMBuilderRef builder = *builder_ref;
3188 if ((call->signature->call_convention != MONO_CALL_DEFAULT) && !((call->signature->call_convention == MONO_CALL_C) && ctx->llvm_only)) {
3189 set_failure (ctx, "non-default callconv");
3193 cinfo = call->cinfo;
3195 if (call->rgctx_arg_reg)
3196 cinfo->rgctx_arg = TRUE;
3197 if (call->imt_arg_reg)
3198 cinfo->imt_arg = TRUE;
3200 vretaddr = (cinfo->ret.storage == LLVMArgVtypeRetAddr || cinfo->ret.storage == LLVMArgVtypeByRef || cinfo->ret.storage == LLVMArgGsharedvtFixed || cinfo->ret.storage == LLVMArgGsharedvtVariable || cinfo->ret.storage == LLVMArgGsharedvtFixedVtype);
3202 llvm_sig = sig_to_llvm_sig_full (ctx, sig, cinfo);
3206 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);
3207 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);
3209 preserveall = FALSE;
3211 /* FIXME: Avoid creating duplicate methods */
3213 if (ins->flags & MONO_INST_HAS_METHOD) {
3217 if (cfg->compile_aot) {
3218 callee = get_callee (ctx, llvm_sig, MONO_PATCH_INFO_METHOD, call->method);
3220 set_failure (ctx, "can't encode patch");
3223 if (cfg->llvm_only && call->method->klass->image->assembly == ctx->module->assembly) {
3225 * Collect instructions representing the callee into a hash so they can be replaced
3226 * by the llvm method for the callee if the callee turns out to be direct
3227 * callable. Currently this only requires it to not fail llvm compilation.
3229 GSList *l = (GSList*)g_hash_table_lookup (ctx->method_to_callers, call->method);
3230 l = g_slist_prepend (l, callee);
3231 g_hash_table_insert (ctx->method_to_callers, call->method, l);
3235 static int tramp_index;
3238 name = g_strdup_printf ("tramp_%d", tramp_index);
3241 #if LLVM_API_VERSION > 100
3243 * Use our trampoline infrastructure for lazy compilation instead of llvm's.
3244 * Make all calls through a global. The address of the global will be saved in
3245 * MonoJitDomainInfo.llvm_jit_callees and updated when the method it refers to is
3248 LLVMValueRef tramp_var = g_hash_table_lookup (ctx->jit_callees, call->method);
3251 mono_create_jit_trampoline (mono_domain_get (),
3252 call->method, &error);
3253 if (!is_ok (&error)) {
3254 set_failure (ctx, mono_error_get_message (&error));
3255 mono_error_cleanup (&error);
3259 tramp_var = LLVMAddGlobal (ctx->lmodule, LLVMPointerType (llvm_sig, 0), name);
3260 LLVMSetInitializer (tramp_var, LLVMConstIntToPtr (LLVMConstInt (LLVMInt64Type (), (guint64)(size_t)target, FALSE), LLVMPointerType (llvm_sig, 0)));
3261 LLVMSetLinkage (tramp_var, LLVMExternalLinkage);
3262 g_hash_table_insert (ctx->jit_callees, call->method, tramp_var);
3264 callee = LLVMBuildLoad (builder, tramp_var, "");
3267 mono_create_jit_trampoline (mono_domain_get (),
3268 call->method, &error);
3269 if (!is_ok (&error)) {
3271 set_failure (ctx, mono_error_get_message (&error));
3272 mono_error_cleanup (&error);
3276 callee = LLVMAddFunction (ctx->lmodule, name, llvm_sig);
3279 LLVMAddGlobalMapping (ctx->module->ee, callee, target);
3284 if (!cfg->llvm_only && call->method && strstr (call->method->klass->name, "AsyncVoidMethodBuilder")) {
3285 /* LLVM miscompiles async methods */
3286 set_failure (ctx, "#13734");
3291 MonoJitICallInfo *info = mono_find_jit_icall_by_addr (call->fptr);
3297 memset (&ji, 0, sizeof (ji));
3298 ji.type = MONO_PATCH_INFO_JIT_ICALL_ADDR;
3299 ji.data.target = info->name;
3301 target = mono_resolve_patch_target (cfg->method, cfg->domain, NULL, &ji, FALSE);
3303 if (cfg->compile_aot) {
3304 callee = get_callee (ctx, llvm_sig, MONO_PATCH_INFO_INTERNAL_METHOD, (char*)info->name);
3306 set_failure (ctx, "can't encode patch");
3310 target = (gpointer)mono_icall_get_wrapper (info);
3311 callee = emit_jit_callee (ctx, "", llvm_sig, target);
3314 if (cfg->compile_aot) {
3316 if (cfg->abs_patches) {
3317 MonoJumpInfo *abs_ji = (MonoJumpInfo*)g_hash_table_lookup (cfg->abs_patches, call->fptr);
3319 callee = get_callee (ctx, llvm_sig, abs_ji->type, abs_ji->data.target);
3321 set_failure (ctx, "can't encode patch");
3327 set_failure (ctx, "aot");
3331 #if LLVM_API_VERSION > 100
3332 if (cfg->abs_patches) {
3333 MonoJumpInfo *abs_ji = (MonoJumpInfo*)g_hash_table_lookup (cfg->abs_patches, call->fptr);
3337 target = mono_resolve_patch_target (cfg->method, cfg->domain, NULL, abs_ji, FALSE, &error);
3338 mono_error_assert_ok (&error);
3339 callee = emit_jit_callee (ctx, "", llvm_sig, target);
3341 g_assert_not_reached ();
3344 g_assert_not_reached ();
3347 callee = LLVMAddFunction (ctx->lmodule, "", llvm_sig);
3349 if (cfg->abs_patches) {
3350 MonoJumpInfo *abs_ji = (MonoJumpInfo*)g_hash_table_lookup (cfg->abs_patches, call->fptr);
3355 * FIXME: Some trampolines might have
3356 * their own calling convention on some platforms.
3358 target = mono_resolve_patch_target (cfg->method, cfg->domain, NULL, abs_ji, FALSE, &error);
3359 mono_error_assert_ok (&error);
3360 LLVMAddGlobalMapping (ctx->module->ee, callee, target);
3364 LLVMAddGlobalMapping (ctx->module->ee, callee, (gpointer)call->fptr);
3371 int size = sizeof (gpointer);
3374 g_assert (ins->inst_offset % size == 0);
3375 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
3377 callee = convert (ctx, LLVMBuildLoad (builder, LLVMBuildGEP (builder, convert (ctx, values [ins->inst_basereg], LLVMPointerType (LLVMPointerType (IntPtrType (), 0), 0)), &index, 1, ""), ""), LLVMPointerType (llvm_sig, 0));
3379 callee = convert (ctx, values [ins->sreg1], LLVMPointerType (llvm_sig, 0));
3381 if (ins->flags & MONO_INST_HAS_METHOD) {
3386 * Collect and convert arguments
3388 nargs = (sig->param_count * 16) + sig->hasthis + vretaddr + call->rgctx_reg + call->imt_arg_reg;
3389 len = sizeof (LLVMValueRef) * nargs;
3390 args = (LLVMValueRef*)alloca (len);
3391 memset (args, 0, len);
3392 l = call->out_ireg_args;
3394 if (call->rgctx_arg_reg) {
3395 g_assert (values [call->rgctx_arg_reg]);
3396 g_assert (cinfo->rgctx_arg_pindex < nargs);
3398 * On ARM, the imt/rgctx argument is passed in a caller save register, but some of our trampolines etc. clobber it, leading to
3399 * problems is LLVM moves the arg assignment earlier. To work around this, save the argument into a stack slot and load
3400 * it using a volatile load.
3403 if (!ctx->imt_rgctx_loc)
3404 ctx->imt_rgctx_loc = build_alloca_llvm_type (ctx, ctx->module->ptr_type, sizeof (gpointer));
3405 LLVMBuildStore (builder, convert (ctx, ctx->values [call->rgctx_arg_reg], ctx->module->ptr_type), ctx->imt_rgctx_loc);
3406 args [cinfo->rgctx_arg_pindex] = mono_llvm_build_load (builder, ctx->imt_rgctx_loc, "", TRUE);
3408 args [cinfo->rgctx_arg_pindex] = convert (ctx, values [call->rgctx_arg_reg], ctx->module->ptr_type);
3411 if (call->imt_arg_reg) {
3412 g_assert (!ctx->llvm_only);
3413 g_assert (values [call->imt_arg_reg]);
3414 g_assert (cinfo->imt_arg_pindex < nargs);
3416 if (!ctx->imt_rgctx_loc)
3417 ctx->imt_rgctx_loc = build_alloca_llvm_type (ctx, ctx->module->ptr_type, sizeof (gpointer));
3418 LLVMBuildStore (builder, convert (ctx, ctx->values [call->imt_arg_reg], ctx->module->ptr_type), ctx->imt_rgctx_loc);
3419 args [cinfo->imt_arg_pindex] = mono_llvm_build_load (builder, ctx->imt_rgctx_loc, "", TRUE);
3421 args [cinfo->imt_arg_pindex] = convert (ctx, values [call->imt_arg_reg], ctx->module->ptr_type);
3424 switch (cinfo->ret.storage) {
3425 case LLVMArgGsharedvtVariable: {
3426 MonoInst *var = get_vreg_to_inst (cfg, call->inst.dreg);
3428 if (var && var->opcode == OP_GSHAREDVT_LOCAL) {
3429 args [cinfo->vret_arg_pindex] = convert (ctx, emit_gsharedvt_ldaddr (ctx, var->dreg), IntPtrType ());
3431 g_assert (addresses [call->inst.dreg]);
3432 args [cinfo->vret_arg_pindex] = addresses [call->inst.dreg];
3438 if (!addresses [call->inst.dreg])
3439 addresses [call->inst.dreg] = build_alloca (ctx, sig->ret);
3440 g_assert (cinfo->vret_arg_pindex < nargs);
3441 if (cinfo->ret.storage == LLVMArgVtypeByRef)
3442 args [cinfo->vret_arg_pindex] = addresses [call->inst.dreg];
3444 args [cinfo->vret_arg_pindex] = LLVMBuildPtrToInt (builder, addresses [call->inst.dreg], IntPtrType (), "");
3450 * Sometimes the same method is called with two different signatures (i.e. with and without 'this'), so
3451 * use the real callee for argument type conversion.
3453 LLVMTypeRef callee_type = LLVMGetElementType (LLVMTypeOf (callee));
3454 LLVMTypeRef *param_types = (LLVMTypeRef*)g_alloca (sizeof (LLVMTypeRef) * LLVMCountParamTypes (callee_type));
3455 LLVMGetParamTypes (callee_type, param_types);
3457 for (i = 0; i < sig->param_count + sig->hasthis; ++i) {
3460 LLVMArgInfo *ainfo = &call->cinfo->args [i];
3462 pindex = ainfo->pindex;
3464 regpair = (guint32)(gssize)(l->data);
3465 reg = regpair & 0xffffff;
3466 args [pindex] = values [reg];
3467 switch (ainfo->storage) {
3468 case LLVMArgVtypeInReg:
3469 case LLVMArgAsFpArgs: {
3473 for (j = 0; j < ainfo->ndummy_fpargs; ++j)
3474 args [pindex + j] = LLVMConstNull (LLVMDoubleType ());
3475 pindex += ainfo->ndummy_fpargs;
3477 g_assert (addresses [reg]);
3478 emit_vtype_to_args (ctx, builder, ainfo->type, addresses [reg], ainfo, args + pindex, &nargs);
3482 // FIXME: Get rid of the VMOVE
3485 case LLVMArgVtypeByVal:
3486 g_assert (addresses [reg]);
3487 args [pindex] = addresses [reg];
3489 case LLVMArgVtypeByRef: {
3490 g_assert (addresses [reg]);
3491 args [pindex] = convert (ctx, addresses [reg], LLVMPointerType (type_to_llvm_arg_type (ctx, ainfo->type), 0));
3494 case LLVMArgAsIArgs:
3495 g_assert (addresses [reg]);
3496 if (ainfo->esize == 8)
3497 args [pindex] = LLVMBuildLoad (ctx->builder, convert (ctx, addresses [reg], LLVMPointerType (LLVMArrayType (LLVMInt64Type (), ainfo->nslots), 0)), "");
3499 args [pindex] = LLVMBuildLoad (ctx->builder, convert (ctx, addresses [reg], LLVMPointerType (LLVMArrayType (IntPtrType (), ainfo->nslots), 0)), "");
3501 case LLVMArgVtypeAsScalar:
3502 g_assert_not_reached ();
3504 case LLVMArgGsharedvtFixed:
3505 case LLVMArgGsharedvtFixedVtype:
3506 g_assert (addresses [reg]);
3507 args [pindex] = convert (ctx, addresses [reg], LLVMPointerType (type_to_llvm_arg_type (ctx, ainfo->type), 0));
3509 case LLVMArgGsharedvtVariable:
3510 g_assert (addresses [reg]);
3511 args [pindex] = convert (ctx, addresses [reg], LLVMPointerType (IntPtrType (), 0));
3514 g_assert (args [pindex]);
3515 if (i == 0 && sig->hasthis)
3516 args [pindex] = convert (ctx, args [pindex], param_types [pindex]);
3518 args [pindex] = convert (ctx, args [pindex], type_to_llvm_arg_type (ctx, ainfo->type));
3521 g_assert (pindex <= nargs);
3526 // FIXME: Align call sites
3532 lcall = emit_call (ctx, bb, &builder, callee, args, LLVMCountParamTypes (llvm_sig));
3534 if (ins->opcode != OP_TAILCALL && LLVMGetInstructionOpcode (lcall) == LLVMCall)
3535 mono_llvm_set_call_notail (lcall);
3538 * Modify cconv and parameter attributes to pass rgctx/imt correctly.
3540 #if defined(MONO_ARCH_IMT_REG) && defined(MONO_ARCH_RGCTX_REG)
3541 g_assert (MONO_ARCH_IMT_REG == MONO_ARCH_RGCTX_REG);
3543 /* The two can't be used together, so use only one LLVM calling conv to pass them */
3544 g_assert (!(call->rgctx_arg_reg && call->imt_arg_reg));
3545 if (!sig->pinvoke && !cfg->llvm_only)
3546 LLVMSetInstructionCallConv (lcall, LLVMMono1CallConv);
3548 mono_llvm_set_call_preserveall_cc (lcall);
3550 if (cinfo->ret.storage == LLVMArgVtypeByRef)
3551 LLVMAddInstrAttribute (lcall, 1 + cinfo->vret_arg_pindex, LLVMStructRetAttribute);
3552 if (!ctx->llvm_only && call->rgctx_arg_reg)
3553 LLVMAddInstrAttribute (lcall, 1 + cinfo->rgctx_arg_pindex, LLVMInRegAttribute);
3554 if (call->imt_arg_reg)
3555 LLVMAddInstrAttribute (lcall, 1 + cinfo->imt_arg_pindex, LLVMInRegAttribute);
3557 /* Add byval attributes if needed */
3558 for (i = 0; i < sig->param_count; ++i) {
3559 LLVMArgInfo *ainfo = &call->cinfo->args [i + sig->hasthis];
3561 if (ainfo && ainfo->storage == LLVMArgVtypeByVal)
3562 LLVMAddInstrAttribute (lcall, 1 + ainfo->pindex, LLVMByValAttribute);
3566 * Convert the result
3568 switch (cinfo->ret.storage) {
3569 case LLVMArgVtypeInReg: {
3570 LLVMValueRef regs [2];
3572 if (LLVMTypeOf (lcall) == LLVMVoidType ())
3576 if (!addresses [ins->dreg])
3577 addresses [ins->dreg] = build_alloca (ctx, sig->ret);
3579 regs [0] = LLVMBuildExtractValue (builder, lcall, 0, "");
3580 if (cinfo->ret.pair_storage [1] != LLVMArgNone)
3581 regs [1] = LLVMBuildExtractValue (builder, lcall, 1, "");
3582 emit_args_to_vtype (ctx, builder, sig->ret, addresses [ins->dreg], &cinfo->ret, regs);
3585 case LLVMArgVtypeByVal:
3586 if (!addresses [call->inst.dreg])
3587 addresses [call->inst.dreg] = build_alloca (ctx, sig->ret);
3588 LLVMBuildStore (builder, lcall, addresses [call->inst.dreg]);
3590 case LLVMArgAsIArgs:
3591 case LLVMArgFpStruct:
3592 if (!addresses [call->inst.dreg])
3593 addresses [call->inst.dreg] = build_alloca (ctx, sig->ret);
3594 LLVMBuildStore (builder, lcall, convert_full (ctx, addresses [call->inst.dreg], LLVMPointerType (LLVMTypeOf (lcall), 0), FALSE));
3596 case LLVMArgVtypeAsScalar:
3597 if (!addresses [call->inst.dreg])
3598 addresses [call->inst.dreg] = build_alloca (ctx, sig->ret);
3599 LLVMBuildStore (builder, lcall, convert_full (ctx, addresses [call->inst.dreg], LLVMPointerType (LLVMTypeOf (lcall), 0), FALSE));
3601 case LLVMArgVtypeRetAddr:
3602 case LLVMArgVtypeByRef:
3603 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (sig->ret))) {
3604 /* Some opcodes like STOREX_MEMBASE access these by value */
3605 g_assert (addresses [call->inst.dreg]);
3606 values [ins->dreg] = LLVMBuildLoad (builder, convert_full (ctx, addresses [call->inst.dreg], LLVMPointerType (type_to_llvm_type (ctx, sig->ret), 0), FALSE), "");
3609 case LLVMArgGsharedvtVariable:
3611 case LLVMArgGsharedvtFixed:
3612 case LLVMArgGsharedvtFixedVtype:
3613 values [ins->dreg] = LLVMBuildLoad (builder, convert_full (ctx, addresses [call->inst.dreg], LLVMPointerType (type_to_llvm_type (ctx, sig->ret), 0), FALSE), "");
3616 if (sig->ret->type != MONO_TYPE_VOID)
3617 /* If the method returns an unsigned value, need to zext it */
3618 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));
3622 *builder_ref = ctx->builder;
3626 emit_llvmonly_throw (EmitContext *ctx, MonoBasicBlock *bb, gboolean rethrow, LLVMValueRef exc)
3628 const char *icall_name = rethrow ? "mono_llvm_rethrow_exception" : "mono_llvm_throw_exception";
3629 LLVMValueRef callee = rethrow ? ctx->module->rethrow : ctx->module->throw_icall;
3631 LLVMTypeRef exc_type = type_to_llvm_type (ctx, &mono_get_exception_class ()->byval_arg);
3634 LLVMTypeRef fun_sig = LLVMFunctionType1 (LLVMVoidType (), exc_type, FALSE);
3636 if (ctx->cfg->compile_aot) {
3637 callee = get_callee (ctx, fun_sig, MONO_PATCH_INFO_JIT_ICALL_ADDR, icall_name);
3639 callee = LLVMAddFunction (ctx->lmodule, icall_name, fun_sig);
3640 LLVMAddGlobalMapping (ctx->module->ee, callee, resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name));
3641 mono_memory_barrier ();
3644 ctx->module->rethrow = callee;
3646 ctx->module->throw_icall = callee;
3650 LLVMValueRef args [2];
3652 args [0] = convert (ctx, exc, exc_type);
3653 emit_call (ctx, bb, &ctx->builder, callee, args, 1);
3655 LLVMBuildUnreachable (ctx->builder);
3657 ctx->builder = create_builder (ctx);
3661 emit_throw (EmitContext *ctx, MonoBasicBlock *bb, gboolean rethrow, LLVMValueRef exc)
3663 MonoMethodSignature *throw_sig;
3664 LLVMValueRef callee, arg;
3665 const char *icall_name;
3667 callee = rethrow ? ctx->module->rethrow : ctx->module->throw_icall;
3668 icall_name = rethrow ? "mono_arch_rethrow_exception" : "mono_arch_throw_exception";
3671 throw_sig = mono_metadata_signature_alloc (mono_get_corlib (), 1);
3672 throw_sig->ret = &mono_get_void_class ()->byval_arg;
3673 throw_sig->params [0] = &mono_get_object_class ()->byval_arg;
3674 if (ctx->cfg->compile_aot) {
3675 callee = get_callee (ctx, sig_to_llvm_sig (ctx, throw_sig), MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
3680 * LLVM doesn't push the exception argument, so we need a different
3683 target = resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, rethrow ? "llvm_rethrow_exception_trampoline" : "llvm_throw_exception_trampoline");
3685 target = resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
3687 callee = emit_jit_callee (ctx, icall_name, sig_to_llvm_sig (ctx, throw_sig), target);
3690 mono_memory_barrier ();
3691 #if LLVM_API_VERSION < 100
3693 ctx->module->rethrow = callee;
3695 ctx->module->throw_icall = callee;
3698 arg = convert (ctx, exc, type_to_llvm_type (ctx, &mono_get_object_class ()->byval_arg));
3699 emit_call (ctx, bb, &ctx->builder, callee, &arg, 1);
3703 emit_resume_eh (EmitContext *ctx, MonoBasicBlock *bb)
3705 const char *icall_name = "mono_llvm_resume_exception";
3706 LLVMValueRef callee = ctx->module->resume_eh;
3708 LLVMTypeRef fun_sig = LLVMFunctionType0 (LLVMVoidType (), FALSE);
3711 if (ctx->cfg->compile_aot) {
3712 callee = get_callee (ctx, fun_sig, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
3714 callee = LLVMAddFunction (ctx->lmodule, icall_name, fun_sig);
3715 LLVMAddGlobalMapping (ctx->module->ee, callee, resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name));
3716 mono_memory_barrier ();
3718 ctx->module->resume_eh = callee;
3722 emit_call (ctx, bb, &ctx->builder, callee, NULL, 0);
3724 LLVMBuildUnreachable (ctx->builder);
3726 ctx->builder = create_builder (ctx);
3730 mono_llvm_emit_clear_exception_call (EmitContext *ctx, LLVMBuilderRef builder)
3732 const char *icall_name = "mono_llvm_clear_exception";
3734 LLVMTypeRef call_sig = LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE);
3735 LLVMValueRef callee = NULL;
3738 if (ctx->cfg->compile_aot) {
3739 callee = get_callee (ctx, call_sig, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
3741 // FIXME: This is broken.
3742 callee = LLVMAddFunction (ctx->lmodule, icall_name, call_sig);
3746 g_assert (builder && callee);
3748 return LLVMBuildCall (builder, callee, NULL, 0, "");
3752 mono_llvm_emit_load_exception_call (EmitContext *ctx, LLVMBuilderRef builder)
3754 const char *icall_name = "mono_llvm_load_exception";
3756 LLVMTypeRef call_sig = LLVMFunctionType (ObjRefType (), NULL, 0, FALSE);
3757 LLVMValueRef callee = NULL;
3760 if (ctx->cfg->compile_aot) {
3761 callee = get_callee (ctx, call_sig, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
3763 // FIXME: This is broken.
3764 callee = LLVMAddFunction (ctx->lmodule, icall_name, call_sig);
3768 g_assert (builder && callee);
3770 return LLVMBuildCall (builder, callee, NULL, 0, icall_name);
3775 mono_llvm_emit_match_exception_call (EmitContext *ctx, LLVMBuilderRef builder, gint32 region_start, gint32 region_end)
3777 const char *icall_name = "mono_llvm_match_exception";
3779 ctx->builder = builder;
3781 const int num_args = 5;
3782 LLVMValueRef args [num_args];
3783 args [0] = convert (ctx, get_aotconst (ctx, MONO_PATCH_INFO_AOT_JIT_INFO, GINT_TO_POINTER (ctx->cfg->method_index)), IntPtrType ());
3784 args [1] = LLVMConstInt (LLVMInt32Type (), region_start, 0);
3785 args [2] = LLVMConstInt (LLVMInt32Type (), region_end, 0);
3786 if (ctx->cfg->rgctx_var) {
3787 LLVMValueRef rgctx_alloc = ctx->addresses [ctx->cfg->rgctx_var->dreg];
3788 g_assert (rgctx_alloc);
3789 args [3] = LLVMBuildLoad (builder, convert (ctx, rgctx_alloc, LLVMPointerType (IntPtrType (), 0)), "");
3791 args [3] = LLVMConstInt (IntPtrType (), 0, 0);
3794 args [4] = convert (ctx, ctx->this_arg, IntPtrType ());
3796 args [4] = LLVMConstInt (IntPtrType (), 0, 0);
3798 LLVMTypeRef match_sig = LLVMFunctionType5 (LLVMInt32Type (), IntPtrType (), LLVMInt32Type (), LLVMInt32Type (), IntPtrType (), IntPtrType (), FALSE);
3799 LLVMValueRef callee = ctx->module->match_exc;
3802 if (ctx->cfg->compile_aot) {
3803 ctx->builder = builder;
3804 // get_callee expects ctx->builder to be the emitting builder
3805 callee = get_callee (ctx, match_sig, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
3807 callee = ctx->module->match_exc = LLVMAddFunction (ctx->lmodule, icall_name, match_sig);
3808 LLVMAddGlobalMapping (ctx->module->ee, ctx->module->match_exc, resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name));
3809 ctx->module->match_exc = callee;
3810 mono_memory_barrier ();
3814 g_assert (builder && callee);
3816 g_assert (ctx->ex_var);
3818 return LLVMBuildCall (builder, callee, args, num_args, icall_name);
3821 // FIXME: This won't work because the code-finding makes this
3823 /*#define MONO_PERSONALITY_DEBUG*/
3825 #ifdef MONO_PERSONALITY_DEBUG
3826 static const gboolean use_debug_personality = TRUE;
3827 static const char *default_personality_name = "mono_debug_personality";
3829 static const gboolean use_debug_personality = FALSE;
3830 static const char *default_personality_name = "__gxx_personality_v0";
3834 default_cpp_lpad_exc_signature (void)
3836 static gboolean inited = FALSE;
3837 static LLVMTypeRef sig;
3840 LLVMTypeRef signature [2];
3841 signature [0] = LLVMPointerType (LLVMInt8Type (), 0);
3842 signature [1] = LLVMInt32Type ();
3843 sig = LLVMStructType (signature, 2, FALSE);
3851 get_mono_personality (EmitContext *ctx)
3853 LLVMValueRef personality = NULL;
3854 static gint32 mapping_inited = FALSE;
3855 LLVMTypeRef personality_type = LLVMFunctionType (LLVMInt32Type (), NULL, 0, TRUE);
3857 if (!use_debug_personality) {
3858 if (ctx->cfg->compile_aot) {
3859 personality = get_intrinsic (ctx, default_personality_name);
3860 } else if (InterlockedCompareExchange (&mapping_inited, 1, 0) == 0) {
3861 personality = LLVMAddFunction (ctx->lmodule, default_personality_name, personality_type);
3862 LLVMAddGlobalMapping (ctx->module->ee, personality, personality);
3865 if (ctx->cfg->compile_aot) {
3866 personality = get_callee (ctx, personality_type, MONO_PATCH_INFO_INTERNAL_METHOD, default_personality_name);
3868 personality = LLVMAddFunction (ctx->lmodule, default_personality_name, personality_type);
3869 LLVMAddGlobalMapping (ctx->module->ee, personality, resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, default_personality_name));
3870 mono_memory_barrier ();
3874 g_assert (personality);
3878 static LLVMBasicBlockRef
3879 emit_landing_pad (EmitContext *ctx, int group_index, int group_size)
3881 MonoCompile *cfg = ctx->cfg;
3882 LLVMBuilderRef old_builder = ctx->builder;
3883 MonoExceptionClause *group_start = cfg->header->clauses + group_index;
3885 LLVMBuilderRef lpadBuilder = create_builder (ctx);
3886 ctx->builder = lpadBuilder;
3888 MonoBasicBlock *handler_bb = cfg->cil_offset_to_bb [CLAUSE_START (group_start)];
3889 g_assert (handler_bb);
3891 // <resultval> = landingpad <somety> personality <type> <pers_fn> <clause>+
3892 LLVMValueRef personality = get_mono_personality (ctx);
3893 g_assert (personality);
3895 char *bb_name = g_strdup_printf ("LPAD%d_BB", group_index);
3896 LLVMBasicBlockRef lpad_bb = gen_bb (ctx, bb_name);
3898 LLVMPositionBuilderAtEnd (lpadBuilder, lpad_bb);
3899 LLVMValueRef landing_pad = LLVMBuildLandingPad (lpadBuilder, default_cpp_lpad_exc_signature (), personality, 0, "");
3900 g_assert (landing_pad);
3902 LLVMValueRef cast = LLVMBuildBitCast (lpadBuilder, ctx->module->sentinel_exception, LLVMPointerType (LLVMInt8Type (), 0), "int8TypeInfo");
3903 LLVMAddClause (landing_pad, cast);
3905 LLVMBasicBlockRef resume_bb = gen_bb (ctx, "RESUME_BB");
3906 LLVMBuilderRef resume_builder = create_builder (ctx);
3907 ctx->builder = resume_builder;
3908 LLVMPositionBuilderAtEnd (resume_builder, resume_bb);
3910 emit_resume_eh (ctx, handler_bb);
3913 ctx->builder = lpadBuilder;
3914 LLVMPositionBuilderAtEnd (lpadBuilder, lpad_bb);
3916 gboolean finally_only = TRUE;
3918 MonoExceptionClause *group_cursor = group_start;
3920 for (int i = 0; i < group_size; i ++) {
3921 if (!(group_cursor->flags & MONO_EXCEPTION_CLAUSE_FINALLY))
3922 finally_only = FALSE;
3928 // Handle landing pad inlining
3930 if (!finally_only) {
3931 // So at each level of the exception stack we will match the exception again.
3932 // During that match, we need to compare against the handler types for the current
3933 // protected region. We send the try start and end so that we can only check against
3934 // handlers for this lexical protected region.
3935 LLVMValueRef match = mono_llvm_emit_match_exception_call (ctx, lpadBuilder, group_start->try_offset, group_start->try_offset + group_start->try_len);
3937 // if returns -1, resume
3938 LLVMValueRef switch_ins = LLVMBuildSwitch (lpadBuilder, match, resume_bb, group_size);
3940 // else move to that target bb
3941 for (int i = 0; i < group_size; i++) {
3942 MonoExceptionClause *clause = group_start + i;
3943 int clause_index = clause - cfg->header->clauses;
3944 MonoBasicBlock *handler_bb = (MonoBasicBlock*)g_hash_table_lookup (ctx->clause_to_handler, GINT_TO_POINTER (clause_index));
3945 g_assert (handler_bb);
3946 g_assert (ctx->bblocks [handler_bb->block_num].call_handler_target_bb);
3947 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), clause_index, FALSE), ctx->bblocks [handler_bb->block_num].call_handler_target_bb);
3950 int clause_index = group_start - cfg->header->clauses;
3951 MonoBasicBlock *finally_bb = (MonoBasicBlock*)g_hash_table_lookup (ctx->clause_to_handler, GINT_TO_POINTER (clause_index));
3952 g_assert (finally_bb);
3954 LLVMBuildBr (ctx->builder, ctx->bblocks [finally_bb->block_num].call_handler_target_bb);
3957 ctx->builder = old_builder;
3964 emit_llvmonly_handler_start (EmitContext *ctx, MonoBasicBlock *bb, LLVMBasicBlockRef cbb)
3966 int clause_index = MONO_REGION_CLAUSE_INDEX (bb->region);
3967 MonoExceptionClause *clause = &ctx->cfg->header->clauses [clause_index];
3969 // Make exception available to catch blocks
3970 if (!(clause->flags & MONO_EXCEPTION_CLAUSE_FINALLY)) {
3971 LLVMValueRef mono_exc = mono_llvm_emit_load_exception_call (ctx, ctx->builder);
3973 g_assert (ctx->ex_var);
3974 LLVMBuildStore (ctx->builder, LLVMBuildBitCast (ctx->builder, mono_exc, ObjRefType (), ""), ctx->ex_var);
3976 if (bb->in_scount == 1) {
3977 MonoInst *exvar = bb->in_stack [0];
3978 g_assert (!ctx->values [exvar->dreg]);
3979 g_assert (ctx->ex_var);
3980 ctx->values [exvar->dreg] = LLVMBuildLoad (ctx->builder, ctx->ex_var, "save_exception");
3981 emit_volatile_store (ctx, exvar->dreg);
3984 mono_llvm_emit_clear_exception_call (ctx, ctx->builder);
3987 LLVMBuilderRef handler_builder = create_builder (ctx);
3988 LLVMBasicBlockRef target_bb = ctx->bblocks [bb->block_num].call_handler_target_bb;
3989 LLVMPositionBuilderAtEnd (handler_builder, target_bb);
3991 // Make the handler code end with a jump to cbb
3992 LLVMBuildBr (handler_builder, cbb);
3996 emit_handler_start (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef builder)
3998 MonoCompile *cfg = ctx->cfg;
3999 LLVMValueRef *values = ctx->values;
4000 LLVMModuleRef lmodule = ctx->lmodule;
4001 BBInfo *bblocks = ctx->bblocks;
4003 LLVMValueRef personality;
4004 LLVMValueRef landing_pad;
4005 LLVMBasicBlockRef target_bb;
4007 static int ti_generator;
4009 LLVMValueRef type_info;
4013 // <resultval> = landingpad <somety> personality <type> <pers_fn> <clause>+
4015 if (cfg->compile_aot) {
4016 /* Use a dummy personality function */
4017 personality = LLVMGetNamedFunction (lmodule, "mono_personality");
4018 g_assert (personality);
4020 #if LLVM_API_VERSION > 100
4021 personality = ctx->module->personality;
4023 LLVMTypeRef personality_type = LLVMFunctionType (LLVMInt32Type (), NULL, 0, TRUE);
4024 personality = LLVMAddFunction (ctx->lmodule, "mono_personality", personality_type);
4025 LLVMAddFunctionAttr (personality, LLVMNoUnwindAttribute);
4026 LLVMBasicBlockRef entry_bb = LLVMAppendBasicBlock (personality, "ENTRY");
4027 LLVMBuilderRef builder2 = LLVMCreateBuilder ();
4028 LLVMPositionBuilderAtEnd (builder2, entry_bb);
4029 LLVMBuildRet (builder2, LLVMConstInt (LLVMInt32Type (), 0, FALSE));
4030 ctx->module->personality = personality;
4031 LLVMDisposeBuilder (builder2);
4034 static gint32 mapping_inited;
4036 personality = LLVMGetNamedFunction (lmodule, "mono_personality");
4038 if (InterlockedCompareExchange (&mapping_inited, 1, 0) == 0)
4039 LLVMAddGlobalMapping (ctx->module->ee, personality, (gpointer)mono_personality);
4043 i8ptr = LLVMPointerType (LLVMInt8Type (), 0);
4045 clause_index = (mono_get_block_region_notry (cfg, bb->region) >> 8) - 1;
4048 * Create the type info
4050 sprintf (ti_name, "type_info_%d", ti_generator);
4053 if (cfg->compile_aot) {
4054 /* decode_eh_frame () in aot-runtime.c will decode this */
4055 type_info = LLVMAddGlobal (lmodule, LLVMInt32Type (), ti_name);
4056 LLVMSetInitializer (type_info, LLVMConstInt (LLVMInt32Type (), clause_index, FALSE));
4059 * These symbols are not really used, the clause_index is embedded into the EH tables generated by DwarfMonoException in LLVM.
4061 LLVMSetLinkage (type_info, LLVMInternalLinkage);
4063 #if LLVM_API_VERSION > 100
4064 type_info = LLVMAddGlobal (lmodule, LLVMInt32Type (), ti_name);
4065 LLVMSetInitializer (type_info, LLVMConstInt (LLVMInt32Type (), clause_index, FALSE));
4070 * After the cfg mempool is freed, the type info will point to stale memory,
4071 * but this is not a problem, since we decode it once in exception_cb during
4074 ti = (gint32*)mono_mempool_alloc (cfg->mempool, sizeof (gint32));
4075 *(gint32*)ti = clause_index;
4077 type_info = LLVMAddGlobal (lmodule, i8ptr, ti_name);
4079 LLVMAddGlobalMapping (ctx->module->ee, type_info, ti);
4084 LLVMTypeRef members [2], ret_type;
4086 members [0] = i8ptr;
4087 members [1] = LLVMInt32Type ();
4088 ret_type = LLVMStructType (members, 2, FALSE);
4090 landing_pad = LLVMBuildLandingPad (builder, ret_type, personality, 1, "");
4091 LLVMAddClause (landing_pad, type_info);
4093 /* Store the exception into the exvar */
4095 LLVMBuildStore (builder, convert (ctx, LLVMBuildExtractValue (builder, landing_pad, 0, "ex_obj"), ObjRefType ()), ctx->ex_var);
4099 * LLVM throw sites are associated with a one landing pad, and LLVM generated
4100 * code expects control to be transferred to this landing pad even in the
4101 * presence of nested clauses. The landing pad needs to branch to the landing
4102 * pads belonging to nested clauses based on the selector value returned by
4103 * the landing pad instruction, which is passed to the landing pad in a
4104 * register by the EH code.
4106 target_bb = bblocks [bb->block_num].call_handler_target_bb;
4107 g_assert (target_bb);
4110 * Branch to the correct landing pad
4112 LLVMValueRef ex_selector = LLVMBuildExtractValue (builder, landing_pad, 1, "ex_selector");
4113 LLVMValueRef switch_ins = LLVMBuildSwitch (builder, ex_selector, target_bb, 0);
4115 for (l = ctx->nested_in [clause_index]; l; l = l->next) {
4116 int nesting_clause_index = GPOINTER_TO_INT (l->data);
4117 MonoBasicBlock *handler_bb;
4119 handler_bb = (MonoBasicBlock*)g_hash_table_lookup (ctx->clause_to_handler, GINT_TO_POINTER (nesting_clause_index));
4120 g_assert (handler_bb);
4122 g_assert (ctx->bblocks [handler_bb->block_num].call_handler_target_bb);
4123 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), nesting_clause_index, FALSE), ctx->bblocks [handler_bb->block_num].call_handler_target_bb);
4126 /* Start a new bblock which CALL_HANDLER can branch to */
4127 target_bb = bblocks [bb->block_num].call_handler_target_bb;
4129 ctx->builder = builder = create_builder (ctx);
4130 LLVMPositionBuilderAtEnd (ctx->builder, target_bb);
4132 ctx->bblocks [bb->block_num].end_bblock = target_bb;
4134 /* Store the exception into the IL level exvar */
4135 if (bb->in_scount == 1) {
4136 g_assert (bb->in_scount == 1);
4137 exvar = bb->in_stack [0];
4139 // FIXME: This is shared with filter clauses ?
4140 g_assert (!values [exvar->dreg]);
4142 g_assert (ctx->ex_var);
4143 values [exvar->dreg] = LLVMBuildLoad (builder, ctx->ex_var, "");
4144 emit_volatile_store (ctx, exvar->dreg);
4150 process_bb (EmitContext *ctx, MonoBasicBlock *bb)
4152 MonoCompile *cfg = ctx->cfg;
4153 MonoMethodSignature *sig = ctx->sig;
4154 LLVMValueRef method = ctx->lmethod;
4155 LLVMValueRef *values = ctx->values;
4156 LLVMValueRef *addresses = ctx->addresses;
4157 LLVMCallInfo *linfo = ctx->linfo;
4158 BBInfo *bblocks = ctx->bblocks;
4160 LLVMBasicBlockRef cbb;
4161 LLVMBuilderRef builder, starting_builder;
4162 gboolean has_terminator;
4164 LLVMValueRef lhs, rhs;
4167 cbb = get_end_bb (ctx, bb);
4169 builder = create_builder (ctx);
4170 ctx->builder = builder;
4171 LLVMPositionBuilderAtEnd (builder, cbb);
4176 if (bb->flags & BB_EXCEPTION_HANDLER) {
4177 if (!ctx->llvm_only && !bblocks [bb->block_num].invoke_target) {
4178 set_failure (ctx, "handler without invokes");
4183 emit_llvmonly_handler_start (ctx, bb, cbb);
4185 emit_handler_start (ctx, bb, builder);
4188 builder = ctx->builder;
4191 has_terminator = FALSE;
4192 starting_builder = builder;
4193 for (ins = bb->code; ins; ins = ins->next) {
4194 const char *spec = LLVM_INS_INFO (ins->opcode);
4196 char dname_buf [128];
4198 emit_dbg_loc (ctx, builder, ins->cil_code);
4203 * Some steps in llc are non-linear in the size of basic blocks, see #5714.
4204 * Start a new bblock.
4205 * Prevent the bblocks to be merged by doing a volatile load + cond branch
4206 * from localloc-ed memory.
4208 if (!cfg->llvm_only)
4209 ;//set_failure (ctx, "basic block too long");
4211 if (!ctx->long_bb_break_var) {
4212 ctx->long_bb_break_var = build_alloca_llvm_type_name (ctx, LLVMInt32Type (), 0, "long_bb_break");
4213 mono_llvm_build_store (ctx->alloca_builder, LLVMConstInt (LLVMInt32Type (), 0, FALSE), ctx->long_bb_break_var, TRUE, LLVM_BARRIER_NONE);
4216 cbb = gen_bb (ctx, "CONT_LONG_BB");
4217 LLVMBasicBlockRef dummy_bb = gen_bb (ctx, "CONT_LONG_BB_DUMMY");
4219 LLVMValueRef load = mono_llvm_build_load (builder, ctx->long_bb_break_var, "", TRUE);
4221 * The long_bb_break_var is initialized to 0 in the prolog, so this branch will always go to 'cbb'
4222 * but llvm doesn't know that, so the branch is not going to be eliminated.
4224 LLVMValueRef cmp = LLVMBuildICmp (builder, LLVMIntEQ, load, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
4226 LLVMBuildCondBr (builder, cmp, cbb, dummy_bb);
4228 /* Emit a dummy false bblock which does nothing but contains a volatile store so it cannot be eliminated */
4229 ctx->builder = builder = create_builder (ctx);
4230 LLVMPositionBuilderAtEnd (builder, dummy_bb);
4231 mono_llvm_build_store (builder, LLVMConstInt (LLVMInt32Type (), 1, FALSE), ctx->long_bb_break_var, TRUE, LLVM_BARRIER_NONE);
4232 LLVMBuildBr (builder, cbb);
4234 ctx->builder = builder = create_builder (ctx);
4235 LLVMPositionBuilderAtEnd (builder, cbb);
4236 ctx->bblocks [bb->block_num].end_bblock = cbb;
4241 /* There could be instructions after a terminator, skip them */
4244 if (spec [MONO_INST_DEST] != ' ' && !MONO_IS_STORE_MEMBASE (ins)) {
4245 sprintf (dname_buf, "t%d", ins->dreg);
4249 if (spec [MONO_INST_SRC1] != ' ' && spec [MONO_INST_SRC1] != 'v') {
4250 MonoInst *var = get_vreg_to_inst (cfg, ins->sreg1);
4252 if (var && var->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT) && var->opcode != OP_GSHAREDVT_ARG_REGOFFSET) {
4253 lhs = emit_volatile_load (ctx, ins->sreg1);
4255 /* It is ok for SETRET to have an uninitialized argument */
4256 if (!values [ins->sreg1] && ins->opcode != OP_SETRET) {
4257 set_failure (ctx, "sreg1");
4260 lhs = values [ins->sreg1];
4266 if (spec [MONO_INST_SRC2] != ' ' && spec [MONO_INST_SRC2] != ' ') {
4267 MonoInst *var = get_vreg_to_inst (cfg, ins->sreg2);
4268 if (var && var->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT)) {
4269 rhs = emit_volatile_load (ctx, ins->sreg2);
4271 if (!values [ins->sreg2]) {
4272 set_failure (ctx, "sreg2");
4275 rhs = values [ins->sreg2];
4281 //mono_print_ins (ins);
4282 switch (ins->opcode) {
4285 case OP_LIVERANGE_START:
4286 case OP_LIVERANGE_END:
4289 values [ins->dreg] = LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE);
4292 #if SIZEOF_VOID_P == 4
4293 values [ins->dreg] = LLVMConstInt (LLVMInt64Type (), GET_LONG_IMM (ins), FALSE);
4295 values [ins->dreg] = LLVMConstInt (LLVMInt64Type (), (gint64)ins->inst_c0, FALSE);
4299 values [ins->dreg] = LLVMConstReal (LLVMDoubleType (), *(double*)ins->inst_p0);
4303 values [ins->dreg] = LLVMConstReal (LLVMFloatType (), *(float*)ins->inst_p0);
4305 values [ins->dreg] = LLVMConstFPExt (LLVMConstReal (LLVMFloatType (), *(float*)ins->inst_p0), LLVMDoubleType ());
4307 case OP_DUMMY_ICONST:
4308 values [ins->dreg] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
4310 case OP_DUMMY_I8CONST:
4311 values [ins->dreg] = LLVMConstInt (LLVMInt64Type (), 0, FALSE);
4313 case OP_DUMMY_R8CONST:
4314 values [ins->dreg] = LLVMConstReal (LLVMDoubleType (), 0.0f);
4317 LLVMBasicBlockRef target_bb = get_bb (ctx, ins->inst_target_bb);
4318 LLVMBuildBr (builder, target_bb);
4319 has_terminator = TRUE;
4326 LLVMBasicBlockRef new_bb;
4327 LLVMBuilderRef new_builder;
4329 // The default branch is already handled
4330 // FIXME: Handle it here
4332 /* Start new bblock */
4333 sprintf (bb_name, "SWITCH_DEFAULT_BB%d", ctx->default_index ++);
4334 new_bb = LLVMAppendBasicBlock (ctx->lmethod, bb_name);
4336 lhs = convert (ctx, lhs, LLVMInt32Type ());
4337 v = LLVMBuildSwitch (builder, lhs, new_bb, GPOINTER_TO_UINT (ins->klass));
4338 for (i = 0; i < GPOINTER_TO_UINT (ins->klass); ++i) {
4339 MonoBasicBlock *target_bb = ins->inst_many_bb [i];
4341 LLVMAddCase (v, LLVMConstInt (LLVMInt32Type (), i, FALSE), get_bb (ctx, target_bb));
4344 new_builder = create_builder (ctx);
4345 LLVMPositionBuilderAtEnd (new_builder, new_bb);
4346 LLVMBuildUnreachable (new_builder);
4348 has_terminator = TRUE;
4349 g_assert (!ins->next);
4355 switch (linfo->ret.storage) {
4356 case LLVMArgVtypeInReg: {
4357 LLVMTypeRef ret_type = LLVMGetReturnType (LLVMGetElementType (LLVMTypeOf (method)));
4358 LLVMValueRef val, addr, retval;
4361 retval = LLVMGetUndef (ret_type);
4363 if (!addresses [ins->sreg1]) {
4365 * The return type is an LLVM vector type, have to convert between it and the
4366 * real return type which is a struct type.
4368 g_assert (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (sig->ret)));
4369 /* Convert to 2xi64 first */
4370 val = LLVMBuildBitCast (builder, values [ins->sreg1], LLVMVectorType (IntPtrType (), 2), "");
4372 for (i = 0; i < 2; ++i) {
4373 if (linfo->ret.pair_storage [i] == LLVMArgInIReg) {
4374 retval = LLVMBuildInsertValue (builder, retval, LLVMBuildExtractElement (builder, val, LLVMConstInt (LLVMInt32Type (), i, FALSE), ""), i, "");
4376 g_assert (linfo->ret.pair_storage [i] == LLVMArgNone);
4380 addr = LLVMBuildBitCast (builder, addresses [ins->sreg1], LLVMPointerType (ret_type, 0), "");
4381 for (i = 0; i < 2; ++i) {
4382 if (linfo->ret.pair_storage [i] == LLVMArgInIReg) {
4383 LLVMValueRef indexes [2], part_addr;
4385 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
4386 indexes [1] = LLVMConstInt (LLVMInt32Type (), i, FALSE);
4387 part_addr = LLVMBuildGEP (builder, addr, indexes, 2, "");
4389 retval = LLVMBuildInsertValue (builder, retval, LLVMBuildLoad (builder, part_addr, ""), i, "");
4391 g_assert (linfo->ret.pair_storage [i] == LLVMArgNone);
4395 LLVMBuildRet (builder, retval);
4398 case LLVMArgVtypeAsScalar: {
4399 LLVMTypeRef ret_type = LLVMGetReturnType (LLVMGetElementType (LLVMTypeOf (method)));
4400 LLVMValueRef retval;
4402 g_assert (addresses [ins->sreg1]);
4404 retval = LLVMBuildLoad (builder, LLVMBuildBitCast (builder, addresses [ins->sreg1], LLVMPointerType (ret_type, 0), ""), "");
4405 LLVMBuildRet (builder, retval);
4408 case LLVMArgVtypeByVal: {
4409 LLVMValueRef retval;
4411 g_assert (addresses [ins->sreg1]);
4412 retval = LLVMBuildLoad (builder, addresses [ins->sreg1], "");
4413 LLVMBuildRet (builder, retval);
4416 case LLVMArgVtypeByRef: {
4417 LLVMBuildRetVoid (builder);
4420 case LLVMArgGsharedvtFixed: {
4421 LLVMTypeRef ret_type = type_to_llvm_type (ctx, sig->ret);
4422 /* The return value is in lhs, need to store to the vret argument */
4423 /* sreg1 might not be set */
4425 g_assert (cfg->vret_addr);
4426 g_assert (values [cfg->vret_addr->dreg]);
4427 LLVMBuildStore (builder, convert (ctx, lhs, ret_type), convert (ctx, values [cfg->vret_addr->dreg], LLVMPointerType (ret_type, 0)));
4429 LLVMBuildRetVoid (builder);
4432 case LLVMArgGsharedvtFixedVtype: {
4434 LLVMBuildRetVoid (builder);
4437 case LLVMArgGsharedvtVariable: {
4439 LLVMBuildRetVoid (builder);
4442 case LLVMArgVtypeRetAddr: {
4443 LLVMBuildRetVoid (builder);
4446 case LLVMArgAsIArgs:
4447 case LLVMArgFpStruct: {
4448 LLVMTypeRef ret_type = LLVMGetReturnType (LLVMGetElementType (LLVMTypeOf (method)));
4449 LLVMValueRef retval;
4451 g_assert (addresses [ins->sreg1]);
4452 retval = LLVMBuildLoad (builder, convert (ctx, addresses [ins->sreg1], LLVMPointerType (ret_type, 0)), "");
4453 LLVMBuildRet (builder, retval);
4457 case LLVMArgNormal: {
4458 if (!lhs || ctx->is_dead [ins->sreg1]) {
4460 * The method did not set its return value, probably because it
4461 * ends with a throw.
4464 LLVMBuildRetVoid (builder);
4466 LLVMBuildRet (builder, LLVMConstNull (type_to_llvm_type (ctx, sig->ret)));
4468 LLVMBuildRet (builder, convert (ctx, lhs, type_to_llvm_type (ctx, sig->ret)));
4470 has_terminator = TRUE;
4474 g_assert_not_reached ();
4483 case OP_ICOMPARE_IMM:
4484 case OP_LCOMPARE_IMM:
4485 case OP_COMPARE_IMM: {
4487 LLVMValueRef cmp, args [16];
4488 gboolean likely = (ins->flags & MONO_INST_LIKELY) != 0;
4490 if (ins->next->opcode == OP_NOP)
4493 if (ins->next->opcode == OP_BR)
4494 /* The comparison result is not needed */
4497 rel = mono_opcode_to_cond (ins->next->opcode);
4499 if (ins->opcode == OP_ICOMPARE_IMM) {
4500 lhs = convert (ctx, lhs, LLVMInt32Type ());
4501 rhs = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
4503 if (ins->opcode == OP_LCOMPARE_IMM) {
4504 lhs = convert (ctx, lhs, LLVMInt64Type ());
4505 rhs = LLVMConstInt (LLVMInt64Type (), GET_LONG_IMM (ins), FALSE);
4507 if (ins->opcode == OP_LCOMPARE) {
4508 lhs = convert (ctx, lhs, LLVMInt64Type ());
4509 rhs = convert (ctx, rhs, LLVMInt64Type ());
4511 if (ins->opcode == OP_ICOMPARE) {
4512 lhs = convert (ctx, lhs, LLVMInt32Type ());
4513 rhs = convert (ctx, rhs, LLVMInt32Type ());
4517 if (LLVMGetTypeKind (LLVMTypeOf (lhs)) == LLVMPointerTypeKind)
4518 rhs = convert (ctx, rhs, LLVMTypeOf (lhs));
4519 else if (LLVMGetTypeKind (LLVMTypeOf (rhs)) == LLVMPointerTypeKind)
4520 lhs = convert (ctx, lhs, LLVMTypeOf (rhs));
4523 /* We use COMPARE+SETcc/Bcc, llvm uses SETcc+br cond */
4524 if (ins->opcode == OP_FCOMPARE) {
4525 cmp = LLVMBuildFCmp (builder, fpcond_to_llvm_cond [rel], convert (ctx, lhs, LLVMDoubleType ()), convert (ctx, rhs, LLVMDoubleType ()), "");
4526 } else if (ins->opcode == OP_RCOMPARE) {
4527 cmp = LLVMBuildFCmp (builder, fpcond_to_llvm_cond [rel], convert (ctx, lhs, LLVMFloatType ()), convert (ctx, rhs, LLVMFloatType ()), "");
4528 } else if (ins->opcode == OP_COMPARE_IMM) {
4529 if (LLVMGetTypeKind (LLVMTypeOf (lhs)) == LLVMPointerTypeKind && ins->inst_imm == 0)
4530 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], lhs, LLVMConstNull (LLVMTypeOf (lhs)), "");
4532 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE), "");
4533 } else if (ins->opcode == OP_LCOMPARE_IMM) {
4534 if (SIZEOF_REGISTER == 4 && COMPILE_LLVM (cfg)) {
4535 /* The immediate is encoded in two fields */
4536 guint64 l = ((guint64)(guint32)ins->inst_offset << 32) | ((guint32)ins->inst_imm);
4537 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, LLVMInt64Type ()), LLVMConstInt (LLVMInt64Type (), l, FALSE), "");
4539 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, LLVMInt64Type ()), LLVMConstInt (LLVMInt64Type (), ins->inst_imm, FALSE), "");
4542 else if (ins->opcode == OP_COMPARE) {
4543 if (LLVMGetTypeKind (LLVMTypeOf (lhs)) == LLVMPointerTypeKind && LLVMTypeOf (lhs) == LLVMTypeOf (rhs))
4544 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], lhs, rhs, "");
4546 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, IntPtrType ()), convert (ctx, rhs, IntPtrType ()), "");
4548 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], lhs, rhs, "");
4552 args [1] = LLVMConstInt (LLVMInt1Type (), 1, FALSE);
4553 cmp = LLVMBuildCall (ctx->builder, get_intrinsic (ctx, "llvm.expect.i1"), args, 2, "");
4556 if (MONO_IS_COND_BRANCH_OP (ins->next)) {
4557 if (ins->next->inst_true_bb == ins->next->inst_false_bb) {
4559 * If the target bb contains PHI instructions, LLVM requires
4560 * two PHI entries for this bblock, while we only generate one.
4561 * So convert this to an unconditional bblock. (bxc #171).
4563 LLVMBuildBr (builder, get_bb (ctx, ins->next->inst_true_bb));
4565 LLVMBuildCondBr (builder, cmp, get_bb (ctx, ins->next->inst_true_bb), get_bb (ctx, ins->next->inst_false_bb));
4567 has_terminator = TRUE;
4568 } else if (MONO_IS_SETCC (ins->next)) {
4569 sprintf (dname_buf, "t%d", ins->next->dreg);
4571 values [ins->next->dreg] = LLVMBuildZExt (builder, cmp, LLVMInt32Type (), dname);
4573 /* Add stores for volatile variables */
4574 emit_volatile_store (ctx, ins->next->dreg);
4575 } else if (MONO_IS_COND_EXC (ins->next)) {
4576 emit_cond_system_exception (ctx, bb, (const char*)ins->next->inst_p1, cmp);
4579 builder = ctx->builder;
4581 set_failure (ctx, "next");
4599 rel = mono_opcode_to_cond (ins->opcode);
4601 cmp = LLVMBuildFCmp (builder, fpcond_to_llvm_cond [rel], convert (ctx, lhs, LLVMDoubleType ()), convert (ctx, rhs, LLVMDoubleType ()), "");
4602 values [ins->dreg] = LLVMBuildZExt (builder, cmp, LLVMInt32Type (), dname);
4613 rel = mono_opcode_to_cond (ins->opcode);
4615 cmp = LLVMBuildFCmp (builder, fpcond_to_llvm_cond [rel], convert (ctx, lhs, LLVMFloatType ()), convert (ctx, rhs, LLVMFloatType ()), "");
4616 values [ins->dreg] = LLVMBuildZExt (builder, cmp, LLVMInt32Type (), dname);
4624 gboolean empty = TRUE;
4626 /* Check that all input bblocks really branch to us */
4627 for (i = 0; i < bb->in_count; ++i) {
4628 if (bb->in_bb [i]->last_ins && bb->in_bb [i]->last_ins->opcode == OP_NOT_REACHED)
4629 ins->inst_phi_args [i + 1] = -1;
4635 /* LLVM doesn't like phi instructions with zero operands */
4636 ctx->is_dead [ins->dreg] = TRUE;
4640 /* Created earlier, insert it now */
4641 LLVMInsertIntoBuilder (builder, values [ins->dreg]);
4643 for (i = 0; i < ins->inst_phi_args [0]; i++) {
4644 int sreg1 = ins->inst_phi_args [i + 1];
4648 * Count the number of times the incoming bblock branches to us,
4649 * since llvm requires a separate entry for each.
4651 if (bb->in_bb [i]->last_ins && bb->in_bb [i]->last_ins->opcode == OP_SWITCH) {
4652 MonoInst *switch_ins = bb->in_bb [i]->last_ins;
4655 for (j = 0; j < GPOINTER_TO_UINT (switch_ins->klass); ++j) {
4656 if (switch_ins->inst_many_bb [j] == bb)
4663 /* Remember for later */
4664 for (j = 0; j < count; ++j) {
4665 PhiNode *node = (PhiNode*)mono_mempool_alloc0 (ctx->mempool, sizeof (PhiNode));
4668 node->in_bb = bb->in_bb [i];
4670 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);
4680 values [ins->dreg] = lhs;
4684 MonoInst *var = get_vreg_to_inst (cfg, ins->dreg);
4687 values [ins->dreg] = lhs;
4689 if (var && var->klass->byval_arg.type == MONO_TYPE_R4) {
4691 * This is added by the spilling pass in case of the JIT,
4692 * but we have to do it ourselves.
4694 values [ins->dreg] = convert (ctx, values [ins->dreg], LLVMFloatType ());
4698 case OP_MOVE_F_TO_I4: {
4699 values [ins->dreg] = LLVMBuildBitCast (builder, LLVMBuildFPTrunc (builder, lhs, LLVMFloatType (), ""), LLVMInt32Type (), "");
4702 case OP_MOVE_I4_TO_F: {
4703 values [ins->dreg] = LLVMBuildFPExt (builder, LLVMBuildBitCast (builder, lhs, LLVMFloatType (), ""), LLVMDoubleType (), "");
4706 case OP_MOVE_F_TO_I8: {
4707 values [ins->dreg] = LLVMBuildBitCast (builder, lhs, LLVMInt64Type (), "");
4710 case OP_MOVE_I8_TO_F: {
4711 values [ins->dreg] = LLVMBuildBitCast (builder, lhs, LLVMDoubleType (), "");
4744 lhs = convert (ctx, lhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
4745 rhs = convert (ctx, rhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
4747 emit_div_check (ctx, builder, bb, ins, lhs, rhs);
4750 builder = ctx->builder;
4752 switch (ins->opcode) {
4755 values [ins->dreg] = LLVMBuildAdd (builder, lhs, rhs, dname);
4759 values [ins->dreg] = LLVMBuildSub (builder, lhs, rhs, dname);
4763 values [ins->dreg] = LLVMBuildMul (builder, lhs, rhs, dname);
4767 values [ins->dreg] = LLVMBuildSRem (builder, lhs, rhs, dname);
4771 values [ins->dreg] = LLVMBuildURem (builder, lhs, rhs, dname);
4775 values [ins->dreg] = LLVMBuildSDiv (builder, lhs, rhs, dname);
4779 values [ins->dreg] = LLVMBuildUDiv (builder, lhs, rhs, dname);
4783 values [ins->dreg] = LLVMBuildFDiv (builder, lhs, rhs, dname);
4787 values [ins->dreg] = LLVMBuildAnd (builder, lhs, rhs, dname);
4791 values [ins->dreg] = LLVMBuildOr (builder, lhs, rhs, dname);
4795 values [ins->dreg] = LLVMBuildXor (builder, lhs, rhs, dname);
4799 values [ins->dreg] = LLVMBuildShl (builder, lhs, rhs, dname);
4803 values [ins->dreg] = LLVMBuildAShr (builder, lhs, rhs, dname);
4807 values [ins->dreg] = LLVMBuildLShr (builder, lhs, rhs, dname);
4811 values [ins->dreg] = LLVMBuildFAdd (builder, lhs, rhs, dname);
4814 values [ins->dreg] = LLVMBuildFSub (builder, lhs, rhs, dname);
4817 values [ins->dreg] = LLVMBuildFMul (builder, lhs, rhs, dname);
4821 g_assert_not_reached ();
4828 lhs = convert (ctx, lhs, LLVMFloatType ());
4829 rhs = convert (ctx, rhs, LLVMFloatType ());
4830 switch (ins->opcode) {
4832 values [ins->dreg] = LLVMBuildFAdd (builder, lhs, rhs, dname);
4835 values [ins->dreg] = LLVMBuildFSub (builder, lhs, rhs, dname);
4838 values [ins->dreg] = LLVMBuildFMul (builder, lhs, rhs, dname);
4841 values [ins->dreg] = LLVMBuildFDiv (builder, lhs, rhs, dname);
4844 g_assert_not_reached ();
4853 case OP_IREM_UN_IMM:
4855 case OP_IDIV_UN_IMM:
4861 case OP_ISHR_UN_IMM:
4871 case OP_LSHR_UN_IMM:
4877 case OP_SHR_UN_IMM: {
4880 if (spec [MONO_INST_SRC1] == 'l') {
4881 imm = LLVMConstInt (LLVMInt64Type (), GET_LONG_IMM (ins), FALSE);
4883 imm = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
4886 emit_div_check (ctx, builder, bb, ins, lhs, imm);
4889 builder = ctx->builder;
4891 #if SIZEOF_VOID_P == 4
4892 if (ins->opcode == OP_LSHL_IMM || ins->opcode == OP_LSHR_IMM || ins->opcode == OP_LSHR_UN_IMM)
4893 imm = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
4896 if (LLVMGetTypeKind (LLVMTypeOf (lhs)) == LLVMPointerTypeKind)
4897 lhs = convert (ctx, lhs, IntPtrType ());
4898 imm = convert (ctx, imm, LLVMTypeOf (lhs));
4899 switch (ins->opcode) {
4903 values [ins->dreg] = LLVMBuildAdd (builder, lhs, imm, dname);
4907 values [ins->dreg] = LLVMBuildSub (builder, lhs, imm, dname);
4912 values [ins->dreg] = LLVMBuildMul (builder, lhs, imm, dname);
4916 values [ins->dreg] = LLVMBuildSDiv (builder, lhs, imm, dname);
4918 case OP_IDIV_UN_IMM:
4919 case OP_LDIV_UN_IMM:
4920 values [ins->dreg] = LLVMBuildUDiv (builder, lhs, imm, dname);
4924 values [ins->dreg] = LLVMBuildSRem (builder, lhs, imm, dname);
4926 case OP_IREM_UN_IMM:
4927 values [ins->dreg] = LLVMBuildURem (builder, lhs, imm, dname);
4932 values [ins->dreg] = LLVMBuildAnd (builder, lhs, imm, dname);
4936 values [ins->dreg] = LLVMBuildOr (builder, lhs, imm, dname);
4940 values [ins->dreg] = LLVMBuildXor (builder, lhs, imm, dname);
4945 values [ins->dreg] = LLVMBuildShl (builder, lhs, imm, dname);
4950 values [ins->dreg] = LLVMBuildAShr (builder, lhs, imm, dname);
4952 case OP_ISHR_UN_IMM:
4953 /* This is used to implement conv.u4, so the lhs could be an i8 */
4954 lhs = convert (ctx, lhs, LLVMInt32Type ());
4955 imm = convert (ctx, imm, LLVMInt32Type ());
4956 values [ins->dreg] = LLVMBuildLShr (builder, lhs, imm, dname);
4958 case OP_LSHR_UN_IMM:
4960 values [ins->dreg] = LLVMBuildLShr (builder, lhs, imm, dname);
4963 g_assert_not_reached ();
4968 values [ins->dreg] = LLVMBuildSub (builder, LLVMConstInt (LLVMInt32Type (), 0, FALSE), convert (ctx, lhs, LLVMInt32Type ()), dname);
4971 values [ins->dreg] = LLVMBuildSub (builder, LLVMConstInt (LLVMInt64Type (), 0, FALSE), lhs, dname);
4974 lhs = convert (ctx, lhs, LLVMDoubleType ());
4975 values [ins->dreg] = LLVMBuildFSub (builder, LLVMConstReal (LLVMDoubleType (), 0.0), lhs, dname);
4978 lhs = convert (ctx, lhs, LLVMFloatType ());
4979 values [ins->dreg] = LLVMBuildFSub (builder, LLVMConstReal (LLVMFloatType (), 0.0), lhs, dname);
4982 guint32 v = 0xffffffff;
4983 values [ins->dreg] = LLVMBuildXor (builder, LLVMConstInt (LLVMInt32Type (), v, FALSE), convert (ctx, lhs, LLVMInt32Type ()), dname);
4987 guint64 v = 0xffffffffffffffffLL;
4988 values [ins->dreg] = LLVMBuildXor (builder, LLVMConstInt (LLVMInt64Type (), v, FALSE), lhs, dname);
4991 #if defined(TARGET_X86) || defined(TARGET_AMD64)
4993 LLVMValueRef v1, v2;
4995 v1 = LLVMBuildMul (builder, convert (ctx, rhs, IntPtrType ()), LLVMConstInt (IntPtrType (), (1 << ins->backend.shift_amount), FALSE), "");
4996 v2 = LLVMBuildAdd (builder, convert (ctx, lhs, IntPtrType ()), v1, "");
4997 values [ins->dreg] = LLVMBuildAdd (builder, v2, LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE), dname);
5002 case OP_ICONV_TO_I1:
5003 case OP_ICONV_TO_I2:
5004 case OP_ICONV_TO_I4:
5005 case OP_ICONV_TO_U1:
5006 case OP_ICONV_TO_U2:
5007 case OP_ICONV_TO_U4:
5008 case OP_LCONV_TO_I1:
5009 case OP_LCONV_TO_I2:
5010 case OP_LCONV_TO_U1:
5011 case OP_LCONV_TO_U2:
5012 case OP_LCONV_TO_U4: {
5015 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);
5017 /* Have to do two casts since our vregs have type int */
5018 v = LLVMBuildTrunc (builder, lhs, op_to_llvm_type (ins->opcode), "");
5020 values [ins->dreg] = LLVMBuildSExt (builder, v, LLVMInt32Type (), dname);
5022 values [ins->dreg] = LLVMBuildZExt (builder, v, LLVMInt32Type (), dname);
5025 case OP_ICONV_TO_I8:
5026 values [ins->dreg] = LLVMBuildSExt (builder, lhs, LLVMInt64Type (), dname);
5028 case OP_ICONV_TO_U8:
5029 values [ins->dreg] = LLVMBuildZExt (builder, lhs, LLVMInt64Type (), dname);
5031 case OP_FCONV_TO_I4:
5032 case OP_RCONV_TO_I4:
5033 values [ins->dreg] = LLVMBuildFPToSI (builder, lhs, LLVMInt32Type (), dname);
5035 case OP_FCONV_TO_I1:
5036 case OP_RCONV_TO_I1:
5037 values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildFPToSI (builder, lhs, LLVMInt8Type (), dname), LLVMInt32Type (), "");
5039 case OP_FCONV_TO_U1:
5040 case OP_RCONV_TO_U1:
5041 values [ins->dreg] = LLVMBuildZExt (builder, LLVMBuildTrunc (builder, LLVMBuildFPToUI (builder, lhs, IntPtrType (), dname), LLVMInt8Type (), ""), LLVMInt32Type (), "");
5043 case OP_FCONV_TO_I2:
5044 case OP_RCONV_TO_I2:
5045 values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildFPToSI (builder, lhs, LLVMInt16Type (), dname), LLVMInt32Type (), "");
5047 case OP_FCONV_TO_U2:
5048 case OP_RCONV_TO_U2:
5049 values [ins->dreg] = LLVMBuildZExt (builder, LLVMBuildFPToUI (builder, lhs, LLVMInt16Type (), dname), LLVMInt32Type (), "");
5051 case OP_RCONV_TO_U4:
5052 values [ins->dreg] = LLVMBuildFPToUI (builder, lhs, LLVMInt32Type (), dname);
5054 case OP_FCONV_TO_I8:
5055 case OP_RCONV_TO_I8:
5056 values [ins->dreg] = LLVMBuildFPToSI (builder, lhs, LLVMInt64Type (), dname);
5059 values [ins->dreg] = LLVMBuildFPToSI (builder, lhs, IntPtrType (), dname);
5061 case OP_ICONV_TO_R8:
5062 case OP_LCONV_TO_R8:
5063 values [ins->dreg] = LLVMBuildSIToFP (builder, lhs, LLVMDoubleType (), dname);
5065 case OP_ICONV_TO_R_UN:
5066 case OP_LCONV_TO_R_UN:
5067 values [ins->dreg] = LLVMBuildUIToFP (builder, lhs, LLVMDoubleType (), dname);
5069 #if SIZEOF_VOID_P == 4
5072 case OP_LCONV_TO_I4:
5073 values [ins->dreg] = LLVMBuildTrunc (builder, lhs, LLVMInt32Type (), dname);
5075 case OP_ICONV_TO_R4:
5076 case OP_LCONV_TO_R4:
5077 v = LLVMBuildSIToFP (builder, lhs, LLVMFloatType (), "");
5079 values [ins->dreg] = v;
5081 values [ins->dreg] = LLVMBuildFPExt (builder, v, LLVMDoubleType (), dname);
5083 case OP_FCONV_TO_R4:
5084 v = LLVMBuildFPTrunc (builder, lhs, LLVMFloatType (), "");
5086 values [ins->dreg] = v;
5088 values [ins->dreg] = LLVMBuildFPExt (builder, v, LLVMDoubleType (), dname);
5090 case OP_RCONV_TO_R8:
5091 values [ins->dreg] = LLVMBuildFPExt (builder, lhs, LLVMDoubleType (), dname);
5093 case OP_RCONV_TO_R4:
5094 values [ins->dreg] = lhs;
5097 values [ins->dreg] = LLVMBuildSExt (builder, convert (ctx, lhs, LLVMInt32Type ()), LLVMInt64Type (), dname);
5100 values [ins->dreg] = LLVMBuildZExt (builder, convert (ctx, lhs, LLVMInt32Type ()), LLVMInt64Type (), dname);
5103 values [ins->dreg] = LLVMBuildTrunc (builder, lhs, LLVMInt32Type (), dname);
5105 case OP_LOCALLOC_IMM: {
5108 guint32 size = ins->inst_imm;
5109 size = (size + (MONO_ARCH_FRAME_ALIGNMENT - 1)) & ~ (MONO_ARCH_FRAME_ALIGNMENT - 1);
5111 v = mono_llvm_build_alloca (builder, LLVMInt8Type (), LLVMConstInt (LLVMInt32Type (), size, FALSE), MONO_ARCH_FRAME_ALIGNMENT, "");
5113 if (ins->flags & MONO_INST_INIT) {
5114 LLVMValueRef args [5];
5117 args [1] = LLVMConstInt (LLVMInt8Type (), 0, FALSE);
5118 args [2] = LLVMConstInt (LLVMInt32Type (), size, FALSE);
5119 args [3] = LLVMConstInt (LLVMInt32Type (), MONO_ARCH_FRAME_ALIGNMENT, FALSE);
5120 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
5121 LLVMBuildCall (builder, get_intrinsic (ctx, "llvm.memset.p0i8.i32"), args, 5, "");
5124 values [ins->dreg] = v;
5128 LLVMValueRef v, size;
5130 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), "");
5132 v = mono_llvm_build_alloca (builder, LLVMInt8Type (), size, MONO_ARCH_FRAME_ALIGNMENT, "");
5134 if (ins->flags & MONO_INST_INIT) {
5135 LLVMValueRef args [5];
5138 args [1] = LLVMConstInt (LLVMInt8Type (), 0, FALSE);
5140 args [3] = LLVMConstInt (LLVMInt32Type (), MONO_ARCH_FRAME_ALIGNMENT, FALSE);
5141 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
5142 LLVMBuildCall (builder, get_intrinsic (ctx, "llvm.memset.p0i8.i32"), args, 5, "");
5144 values [ins->dreg] = v;
5148 case OP_LOADI1_MEMBASE:
5149 case OP_LOADU1_MEMBASE:
5150 case OP_LOADI2_MEMBASE:
5151 case OP_LOADU2_MEMBASE:
5152 case OP_LOADI4_MEMBASE:
5153 case OP_LOADU4_MEMBASE:
5154 case OP_LOADI8_MEMBASE:
5155 case OP_LOADR4_MEMBASE:
5156 case OP_LOADR8_MEMBASE:
5157 case OP_LOAD_MEMBASE:
5165 LLVMValueRef base, index, addr;
5167 gboolean sext = FALSE, zext = FALSE;
5168 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
5170 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
5175 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)) {
5176 addr = LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE);
5182 if (ins->inst_offset == 0) {
5184 } else if (ins->inst_offset % size != 0) {
5185 /* Unaligned load */
5186 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset, FALSE);
5187 addr = LLVMBuildGEP (builder, convert (ctx, base, LLVMPointerType (LLVMInt8Type (), 0)), &index, 1, "");
5189 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
5190 addr = LLVMBuildGEP (builder, convert (ctx, base, LLVMPointerType (t, 0)), &index, 1, "");
5194 addr = convert (ctx, addr, LLVMPointerType (t, 0));
5196 values [ins->dreg] = emit_load_general (ctx, bb, &builder, size, addr, base, dname, is_volatile, LLVM_BARRIER_NONE);
5198 if (!is_volatile && (ins->flags & MONO_INST_INVARIANT_LOAD)) {
5200 * These will signal LLVM that these loads do not alias any stores, and
5201 * they can't fail, allowing them to be hoisted out of loops.
5203 set_invariant_load_flag (values [ins->dreg]);
5204 #if LLVM_API_VERSION < 100
5205 set_metadata_flag (values [ins->dreg], "mono.nofail.load");
5210 values [ins->dreg] = LLVMBuildSExt (builder, values [ins->dreg], LLVMInt32Type (), dname);
5212 values [ins->dreg] = LLVMBuildZExt (builder, values [ins->dreg], LLVMInt32Type (), dname);
5213 else if (!cfg->r4fp && ins->opcode == OP_LOADR4_MEMBASE)
5214 values [ins->dreg] = LLVMBuildFPExt (builder, values [ins->dreg], LLVMDoubleType (), dname);
5218 case OP_STOREI1_MEMBASE_REG:
5219 case OP_STOREI2_MEMBASE_REG:
5220 case OP_STOREI4_MEMBASE_REG:
5221 case OP_STOREI8_MEMBASE_REG:
5222 case OP_STORER4_MEMBASE_REG:
5223 case OP_STORER8_MEMBASE_REG:
5224 case OP_STORE_MEMBASE_REG: {
5226 LLVMValueRef index, addr, base;
5228 gboolean sext = FALSE, zext = FALSE;
5229 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
5231 if (!values [ins->inst_destbasereg]) {
5232 set_failure (ctx, "inst_destbasereg");
5236 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
5238 base = values [ins->inst_destbasereg];
5239 if (ins->inst_offset % size != 0) {
5240 /* Unaligned store */
5241 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset, FALSE);
5242 addr = LLVMBuildGEP (builder, convert (ctx, base, LLVMPointerType (LLVMInt8Type (), 0)), &index, 1, "");
5244 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
5245 addr = LLVMBuildGEP (builder, convert (ctx, base, LLVMPointerType (t, 0)), &index, 1, "");
5247 emit_store (ctx, bb, &builder, size, convert (ctx, values [ins->sreg1], t), convert (ctx, addr, LLVMPointerType (t, 0)), base, is_volatile);
5251 case OP_STOREI1_MEMBASE_IMM:
5252 case OP_STOREI2_MEMBASE_IMM:
5253 case OP_STOREI4_MEMBASE_IMM:
5254 case OP_STOREI8_MEMBASE_IMM:
5255 case OP_STORE_MEMBASE_IMM: {
5257 LLVMValueRef index, addr, base;
5259 gboolean sext = FALSE, zext = FALSE;
5260 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
5262 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
5264 base = values [ins->inst_destbasereg];
5265 if (ins->inst_offset % size != 0) {
5266 /* Unaligned store */
5267 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset, FALSE);
5268 addr = LLVMBuildGEP (builder, convert (ctx, base, LLVMPointerType (LLVMInt8Type (), 0)), &index, 1, "");
5270 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
5271 addr = LLVMBuildGEP (builder, convert (ctx, base, LLVMPointerType (t, 0)), &index, 1, "");
5273 emit_store (ctx, bb, &builder, size, convert (ctx, LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE), t), convert (ctx, addr, LLVMPointerType (t, 0)), base, is_volatile);
5278 emit_load_general (ctx, bb, &builder, sizeof (gpointer), convert (ctx, lhs, LLVMPointerType (IntPtrType (), 0)), lhs, "", TRUE, LLVM_BARRIER_NONE);
5280 case OP_OUTARG_VTRETADDR:
5288 case OP_VOIDCALL_MEMBASE:
5289 case OP_CALL_MEMBASE:
5290 case OP_LCALL_MEMBASE:
5291 case OP_FCALL_MEMBASE:
5292 case OP_RCALL_MEMBASE:
5293 case OP_VCALL_MEMBASE:
5294 case OP_VOIDCALL_REG:
5299 case OP_VCALL_REG: {
5300 process_call (ctx, bb, &builder, ins);
5305 LLVMValueRef indexes [2];
5306 MonoJumpInfo *tmp_ji, *ji;
5307 LLVMValueRef got_entry_addr;
5311 * FIXME: Can't allocate from the cfg mempool since that is freed if
5312 * the LLVM compile fails.
5314 tmp_ji = g_new0 (MonoJumpInfo, 1);
5315 tmp_ji->type = (MonoJumpInfoType)ins->inst_c1;
5316 tmp_ji->data.target = ins->inst_p0;
5318 ji = mono_aot_patch_info_dup (tmp_ji);
5321 if (ji->type == MONO_PATCH_INFO_ICALL_ADDR) {
5322 char *symbol = mono_aot_get_direct_call_symbol (MONO_PATCH_INFO_ICALL_ADDR_CALL, ji->data.target);
5325 * Avoid emitting a got entry for these since the method is directly called, and it might not be
5326 * resolvable at runtime using dlsym ().
5329 values [ins->dreg] = LLVMConstInt (IntPtrType (), 0, FALSE);
5334 ji->next = cfg->patch_info;
5335 cfg->patch_info = ji;
5337 //mono_add_patch_info (cfg, 0, (MonoJumpInfoType)ins->inst_i1, ins->inst_p0);
5338 got_offset = mono_aot_get_got_offset (cfg->patch_info);
5339 ctx->module->max_got_offset = MAX (ctx->module->max_got_offset, got_offset);
5340 if (!mono_aot_is_shared_got_offset (got_offset)) {
5341 //mono_print_ji (ji);
5343 ctx->has_got_access = TRUE;
5346 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
5347 indexes [1] = LLVMConstInt (LLVMInt32Type (), (gssize)got_offset, FALSE);
5348 got_entry_addr = LLVMBuildGEP (builder, ctx->module->got_var, indexes, 2, "");
5350 name = get_aotconst_name (ji->type, ji->data.target, got_offset);
5351 values [ins->dreg] = LLVMBuildLoad (builder, got_entry_addr, name);
5353 /* Can't use this in llvmonly mode since the got slots are initialized by the methods themselves */
5354 if (!cfg->llvm_only)
5355 set_invariant_load_flag (values [ins->dreg]);
5358 case OP_NOT_REACHED:
5359 LLVMBuildUnreachable (builder);
5360 has_terminator = TRUE;
5361 g_assert (bb->block_num < cfg->max_block_num);
5362 ctx->unreachable [bb->block_num] = TRUE;
5363 /* Might have instructions after this */
5365 MonoInst *next = ins->next;
5367 * FIXME: If later code uses the regs defined by these instructions,
5368 * compilation will fail.
5370 MONO_DELETE_INS (bb, next);
5374 MonoInst *var = ins->inst_i0;
5376 if (var->opcode == OP_VTARG_ADDR) {
5377 /* The variable contains the vtype address */
5378 values [ins->dreg] = values [var->dreg];
5379 } else if (var->opcode == OP_GSHAREDVT_LOCAL) {
5380 values [ins->dreg] = emit_gsharedvt_ldaddr (ctx, var->dreg);
5382 values [ins->dreg] = addresses [var->dreg];
5387 LLVMValueRef args [1];
5389 args [0] = convert (ctx, lhs, LLVMDoubleType ());
5390 values [ins->dreg] = LLVMBuildCall (builder, get_intrinsic (ctx, "llvm.sin.f64"), args, 1, dname);
5394 LLVMValueRef args [1];
5396 args [0] = convert (ctx, lhs, LLVMDoubleType ());
5397 values [ins->dreg] = LLVMBuildCall (builder, get_intrinsic (ctx, "llvm.cos.f64"), args, 1, dname);
5401 LLVMValueRef args [1];
5403 args [0] = convert (ctx, lhs, LLVMDoubleType ());
5404 values [ins->dreg] = LLVMBuildCall (builder, get_intrinsic (ctx, "llvm.sqrt.f64"), args, 1, dname);
5408 LLVMValueRef args [1];
5410 args [0] = convert (ctx, lhs, LLVMDoubleType ());
5411 values [ins->dreg] = LLVMBuildCall (builder, get_intrinsic (ctx, "fabs"), args, 1, dname);
5425 lhs = convert (ctx, lhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
5426 rhs = convert (ctx, rhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
5428 switch (ins->opcode) {
5431 v = LLVMBuildICmp (builder, LLVMIntSLE, lhs, rhs, "");
5435 v = LLVMBuildICmp (builder, LLVMIntSGE, lhs, rhs, "");
5439 v = LLVMBuildICmp (builder, LLVMIntULE, lhs, rhs, "");
5443 v = LLVMBuildICmp (builder, LLVMIntUGE, lhs, rhs, "");
5446 g_assert_not_reached ();
5449 values [ins->dreg] = LLVMBuildSelect (builder, v, lhs, rhs, dname);
5454 * See the ARM64 comment in mono/utils/atomic.h for an explanation of why this
5455 * hack is necessary (for now).
5458 #define ARM64_ATOMIC_FENCE_FIX mono_llvm_build_fence (builder, LLVM_BARRIER_SEQ)
5460 #define ARM64_ATOMIC_FENCE_FIX
5463 case OP_ATOMIC_EXCHANGE_I4:
5464 case OP_ATOMIC_EXCHANGE_I8: {
5465 LLVMValueRef args [2];
5468 if (ins->opcode == OP_ATOMIC_EXCHANGE_I4)
5469 t = LLVMInt32Type ();
5471 t = LLVMInt64Type ();
5473 g_assert (ins->inst_offset == 0);
5475 args [0] = convert (ctx, lhs, LLVMPointerType (t, 0));
5476 args [1] = convert (ctx, rhs, t);
5478 ARM64_ATOMIC_FENCE_FIX;
5479 values [ins->dreg] = mono_llvm_build_atomic_rmw (builder, LLVM_ATOMICRMW_OP_XCHG, args [0], args [1]);
5480 ARM64_ATOMIC_FENCE_FIX;
5483 case OP_ATOMIC_ADD_I4:
5484 case OP_ATOMIC_ADD_I8: {
5485 LLVMValueRef args [2];
5488 if (ins->opcode == OP_ATOMIC_ADD_I4)
5489 t = LLVMInt32Type ();
5491 t = LLVMInt64Type ();
5493 g_assert (ins->inst_offset == 0);
5495 args [0] = convert (ctx, lhs, LLVMPointerType (t, 0));
5496 args [1] = convert (ctx, rhs, t);
5497 ARM64_ATOMIC_FENCE_FIX;
5498 values [ins->dreg] = LLVMBuildAdd (builder, mono_llvm_build_atomic_rmw (builder, LLVM_ATOMICRMW_OP_ADD, args [0], args [1]), args [1], dname);
5499 ARM64_ATOMIC_FENCE_FIX;
5502 case OP_ATOMIC_CAS_I4:
5503 case OP_ATOMIC_CAS_I8: {
5504 LLVMValueRef args [3], val;
5507 if (ins->opcode == OP_ATOMIC_CAS_I4)
5508 t = LLVMInt32Type ();
5510 t = LLVMInt64Type ();
5512 args [0] = convert (ctx, lhs, LLVMPointerType (t, 0));
5514 args [1] = convert (ctx, values [ins->sreg3], t);
5516 args [2] = convert (ctx, values [ins->sreg2], t);
5517 ARM64_ATOMIC_FENCE_FIX;
5518 val = mono_llvm_build_cmpxchg (builder, args [0], args [1], args [2]);
5519 ARM64_ATOMIC_FENCE_FIX;
5520 /* cmpxchg returns a pair */
5521 values [ins->dreg] = LLVMBuildExtractValue (builder, val, 0, "");
5524 case OP_MEMORY_BARRIER: {
5525 mono_llvm_build_fence (builder, (BarrierKind) ins->backend.memory_barrier_kind);
5528 case OP_ATOMIC_LOAD_I1:
5529 case OP_ATOMIC_LOAD_I2:
5530 case OP_ATOMIC_LOAD_I4:
5531 case OP_ATOMIC_LOAD_I8:
5532 case OP_ATOMIC_LOAD_U1:
5533 case OP_ATOMIC_LOAD_U2:
5534 case OP_ATOMIC_LOAD_U4:
5535 case OP_ATOMIC_LOAD_U8:
5536 case OP_ATOMIC_LOAD_R4:
5537 case OP_ATOMIC_LOAD_R8: {
5538 #if LLVM_API_VERSION > 100
5540 gboolean sext, zext;
5542 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
5543 BarrierKind barrier = (BarrierKind) ins->backend.memory_barrier_kind;
5544 LLVMValueRef index, addr;
5546 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
5551 if (ins->inst_offset != 0) {
5552 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
5553 addr = LLVMBuildGEP (builder, convert (ctx, lhs, LLVMPointerType (t, 0)), &index, 1, "");
5558 addr = convert (ctx, addr, LLVMPointerType (t, 0));
5560 ARM64_ATOMIC_FENCE_FIX;
5561 values [ins->dreg] = emit_load_general (ctx, bb, &builder, size, addr, lhs, dname, is_volatile, barrier);
5562 ARM64_ATOMIC_FENCE_FIX;
5565 values [ins->dreg] = LLVMBuildSExt (builder, values [ins->dreg], LLVMInt32Type (), dname);
5567 values [ins->dreg] = LLVMBuildZExt (builder, values [ins->dreg], LLVMInt32Type (), dname);
5570 set_failure (ctx, "atomic mono.load intrinsic");
5574 case OP_ATOMIC_STORE_I1:
5575 case OP_ATOMIC_STORE_I2:
5576 case OP_ATOMIC_STORE_I4:
5577 case OP_ATOMIC_STORE_I8:
5578 case OP_ATOMIC_STORE_U1:
5579 case OP_ATOMIC_STORE_U2:
5580 case OP_ATOMIC_STORE_U4:
5581 case OP_ATOMIC_STORE_U8:
5582 case OP_ATOMIC_STORE_R4:
5583 case OP_ATOMIC_STORE_R8: {
5585 gboolean sext, zext;
5587 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
5588 BarrierKind barrier = (BarrierKind) ins->backend.memory_barrier_kind;
5589 LLVMValueRef index, addr, value, base;
5591 #if LLVM_API_VERSION < 100
5592 if (!cfg->llvm_only) {
5593 set_failure (ctx, "atomic mono.store intrinsic");
5598 if (!values [ins->inst_destbasereg]) {
5599 set_failure (ctx, "inst_destbasereg");
5603 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
5605 base = values [ins->inst_destbasereg];
5606 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
5607 addr = LLVMBuildGEP (builder, convert (ctx, base, LLVMPointerType (t, 0)), &index, 1, "");
5608 value = convert (ctx, values [ins->sreg1], t);
5610 ARM64_ATOMIC_FENCE_FIX;
5611 emit_store_general (ctx, bb, &builder, size, value, addr, base, is_volatile, barrier);
5612 ARM64_ATOMIC_FENCE_FIX;
5615 case OP_RELAXED_NOP: {
5616 #if defined(TARGET_AMD64) || defined(TARGET_X86)
5617 emit_call (ctx, bb, &builder, get_intrinsic (ctx, "llvm.x86.sse2.pause"), NULL, 0);
5624 #if (defined(TARGET_AMD64) || defined(TARGET_X86)) && defined(__linux__)
5626 // 257 == FS segment register
5627 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 257);
5629 // 256 == GS segment register
5630 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 256);
5633 values [ins->dreg] = LLVMBuildLoad (builder, LLVMBuildIntToPtr (builder, LLVMConstInt (IntPtrType (), ins->inst_offset, TRUE), ptrtype, ""), "");
5634 #elif defined(TARGET_AMD64) && defined(TARGET_OSX)
5635 /* See mono_amd64_emit_tls_get () */
5636 int offset = mono_amd64_get_tls_gs_offset () + (ins->inst_offset * 8);
5638 // 256 == GS segment register
5639 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 256);
5640 values [ins->dreg] = LLVMBuildLoad (builder, LLVMBuildIntToPtr (builder, LLVMConstInt (IntPtrType (), offset, TRUE), ptrtype, ""), "");
5642 set_failure (ctx, "opcode tls-get");
5648 case OP_GC_SAFE_POINT: {
5649 LLVMValueRef val, cmp, callee;
5650 LLVMBasicBlockRef poll_bb, cont_bb;
5651 static LLVMTypeRef sig;
5652 const char *icall_name = "mono_threads_state_poll";
5655 sig = LLVMFunctionType0 (LLVMVoidType (), FALSE);
5659 * mono_threads_state_poll ();
5660 * FIXME: Use a preserveall wrapper
5662 val = mono_llvm_build_load (builder, convert (ctx, lhs, LLVMPointerType (IntPtrType (), 0)), "", TRUE);
5663 cmp = LLVMBuildICmp (builder, LLVMIntEQ, val, LLVMConstNull (LLVMTypeOf (val)), "");
5664 poll_bb = gen_bb (ctx, "POLL_BB");
5665 cont_bb = gen_bb (ctx, "CONT_BB");
5666 LLVMBuildCondBr (builder, cmp, cont_bb, poll_bb);
5668 ctx->builder = builder = create_builder (ctx);
5669 LLVMPositionBuilderAtEnd (builder, poll_bb);
5671 if (ctx->cfg->compile_aot) {
5672 callee = get_callee (ctx, sig, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
5674 gpointer target = resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
5675 callee = emit_jit_callee (ctx, icall_name, sig, target);
5677 LLVMBuildCall (builder, callee, NULL, 0, "");
5678 LLVMBuildBr (builder, cont_bb);
5680 ctx->builder = builder = create_builder (ctx);
5681 LLVMPositionBuilderAtEnd (builder, cont_bb);
5682 ctx->bblocks [bb->block_num].end_bblock = cont_bb;
5690 case OP_IADD_OVF_UN:
5692 case OP_ISUB_OVF_UN:
5694 case OP_IMUL_OVF_UN:
5696 case OP_LADD_OVF_UN:
5698 case OP_LSUB_OVF_UN:
5700 case OP_LMUL_OVF_UN:
5702 LLVMValueRef args [2], val, ovf, func;
5704 args [0] = convert (ctx, lhs, op_to_llvm_type (ins->opcode));
5705 args [1] = convert (ctx, rhs, op_to_llvm_type (ins->opcode));
5706 func = get_intrinsic (ctx, ovf_op_to_intrins (ins->opcode));
5708 val = LLVMBuildCall (builder, func, args, 2, "");
5709 values [ins->dreg] = LLVMBuildExtractValue (builder, val, 0, dname);
5710 ovf = LLVMBuildExtractValue (builder, val, 1, "");
5711 emit_cond_system_exception (ctx, bb, "OverflowException", ovf);
5714 builder = ctx->builder;
5720 * We currently model them using arrays. Promotion to local vregs is
5721 * disabled for them in mono_handle_global_vregs () in the LLVM case,
5722 * so we always have an entry in cfg->varinfo for them.
5723 * FIXME: Is this needed ?
5726 MonoClass *klass = ins->klass;
5727 LLVMValueRef args [5];
5731 set_failure (ctx, "!klass");
5735 if (!addresses [ins->dreg])
5736 addresses [ins->dreg] = build_alloca (ctx, &klass->byval_arg);
5737 args [0] = LLVMBuildBitCast (builder, addresses [ins->dreg], LLVMPointerType (LLVMInt8Type (), 0), "");
5738 args [1] = LLVMConstInt (LLVMInt8Type (), 0, FALSE);
5739 args [2] = LLVMConstInt (LLVMInt32Type (), mono_class_value_size (klass, NULL), FALSE);
5741 args [3] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
5742 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
5743 LLVMBuildCall (builder, get_intrinsic (ctx, "llvm.memset.p0i8.i32"), args, 5, "");
5746 case OP_DUMMY_VZERO:
5749 case OP_STOREV_MEMBASE:
5750 case OP_LOADV_MEMBASE:
5752 MonoClass *klass = ins->klass;
5753 LLVMValueRef src = NULL, dst, args [5];
5754 gboolean done = FALSE;
5758 set_failure (ctx, "!klass");
5762 if (mini_is_gsharedvt_klass (klass)) {
5764 set_failure (ctx, "gsharedvt");
5768 switch (ins->opcode) {
5769 case OP_STOREV_MEMBASE:
5770 if (cfg->gen_write_barriers && klass->has_references && ins->inst_destbasereg != cfg->frame_reg &&
5771 LLVMGetInstructionOpcode (values [ins->inst_destbasereg]) != LLVMAlloca) {
5772 /* Decomposed earlier */
5773 g_assert_not_reached ();
5776 if (!addresses [ins->sreg1]) {
5778 g_assert (values [ins->sreg1]);
5779 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));
5780 LLVMBuildStore (builder, values [ins->sreg1], dst);
5783 src = LLVMBuildBitCast (builder, addresses [ins->sreg1], LLVMPointerType (LLVMInt8Type (), 0), "");
5784 dst = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_destbasereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (LLVMInt8Type (), 0));
5787 case OP_LOADV_MEMBASE:
5788 if (!addresses [ins->dreg])
5789 addresses [ins->dreg] = build_alloca (ctx, &klass->byval_arg);
5790 src = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_basereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (LLVMInt8Type (), 0));
5791 dst = LLVMBuildBitCast (builder, addresses [ins->dreg], LLVMPointerType (LLVMInt8Type (), 0), "");
5794 if (!addresses [ins->sreg1])
5795 addresses [ins->sreg1] = build_alloca (ctx, &klass->byval_arg);
5796 if (!addresses [ins->dreg])
5797 addresses [ins->dreg] = build_alloca (ctx, &klass->byval_arg);
5798 src = LLVMBuildBitCast (builder, addresses [ins->sreg1], LLVMPointerType (LLVMInt8Type (), 0), "");
5799 dst = LLVMBuildBitCast (builder, addresses [ins->dreg], LLVMPointerType (LLVMInt8Type (), 0), "");
5802 g_assert_not_reached ();
5812 args [2] = LLVMConstInt (LLVMInt32Type (), mono_class_value_size (klass, NULL), FALSE);
5813 args [3] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
5815 args [3] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
5816 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
5817 LLVMBuildCall (builder, get_intrinsic (ctx, "llvm.memcpy.p0i8.p0i8.i32"), args, 5, "");
5820 case OP_LLVM_OUTARG_VT: {
5821 LLVMArgInfo *ainfo = (LLVMArgInfo*)ins->inst_p0;
5822 MonoType *t = mini_get_underlying_type (ins->inst_vtype);
5824 if (ainfo->storage == LLVMArgGsharedvtVariable) {
5825 MonoInst *var = get_vreg_to_inst (cfg, ins->sreg1);
5827 if (var && var->opcode == OP_GSHAREDVT_LOCAL) {
5828 addresses [ins->dreg] = convert (ctx, emit_gsharedvt_ldaddr (ctx, var->dreg), LLVMPointerType (IntPtrType (), 0));
5830 g_assert (addresses [ins->sreg1]);
5831 addresses [ins->dreg] = addresses [ins->sreg1];
5833 } else if (ainfo->storage == LLVMArgGsharedvtFixed) {
5834 if (!addresses [ins->sreg1]) {
5835 addresses [ins->sreg1] = build_alloca (ctx, t);
5836 g_assert (values [ins->sreg1]);
5838 LLVMBuildStore (builder, convert (ctx, values [ins->sreg1], LLVMGetElementType (LLVMTypeOf (addresses [ins->sreg1]))), addresses [ins->sreg1]);
5839 addresses [ins->dreg] = addresses [ins->sreg1];
5841 if (!addresses [ins->sreg1]) {
5842 addresses [ins->sreg1] = build_alloca (ctx, t);
5843 g_assert (values [ins->sreg1]);
5844 LLVMBuildStore (builder, convert (ctx, values [ins->sreg1], type_to_llvm_type (ctx, t)), addresses [ins->sreg1]);
5846 addresses [ins->dreg] = addresses [ins->sreg1];
5850 case OP_OBJC_GET_SELECTOR: {
5851 const char *name = (const char*)ins->inst_p0;
5854 if (!ctx->module->objc_selector_to_var) {
5855 ctx->module->objc_selector_to_var = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
5857 LLVMValueRef info_var = LLVMAddGlobal (ctx->lmodule, LLVMArrayType (LLVMInt8Type (), 8), "@OBJC_IMAGE_INFO");
5858 int32_t objc_imageinfo [] = { 0, 16 };
5859 LLVMSetInitializer (info_var, mono_llvm_create_constant_data_array ((uint8_t *) &objc_imageinfo, 8));
5860 LLVMSetLinkage (info_var, LLVMPrivateLinkage);
5861 LLVMSetExternallyInitialized (info_var, TRUE);
5862 LLVMSetSection (info_var, "__DATA, __objc_imageinfo,regular,no_dead_strip");
5863 LLVMSetAlignment (info_var, sizeof (mgreg_t));
5864 mark_as_used (ctx->module, info_var);
5867 var = g_hash_table_lookup (ctx->module->objc_selector_to_var, name);
5869 LLVMValueRef indexes [16];
5871 LLVMValueRef name_var = LLVMAddGlobal (ctx->lmodule, LLVMArrayType (LLVMInt8Type (), strlen (name) + 1), "@OBJC_METH_VAR_NAME_");
5872 LLVMSetInitializer (name_var, mono_llvm_create_constant_data_array ((const uint8_t*)name, strlen (name) + 1));
5873 LLVMSetLinkage (name_var, LLVMPrivateLinkage);
5874 LLVMSetSection (name_var, "__TEXT,__objc_methname,cstring_literals");
5875 mark_as_used (ctx->module, name_var);
5877 LLVMValueRef ref_var = LLVMAddGlobal (ctx->lmodule, LLVMPointerType (LLVMInt8Type (), 0), "@OBJC_SELECTOR_REFERENCES_");
5879 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, 0);
5880 indexes [1] = LLVMConstInt (LLVMInt32Type (), 0, 0);
5881 LLVMSetInitializer (ref_var, LLVMConstGEP (name_var, indexes, 2));
5882 LLVMSetLinkage (ref_var, LLVMPrivateLinkage);
5883 LLVMSetExternallyInitialized (ref_var, TRUE);
5884 LLVMSetSection (ref_var, "__DATA, __objc_selrefs, literal_pointers, no_dead_strip");
5885 LLVMSetAlignment (ref_var, sizeof (mgreg_t));
5886 mark_as_used (ctx->module, ref_var);
5888 g_hash_table_insert (ctx->module->objc_selector_to_var, g_strdup (name), ref_var);
5892 values [ins->dreg] = LLVMBuildLoad (builder, var, "");
5899 #if defined(TARGET_X86) || defined(TARGET_AMD64)
5901 values [ins->dreg] = LLVMConstNull (type_to_llvm_type (ctx, &ins->klass->byval_arg));
5904 case OP_LOADX_MEMBASE: {
5905 LLVMTypeRef t = type_to_llvm_type (ctx, &ins->klass->byval_arg);
5908 src = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_basereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (t, 0));
5909 values [ins->dreg] = mono_llvm_build_aligned_load (builder, src, "", FALSE, 1);
5912 case OP_STOREX_MEMBASE: {
5913 LLVMTypeRef t = LLVMTypeOf (values [ins->sreg1]);
5916 dest = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_destbasereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (t, 0));
5917 mono_llvm_build_aligned_store (builder, values [ins->sreg1], dest, FALSE, 1);
5924 values [ins->dreg] = LLVMBuildAdd (builder, lhs, rhs, "");
5928 values [ins->dreg] = LLVMBuildFAdd (builder, lhs, rhs, "");
5934 values [ins->dreg] = LLVMBuildSub (builder, lhs, rhs, "");
5938 values [ins->dreg] = LLVMBuildFSub (builder, lhs, rhs, "");
5942 values [ins->dreg] = LLVMBuildFMul (builder, lhs, rhs, "");
5946 values [ins->dreg] = LLVMBuildFDiv (builder, lhs, rhs, "");
5949 values [ins->dreg] = LLVMBuildAnd (builder, lhs, rhs, "");
5952 values [ins->dreg] = LLVMBuildOr (builder, lhs, rhs, "");
5955 values [ins->dreg] = LLVMBuildXor (builder, lhs, rhs, "");
5959 values [ins->dreg] = LLVMBuildMul (builder, lhs, rhs, "");
5970 LLVMValueRef v = NULL;
5972 switch (ins->opcode) {
5977 t = LLVMVectorType (LLVMInt32Type (), 4);
5978 rt = LLVMVectorType (LLVMFloatType (), 4);
5984 t = LLVMVectorType (LLVMInt64Type (), 2);
5985 rt = LLVMVectorType (LLVMDoubleType (), 2);
5988 t = LLVMInt32Type ();
5989 rt = LLVMInt32Type ();
5990 g_assert_not_reached ();
5993 lhs = LLVMBuildBitCast (builder, lhs, t, "");
5994 rhs = LLVMBuildBitCast (builder, rhs, t, "");
5995 switch (ins->opcode) {
5998 v = LLVMBuildAnd (builder, lhs, rhs, "");
6002 v = LLVMBuildOr (builder, lhs, rhs, "");
6006 v = LLVMBuildXor (builder, lhs, rhs, "");
6010 v = LLVMBuildAnd (builder, rhs, LLVMBuildNot (builder, lhs, ""), "");
6013 values [ins->dreg] = LLVMBuildBitCast (builder, v, rt, "");
6019 LLVMValueRef cmp = LLVMBuildICmp (builder, LLVMIntULT, lhs, rhs, "");
6020 values [ins->dreg] = LLVMBuildSelect (builder, cmp, lhs, rhs, "");
6026 LLVMValueRef cmp = LLVMBuildICmp (builder, LLVMIntUGT, lhs, rhs, "");
6027 values [ins->dreg] = LLVMBuildSelect (builder, cmp, lhs, rhs, "");
6031 LLVMValueRef cmp = LLVMBuildICmp (builder, LLVMIntSLT, lhs, rhs, "");
6032 values [ins->dreg] = LLVMBuildSelect (builder, cmp, lhs, rhs, "");
6049 case OP_PADDB_SAT_UN:
6050 case OP_PADDW_SAT_UN:
6051 case OP_PSUBB_SAT_UN:
6052 case OP_PSUBW_SAT_UN:
6060 case OP_PMULW_HIGH_UN: {
6061 LLVMValueRef args [2];
6066 values [ins->dreg] = LLVMBuildCall (builder, get_intrinsic (ctx, simd_op_to_intrins (ins->opcode)), args, 2, dname);
6073 values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildICmp (builder, LLVMIntEQ, lhs, rhs, ""), LLVMTypeOf (lhs), "");
6077 values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildICmp (builder, LLVMIntSGT, lhs, rhs, ""), LLVMTypeOf (lhs), "");
6085 case OP_EXTRACTX_U2:
6087 case OP_EXTRACT_U1: {
6089 gboolean zext = FALSE;
6091 t = simd_op_to_llvm_type (ins->opcode);
6093 switch (ins->opcode) {
6101 case OP_EXTRACTX_U2:
6106 t = LLVMInt32Type ();
6107 g_assert_not_reached ();
6110 lhs = LLVMBuildBitCast (builder, lhs, t, "");
6111 values [ins->dreg] = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), "");
6113 values [ins->dreg] = LLVMBuildZExt (builder, values [ins->dreg], LLVMInt32Type (), "");
6122 case OP_EXPAND_R8: {
6123 LLVMTypeRef t = simd_op_to_llvm_type (ins->opcode);
6124 LLVMValueRef mask [16], v;
6127 for (i = 0; i < 16; ++i)
6128 mask [i] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
6130 v = convert (ctx, values [ins->sreg1], LLVMGetElementType (t));
6132 values [ins->dreg] = LLVMBuildInsertElement (builder, LLVMConstNull (t), v, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
6133 values [ins->dreg] = LLVMBuildShuffleVector (builder, values [ins->dreg], LLVMGetUndef (t), LLVMConstVector (mask, LLVMGetVectorSize (t)), "");
6138 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt8Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
6141 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt16Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
6144 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt32Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
6147 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt64Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
6150 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMFloatType ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
6153 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMDoubleType ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
6156 #if LLVM_API_VERSION > 100
6158 LLVMValueRef indexes [16];
6160 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
6161 indexes [1] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
6162 LLVMValueRef mask = LLVMConstVector (indexes, 2);
6163 LLVMValueRef shuffle = LLVMBuildShuffleVector (builder, lhs, LLVMConstNull (LLVMTypeOf (lhs)), mask, "");
6164 values [ins->dreg] = LLVMBuildSIToFP (builder, shuffle, LLVMVectorType (LLVMDoubleType (), 2), dname);
6168 LLVMValueRef indexes [16];
6170 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
6171 indexes [1] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
6172 LLVMValueRef mask = LLVMConstVector (indexes, 2);
6173 LLVMValueRef shuffle = LLVMBuildShuffleVector (builder, lhs, LLVMConstNull (LLVMTypeOf (lhs)), mask, "");
6174 values [ins->dreg] = LLVMBuildFPExt (builder, shuffle, LLVMVectorType (LLVMDoubleType (), 2), dname);
6178 values [ins->dreg] = LLVMBuildFPToSI (builder, lhs, LLVMVectorType (LLVMInt32Type (), 4), dname);
6182 #if LLVM_API_VERSION <= 100
6192 case OP_EXTRACT_MASK:
6199 v = convert (ctx, values [ins->sreg1], simd_op_to_llvm_type (ins->opcode));
6201 values [ins->dreg] = LLVMBuildCall (builder, get_intrinsic (ctx, simd_op_to_intrins (ins->opcode)), &v, 1, dname);
6206 LLVMRealPredicate op;
6208 switch (ins->inst_c0) {
6218 case SIMD_COMP_UNORD:
6234 g_assert_not_reached ();
6237 LLVMValueRef cmp = LLVMBuildFCmp (builder, op, lhs, rhs, "");
6238 if (ins->opcode == OP_COMPPD)
6239 values [ins->dreg] = LLVMBuildBitCast (builder, LLVMBuildSExt (builder, cmp, LLVMVectorType (LLVMInt64Type (), 2), ""), LLVMTypeOf (lhs), "");
6241 values [ins->dreg] = LLVMBuildBitCast (builder, LLVMBuildSExt (builder, cmp, LLVMVectorType (LLVMInt32Type (), 4), ""), LLVMTypeOf (lhs), "");
6245 /* This is only used for implementing shifts by non-immediate */
6246 values [ins->dreg] = lhs;
6257 LLVMValueRef args [3];
6260 args [1] = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
6262 values [ins->dreg] = LLVMBuildCall (builder, get_intrinsic (ctx, simd_op_to_intrins (ins->opcode)), args, 2, dname);
6273 case OP_PSHLQ_REG: {
6274 LLVMValueRef args [3];
6277 args [1] = values [ins->sreg2];
6279 values [ins->dreg] = LLVMBuildCall (builder, get_intrinsic (ctx, simd_op_to_intrins (ins->opcode)), args, 2, dname);
6286 case OP_PSHUFLEW_LOW:
6287 case OP_PSHUFLEW_HIGH: {
6289 LLVMValueRef v1 = NULL, v2 = NULL, mask_values [16];
6290 int i, mask_size = 0;
6291 int imask = ins->inst_c0;
6293 /* Convert the x86 shuffle mask to LLVM's */
6294 switch (ins->opcode) {
6297 mask [0] = ((imask >> 0) & 3);
6298 mask [1] = ((imask >> 2) & 3);
6299 mask [2] = ((imask >> 4) & 3) + 4;
6300 mask [3] = ((imask >> 6) & 3) + 4;
6301 v1 = values [ins->sreg1];
6302 v2 = values [ins->sreg2];
6306 mask [0] = ((imask >> 0) & 1);
6307 mask [1] = ((imask >> 1) & 1) + 2;
6308 v1 = values [ins->sreg1];
6309 v2 = values [ins->sreg2];
6311 case OP_PSHUFLEW_LOW:
6313 mask [0] = ((imask >> 0) & 3);
6314 mask [1] = ((imask >> 2) & 3);
6315 mask [2] = ((imask >> 4) & 3);
6316 mask [3] = ((imask >> 6) & 3);
6321 v1 = values [ins->sreg1];
6322 v2 = LLVMGetUndef (LLVMTypeOf (v1));
6324 case OP_PSHUFLEW_HIGH:
6330 mask [4] = 4 + ((imask >> 0) & 3);
6331 mask [5] = 4 + ((imask >> 2) & 3);
6332 mask [6] = 4 + ((imask >> 4) & 3);
6333 mask [7] = 4 + ((imask >> 6) & 3);
6334 v1 = values [ins->sreg1];
6335 v2 = LLVMGetUndef (LLVMTypeOf (v1));
6339 mask [0] = ((imask >> 0) & 3);
6340 mask [1] = ((imask >> 2) & 3);
6341 mask [2] = ((imask >> 4) & 3);
6342 mask [3] = ((imask >> 6) & 3);
6343 v1 = values [ins->sreg1];
6344 v2 = LLVMGetUndef (LLVMTypeOf (v1));
6347 g_assert_not_reached ();
6349 for (i = 0; i < mask_size; ++i)
6350 mask_values [i] = LLVMConstInt (LLVMInt32Type (), mask [i], FALSE);
6352 values [ins->dreg] =
6353 LLVMBuildShuffleVector (builder, v1, v2,
6354 LLVMConstVector (mask_values, mask_size), dname);
6358 case OP_UNPACK_LOWB:
6359 case OP_UNPACK_LOWW:
6360 case OP_UNPACK_LOWD:
6361 case OP_UNPACK_LOWQ:
6362 case OP_UNPACK_LOWPS:
6363 case OP_UNPACK_LOWPD:
6364 case OP_UNPACK_HIGHB:
6365 case OP_UNPACK_HIGHW:
6366 case OP_UNPACK_HIGHD:
6367 case OP_UNPACK_HIGHQ:
6368 case OP_UNPACK_HIGHPS:
6369 case OP_UNPACK_HIGHPD: {
6371 LLVMValueRef mask_values [16];
6372 int i, mask_size = 0;
6373 gboolean low = FALSE;
6375 switch (ins->opcode) {
6376 case OP_UNPACK_LOWB:
6380 case OP_UNPACK_LOWW:
6384 case OP_UNPACK_LOWD:
6385 case OP_UNPACK_LOWPS:
6389 case OP_UNPACK_LOWQ:
6390 case OP_UNPACK_LOWPD:
6394 case OP_UNPACK_HIGHB:
6397 case OP_UNPACK_HIGHW:
6400 case OP_UNPACK_HIGHD:
6401 case OP_UNPACK_HIGHPS:
6404 case OP_UNPACK_HIGHQ:
6405 case OP_UNPACK_HIGHPD:
6409 g_assert_not_reached ();
6413 for (i = 0; i < (mask_size / 2); ++i) {
6415 mask [(i * 2) + 1] = mask_size + i;
6418 for (i = 0; i < (mask_size / 2); ++i) {
6419 mask [(i * 2)] = (mask_size / 2) + i;
6420 mask [(i * 2) + 1] = mask_size + (mask_size / 2) + i;
6424 for (i = 0; i < mask_size; ++i)
6425 mask_values [i] = LLVMConstInt (LLVMInt32Type (), mask [i], FALSE);
6427 values [ins->dreg] =
6428 LLVMBuildShuffleVector (builder, values [ins->sreg1], values [ins->sreg2],
6429 LLVMConstVector (mask_values, mask_size), dname);
6434 LLVMTypeRef t = simd_op_to_llvm_type (ins->opcode);
6435 LLVMValueRef v, val;
6437 v = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
6438 val = LLVMConstNull (t);
6439 val = LLVMBuildInsertElement (builder, val, v, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
6440 val = LLVMBuildInsertElement (builder, val, v, LLVMConstInt (LLVMInt32Type (), 1, FALSE), dname);
6442 values [ins->dreg] = val;
6446 case OP_DUPPS_HIGH: {
6447 LLVMTypeRef t = simd_op_to_llvm_type (ins->opcode);
6448 LLVMValueRef v1, v2, val;
6451 if (ins->opcode == OP_DUPPS_LOW) {
6452 v1 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
6453 v2 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 2, FALSE), "");
6455 v1 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 1, FALSE), "");
6456 v2 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 3, FALSE), "");
6458 val = LLVMConstNull (t);
6459 val = LLVMBuildInsertElement (builder, val, v1, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
6460 val = LLVMBuildInsertElement (builder, val, v1, LLVMConstInt (LLVMInt32Type (), 1, FALSE), "");
6461 val = LLVMBuildInsertElement (builder, val, v2, LLVMConstInt (LLVMInt32Type (), 2, FALSE), "");
6462 val = LLVMBuildInsertElement (builder, val, v2, LLVMConstInt (LLVMInt32Type (), 3, FALSE), "");
6464 values [ins->dreg] = val;
6469 LLVMValueRef args [3];
6473 /* 0xf1 == multiply all 4 elements, add them together, and store the result to the lowest element */
6474 args [2] = LLVMConstInt (LLVMInt32Type (), 0xf1, FALSE);
6476 values [ins->dreg] = LLVMBuildCall (builder, get_intrinsic (ctx, simd_op_to_intrins (ins->opcode)), args, 3, dname);
6486 * EXCEPTION HANDLING
6488 case OP_IMPLICIT_EXCEPTION:
6489 /* This marks a place where an implicit exception can happen */
6490 if (bb->region != -1)
6491 set_failure (ctx, "implicit-exception");
6495 gboolean rethrow = (ins->opcode == OP_RETHROW);
6496 if (ctx->llvm_only) {
6497 emit_llvmonly_throw (ctx, bb, rethrow, lhs);
6498 has_terminator = TRUE;
6499 ctx->unreachable [bb->block_num] = TRUE;
6501 emit_throw (ctx, bb, rethrow, lhs);
6502 builder = ctx->builder;
6506 case OP_CALL_HANDLER: {
6508 * We don't 'call' handlers, but instead simply branch to them.
6509 * The code generated by ENDFINALLY will branch back to us.
6511 LLVMBasicBlockRef noex_bb;
6513 BBInfo *info = &bblocks [ins->inst_target_bb->block_num];
6515 bb_list = info->call_handler_return_bbs;
6518 * Set the indicator variable for the finally clause.
6520 lhs = info->finally_ind;
6522 LLVMBuildStore (builder, LLVMConstInt (LLVMInt32Type (), g_slist_length (bb_list) + 1, FALSE), lhs);
6524 /* Branch to the finally clause */
6525 LLVMBuildBr (builder, info->call_handler_target_bb);
6527 noex_bb = gen_bb (ctx, "CALL_HANDLER_CONT_BB");
6528 info->call_handler_return_bbs = g_slist_append_mempool (cfg->mempool, info->call_handler_return_bbs, noex_bb);
6530 builder = ctx->builder = create_builder (ctx);
6531 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
6533 bblocks [bb->block_num].end_bblock = noex_bb;
6536 case OP_START_HANDLER: {
6539 case OP_ENDFINALLY: {
6540 LLVMBasicBlockRef resume_bb;
6541 MonoBasicBlock *handler_bb;
6542 LLVMValueRef val, switch_ins, callee;
6546 handler_bb = (MonoBasicBlock*)g_hash_table_lookup (ctx->region_to_handler, GUINT_TO_POINTER (mono_get_block_region_notry (cfg, bb->region)));
6547 g_assert (handler_bb);
6548 info = &bblocks [handler_bb->block_num];
6549 lhs = info->finally_ind;
6552 bb_list = info->call_handler_return_bbs;
6554 resume_bb = gen_bb (ctx, "ENDFINALLY_RESUME_BB");
6556 /* Load the finally variable */
6557 val = LLVMBuildLoad (builder, lhs, "");
6559 /* Reset the variable */
6560 LLVMBuildStore (builder, LLVMConstInt (LLVMInt32Type (), 0, FALSE), lhs);
6562 /* Branch to either resume_bb, or to the bblocks in bb_list */
6563 switch_ins = LLVMBuildSwitch (builder, val, resume_bb, g_slist_length (bb_list));
6565 * The other targets are added at the end to handle OP_CALL_HANDLER
6566 * opcodes processed later.
6568 info->endfinally_switch_ins_list = g_slist_append_mempool (cfg->mempool, info->endfinally_switch_ins_list, switch_ins);
6570 builder = ctx->builder = create_builder (ctx);
6571 LLVMPositionBuilderAtEnd (ctx->builder, resume_bb);
6573 if (ctx->llvm_only) {
6574 emit_resume_eh (ctx, bb);
6576 if (ctx->cfg->compile_aot) {
6577 callee = get_callee (ctx, LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE), MONO_PATCH_INFO_INTERNAL_METHOD, "llvm_resume_unwind_trampoline");
6579 #if LLVM_API_VERSION > 100
6580 MonoJitICallInfo *info;
6582 info = mono_find_jit_icall_by_name ("llvm_resume_unwind_trampoline");
6584 gpointer target = (void*)info->func;
6585 LLVMTypeRef icall_sig = LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE);
6586 callee = emit_jit_callee (ctx, "llvm_resume_unwind_trampoline", icall_sig, target);
6588 callee = LLVMGetNamedFunction (ctx->lmodule, "llvm_resume_unwind_trampoline");
6591 LLVMBuildCall (builder, callee, NULL, 0, "");
6592 LLVMBuildUnreachable (builder);
6595 has_terminator = TRUE;
6598 case OP_IL_SEQ_POINT:
6603 sprintf (reason, "opcode %s", mono_inst_name (ins->opcode));
6604 set_failure (ctx, reason);
6612 /* Convert the value to the type required by phi nodes */
6613 if (spec [MONO_INST_DEST] != ' ' && !MONO_IS_STORE_MEMBASE (ins) && ctx->vreg_types [ins->dreg]) {
6614 if (ctx->is_vphi [ins->dreg])
6616 values [ins->dreg] = addresses [ins->dreg];
6618 values [ins->dreg] = convert (ctx, values [ins->dreg], ctx->vreg_types [ins->dreg]);
6621 /* Add stores for volatile variables */
6622 if (spec [MONO_INST_DEST] != ' ' && spec [MONO_INST_DEST] != 'v' && !MONO_IS_STORE_MEMBASE (ins))
6623 emit_volatile_store (ctx, ins->dreg);
6629 if (!has_terminator && bb->next_bb && (bb == cfg->bb_entry || bb->in_count > 0)) {
6630 LLVMBuildBr (builder, get_bb (ctx, bb->next_bb));
6633 if (bb == cfg->bb_exit && sig->ret->type == MONO_TYPE_VOID) {
6634 emit_dbg_loc (ctx, builder, cfg->header->code + cfg->header->code_size - 1);
6635 LLVMBuildRetVoid (builder);
6638 if (bb == cfg->bb_entry)
6639 ctx->last_alloca = LLVMGetLastInstruction (get_bb (ctx, cfg->bb_entry));
6643 * mono_llvm_check_method_supported:
6645 * Do some quick checks to decide whenever cfg->method can be compiled by LLVM, to avoid
6646 * compiling a method twice.
6649 mono_llvm_check_method_supported (MonoCompile *cfg)
6656 if (cfg->method->save_lmf) {
6657 cfg->exception_message = g_strdup ("lmf");
6658 cfg->disable_llvm = TRUE;
6660 if (cfg->disable_llvm)
6664 * Nested clauses where one of the clauses is a finally clause is
6665 * not supported, because LLVM can't figure out the control flow,
6666 * probably because we resume exception handling by calling our
6667 * own function instead of using the 'resume' llvm instruction.
6669 for (i = 0; i < cfg->header->num_clauses; ++i) {
6670 for (j = 0; j < cfg->header->num_clauses; ++j) {
6671 MonoExceptionClause *clause1 = &cfg->header->clauses [i];
6672 MonoExceptionClause *clause2 = &cfg->header->clauses [j];
6674 // FIXME: Nested try clauses fail in some cases too, i.e. #37273
6675 if (i != j && clause1->try_offset >= clause2->try_offset && clause1->handler_offset <= clause2->handler_offset) {
6676 //(clause1->flags == MONO_EXCEPTION_CLAUSE_FINALLY || clause2->flags == MONO_EXCEPTION_CLAUSE_FINALLY)) {
6677 cfg->exception_message = g_strdup ("nested clauses");
6678 cfg->disable_llvm = TRUE;
6683 if (cfg->disable_llvm)
6687 if (cfg->method->dynamic) {
6688 cfg->exception_message = g_strdup ("dynamic.");
6689 cfg->disable_llvm = TRUE;
6691 if (cfg->disable_llvm)
6695 static LLVMCallInfo*
6696 get_llvm_call_info (MonoCompile *cfg, MonoMethodSignature *sig)
6698 LLVMCallInfo *linfo;
6701 if (cfg->gsharedvt && cfg->llvm_only && mini_is_gsharedvt_variable_signature (sig)) {
6705 * Gsharedvt methods have the following calling convention:
6706 * - all arguments are passed by ref, even non generic ones
6707 * - the return value is returned by ref too, using a vret
6708 * argument passed after 'this'.
6710 n = sig->param_count + sig->hasthis;
6711 linfo = (LLVMCallInfo*)mono_mempool_alloc0 (cfg->mempool, sizeof (LLVMCallInfo) + (sizeof (LLVMArgInfo) * n));
6715 linfo->args [pindex ++].storage = LLVMArgNormal;
6717 if (sig->ret->type != MONO_TYPE_VOID) {
6718 if (mini_is_gsharedvt_variable_type (sig->ret))
6719 linfo->ret.storage = LLVMArgGsharedvtVariable;
6720 else if (mini_type_is_vtype (sig->ret))
6721 linfo->ret.storage = LLVMArgGsharedvtFixedVtype;
6723 linfo->ret.storage = LLVMArgGsharedvtFixed;
6724 linfo->vret_arg_index = pindex;
6726 linfo->ret.storage = LLVMArgNone;
6729 for (i = 0; i < sig->param_count; ++i) {
6730 if (sig->params [i]->byref)
6731 linfo->args [pindex].storage = LLVMArgNormal;
6732 else if (mini_is_gsharedvt_variable_type (sig->params [i]))
6733 linfo->args [pindex].storage = LLVMArgGsharedvtVariable;
6734 else if (mini_type_is_vtype (sig->params [i]))
6735 linfo->args [pindex].storage = LLVMArgGsharedvtFixedVtype;
6737 linfo->args [pindex].storage = LLVMArgGsharedvtFixed;
6738 linfo->args [pindex].type = sig->params [i];
6745 linfo = mono_arch_get_llvm_call_info (cfg, sig);
6746 for (i = 0; i < sig->param_count; ++i)
6747 linfo->args [i + sig->hasthis].type = sig->params [i];
6753 emit_method_inner (EmitContext *ctx);
6756 free_ctx (EmitContext *ctx)
6760 g_free (ctx->values);
6761 g_free (ctx->addresses);
6762 g_free (ctx->vreg_types);
6763 g_free (ctx->is_vphi);
6764 g_free (ctx->vreg_cli_types);
6765 g_free (ctx->is_dead);
6766 g_free (ctx->unreachable);
6767 g_ptr_array_free (ctx->phi_values, TRUE);
6768 g_free (ctx->bblocks);
6769 g_hash_table_destroy (ctx->region_to_handler);
6770 g_hash_table_destroy (ctx->clause_to_handler);
6771 g_hash_table_destroy (ctx->jit_callees);
6773 GHashTableIter iter;
6774 g_hash_table_iter_init (&iter, ctx->method_to_callers);
6775 while (g_hash_table_iter_next (&iter, NULL, (gpointer)&l))
6778 g_hash_table_destroy (ctx->method_to_callers);
6780 g_free (ctx->method_name);
6781 g_ptr_array_free (ctx->bblock_list, TRUE);
6783 for (l = ctx->builders; l; l = l->next) {
6784 LLVMBuilderRef builder = (LLVMBuilderRef)l->data;
6785 LLVMDisposeBuilder (builder);
6792 * mono_llvm_emit_method:
6794 * Emit LLVM IL from the mono IL, and compile it to native code using LLVM.
6797 mono_llvm_emit_method (MonoCompile *cfg)
6801 gboolean is_linkonce = FALSE;
6804 /* The code below might acquire the loader lock, so use it for global locking */
6805 mono_loader_lock ();
6807 /* Used to communicate with the callbacks */
6808 mono_native_tls_set_value (current_cfg_tls_id, cfg);
6810 ctx = g_new0 (EmitContext, 1);
6812 ctx->mempool = cfg->mempool;
6815 * This maps vregs to the LLVM instruction defining them
6817 ctx->values = g_new0 (LLVMValueRef, cfg->next_vreg);
6819 * This maps vregs for volatile variables to the LLVM instruction defining their
6822 ctx->addresses = g_new0 (LLVMValueRef, cfg->next_vreg);
6823 ctx->vreg_types = g_new0 (LLVMTypeRef, cfg->next_vreg);
6824 ctx->is_vphi = g_new0 (gboolean, cfg->next_vreg);
6825 ctx->vreg_cli_types = g_new0 (MonoType*, cfg->next_vreg);
6826 ctx->phi_values = g_ptr_array_sized_new (256);
6828 * This signals whenever the vreg was defined by a phi node with no input vars
6829 * (i.e. all its input bblocks end with NOT_REACHABLE).
6831 ctx->is_dead = g_new0 (gboolean, cfg->next_vreg);
6832 /* Whenever the bblock is unreachable */
6833 ctx->unreachable = g_new0 (gboolean, cfg->max_block_num);
6834 ctx->bblock_list = g_ptr_array_sized_new (256);
6836 ctx->region_to_handler = g_hash_table_new (NULL, NULL);
6837 ctx->clause_to_handler = g_hash_table_new (NULL, NULL);
6838 ctx->method_to_callers = g_hash_table_new (NULL, NULL);
6839 ctx->jit_callees = g_hash_table_new (NULL, NULL);
6840 if (cfg->compile_aot) {
6841 ctx->module = &aot_module;
6845 * Allow the linker to discard duplicate copies of wrappers, generic instances etc. by using the 'linkonce'
6846 * linkage for them. This requires the following:
6847 * - the method needs to have a unique mangled name
6848 * - llvmonly mode, since the code in aot-runtime.c would initialize got slots in the wrong aot image etc.
6850 is_linkonce = ctx->module->llvm_only && ctx->module->static_link && mono_aot_is_linkonce_method (cfg->method);
6852 method_name = mono_aot_get_mangled_method_name (cfg->method);
6854 is_linkonce = FALSE;
6857 printf ("%s %s\n", mono_method_full_name (cfg->method, 1), method_name);
6859 printf ("%s\n", mono_method_full_name (cfg->method, 1));
6863 method_name = mono_aot_get_method_name (cfg);
6864 cfg->llvm_method_name = g_strdup (method_name);
6866 init_jit_module (cfg->domain);
6867 ctx->module = (MonoLLVMModule*)domain_jit_info (cfg->domain)->llvm_module;
6868 method_name = mono_method_full_name (cfg->method, TRUE);
6870 ctx->method_name = method_name;
6871 ctx->is_linkonce = is_linkonce;
6873 #if LLVM_API_VERSION > 100
6874 if (cfg->compile_aot)
6875 ctx->lmodule = ctx->module->lmodule;
6877 ctx->lmodule = LLVMModuleCreateWithName ("jit-module");
6879 ctx->lmodule = ctx->module->lmodule;
6881 ctx->llvm_only = ctx->module->llvm_only;
6883 emit_method_inner (ctx);
6885 if (!ctx_ok (ctx)) {
6887 /* Need to add unused phi nodes as they can be referenced by other values */
6888 LLVMBasicBlockRef phi_bb = LLVMAppendBasicBlock (ctx->lmethod, "PHI_BB");
6889 LLVMBuilderRef builder;
6891 builder = create_builder (ctx);
6892 LLVMPositionBuilderAtEnd (builder, phi_bb);
6894 for (i = 0; i < ctx->phi_values->len; ++i) {
6895 LLVMValueRef v = (LLVMValueRef)g_ptr_array_index (ctx->phi_values, i);
6896 if (LLVMGetInstructionParent (v) == NULL)
6897 LLVMInsertIntoBuilder (builder, v);
6900 LLVMDeleteFunction (ctx->lmethod);
6906 mono_native_tls_set_value (current_cfg_tls_id, NULL);
6908 mono_loader_unlock ();
6912 emit_method_inner (EmitContext *ctx)
6914 MonoCompile *cfg = ctx->cfg;
6915 MonoMethodSignature *sig;
6917 LLVMTypeRef method_type;
6918 LLVMValueRef method = NULL;
6919 LLVMValueRef *values = ctx->values;
6920 int i, max_block_num, bb_index;
6921 gboolean last = FALSE;
6922 LLVMCallInfo *linfo;
6923 LLVMModuleRef lmodule = ctx->lmodule;
6925 GPtrArray *bblock_list = ctx->bblock_list;
6926 MonoMethodHeader *header;
6927 MonoExceptionClause *clause;
6930 if (cfg->gsharedvt && !cfg->llvm_only) {
6931 set_failure (ctx, "gsharedvt");
6937 static int count = 0;
6940 char *llvm_count_str = g_getenv ("LLVM_COUNT");
6941 if (llvm_count_str) {
6942 int lcount = atoi (llvm_count_str);
6943 g_free (llvm_count_str);
6944 if (count == lcount) {
6945 printf ("LAST: %s\n", mono_method_full_name (cfg->method, TRUE));
6949 if (count > lcount) {
6950 set_failure (ctx, "count");
6957 sig = mono_method_signature (cfg->method);
6960 linfo = get_llvm_call_info (cfg, sig);
6966 linfo->rgctx_arg = TRUE;
6967 ctx->method_type = method_type = sig_to_llvm_sig_full (ctx, sig, linfo);
6971 method = LLVMAddFunction (lmodule, ctx->method_name, method_type);
6972 ctx->lmethod = method;
6974 if (!cfg->llvm_only)
6975 LLVMSetFunctionCallConv (method, LLVMMono1CallConv);
6976 LLVMSetLinkage (method, LLVMPrivateLinkage);
6978 LLVMAddFunctionAttr (method, LLVMUWTable);
6980 if (cfg->compile_aot) {
6981 LLVMSetLinkage (method, LLVMInternalLinkage);
6982 if (ctx->module->external_symbols) {
6983 LLVMSetLinkage (method, LLVMExternalLinkage);
6984 LLVMSetVisibility (method, LLVMHiddenVisibility);
6986 if (ctx->is_linkonce) {
6987 LLVMSetLinkage (method, LLVMLinkOnceAnyLinkage);
6988 LLVMSetVisibility (method, LLVMDefaultVisibility);
6991 #if LLVM_API_VERSION > 100
6992 LLVMSetLinkage (method, LLVMExternalLinkage);
6994 LLVMSetLinkage (method, LLVMPrivateLinkage);
6998 if (cfg->method->save_lmf && !cfg->llvm_only) {
6999 set_failure (ctx, "lmf");
7003 if (sig->pinvoke && cfg->method->wrapper_type != MONO_WRAPPER_RUNTIME_INVOKE && !cfg->llvm_only) {
7004 set_failure (ctx, "pinvoke signature");
7008 header = cfg->header;
7009 for (i = 0; i < header->num_clauses; ++i) {
7010 clause = &header->clauses [i];
7011 if (clause->flags != MONO_EXCEPTION_CLAUSE_FINALLY && clause->flags != MONO_EXCEPTION_CLAUSE_NONE) {
7012 set_failure (ctx, "non-finally/catch clause.");
7016 if (header->num_clauses || (cfg->method->iflags & METHOD_IMPL_ATTRIBUTE_NOINLINING) || cfg->no_inline)
7017 /* We can't handle inlined methods with clauses */
7018 LLVMAddFunctionAttr (method, LLVMNoInlineAttribute);
7020 if (linfo->rgctx_arg) {
7021 ctx->rgctx_arg = LLVMGetParam (method, linfo->rgctx_arg_pindex);
7022 ctx->rgctx_arg_pindex = linfo->rgctx_arg_pindex;
7024 * We mark the rgctx parameter with the inreg attribute, which is mapped to
7025 * MONO_ARCH_RGCTX_REG in the Mono calling convention in llvm, i.e.
7026 * CC_X86_64_Mono in X86CallingConv.td.
7028 if (!ctx->llvm_only)
7029 LLVMAddAttribute (ctx->rgctx_arg, LLVMInRegAttribute);
7030 LLVMSetValueName (ctx->rgctx_arg, "rgctx");
7032 ctx->rgctx_arg_pindex = -1;
7034 if (cfg->vret_addr) {
7035 values [cfg->vret_addr->dreg] = LLVMGetParam (method, linfo->vret_arg_pindex);
7036 LLVMSetValueName (values [cfg->vret_addr->dreg], "vret");
7037 if (linfo->ret.storage == LLVMArgVtypeByRef) {
7038 LLVMAddAttribute (LLVMGetParam (method, linfo->vret_arg_pindex), LLVMStructRetAttribute);
7039 LLVMAddAttribute (LLVMGetParam (method, linfo->vret_arg_pindex), LLVMNoAliasAttribute);
7044 ctx->this_arg_pindex = linfo->this_arg_pindex;
7045 ctx->this_arg = LLVMGetParam (method, linfo->this_arg_pindex);
7046 values [cfg->args [0]->dreg] = ctx->this_arg;
7047 LLVMSetValueName (values [cfg->args [0]->dreg], "this");
7050 names = g_new (char *, sig->param_count);
7051 mono_method_get_param_names (cfg->method, (const char **) names);
7053 /* Set parameter names/attributes */
7054 for (i = 0; i < sig->param_count; ++i) {
7055 LLVMArgInfo *ainfo = &linfo->args [i + sig->hasthis];
7057 int pindex = ainfo->pindex + ainfo->ndummy_fpargs;
7060 for (j = 0; j < ainfo->ndummy_fpargs; ++j) {
7061 name = g_strdup_printf ("dummy_%d_%d", i, j);
7062 LLVMSetValueName (LLVMGetParam (method, ainfo->pindex + j), name);
7066 if (ainfo->storage == LLVMArgVtypeInReg && ainfo->pair_storage [0] == LLVMArgNone && ainfo->pair_storage [1] == LLVMArgNone)
7069 values [cfg->args [i + sig->hasthis]->dreg] = LLVMGetParam (method, pindex);
7070 if (ainfo->storage == LLVMArgGsharedvtFixed || ainfo->storage == LLVMArgGsharedvtFixedVtype) {
7071 if (names [i] && names [i][0] != '\0')
7072 name = g_strdup_printf ("p_arg_%s", names [i]);
7074 name = g_strdup_printf ("p_arg_%d", i);
7076 if (names [i] && names [i][0] != '\0')
7077 name = g_strdup_printf ("arg_%s", names [i]);
7079 name = g_strdup_printf ("arg_%d", i);
7081 LLVMSetValueName (values [cfg->args [i + sig->hasthis]->dreg], name);
7083 if (ainfo->storage == LLVMArgVtypeByVal)
7084 LLVMAddAttribute (LLVMGetParam (method, pindex), LLVMByValAttribute);
7086 if (ainfo->storage == LLVMArgVtypeByRef) {
7088 cfg->args [i + sig->hasthis]->opcode = OP_VTARG_ADDR;
7093 if (ctx->module->emit_dwarf && cfg->compile_aot && mono_debug_enabled ()) {
7094 ctx->minfo = mono_debug_lookup_method (cfg->method);
7095 ctx->dbg_md = emit_dbg_subprogram (ctx, cfg, method, ctx->method_name);
7099 for (bb = cfg->bb_entry; bb; bb = bb->next_bb)
7100 max_block_num = MAX (max_block_num, bb->block_num);
7101 ctx->bblocks = bblocks = g_new0 (BBInfo, max_block_num + 1);
7103 /* Add branches between non-consecutive bblocks */
7104 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
7105 if (bb->last_ins && MONO_IS_COND_BRANCH_OP (bb->last_ins) &&
7106 bb->next_bb != bb->last_ins->inst_false_bb) {
7108 MonoInst *inst = (MonoInst*)mono_mempool_alloc0 (cfg->mempool, sizeof (MonoInst));
7109 inst->opcode = OP_BR;
7110 inst->inst_target_bb = bb->last_ins->inst_false_bb;
7111 mono_bblock_add_inst (bb, inst);
7116 * The INDIRECT flag added by OP_LDADDR inhibits optimizations, even if the LDADDR
7117 * was later optimized away, so clear these flags, and add them back for the still
7118 * present OP_LDADDR instructions.
7120 for (i = 0; i < cfg->next_vreg; ++i) {
7123 ins = get_vreg_to_inst (cfg, i);
7124 if (ins && ins != cfg->rgctx_var)
7125 ins->flags &= ~MONO_INST_INDIRECT;
7129 * Make a first pass over the code to precreate PHI nodes/set INDIRECT flags.
7131 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
7133 LLVMBuilderRef builder;
7135 char dname_buf[128];
7137 builder = create_builder (ctx);
7139 for (ins = bb->code; ins; ins = ins->next) {
7140 switch (ins->opcode) {
7145 LLVMTypeRef phi_type = llvm_type_to_stack_type (cfg, type_to_llvm_type (ctx, &ins->klass->byval_arg));
7150 if (ins->opcode == OP_VPHI) {
7151 /* Treat valuetype PHI nodes as operating on the address itself */
7152 g_assert (ins->klass);
7153 phi_type = LLVMPointerType (type_to_llvm_type (ctx, &ins->klass->byval_arg), 0);
7157 * Have to precreate these, as they can be referenced by
7158 * earlier instructions.
7160 sprintf (dname_buf, "t%d", ins->dreg);
7162 values [ins->dreg] = LLVMBuildPhi (builder, phi_type, dname);
7164 if (ins->opcode == OP_VPHI)
7165 ctx->addresses [ins->dreg] = values [ins->dreg];
7167 g_ptr_array_add (ctx->phi_values, values [ins->dreg]);
7170 * Set the expected type of the incoming arguments since these have
7171 * to have the same type.
7173 for (i = 0; i < ins->inst_phi_args [0]; i++) {
7174 int sreg1 = ins->inst_phi_args [i + 1];
7177 if (ins->opcode == OP_VPHI)
7178 ctx->is_vphi [sreg1] = TRUE;
7179 ctx->vreg_types [sreg1] = phi_type;
7185 ((MonoInst*)ins->inst_p0)->flags |= MONO_INST_INDIRECT;
7194 * Create an ordering for bblocks, use the depth first order first, then
7195 * put the exception handling bblocks last.
7197 for (bb_index = 0; bb_index < cfg->num_bblocks; ++bb_index) {
7198 bb = cfg->bblocks [bb_index];
7199 if (!(bb->region != -1 && !MONO_BBLOCK_IS_IN_REGION (bb, MONO_REGION_TRY))) {
7200 g_ptr_array_add (bblock_list, bb);
7201 bblocks [bb->block_num].added = TRUE;
7205 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
7206 if (!bblocks [bb->block_num].added)
7207 g_ptr_array_add (bblock_list, bb);
7211 * Second pass: generate code.
7214 LLVMBuilderRef entry_builder = create_builder (ctx);
7215 LLVMBasicBlockRef entry_bb = get_bb (ctx, cfg->bb_entry);
7216 LLVMPositionBuilderAtEnd (entry_builder, entry_bb);
7217 emit_entry_bb (ctx, entry_builder);
7219 // Make landing pads first
7220 ctx->exc_meta = g_hash_table_new_full (NULL, NULL, NULL, NULL);
7222 if (ctx->llvm_only) {
7223 size_t group_index = 0;
7224 while (group_index < cfg->header->num_clauses) {
7226 size_t cursor = group_index;
7227 while (cursor < cfg->header->num_clauses &&
7228 CLAUSE_START (&cfg->header->clauses [cursor]) == CLAUSE_START (&cfg->header->clauses [group_index]) &&
7229 CLAUSE_END (&cfg->header->clauses [cursor]) == CLAUSE_END (&cfg->header->clauses [group_index])) {
7234 LLVMBasicBlockRef lpad_bb = emit_landing_pad (ctx, group_index, count);
7235 intptr_t key = CLAUSE_END (&cfg->header->clauses [group_index]);
7236 g_hash_table_insert (ctx->exc_meta, (gpointer)key, lpad_bb);
7238 group_index = cursor;
7242 for (bb_index = 0; bb_index < bblock_list->len; ++bb_index) {
7243 bb = (MonoBasicBlock*)g_ptr_array_index (bblock_list, bb_index);
7245 // Prune unreachable mono BBs.
7246 if (!(bb == cfg->bb_entry || bb->in_count > 0))
7249 process_bb (ctx, bb);
7253 g_hash_table_destroy (ctx->exc_meta);
7255 mono_memory_barrier ();
7257 /* Add incoming phi values */
7258 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
7259 GSList *l, *ins_list;
7261 ins_list = bblocks [bb->block_num].phi_nodes;
7263 for (l = ins_list; l; l = l->next) {
7264 PhiNode *node = (PhiNode*)l->data;
7265 MonoInst *phi = node->phi;
7266 int sreg1 = node->sreg;
7267 LLVMBasicBlockRef in_bb;
7272 in_bb = get_end_bb (ctx, node->in_bb);
7274 if (ctx->unreachable [node->in_bb->block_num])
7277 if (!values [sreg1]) {
7278 /* Can happen with values in EH clauses */
7279 set_failure (ctx, "incoming phi sreg1");
7283 if (phi->opcode == OP_VPHI) {
7284 g_assert (LLVMTypeOf (ctx->addresses [sreg1]) == LLVMTypeOf (values [phi->dreg]));
7285 LLVMAddIncoming (values [phi->dreg], &ctx->addresses [sreg1], &in_bb, 1);
7287 if (LLVMTypeOf (values [sreg1]) != LLVMTypeOf (values [phi->dreg])) {
7288 set_failure (ctx, "incoming phi arg type mismatch");
7291 g_assert (LLVMTypeOf (values [sreg1]) == LLVMTypeOf (values [phi->dreg]));
7292 LLVMAddIncoming (values [phi->dreg], &values [sreg1], &in_bb, 1);
7297 /* Nullify empty phi instructions */
7298 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
7299 GSList *l, *ins_list;
7301 ins_list = bblocks [bb->block_num].phi_nodes;
7303 for (l = ins_list; l; l = l->next) {
7304 PhiNode *node = (PhiNode*)l->data;
7305 MonoInst *phi = node->phi;
7306 LLVMValueRef phi_ins = values [phi->dreg];
7309 /* Already removed */
7312 if (LLVMCountIncoming (phi_ins) == 0) {
7313 mono_llvm_replace_uses_of (phi_ins, LLVMConstNull (LLVMTypeOf (phi_ins)));
7314 LLVMInstructionEraseFromParent (phi_ins);
7315 values [phi->dreg] = NULL;
7320 /* Create the SWITCH statements for ENDFINALLY instructions */
7321 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
7322 BBInfo *info = &bblocks [bb->block_num];
7324 for (l = info->endfinally_switch_ins_list; l; l = l->next) {
7325 LLVMValueRef switch_ins = (LLVMValueRef)l->data;
7326 GSList *bb_list = info->call_handler_return_bbs;
7328 GSList *bb_list_iter;
7330 for (bb_list_iter = bb_list; bb_list_iter; bb_list_iter = g_slist_next (bb_list_iter)) {
7331 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), i + 1, FALSE), (LLVMBasicBlockRef)bb_list_iter->data);
7337 /* Initialize the method if needed */
7338 if (cfg->compile_aot && ctx->llvm_only) {
7339 // FIXME: Add more shared got entries
7340 ctx->builder = create_builder (ctx);
7341 LLVMPositionBuilderAtEnd (ctx->builder, ctx->init_bb);
7343 ctx->module->max_method_idx = MAX (ctx->module->max_method_idx, cfg->method_index);
7345 // FIXME: beforefieldinit
7347 * NATIVE_TO_MANAGED methods might be called on a thread not attached to the runtime, so they are initialized when loaded
7348 * in load_method ().
7350 if ((ctx->has_got_access || mono_class_get_cctor (cfg->method->klass)) && !(cfg->method->wrapper_type == MONO_WRAPPER_NATIVE_TO_MANAGED)) {
7352 * linkonce methods shouldn't have initialization,
7353 * because they might belong to assemblies which
7354 * haven't been loaded yet.
7356 g_assert (!ctx->is_linkonce);
7357 emit_init_method (ctx);
7359 LLVMBuildBr (ctx->builder, ctx->inited_bb);
7363 if (cfg->llvm_only) {
7364 GHashTableIter iter;
7366 GSList *callers, *l, *l2;
7369 * Add the contents of ctx->method_to_callers to module->method_to_callers.
7370 * We can't do this earlier, as it contains llvm instructions which can be
7371 * freed if compilation fails.
7372 * FIXME: Get rid of this when all methods can be llvm compiled.
7374 g_hash_table_iter_init (&iter, ctx->method_to_callers);
7375 while (g_hash_table_iter_next (&iter, (void**)&method, (void**)&callers)) {
7376 for (l = callers; l; l = l->next) {
7377 l2 = (GSList*)g_hash_table_lookup (ctx->module->method_to_callers, method);
7378 l2 = g_slist_prepend (l2, l->data);
7379 g_hash_table_insert (ctx->module->method_to_callers, method, l2);
7384 if (cfg->verbose_level > 1)
7385 mono_llvm_dump_value (method);
7387 if (cfg->compile_aot && !cfg->llvm_only)
7388 mark_as_used (ctx->module, method);
7390 if (!cfg->llvm_only) {
7391 LLVMValueRef md_args [16];
7392 LLVMValueRef md_node;
7395 if (cfg->compile_aot)
7396 method_index = mono_aot_get_method_index (cfg->orig_method);
7399 md_args [0] = LLVMMDString (ctx->method_name, strlen (ctx->method_name));
7400 md_args [1] = LLVMConstInt (LLVMInt32Type (), method_index, FALSE);
7401 md_node = LLVMMDNode (md_args, 2);
7402 LLVMAddNamedMetadataOperand (lmodule, "mono.function_indexes", md_node);
7403 //LLVMSetMetadata (method, md_kind, LLVMMDNode (&md_arg, 1));
7406 if (cfg->compile_aot) {
7407 /* Don't generate native code, keep the LLVM IR */
7408 if (cfg->verbose_level)
7409 printf ("%s emitted as %s\n", mono_method_full_name (cfg->method, TRUE), ctx->method_name);
7411 #if LLVM_API_VERSION < 100
7412 /* VerifyFunction can't handle some of the debug info created by DIBuilder in llvm 3.9 */
7413 int err = LLVMVerifyFunction(ctx->lmethod, LLVMPrintMessageAction);
7414 g_assert (err == 0);
7417 //LLVMVerifyFunction(method, 0);
7418 #if LLVM_API_VERSION > 100
7419 MonoDomain *domain = mono_domain_get ();
7420 MonoJitDomainInfo *domain_info;
7421 int nvars = g_hash_table_size (ctx->jit_callees);
7422 LLVMValueRef *callee_vars = g_new0 (LLVMValueRef, nvars);
7423 gpointer *callee_addrs = g_new0 (gpointer, nvars);
7424 GHashTableIter iter;
7430 * Compute the addresses of the LLVM globals pointing to the
7431 * methods called by the current method. Pass it to the trampoline
7432 * code so it can update them after their corresponding method was
7435 g_hash_table_iter_init (&iter, ctx->jit_callees);
7437 while (g_hash_table_iter_next (&iter, NULL, (void**)&var))
7438 callee_vars [i ++] = var;
7440 cfg->native_code = mono_llvm_compile_method (ctx->module->mono_ee, ctx->lmethod, nvars, callee_vars, callee_addrs, &eh_frame);
7442 decode_llvm_eh_info (ctx, eh_frame);
7444 mono_domain_lock (domain);
7445 domain_info = domain_jit_info (domain);
7446 if (!domain_info->llvm_jit_callees)
7447 domain_info->llvm_jit_callees = g_hash_table_new (NULL, NULL);
7448 g_hash_table_iter_init (&iter, ctx->jit_callees);
7450 while (g_hash_table_iter_next (&iter, (void**)&callee, (void**)&var)) {
7451 GSList *addrs = g_hash_table_lookup (domain_info->llvm_jit_callees, callee);
7452 addrs = g_slist_prepend (addrs, callee_addrs [i]);
7453 g_hash_table_insert (domain_info->llvm_jit_callees, callee, addrs);
7456 mono_domain_unlock (domain);
7458 mono_llvm_optimize_method (ctx->module->mono_ee, ctx->lmethod);
7460 if (cfg->verbose_level > 1)
7461 mono_llvm_dump_value (ctx->lmethod);
7463 cfg->native_code = (unsigned char*)LLVMGetPointerToGlobal (ctx->module->ee, ctx->lmethod);
7465 /* Set by emit_cb */
7466 g_assert (cfg->code_len);
7470 if (ctx->module->method_to_lmethod)
7471 g_hash_table_insert (ctx->module->method_to_lmethod, cfg->method, ctx->lmethod);
7472 if (ctx->module->idx_to_lmethod)
7473 g_hash_table_insert (ctx->module->idx_to_lmethod, GINT_TO_POINTER (cfg->method_index), ctx->lmethod);
7475 if (ctx->llvm_only && cfg->orig_method->klass->valuetype && !(cfg->orig_method->flags & METHOD_ATTRIBUTE_STATIC))
7476 emit_unbox_tramp (ctx, ctx->method_name, ctx->method_type, ctx->lmethod, cfg->method_index);
7480 * mono_llvm_create_vars:
7482 * Same as mono_arch_create_vars () for LLVM.
7485 mono_llvm_create_vars (MonoCompile *cfg)
7487 MonoMethodSignature *sig;
7489 sig = mono_method_signature (cfg->method);
7490 if (cfg->gsharedvt && cfg->llvm_only) {
7491 if (mini_is_gsharedvt_variable_signature (sig) && sig->ret->type != MONO_TYPE_VOID) {
7492 cfg->vret_addr = mono_compile_create_var (cfg, &mono_get_intptr_class ()->byval_arg, OP_ARG);
7493 if (G_UNLIKELY (cfg->verbose_level > 1)) {
7494 printf ("vret_addr = ");
7495 mono_print_ins (cfg->vret_addr);
7499 mono_arch_create_vars (cfg);
7504 * mono_llvm_emit_call:
7506 * Same as mono_arch_emit_call () for LLVM.
7509 mono_llvm_emit_call (MonoCompile *cfg, MonoCallInst *call)
7512 MonoMethodSignature *sig;
7513 int i, n, stack_size;
7518 sig = call->signature;
7519 n = sig->param_count + sig->hasthis;
7521 call->cinfo = get_llvm_call_info (cfg, sig);
7523 if (cfg->disable_llvm)
7526 if (sig->call_convention == MONO_CALL_VARARG) {
7527 cfg->exception_message = g_strdup ("varargs");
7528 cfg->disable_llvm = TRUE;
7531 for (i = 0; i < n; ++i) {
7534 ainfo = call->cinfo->args + i;
7536 in = call->args [i];
7538 /* Simply remember the arguments */
7539 switch (ainfo->storage) {
7540 case LLVMArgNormal: {
7541 MonoType *t = (sig->hasthis && i == 0) ? &mono_get_intptr_class ()->byval_arg : ainfo->type;
7544 opcode = mono_type_to_regmove (cfg, t);
7545 if (opcode == OP_FMOVE) {
7546 MONO_INST_NEW (cfg, ins, OP_FMOVE);
7547 ins->dreg = mono_alloc_freg (cfg);
7548 } else if (opcode == OP_LMOVE) {
7549 MONO_INST_NEW (cfg, ins, OP_LMOVE);
7550 ins->dreg = mono_alloc_lreg (cfg);
7551 } else if (opcode == OP_RMOVE) {
7552 MONO_INST_NEW (cfg, ins, OP_RMOVE);
7553 ins->dreg = mono_alloc_freg (cfg);
7555 MONO_INST_NEW (cfg, ins, OP_MOVE);
7556 ins->dreg = mono_alloc_ireg (cfg);
7558 ins->sreg1 = in->dreg;
7561 case LLVMArgVtypeByVal:
7562 case LLVMArgVtypeByRef:
7563 case LLVMArgVtypeInReg:
7564 case LLVMArgVtypeAsScalar:
7565 case LLVMArgAsIArgs:
7566 case LLVMArgAsFpArgs:
7567 case LLVMArgGsharedvtVariable:
7568 case LLVMArgGsharedvtFixed:
7569 case LLVMArgGsharedvtFixedVtype:
7570 MONO_INST_NEW (cfg, ins, OP_LLVM_OUTARG_VT);
7571 ins->dreg = mono_alloc_ireg (cfg);
7572 ins->sreg1 = in->dreg;
7573 ins->inst_p0 = mono_mempool_alloc0 (cfg->mempool, sizeof (LLVMArgInfo));
7574 memcpy (ins->inst_p0, ainfo, sizeof (LLVMArgInfo));
7575 ins->inst_vtype = ainfo->type;
7576 ins->klass = mono_class_from_mono_type (ainfo->type);
7579 cfg->exception_message = g_strdup ("ainfo->storage");
7580 cfg->disable_llvm = TRUE;
7584 if (!cfg->disable_llvm) {
7585 MONO_ADD_INS (cfg->cbb, ins);
7586 mono_call_inst_add_outarg_reg (cfg, call, ins->dreg, 0, FALSE);
7591 static unsigned char*
7592 alloc_cb (LLVMValueRef function, int size)
7596 cfg = (MonoCompile*)mono_native_tls_get_value (current_cfg_tls_id);
7600 return (unsigned char*)mono_domain_code_reserve (cfg->domain, size);
7602 return (unsigned char*)mono_domain_code_reserve (mono_domain_get (), size);
7607 emitted_cb (LLVMValueRef function, void *start, void *end)
7611 cfg = (MonoCompile*)mono_native_tls_get_value (current_cfg_tls_id);
7613 cfg->code_len = (guint8*)end - (guint8*)start;
7617 exception_cb (void *data)
7620 MonoJitExceptionInfo *ei;
7621 guint32 ei_len, i, j, nested_len, nindex;
7622 gpointer *type_info;
7623 int this_reg, this_offset;
7625 cfg = (MonoCompile*)mono_native_tls_get_value (current_cfg_tls_id);
7629 * data points to a DWARF FDE structure, convert it to our unwind format and
7631 * An alternative would be to save it directly, and modify our unwinder to work
7634 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);
7635 if (cfg->verbose_level > 1)
7636 mono_print_unwind_info (cfg->encoded_unwind_ops, cfg->encoded_unwind_ops_len);
7638 /* Count nested clauses */
7640 for (i = 0; i < ei_len; ++i) {
7641 gint32 cindex1 = *(gint32*)type_info [i];
7642 MonoExceptionClause *clause1 = &cfg->header->clauses [cindex1];
7644 for (j = 0; j < cfg->header->num_clauses; ++j) {
7646 MonoExceptionClause *clause2 = &cfg->header->clauses [cindex2];
7648 if (cindex1 != cindex2 && clause1->try_offset >= clause2->try_offset && clause1->handler_offset <= clause2->handler_offset) {
7654 cfg->llvm_ex_info = (MonoJitExceptionInfo*)mono_mempool_alloc0 (cfg->mempool, (ei_len + nested_len) * sizeof (MonoJitExceptionInfo));
7655 cfg->llvm_ex_info_len = ei_len + nested_len;
7656 memcpy (cfg->llvm_ex_info, ei, ei_len * sizeof (MonoJitExceptionInfo));
7657 /* Fill the rest of the information from the type info */
7658 for (i = 0; i < ei_len; ++i) {
7659 gint32 clause_index = *(gint32*)type_info [i];
7660 MonoExceptionClause *clause = &cfg->header->clauses [clause_index];
7662 cfg->llvm_ex_info [i].flags = clause->flags;
7663 cfg->llvm_ex_info [i].data.catch_class = clause->data.catch_class;
7664 cfg->llvm_ex_info [i].clause_index = clause_index;
7668 * For nested clauses, the LLVM produced exception info associates the try interval with
7669 * the innermost handler, while mono expects it to be associated with all nesting clauses.
7670 * So add new clauses which use the IL info (catch class etc.) from the nesting clause,
7671 * and everything else from the nested clause.
7674 for (i = 0; i < ei_len; ++i) {
7675 gint32 cindex1 = *(gint32*)type_info [i];
7676 MonoExceptionClause *clause1 = &cfg->header->clauses [cindex1];
7678 for (j = 0; j < cfg->header->num_clauses; ++j) {
7680 MonoExceptionClause *clause2 = &cfg->header->clauses [cindex2];
7681 MonoJitExceptionInfo *nesting_ei, *nested_ei;
7683 if (cindex1 != cindex2 && clause1->try_offset >= clause2->try_offset && clause1->handler_offset <= clause2->handler_offset) {
7684 /* clause1 is the nested clause */
7685 nested_ei = &cfg->llvm_ex_info [i];
7686 nesting_ei = &cfg->llvm_ex_info [nindex];
7689 memcpy (nesting_ei, nested_ei, sizeof (MonoJitExceptionInfo));
7691 nesting_ei->flags = clause2->flags;
7692 nesting_ei->data.catch_class = clause2->data.catch_class;
7693 nesting_ei->clause_index = cindex2;
7697 g_assert (nindex == ei_len + nested_len);
7698 cfg->llvm_this_reg = this_reg;
7699 cfg->llvm_this_offset = this_offset;
7701 /* type_info [i] is cfg mempool allocated, no need to free it */
7707 #if LLVM_API_VERSION > 100
7709 * decode_llvm_eh_info:
7711 * Decode the EH table emitted by llvm in jit mode, and store
7712 * the result into cfg.
7715 decode_llvm_eh_info (EmitContext *ctx, gpointer eh_frame)
7717 MonoCompile *cfg = ctx->cfg;
7720 MonoLLVMFDEInfo info;
7721 MonoJitExceptionInfo *ei;
7722 guint8 *p = eh_frame;
7723 int version, fde_count, fde_offset;
7724 guint32 ei_len, i, nested_len;
7725 gpointer *type_info;
7729 * Decode the one element EH table emitted by the MonoException class
7733 /* Similar to decode_llvm_mono_eh_frame () in aot-runtime.c */
7736 g_assert (version == 3);
7739 p = (guint8 *)ALIGN_PTR_TO (p, 4);
7741 fde_count = *(guint32*)p;
7745 g_assert (fde_count <= 2);
7747 /* The first entry is the real method */
7748 g_assert (table [0] == 1);
7749 fde_offset = table [1];
7750 table += fde_count * 2;
7752 cfg->code_len = table [0];
7753 fde_len = table [1] - fde_offset;
7756 fde = (guint8*)eh_frame + fde_offset;
7757 cie = (guint8*)table;
7759 mono_unwind_decode_llvm_mono_fde (fde, fde_len, cie, cfg->native_code, &info);
7761 cfg->encoded_unwind_ops = info.unw_info;
7762 cfg->encoded_unwind_ops_len = info.unw_info_len;
7763 if (cfg->verbose_level > 1)
7764 mono_print_unwind_info (cfg->encoded_unwind_ops, cfg->encoded_unwind_ops_len);
7765 if (info.this_reg != -1) {
7766 cfg->llvm_this_reg = info.this_reg;
7767 cfg->llvm_this_offset = info.this_offset;
7771 ei_len = info.ex_info_len;
7772 type_info = info.type_info;
7774 // Nested clauses are currently disabled
7777 cfg->llvm_ex_info = (MonoJitExceptionInfo*)mono_mempool_alloc0 (cfg->mempool, (ei_len + nested_len) * sizeof (MonoJitExceptionInfo));
7778 cfg->llvm_ex_info_len = ei_len + nested_len;
7779 memcpy (cfg->llvm_ex_info, ei, ei_len * sizeof (MonoJitExceptionInfo));
7780 /* Fill the rest of the information from the type info */
7781 for (i = 0; i < ei_len; ++i) {
7782 gint32 clause_index = *(gint32*)type_info [i];
7783 MonoExceptionClause *clause = &cfg->header->clauses [clause_index];
7785 cfg->llvm_ex_info [i].flags = clause->flags;
7786 cfg->llvm_ex_info [i].data.catch_class = clause->data.catch_class;
7787 cfg->llvm_ex_info [i].clause_index = clause_index;
7793 dlsym_cb (const char *name, void **symbol)
7799 if (!strcmp (name, "__bzero")) {
7800 *symbol = (void*)bzero;
7802 current = mono_dl_open (NULL, 0, NULL);
7805 err = mono_dl_symbol (current, name, symbol);
7807 mono_dl_close (current);
7809 #ifdef MONO_ARCH_HAVE_CREATE_LLVM_NATIVE_THUNK
7810 *symbol = (char*)mono_arch_create_llvm_native_thunk (mono_domain_get (), (guint8*)(*symbol));
7816 AddFunc (LLVMModuleRef module, const char *name, LLVMTypeRef ret_type, LLVMTypeRef *param_types, int nparams)
7818 LLVMAddFunction (module, name, LLVMFunctionType (ret_type, param_types, nparams, FALSE));
7822 AddFunc2 (LLVMModuleRef module, const char *name, LLVMTypeRef ret_type, LLVMTypeRef param_type1, LLVMTypeRef param_type2)
7824 LLVMTypeRef param_types [4];
7826 param_types [0] = param_type1;
7827 param_types [1] = param_type2;
7829 AddFunc (module, name, ret_type, param_types, 2);
7835 INTRINS_SADD_OVF_I32,
7836 INTRINS_UADD_OVF_I32,
7837 INTRINS_SSUB_OVF_I32,
7838 INTRINS_USUB_OVF_I32,
7839 INTRINS_SMUL_OVF_I32,
7840 INTRINS_UMUL_OVF_I32,
7841 INTRINS_SADD_OVF_I64,
7842 INTRINS_UADD_OVF_I64,
7843 INTRINS_SSUB_OVF_I64,
7844 INTRINS_USUB_OVF_I64,
7845 INTRINS_SMUL_OVF_I64,
7846 INTRINS_UMUL_OVF_I64,
7853 #if defined(TARGET_AMD64) || defined(TARGET_X86)
7854 INTRINS_SSE_PMOVMSKB,
7855 INTRINS_SSE_PSRLI_W,
7856 INTRINS_SSE_PSRAI_W,
7857 INTRINS_SSE_PSLLI_W,
7858 INTRINS_SSE_PSRLI_D,
7859 INTRINS_SSE_PSRAI_D,
7860 INTRINS_SSE_PSLLI_D,
7861 INTRINS_SSE_PSRLI_Q,
7862 INTRINS_SSE_PSLLI_Q,
7863 INTRINS_SSE_SQRT_PD,
7864 INTRINS_SSE_SQRT_PS,
7865 INTRINS_SSE_RSQRT_PS,
7867 INTRINS_SSE_CVTTPD2DQ,
7868 INTRINS_SSE_CVTTPS2DQ,
7869 INTRINS_SSE_CVTDQ2PD,
7870 INTRINS_SSE_CVTDQ2PS,
7871 INTRINS_SSE_CVTPD2DQ,
7872 INTRINS_SSE_CVTPS2DQ,
7873 INTRINS_SSE_CVTPD2PS,
7874 INTRINS_SSE_CVTPS2PD,
7877 INTRINS_SSE_PACKSSWB,
7878 INTRINS_SSE_PACKUSWB,
7879 INTRINS_SSE_PACKSSDW,
7880 INTRINS_SSE_PACKUSDW,
7885 INTRINS_SSE_ADDSUBPS,
7890 INTRINS_SSE_ADDSUBPD,
7893 INTRINS_SSE_PADDUSW,
7894 INTRINS_SSE_PSUBUSW,
7900 INTRINS_SSE_PADDUSB,
7901 INTRINS_SSE_PSUBUSB,
7914 static IntrinsicDesc intrinsics[] = {
7915 {INTRINS_MEMSET, "llvm.memset.p0i8.i32"},
7916 {INTRINS_MEMCPY, "llvm.memcpy.p0i8.p0i8.i32"},
7917 {INTRINS_SADD_OVF_I32, "llvm.sadd.with.overflow.i32"},
7918 {INTRINS_UADD_OVF_I32, "llvm.uadd.with.overflow.i32"},
7919 {INTRINS_SSUB_OVF_I32, "llvm.ssub.with.overflow.i32"},
7920 {INTRINS_USUB_OVF_I32, "llvm.usub.with.overflow.i32"},
7921 {INTRINS_SMUL_OVF_I32, "llvm.smul.with.overflow.i32"},
7922 {INTRINS_UMUL_OVF_I32, "llvm.umul.with.overflow.i32"},
7923 {INTRINS_SADD_OVF_I64, "llvm.sadd.with.overflow.i64"},
7924 {INTRINS_UADD_OVF_I64, "llvm.uadd.with.overflow.i64"},
7925 {INTRINS_SSUB_OVF_I64, "llvm.ssub.with.overflow.i64"},
7926 {INTRINS_USUB_OVF_I64, "llvm.usub.with.overflow.i64"},
7927 {INTRINS_SMUL_OVF_I64, "llvm.smul.with.overflow.i64"},
7928 {INTRINS_UMUL_OVF_I64, "llvm.umul.with.overflow.i64"},
7929 {INTRINS_SIN, "llvm.sin.f64"},
7930 {INTRINS_COS, "llvm.cos.f64"},
7931 {INTRINS_SQRT, "llvm.sqrt.f64"},
7932 /* This isn't an intrinsic, instead llvm seems to special case it by name */
7933 {INTRINS_FABS, "fabs"},
7934 {INTRINS_EXPECT_I8, "llvm.expect.i8"},
7935 {INTRINS_EXPECT_I1, "llvm.expect.i1"},
7936 #if defined(TARGET_AMD64) || defined(TARGET_X86)
7937 {INTRINS_SSE_PMOVMSKB, "llvm.x86.sse2.pmovmskb.128"},
7938 {INTRINS_SSE_PSRLI_W, "llvm.x86.sse2.psrli.w"},
7939 {INTRINS_SSE_PSRAI_W, "llvm.x86.sse2.psrai.w"},
7940 {INTRINS_SSE_PSLLI_W, "llvm.x86.sse2.pslli.w"},
7941 {INTRINS_SSE_PSRLI_D, "llvm.x86.sse2.psrli.d"},
7942 {INTRINS_SSE_PSRAI_D, "llvm.x86.sse2.psrai.d"},
7943 {INTRINS_SSE_PSLLI_D, "llvm.x86.sse2.pslli.d"},
7944 {INTRINS_SSE_PSRLI_Q, "llvm.x86.sse2.psrli.q"},
7945 {INTRINS_SSE_PSLLI_Q, "llvm.x86.sse2.pslli.q"},
7946 {INTRINS_SSE_SQRT_PD, "llvm.x86.sse2.sqrt.pd"},
7947 {INTRINS_SSE_SQRT_PS, "llvm.x86.sse.sqrt.ps"},
7948 {INTRINS_SSE_RSQRT_PS, "llvm.x86.sse.rsqrt.ps"},
7949 {INTRINS_SSE_RCP_PS, "llvm.x86.sse.rcp.ps"},
7950 {INTRINS_SSE_CVTTPD2DQ, "llvm.x86.sse2.cvttpd2dq"},
7951 {INTRINS_SSE_CVTTPS2DQ, "llvm.x86.sse2.cvttps2dq"},
7952 {INTRINS_SSE_CVTDQ2PD, "llvm.x86.sse2.cvtdq2pd"},
7953 {INTRINS_SSE_CVTDQ2PS, "llvm.x86.sse2.cvtdq2ps"},
7954 {INTRINS_SSE_CVTPD2DQ, "llvm.x86.sse2.cvtpd2dq"},
7955 {INTRINS_SSE_CVTPS2DQ, "llvm.x86.sse2.cvtps2dq"},
7956 {INTRINS_SSE_CVTPD2PS, "llvm.x86.sse2.cvtpd2ps"},
7957 {INTRINS_SSE_CVTPS2PD, "llvm.x86.sse2.cvtps2pd"},
7958 {INTRINS_SSE_CMPPD, "llvm.x86.sse2.cmp.pd"},
7959 {INTRINS_SSE_CMPPS, "llvm.x86.sse.cmp.ps"},
7960 {INTRINS_SSE_PACKSSWB, "llvm.x86.sse2.packsswb.128"},
7961 {INTRINS_SSE_PACKUSWB, "llvm.x86.sse2.packuswb.128"},
7962 {INTRINS_SSE_PACKSSDW, "llvm.x86.sse2.packssdw.128"},
7963 {INTRINS_SSE_PACKUSDW, "llvm.x86.sse41.packusdw"},
7964 {INTRINS_SSE_MINPS, "llvm.x86.sse.min.ps"},
7965 {INTRINS_SSE_MAXPS, "llvm.x86.sse.max.ps"},
7966 {INTRINS_SSE_HADDPS, "llvm.x86.sse3.hadd.ps"},
7967 {INTRINS_SSE_HSUBPS, "llvm.x86.sse3.hsub.ps"},
7968 {INTRINS_SSE_ADDSUBPS, "llvm.x86.sse3.addsub.ps"},
7969 {INTRINS_SSE_MINPD, "llvm.x86.sse2.min.pd"},
7970 {INTRINS_SSE_MAXPD, "llvm.x86.sse2.max.pd"},
7971 {INTRINS_SSE_HADDPD, "llvm.x86.sse3.hadd.pd"},
7972 {INTRINS_SSE_HSUBPD, "llvm.x86.sse3.hsub.pd"},
7973 {INTRINS_SSE_ADDSUBPD, "llvm.x86.sse3.addsub.pd"},
7974 {INTRINS_SSE_PADDSW, "llvm.x86.sse2.padds.w"},
7975 {INTRINS_SSE_PSUBSW, "llvm.x86.sse2.psubs.w"},
7976 {INTRINS_SSE_PADDUSW, "llvm.x86.sse2.paddus.w"},
7977 {INTRINS_SSE_PSUBUSW, "llvm.x86.sse2.psubus.w"},
7978 {INTRINS_SSE_PAVGW, "llvm.x86.sse2.pavg.w"},
7979 {INTRINS_SSE_PMULHW, "llvm.x86.sse2.pmulh.w"},
7980 {INTRINS_SSE_PMULHU, "llvm.x86.sse2.pmulhu.w"},
7981 {INTRINS_SE_PADDSB, "llvm.x86.sse2.padds.b"},
7982 {INTRINS_SSE_PSUBSB, "llvm.x86.sse2.psubs.b"},
7983 {INTRINS_SSE_PADDUSB, "llvm.x86.sse2.paddus.b"},
7984 {INTRINS_SSE_PSUBUSB, "llvm.x86.sse2.psubus.b"},
7985 {INTRINS_SSE_PAVGB, "llvm.x86.sse2.pavg.b"},
7986 {INTRINS_SSE_PAUSE, "llvm.x86.sse2.pause"},
7987 {INTRINS_SSE_DPPS, "llvm.x86.sse41.dpps"}
7992 add_sse_binary (LLVMModuleRef module, const char *name, int type)
7994 LLVMTypeRef ret_type = type_to_simd_type (type);
7995 AddFunc2 (module, name, ret_type, ret_type, ret_type);
7999 add_intrinsic (LLVMModuleRef module, int id)
8002 #if defined(TARGET_AMD64) || defined(TARGET_X86)
8003 LLVMTypeRef ret_type, arg_types [16];
8006 name = g_hash_table_lookup (intrins_id_to_name, GINT_TO_POINTER (id));
8010 case INTRINS_MEMSET: {
8011 LLVMTypeRef params [] = { LLVMPointerType (LLVMInt8Type (), 0), LLVMInt8Type (), LLVMInt32Type (), LLVMInt32Type (), LLVMInt1Type () };
8013 AddFunc (module, name, LLVMVoidType (), params, 5);
8016 case INTRINS_MEMCPY: {
8017 LLVMTypeRef params [] = { LLVMPointerType (LLVMInt8Type (), 0), LLVMPointerType (LLVMInt8Type (), 0), LLVMInt32Type (), LLVMInt32Type (), LLVMInt1Type () };
8019 AddFunc (module, name, LLVMVoidType (), params, 5);
8022 case INTRINS_SADD_OVF_I32:
8023 case INTRINS_UADD_OVF_I32:
8024 case INTRINS_SSUB_OVF_I32:
8025 case INTRINS_USUB_OVF_I32:
8026 case INTRINS_SMUL_OVF_I32:
8027 case INTRINS_UMUL_OVF_I32: {
8028 LLVMTypeRef ovf_res_i32 [] = { LLVMInt32Type (), LLVMInt1Type () };
8029 LLVMTypeRef params [] = { LLVMInt32Type (), LLVMInt32Type () };
8030 LLVMTypeRef ret_type = LLVMStructType (ovf_res_i32, 2, FALSE);
8032 AddFunc (module, name, ret_type, params, 2);
8035 case INTRINS_SADD_OVF_I64:
8036 case INTRINS_UADD_OVF_I64:
8037 case INTRINS_SSUB_OVF_I64:
8038 case INTRINS_USUB_OVF_I64:
8039 case INTRINS_SMUL_OVF_I64:
8040 case INTRINS_UMUL_OVF_I64: {
8041 LLVMTypeRef ovf_res_i64 [] = { LLVMInt64Type (), LLVMInt1Type () };
8042 LLVMTypeRef params [] = { LLVMInt64Type (), LLVMInt64Type () };
8043 LLVMTypeRef ret_type = LLVMStructType (ovf_res_i64, 2, FALSE);
8045 AddFunc (module, name, ret_type, params, 2);
8051 case INTRINS_FABS: {
8052 LLVMTypeRef params [] = { LLVMDoubleType () };
8054 AddFunc (module, name, LLVMDoubleType (), params, 1);
8057 case INTRINS_EXPECT_I8:
8058 AddFunc2 (module, name, LLVMInt8Type (), LLVMInt8Type (), LLVMInt8Type ());
8060 case INTRINS_EXPECT_I1:
8061 AddFunc2 (module, name, LLVMInt1Type (), LLVMInt1Type (), LLVMInt1Type ());
8063 #if defined(TARGET_AMD64) || defined(TARGET_X86)
8064 case INTRINS_SSE_PMOVMSKB:
8066 ret_type = LLVMInt32Type ();
8067 arg_types [0] = type_to_simd_type (MONO_TYPE_I1);
8068 AddFunc (module, name, ret_type, arg_types, 1);
8070 case INTRINS_SSE_PSRLI_W:
8071 case INTRINS_SSE_PSRAI_W:
8072 case INTRINS_SSE_PSLLI_W:
8074 ret_type = type_to_simd_type (MONO_TYPE_I2);
8075 arg_types [0] = ret_type;
8076 arg_types [1] = LLVMInt32Type ();
8077 AddFunc (module, name, ret_type, arg_types, 2);
8079 case INTRINS_SSE_PSRLI_D:
8080 case INTRINS_SSE_PSRAI_D:
8081 case INTRINS_SSE_PSLLI_D:
8082 ret_type = type_to_simd_type (MONO_TYPE_I4);
8083 arg_types [0] = ret_type;
8084 arg_types [1] = LLVMInt32Type ();
8085 AddFunc (module, name, ret_type, arg_types, 2);
8087 case INTRINS_SSE_PSRLI_Q:
8088 case INTRINS_SSE_PSLLI_Q:
8089 ret_type = type_to_simd_type (MONO_TYPE_I8);
8090 arg_types [0] = ret_type;
8091 arg_types [1] = LLVMInt32Type ();
8092 AddFunc (module, name, ret_type, arg_types, 2);
8094 case INTRINS_SSE_SQRT_PD:
8096 ret_type = type_to_simd_type (MONO_TYPE_R8);
8097 arg_types [0] = ret_type;
8098 AddFunc (module, name, ret_type, arg_types, 1);
8100 case INTRINS_SSE_SQRT_PS:
8101 ret_type = type_to_simd_type (MONO_TYPE_R4);
8102 arg_types [0] = ret_type;
8103 AddFunc (module, name, ret_type, arg_types, 1);
8105 case INTRINS_SSE_RSQRT_PS:
8106 ret_type = type_to_simd_type (MONO_TYPE_R4);
8107 arg_types [0] = ret_type;
8108 AddFunc (module, name, ret_type, arg_types, 1);
8110 case INTRINS_SSE_RCP_PS:
8111 ret_type = type_to_simd_type (MONO_TYPE_R4);
8112 arg_types [0] = ret_type;
8113 AddFunc (module, name, ret_type, arg_types, 1);
8115 case INTRINS_SSE_CVTTPD2DQ:
8116 ret_type = type_to_simd_type (MONO_TYPE_I4);
8117 arg_types [0] = type_to_simd_type (MONO_TYPE_R8);
8118 AddFunc (module, name, ret_type, arg_types, 1);
8120 case INTRINS_SSE_CVTTPS2DQ:
8121 ret_type = type_to_simd_type (MONO_TYPE_I4);
8122 arg_types [0] = type_to_simd_type (MONO_TYPE_R4);
8123 AddFunc (module, name, ret_type, arg_types, 1);
8125 case INTRINS_SSE_CVTDQ2PD:
8126 /* Conversion ops */
8127 ret_type = type_to_simd_type (MONO_TYPE_R8);
8128 arg_types [0] = type_to_simd_type (MONO_TYPE_I4);
8129 AddFunc (module, name, ret_type, arg_types, 1);
8131 case INTRINS_SSE_CVTDQ2PS:
8132 ret_type = type_to_simd_type (MONO_TYPE_R4);
8133 arg_types [0] = type_to_simd_type (MONO_TYPE_I4);
8134 AddFunc (module, name, ret_type, arg_types, 1);
8136 case INTRINS_SSE_CVTPD2DQ:
8137 ret_type = type_to_simd_type (MONO_TYPE_I4);
8138 arg_types [0] = type_to_simd_type (MONO_TYPE_R8);
8139 AddFunc (module, name, ret_type, arg_types, 1);
8141 case INTRINS_SSE_CVTPS2DQ:
8142 ret_type = type_to_simd_type (MONO_TYPE_I4);
8143 arg_types [0] = type_to_simd_type (MONO_TYPE_R4);
8144 AddFunc (module, name, ret_type, arg_types, 1);
8146 case INTRINS_SSE_CVTPD2PS:
8147 ret_type = type_to_simd_type (MONO_TYPE_R4);
8148 arg_types [0] = type_to_simd_type (MONO_TYPE_R8);
8149 AddFunc (module, name, ret_type, arg_types, 1);
8151 case INTRINS_SSE_CVTPS2PD:
8152 ret_type = type_to_simd_type (MONO_TYPE_R8);
8153 arg_types [0] = type_to_simd_type (MONO_TYPE_R4);
8154 AddFunc (module, name, ret_type, arg_types, 1);
8156 case INTRINS_SSE_CMPPD:
8158 ret_type = type_to_simd_type (MONO_TYPE_R8);
8159 arg_types [0] = ret_type;
8160 arg_types [1] = ret_type;
8161 arg_types [2] = LLVMInt8Type ();
8162 AddFunc (module, name, ret_type, arg_types, 3);
8164 case INTRINS_SSE_CMPPS:
8165 ret_type = type_to_simd_type (MONO_TYPE_R4);
8166 arg_types [0] = ret_type;
8167 arg_types [1] = ret_type;
8168 arg_types [2] = LLVMInt8Type ();
8169 AddFunc (module, name, ret_type, arg_types, 3);
8171 case INTRINS_SSE_PACKSSWB:
8172 case INTRINS_SSE_PACKUSWB:
8173 case INTRINS_SSE_PACKSSDW:
8175 ret_type = type_to_simd_type (MONO_TYPE_I1);
8176 arg_types [0] = type_to_simd_type (MONO_TYPE_I2);
8177 arg_types [1] = type_to_simd_type (MONO_TYPE_I2);
8178 AddFunc (module, name, ret_type, arg_types, 2);
8180 case INTRINS_SSE_PACKUSDW:
8181 ret_type = type_to_simd_type (MONO_TYPE_I2);
8182 arg_types [0] = type_to_simd_type (MONO_TYPE_I4);
8183 arg_types [1] = type_to_simd_type (MONO_TYPE_I4);
8184 AddFunc (module, name, ret_type, arg_types, 2);
8186 /* SSE Binary ops */
8187 case INTRINS_SSE_PADDSW:
8188 case INTRINS_SSE_PSUBSW:
8189 case INTRINS_SSE_PADDUSW:
8190 case INTRINS_SSE_PSUBUSW:
8191 case INTRINS_SSE_PAVGW:
8192 case INTRINS_SSE_PMULHW:
8193 case INTRINS_SSE_PMULHU:
8194 add_sse_binary (module, name, MONO_TYPE_I2);
8196 case INTRINS_SSE_MINPS:
8197 case INTRINS_SSE_MAXPS:
8198 case INTRINS_SSE_HADDPS:
8199 case INTRINS_SSE_HSUBPS:
8200 case INTRINS_SSE_ADDSUBPS:
8201 add_sse_binary (module, name, MONO_TYPE_R4);
8203 case INTRINS_SSE_MINPD:
8204 case INTRINS_SSE_MAXPD:
8205 case INTRINS_SSE_HADDPD:
8206 case INTRINS_SSE_HSUBPD:
8207 case INTRINS_SSE_ADDSUBPD:
8208 add_sse_binary (module, name, MONO_TYPE_R8);
8210 case INTRINS_SE_PADDSB:
8211 case INTRINS_SSE_PSUBSB:
8212 case INTRINS_SSE_PADDUSB:
8213 case INTRINS_SSE_PSUBUSB:
8214 case INTRINS_SSE_PAVGB:
8215 add_sse_binary (module, name, MONO_TYPE_I1);
8217 case INTRINS_SSE_PAUSE:
8218 AddFunc (module, "llvm.x86.sse2.pause", LLVMVoidType (), NULL, 0);
8220 case INTRINS_SSE_DPPS:
8221 ret_type = type_to_simd_type (MONO_TYPE_R4);
8222 arg_types [0] = type_to_simd_type (MONO_TYPE_R4);
8223 arg_types [1] = type_to_simd_type (MONO_TYPE_R4);
8224 arg_types [2] = LLVMInt32Type ();
8225 AddFunc (module, name, ret_type, arg_types, 3);
8229 g_assert_not_reached ();
8235 get_intrinsic (EmitContext *ctx, const char *name)
8237 #if LLVM_API_VERSION > 100
8241 * Every method is emitted into its own module so
8242 * we can add intrinsics on demand.
8244 res = LLVMGetNamedFunction (ctx->lmodule, name);
8248 /* No locking needed */
8249 id = GPOINTER_TO_INT (g_hash_table_lookup (intrins_name_to_id, name));
8252 printf ("%s\n", name);
8253 g_assert (id != -1);
8254 add_intrinsic (ctx->lmodule, id);
8255 res = LLVMGetNamedFunction (ctx->lmodule, name);
8263 res = LLVMGetNamedFunction (ctx->lmodule, name);
8270 add_intrinsics (LLVMModuleRef module)
8274 /* Emit declarations of instrinsics */
8276 * It would be nicer to emit only the intrinsics actually used, but LLVM's Module
8277 * type doesn't seem to do any locking.
8279 for (i = 0; i < INTRINS_NUM; ++i)
8280 add_intrinsic (module, i);
8284 AddFunc (module, "mono_personality", LLVMVoidType (), NULL, 0);
8286 AddFunc (module, "llvm_resume_unwind_trampoline", LLVMVoidType (), NULL, 0);
8289 /* Load/Store intrinsics */
8291 LLVMTypeRef arg_types [5];
8295 for (i = 1; i <= 8; i *= 2) {
8296 arg_types [0] = LLVMPointerType (LLVMIntType (i * 8), 0);
8297 arg_types [1] = LLVMInt32Type ();
8298 arg_types [2] = LLVMInt1Type ();
8299 arg_types [3] = LLVMInt32Type ();
8300 sprintf (name, "llvm.mono.load.i%d.p0i%d", i * 8, i * 8);
8301 AddFunc (module, name, LLVMIntType (i * 8), arg_types, 4);
8303 arg_types [0] = LLVMIntType (i * 8);
8304 arg_types [1] = LLVMPointerType (LLVMIntType (i * 8), 0);
8305 arg_types [2] = LLVMInt32Type ();
8306 arg_types [3] = LLVMInt1Type ();
8307 arg_types [4] = LLVMInt32Type ();
8308 sprintf (name, "llvm.mono.store.i%d.p0i%d", i * 8, i * 8);
8309 AddFunc (module, name, LLVMVoidType (), arg_types, 5);
8315 add_types (MonoLLVMModule *module)
8317 module->ptr_type = LLVMPointerType (sizeof (gpointer) == 8 ? LLVMInt64Type () : LLVMInt32Type (), 0);
8321 mono_llvm_init (void)
8326 mono_native_tls_alloc (¤t_cfg_tls_id, NULL);
8328 h = g_hash_table_new (NULL, NULL);
8329 for (i = 0; i < INTRINS_NUM; ++i)
8330 g_hash_table_insert (h, GINT_TO_POINTER (intrinsics [i].id), (gpointer)intrinsics [i].name);
8331 intrins_id_to_name = h;
8333 h = g_hash_table_new (g_str_hash, g_str_equal);
8334 for (i = 0; i < INTRINS_NUM; ++i)
8335 g_hash_table_insert (h, (gpointer)intrinsics [i].name, GINT_TO_POINTER (intrinsics [i].id + 1));
8336 intrins_name_to_id = h;
8340 init_jit_module (MonoDomain *domain)
8342 MonoJitDomainInfo *dinfo;
8343 MonoLLVMModule *module;
8346 dinfo = domain_jit_info (domain);
8347 if (dinfo->llvm_module)
8350 mono_loader_lock ();
8352 if (dinfo->llvm_module) {
8353 mono_loader_unlock ();
8357 module = g_new0 (MonoLLVMModule, 1);
8359 name = g_strdup_printf ("mono-%s", domain->friendly_name);
8360 module->lmodule = LLVMModuleCreateWithName (name);
8361 module->context = LLVMGetGlobalContext ();
8363 module->mono_ee = (MonoEERef*)mono_llvm_create_ee (LLVMCreateModuleProviderForExistingModule (module->lmodule), alloc_cb, emitted_cb, exception_cb, dlsym_cb, &module->ee);
8365 add_intrinsics (module->lmodule);
8368 module->llvm_types = g_hash_table_new (NULL, NULL);
8370 #if LLVM_API_VERSION < 100
8371 MonoJitICallInfo *info;
8373 info = mono_find_jit_icall_by_name ("llvm_resume_unwind_trampoline");
8375 LLVMAddGlobalMapping (module->ee, LLVMGetNamedFunction (module->lmodule, "llvm_resume_unwind_trampoline"), (void*)info->func);
8378 mono_memory_barrier ();
8380 dinfo->llvm_module = module;
8382 mono_loader_unlock ();
8386 mono_llvm_cleanup (void)
8388 MonoLLVMModule *module = &aot_module;
8390 if (module->lmodule)
8391 LLVMDisposeModule (module->lmodule);
8393 if (module->context)
8394 LLVMContextDispose (module->context);
8398 mono_llvm_free_domain_info (MonoDomain *domain)
8400 MonoJitDomainInfo *info = domain_jit_info (domain);
8401 MonoLLVMModule *module = (MonoLLVMModule*)info->llvm_module;
8407 if (module->llvm_types)
8408 g_hash_table_destroy (module->llvm_types);
8410 mono_llvm_dispose_ee (module->mono_ee);
8412 if (module->bb_names) {
8413 for (i = 0; i < module->bb_names_len; ++i)
8414 g_free (module->bb_names [i]);
8415 g_free (module->bb_names);
8417 //LLVMDisposeModule (module->module);
8421 info->llvm_module = NULL;
8425 mono_llvm_create_aot_module (MonoAssembly *assembly, const char *global_prefix, gboolean emit_dwarf, gboolean static_link, gboolean llvm_only)
8427 MonoLLVMModule *module = &aot_module;
8429 /* Delete previous module */
8430 if (module->plt_entries)
8431 g_hash_table_destroy (module->plt_entries);
8432 if (module->lmodule)
8433 LLVMDisposeModule (module->lmodule);
8435 memset (module, 0, sizeof (aot_module));
8437 module->lmodule = LLVMModuleCreateWithName ("aot");
8438 module->assembly = assembly;
8439 module->global_prefix = g_strdup (global_prefix);
8440 module->got_symbol = g_strdup_printf ("%s_llvm_got", global_prefix);
8441 module->eh_frame_symbol = g_strdup_printf ("%s_eh_frame", global_prefix);
8442 module->get_method_symbol = g_strdup_printf ("%s_get_method", global_prefix);
8443 module->get_unbox_tramp_symbol = g_strdup_printf ("%s_get_unbox_tramp", global_prefix);
8444 module->external_symbols = TRUE;
8445 module->emit_dwarf = emit_dwarf;
8446 module->static_link = static_link;
8447 module->llvm_only = llvm_only;
8448 /* The first few entries are reserved */
8449 module->max_got_offset = 16;
8450 module->context = LLVMGetGlobalContext ();
8453 /* clang ignores our debug info because it has an invalid version */
8454 module->emit_dwarf = FALSE;
8456 add_intrinsics (module->lmodule);
8459 #if LLVM_API_VERSION > 100
8460 if (module->emit_dwarf) {
8461 char *dir, *build_info, *s, *cu_name;
8463 module->di_builder = mono_llvm_create_di_builder (module->lmodule);
8466 dir = g_strdup (".");
8467 build_info = mono_get_runtime_build_info ();
8468 s = g_strdup_printf ("Mono AOT Compiler %s (LLVM)", build_info);
8469 cu_name = g_path_get_basename (assembly->image->name);
8470 module->cu = mono_llvm_di_create_compile_unit (module->di_builder, cu_name, dir, s);
8472 g_free (build_info);
8479 * We couldn't compute the type of the LLVM global representing the got because
8480 * its size is only known after all the methods have been emitted. So create
8481 * a dummy variable, and replace all uses it with the real got variable when
8482 * its size is known in mono_llvm_emit_aot_module ().
8485 LLVMTypeRef got_type = LLVMArrayType (module->ptr_type, 0);
8487 module->got_var = LLVMAddGlobal (module->lmodule, got_type, "mono_dummy_got");
8488 LLVMSetInitializer (module->got_var, LLVMConstNull (got_type));
8491 /* Add initialization array */
8493 LLVMTypeRef inited_type = LLVMArrayType (LLVMInt8Type (), 0);
8495 module->inited_var = LLVMAddGlobal (aot_module.lmodule, inited_type, "mono_inited_tmp");
8496 LLVMSetInitializer (module->inited_var, LLVMConstNull (inited_type));
8500 emit_init_icall_wrappers (module);
8502 emit_llvm_code_start (module);
8504 /* Add a dummy personality function */
8505 if (!use_debug_personality) {
8506 LLVMValueRef personality = LLVMAddFunction (module->lmodule, default_personality_name, LLVMFunctionType (LLVMInt32Type (), NULL, 0, TRUE));
8507 LLVMSetLinkage (personality, LLVMExternalLinkage);
8508 mark_as_used (module, personality);
8511 /* Add a reference to the c++ exception we throw/catch */
8513 LLVMTypeRef exc = LLVMPointerType (LLVMInt8Type (), 0);
8514 module->sentinel_exception = LLVMAddGlobal (module->lmodule, exc, "_ZTIPi");
8515 LLVMSetLinkage (module->sentinel_exception, LLVMExternalLinkage);
8516 mono_llvm_set_is_constant (module->sentinel_exception);
8519 module->llvm_types = g_hash_table_new (NULL, NULL);
8520 module->plt_entries = g_hash_table_new (g_str_hash, g_str_equal);
8521 module->plt_entries_ji = g_hash_table_new (NULL, NULL);
8522 module->direct_callables = g_hash_table_new (g_str_hash, g_str_equal);
8523 module->method_to_lmethod = g_hash_table_new (NULL, NULL);
8524 module->idx_to_lmethod = g_hash_table_new (NULL, NULL);
8525 module->idx_to_unbox_tramp = g_hash_table_new (NULL, NULL);
8526 module->method_to_callers = g_hash_table_new (NULL, NULL);
8530 llvm_array_from_uints (LLVMTypeRef el_type, guint32 *values, int nvalues)
8533 LLVMValueRef res, *vals;
8535 vals = g_new0 (LLVMValueRef, nvalues);
8536 for (i = 0; i < nvalues; ++i)
8537 vals [i] = LLVMConstInt (LLVMInt32Type (), values [i], FALSE);
8538 res = LLVMConstArray (LLVMInt32Type (), vals, nvalues);
8544 llvm_array_from_bytes (guint8 *values, int nvalues)
8547 LLVMValueRef res, *vals;
8549 vals = g_new0 (LLVMValueRef, nvalues);
8550 for (i = 0; i < nvalues; ++i)
8551 vals [i] = LLVMConstInt (LLVMInt8Type (), values [i], FALSE);
8552 res = LLVMConstArray (LLVMInt8Type (), vals, nvalues);
8557 * mono_llvm_emit_aot_file_info:
8559 * Emit the MonoAotFileInfo structure.
8560 * Same as emit_aot_file_info () in aot-compiler.c.
8563 mono_llvm_emit_aot_file_info (MonoAotFileInfo *info, gboolean has_jitted_code)
8565 MonoLLVMModule *module = &aot_module;
8567 /* Save these for later */
8568 memcpy (&module->aot_info, info, sizeof (MonoAotFileInfo));
8569 module->has_jitted_code = has_jitted_code;
8573 * mono_llvm_emit_aot_data:
8575 * Emit the binary data DATA pointed to by symbol SYMBOL.
8578 mono_llvm_emit_aot_data (const char *symbol, guint8 *data, int data_len)
8580 MonoLLVMModule *module = &aot_module;
8584 type = LLVMArrayType (LLVMInt8Type (), data_len);
8585 d = LLVMAddGlobal (module->lmodule, type, symbol);
8586 LLVMSetVisibility (d, LLVMHiddenVisibility);
8587 LLVMSetLinkage (d, LLVMInternalLinkage);
8588 LLVMSetInitializer (d, mono_llvm_create_constant_data_array (data, data_len));
8589 mono_llvm_set_is_constant (d);
8592 /* Add a reference to a global defined in JITted code */
8594 AddJitGlobal (MonoLLVMModule *module, LLVMTypeRef type, const char *name)
8599 s = g_strdup_printf ("%s%s", module->global_prefix, name);
8600 v = LLVMAddGlobal (module->lmodule, LLVMInt8Type (), s);
8606 emit_aot_file_info (MonoLLVMModule *module)
8608 LLVMTypeRef file_info_type;
8609 LLVMTypeRef *eltypes, eltype;
8610 LLVMValueRef info_var;
8611 LLVMValueRef *fields;
8612 int i, nfields, tindex;
8613 MonoAotFileInfo *info;
8614 LLVMModuleRef lmodule = module->lmodule;
8616 info = &module->aot_info;
8618 /* Create an LLVM type to represent MonoAotFileInfo */
8619 nfields = 2 + MONO_AOT_FILE_INFO_NUM_SYMBOLS + 16 + 5;
8620 eltypes = g_new (LLVMTypeRef, nfields);
8622 eltypes [tindex ++] = LLVMInt32Type ();
8623 eltypes [tindex ++] = LLVMInt32Type ();
8625 for (i = 0; i < MONO_AOT_FILE_INFO_NUM_SYMBOLS; ++i)
8626 eltypes [tindex ++] = LLVMPointerType (LLVMInt8Type (), 0);
8628 for (i = 0; i < 15; ++i)
8629 eltypes [tindex ++] = LLVMInt32Type ();
8631 eltypes [tindex ++] = LLVMArrayType (LLVMInt32Type (), MONO_AOT_TABLE_NUM);
8632 for (i = 0; i < 4; ++i)
8633 eltypes [tindex ++] = LLVMArrayType (LLVMInt32Type (), MONO_AOT_TRAMP_NUM);
8634 eltypes [tindex ++] = LLVMArrayType (LLVMInt8Type (), 16);
8635 g_assert (tindex == nfields);
8636 file_info_type = LLVMStructCreateNamed (module->context, "MonoAotFileInfo");
8637 LLVMStructSetBody (file_info_type, eltypes, nfields, FALSE);
8639 info_var = LLVMAddGlobal (lmodule, file_info_type, "mono_aot_file_info");
8640 if (module->static_link) {
8641 LLVMSetVisibility (info_var, LLVMHiddenVisibility);
8642 LLVMSetLinkage (info_var, LLVMInternalLinkage);
8644 fields = g_new (LLVMValueRef, nfields);
8646 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->version, FALSE);
8647 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->dummy, FALSE);
8651 * We use LLVMGetNamedGlobal () for symbol which are defined in LLVM code, and LLVMAddGlobal ()
8652 * for symbols defined in the .s file emitted by the aot compiler.
8654 eltype = eltypes [tindex];
8655 if (module->llvm_only)
8656 fields [tindex ++] = LLVMConstNull (eltype);
8658 fields [tindex ++] = AddJitGlobal (module, eltype, "jit_got");
8659 fields [tindex ++] = module->got_var;
8660 /* llc defines this directly */
8661 if (!module->llvm_only) {
8662 fields [tindex ++] = LLVMAddGlobal (lmodule, eltype, module->eh_frame_symbol);
8663 fields [tindex ++] = LLVMConstNull (eltype);
8664 fields [tindex ++] = LLVMConstNull (eltype);
8666 fields [tindex ++] = LLVMConstNull (eltype);
8667 fields [tindex ++] = module->get_method;
8668 fields [tindex ++] = module->get_unbox_tramp;
8670 if (module->has_jitted_code) {
8671 fields [tindex ++] = AddJitGlobal (module, eltype, "jit_code_start");
8672 fields [tindex ++] = AddJitGlobal (module, eltype, "jit_code_end");
8674 fields [tindex ++] = LLVMConstNull (eltype);
8675 fields [tindex ++] = LLVMConstNull (eltype);
8677 if (!module->llvm_only)
8678 fields [tindex ++] = AddJitGlobal (module, eltype, "method_addresses");
8680 fields [tindex ++] = LLVMConstNull (eltype);
8681 if (info->flags & MONO_AOT_FILE_FLAG_SEPARATE_DATA) {
8682 for (i = 0; i < MONO_AOT_TABLE_NUM; ++i)
8683 fields [tindex ++] = LLVMConstNull (eltype);
8685 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "blob");
8686 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "class_name_table");
8687 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "class_info_offsets");
8688 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "method_info_offsets");
8689 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "ex_info_offsets");
8690 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "extra_method_info_offsets");
8691 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "extra_method_table");
8692 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "got_info_offsets");
8693 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "llvm_got_info_offsets");
8694 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "image_table");
8696 /* Not needed (mem_end) */
8697 fields [tindex ++] = LLVMConstNull (eltype);
8698 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "assembly_guid");
8699 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "runtime_version");
8700 if (info->trampoline_size [0]) {
8701 fields [tindex ++] = AddJitGlobal (module, eltype, "specific_trampolines");
8702 fields [tindex ++] = AddJitGlobal (module, eltype, "static_rgctx_trampolines");
8703 fields [tindex ++] = AddJitGlobal (module, eltype, "imt_trampolines");
8704 fields [tindex ++] = AddJitGlobal (module, eltype, "gsharedvt_arg_trampolines");
8706 fields [tindex ++] = LLVMConstNull (eltype);
8707 fields [tindex ++] = LLVMConstNull (eltype);
8708 fields [tindex ++] = LLVMConstNull (eltype);
8709 fields [tindex ++] = LLVMConstNull (eltype);
8711 if (module->static_link && !module->llvm_only)
8712 fields [tindex ++] = AddJitGlobal (module, eltype, "globals");
8714 fields [tindex ++] = LLVMConstNull (eltype);
8715 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "assembly_name");
8716 if (!module->llvm_only) {
8717 fields [tindex ++] = AddJitGlobal (module, eltype, "plt");
8718 fields [tindex ++] = AddJitGlobal (module, eltype, "plt_end");
8719 fields [tindex ++] = AddJitGlobal (module, eltype, "unwind_info");
8720 fields [tindex ++] = AddJitGlobal (module, eltype, "unbox_trampolines");
8721 fields [tindex ++] = AddJitGlobal (module, eltype, "unbox_trampolines_end");
8722 fields [tindex ++] = AddJitGlobal (module, eltype, "unbox_trampoline_addresses");
8724 fields [tindex ++] = LLVMConstNull (eltype);
8725 fields [tindex ++] = LLVMConstNull (eltype);
8726 fields [tindex ++] = LLVMConstNull (eltype);
8727 fields [tindex ++] = LLVMConstNull (eltype);
8728 fields [tindex ++] = LLVMConstNull (eltype);
8729 fields [tindex ++] = LLVMConstNull (eltype);
8732 for (i = 0; i < MONO_AOT_FILE_INFO_NUM_SYMBOLS; ++i)
8733 fields [2 + i] = LLVMConstBitCast (fields [2 + i], eltype);
8736 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->plt_got_offset_base, FALSE);
8737 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->got_size, FALSE);
8738 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->plt_size, FALSE);
8739 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->nmethods, FALSE);
8740 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->flags, FALSE);
8741 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->opts, FALSE);
8742 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->simd_opts, FALSE);
8743 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->gc_name_index, FALSE);
8744 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->num_rgctx_fetch_trampolines, FALSE);
8745 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->double_align, FALSE);
8746 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->long_align, FALSE);
8747 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->generic_tramp_num, FALSE);
8748 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->tramp_page_size, FALSE);
8749 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->nshared_got_entries, FALSE);
8750 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->datafile_size, FALSE);
8752 fields [tindex ++] = llvm_array_from_uints (LLVMInt32Type (), info->table_offsets, MONO_AOT_TABLE_NUM);
8753 fields [tindex ++] = llvm_array_from_uints (LLVMInt32Type (), info->num_trampolines, MONO_AOT_TRAMP_NUM);
8754 fields [tindex ++] = llvm_array_from_uints (LLVMInt32Type (), info->trampoline_got_offset_base, MONO_AOT_TRAMP_NUM);
8755 fields [tindex ++] = llvm_array_from_uints (LLVMInt32Type (), info->trampoline_size, MONO_AOT_TRAMP_NUM);
8756 fields [tindex ++] = llvm_array_from_uints (LLVMInt32Type (), info->tramp_page_code_offsets, MONO_AOT_TRAMP_NUM);
8758 fields [tindex ++] = llvm_array_from_bytes (info->aotid, 16);
8759 g_assert (tindex == nfields);
8761 LLVMSetInitializer (info_var, LLVMConstNamedStruct (file_info_type, fields, nfields));
8763 if (module->static_link) {
8767 s = g_strdup_printf ("mono_aot_module_%s_info", module->assembly->aname.name);
8768 /* Get rid of characters which cannot occur in symbols */
8770 for (p = s; *p; ++p) {
8771 if (!(isalnum (*p) || *p == '_'))
8774 var = LLVMAddGlobal (module->lmodule, LLVMPointerType (LLVMInt8Type (), 0), s);
8776 LLVMSetInitializer (var, LLVMConstBitCast (LLVMGetNamedGlobal (module->lmodule, "mono_aot_file_info"), LLVMPointerType (LLVMInt8Type (), 0)));
8777 LLVMSetLinkage (var, LLVMExternalLinkage);
8782 * Emit the aot module into the LLVM bitcode file FILENAME.
8785 mono_llvm_emit_aot_module (const char *filename, const char *cu_name)
8787 LLVMTypeRef got_type, inited_type;
8788 LLVMValueRef real_got, real_inited;
8789 MonoLLVMModule *module = &aot_module;
8791 emit_llvm_code_end (module);
8794 * Create the real got variable and replace all uses of the dummy variable with
8797 got_type = LLVMArrayType (module->ptr_type, module->max_got_offset + 1);
8798 real_got = LLVMAddGlobal (module->lmodule, got_type, module->got_symbol);
8799 LLVMSetInitializer (real_got, LLVMConstNull (got_type));
8800 if (module->external_symbols) {
8801 LLVMSetLinkage (real_got, LLVMExternalLinkage);
8802 LLVMSetVisibility (real_got, LLVMHiddenVisibility);
8804 LLVMSetLinkage (real_got, LLVMInternalLinkage);
8806 mono_llvm_replace_uses_of (module->got_var, real_got);
8808 mark_as_used (&aot_module, real_got);
8810 /* Delete the dummy got so it doesn't become a global */
8811 LLVMDeleteGlobal (module->got_var);
8812 module->got_var = real_got;
8815 * Same for the init_var
8817 if (module->llvm_only) {
8818 inited_type = LLVMArrayType (LLVMInt8Type (), module->max_inited_idx + 1);
8819 real_inited = LLVMAddGlobal (module->lmodule, inited_type, "mono_inited");
8820 LLVMSetInitializer (real_inited, LLVMConstNull (inited_type));
8821 LLVMSetLinkage (real_inited, LLVMInternalLinkage);
8822 mono_llvm_replace_uses_of (module->inited_var, real_inited);
8823 LLVMDeleteGlobal (module->inited_var);
8826 if (module->llvm_only) {
8827 emit_get_method (&aot_module);
8828 emit_get_unbox_tramp (&aot_module);
8831 emit_llvm_used (&aot_module);
8832 emit_dbg_info (&aot_module, filename, cu_name);
8833 emit_aot_file_info (&aot_module);
8836 * Replace GOT entries for directly callable methods with the methods themselves.
8837 * It would be easier to implement this by predefining all methods before compiling
8838 * their bodies, but that couldn't handle the case when a method fails to compile
8841 if (module->llvm_only) {
8842 GHashTableIter iter;
8844 GSList *callers, *l;
8846 g_hash_table_iter_init (&iter, module->method_to_callers);
8847 while (g_hash_table_iter_next (&iter, (void**)&method, (void**)&callers)) {
8848 LLVMValueRef lmethod;
8850 if (method->iflags & METHOD_IMPL_ATTRIBUTE_SYNCHRONIZED)
8853 lmethod = (LLVMValueRef)g_hash_table_lookup (module->method_to_lmethod, method);
8855 for (l = callers; l; l = l->next) {
8856 LLVMValueRef caller = (LLVMValueRef)l->data;
8858 mono_llvm_replace_uses_of (caller, lmethod);
8864 /* Replace PLT entries for directly callable methods with the methods themselves */
8866 GHashTableIter iter;
8868 LLVMValueRef callee;
8870 g_hash_table_iter_init (&iter, module->plt_entries_ji);
8871 while (g_hash_table_iter_next (&iter, (void**)&ji, (void**)&callee)) {
8872 if (mono_aot_is_direct_callable (ji)) {
8873 LLVMValueRef lmethod;
8875 lmethod = (LLVMValueRef)g_hash_table_lookup (module->method_to_lmethod, ji->data.method);
8876 /* The types might not match because the caller might pass an rgctx */
8877 if (lmethod && LLVMTypeOf (callee) == LLVMTypeOf (lmethod)) {
8878 mono_llvm_replace_uses_of (callee, lmethod);
8879 mono_aot_mark_unused_llvm_plt_entry (ji);
8889 if (LLVMVerifyModule (module->lmodule, LLVMReturnStatusAction, &verifier_err)) {
8890 printf ("%s\n", verifier_err);
8891 g_assert_not_reached ();
8896 LLVMWriteBitcodeToFile (module->lmodule, filename);
8901 md_string (const char *s)
8903 return LLVMMDString (s, strlen (s));
8906 /* Debugging support */
8909 emit_dbg_info (MonoLLVMModule *module, const char *filename, const char *cu_name)
8911 LLVMModuleRef lmodule = module->lmodule;
8912 LLVMValueRef args [16], ver;
8915 * This can only be enabled when LLVM code is emitted into a separate object
8916 * file, since the AOT compiler also emits dwarf info,
8917 * and the abbrev indexes will not be correct since llvm has added its own
8920 if (!module->emit_dwarf)
8923 #if LLVM_API_VERSION > 100
8924 mono_llvm_di_builder_finalize (module->di_builder);
8926 LLVMValueRef cu_args [16], cu;
8928 char *build_info, *s, *dir;
8931 * Emit dwarf info in the form of LLVM metadata. There is some
8932 * out-of-date documentation at:
8933 * http://llvm.org/docs/SourceLevelDebugging.html
8934 * but most of this was gathered from the llvm and
8939 cu_args [n_cuargs ++] = LLVMConstInt (LLVMInt32Type (), DW_TAG_compile_unit, FALSE);
8940 /* CU name/compilation dir */
8941 dir = g_path_get_dirname (filename);
8942 args [0] = LLVMMDString (cu_name, strlen (cu_name));
8943 args [1] = LLVMMDString (dir, strlen (dir));
8944 cu_args [n_cuargs ++] = LLVMMDNode (args, 2);
8947 cu_args [n_cuargs ++] = LLVMConstInt (LLVMInt32Type (), DW_LANG_C99, FALSE);
8949 build_info = mono_get_runtime_build_info ();
8950 s = g_strdup_printf ("Mono AOT Compiler %s (LLVM)", build_info);
8951 cu_args [n_cuargs ++] = LLVMMDString (s, strlen (s));
8952 g_free (build_info);
8954 cu_args [n_cuargs ++] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
8956 cu_args [n_cuargs ++] = LLVMMDString ("", strlen (""));
8957 /* Runtime version */
8958 cu_args [n_cuargs ++] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
8960 cu_args [n_cuargs ++] = LLVMMDNode (args, 0);
8961 cu_args [n_cuargs ++] = LLVMMDNode (args, 0);
8963 if (module->subprogram_mds) {
8967 mds = g_new0 (LLVMValueRef, module->subprogram_mds->len);
8968 for (i = 0; i < module->subprogram_mds->len; ++i)
8969 mds [i] = (LLVMValueRef)g_ptr_array_index (module->subprogram_mds, i);
8970 cu_args [n_cuargs ++] = LLVMMDNode (mds, module->subprogram_mds->len);
8972 cu_args [n_cuargs ++] = LLVMMDNode (args, 0);
8975 cu_args [n_cuargs ++] = LLVMMDNode (args, 0);
8976 /* Imported modules */
8977 cu_args [n_cuargs ++] = LLVMMDNode (args, 0);
8979 cu_args [n_cuargs ++] = LLVMMDString ("", strlen (""));
8980 /* DebugEmissionKind = FullDebug */
8981 cu_args [n_cuargs ++] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
8982 cu = LLVMMDNode (cu_args, n_cuargs);
8983 LLVMAddNamedMetadataOperand (lmodule, "llvm.dbg.cu", cu);
8986 #if LLVM_API_VERSION > 100
8987 args [0] = LLVMConstInt (LLVMInt32Type (), 2, FALSE);
8988 args [1] = LLVMMDString ("Dwarf Version", strlen ("Dwarf Version"));
8989 args [2] = LLVMConstInt (LLVMInt32Type (), 2, FALSE);
8990 ver = LLVMMDNode (args, 3);
8991 LLVMAddNamedMetadataOperand (lmodule, "llvm.module.flags", ver);
8993 args [0] = LLVMConstInt (LLVMInt32Type (), 2, FALSE);
8994 args [1] = LLVMMDString ("Debug Info Version", strlen ("Debug Info Version"));
8995 args [2] = LLVMConstInt (LLVMInt64Type (), 3, FALSE);
8996 ver = LLVMMDNode (args, 3);
8997 LLVMAddNamedMetadataOperand (lmodule, "llvm.module.flags", ver);
8999 args [0] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
9000 args [1] = LLVMMDString ("Dwarf Version", strlen ("Dwarf Version"));
9001 args [2] = LLVMConstInt (LLVMInt32Type (), 2, FALSE);
9002 ver = LLVMMDNode (args, 3);
9003 LLVMAddNamedMetadataOperand (lmodule, "llvm.module.flags", ver);
9005 args [0] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
9006 args [1] = LLVMMDString ("Debug Info Version", strlen ("Debug Info Version"));
9007 args [2] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
9008 ver = LLVMMDNode (args, 3);
9009 LLVMAddNamedMetadataOperand (lmodule, "llvm.module.flags", ver);
9014 emit_dbg_subprogram (EmitContext *ctx, MonoCompile *cfg, LLVMValueRef method, const char *name)
9016 MonoLLVMModule *module = ctx->module;
9017 MonoDebugMethodInfo *minfo = ctx->minfo;
9018 char *source_file, *dir, *filename;
9019 LLVMValueRef md, args [16], ctx_args [16], md_args [64], type_args [16], ctx_md, type_md;
9020 MonoSymSeqPoint *sym_seq_points;
9026 mono_debug_get_seq_points (minfo, &source_file, NULL, NULL, &sym_seq_points, &n_seq_points);
9028 source_file = g_strdup ("<unknown>");
9029 dir = g_path_get_dirname (source_file);
9030 filename = g_path_get_basename (source_file);
9032 #if LLVM_API_VERSION > 100
9033 return mono_llvm_di_create_function (module->di_builder, module->cu, method, cfg->method->name, name, dir, filename, n_seq_points ? sym_seq_points [0].line : 1);
9036 ctx_args [0] = LLVMConstInt (LLVMInt32Type (), 0x29, FALSE);
9037 args [0] = md_string (filename);
9038 args [1] = md_string (dir);
9039 ctx_args [1] = LLVMMDNode (args, 2);
9040 ctx_md = LLVMMDNode (ctx_args, 2);
9042 type_args [0] = LLVMConstInt (LLVMInt32Type (), DW_TAG_subroutine_type, FALSE);
9043 type_args [1] = NULL;
9044 type_args [2] = NULL;
9045 type_args [3] = LLVMMDString ("", 0);
9046 type_args [4] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
9047 type_args [5] = LLVMConstInt (LLVMInt64Type (), 0, FALSE);
9048 type_args [6] = LLVMConstInt (LLVMInt64Type (), 0, FALSE);
9049 type_args [7] = LLVMConstInt (LLVMInt64Type (), 0, FALSE);
9050 type_args [8] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
9051 type_args [9] = NULL;
9052 type_args [10] = NULL;
9053 type_args [11] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
9054 type_args [12] = NULL;
9055 type_args [13] = NULL;
9056 type_args [14] = NULL;
9057 type_md = LLVMMDNode (type_args, 14);
9059 /* http://llvm.org/docs/SourceLevelDebugging.html#subprogram-descriptors */
9060 md_args [0] = LLVMConstInt (LLVMInt32Type (), DW_TAG_subprogram, FALSE);
9061 /* Source directory + file pair */
9062 args [0] = md_string (filename);
9063 args [1] = md_string (dir);
9064 md_args [1] = LLVMMDNode (args ,2);
9065 md_args [2] = ctx_md;
9066 md_args [3] = md_string (cfg->method->name);
9067 md_args [4] = md_string (name);
9068 md_args [5] = md_string (name);
9071 md_args [6] = LLVMConstInt (LLVMInt32Type (), sym_seq_points [0].line, FALSE);
9073 md_args [6] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
9075 md_args [7] = type_md;
9077 md_args [8] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
9079 md_args [9] = LLVMConstInt (LLVMInt1Type (), 1, FALSE);
9081 md_args [10] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
9082 /* Index into a virtual function */
9083 md_args [11] = NULL;
9084 md_args [12] = NULL;
9086 md_args [13] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
9088 md_args [14] = LLVMConstInt (LLVMInt1Type (), 1, FALSE);
9089 /* Pointer to LLVM function */
9090 md_args [15] = method;
9091 /* Function template parameter */
9092 md_args [16] = NULL;
9093 /* Function declaration descriptor */
9094 md_args [17] = NULL;
9095 /* List of function variables */
9096 md_args [18] = LLVMMDNode (args, 0);
9098 md_args [19] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
9099 md = LLVMMDNode (md_args, 20);
9101 if (!module->subprogram_mds)
9102 module->subprogram_mds = g_ptr_array_new ();
9103 g_ptr_array_add (module->subprogram_mds, md);
9107 g_free (source_file);
9108 g_free (sym_seq_points);
9114 emit_dbg_loc (EmitContext *ctx, LLVMBuilderRef builder, const unsigned char *cil_code)
9116 MonoCompile *cfg = ctx->cfg;
9118 if (ctx->minfo && cil_code && cil_code >= cfg->header->code && cil_code < cfg->header->code + cfg->header->code_size) {
9119 MonoDebugSourceLocation *loc;
9120 LLVMValueRef loc_md;
9122 loc = mono_debug_method_lookup_location (ctx->minfo, cil_code - cfg->header->code);
9125 #if LLVM_API_VERSION > 100
9126 loc_md = mono_llvm_di_create_location (ctx->module->di_builder, ctx->dbg_md, loc->row, loc->column);
9127 mono_llvm_di_set_location (builder, loc_md);
9129 LLVMValueRef md_args [16];
9133 md_args [nmd_args ++] = LLVMConstInt (LLVMInt32Type (), loc->row, FALSE);
9134 md_args [nmd_args ++] = LLVMConstInt (LLVMInt32Type (), loc->column, FALSE);
9135 md_args [nmd_args ++] = ctx->dbg_md;
9136 md_args [nmd_args ++] = NULL;
9137 loc_md = LLVMMDNode (md_args, nmd_args);
9138 LLVMSetCurrentDebugLocation (builder, loc_md);
9140 mono_debug_free_source_location (loc);
9146 default_mono_llvm_unhandled_exception (void)
9148 MonoJitTlsData *jit_tls = mono_get_jit_tls ();
9149 MonoObject *target = mono_gchandle_get_target (jit_tls->thrown_exc);
9151 mono_unhandled_exception (target);
9152 mono_invoke_unhandled_exception_hook (target);
9153 g_assert_not_reached ();
9158 - Emit LLVM IR from the mono IR using the LLVM C API.
9159 - The original arch specific code remains, so we can fall back to it if we run
9160 into something we can't handle.
9164 A partial list of issues:
9165 - Handling of opcodes which can throw exceptions.
9167 In the mono JIT, these are implemented using code like this:
9174 push throw_pos - method
9175 call <exception trampoline>
9177 The problematic part is push throw_pos - method, which cannot be represented
9178 in the LLVM IR, since it does not support label values.
9179 -> this can be implemented in AOT mode using inline asm + labels, but cannot
9180 be implemented in JIT mode ?
9181 -> a possible but slower implementation would use the normal exception
9182 throwing code but it would need to control the placement of the throw code
9183 (it needs to be exactly after the compare+branch).
9184 -> perhaps add a PC offset intrinsics ?
9186 - efficient implementation of .ovf opcodes.
9188 These are currently implemented as:
9189 <ins which sets the condition codes>
9192 Some overflow opcodes are now supported by LLVM SVN.
9194 - exception handling, unwinding.
9195 - SSA is disabled for methods with exception handlers
9196 - How to obtain unwind info for LLVM compiled methods ?
9197 -> this is now solved by converting the unwind info generated by LLVM
9199 - LLVM uses the c++ exception handling framework, while we use our home grown
9200 code, and couldn't use the c++ one:
9201 - its not supported under VC++, other exotic platforms.
9202 - it might be impossible to support filter clauses with it.
9206 The trampolines need a predictable call sequence, since they need to disasm
9207 the calling code to obtain register numbers / offsets.
9209 LLVM currently generates this code in non-JIT mode:
9210 mov -0x98(%rax),%eax
9212 Here, the vtable pointer is lost.
9213 -> solution: use one vtable trampoline per class.
9215 - passing/receiving the IMT pointer/RGCTX.
9216 -> solution: pass them as normal arguments ?
9220 LLVM does not allow the specification of argument registers etc. This means
9221 that all calls are made according to the platform ABI.
9223 - passing/receiving vtypes.
9225 Vtypes passed/received in registers are handled by the front end by using
9226 a signature with scalar arguments, and loading the parts of the vtype into those
9229 Vtypes passed on the stack are handled using the 'byval' attribute.
9233 Supported though alloca, we need to emit the load/store code.
9237 The mono JIT uses pointer sized iregs/double fregs, while LLVM uses precisely
9238 typed registers, so we have to keep track of the precise LLVM type of each vreg.
9239 This is made easier because the IR is already in SSA form.
9240 An additional problem is that our IR is not consistent with types, i.e. i32/ia64
9241 types are frequently used incorrectly.
9246 Emit LLVM bytecode into a .bc file, compile it using llc into a .s file, then link
9247 it with the file containing the methods emitted by the JIT and the AOT data
9251 /* FIXME: Normalize some aspects of the mono IR to allow easier translation, like:
9252 * - each bblock should end with a branch
9253 * - setting the return value, making cfg->ret non-volatile
9254 * - avoid some transformations in the JIT which make it harder for us to generate
9256 * - use pointer types to help optimizations.
9259 #else /* DISABLE_JIT */
9262 mono_llvm_cleanup (void)
9267 mono_llvm_free_domain_info (MonoDomain *domain)
9272 mono_llvm_init (void)
9277 default_mono_llvm_unhandled_exception (void)
9281 #endif /* DISABLE_JIT */