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-mono-symfile.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 if (g_getenv ("LLVM_COUNT")) {
6941 if (count == atoi (g_getenv ("LLVM_COUNT"))) {
6942 printf ("LAST: %s\n", mono_method_full_name (cfg->method, TRUE));
6946 if (count > atoi (g_getenv ("LLVM_COUNT"))) {
6947 set_failure (ctx, "count");
6954 sig = mono_method_signature (cfg->method);
6957 linfo = get_llvm_call_info (cfg, sig);
6963 linfo->rgctx_arg = TRUE;
6964 ctx->method_type = method_type = sig_to_llvm_sig_full (ctx, sig, linfo);
6968 method = LLVMAddFunction (lmodule, ctx->method_name, method_type);
6969 ctx->lmethod = method;
6971 if (!cfg->llvm_only)
6972 LLVMSetFunctionCallConv (method, LLVMMono1CallConv);
6973 LLVMSetLinkage (method, LLVMPrivateLinkage);
6975 LLVMAddFunctionAttr (method, LLVMUWTable);
6977 if (cfg->compile_aot) {
6978 LLVMSetLinkage (method, LLVMInternalLinkage);
6979 if (ctx->module->external_symbols) {
6980 LLVMSetLinkage (method, LLVMExternalLinkage);
6981 LLVMSetVisibility (method, LLVMHiddenVisibility);
6983 if (ctx->is_linkonce) {
6984 LLVMSetLinkage (method, LLVMLinkOnceAnyLinkage);
6985 LLVMSetVisibility (method, LLVMDefaultVisibility);
6988 #if LLVM_API_VERSION > 100
6989 LLVMSetLinkage (method, LLVMExternalLinkage);
6991 LLVMSetLinkage (method, LLVMPrivateLinkage);
6995 if (cfg->method->save_lmf && !cfg->llvm_only) {
6996 set_failure (ctx, "lmf");
7000 if (sig->pinvoke && cfg->method->wrapper_type != MONO_WRAPPER_RUNTIME_INVOKE && !cfg->llvm_only) {
7001 set_failure (ctx, "pinvoke signature");
7005 header = cfg->header;
7006 for (i = 0; i < header->num_clauses; ++i) {
7007 clause = &header->clauses [i];
7008 if (clause->flags != MONO_EXCEPTION_CLAUSE_FINALLY && clause->flags != MONO_EXCEPTION_CLAUSE_NONE) {
7009 set_failure (ctx, "non-finally/catch clause.");
7013 if (header->num_clauses || (cfg->method->iflags & METHOD_IMPL_ATTRIBUTE_NOINLINING) || cfg->no_inline)
7014 /* We can't handle inlined methods with clauses */
7015 LLVMAddFunctionAttr (method, LLVMNoInlineAttribute);
7017 if (linfo->rgctx_arg) {
7018 ctx->rgctx_arg = LLVMGetParam (method, linfo->rgctx_arg_pindex);
7019 ctx->rgctx_arg_pindex = linfo->rgctx_arg_pindex;
7021 * We mark the rgctx parameter with the inreg attribute, which is mapped to
7022 * MONO_ARCH_RGCTX_REG in the Mono calling convention in llvm, i.e.
7023 * CC_X86_64_Mono in X86CallingConv.td.
7025 if (!ctx->llvm_only)
7026 LLVMAddAttribute (ctx->rgctx_arg, LLVMInRegAttribute);
7027 LLVMSetValueName (ctx->rgctx_arg, "rgctx");
7029 ctx->rgctx_arg_pindex = -1;
7031 if (cfg->vret_addr) {
7032 values [cfg->vret_addr->dreg] = LLVMGetParam (method, linfo->vret_arg_pindex);
7033 LLVMSetValueName (values [cfg->vret_addr->dreg], "vret");
7034 if (linfo->ret.storage == LLVMArgVtypeByRef) {
7035 LLVMAddAttribute (LLVMGetParam (method, linfo->vret_arg_pindex), LLVMStructRetAttribute);
7036 LLVMAddAttribute (LLVMGetParam (method, linfo->vret_arg_pindex), LLVMNoAliasAttribute);
7041 ctx->this_arg_pindex = linfo->this_arg_pindex;
7042 ctx->this_arg = LLVMGetParam (method, linfo->this_arg_pindex);
7043 values [cfg->args [0]->dreg] = ctx->this_arg;
7044 LLVMSetValueName (values [cfg->args [0]->dreg], "this");
7047 names = g_new (char *, sig->param_count);
7048 mono_method_get_param_names (cfg->method, (const char **) names);
7050 /* Set parameter names/attributes */
7051 for (i = 0; i < sig->param_count; ++i) {
7052 LLVMArgInfo *ainfo = &linfo->args [i + sig->hasthis];
7054 int pindex = ainfo->pindex + ainfo->ndummy_fpargs;
7057 for (j = 0; j < ainfo->ndummy_fpargs; ++j) {
7058 name = g_strdup_printf ("dummy_%d_%d", i, j);
7059 LLVMSetValueName (LLVMGetParam (method, ainfo->pindex + j), name);
7063 if (ainfo->storage == LLVMArgVtypeInReg && ainfo->pair_storage [0] == LLVMArgNone && ainfo->pair_storage [1] == LLVMArgNone)
7066 values [cfg->args [i + sig->hasthis]->dreg] = LLVMGetParam (method, pindex);
7067 if (ainfo->storage == LLVMArgGsharedvtFixed || ainfo->storage == LLVMArgGsharedvtFixedVtype) {
7068 if (names [i] && names [i][0] != '\0')
7069 name = g_strdup_printf ("p_arg_%s", names [i]);
7071 name = g_strdup_printf ("p_arg_%d", i);
7073 if (names [i] && names [i][0] != '\0')
7074 name = g_strdup_printf ("arg_%s", names [i]);
7076 name = g_strdup_printf ("arg_%d", i);
7078 LLVMSetValueName (values [cfg->args [i + sig->hasthis]->dreg], name);
7080 if (ainfo->storage == LLVMArgVtypeByVal)
7081 LLVMAddAttribute (LLVMGetParam (method, pindex), LLVMByValAttribute);
7083 if (ainfo->storage == LLVMArgVtypeByRef) {
7085 cfg->args [i + sig->hasthis]->opcode = OP_VTARG_ADDR;
7090 if (ctx->module->emit_dwarf && cfg->compile_aot && mono_debug_enabled ()) {
7091 ctx->minfo = mono_debug_lookup_method (cfg->method);
7092 ctx->dbg_md = emit_dbg_subprogram (ctx, cfg, method, ctx->method_name);
7096 for (bb = cfg->bb_entry; bb; bb = bb->next_bb)
7097 max_block_num = MAX (max_block_num, bb->block_num);
7098 ctx->bblocks = bblocks = g_new0 (BBInfo, max_block_num + 1);
7100 /* Add branches between non-consecutive bblocks */
7101 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
7102 if (bb->last_ins && MONO_IS_COND_BRANCH_OP (bb->last_ins) &&
7103 bb->next_bb != bb->last_ins->inst_false_bb) {
7105 MonoInst *inst = (MonoInst*)mono_mempool_alloc0 (cfg->mempool, sizeof (MonoInst));
7106 inst->opcode = OP_BR;
7107 inst->inst_target_bb = bb->last_ins->inst_false_bb;
7108 mono_bblock_add_inst (bb, inst);
7113 * The INDIRECT flag added by OP_LDADDR inhibits optimizations, even if the LDADDR
7114 * was later optimized away, so clear these flags, and add them back for the still
7115 * present OP_LDADDR instructions.
7117 for (i = 0; i < cfg->next_vreg; ++i) {
7120 ins = get_vreg_to_inst (cfg, i);
7121 if (ins && ins != cfg->rgctx_var)
7122 ins->flags &= ~MONO_INST_INDIRECT;
7126 * Make a first pass over the code to precreate PHI nodes/set INDIRECT flags.
7128 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
7130 LLVMBuilderRef builder;
7132 char dname_buf[128];
7134 builder = create_builder (ctx);
7136 for (ins = bb->code; ins; ins = ins->next) {
7137 switch (ins->opcode) {
7142 LLVMTypeRef phi_type = llvm_type_to_stack_type (cfg, type_to_llvm_type (ctx, &ins->klass->byval_arg));
7147 if (ins->opcode == OP_VPHI) {
7148 /* Treat valuetype PHI nodes as operating on the address itself */
7149 g_assert (ins->klass);
7150 phi_type = LLVMPointerType (type_to_llvm_type (ctx, &ins->klass->byval_arg), 0);
7154 * Have to precreate these, as they can be referenced by
7155 * earlier instructions.
7157 sprintf (dname_buf, "t%d", ins->dreg);
7159 values [ins->dreg] = LLVMBuildPhi (builder, phi_type, dname);
7161 if (ins->opcode == OP_VPHI)
7162 ctx->addresses [ins->dreg] = values [ins->dreg];
7164 g_ptr_array_add (ctx->phi_values, values [ins->dreg]);
7167 * Set the expected type of the incoming arguments since these have
7168 * to have the same type.
7170 for (i = 0; i < ins->inst_phi_args [0]; i++) {
7171 int sreg1 = ins->inst_phi_args [i + 1];
7174 if (ins->opcode == OP_VPHI)
7175 ctx->is_vphi [sreg1] = TRUE;
7176 ctx->vreg_types [sreg1] = phi_type;
7182 ((MonoInst*)ins->inst_p0)->flags |= MONO_INST_INDIRECT;
7191 * Create an ordering for bblocks, use the depth first order first, then
7192 * put the exception handling bblocks last.
7194 for (bb_index = 0; bb_index < cfg->num_bblocks; ++bb_index) {
7195 bb = cfg->bblocks [bb_index];
7196 if (!(bb->region != -1 && !MONO_BBLOCK_IS_IN_REGION (bb, MONO_REGION_TRY))) {
7197 g_ptr_array_add (bblock_list, bb);
7198 bblocks [bb->block_num].added = TRUE;
7202 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
7203 if (!bblocks [bb->block_num].added)
7204 g_ptr_array_add (bblock_list, bb);
7208 * Second pass: generate code.
7211 LLVMBuilderRef entry_builder = create_builder (ctx);
7212 LLVMBasicBlockRef entry_bb = get_bb (ctx, cfg->bb_entry);
7213 LLVMPositionBuilderAtEnd (entry_builder, entry_bb);
7214 emit_entry_bb (ctx, entry_builder);
7216 // Make landing pads first
7217 ctx->exc_meta = g_hash_table_new_full (NULL, NULL, NULL, NULL);
7219 if (ctx->llvm_only) {
7220 size_t group_index = 0;
7221 while (group_index < cfg->header->num_clauses) {
7223 size_t cursor = group_index;
7224 while (cursor < cfg->header->num_clauses &&
7225 CLAUSE_START (&cfg->header->clauses [cursor]) == CLAUSE_START (&cfg->header->clauses [group_index]) &&
7226 CLAUSE_END (&cfg->header->clauses [cursor]) == CLAUSE_END (&cfg->header->clauses [group_index])) {
7231 LLVMBasicBlockRef lpad_bb = emit_landing_pad (ctx, group_index, count);
7232 intptr_t key = CLAUSE_END (&cfg->header->clauses [group_index]);
7233 g_hash_table_insert (ctx->exc_meta, (gpointer)key, lpad_bb);
7235 group_index = cursor;
7239 for (bb_index = 0; bb_index < bblock_list->len; ++bb_index) {
7240 bb = (MonoBasicBlock*)g_ptr_array_index (bblock_list, bb_index);
7242 // Prune unreachable mono BBs.
7243 if (!(bb == cfg->bb_entry || bb->in_count > 0))
7246 process_bb (ctx, bb);
7250 g_hash_table_destroy (ctx->exc_meta);
7252 mono_memory_barrier ();
7254 /* Add incoming phi values */
7255 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
7256 GSList *l, *ins_list;
7258 ins_list = bblocks [bb->block_num].phi_nodes;
7260 for (l = ins_list; l; l = l->next) {
7261 PhiNode *node = (PhiNode*)l->data;
7262 MonoInst *phi = node->phi;
7263 int sreg1 = node->sreg;
7264 LLVMBasicBlockRef in_bb;
7269 in_bb = get_end_bb (ctx, node->in_bb);
7271 if (ctx->unreachable [node->in_bb->block_num])
7274 if (!values [sreg1]) {
7275 /* Can happen with values in EH clauses */
7276 set_failure (ctx, "incoming phi sreg1");
7280 if (phi->opcode == OP_VPHI) {
7281 g_assert (LLVMTypeOf (ctx->addresses [sreg1]) == LLVMTypeOf (values [phi->dreg]));
7282 LLVMAddIncoming (values [phi->dreg], &ctx->addresses [sreg1], &in_bb, 1);
7284 if (LLVMTypeOf (values [sreg1]) != LLVMTypeOf (values [phi->dreg])) {
7285 set_failure (ctx, "incoming phi arg type mismatch");
7288 g_assert (LLVMTypeOf (values [sreg1]) == LLVMTypeOf (values [phi->dreg]));
7289 LLVMAddIncoming (values [phi->dreg], &values [sreg1], &in_bb, 1);
7294 /* Nullify empty phi instructions */
7295 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
7296 GSList *l, *ins_list;
7298 ins_list = bblocks [bb->block_num].phi_nodes;
7300 for (l = ins_list; l; l = l->next) {
7301 PhiNode *node = (PhiNode*)l->data;
7302 MonoInst *phi = node->phi;
7303 LLVMValueRef phi_ins = values [phi->dreg];
7306 /* Already removed */
7309 if (LLVMCountIncoming (phi_ins) == 0) {
7310 mono_llvm_replace_uses_of (phi_ins, LLVMConstNull (LLVMTypeOf (phi_ins)));
7311 LLVMInstructionEraseFromParent (phi_ins);
7312 values [phi->dreg] = NULL;
7317 /* Create the SWITCH statements for ENDFINALLY instructions */
7318 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
7319 BBInfo *info = &bblocks [bb->block_num];
7321 for (l = info->endfinally_switch_ins_list; l; l = l->next) {
7322 LLVMValueRef switch_ins = (LLVMValueRef)l->data;
7323 GSList *bb_list = info->call_handler_return_bbs;
7325 GSList *bb_list_iter;
7327 for (bb_list_iter = bb_list; bb_list_iter; bb_list_iter = g_slist_next (bb_list_iter)) {
7328 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), i + 1, FALSE), (LLVMBasicBlockRef)bb_list_iter->data);
7334 /* Initialize the method if needed */
7335 if (cfg->compile_aot && ctx->llvm_only) {
7336 // FIXME: Add more shared got entries
7337 ctx->builder = create_builder (ctx);
7338 LLVMPositionBuilderAtEnd (ctx->builder, ctx->init_bb);
7340 ctx->module->max_method_idx = MAX (ctx->module->max_method_idx, cfg->method_index);
7342 // FIXME: beforefieldinit
7344 * NATIVE_TO_MANAGED methods might be called on a thread not attached to the runtime, so they are initialized when loaded
7345 * in load_method ().
7347 if ((ctx->has_got_access || mono_class_get_cctor (cfg->method->klass)) && !(cfg->method->wrapper_type == MONO_WRAPPER_NATIVE_TO_MANAGED)) {
7349 * linkonce methods shouldn't have initialization,
7350 * because they might belong to assemblies which
7351 * haven't been loaded yet.
7353 g_assert (!ctx->is_linkonce);
7354 emit_init_method (ctx);
7356 LLVMBuildBr (ctx->builder, ctx->inited_bb);
7360 if (cfg->llvm_only) {
7361 GHashTableIter iter;
7363 GSList *callers, *l, *l2;
7366 * Add the contents of ctx->method_to_callers to module->method_to_callers.
7367 * We can't do this earlier, as it contains llvm instructions which can be
7368 * freed if compilation fails.
7369 * FIXME: Get rid of this when all methods can be llvm compiled.
7371 g_hash_table_iter_init (&iter, ctx->method_to_callers);
7372 while (g_hash_table_iter_next (&iter, (void**)&method, (void**)&callers)) {
7373 for (l = callers; l; l = l->next) {
7374 l2 = (GSList*)g_hash_table_lookup (ctx->module->method_to_callers, method);
7375 l2 = g_slist_prepend (l2, l->data);
7376 g_hash_table_insert (ctx->module->method_to_callers, method, l2);
7381 if (cfg->verbose_level > 1)
7382 mono_llvm_dump_value (method);
7384 if (cfg->compile_aot && !cfg->llvm_only)
7385 mark_as_used (ctx->module, method);
7387 if (!cfg->llvm_only) {
7388 LLVMValueRef md_args [16];
7389 LLVMValueRef md_node;
7392 if (cfg->compile_aot)
7393 method_index = mono_aot_get_method_index (cfg->orig_method);
7396 md_args [0] = LLVMMDString (ctx->method_name, strlen (ctx->method_name));
7397 md_args [1] = LLVMConstInt (LLVMInt32Type (), method_index, FALSE);
7398 md_node = LLVMMDNode (md_args, 2);
7399 LLVMAddNamedMetadataOperand (lmodule, "mono.function_indexes", md_node);
7400 //LLVMSetMetadata (method, md_kind, LLVMMDNode (&md_arg, 1));
7403 if (cfg->compile_aot) {
7404 /* Don't generate native code, keep the LLVM IR */
7405 if (cfg->verbose_level)
7406 printf ("%s emitted as %s\n", mono_method_full_name (cfg->method, TRUE), ctx->method_name);
7408 #if LLVM_API_VERSION < 100
7409 /* VerifyFunction can't handle some of the debug info created by DIBuilder in llvm 3.9 */
7410 int err = LLVMVerifyFunction(ctx->lmethod, LLVMPrintMessageAction);
7411 g_assert (err == 0);
7414 //LLVMVerifyFunction(method, 0);
7415 #if LLVM_API_VERSION > 100
7416 MonoDomain *domain = mono_domain_get ();
7417 MonoJitDomainInfo *domain_info;
7418 int nvars = g_hash_table_size (ctx->jit_callees);
7419 LLVMValueRef *callee_vars = g_new0 (LLVMValueRef, nvars);
7420 gpointer *callee_addrs = g_new0 (gpointer, nvars);
7421 GHashTableIter iter;
7427 * Compute the addresses of the LLVM globals pointing to the
7428 * methods called by the current method. Pass it to the trampoline
7429 * code so it can update them after their corresponding method was
7432 g_hash_table_iter_init (&iter, ctx->jit_callees);
7434 while (g_hash_table_iter_next (&iter, NULL, (void**)&var))
7435 callee_vars [i ++] = var;
7437 cfg->native_code = mono_llvm_compile_method (ctx->module->mono_ee, ctx->lmethod, nvars, callee_vars, callee_addrs, &eh_frame);
7439 decode_llvm_eh_info (ctx, eh_frame);
7441 mono_domain_lock (domain);
7442 domain_info = domain_jit_info (domain);
7443 if (!domain_info->llvm_jit_callees)
7444 domain_info->llvm_jit_callees = g_hash_table_new (NULL, NULL);
7445 g_hash_table_iter_init (&iter, ctx->jit_callees);
7447 while (g_hash_table_iter_next (&iter, (void**)&callee, (void**)&var)) {
7448 GSList *addrs = g_hash_table_lookup (domain_info->llvm_jit_callees, callee);
7449 addrs = g_slist_prepend (addrs, callee_addrs [i]);
7450 g_hash_table_insert (domain_info->llvm_jit_callees, callee, addrs);
7453 mono_domain_unlock (domain);
7455 mono_llvm_optimize_method (ctx->module->mono_ee, ctx->lmethod);
7457 if (cfg->verbose_level > 1)
7458 mono_llvm_dump_value (ctx->lmethod);
7460 cfg->native_code = (unsigned char*)LLVMGetPointerToGlobal (ctx->module->ee, ctx->lmethod);
7462 /* Set by emit_cb */
7463 g_assert (cfg->code_len);
7467 if (ctx->module->method_to_lmethod)
7468 g_hash_table_insert (ctx->module->method_to_lmethod, cfg->method, ctx->lmethod);
7469 if (ctx->module->idx_to_lmethod)
7470 g_hash_table_insert (ctx->module->idx_to_lmethod, GINT_TO_POINTER (cfg->method_index), ctx->lmethod);
7472 if (ctx->llvm_only && cfg->orig_method->klass->valuetype && !(cfg->orig_method->flags & METHOD_ATTRIBUTE_STATIC))
7473 emit_unbox_tramp (ctx, ctx->method_name, ctx->method_type, ctx->lmethod, cfg->method_index);
7477 * mono_llvm_create_vars:
7479 * Same as mono_arch_create_vars () for LLVM.
7482 mono_llvm_create_vars (MonoCompile *cfg)
7484 MonoMethodSignature *sig;
7486 sig = mono_method_signature (cfg->method);
7487 if (cfg->gsharedvt && cfg->llvm_only) {
7488 if (mini_is_gsharedvt_variable_signature (sig) && sig->ret->type != MONO_TYPE_VOID) {
7489 cfg->vret_addr = mono_compile_create_var (cfg, &mono_get_intptr_class ()->byval_arg, OP_ARG);
7490 if (G_UNLIKELY (cfg->verbose_level > 1)) {
7491 printf ("vret_addr = ");
7492 mono_print_ins (cfg->vret_addr);
7496 mono_arch_create_vars (cfg);
7501 * mono_llvm_emit_call:
7503 * Same as mono_arch_emit_call () for LLVM.
7506 mono_llvm_emit_call (MonoCompile *cfg, MonoCallInst *call)
7509 MonoMethodSignature *sig;
7510 int i, n, stack_size;
7515 sig = call->signature;
7516 n = sig->param_count + sig->hasthis;
7518 call->cinfo = get_llvm_call_info (cfg, sig);
7520 if (cfg->disable_llvm)
7523 if (sig->call_convention == MONO_CALL_VARARG) {
7524 cfg->exception_message = g_strdup ("varargs");
7525 cfg->disable_llvm = TRUE;
7528 for (i = 0; i < n; ++i) {
7531 ainfo = call->cinfo->args + i;
7533 in = call->args [i];
7535 /* Simply remember the arguments */
7536 switch (ainfo->storage) {
7537 case LLVMArgNormal: {
7538 MonoType *t = (sig->hasthis && i == 0) ? &mono_get_intptr_class ()->byval_arg : ainfo->type;
7541 opcode = mono_type_to_regmove (cfg, t);
7542 if (opcode == OP_FMOVE) {
7543 MONO_INST_NEW (cfg, ins, OP_FMOVE);
7544 ins->dreg = mono_alloc_freg (cfg);
7545 } else if (opcode == OP_LMOVE) {
7546 MONO_INST_NEW (cfg, ins, OP_LMOVE);
7547 ins->dreg = mono_alloc_lreg (cfg);
7548 } else if (opcode == OP_RMOVE) {
7549 MONO_INST_NEW (cfg, ins, OP_RMOVE);
7550 ins->dreg = mono_alloc_freg (cfg);
7552 MONO_INST_NEW (cfg, ins, OP_MOVE);
7553 ins->dreg = mono_alloc_ireg (cfg);
7555 ins->sreg1 = in->dreg;
7558 case LLVMArgVtypeByVal:
7559 case LLVMArgVtypeByRef:
7560 case LLVMArgVtypeInReg:
7561 case LLVMArgVtypeAsScalar:
7562 case LLVMArgAsIArgs:
7563 case LLVMArgAsFpArgs:
7564 case LLVMArgGsharedvtVariable:
7565 case LLVMArgGsharedvtFixed:
7566 case LLVMArgGsharedvtFixedVtype:
7567 MONO_INST_NEW (cfg, ins, OP_LLVM_OUTARG_VT);
7568 ins->dreg = mono_alloc_ireg (cfg);
7569 ins->sreg1 = in->dreg;
7570 ins->inst_p0 = mono_mempool_alloc0 (cfg->mempool, sizeof (LLVMArgInfo));
7571 memcpy (ins->inst_p0, ainfo, sizeof (LLVMArgInfo));
7572 ins->inst_vtype = ainfo->type;
7573 ins->klass = mono_class_from_mono_type (ainfo->type);
7576 cfg->exception_message = g_strdup ("ainfo->storage");
7577 cfg->disable_llvm = TRUE;
7581 if (!cfg->disable_llvm) {
7582 MONO_ADD_INS (cfg->cbb, ins);
7583 mono_call_inst_add_outarg_reg (cfg, call, ins->dreg, 0, FALSE);
7588 static unsigned char*
7589 alloc_cb (LLVMValueRef function, int size)
7593 cfg = (MonoCompile*)mono_native_tls_get_value (current_cfg_tls_id);
7597 return (unsigned char*)mono_domain_code_reserve (cfg->domain, size);
7599 return (unsigned char*)mono_domain_code_reserve (mono_domain_get (), size);
7604 emitted_cb (LLVMValueRef function, void *start, void *end)
7608 cfg = (MonoCompile*)mono_native_tls_get_value (current_cfg_tls_id);
7610 cfg->code_len = (guint8*)end - (guint8*)start;
7614 exception_cb (void *data)
7617 MonoJitExceptionInfo *ei;
7618 guint32 ei_len, i, j, nested_len, nindex;
7619 gpointer *type_info;
7620 int this_reg, this_offset;
7622 cfg = (MonoCompile*)mono_native_tls_get_value (current_cfg_tls_id);
7626 * data points to a DWARF FDE structure, convert it to our unwind format and
7628 * An alternative would be to save it directly, and modify our unwinder to work
7631 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);
7632 if (cfg->verbose_level > 1)
7633 mono_print_unwind_info (cfg->encoded_unwind_ops, cfg->encoded_unwind_ops_len);
7635 /* Count nested clauses */
7637 for (i = 0; i < ei_len; ++i) {
7638 gint32 cindex1 = *(gint32*)type_info [i];
7639 MonoExceptionClause *clause1 = &cfg->header->clauses [cindex1];
7641 for (j = 0; j < cfg->header->num_clauses; ++j) {
7643 MonoExceptionClause *clause2 = &cfg->header->clauses [cindex2];
7645 if (cindex1 != cindex2 && clause1->try_offset >= clause2->try_offset && clause1->handler_offset <= clause2->handler_offset) {
7651 cfg->llvm_ex_info = (MonoJitExceptionInfo*)mono_mempool_alloc0 (cfg->mempool, (ei_len + nested_len) * sizeof (MonoJitExceptionInfo));
7652 cfg->llvm_ex_info_len = ei_len + nested_len;
7653 memcpy (cfg->llvm_ex_info, ei, ei_len * sizeof (MonoJitExceptionInfo));
7654 /* Fill the rest of the information from the type info */
7655 for (i = 0; i < ei_len; ++i) {
7656 gint32 clause_index = *(gint32*)type_info [i];
7657 MonoExceptionClause *clause = &cfg->header->clauses [clause_index];
7659 cfg->llvm_ex_info [i].flags = clause->flags;
7660 cfg->llvm_ex_info [i].data.catch_class = clause->data.catch_class;
7661 cfg->llvm_ex_info [i].clause_index = clause_index;
7665 * For nested clauses, the LLVM produced exception info associates the try interval with
7666 * the innermost handler, while mono expects it to be associated with all nesting clauses.
7667 * So add new clauses which use the IL info (catch class etc.) from the nesting clause,
7668 * and everything else from the nested clause.
7671 for (i = 0; i < ei_len; ++i) {
7672 gint32 cindex1 = *(gint32*)type_info [i];
7673 MonoExceptionClause *clause1 = &cfg->header->clauses [cindex1];
7675 for (j = 0; j < cfg->header->num_clauses; ++j) {
7677 MonoExceptionClause *clause2 = &cfg->header->clauses [cindex2];
7678 MonoJitExceptionInfo *nesting_ei, *nested_ei;
7680 if (cindex1 != cindex2 && clause1->try_offset >= clause2->try_offset && clause1->handler_offset <= clause2->handler_offset) {
7681 /* clause1 is the nested clause */
7682 nested_ei = &cfg->llvm_ex_info [i];
7683 nesting_ei = &cfg->llvm_ex_info [nindex];
7686 memcpy (nesting_ei, nested_ei, sizeof (MonoJitExceptionInfo));
7688 nesting_ei->flags = clause2->flags;
7689 nesting_ei->data.catch_class = clause2->data.catch_class;
7690 nesting_ei->clause_index = cindex2;
7694 g_assert (nindex == ei_len + nested_len);
7695 cfg->llvm_this_reg = this_reg;
7696 cfg->llvm_this_offset = this_offset;
7698 /* type_info [i] is cfg mempool allocated, no need to free it */
7704 #if LLVM_API_VERSION > 100
7706 * decode_llvm_eh_info:
7708 * Decode the EH table emitted by llvm in jit mode, and store
7709 * the result into cfg.
7712 decode_llvm_eh_info (EmitContext *ctx, gpointer eh_frame)
7714 MonoCompile *cfg = ctx->cfg;
7717 MonoLLVMFDEInfo info;
7718 MonoJitExceptionInfo *ei;
7719 guint8 *p = eh_frame;
7720 int version, fde_count, fde_offset;
7721 guint32 ei_len, i, nested_len;
7722 gpointer *type_info;
7726 * Decode the one element EH table emitted by the MonoException class
7730 /* Similar to decode_llvm_mono_eh_frame () in aot-runtime.c */
7733 g_assert (version == 3);
7736 p = (guint8 *)ALIGN_PTR_TO (p, 4);
7738 fde_count = *(guint32*)p;
7742 g_assert (fde_count <= 2);
7744 /* The first entry is the real method */
7745 g_assert (table [0] == 1);
7746 fde_offset = table [1];
7747 table += fde_count * 2;
7749 cfg->code_len = table [0];
7750 fde_len = table [1] - fde_offset;
7753 fde = (guint8*)eh_frame + fde_offset;
7754 cie = (guint8*)table;
7756 mono_unwind_decode_llvm_mono_fde (fde, fde_len, cie, cfg->native_code, &info);
7758 cfg->encoded_unwind_ops = info.unw_info;
7759 cfg->encoded_unwind_ops_len = info.unw_info_len;
7760 if (cfg->verbose_level > 1)
7761 mono_print_unwind_info (cfg->encoded_unwind_ops, cfg->encoded_unwind_ops_len);
7762 if (info.this_reg != -1) {
7763 cfg->llvm_this_reg = info.this_reg;
7764 cfg->llvm_this_offset = info.this_offset;
7768 ei_len = info.ex_info_len;
7769 type_info = info.type_info;
7771 // Nested clauses are currently disabled
7774 cfg->llvm_ex_info = (MonoJitExceptionInfo*)mono_mempool_alloc0 (cfg->mempool, (ei_len + nested_len) * sizeof (MonoJitExceptionInfo));
7775 cfg->llvm_ex_info_len = ei_len + nested_len;
7776 memcpy (cfg->llvm_ex_info, ei, ei_len * sizeof (MonoJitExceptionInfo));
7777 /* Fill the rest of the information from the type info */
7778 for (i = 0; i < ei_len; ++i) {
7779 gint32 clause_index = *(gint32*)type_info [i];
7780 MonoExceptionClause *clause = &cfg->header->clauses [clause_index];
7782 cfg->llvm_ex_info [i].flags = clause->flags;
7783 cfg->llvm_ex_info [i].data.catch_class = clause->data.catch_class;
7784 cfg->llvm_ex_info [i].clause_index = clause_index;
7790 dlsym_cb (const char *name, void **symbol)
7796 if (!strcmp (name, "__bzero")) {
7797 *symbol = (void*)bzero;
7799 current = mono_dl_open (NULL, 0, NULL);
7802 err = mono_dl_symbol (current, name, symbol);
7804 mono_dl_close (current);
7806 #ifdef MONO_ARCH_HAVE_CREATE_LLVM_NATIVE_THUNK
7807 *symbol = (char*)mono_arch_create_llvm_native_thunk (mono_domain_get (), (guint8*)(*symbol));
7813 AddFunc (LLVMModuleRef module, const char *name, LLVMTypeRef ret_type, LLVMTypeRef *param_types, int nparams)
7815 LLVMAddFunction (module, name, LLVMFunctionType (ret_type, param_types, nparams, FALSE));
7819 AddFunc2 (LLVMModuleRef module, const char *name, LLVMTypeRef ret_type, LLVMTypeRef param_type1, LLVMTypeRef param_type2)
7821 LLVMTypeRef param_types [4];
7823 param_types [0] = param_type1;
7824 param_types [1] = param_type2;
7826 AddFunc (module, name, ret_type, param_types, 2);
7832 INTRINS_SADD_OVF_I32,
7833 INTRINS_UADD_OVF_I32,
7834 INTRINS_SSUB_OVF_I32,
7835 INTRINS_USUB_OVF_I32,
7836 INTRINS_SMUL_OVF_I32,
7837 INTRINS_UMUL_OVF_I32,
7838 INTRINS_SADD_OVF_I64,
7839 INTRINS_UADD_OVF_I64,
7840 INTRINS_SSUB_OVF_I64,
7841 INTRINS_USUB_OVF_I64,
7842 INTRINS_SMUL_OVF_I64,
7843 INTRINS_UMUL_OVF_I64,
7850 #if defined(TARGET_AMD64) || defined(TARGET_X86)
7851 INTRINS_SSE_PMOVMSKB,
7852 INTRINS_SSE_PSRLI_W,
7853 INTRINS_SSE_PSRAI_W,
7854 INTRINS_SSE_PSLLI_W,
7855 INTRINS_SSE_PSRLI_D,
7856 INTRINS_SSE_PSRAI_D,
7857 INTRINS_SSE_PSLLI_D,
7858 INTRINS_SSE_PSRLI_Q,
7859 INTRINS_SSE_PSLLI_Q,
7860 INTRINS_SSE_SQRT_PD,
7861 INTRINS_SSE_SQRT_PS,
7862 INTRINS_SSE_RSQRT_PS,
7864 INTRINS_SSE_CVTTPD2DQ,
7865 INTRINS_SSE_CVTTPS2DQ,
7866 INTRINS_SSE_CVTDQ2PD,
7867 INTRINS_SSE_CVTDQ2PS,
7868 INTRINS_SSE_CVTPD2DQ,
7869 INTRINS_SSE_CVTPS2DQ,
7870 INTRINS_SSE_CVTPD2PS,
7871 INTRINS_SSE_CVTPS2PD,
7874 INTRINS_SSE_PACKSSWB,
7875 INTRINS_SSE_PACKUSWB,
7876 INTRINS_SSE_PACKSSDW,
7877 INTRINS_SSE_PACKUSDW,
7882 INTRINS_SSE_ADDSUBPS,
7887 INTRINS_SSE_ADDSUBPD,
7890 INTRINS_SSE_PADDUSW,
7891 INTRINS_SSE_PSUBUSW,
7897 INTRINS_SSE_PADDUSB,
7898 INTRINS_SSE_PSUBUSB,
7911 static IntrinsicDesc intrinsics[] = {
7912 {INTRINS_MEMSET, "llvm.memset.p0i8.i32"},
7913 {INTRINS_MEMCPY, "llvm.memcpy.p0i8.p0i8.i32"},
7914 {INTRINS_SADD_OVF_I32, "llvm.sadd.with.overflow.i32"},
7915 {INTRINS_UADD_OVF_I32, "llvm.uadd.with.overflow.i32"},
7916 {INTRINS_SSUB_OVF_I32, "llvm.ssub.with.overflow.i32"},
7917 {INTRINS_USUB_OVF_I32, "llvm.usub.with.overflow.i32"},
7918 {INTRINS_SMUL_OVF_I32, "llvm.smul.with.overflow.i32"},
7919 {INTRINS_UMUL_OVF_I32, "llvm.umul.with.overflow.i32"},
7920 {INTRINS_SADD_OVF_I64, "llvm.sadd.with.overflow.i64"},
7921 {INTRINS_UADD_OVF_I64, "llvm.uadd.with.overflow.i64"},
7922 {INTRINS_SSUB_OVF_I64, "llvm.ssub.with.overflow.i64"},
7923 {INTRINS_USUB_OVF_I64, "llvm.usub.with.overflow.i64"},
7924 {INTRINS_SMUL_OVF_I64, "llvm.smul.with.overflow.i64"},
7925 {INTRINS_UMUL_OVF_I64, "llvm.umul.with.overflow.i64"},
7926 {INTRINS_SIN, "llvm.sin.f64"},
7927 {INTRINS_COS, "llvm.cos.f64"},
7928 {INTRINS_SQRT, "llvm.sqrt.f64"},
7929 /* This isn't an intrinsic, instead llvm seems to special case it by name */
7930 {INTRINS_FABS, "fabs"},
7931 {INTRINS_EXPECT_I8, "llvm.expect.i8"},
7932 {INTRINS_EXPECT_I1, "llvm.expect.i1"},
7933 #if defined(TARGET_AMD64) || defined(TARGET_X86)
7934 {INTRINS_SSE_PMOVMSKB, "llvm.x86.sse2.pmovmskb.128"},
7935 {INTRINS_SSE_PSRLI_W, "llvm.x86.sse2.psrli.w"},
7936 {INTRINS_SSE_PSRAI_W, "llvm.x86.sse2.psrai.w"},
7937 {INTRINS_SSE_PSLLI_W, "llvm.x86.sse2.pslli.w"},
7938 {INTRINS_SSE_PSRLI_D, "llvm.x86.sse2.psrli.d"},
7939 {INTRINS_SSE_PSRAI_D, "llvm.x86.sse2.psrai.d"},
7940 {INTRINS_SSE_PSLLI_D, "llvm.x86.sse2.pslli.d"},
7941 {INTRINS_SSE_PSRLI_Q, "llvm.x86.sse2.psrli.q"},
7942 {INTRINS_SSE_PSLLI_Q, "llvm.x86.sse2.pslli.q"},
7943 {INTRINS_SSE_SQRT_PD, "llvm.x86.sse2.sqrt.pd"},
7944 {INTRINS_SSE_SQRT_PS, "llvm.x86.sse.sqrt.ps"},
7945 {INTRINS_SSE_RSQRT_PS, "llvm.x86.sse.rsqrt.ps"},
7946 {INTRINS_SSE_RCP_PS, "llvm.x86.sse.rcp.ps"},
7947 {INTRINS_SSE_CVTTPD2DQ, "llvm.x86.sse2.cvttpd2dq"},
7948 {INTRINS_SSE_CVTTPS2DQ, "llvm.x86.sse2.cvttps2dq"},
7949 {INTRINS_SSE_CVTDQ2PD, "llvm.x86.sse2.cvtdq2pd"},
7950 {INTRINS_SSE_CVTDQ2PS, "llvm.x86.sse2.cvtdq2ps"},
7951 {INTRINS_SSE_CVTPD2DQ, "llvm.x86.sse2.cvtpd2dq"},
7952 {INTRINS_SSE_CVTPS2DQ, "llvm.x86.sse2.cvtps2dq"},
7953 {INTRINS_SSE_CVTPD2PS, "llvm.x86.sse2.cvtpd2ps"},
7954 {INTRINS_SSE_CVTPS2PD, "llvm.x86.sse2.cvtps2pd"},
7955 {INTRINS_SSE_CMPPD, "llvm.x86.sse2.cmp.pd"},
7956 {INTRINS_SSE_CMPPS, "llvm.x86.sse.cmp.ps"},
7957 {INTRINS_SSE_PACKSSWB, "llvm.x86.sse2.packsswb.128"},
7958 {INTRINS_SSE_PACKUSWB, "llvm.x86.sse2.packuswb.128"},
7959 {INTRINS_SSE_PACKSSDW, "llvm.x86.sse2.packssdw.128"},
7960 {INTRINS_SSE_PACKUSDW, "llvm.x86.sse41.packusdw"},
7961 {INTRINS_SSE_MINPS, "llvm.x86.sse.min.ps"},
7962 {INTRINS_SSE_MAXPS, "llvm.x86.sse.max.ps"},
7963 {INTRINS_SSE_HADDPS, "llvm.x86.sse3.hadd.ps"},
7964 {INTRINS_SSE_HSUBPS, "llvm.x86.sse3.hsub.ps"},
7965 {INTRINS_SSE_ADDSUBPS, "llvm.x86.sse3.addsub.ps"},
7966 {INTRINS_SSE_MINPD, "llvm.x86.sse2.min.pd"},
7967 {INTRINS_SSE_MAXPD, "llvm.x86.sse2.max.pd"},
7968 {INTRINS_SSE_HADDPD, "llvm.x86.sse3.hadd.pd"},
7969 {INTRINS_SSE_HSUBPD, "llvm.x86.sse3.hsub.pd"},
7970 {INTRINS_SSE_ADDSUBPD, "llvm.x86.sse3.addsub.pd"},
7971 {INTRINS_SSE_PADDSW, "llvm.x86.sse2.padds.w"},
7972 {INTRINS_SSE_PSUBSW, "llvm.x86.sse2.psubs.w"},
7973 {INTRINS_SSE_PADDUSW, "llvm.x86.sse2.paddus.w"},
7974 {INTRINS_SSE_PSUBUSW, "llvm.x86.sse2.psubus.w"},
7975 {INTRINS_SSE_PAVGW, "llvm.x86.sse2.pavg.w"},
7976 {INTRINS_SSE_PMULHW, "llvm.x86.sse2.pmulh.w"},
7977 {INTRINS_SSE_PMULHU, "llvm.x86.sse2.pmulhu.w"},
7978 {INTRINS_SE_PADDSB, "llvm.x86.sse2.padds.b"},
7979 {INTRINS_SSE_PSUBSB, "llvm.x86.sse2.psubs.b"},
7980 {INTRINS_SSE_PADDUSB, "llvm.x86.sse2.paddus.b"},
7981 {INTRINS_SSE_PSUBUSB, "llvm.x86.sse2.psubus.b"},
7982 {INTRINS_SSE_PAVGB, "llvm.x86.sse2.pavg.b"},
7983 {INTRINS_SSE_PAUSE, "llvm.x86.sse2.pause"},
7984 {INTRINS_SSE_DPPS, "llvm.x86.sse41.dpps"}
7989 add_sse_binary (LLVMModuleRef module, const char *name, int type)
7991 LLVMTypeRef ret_type = type_to_simd_type (type);
7992 AddFunc2 (module, name, ret_type, ret_type, ret_type);
7996 add_intrinsic (LLVMModuleRef module, int id)
7999 #if defined(TARGET_AMD64) || defined(TARGET_X86)
8000 LLVMTypeRef ret_type, arg_types [16];
8003 name = g_hash_table_lookup (intrins_id_to_name, GINT_TO_POINTER (id));
8007 case INTRINS_MEMSET: {
8008 LLVMTypeRef params [] = { LLVMPointerType (LLVMInt8Type (), 0), LLVMInt8Type (), LLVMInt32Type (), LLVMInt32Type (), LLVMInt1Type () };
8010 AddFunc (module, name, LLVMVoidType (), params, 5);
8013 case INTRINS_MEMCPY: {
8014 LLVMTypeRef params [] = { LLVMPointerType (LLVMInt8Type (), 0), LLVMPointerType (LLVMInt8Type (), 0), LLVMInt32Type (), LLVMInt32Type (), LLVMInt1Type () };
8016 AddFunc (module, name, LLVMVoidType (), params, 5);
8019 case INTRINS_SADD_OVF_I32:
8020 case INTRINS_UADD_OVF_I32:
8021 case INTRINS_SSUB_OVF_I32:
8022 case INTRINS_USUB_OVF_I32:
8023 case INTRINS_SMUL_OVF_I32:
8024 case INTRINS_UMUL_OVF_I32: {
8025 LLVMTypeRef ovf_res_i32 [] = { LLVMInt32Type (), LLVMInt1Type () };
8026 LLVMTypeRef params [] = { LLVMInt32Type (), LLVMInt32Type () };
8027 LLVMTypeRef ret_type = LLVMStructType (ovf_res_i32, 2, FALSE);
8029 AddFunc (module, name, ret_type, params, 2);
8032 case INTRINS_SADD_OVF_I64:
8033 case INTRINS_UADD_OVF_I64:
8034 case INTRINS_SSUB_OVF_I64:
8035 case INTRINS_USUB_OVF_I64:
8036 case INTRINS_SMUL_OVF_I64:
8037 case INTRINS_UMUL_OVF_I64: {
8038 LLVMTypeRef ovf_res_i64 [] = { LLVMInt64Type (), LLVMInt1Type () };
8039 LLVMTypeRef params [] = { LLVMInt64Type (), LLVMInt64Type () };
8040 LLVMTypeRef ret_type = LLVMStructType (ovf_res_i64, 2, FALSE);
8042 AddFunc (module, name, ret_type, params, 2);
8048 case INTRINS_FABS: {
8049 LLVMTypeRef params [] = { LLVMDoubleType () };
8051 AddFunc (module, name, LLVMDoubleType (), params, 1);
8054 case INTRINS_EXPECT_I8:
8055 AddFunc2 (module, name, LLVMInt8Type (), LLVMInt8Type (), LLVMInt8Type ());
8057 case INTRINS_EXPECT_I1:
8058 AddFunc2 (module, name, LLVMInt1Type (), LLVMInt1Type (), LLVMInt1Type ());
8060 #if defined(TARGET_AMD64) || defined(TARGET_X86)
8061 case INTRINS_SSE_PMOVMSKB:
8063 ret_type = LLVMInt32Type ();
8064 arg_types [0] = type_to_simd_type (MONO_TYPE_I1);
8065 AddFunc (module, name, ret_type, arg_types, 1);
8067 case INTRINS_SSE_PSRLI_W:
8068 case INTRINS_SSE_PSRAI_W:
8069 case INTRINS_SSE_PSLLI_W:
8071 ret_type = type_to_simd_type (MONO_TYPE_I2);
8072 arg_types [0] = ret_type;
8073 arg_types [1] = LLVMInt32Type ();
8074 AddFunc (module, name, ret_type, arg_types, 2);
8076 case INTRINS_SSE_PSRLI_D:
8077 case INTRINS_SSE_PSRAI_D:
8078 case INTRINS_SSE_PSLLI_D:
8079 ret_type = type_to_simd_type (MONO_TYPE_I4);
8080 arg_types [0] = ret_type;
8081 arg_types [1] = LLVMInt32Type ();
8082 AddFunc (module, name, ret_type, arg_types, 2);
8084 case INTRINS_SSE_PSRLI_Q:
8085 case INTRINS_SSE_PSLLI_Q:
8086 ret_type = type_to_simd_type (MONO_TYPE_I8);
8087 arg_types [0] = ret_type;
8088 arg_types [1] = LLVMInt32Type ();
8089 AddFunc (module, name, ret_type, arg_types, 2);
8091 case INTRINS_SSE_SQRT_PD:
8093 ret_type = type_to_simd_type (MONO_TYPE_R8);
8094 arg_types [0] = ret_type;
8095 AddFunc (module, name, ret_type, arg_types, 1);
8097 case INTRINS_SSE_SQRT_PS:
8098 ret_type = type_to_simd_type (MONO_TYPE_R4);
8099 arg_types [0] = ret_type;
8100 AddFunc (module, name, ret_type, arg_types, 1);
8102 case INTRINS_SSE_RSQRT_PS:
8103 ret_type = type_to_simd_type (MONO_TYPE_R4);
8104 arg_types [0] = ret_type;
8105 AddFunc (module, name, ret_type, arg_types, 1);
8107 case INTRINS_SSE_RCP_PS:
8108 ret_type = type_to_simd_type (MONO_TYPE_R4);
8109 arg_types [0] = ret_type;
8110 AddFunc (module, name, ret_type, arg_types, 1);
8112 case INTRINS_SSE_CVTTPD2DQ:
8113 ret_type = type_to_simd_type (MONO_TYPE_I4);
8114 arg_types [0] = type_to_simd_type (MONO_TYPE_R8);
8115 AddFunc (module, name, ret_type, arg_types, 1);
8117 case INTRINS_SSE_CVTTPS2DQ:
8118 ret_type = type_to_simd_type (MONO_TYPE_I4);
8119 arg_types [0] = type_to_simd_type (MONO_TYPE_R4);
8120 AddFunc (module, name, ret_type, arg_types, 1);
8122 case INTRINS_SSE_CVTDQ2PD:
8123 /* Conversion ops */
8124 ret_type = type_to_simd_type (MONO_TYPE_R8);
8125 arg_types [0] = type_to_simd_type (MONO_TYPE_I4);
8126 AddFunc (module, name, ret_type, arg_types, 1);
8128 case INTRINS_SSE_CVTDQ2PS:
8129 ret_type = type_to_simd_type (MONO_TYPE_R4);
8130 arg_types [0] = type_to_simd_type (MONO_TYPE_I4);
8131 AddFunc (module, name, ret_type, arg_types, 1);
8133 case INTRINS_SSE_CVTPD2DQ:
8134 ret_type = type_to_simd_type (MONO_TYPE_I4);
8135 arg_types [0] = type_to_simd_type (MONO_TYPE_R8);
8136 AddFunc (module, name, ret_type, arg_types, 1);
8138 case INTRINS_SSE_CVTPS2DQ:
8139 ret_type = type_to_simd_type (MONO_TYPE_I4);
8140 arg_types [0] = type_to_simd_type (MONO_TYPE_R4);
8141 AddFunc (module, name, ret_type, arg_types, 1);
8143 case INTRINS_SSE_CVTPD2PS:
8144 ret_type = type_to_simd_type (MONO_TYPE_R4);
8145 arg_types [0] = type_to_simd_type (MONO_TYPE_R8);
8146 AddFunc (module, name, ret_type, arg_types, 1);
8148 case INTRINS_SSE_CVTPS2PD:
8149 ret_type = type_to_simd_type (MONO_TYPE_R8);
8150 arg_types [0] = type_to_simd_type (MONO_TYPE_R4);
8151 AddFunc (module, name, ret_type, arg_types, 1);
8153 case INTRINS_SSE_CMPPD:
8155 ret_type = type_to_simd_type (MONO_TYPE_R8);
8156 arg_types [0] = ret_type;
8157 arg_types [1] = ret_type;
8158 arg_types [2] = LLVMInt8Type ();
8159 AddFunc (module, name, ret_type, arg_types, 3);
8161 case INTRINS_SSE_CMPPS:
8162 ret_type = type_to_simd_type (MONO_TYPE_R4);
8163 arg_types [0] = ret_type;
8164 arg_types [1] = ret_type;
8165 arg_types [2] = LLVMInt8Type ();
8166 AddFunc (module, name, ret_type, arg_types, 3);
8168 case INTRINS_SSE_PACKSSWB:
8169 case INTRINS_SSE_PACKUSWB:
8170 case INTRINS_SSE_PACKSSDW:
8172 ret_type = type_to_simd_type (MONO_TYPE_I1);
8173 arg_types [0] = type_to_simd_type (MONO_TYPE_I2);
8174 arg_types [1] = type_to_simd_type (MONO_TYPE_I2);
8175 AddFunc (module, name, ret_type, arg_types, 2);
8177 case INTRINS_SSE_PACKUSDW:
8178 ret_type = type_to_simd_type (MONO_TYPE_I2);
8179 arg_types [0] = type_to_simd_type (MONO_TYPE_I4);
8180 arg_types [1] = type_to_simd_type (MONO_TYPE_I4);
8181 AddFunc (module, name, ret_type, arg_types, 2);
8183 /* SSE Binary ops */
8184 case INTRINS_SSE_PADDSW:
8185 case INTRINS_SSE_PSUBSW:
8186 case INTRINS_SSE_PADDUSW:
8187 case INTRINS_SSE_PSUBUSW:
8188 case INTRINS_SSE_PAVGW:
8189 case INTRINS_SSE_PMULHW:
8190 case INTRINS_SSE_PMULHU:
8191 add_sse_binary (module, name, MONO_TYPE_I2);
8193 case INTRINS_SSE_MINPS:
8194 case INTRINS_SSE_MAXPS:
8195 case INTRINS_SSE_HADDPS:
8196 case INTRINS_SSE_HSUBPS:
8197 case INTRINS_SSE_ADDSUBPS:
8198 add_sse_binary (module, name, MONO_TYPE_R4);
8200 case INTRINS_SSE_MINPD:
8201 case INTRINS_SSE_MAXPD:
8202 case INTRINS_SSE_HADDPD:
8203 case INTRINS_SSE_HSUBPD:
8204 case INTRINS_SSE_ADDSUBPD:
8205 add_sse_binary (module, name, MONO_TYPE_R8);
8207 case INTRINS_SE_PADDSB:
8208 case INTRINS_SSE_PSUBSB:
8209 case INTRINS_SSE_PADDUSB:
8210 case INTRINS_SSE_PSUBUSB:
8211 case INTRINS_SSE_PAVGB:
8212 add_sse_binary (module, name, MONO_TYPE_I1);
8214 case INTRINS_SSE_PAUSE:
8215 AddFunc (module, "llvm.x86.sse2.pause", LLVMVoidType (), NULL, 0);
8217 case INTRINS_SSE_DPPS:
8218 ret_type = type_to_simd_type (MONO_TYPE_R4);
8219 arg_types [0] = type_to_simd_type (MONO_TYPE_R4);
8220 arg_types [1] = type_to_simd_type (MONO_TYPE_R4);
8221 arg_types [2] = LLVMInt32Type ();
8222 AddFunc (module, name, ret_type, arg_types, 3);
8226 g_assert_not_reached ();
8232 get_intrinsic (EmitContext *ctx, const char *name)
8234 #if LLVM_API_VERSION > 100
8238 * Every method is emitted into its own module so
8239 * we can add intrinsics on demand.
8241 res = LLVMGetNamedFunction (ctx->lmodule, name);
8245 /* No locking needed */
8246 id = GPOINTER_TO_INT (g_hash_table_lookup (intrins_name_to_id, name));
8249 printf ("%s\n", name);
8250 g_assert (id != -1);
8251 add_intrinsic (ctx->lmodule, id);
8252 res = LLVMGetNamedFunction (ctx->lmodule, name);
8260 res = LLVMGetNamedFunction (ctx->lmodule, name);
8267 add_intrinsics (LLVMModuleRef module)
8271 /* Emit declarations of instrinsics */
8273 * It would be nicer to emit only the intrinsics actually used, but LLVM's Module
8274 * type doesn't seem to do any locking.
8276 for (i = 0; i < INTRINS_NUM; ++i)
8277 add_intrinsic (module, i);
8281 AddFunc (module, "mono_personality", LLVMVoidType (), NULL, 0);
8283 AddFunc (module, "llvm_resume_unwind_trampoline", LLVMVoidType (), NULL, 0);
8286 /* Load/Store intrinsics */
8288 LLVMTypeRef arg_types [5];
8292 for (i = 1; i <= 8; i *= 2) {
8293 arg_types [0] = LLVMPointerType (LLVMIntType (i * 8), 0);
8294 arg_types [1] = LLVMInt32Type ();
8295 arg_types [2] = LLVMInt1Type ();
8296 arg_types [3] = LLVMInt32Type ();
8297 sprintf (name, "llvm.mono.load.i%d.p0i%d", i * 8, i * 8);
8298 AddFunc (module, name, LLVMIntType (i * 8), arg_types, 4);
8300 arg_types [0] = LLVMIntType (i * 8);
8301 arg_types [1] = LLVMPointerType (LLVMIntType (i * 8), 0);
8302 arg_types [2] = LLVMInt32Type ();
8303 arg_types [3] = LLVMInt1Type ();
8304 arg_types [4] = LLVMInt32Type ();
8305 sprintf (name, "llvm.mono.store.i%d.p0i%d", i * 8, i * 8);
8306 AddFunc (module, name, LLVMVoidType (), arg_types, 5);
8312 add_types (MonoLLVMModule *module)
8314 module->ptr_type = LLVMPointerType (sizeof (gpointer) == 8 ? LLVMInt64Type () : LLVMInt32Type (), 0);
8318 mono_llvm_init (void)
8323 mono_native_tls_alloc (¤t_cfg_tls_id, NULL);
8325 h = g_hash_table_new (NULL, NULL);
8326 for (i = 0; i < INTRINS_NUM; ++i)
8327 g_hash_table_insert (h, GINT_TO_POINTER (intrinsics [i].id), (gpointer)intrinsics [i].name);
8328 intrins_id_to_name = h;
8330 h = g_hash_table_new (g_str_hash, g_str_equal);
8331 for (i = 0; i < INTRINS_NUM; ++i)
8332 g_hash_table_insert (h, (gpointer)intrinsics [i].name, GINT_TO_POINTER (intrinsics [i].id + 1));
8333 intrins_name_to_id = h;
8337 init_jit_module (MonoDomain *domain)
8339 MonoJitDomainInfo *dinfo;
8340 MonoLLVMModule *module;
8343 dinfo = domain_jit_info (domain);
8344 if (dinfo->llvm_module)
8347 mono_loader_lock ();
8349 if (dinfo->llvm_module) {
8350 mono_loader_unlock ();
8354 module = g_new0 (MonoLLVMModule, 1);
8356 name = g_strdup_printf ("mono-%s", domain->friendly_name);
8357 module->lmodule = LLVMModuleCreateWithName (name);
8358 module->context = LLVMGetGlobalContext ();
8360 module->mono_ee = (MonoEERef*)mono_llvm_create_ee (LLVMCreateModuleProviderForExistingModule (module->lmodule), alloc_cb, emitted_cb, exception_cb, dlsym_cb, &module->ee);
8362 add_intrinsics (module->lmodule);
8365 module->llvm_types = g_hash_table_new (NULL, NULL);
8367 #if LLVM_API_VERSION < 100
8368 MonoJitICallInfo *info;
8370 info = mono_find_jit_icall_by_name ("llvm_resume_unwind_trampoline");
8372 LLVMAddGlobalMapping (module->ee, LLVMGetNamedFunction (module->lmodule, "llvm_resume_unwind_trampoline"), (void*)info->func);
8375 mono_memory_barrier ();
8377 dinfo->llvm_module = module;
8379 mono_loader_unlock ();
8383 mono_llvm_cleanup (void)
8385 MonoLLVMModule *module = &aot_module;
8387 if (module->lmodule)
8388 LLVMDisposeModule (module->lmodule);
8390 if (module->context)
8391 LLVMContextDispose (module->context);
8395 mono_llvm_free_domain_info (MonoDomain *domain)
8397 MonoJitDomainInfo *info = domain_jit_info (domain);
8398 MonoLLVMModule *module = (MonoLLVMModule*)info->llvm_module;
8404 if (module->llvm_types)
8405 g_hash_table_destroy (module->llvm_types);
8407 mono_llvm_dispose_ee (module->mono_ee);
8409 if (module->bb_names) {
8410 for (i = 0; i < module->bb_names_len; ++i)
8411 g_free (module->bb_names [i]);
8412 g_free (module->bb_names);
8414 //LLVMDisposeModule (module->module);
8418 info->llvm_module = NULL;
8422 mono_llvm_create_aot_module (MonoAssembly *assembly, const char *global_prefix, gboolean emit_dwarf, gboolean static_link, gboolean llvm_only)
8424 MonoLLVMModule *module = &aot_module;
8426 /* Delete previous module */
8427 if (module->plt_entries)
8428 g_hash_table_destroy (module->plt_entries);
8429 if (module->lmodule)
8430 LLVMDisposeModule (module->lmodule);
8432 memset (module, 0, sizeof (aot_module));
8434 module->lmodule = LLVMModuleCreateWithName ("aot");
8435 module->assembly = assembly;
8436 module->global_prefix = g_strdup (global_prefix);
8437 module->got_symbol = g_strdup_printf ("%s_llvm_got", global_prefix);
8438 module->eh_frame_symbol = g_strdup_printf ("%s_eh_frame", global_prefix);
8439 module->get_method_symbol = g_strdup_printf ("%s_get_method", global_prefix);
8440 module->get_unbox_tramp_symbol = g_strdup_printf ("%s_get_unbox_tramp", global_prefix);
8441 module->external_symbols = TRUE;
8442 module->emit_dwarf = emit_dwarf;
8443 module->static_link = static_link;
8444 module->llvm_only = llvm_only;
8445 /* The first few entries are reserved */
8446 module->max_got_offset = 16;
8447 module->context = LLVMGetGlobalContext ();
8450 /* clang ignores our debug info because it has an invalid version */
8451 module->emit_dwarf = FALSE;
8453 add_intrinsics (module->lmodule);
8456 #if LLVM_API_VERSION > 100
8457 if (module->emit_dwarf) {
8458 char *dir, *build_info, *s, *cu_name;
8460 module->di_builder = mono_llvm_create_di_builder (module->lmodule);
8463 dir = g_strdup (".");
8464 build_info = mono_get_runtime_build_info ();
8465 s = g_strdup_printf ("Mono AOT Compiler %s (LLVM)", build_info);
8466 cu_name = g_path_get_basename (assembly->image->name);
8467 module->cu = mono_llvm_di_create_compile_unit (module->di_builder, cu_name, dir, s);
8469 g_free (build_info);
8476 * We couldn't compute the type of the LLVM global representing the got because
8477 * its size is only known after all the methods have been emitted. So create
8478 * a dummy variable, and replace all uses it with the real got variable when
8479 * its size is known in mono_llvm_emit_aot_module ().
8482 LLVMTypeRef got_type = LLVMArrayType (module->ptr_type, 0);
8484 module->got_var = LLVMAddGlobal (module->lmodule, got_type, "mono_dummy_got");
8485 LLVMSetInitializer (module->got_var, LLVMConstNull (got_type));
8488 /* Add initialization array */
8490 LLVMTypeRef inited_type = LLVMArrayType (LLVMInt8Type (), 0);
8492 module->inited_var = LLVMAddGlobal (aot_module.lmodule, inited_type, "mono_inited_tmp");
8493 LLVMSetInitializer (module->inited_var, LLVMConstNull (inited_type));
8497 emit_init_icall_wrappers (module);
8499 emit_llvm_code_start (module);
8501 /* Add a dummy personality function */
8502 if (!use_debug_personality) {
8503 LLVMValueRef personality = LLVMAddFunction (module->lmodule, default_personality_name, LLVMFunctionType (LLVMInt32Type (), NULL, 0, TRUE));
8504 LLVMSetLinkage (personality, LLVMExternalLinkage);
8505 mark_as_used (module, personality);
8508 /* Add a reference to the c++ exception we throw/catch */
8510 LLVMTypeRef exc = LLVMPointerType (LLVMInt8Type (), 0);
8511 module->sentinel_exception = LLVMAddGlobal (module->lmodule, exc, "_ZTIPi");
8512 LLVMSetLinkage (module->sentinel_exception, LLVMExternalLinkage);
8513 mono_llvm_set_is_constant (module->sentinel_exception);
8516 module->llvm_types = g_hash_table_new (NULL, NULL);
8517 module->plt_entries = g_hash_table_new (g_str_hash, g_str_equal);
8518 module->plt_entries_ji = g_hash_table_new (NULL, NULL);
8519 module->direct_callables = g_hash_table_new (g_str_hash, g_str_equal);
8520 module->method_to_lmethod = g_hash_table_new (NULL, NULL);
8521 module->idx_to_lmethod = g_hash_table_new (NULL, NULL);
8522 module->idx_to_unbox_tramp = g_hash_table_new (NULL, NULL);
8523 module->method_to_callers = g_hash_table_new (NULL, NULL);
8527 llvm_array_from_uints (LLVMTypeRef el_type, guint32 *values, int nvalues)
8530 LLVMValueRef res, *vals;
8532 vals = g_new0 (LLVMValueRef, nvalues);
8533 for (i = 0; i < nvalues; ++i)
8534 vals [i] = LLVMConstInt (LLVMInt32Type (), values [i], FALSE);
8535 res = LLVMConstArray (LLVMInt32Type (), vals, nvalues);
8541 llvm_array_from_bytes (guint8 *values, int nvalues)
8544 LLVMValueRef res, *vals;
8546 vals = g_new0 (LLVMValueRef, nvalues);
8547 for (i = 0; i < nvalues; ++i)
8548 vals [i] = LLVMConstInt (LLVMInt8Type (), values [i], FALSE);
8549 res = LLVMConstArray (LLVMInt8Type (), vals, nvalues);
8554 * mono_llvm_emit_aot_file_info:
8556 * Emit the MonoAotFileInfo structure.
8557 * Same as emit_aot_file_info () in aot-compiler.c.
8560 mono_llvm_emit_aot_file_info (MonoAotFileInfo *info, gboolean has_jitted_code)
8562 MonoLLVMModule *module = &aot_module;
8564 /* Save these for later */
8565 memcpy (&module->aot_info, info, sizeof (MonoAotFileInfo));
8566 module->has_jitted_code = has_jitted_code;
8570 * mono_llvm_emit_aot_data:
8572 * Emit the binary data DATA pointed to by symbol SYMBOL.
8575 mono_llvm_emit_aot_data (const char *symbol, guint8 *data, int data_len)
8577 MonoLLVMModule *module = &aot_module;
8581 type = LLVMArrayType (LLVMInt8Type (), data_len);
8582 d = LLVMAddGlobal (module->lmodule, type, symbol);
8583 LLVMSetVisibility (d, LLVMHiddenVisibility);
8584 LLVMSetLinkage (d, LLVMInternalLinkage);
8585 LLVMSetInitializer (d, mono_llvm_create_constant_data_array (data, data_len));
8586 mono_llvm_set_is_constant (d);
8589 /* Add a reference to a global defined in JITted code */
8591 AddJitGlobal (MonoLLVMModule *module, LLVMTypeRef type, const char *name)
8596 s = g_strdup_printf ("%s%s", module->global_prefix, name);
8597 v = LLVMAddGlobal (module->lmodule, LLVMInt8Type (), s);
8603 emit_aot_file_info (MonoLLVMModule *module)
8605 LLVMTypeRef file_info_type;
8606 LLVMTypeRef *eltypes, eltype;
8607 LLVMValueRef info_var;
8608 LLVMValueRef *fields;
8609 int i, nfields, tindex;
8610 MonoAotFileInfo *info;
8611 LLVMModuleRef lmodule = module->lmodule;
8613 info = &module->aot_info;
8615 /* Create an LLVM type to represent MonoAotFileInfo */
8616 nfields = 2 + MONO_AOT_FILE_INFO_NUM_SYMBOLS + 16 + 5;
8617 eltypes = g_new (LLVMTypeRef, nfields);
8619 eltypes [tindex ++] = LLVMInt32Type ();
8620 eltypes [tindex ++] = LLVMInt32Type ();
8622 for (i = 0; i < MONO_AOT_FILE_INFO_NUM_SYMBOLS; ++i)
8623 eltypes [tindex ++] = LLVMPointerType (LLVMInt8Type (), 0);
8625 for (i = 0; i < 15; ++i)
8626 eltypes [tindex ++] = LLVMInt32Type ();
8628 eltypes [tindex ++] = LLVMArrayType (LLVMInt32Type (), MONO_AOT_TABLE_NUM);
8629 for (i = 0; i < 4; ++i)
8630 eltypes [tindex ++] = LLVMArrayType (LLVMInt32Type (), MONO_AOT_TRAMP_NUM);
8631 eltypes [tindex ++] = LLVMArrayType (LLVMInt8Type (), 16);
8632 g_assert (tindex == nfields);
8633 file_info_type = LLVMStructCreateNamed (module->context, "MonoAotFileInfo");
8634 LLVMStructSetBody (file_info_type, eltypes, nfields, FALSE);
8636 info_var = LLVMAddGlobal (lmodule, file_info_type, "mono_aot_file_info");
8637 if (module->static_link) {
8638 LLVMSetVisibility (info_var, LLVMHiddenVisibility);
8639 LLVMSetLinkage (info_var, LLVMInternalLinkage);
8641 fields = g_new (LLVMValueRef, nfields);
8643 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->version, FALSE);
8644 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->dummy, FALSE);
8648 * We use LLVMGetNamedGlobal () for symbol which are defined in LLVM code, and LLVMAddGlobal ()
8649 * for symbols defined in the .s file emitted by the aot compiler.
8651 eltype = eltypes [tindex];
8652 if (module->llvm_only)
8653 fields [tindex ++] = LLVMConstNull (eltype);
8655 fields [tindex ++] = AddJitGlobal (module, eltype, "jit_got");
8656 fields [tindex ++] = module->got_var;
8657 /* llc defines this directly */
8658 if (!module->llvm_only) {
8659 fields [tindex ++] = LLVMAddGlobal (lmodule, eltype, module->eh_frame_symbol);
8660 fields [tindex ++] = LLVMConstNull (eltype);
8661 fields [tindex ++] = LLVMConstNull (eltype);
8663 fields [tindex ++] = LLVMConstNull (eltype);
8664 fields [tindex ++] = module->get_method;
8665 fields [tindex ++] = module->get_unbox_tramp;
8667 if (module->has_jitted_code) {
8668 fields [tindex ++] = AddJitGlobal (module, eltype, "jit_code_start");
8669 fields [tindex ++] = AddJitGlobal (module, eltype, "jit_code_end");
8671 fields [tindex ++] = LLVMConstNull (eltype);
8672 fields [tindex ++] = LLVMConstNull (eltype);
8674 if (!module->llvm_only)
8675 fields [tindex ++] = AddJitGlobal (module, eltype, "method_addresses");
8677 fields [tindex ++] = LLVMConstNull (eltype);
8678 if (info->flags & MONO_AOT_FILE_FLAG_SEPARATE_DATA) {
8679 for (i = 0; i < MONO_AOT_TABLE_NUM; ++i)
8680 fields [tindex ++] = LLVMConstNull (eltype);
8682 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "blob");
8683 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "class_name_table");
8684 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "class_info_offsets");
8685 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "method_info_offsets");
8686 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "ex_info_offsets");
8687 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "extra_method_info_offsets");
8688 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "extra_method_table");
8689 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "got_info_offsets");
8690 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "llvm_got_info_offsets");
8691 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "image_table");
8693 /* Not needed (mem_end) */
8694 fields [tindex ++] = LLVMConstNull (eltype);
8695 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "assembly_guid");
8696 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "runtime_version");
8697 if (info->trampoline_size [0]) {
8698 fields [tindex ++] = AddJitGlobal (module, eltype, "specific_trampolines");
8699 fields [tindex ++] = AddJitGlobal (module, eltype, "static_rgctx_trampolines");
8700 fields [tindex ++] = AddJitGlobal (module, eltype, "imt_trampolines");
8701 fields [tindex ++] = AddJitGlobal (module, eltype, "gsharedvt_arg_trampolines");
8703 fields [tindex ++] = LLVMConstNull (eltype);
8704 fields [tindex ++] = LLVMConstNull (eltype);
8705 fields [tindex ++] = LLVMConstNull (eltype);
8706 fields [tindex ++] = LLVMConstNull (eltype);
8708 if (module->static_link && !module->llvm_only)
8709 fields [tindex ++] = AddJitGlobal (module, eltype, "globals");
8711 fields [tindex ++] = LLVMConstNull (eltype);
8712 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "assembly_name");
8713 if (!module->llvm_only) {
8714 fields [tindex ++] = AddJitGlobal (module, eltype, "plt");
8715 fields [tindex ++] = AddJitGlobal (module, eltype, "plt_end");
8716 fields [tindex ++] = AddJitGlobal (module, eltype, "unwind_info");
8717 fields [tindex ++] = AddJitGlobal (module, eltype, "unbox_trampolines");
8718 fields [tindex ++] = AddJitGlobal (module, eltype, "unbox_trampolines_end");
8719 fields [tindex ++] = AddJitGlobal (module, eltype, "unbox_trampoline_addresses");
8721 fields [tindex ++] = LLVMConstNull (eltype);
8722 fields [tindex ++] = LLVMConstNull (eltype);
8723 fields [tindex ++] = LLVMConstNull (eltype);
8724 fields [tindex ++] = LLVMConstNull (eltype);
8725 fields [tindex ++] = LLVMConstNull (eltype);
8726 fields [tindex ++] = LLVMConstNull (eltype);
8729 for (i = 0; i < MONO_AOT_FILE_INFO_NUM_SYMBOLS; ++i)
8730 fields [2 + i] = LLVMConstBitCast (fields [2 + i], eltype);
8733 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->plt_got_offset_base, FALSE);
8734 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->got_size, FALSE);
8735 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->plt_size, FALSE);
8736 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->nmethods, FALSE);
8737 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->flags, FALSE);
8738 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->opts, FALSE);
8739 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->simd_opts, FALSE);
8740 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->gc_name_index, FALSE);
8741 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->num_rgctx_fetch_trampolines, FALSE);
8742 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->double_align, FALSE);
8743 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->long_align, FALSE);
8744 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->generic_tramp_num, FALSE);
8745 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->tramp_page_size, FALSE);
8746 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->nshared_got_entries, FALSE);
8747 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->datafile_size, FALSE);
8749 fields [tindex ++] = llvm_array_from_uints (LLVMInt32Type (), info->table_offsets, MONO_AOT_TABLE_NUM);
8750 fields [tindex ++] = llvm_array_from_uints (LLVMInt32Type (), info->num_trampolines, MONO_AOT_TRAMP_NUM);
8751 fields [tindex ++] = llvm_array_from_uints (LLVMInt32Type (), info->trampoline_got_offset_base, MONO_AOT_TRAMP_NUM);
8752 fields [tindex ++] = llvm_array_from_uints (LLVMInt32Type (), info->trampoline_size, MONO_AOT_TRAMP_NUM);
8753 fields [tindex ++] = llvm_array_from_uints (LLVMInt32Type (), info->tramp_page_code_offsets, MONO_AOT_TRAMP_NUM);
8755 fields [tindex ++] = llvm_array_from_bytes (info->aotid, 16);
8756 g_assert (tindex == nfields);
8758 LLVMSetInitializer (info_var, LLVMConstNamedStruct (file_info_type, fields, nfields));
8760 if (module->static_link) {
8764 s = g_strdup_printf ("mono_aot_module_%s_info", module->assembly->aname.name);
8765 /* Get rid of characters which cannot occur in symbols */
8767 for (p = s; *p; ++p) {
8768 if (!(isalnum (*p) || *p == '_'))
8771 var = LLVMAddGlobal (module->lmodule, LLVMPointerType (LLVMInt8Type (), 0), s);
8773 LLVMSetInitializer (var, LLVMConstBitCast (LLVMGetNamedGlobal (module->lmodule, "mono_aot_file_info"), LLVMPointerType (LLVMInt8Type (), 0)));
8774 LLVMSetLinkage (var, LLVMExternalLinkage);
8779 * Emit the aot module into the LLVM bitcode file FILENAME.
8782 mono_llvm_emit_aot_module (const char *filename, const char *cu_name)
8784 LLVMTypeRef got_type, inited_type;
8785 LLVMValueRef real_got, real_inited;
8786 MonoLLVMModule *module = &aot_module;
8788 emit_llvm_code_end (module);
8791 * Create the real got variable and replace all uses of the dummy variable with
8794 got_type = LLVMArrayType (module->ptr_type, module->max_got_offset + 1);
8795 real_got = LLVMAddGlobal (module->lmodule, got_type, module->got_symbol);
8796 LLVMSetInitializer (real_got, LLVMConstNull (got_type));
8797 if (module->external_symbols) {
8798 LLVMSetLinkage (real_got, LLVMExternalLinkage);
8799 LLVMSetVisibility (real_got, LLVMHiddenVisibility);
8801 LLVMSetLinkage (real_got, LLVMInternalLinkage);
8803 mono_llvm_replace_uses_of (module->got_var, real_got);
8805 mark_as_used (&aot_module, real_got);
8807 /* Delete the dummy got so it doesn't become a global */
8808 LLVMDeleteGlobal (module->got_var);
8809 module->got_var = real_got;
8812 * Same for the init_var
8814 if (module->llvm_only) {
8815 inited_type = LLVMArrayType (LLVMInt8Type (), module->max_inited_idx + 1);
8816 real_inited = LLVMAddGlobal (module->lmodule, inited_type, "mono_inited");
8817 LLVMSetInitializer (real_inited, LLVMConstNull (inited_type));
8818 LLVMSetLinkage (real_inited, LLVMInternalLinkage);
8819 mono_llvm_replace_uses_of (module->inited_var, real_inited);
8820 LLVMDeleteGlobal (module->inited_var);
8823 if (module->llvm_only) {
8824 emit_get_method (&aot_module);
8825 emit_get_unbox_tramp (&aot_module);
8828 emit_llvm_used (&aot_module);
8829 emit_dbg_info (&aot_module, filename, cu_name);
8830 emit_aot_file_info (&aot_module);
8833 * Replace GOT entries for directly callable methods with the methods themselves.
8834 * It would be easier to implement this by predefining all methods before compiling
8835 * their bodies, but that couldn't handle the case when a method fails to compile
8838 if (module->llvm_only) {
8839 GHashTableIter iter;
8841 GSList *callers, *l;
8843 g_hash_table_iter_init (&iter, module->method_to_callers);
8844 while (g_hash_table_iter_next (&iter, (void**)&method, (void**)&callers)) {
8845 LLVMValueRef lmethod;
8847 if (method->iflags & METHOD_IMPL_ATTRIBUTE_SYNCHRONIZED)
8850 lmethod = (LLVMValueRef)g_hash_table_lookup (module->method_to_lmethod, method);
8852 for (l = callers; l; l = l->next) {
8853 LLVMValueRef caller = (LLVMValueRef)l->data;
8855 mono_llvm_replace_uses_of (caller, lmethod);
8861 /* Replace PLT entries for directly callable methods with the methods themselves */
8863 GHashTableIter iter;
8865 LLVMValueRef callee;
8867 g_hash_table_iter_init (&iter, module->plt_entries_ji);
8868 while (g_hash_table_iter_next (&iter, (void**)&ji, (void**)&callee)) {
8869 if (mono_aot_is_direct_callable (ji)) {
8870 LLVMValueRef lmethod;
8872 lmethod = (LLVMValueRef)g_hash_table_lookup (module->method_to_lmethod, ji->data.method);
8873 /* The types might not match because the caller might pass an rgctx */
8874 if (lmethod && LLVMTypeOf (callee) == LLVMTypeOf (lmethod)) {
8875 mono_llvm_replace_uses_of (callee, lmethod);
8876 mono_aot_mark_unused_llvm_plt_entry (ji);
8886 if (LLVMVerifyModule (module->lmodule, LLVMReturnStatusAction, &verifier_err)) {
8887 printf ("%s\n", verifier_err);
8888 g_assert_not_reached ();
8893 LLVMWriteBitcodeToFile (module->lmodule, filename);
8898 md_string (const char *s)
8900 return LLVMMDString (s, strlen (s));
8903 /* Debugging support */
8906 emit_dbg_info (MonoLLVMModule *module, const char *filename, const char *cu_name)
8908 LLVMModuleRef lmodule = module->lmodule;
8909 LLVMValueRef args [16], ver;
8912 * This can only be enabled when LLVM code is emitted into a separate object
8913 * file, since the AOT compiler also emits dwarf info,
8914 * and the abbrev indexes will not be correct since llvm has added its own
8917 if (!module->emit_dwarf)
8920 #if LLVM_API_VERSION > 100
8921 mono_llvm_di_builder_finalize (module->di_builder);
8923 LLVMValueRef cu_args [16], cu;
8925 char *build_info, *s, *dir;
8928 * Emit dwarf info in the form of LLVM metadata. There is some
8929 * out-of-date documentation at:
8930 * http://llvm.org/docs/SourceLevelDebugging.html
8931 * but most of this was gathered from the llvm and
8936 cu_args [n_cuargs ++] = LLVMConstInt (LLVMInt32Type (), DW_TAG_compile_unit, FALSE);
8937 /* CU name/compilation dir */
8938 dir = g_path_get_dirname (filename);
8939 args [0] = LLVMMDString (cu_name, strlen (cu_name));
8940 args [1] = LLVMMDString (dir, strlen (dir));
8941 cu_args [n_cuargs ++] = LLVMMDNode (args, 2);
8944 cu_args [n_cuargs ++] = LLVMConstInt (LLVMInt32Type (), DW_LANG_C99, FALSE);
8946 build_info = mono_get_runtime_build_info ();
8947 s = g_strdup_printf ("Mono AOT Compiler %s (LLVM)", build_info);
8948 cu_args [n_cuargs ++] = LLVMMDString (s, strlen (s));
8949 g_free (build_info);
8951 cu_args [n_cuargs ++] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
8953 cu_args [n_cuargs ++] = LLVMMDString ("", strlen (""));
8954 /* Runtime version */
8955 cu_args [n_cuargs ++] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
8957 cu_args [n_cuargs ++] = LLVMMDNode (args, 0);
8958 cu_args [n_cuargs ++] = LLVMMDNode (args, 0);
8960 if (module->subprogram_mds) {
8964 mds = g_new0 (LLVMValueRef, module->subprogram_mds->len);
8965 for (i = 0; i < module->subprogram_mds->len; ++i)
8966 mds [i] = (LLVMValueRef)g_ptr_array_index (module->subprogram_mds, i);
8967 cu_args [n_cuargs ++] = LLVMMDNode (mds, module->subprogram_mds->len);
8969 cu_args [n_cuargs ++] = LLVMMDNode (args, 0);
8972 cu_args [n_cuargs ++] = LLVMMDNode (args, 0);
8973 /* Imported modules */
8974 cu_args [n_cuargs ++] = LLVMMDNode (args, 0);
8976 cu_args [n_cuargs ++] = LLVMMDString ("", strlen (""));
8977 /* DebugEmissionKind = FullDebug */
8978 cu_args [n_cuargs ++] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
8979 cu = LLVMMDNode (cu_args, n_cuargs);
8980 LLVMAddNamedMetadataOperand (lmodule, "llvm.dbg.cu", cu);
8983 #if LLVM_API_VERSION > 100
8984 args [0] = LLVMConstInt (LLVMInt32Type (), 2, FALSE);
8985 args [1] = LLVMMDString ("Dwarf Version", strlen ("Dwarf Version"));
8986 args [2] = LLVMConstInt (LLVMInt32Type (), 2, FALSE);
8987 ver = LLVMMDNode (args, 3);
8988 LLVMAddNamedMetadataOperand (lmodule, "llvm.module.flags", ver);
8990 args [0] = LLVMConstInt (LLVMInt32Type (), 2, FALSE);
8991 args [1] = LLVMMDString ("Debug Info Version", strlen ("Debug Info Version"));
8992 args [2] = LLVMConstInt (LLVMInt64Type (), 3, FALSE);
8993 ver = LLVMMDNode (args, 3);
8994 LLVMAddNamedMetadataOperand (lmodule, "llvm.module.flags", ver);
8996 args [0] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
8997 args [1] = LLVMMDString ("Dwarf Version", strlen ("Dwarf Version"));
8998 args [2] = LLVMConstInt (LLVMInt32Type (), 2, FALSE);
8999 ver = LLVMMDNode (args, 3);
9000 LLVMAddNamedMetadataOperand (lmodule, "llvm.module.flags", ver);
9002 args [0] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
9003 args [1] = LLVMMDString ("Debug Info Version", strlen ("Debug Info Version"));
9004 args [2] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
9005 ver = LLVMMDNode (args, 3);
9006 LLVMAddNamedMetadataOperand (lmodule, "llvm.module.flags", ver);
9011 emit_dbg_subprogram (EmitContext *ctx, MonoCompile *cfg, LLVMValueRef method, const char *name)
9013 MonoLLVMModule *module = ctx->module;
9014 MonoDebugMethodInfo *minfo = ctx->minfo;
9015 char *source_file, *dir, *filename;
9016 LLVMValueRef md, args [16], ctx_args [16], md_args [64], type_args [16], ctx_md, type_md;
9017 MonoSymSeqPoint *sym_seq_points;
9023 mono_debug_symfile_get_seq_points (minfo, &source_file, NULL, NULL, &sym_seq_points, &n_seq_points);
9025 source_file = g_strdup ("<unknown>");
9026 dir = g_path_get_dirname (source_file);
9027 filename = g_path_get_basename (source_file);
9029 #if LLVM_API_VERSION > 100
9030 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);
9033 ctx_args [0] = LLVMConstInt (LLVMInt32Type (), 0x29, FALSE);
9034 args [0] = md_string (filename);
9035 args [1] = md_string (dir);
9036 ctx_args [1] = LLVMMDNode (args, 2);
9037 ctx_md = LLVMMDNode (ctx_args, 2);
9039 type_args [0] = LLVMConstInt (LLVMInt32Type (), DW_TAG_subroutine_type, FALSE);
9040 type_args [1] = NULL;
9041 type_args [2] = NULL;
9042 type_args [3] = LLVMMDString ("", 0);
9043 type_args [4] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
9044 type_args [5] = LLVMConstInt (LLVMInt64Type (), 0, FALSE);
9045 type_args [6] = LLVMConstInt (LLVMInt64Type (), 0, FALSE);
9046 type_args [7] = LLVMConstInt (LLVMInt64Type (), 0, FALSE);
9047 type_args [8] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
9048 type_args [9] = NULL;
9049 type_args [10] = NULL;
9050 type_args [11] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
9051 type_args [12] = NULL;
9052 type_args [13] = NULL;
9053 type_args [14] = NULL;
9054 type_md = LLVMMDNode (type_args, 14);
9056 /* http://llvm.org/docs/SourceLevelDebugging.html#subprogram-descriptors */
9057 md_args [0] = LLVMConstInt (LLVMInt32Type (), DW_TAG_subprogram, FALSE);
9058 /* Source directory + file pair */
9059 args [0] = md_string (filename);
9060 args [1] = md_string (dir);
9061 md_args [1] = LLVMMDNode (args ,2);
9062 md_args [2] = ctx_md;
9063 md_args [3] = md_string (cfg->method->name);
9064 md_args [4] = md_string (name);
9065 md_args [5] = md_string (name);
9068 md_args [6] = LLVMConstInt (LLVMInt32Type (), sym_seq_points [0].line, FALSE);
9070 md_args [6] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
9072 md_args [7] = type_md;
9074 md_args [8] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
9076 md_args [9] = LLVMConstInt (LLVMInt1Type (), 1, FALSE);
9078 md_args [10] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
9079 /* Index into a virtual function */
9080 md_args [11] = NULL;
9081 md_args [12] = NULL;
9083 md_args [13] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
9085 md_args [14] = LLVMConstInt (LLVMInt1Type (), 1, FALSE);
9086 /* Pointer to LLVM function */
9087 md_args [15] = method;
9088 /* Function template parameter */
9089 md_args [16] = NULL;
9090 /* Function declaration descriptor */
9091 md_args [17] = NULL;
9092 /* List of function variables */
9093 md_args [18] = LLVMMDNode (args, 0);
9095 md_args [19] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
9096 md = LLVMMDNode (md_args, 20);
9098 if (!module->subprogram_mds)
9099 module->subprogram_mds = g_ptr_array_new ();
9100 g_ptr_array_add (module->subprogram_mds, md);
9104 g_free (source_file);
9105 g_free (sym_seq_points);
9111 emit_dbg_loc (EmitContext *ctx, LLVMBuilderRef builder, const unsigned char *cil_code)
9113 MonoCompile *cfg = ctx->cfg;
9115 if (ctx->minfo && cil_code && cil_code >= cfg->header->code && cil_code < cfg->header->code + cfg->header->code_size) {
9116 MonoDebugSourceLocation *loc;
9117 LLVMValueRef loc_md;
9119 loc = mono_debug_symfile_lookup_location (ctx->minfo, cil_code - cfg->header->code);
9122 #if LLVM_API_VERSION > 100
9123 loc_md = mono_llvm_di_create_location (ctx->module->di_builder, ctx->dbg_md, loc->row, loc->column);
9124 mono_llvm_di_set_location (builder, loc_md);
9126 LLVMValueRef md_args [16];
9130 md_args [nmd_args ++] = LLVMConstInt (LLVMInt32Type (), loc->row, FALSE);
9131 md_args [nmd_args ++] = LLVMConstInt (LLVMInt32Type (), loc->column, FALSE);
9132 md_args [nmd_args ++] = ctx->dbg_md;
9133 md_args [nmd_args ++] = NULL;
9134 loc_md = LLVMMDNode (md_args, nmd_args);
9135 LLVMSetCurrentDebugLocation (builder, loc_md);
9137 mono_debug_symfile_free_location (loc);
9143 default_mono_llvm_unhandled_exception (void)
9145 MonoJitTlsData *jit_tls = mono_get_jit_tls ();
9146 MonoObject *target = mono_gchandle_get_target (jit_tls->thrown_exc);
9148 mono_unhandled_exception (target);
9149 mono_invoke_unhandled_exception_hook (target);
9150 g_assert_not_reached ();
9155 - Emit LLVM IR from the mono IR using the LLVM C API.
9156 - The original arch specific code remains, so we can fall back to it if we run
9157 into something we can't handle.
9161 A partial list of issues:
9162 - Handling of opcodes which can throw exceptions.
9164 In the mono JIT, these are implemented using code like this:
9171 push throw_pos - method
9172 call <exception trampoline>
9174 The problematic part is push throw_pos - method, which cannot be represented
9175 in the LLVM IR, since it does not support label values.
9176 -> this can be implemented in AOT mode using inline asm + labels, but cannot
9177 be implemented in JIT mode ?
9178 -> a possible but slower implementation would use the normal exception
9179 throwing code but it would need to control the placement of the throw code
9180 (it needs to be exactly after the compare+branch).
9181 -> perhaps add a PC offset intrinsics ?
9183 - efficient implementation of .ovf opcodes.
9185 These are currently implemented as:
9186 <ins which sets the condition codes>
9189 Some overflow opcodes are now supported by LLVM SVN.
9191 - exception handling, unwinding.
9192 - SSA is disabled for methods with exception handlers
9193 - How to obtain unwind info for LLVM compiled methods ?
9194 -> this is now solved by converting the unwind info generated by LLVM
9196 - LLVM uses the c++ exception handling framework, while we use our home grown
9197 code, and couldn't use the c++ one:
9198 - its not supported under VC++, other exotic platforms.
9199 - it might be impossible to support filter clauses with it.
9203 The trampolines need a predictable call sequence, since they need to disasm
9204 the calling code to obtain register numbers / offsets.
9206 LLVM currently generates this code in non-JIT mode:
9207 mov -0x98(%rax),%eax
9209 Here, the vtable pointer is lost.
9210 -> solution: use one vtable trampoline per class.
9212 - passing/receiving the IMT pointer/RGCTX.
9213 -> solution: pass them as normal arguments ?
9217 LLVM does not allow the specification of argument registers etc. This means
9218 that all calls are made according to the platform ABI.
9220 - passing/receiving vtypes.
9222 Vtypes passed/received in registers are handled by the front end by using
9223 a signature with scalar arguments, and loading the parts of the vtype into those
9226 Vtypes passed on the stack are handled using the 'byval' attribute.
9230 Supported though alloca, we need to emit the load/store code.
9234 The mono JIT uses pointer sized iregs/double fregs, while LLVM uses precisely
9235 typed registers, so we have to keep track of the precise LLVM type of each vreg.
9236 This is made easier because the IR is already in SSA form.
9237 An additional problem is that our IR is not consistent with types, i.e. i32/ia64
9238 types are frequently used incorrectly.
9243 Emit LLVM bytecode into a .bc file, compile it using llc into a .s file, then link
9244 it with the file containing the methods emitted by the JIT and the AOT data
9248 /* FIXME: Normalize some aspects of the mono IR to allow easier translation, like:
9249 * - each bblock should end with a branch
9250 * - setting the return value, making cfg->ret non-volatile
9251 * - avoid some transformations in the JIT which make it harder for us to generate
9253 * - use pointer types to help optimizations.
9256 #else /* DISABLE_JIT */
9259 mono_llvm_cleanup (void)
9264 mono_llvm_free_domain_info (MonoDomain *domain)
9269 mono_llvm_init (void)
9274 default_mono_llvm_unhandled_exception (void)
9278 #endif /* DISABLE_JIT */