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 param_types [pindex] = LLVMArrayType (IntPtrType (), ainfo->nslots);
1437 case LLVMArgVtypeByRef:
1438 param_types [pindex] = type_to_llvm_arg_type (ctx, ainfo->type);
1441 param_types [pindex] = LLVMPointerType (param_types [pindex], 0);
1444 case LLVMArgAsFpArgs: {
1447 /* Emit dummy fp arguments if needed so the rest is passed on the stack */
1448 for (j = 0; j < ainfo->ndummy_fpargs; ++j)
1449 param_types [pindex ++] = LLVMDoubleType ();
1450 for (j = 0; j < ainfo->nslots; ++j)
1451 param_types [pindex ++] = ainfo->esize == 8 ? LLVMDoubleType () : LLVMFloatType ();
1454 case LLVMArgVtypeAsScalar:
1455 g_assert_not_reached ();
1457 case LLVMArgGsharedvtFixed:
1458 case LLVMArgGsharedvtFixedVtype:
1459 param_types [pindex ++] = LLVMPointerType (type_to_llvm_arg_type (ctx, ainfo->type), 0);
1461 case LLVMArgGsharedvtVariable:
1462 param_types [pindex ++] = LLVMPointerType (IntPtrType (), 0);
1465 param_types [pindex ++] = type_to_llvm_arg_type (ctx, ainfo->type);
1469 if (!ctx_ok (ctx)) {
1470 g_free (param_types);
1473 if (vretaddr && vret_arg_pindex == pindex)
1474 param_types [pindex ++] = IntPtrType ();
1475 if (ctx->llvm_only && cinfo->rgctx_arg) {
1476 /* Pass the rgctx as the last argument */
1477 cinfo->rgctx_arg_pindex = pindex;
1478 param_types [pindex] = ctx->module->ptr_type;
1482 res = LLVMFunctionType (ret_type, param_types, pindex, FALSE);
1483 g_free (param_types);
1489 sig_to_llvm_sig (EmitContext *ctx, MonoMethodSignature *sig)
1491 return sig_to_llvm_sig_full (ctx, sig, NULL);
1495 * LLVMFunctionType1:
1497 * Create an LLVM function type from the arguments.
1499 static G_GNUC_UNUSED LLVMTypeRef
1500 LLVMFunctionType0 (LLVMTypeRef ReturnType,
1503 return LLVMFunctionType (ReturnType, NULL, 0, IsVarArg);
1507 * LLVMFunctionType1:
1509 * Create an LLVM function type from the arguments.
1511 static G_GNUC_UNUSED LLVMTypeRef
1512 LLVMFunctionType1 (LLVMTypeRef ReturnType,
1513 LLVMTypeRef ParamType1,
1516 LLVMTypeRef param_types [1];
1518 param_types [0] = ParamType1;
1520 return LLVMFunctionType (ReturnType, param_types, 1, IsVarArg);
1524 * LLVMFunctionType2:
1526 * Create an LLVM function type from the arguments.
1528 static G_GNUC_UNUSED LLVMTypeRef
1529 LLVMFunctionType2 (LLVMTypeRef ReturnType,
1530 LLVMTypeRef ParamType1,
1531 LLVMTypeRef ParamType2,
1534 LLVMTypeRef param_types [2];
1536 param_types [0] = ParamType1;
1537 param_types [1] = ParamType2;
1539 return LLVMFunctionType (ReturnType, param_types, 2, IsVarArg);
1543 * LLVMFunctionType3:
1545 * Create an LLVM function type from the arguments.
1547 static G_GNUC_UNUSED LLVMTypeRef
1548 LLVMFunctionType3 (LLVMTypeRef ReturnType,
1549 LLVMTypeRef ParamType1,
1550 LLVMTypeRef ParamType2,
1551 LLVMTypeRef ParamType3,
1554 LLVMTypeRef param_types [3];
1556 param_types [0] = ParamType1;
1557 param_types [1] = ParamType2;
1558 param_types [2] = ParamType3;
1560 return LLVMFunctionType (ReturnType, param_types, 3, IsVarArg);
1563 static G_GNUC_UNUSED LLVMTypeRef
1564 LLVMFunctionType5 (LLVMTypeRef ReturnType,
1565 LLVMTypeRef ParamType1,
1566 LLVMTypeRef ParamType2,
1567 LLVMTypeRef ParamType3,
1568 LLVMTypeRef ParamType4,
1569 LLVMTypeRef ParamType5,
1572 LLVMTypeRef param_types [5];
1574 param_types [0] = ParamType1;
1575 param_types [1] = ParamType2;
1576 param_types [2] = ParamType3;
1577 param_types [3] = ParamType4;
1578 param_types [4] = ParamType5;
1580 return LLVMFunctionType (ReturnType, param_types, 5, IsVarArg);
1586 * Create an LLVM builder and remember it so it can be freed later.
1588 static LLVMBuilderRef
1589 create_builder (EmitContext *ctx)
1591 LLVMBuilderRef builder = LLVMCreateBuilder ();
1593 ctx->builders = g_slist_prepend_mempool (ctx->cfg->mempool, ctx->builders, builder);
1599 get_aotconst_name (MonoJumpInfoType type, gconstpointer data, int got_offset)
1604 case MONO_PATCH_INFO_INTERNAL_METHOD:
1605 name = g_strdup_printf ("jit_icall_%s", data);
1607 case MONO_PATCH_INFO_RGCTX_SLOT_INDEX: {
1608 MonoJumpInfoRgctxEntry *entry = (MonoJumpInfoRgctxEntry*)data;
1609 name = g_strdup_printf ("RGCTX_SLOT_INDEX_%s", mono_rgctx_info_type_to_str (entry->info_type));
1613 name = g_strdup_printf ("%s_%d", mono_ji_type_to_string (type), got_offset);
1621 get_aotconst_typed (EmitContext *ctx, MonoJumpInfoType type, gconstpointer data, LLVMTypeRef llvm_type)
1625 LLVMValueRef indexes [2];
1626 LLVMValueRef got_entry_addr, load;
1627 LLVMBuilderRef builder = ctx->builder;
1632 MonoJumpInfo tmp_ji;
1634 tmp_ji.data.target = data;
1636 MonoJumpInfo *ji = mono_aot_patch_info_dup (&tmp_ji);
1638 ji->next = cfg->patch_info;
1639 cfg->patch_info = ji;
1641 got_offset = mono_aot_get_got_offset (cfg->patch_info);
1642 ctx->module->max_got_offset = MAX (ctx->module->max_got_offset, got_offset);
1644 * If the got slot is shared, it means its initialized when the aot image is loaded, so we don't need to
1645 * explicitly initialize it.
1647 if (!mono_aot_is_shared_got_offset (got_offset)) {
1648 //mono_print_ji (ji);
1650 ctx->has_got_access = TRUE;
1653 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
1654 indexes [1] = LLVMConstInt (LLVMInt32Type (), (gssize)got_offset, FALSE);
1655 got_entry_addr = LLVMBuildGEP (builder, ctx->module->got_var, indexes, 2, "");
1657 name = get_aotconst_name (type, data, got_offset);
1659 load = LLVMBuildLoad (builder, got_entry_addr, "");
1660 load = convert (ctx, load, llvm_type);
1661 LLVMSetValueName (load, name ? name : "");
1663 load = LLVMBuildLoad (builder, got_entry_addr, name ? name : "");
1666 //set_invariant_load_flag (load);
1672 get_aotconst (EmitContext *ctx, MonoJumpInfoType type, gconstpointer data)
1674 return get_aotconst_typed (ctx, type, data, NULL);
1678 get_callee (EmitContext *ctx, LLVMTypeRef llvm_sig, MonoJumpInfoType type, gconstpointer data)
1680 LLVMValueRef callee;
1682 if (ctx->llvm_only) {
1683 callee_name = mono_aot_get_direct_call_symbol (type, data);
1685 /* Directly callable */
1687 callee = (LLVMValueRef)g_hash_table_lookup (ctx->module->direct_callables, callee_name);
1689 callee = LLVMAddFunction (ctx->lmodule, callee_name, llvm_sig);
1691 LLVMSetVisibility (callee, LLVMHiddenVisibility);
1693 g_hash_table_insert (ctx->module->direct_callables, (char*)callee_name, callee);
1695 /* LLVMTypeRef's are uniqued */
1696 if (LLVMGetElementType (LLVMTypeOf (callee)) != llvm_sig)
1697 return LLVMConstBitCast (callee, LLVMPointerType (llvm_sig, 0));
1699 g_free (callee_name);
1705 * Calls are made through the GOT.
1707 return get_aotconst_typed (ctx, type, data, LLVMPointerType (llvm_sig, 0));
1709 MonoJumpInfo *ji = NULL;
1711 callee_name = mono_aot_get_plt_symbol (type, data);
1715 if (ctx->cfg->compile_aot)
1716 /* Add a patch so referenced wrappers can be compiled in full aot mode */
1717 mono_add_patch_info (ctx->cfg, 0, type, data);
1720 callee = (LLVMValueRef)g_hash_table_lookup (ctx->module->plt_entries, callee_name);
1722 callee = LLVMAddFunction (ctx->lmodule, callee_name, llvm_sig);
1724 LLVMSetVisibility (callee, LLVMHiddenVisibility);
1726 g_hash_table_insert (ctx->module->plt_entries, (char*)callee_name, callee);
1729 if (ctx->cfg->compile_aot) {
1730 ji = g_new0 (MonoJumpInfo, 1);
1732 ji->data.target = data;
1734 g_hash_table_insert (ctx->module->plt_entries_ji, ji, callee);
1742 emit_jit_callee (EmitContext *ctx, const char *name, LLVMTypeRef llvm_sig, gpointer target)
1744 #if LLVM_API_VERSION > 100
1745 LLVMValueRef tramp_var = LLVMAddGlobal (ctx->lmodule, LLVMPointerType (llvm_sig, 0), name);
1746 LLVMSetInitializer (tramp_var, LLVMConstIntToPtr (LLVMConstInt (LLVMInt64Type (), (guint64)(size_t)target, FALSE), LLVMPointerType (llvm_sig, 0)));
1747 LLVMSetLinkage (tramp_var, LLVMExternalLinkage);
1748 LLVMValueRef callee = LLVMBuildLoad (ctx->builder, tramp_var, "");
1751 LLVMValueRef callee = LLVMAddFunction (ctx->lmodule, "", llvm_sig);
1752 LLVMAddGlobalMapping (ctx->module->ee, callee, target);
1758 get_handler_clause (MonoCompile *cfg, MonoBasicBlock *bb)
1760 MonoMethodHeader *header = cfg->header;
1761 MonoExceptionClause *clause;
1765 if (bb->region != -1 && MONO_BBLOCK_IS_IN_REGION (bb, MONO_REGION_TRY))
1766 return (bb->region >> 8) - 1;
1769 for (i = 0; i < header->num_clauses; ++i) {
1770 clause = &header->clauses [i];
1772 if (MONO_OFFSET_IN_CLAUSE (clause, bb->real_offset) && clause->flags == MONO_EXCEPTION_CLAUSE_NONE)
1779 static MonoExceptionClause *
1780 get_most_deep_clause (MonoCompile *cfg, EmitContext *ctx, MonoBasicBlock *bb)
1782 if (bb == cfg->bb_init)
1784 // Since they're sorted by nesting we just need
1785 // the first one that the bb is a member of
1786 for (int i = 0; i < cfg->header->num_clauses; i++) {
1787 MonoExceptionClause *curr = &cfg->header->clauses [i];
1789 if (MONO_OFFSET_IN_CLAUSE (curr, bb->real_offset))
1797 set_metadata_flag (LLVMValueRef v, const char *flag_name)
1799 LLVMValueRef md_arg;
1802 md_kind = LLVMGetMDKindID (flag_name, strlen (flag_name));
1803 md_arg = LLVMMDString ("mono", 4);
1804 LLVMSetMetadata (v, md_kind, LLVMMDNode (&md_arg, 1));
1808 set_invariant_load_flag (LLVMValueRef v)
1810 LLVMValueRef md_arg;
1812 const char *flag_name;
1814 // FIXME: Cache this
1815 flag_name = "invariant.load";
1816 md_kind = LLVMGetMDKindID (flag_name, strlen (flag_name));
1817 md_arg = LLVMMDString ("<index>", strlen ("<index>"));
1818 LLVMSetMetadata (v, md_kind, LLVMMDNode (&md_arg, 1));
1824 * Emit an LLVM call or invoke instruction depending on whenever the call is inside
1828 emit_call (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, LLVMValueRef callee, LLVMValueRef *args, int pindex)
1830 MonoCompile *cfg = ctx->cfg;
1831 LLVMValueRef lcall = NULL;
1832 LLVMBuilderRef builder = *builder_ref;
1833 MonoExceptionClause *clause;
1835 if (ctx->llvm_only) {
1836 clause = get_most_deep_clause (cfg, ctx, bb);
1839 g_assert (clause->flags == MONO_EXCEPTION_CLAUSE_NONE || clause->flags == MONO_EXCEPTION_CLAUSE_FINALLY);
1842 * Have to use an invoke instead of a call, branching to the
1843 * handler bblock of the clause containing this bblock.
1845 intptr_t key = CLAUSE_END(clause);
1847 LLVMBasicBlockRef lpad_bb = (LLVMBasicBlockRef)g_hash_table_lookup (ctx->exc_meta, (gconstpointer)key);
1849 // FIXME: Find the one that has the lowest end bound for the right start address
1850 // FIXME: Finally + nesting
1853 LLVMBasicBlockRef noex_bb = gen_bb (ctx, "CALL_NOEX_BB");
1856 lcall = LLVMBuildInvoke (builder, callee, args, pindex, noex_bb, lpad_bb, "");
1858 builder = ctx->builder = create_builder (ctx);
1859 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
1861 ctx->bblocks [bb->block_num].end_bblock = noex_bb;
1865 int clause_index = get_handler_clause (cfg, bb);
1867 if (clause_index != -1) {
1868 MonoMethodHeader *header = cfg->header;
1869 MonoExceptionClause *ec = &header->clauses [clause_index];
1870 MonoBasicBlock *tblock;
1871 LLVMBasicBlockRef ex_bb, noex_bb;
1874 * Have to use an invoke instead of a call, branching to the
1875 * handler bblock of the clause containing this bblock.
1878 g_assert (ec->flags == MONO_EXCEPTION_CLAUSE_NONE || ec->flags == MONO_EXCEPTION_CLAUSE_FINALLY);
1880 tblock = cfg->cil_offset_to_bb [ec->handler_offset];
1883 ctx->bblocks [tblock->block_num].invoke_target = TRUE;
1885 ex_bb = get_bb (ctx, tblock);
1887 noex_bb = gen_bb (ctx, "NOEX_BB");
1890 lcall = LLVMBuildInvoke (builder, callee, args, pindex, noex_bb, ex_bb, "");
1892 builder = ctx->builder = create_builder (ctx);
1893 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
1895 ctx->bblocks [bb->block_num].end_bblock = noex_bb;
1900 lcall = LLVMBuildCall (builder, callee, args, pindex, "");
1901 ctx->builder = builder;
1905 *builder_ref = ctx->builder;
1911 emit_load_general (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, int size, LLVMValueRef addr, LLVMValueRef base, const char *name, gboolean is_faulting, BarrierKind barrier)
1913 const char *intrins_name;
1914 LLVMValueRef args [16], res;
1915 LLVMTypeRef addr_type;
1916 gboolean use_intrinsics = TRUE;
1918 #if LLVM_API_VERSION > 100
1919 if (is_faulting && bb->region != -1 && !ctx->cfg->llvm_only) {
1920 /* The llvm.mono.load/store intrinsics are not supported by this llvm version, emit an explicit null check instead */
1923 cmp = LLVMBuildICmp (*builder_ref, LLVMIntEQ, base, LLVMConstNull (LLVMTypeOf (base)), "");
1924 emit_cond_system_exception (ctx, bb, "NullReferenceException", cmp);
1925 *builder_ref = ctx->builder;
1926 use_intrinsics = FALSE;
1930 if (is_faulting && bb->region != -1 && !ctx->cfg->llvm_only && use_intrinsics) {
1931 LLVMAtomicOrdering ordering;
1934 case LLVM_BARRIER_NONE:
1935 ordering = LLVMAtomicOrderingNotAtomic;
1937 case LLVM_BARRIER_ACQ:
1938 ordering = LLVMAtomicOrderingAcquire;
1940 case LLVM_BARRIER_SEQ:
1941 ordering = LLVMAtomicOrderingSequentiallyConsistent;
1944 g_assert_not_reached ();
1949 * We handle loads which can fault by calling a mono specific intrinsic
1950 * using an invoke, so they are handled properly inside try blocks.
1951 * We can't use this outside clauses, since LLVM optimizes intrinsics which
1952 * are marked with IntrReadArgMem.
1956 intrins_name = "llvm.mono.load.i8.p0i8";
1959 intrins_name = "llvm.mono.load.i16.p0i16";
1962 intrins_name = "llvm.mono.load.i32.p0i32";
1965 intrins_name = "llvm.mono.load.i64.p0i64";
1968 g_assert_not_reached ();
1971 addr_type = LLVMTypeOf (addr);
1972 if (addr_type == LLVMPointerType (LLVMDoubleType (), 0) || addr_type == LLVMPointerType (LLVMFloatType (), 0))
1973 addr = LLVMBuildBitCast (*builder_ref, addr, LLVMPointerType (LLVMIntType (size * 8), 0), "");
1976 args [1] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
1977 args [2] = LLVMConstInt (LLVMInt1Type (), TRUE, FALSE);
1978 args [3] = LLVMConstInt (LLVMInt32Type (), ordering, FALSE);
1979 res = emit_call (ctx, bb, builder_ref, get_intrinsic (ctx, intrins_name), args, 4);
1981 if (addr_type == LLVMPointerType (LLVMDoubleType (), 0))
1982 res = LLVMBuildBitCast (*builder_ref, res, LLVMDoubleType (), "");
1983 else if (addr_type == LLVMPointerType (LLVMFloatType (), 0))
1984 res = LLVMBuildBitCast (*builder_ref, res, LLVMFloatType (), "");
1991 * We emit volatile loads for loads which can fault, because otherwise
1992 * LLVM will generate invalid code when encountering a load from a
1995 if (barrier != LLVM_BARRIER_NONE)
1996 res = mono_llvm_build_atomic_load (*builder_ref, addr, name, is_faulting, size, barrier);
1998 res = mono_llvm_build_load (*builder_ref, addr, name, is_faulting);
2000 /* Mark it with a custom metadata */
2003 set_metadata_flag (res, "mono.faulting.load");
2011 emit_load (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, int size, LLVMValueRef addr, const char *name, gboolean is_faulting)
2013 return emit_load_general (ctx, bb, builder_ref, size, addr, addr, name, is_faulting, LLVM_BARRIER_NONE);
2017 emit_store_general (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, int size, LLVMValueRef value, LLVMValueRef addr, LLVMValueRef base, gboolean is_faulting, BarrierKind barrier)
2019 const char *intrins_name;
2020 LLVMValueRef args [16];
2021 gboolean use_intrinsics = TRUE;
2023 #if LLVM_API_VERSION > 100
2024 if (is_faulting && bb->region != -1 && !ctx->cfg->llvm_only) {
2025 /* The llvm.mono.load/store intrinsics are not supported by this llvm version, emit an explicit null check instead */
2026 LLVMValueRef cmp = LLVMBuildICmp (*builder_ref, LLVMIntEQ, base, LLVMConstNull (LLVMTypeOf (base)), "");
2027 emit_cond_system_exception (ctx, bb, "NullReferenceException", cmp);
2028 *builder_ref = ctx->builder;
2029 use_intrinsics = FALSE;
2033 if (is_faulting && bb->region != -1 && !ctx->cfg->llvm_only && use_intrinsics) {
2034 LLVMAtomicOrdering ordering;
2037 case LLVM_BARRIER_NONE:
2038 ordering = LLVMAtomicOrderingNotAtomic;
2040 case LLVM_BARRIER_REL:
2041 ordering = LLVMAtomicOrderingRelease;
2043 case LLVM_BARRIER_SEQ:
2044 ordering = LLVMAtomicOrderingSequentiallyConsistent;
2047 g_assert_not_reached ();
2053 intrins_name = "llvm.mono.store.i8.p0i8";
2056 intrins_name = "llvm.mono.store.i16.p0i16";
2059 intrins_name = "llvm.mono.store.i32.p0i32";
2062 intrins_name = "llvm.mono.store.i64.p0i64";
2065 g_assert_not_reached ();
2068 if (LLVMTypeOf (value) == LLVMDoubleType () || LLVMTypeOf (value) == LLVMFloatType ()) {
2069 value = LLVMBuildBitCast (*builder_ref, value, LLVMIntType (size * 8), "");
2070 addr = LLVMBuildBitCast (*builder_ref, addr, LLVMPointerType (LLVMIntType (size * 8), 0), "");
2075 args [2] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
2076 args [3] = LLVMConstInt (LLVMInt1Type (), TRUE, FALSE);
2077 args [4] = LLVMConstInt (LLVMInt32Type (), ordering, FALSE);
2078 emit_call (ctx, bb, builder_ref, get_intrinsic (ctx, intrins_name), args, 5);
2080 if (barrier != LLVM_BARRIER_NONE)
2081 mono_llvm_build_aligned_store (*builder_ref, value, addr, barrier, size);
2083 mono_llvm_build_store (*builder_ref, value, addr, is_faulting, barrier);
2088 emit_store (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, int size, LLVMValueRef value, LLVMValueRef addr, LLVMValueRef base, gboolean is_faulting)
2090 emit_store_general (ctx, bb, builder_ref, size, value, addr, base, is_faulting, LLVM_BARRIER_NONE);
2094 * emit_cond_system_exception:
2096 * Emit code to throw the exception EXC_TYPE if the condition CMP is false.
2097 * Might set the ctx exception.
2100 emit_cond_system_exception (EmitContext *ctx, MonoBasicBlock *bb, const char *exc_type, LLVMValueRef cmp)
2102 LLVMBasicBlockRef ex_bb, ex2_bb = NULL, noex_bb;
2103 LLVMBuilderRef builder;
2104 MonoClass *exc_class;
2105 LLVMValueRef args [2];
2106 LLVMValueRef callee;
2107 gboolean no_pc = FALSE;
2109 if (IS_TARGET_AMD64)
2110 /* Some platforms don't require the pc argument */
2113 ex_bb = gen_bb (ctx, "EX_BB");
2115 ex2_bb = gen_bb (ctx, "EX2_BB");
2116 noex_bb = gen_bb (ctx, "NOEX_BB");
2118 LLVMBuildCondBr (ctx->builder, cmp, ex_bb, noex_bb);
2120 exc_class = mono_class_load_from_name (mono_get_corlib (), "System", exc_type);
2122 /* Emit exception throwing code */
2123 ctx->builder = builder = create_builder (ctx);
2124 LLVMPositionBuilderAtEnd (builder, ex_bb);
2126 if (ctx->cfg->llvm_only) {
2127 static LLVMTypeRef sig;
2130 sig = LLVMFunctionType1 (LLVMVoidType (), LLVMInt32Type (), FALSE);
2131 callee = get_callee (ctx, sig, MONO_PATCH_INFO_JIT_ICALL_ADDR, "mono_llvm_throw_corlib_exception");
2133 LLVMBuildBr (builder, ex2_bb);
2135 ctx->builder = builder = create_builder (ctx);
2136 LLVMPositionBuilderAtEnd (ctx->builder, ex2_bb);
2138 args [0] = LLVMConstInt (LLVMInt32Type (), exc_class->type_token - MONO_TOKEN_TYPE_DEF, FALSE);
2139 emit_call (ctx, bb, &builder, callee, args, 1);
2140 LLVMBuildUnreachable (builder);
2142 ctx->builder = builder = create_builder (ctx);
2143 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
2145 ctx->bblocks [bb->block_num].end_bblock = noex_bb;
2151 callee = ctx->module->throw_corlib_exception;
2154 const char *icall_name;
2157 sig = LLVMFunctionType1 (LLVMVoidType (), LLVMInt32Type (), FALSE);
2159 sig = LLVMFunctionType2 (LLVMVoidType (), LLVMInt32Type (), LLVMPointerType (LLVMInt8Type (), 0), FALSE);
2160 icall_name = "llvm_throw_corlib_exception_abs_trampoline";
2162 if (ctx->cfg->compile_aot) {
2163 callee = get_callee (ctx, sig, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
2166 * Differences between the LLVM/non-LLVM throw corlib exception trampoline:
2167 * - On x86, LLVM generated code doesn't push the arguments
2168 * - The trampoline takes the throw address as an arguments, not a pc offset.
2170 gpointer target = resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
2171 callee = emit_jit_callee (ctx, "llvm_throw_corlib_exception_trampoline", sig, target);
2173 #if LLVM_API_VERSION > 100
2175 * Make sure that ex_bb starts with the invoke, so the block address points to it, and not to the load
2176 * added by emit_jit_callee ().
2178 ex2_bb = gen_bb (ctx, "EX2_BB");
2179 LLVMBuildBr (builder, ex2_bb);
2182 ctx->builder = builder = create_builder (ctx);
2183 LLVMPositionBuilderAtEnd (ctx->builder, ex2_bb);
2185 mono_memory_barrier ();
2186 ctx->module->throw_corlib_exception = callee;
2191 args [0] = LLVMConstInt (LLVMInt32Type (), exc_class->type_token - MONO_TOKEN_TYPE_DEF, FALSE);
2194 * The LLVM mono branch contains changes so a block address can be passed as an
2195 * argument to a call.
2198 emit_call (ctx, bb, &builder, callee, args, 1);
2200 args [1] = LLVMBlockAddress (ctx->lmethod, ex_bb);
2201 emit_call (ctx, bb, &builder, callee, args, 2);
2204 LLVMBuildUnreachable (builder);
2206 ctx->builder = builder = create_builder (ctx);
2207 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
2209 ctx->bblocks [bb->block_num].end_bblock = noex_bb;
2216 * emit_args_to_vtype:
2218 * Emit code to store the vtype in the arguments args to the address ADDRESS.
2221 emit_args_to_vtype (EmitContext *ctx, LLVMBuilderRef builder, MonoType *t, LLVMValueRef address, LLVMArgInfo *ainfo, LLVMValueRef *args)
2223 int j, size, nslots;
2225 size = mono_class_value_size (mono_class_from_mono_type (t), NULL);
2227 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (t))) {
2228 address = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (LLVMInt8Type (), 0), "");
2231 if (ainfo->storage == LLVMArgAsFpArgs)
2232 nslots = ainfo->nslots;
2236 for (j = 0; j < nslots; ++j) {
2237 LLVMValueRef index [2], addr, daddr;
2238 int part_size = size > sizeof (gpointer) ? sizeof (gpointer) : size;
2239 LLVMTypeRef part_type;
2241 while (part_size != 1 && part_size != 2 && part_size != 4 && part_size < 8)
2244 if (ainfo->pair_storage [j] == LLVMArgNone)
2247 switch (ainfo->pair_storage [j]) {
2248 case LLVMArgInIReg: {
2249 part_type = LLVMIntType (part_size * 8);
2250 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (t))) {
2251 index [0] = LLVMConstInt (LLVMInt32Type (), j * sizeof (gpointer), FALSE);
2252 addr = LLVMBuildGEP (builder, address, index, 1, "");
2254 daddr = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (IntPtrType (), 0), "");
2255 index [0] = LLVMConstInt (LLVMInt32Type (), j, FALSE);
2256 addr = LLVMBuildGEP (builder, daddr, index, 1, "");
2258 LLVMBuildStore (builder, convert (ctx, args [j], part_type), LLVMBuildBitCast (ctx->builder, addr, LLVMPointerType (part_type, 0), ""));
2261 case LLVMArgInFPReg: {
2262 LLVMTypeRef arg_type;
2264 if (ainfo->esize == 8)
2265 arg_type = LLVMDoubleType ();
2267 arg_type = LLVMFloatType ();
2269 index [0] = LLVMConstInt (LLVMInt32Type (), j, FALSE);
2270 daddr = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (arg_type, 0), "");
2271 addr = LLVMBuildGEP (builder, daddr, index, 1, "");
2272 LLVMBuildStore (builder, args [j], addr);
2278 g_assert_not_reached ();
2281 size -= sizeof (gpointer);
2286 * emit_vtype_to_args:
2288 * Emit code to load a vtype at address ADDRESS into scalar arguments. Store the arguments
2289 * into ARGS, and the number of arguments into NARGS.
2292 emit_vtype_to_args (EmitContext *ctx, LLVMBuilderRef builder, MonoType *t, LLVMValueRef address, LLVMArgInfo *ainfo, LLVMValueRef *args, guint32 *nargs)
2295 int j, size, nslots;
2296 LLVMTypeRef arg_type;
2298 size = get_vtype_size (t);
2300 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (t)))
2301 address = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (LLVMInt8Type (), 0), "");
2303 if (ainfo->storage == LLVMArgAsFpArgs)
2304 nslots = ainfo->nslots;
2307 for (j = 0; j < nslots; ++j) {
2308 LLVMValueRef index [2], addr, daddr;
2309 int partsize = size > sizeof (gpointer) ? sizeof (gpointer) : size;
2311 if (ainfo->pair_storage [j] == LLVMArgNone)
2314 switch (ainfo->pair_storage [j]) {
2316 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (t))) {
2317 index [0] = LLVMConstInt (LLVMInt32Type (), j * sizeof (gpointer), FALSE);
2318 addr = LLVMBuildGEP (builder, address, index, 1, "");
2320 daddr = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (IntPtrType (), 0), "");
2321 index [0] = LLVMConstInt (LLVMInt32Type (), j, FALSE);
2322 addr = LLVMBuildGEP (builder, daddr, index, 1, "");
2324 args [pindex ++] = convert (ctx, LLVMBuildLoad (builder, LLVMBuildBitCast (ctx->builder, addr, LLVMPointerType (LLVMIntType (partsize * 8), 0), ""), ""), IntPtrType ());
2326 case LLVMArgInFPReg:
2327 if (ainfo->esize == 8)
2328 arg_type = LLVMDoubleType ();
2330 arg_type = LLVMFloatType ();
2331 daddr = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (arg_type, 0), "");
2332 index [0] = LLVMConstInt (LLVMInt32Type (), j, FALSE);
2333 addr = LLVMBuildGEP (builder, daddr, index, 1, "");
2334 args [pindex ++] = LLVMBuildLoad (builder, addr, "");
2339 g_assert_not_reached ();
2341 size -= sizeof (gpointer);
2348 build_alloca_llvm_type_name (EmitContext *ctx, LLVMTypeRef t, int align, const char *name)
2351 * Have to place all alloca's at the end of the entry bb, since otherwise they would
2352 * get executed every time control reaches them.
2354 LLVMPositionBuilder (ctx->alloca_builder, get_bb (ctx, ctx->cfg->bb_entry), ctx->last_alloca);
2356 ctx->last_alloca = mono_llvm_build_alloca (ctx->alloca_builder, t, NULL, align, name);
2357 return ctx->last_alloca;
2361 build_alloca_llvm_type (EmitContext *ctx, LLVMTypeRef t, int align)
2363 return build_alloca_llvm_type_name (ctx, t, align, "");
2367 build_alloca (EmitContext *ctx, MonoType *t)
2369 MonoClass *k = mono_class_from_mono_type (t);
2372 g_assert (!mini_is_gsharedvt_variable_type (t));
2374 if (MONO_CLASS_IS_SIMD (ctx->cfg, k))
2377 align = mono_class_min_align (k);
2379 /* Sometimes align is not a power of 2 */
2380 while (mono_is_power_of_two (align) == -1)
2383 return build_alloca_llvm_type (ctx, type_to_llvm_type (ctx, t), align);
2387 emit_gsharedvt_ldaddr (EmitContext *ctx, int vreg)
2391 * Compute the address of the local as gsharedvt_locals_var + gsharedvt_info_var->locals_offsets [idx].
2393 MonoCompile *cfg = ctx->cfg;
2394 LLVMBuilderRef builder = ctx->builder;
2395 LLVMValueRef offset, offset_var;
2396 LLVMValueRef info_var = ctx->values [cfg->gsharedvt_info_var->dreg];
2397 LLVMValueRef locals_var = ctx->values [cfg->gsharedvt_locals_var->dreg];
2401 g_assert (info_var);
2402 g_assert (locals_var);
2404 int idx = cfg->gsharedvt_vreg_to_idx [vreg] - 1;
2406 offset = LLVMConstInt (LLVMInt32Type (), MONO_STRUCT_OFFSET (MonoGSharedVtMethodRuntimeInfo, entries) + (idx * sizeof (gpointer)), FALSE);
2407 ptr = LLVMBuildAdd (builder, convert (ctx, info_var, IntPtrType ()), convert (ctx, offset, IntPtrType ()), "");
2409 name = g_strdup_printf ("gsharedvt_local_%d_offset", vreg);
2410 offset_var = LLVMBuildLoad (builder, convert (ctx, ptr, LLVMPointerType (LLVMInt32Type (), 0)), name);
2412 return LLVMBuildAdd (builder, convert (ctx, locals_var, IntPtrType ()), convert (ctx, offset_var, IntPtrType ()), "");
2416 * Put the global into the 'llvm.used' array to prevent it from being optimized away.
2419 mark_as_used (MonoLLVMModule *module, LLVMValueRef global)
2422 module->used = g_ptr_array_sized_new (16);
2423 g_ptr_array_add (module->used, global);
2427 emit_llvm_used (MonoLLVMModule *module)
2429 LLVMModuleRef lmodule = module->lmodule;
2430 LLVMTypeRef used_type;
2431 LLVMValueRef used, *used_elem;
2437 used_type = LLVMArrayType (LLVMPointerType (LLVMInt8Type (), 0), module->used->len);
2438 used = LLVMAddGlobal (lmodule, used_type, "llvm.used");
2439 used_elem = g_new0 (LLVMValueRef, module->used->len);
2440 for (i = 0; i < module->used->len; ++i)
2441 used_elem [i] = LLVMConstBitCast ((LLVMValueRef)g_ptr_array_index (module->used, i), LLVMPointerType (LLVMInt8Type (), 0));
2442 LLVMSetInitializer (used, LLVMConstArray (LLVMPointerType (LLVMInt8Type (), 0), used_elem, module->used->len));
2443 LLVMSetLinkage (used, LLVMAppendingLinkage);
2444 LLVMSetSection (used, "llvm.metadata");
2450 * Emit a function mapping method indexes to their code
2453 emit_get_method (MonoLLVMModule *module)
2455 LLVMModuleRef lmodule = module->lmodule;
2456 LLVMValueRef func, switch_ins, m;
2457 LLVMBasicBlockRef entry_bb, fail_bb, bb, code_start_bb, code_end_bb;
2458 LLVMBasicBlockRef *bbs;
2460 LLVMBuilderRef builder = LLVMCreateBuilder ();
2465 * Emit a switch statement. Emitting a table of function addresses is smaller/faster,
2466 * but generating code seems safer.
2468 rtype = LLVMPointerType (LLVMInt8Type (), 0);
2469 func = LLVMAddFunction (lmodule, module->get_method_symbol, LLVMFunctionType1 (rtype, LLVMInt32Type (), FALSE));
2470 LLVMSetLinkage (func, LLVMExternalLinkage);
2471 LLVMSetVisibility (func, LLVMHiddenVisibility);
2472 LLVMAddFunctionAttr (func, LLVMNoUnwindAttribute);
2473 module->get_method = func;
2475 entry_bb = LLVMAppendBasicBlock (func, "ENTRY");
2478 * Return llvm_code_start/llvm_code_end when called with -1/-2.
2479 * Hopefully, the toolchain doesn't reorder these functions. If it does,
2480 * then we will have to find another solution.
2483 name = g_strdup_printf ("BB_CODE_START");
2484 code_start_bb = LLVMAppendBasicBlock (func, name);
2486 LLVMPositionBuilderAtEnd (builder, code_start_bb);
2487 LLVMBuildRet (builder, LLVMBuildBitCast (builder, module->code_start, rtype, ""));
2489 name = g_strdup_printf ("BB_CODE_END");
2490 code_end_bb = LLVMAppendBasicBlock (func, name);
2492 LLVMPositionBuilderAtEnd (builder, code_end_bb);
2493 LLVMBuildRet (builder, LLVMBuildBitCast (builder, module->code_end, rtype, ""));
2495 bbs = g_new0 (LLVMBasicBlockRef, module->max_method_idx + 1);
2496 for (i = 0; i < module->max_method_idx + 1; ++i) {
2497 name = g_strdup_printf ("BB_%d", i);
2498 bb = LLVMAppendBasicBlock (func, name);
2502 LLVMPositionBuilderAtEnd (builder, bb);
2504 m = (LLVMValueRef)g_hash_table_lookup (module->idx_to_lmethod, GINT_TO_POINTER (i));
2506 LLVMBuildRet (builder, LLVMBuildBitCast (builder, m, rtype, ""));
2508 LLVMBuildRet (builder, LLVMConstNull (rtype));
2511 fail_bb = LLVMAppendBasicBlock (func, "FAIL");
2512 LLVMPositionBuilderAtEnd (builder, fail_bb);
2513 LLVMBuildRet (builder, LLVMConstNull (rtype));
2515 LLVMPositionBuilderAtEnd (builder, entry_bb);
2517 switch_ins = LLVMBuildSwitch (builder, LLVMGetParam (func, 0), fail_bb, 0);
2518 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), -1, FALSE), code_start_bb);
2519 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), -2, FALSE), code_end_bb);
2520 for (i = 0; i < module->max_method_idx + 1; ++i) {
2521 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), i, FALSE), bbs [i]);
2524 mark_as_used (module, func);
2526 LLVMDisposeBuilder (builder);
2530 * emit_get_unbox_tramp:
2532 * Emit a function mapping method indexes to their unbox trampoline
2535 emit_get_unbox_tramp (MonoLLVMModule *module)
2537 LLVMModuleRef lmodule = module->lmodule;
2538 LLVMValueRef func, switch_ins, m;
2539 LLVMBasicBlockRef entry_bb, fail_bb, bb;
2540 LLVMBasicBlockRef *bbs;
2542 LLVMBuilderRef builder = LLVMCreateBuilder ();
2546 /* Similar to emit_get_method () */
2548 rtype = LLVMPointerType (LLVMInt8Type (), 0);
2549 func = LLVMAddFunction (lmodule, module->get_unbox_tramp_symbol, LLVMFunctionType1 (rtype, LLVMInt32Type (), FALSE));
2550 LLVMSetLinkage (func, LLVMExternalLinkage);
2551 LLVMSetVisibility (func, LLVMHiddenVisibility);
2552 LLVMAddFunctionAttr (func, LLVMNoUnwindAttribute);
2553 module->get_unbox_tramp = func;
2555 entry_bb = LLVMAppendBasicBlock (func, "ENTRY");
2557 bbs = g_new0 (LLVMBasicBlockRef, module->max_method_idx + 1);
2558 for (i = 0; i < module->max_method_idx + 1; ++i) {
2559 m = (LLVMValueRef)g_hash_table_lookup (module->idx_to_unbox_tramp, GINT_TO_POINTER (i));
2563 name = g_strdup_printf ("BB_%d", i);
2564 bb = LLVMAppendBasicBlock (func, name);
2568 LLVMPositionBuilderAtEnd (builder, bb);
2570 LLVMBuildRet (builder, LLVMBuildBitCast (builder, m, rtype, ""));
2573 fail_bb = LLVMAppendBasicBlock (func, "FAIL");
2574 LLVMPositionBuilderAtEnd (builder, fail_bb);
2575 LLVMBuildRet (builder, LLVMConstNull (rtype));
2577 LLVMPositionBuilderAtEnd (builder, entry_bb);
2579 switch_ins = LLVMBuildSwitch (builder, LLVMGetParam (func, 0), fail_bb, 0);
2580 for (i = 0; i < module->max_method_idx + 1; ++i) {
2581 m = (LLVMValueRef)g_hash_table_lookup (module->idx_to_unbox_tramp, GINT_TO_POINTER (i));
2585 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), i, FALSE), bbs [i]);
2588 mark_as_used (module, func);
2589 LLVMDisposeBuilder (builder);
2592 /* Add a function to mark the beginning of LLVM code */
2594 emit_llvm_code_start (MonoLLVMModule *module)
2596 LLVMModuleRef lmodule = module->lmodule;
2598 LLVMBasicBlockRef entry_bb;
2599 LLVMBuilderRef builder;
2601 func = LLVMAddFunction (lmodule, "llvm_code_start", LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE));
2602 LLVMSetLinkage (func, LLVMInternalLinkage);
2603 LLVMAddFunctionAttr (func, LLVMNoUnwindAttribute);
2604 module->code_start = func;
2605 entry_bb = LLVMAppendBasicBlock (func, "ENTRY");
2606 builder = LLVMCreateBuilder ();
2607 LLVMPositionBuilderAtEnd (builder, entry_bb);
2608 LLVMBuildRetVoid (builder);
2609 LLVMDisposeBuilder (builder);
2613 emit_init_icall_wrapper (MonoLLVMModule *module, const char *name, const char *icall_name, int subtype)
2615 LLVMModuleRef lmodule = module->lmodule;
2616 LLVMValueRef func, indexes [2], got_entry_addr, args [16], callee;
2617 LLVMBasicBlockRef entry_bb;
2618 LLVMBuilderRef builder;
2625 func = LLVMAddFunction (lmodule, name, LLVMFunctionType1 (LLVMVoidType (), LLVMInt32Type (), FALSE));
2626 sig = LLVMFunctionType2 (LLVMVoidType (), IntPtrType (), LLVMInt32Type (), FALSE);
2631 func = LLVMAddFunction (lmodule, name, LLVMFunctionType2 (LLVMVoidType (), LLVMInt32Type (), IntPtrType (), FALSE));
2632 sig = LLVMFunctionType3 (LLVMVoidType (), IntPtrType (), LLVMInt32Type (), IntPtrType (), FALSE);
2635 func = LLVMAddFunction (lmodule, name, LLVMFunctionType2 (LLVMVoidType (), LLVMInt32Type (), ObjRefType (), FALSE));
2636 sig = LLVMFunctionType3 (LLVMVoidType (), IntPtrType (), LLVMInt32Type (), ObjRefType (), FALSE);
2639 g_assert_not_reached ();
2641 LLVMSetLinkage (func, LLVMInternalLinkage);
2642 LLVMAddFunctionAttr (func, LLVMNoInlineAttribute);
2643 mono_llvm_set_preserveall_cc (func);
2644 entry_bb = LLVMAppendBasicBlock (func, "ENTRY");
2645 builder = LLVMCreateBuilder ();
2646 LLVMPositionBuilderAtEnd (builder, entry_bb);
2649 ji = g_new0 (MonoJumpInfo, 1);
2650 ji->type = MONO_PATCH_INFO_AOT_MODULE;
2651 ji = mono_aot_patch_info_dup (ji);
2652 got_offset = mono_aot_get_got_offset (ji);
2653 module->max_got_offset = MAX (module->max_got_offset, got_offset);
2654 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
2655 indexes [1] = LLVMConstInt (LLVMInt32Type (), got_offset, FALSE);
2656 got_entry_addr = LLVMBuildGEP (builder, module->got_var, indexes, 2, "");
2657 args [0] = LLVMBuildPtrToInt (builder, LLVMBuildLoad (builder, got_entry_addr, ""), IntPtrType (), "");
2658 args [1] = LLVMGetParam (func, 0);
2660 args [2] = LLVMGetParam (func, 1);
2662 ji = g_new0 (MonoJumpInfo, 1);
2663 ji->type = MONO_PATCH_INFO_INTERNAL_METHOD;
2664 ji->data.name = icall_name;
2665 ji = mono_aot_patch_info_dup (ji);
2666 got_offset = mono_aot_get_got_offset (ji);
2667 module->max_got_offset = MAX (module->max_got_offset, got_offset);
2668 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
2669 indexes [1] = LLVMConstInt (LLVMInt32Type (), got_offset, FALSE);
2670 got_entry_addr = LLVMBuildGEP (builder, module->got_var, indexes, 2, "");
2671 callee = LLVMBuildLoad (builder, got_entry_addr, "");
2672 callee = LLVMBuildBitCast (builder, callee, LLVMPointerType (sig, 0), "");
2673 LLVMBuildCall (builder, callee, args, LLVMCountParamTypes (sig), "");
2675 // Set the inited flag
2676 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
2677 indexes [1] = LLVMGetParam (func, 0);
2678 LLVMBuildStore (builder, LLVMConstInt (LLVMInt8Type (), 1, FALSE), LLVMBuildGEP (builder, module->inited_var, indexes, 2, ""));
2680 LLVMBuildRetVoid (builder);
2682 LLVMVerifyFunction(func, LLVMAbortProcessAction);
2683 LLVMDisposeBuilder (builder);
2688 * Emit wrappers around the C icalls used to initialize llvm methods, to
2689 * make the calling code smaller and to enable usage of the llvm
2690 * PreserveAll calling convention.
2693 emit_init_icall_wrappers (MonoLLVMModule *module)
2695 module->init_method = emit_init_icall_wrapper (module, "init_method", "mono_aot_init_llvm_method", 0);
2696 module->init_method_gshared_mrgctx = emit_init_icall_wrapper (module, "init_method_gshared_mrgctx", "mono_aot_init_gshared_method_mrgctx", 1);
2697 module->init_method_gshared_this = emit_init_icall_wrapper (module, "init_method_gshared_this", "mono_aot_init_gshared_method_this", 2);
2698 module->init_method_gshared_vtable = emit_init_icall_wrapper (module, "init_method_gshared_vtable", "mono_aot_init_gshared_method_vtable", 3);
2702 emit_llvm_code_end (MonoLLVMModule *module)
2704 LLVMModuleRef lmodule = module->lmodule;
2706 LLVMBasicBlockRef entry_bb;
2707 LLVMBuilderRef builder;
2709 func = LLVMAddFunction (lmodule, "llvm_code_end", LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE));
2710 LLVMSetLinkage (func, LLVMInternalLinkage);
2711 LLVMAddFunctionAttr (func, LLVMNoUnwindAttribute);
2712 module->code_end = func;
2713 entry_bb = LLVMAppendBasicBlock (func, "ENTRY");
2714 builder = LLVMCreateBuilder ();
2715 LLVMPositionBuilderAtEnd (builder, entry_bb);
2716 LLVMBuildRetVoid (builder);
2717 LLVMDisposeBuilder (builder);
2721 emit_div_check (EmitContext *ctx, LLVMBuilderRef builder, MonoBasicBlock *bb, MonoInst *ins, LLVMValueRef lhs, LLVMValueRef rhs)
2723 gboolean need_div_check = ctx->cfg->backend->need_div_check;
2726 /* LLVM doesn't know that these can throw an exception since they are not called through an intrinsic */
2727 need_div_check = TRUE;
2729 if (!need_div_check)
2732 switch (ins->opcode) {
2745 case OP_IDIV_UN_IMM:
2746 case OP_LDIV_UN_IMM:
2747 case OP_IREM_UN_IMM:
2748 case OP_LREM_UN_IMM: {
2750 gboolean is_signed = (ins->opcode == OP_IDIV || ins->opcode == OP_LDIV || ins->opcode == OP_IREM || ins->opcode == OP_LREM ||
2751 ins->opcode == OP_IDIV_IMM || ins->opcode == OP_LDIV_IMM || ins->opcode == OP_IREM_IMM || ins->opcode == OP_LREM_IMM);
2753 cmp = LLVMBuildICmp (builder, LLVMIntEQ, rhs, LLVMConstInt (LLVMTypeOf (rhs), 0, FALSE), "");
2754 emit_cond_system_exception (ctx, bb, "DivideByZeroException", cmp);
2757 builder = ctx->builder;
2759 /* b == -1 && a == 0x80000000 */
2761 LLVMValueRef c = (LLVMTypeOf (lhs) == LLVMInt32Type ()) ? LLVMConstInt (LLVMTypeOf (lhs), 0x80000000, FALSE) : LLVMConstInt (LLVMTypeOf (lhs), 0x8000000000000000LL, FALSE);
2762 LLVMValueRef cond1 = LLVMBuildICmp (builder, LLVMIntEQ, rhs, LLVMConstInt (LLVMTypeOf (rhs), -1, FALSE), "");
2763 LLVMValueRef cond2 = LLVMBuildICmp (builder, LLVMIntEQ, lhs, c, "");
2765 cmp = LLVMBuildICmp (builder, LLVMIntEQ, LLVMBuildAnd (builder, cond1, cond2, ""), LLVMConstInt (LLVMInt1Type (), 1, FALSE), "");
2766 emit_cond_system_exception (ctx, bb, "OverflowException", cmp);
2769 builder = ctx->builder;
2781 * Emit code to initialize the GOT slots used by the method.
2784 emit_init_method (EmitContext *ctx)
2786 LLVMValueRef indexes [16], args [16], callee;
2787 LLVMValueRef inited_var, cmp, call;
2788 LLVMBasicBlockRef inited_bb, notinited_bb;
2789 LLVMBuilderRef builder = ctx->builder;
2790 MonoCompile *cfg = ctx->cfg;
2792 ctx->module->max_inited_idx = MAX (ctx->module->max_inited_idx, cfg->method_index);
2794 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
2795 indexes [1] = LLVMConstInt (LLVMInt32Type (), cfg->method_index, FALSE);
2796 inited_var = LLVMBuildLoad (builder, LLVMBuildGEP (builder, ctx->module->inited_var, indexes, 2, ""), "is_inited");
2798 args [0] = inited_var;
2799 args [1] = LLVMConstInt (LLVMInt8Type (), 1, FALSE);
2800 inited_var = LLVMBuildCall (ctx->builder, get_intrinsic (ctx, "llvm.expect.i8"), args, 2, "");
2802 cmp = LLVMBuildICmp (builder, LLVMIntEQ, inited_var, LLVMConstInt (LLVMTypeOf (inited_var), 0, FALSE), "");
2804 inited_bb = ctx->inited_bb;
2805 notinited_bb = gen_bb (ctx, "NOTINITED_BB");
2807 LLVMBuildCondBr (ctx->builder, cmp, notinited_bb, inited_bb);
2809 builder = ctx->builder = create_builder (ctx);
2810 LLVMPositionBuilderAtEnd (ctx->builder, notinited_bb);
2813 if (ctx->rgctx_arg && cfg->method->is_inflated && mono_method_get_context (cfg->method)->method_inst) {
2814 args [0] = LLVMConstInt (LLVMInt32Type (), cfg->method_index, 0);
2815 args [1] = convert (ctx, ctx->rgctx_arg, IntPtrType ());
2816 callee = ctx->module->init_method_gshared_mrgctx;
2817 call = LLVMBuildCall (builder, callee, args, 2, "");
2818 } else if (ctx->rgctx_arg) {
2819 /* A vtable is passed as the rgctx argument */
2820 args [0] = LLVMConstInt (LLVMInt32Type (), cfg->method_index, 0);
2821 args [1] = convert (ctx, ctx->rgctx_arg, IntPtrType ());
2822 callee = ctx->module->init_method_gshared_vtable;
2823 call = LLVMBuildCall (builder, callee, args, 2, "");
2824 } else if (cfg->gshared) {
2825 args [0] = LLVMConstInt (LLVMInt32Type (), cfg->method_index, 0);
2826 args [1] = convert (ctx, ctx->this_arg, ObjRefType ());
2827 callee = ctx->module->init_method_gshared_this;
2828 call = LLVMBuildCall (builder, callee, args, 2, "");
2830 args [0] = LLVMConstInt (LLVMInt32Type (), cfg->method_index, 0);
2831 callee = ctx->module->init_method;
2832 call = LLVMBuildCall (builder, callee, args, 1, "");
2836 * This enables llvm to keep arguments in their original registers/
2837 * scratch registers, since the call will not clobber them.
2839 mono_llvm_set_call_preserveall_cc (call);
2841 LLVMBuildBr (builder, inited_bb);
2842 ctx->bblocks [cfg->bb_entry->block_num].end_bblock = inited_bb;
2844 builder = ctx->builder = create_builder (ctx);
2845 LLVMPositionBuilderAtEnd (ctx->builder, inited_bb);
2849 emit_unbox_tramp (EmitContext *ctx, const char *method_name, LLVMTypeRef method_type, LLVMValueRef method, int method_index)
2852 * Emit unbox trampoline using a tail call
2854 LLVMValueRef tramp, call, *args;
2855 LLVMBuilderRef builder;
2856 LLVMBasicBlockRef lbb;
2857 LLVMCallInfo *linfo;
2861 tramp_name = g_strdup_printf ("ut_%s", method_name);
2862 tramp = LLVMAddFunction (ctx->module->lmodule, tramp_name, method_type);
2863 LLVMSetLinkage (tramp, LLVMInternalLinkage);
2864 LLVMAddFunctionAttr (tramp, LLVMOptimizeForSizeAttribute);
2865 //LLVMAddFunctionAttr (tramp, LLVMNoUnwindAttribute);
2867 // FIXME: Reduce code duplication with mono_llvm_compile_method () etc.
2868 if (!ctx->llvm_only && ctx->rgctx_arg_pindex != -1)
2869 LLVMAddAttribute (LLVMGetParam (tramp, ctx->rgctx_arg_pindex), LLVMInRegAttribute);
2870 if (ctx->cfg->vret_addr) {
2871 LLVMSetValueName (LLVMGetParam (tramp, linfo->vret_arg_pindex), "vret");
2872 if (linfo->ret.storage == LLVMArgVtypeByRef) {
2873 LLVMAddAttribute (LLVMGetParam (tramp, linfo->vret_arg_pindex), LLVMStructRetAttribute);
2874 LLVMAddAttribute (LLVMGetParam (tramp, linfo->vret_arg_pindex), LLVMNoAliasAttribute);
2878 lbb = LLVMAppendBasicBlock (tramp, "");
2879 builder = LLVMCreateBuilder ();
2880 LLVMPositionBuilderAtEnd (builder, lbb);
2882 nargs = LLVMCountParamTypes (method_type);
2883 args = g_new0 (LLVMValueRef, nargs);
2884 for (i = 0; i < nargs; ++i) {
2885 args [i] = LLVMGetParam (tramp, i);
2886 if (i == ctx->this_arg_pindex) {
2887 LLVMTypeRef arg_type = LLVMTypeOf (args [i]);
2889 args [i] = LLVMBuildPtrToInt (builder, args [i], IntPtrType (), "");
2890 args [i] = LLVMBuildAdd (builder, args [i], LLVMConstInt (IntPtrType (), sizeof (MonoObject), FALSE), "");
2891 args [i] = LLVMBuildIntToPtr (builder, args [i], arg_type, "");
2894 call = LLVMBuildCall (builder, method, args, nargs, "");
2895 if (!ctx->llvm_only && ctx->rgctx_arg_pindex != -1)
2896 LLVMAddInstrAttribute (call, 1 + ctx->rgctx_arg_pindex, LLVMInRegAttribute);
2897 if (linfo->ret.storage == LLVMArgVtypeByRef)
2898 LLVMAddInstrAttribute (call, 1 + linfo->vret_arg_pindex, LLVMStructRetAttribute);
2900 // FIXME: This causes assertions in clang
2901 //mono_llvm_set_must_tail (call);
2902 if (LLVMGetReturnType (method_type) == LLVMVoidType ())
2903 LLVMBuildRetVoid (builder);
2905 LLVMBuildRet (builder, call);
2907 g_hash_table_insert (ctx->module->idx_to_unbox_tramp, GINT_TO_POINTER (method_index), tramp);
2908 LLVMDisposeBuilder (builder);
2914 * Emit code to load/convert arguments.
2917 emit_entry_bb (EmitContext *ctx, LLVMBuilderRef builder)
2920 MonoCompile *cfg = ctx->cfg;
2921 MonoMethodSignature *sig = ctx->sig;
2922 LLVMCallInfo *linfo = ctx->linfo;
2926 LLVMBuilderRef old_builder = ctx->builder;
2927 ctx->builder = builder;
2929 ctx->alloca_builder = create_builder (ctx);
2932 * Handle indirect/volatile variables by allocating memory for them
2933 * using 'alloca', and storing their address in a temporary.
2935 for (i = 0; i < cfg->num_varinfo; ++i) {
2936 MonoInst *var = cfg->varinfo [i];
2939 if (var->opcode == OP_GSHAREDVT_LOCAL || var->opcode == OP_GSHAREDVT_ARG_REGOFFSET) {
2940 } 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))) {
2941 vtype = type_to_llvm_type (ctx, var->inst_vtype);
2944 /* Could be already created by an OP_VPHI */
2945 if (!ctx->addresses [var->dreg]) {
2946 ctx->addresses [var->dreg] = build_alloca (ctx, var->inst_vtype);
2947 //LLVMSetValueName (ctx->addresses [var->dreg], g_strdup_printf ("vreg_loc_%d", var->dreg));
2949 ctx->vreg_cli_types [var->dreg] = var->inst_vtype;
2953 names = g_new (char *, sig->param_count);
2954 mono_method_get_param_names (cfg->method, (const char **) names);
2956 for (i = 0; i < sig->param_count; ++i) {
2957 LLVMArgInfo *ainfo = &linfo->args [i + sig->hasthis];
2958 int reg = cfg->args [i + sig->hasthis]->dreg;
2961 pindex = ainfo->pindex;
2963 switch (ainfo->storage) {
2964 case LLVMArgVtypeInReg:
2965 case LLVMArgAsFpArgs: {
2966 LLVMValueRef args [8];
2969 pindex += ainfo->ndummy_fpargs;
2971 /* The argument is received as a set of int/fp arguments, store them into the real argument */
2972 memset (args, 0, sizeof (args));
2973 if (ainfo->storage == LLVMArgVtypeInReg) {
2974 args [0] = LLVMGetParam (ctx->lmethod, pindex);
2975 if (ainfo->pair_storage [1] != LLVMArgNone)
2976 args [1] = LLVMGetParam (ctx->lmethod, pindex + 1);
2978 g_assert (ainfo->nslots <= 8);
2979 for (j = 0; j < ainfo->nslots; ++j)
2980 args [j] = LLVMGetParam (ctx->lmethod, pindex + j);
2982 ctx->addresses [reg] = build_alloca (ctx, ainfo->type);
2984 emit_args_to_vtype (ctx, builder, ainfo->type, ctx->addresses [reg], ainfo, args);
2986 if (ainfo->storage == LLVMArgVtypeInReg && MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (ainfo->type))) {
2987 /* Treat these as normal values */
2988 ctx->values [reg] = LLVMBuildLoad (builder, ctx->addresses [reg], "");
2992 case LLVMArgVtypeByVal: {
2993 ctx->addresses [reg] = LLVMGetParam (ctx->lmethod, pindex);
2995 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (ainfo->type))) {
2996 /* Treat these as normal values */
2997 ctx->values [reg] = LLVMBuildLoad (builder, ctx->addresses [reg], "");
3001 case LLVMArgVtypeByRef: {
3002 /* The argument is passed by ref */
3003 ctx->addresses [reg] = LLVMGetParam (ctx->lmethod, pindex);
3006 case LLVMArgAsIArgs: {
3007 LLVMValueRef arg = LLVMGetParam (ctx->lmethod, pindex);
3010 /* The argument is received as an array of ints, store it into the real argument */
3011 ctx->addresses [reg] = build_alloca (ctx, ainfo->type);
3013 size = mono_class_value_size (mono_class_from_mono_type (ainfo->type), NULL);
3014 if (size < SIZEOF_VOID_P) {
3015 /* The upper bits of the registers might not be valid */
3016 LLVMValueRef val = LLVMBuildExtractValue (builder, arg, 0, "");
3017 LLVMValueRef dest = convert (ctx, ctx->addresses [reg], LLVMPointerType (LLVMIntType (size * 8), 0));
3018 LLVMBuildStore (ctx->builder, LLVMBuildTrunc (builder, val, LLVMIntType (size * 8), ""), dest);
3020 LLVMBuildStore (ctx->builder, arg, convert (ctx, ctx->addresses [reg], LLVMPointerType (LLVMTypeOf (arg), 0)));
3024 case LLVMArgVtypeAsScalar:
3025 g_assert_not_reached ();
3027 case LLVMArgGsharedvtFixed: {
3028 /* These are non-gsharedvt arguments passed by ref, the rest of the IR treats them as scalars */
3029 LLVMValueRef arg = LLVMGetParam (ctx->lmethod, pindex);
3032 name = g_strdup_printf ("arg_%s", names [i]);
3034 name = g_strdup_printf ("arg_%d", i);
3036 ctx->values [reg] = LLVMBuildLoad (builder, convert (ctx, arg, LLVMPointerType (type_to_llvm_type (ctx, ainfo->type), 0)), name);
3039 case LLVMArgGsharedvtFixedVtype: {
3040 LLVMValueRef arg = LLVMGetParam (ctx->lmethod, pindex);
3043 name = g_strdup_printf ("vtype_arg_%s", names [i]);
3045 name = g_strdup_printf ("vtype_arg_%d", i);
3047 /* Non-gsharedvt vtype argument passed by ref, the rest of the IR treats it as a vtype */
3048 g_assert (ctx->addresses [reg]);
3049 LLVMSetValueName (ctx->addresses [reg], name);
3050 LLVMBuildStore (builder, LLVMBuildLoad (builder, convert (ctx, arg, LLVMPointerType (type_to_llvm_type (ctx, ainfo->type), 0)), ""), ctx->addresses [reg]);
3053 case LLVMArgGsharedvtVariable:
3054 /* The IR treats these as variables with addresses */
3055 ctx->addresses [reg] = LLVMGetParam (ctx->lmethod, pindex);
3058 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));
3065 emit_volatile_store (ctx, cfg->vret_addr->dreg);
3067 emit_volatile_store (ctx, cfg->args [0]->dreg);
3068 for (i = 0; i < sig->param_count; ++i)
3069 if (!mini_type_is_vtype (sig->params [i]))
3070 emit_volatile_store (ctx, cfg->args [i + sig->hasthis]->dreg);
3072 if (sig->hasthis && !cfg->rgctx_var && cfg->gshared) {
3073 LLVMValueRef this_alloc;
3076 * The exception handling code needs the location where the this argument was
3077 * stored for gshared methods. We create a separate alloca to hold it, and mark it
3078 * with the "mono.this" custom metadata to tell llvm that it needs to save its
3079 * location into the LSDA.
3081 this_alloc = mono_llvm_build_alloca (builder, ThisType (), LLVMConstInt (LLVMInt32Type (), 1, FALSE), 0, "");
3082 /* This volatile store will keep the alloca alive */
3083 mono_llvm_build_store (builder, ctx->values [cfg->args [0]->dreg], this_alloc, TRUE, LLVM_BARRIER_NONE);
3085 set_metadata_flag (this_alloc, "mono.this");
3088 if (cfg->rgctx_var) {
3089 LLVMValueRef rgctx_alloc, store;
3092 * We handle the rgctx arg similarly to the this pointer.
3094 g_assert (ctx->addresses [cfg->rgctx_var->dreg]);
3095 rgctx_alloc = ctx->addresses [cfg->rgctx_var->dreg];
3096 /* This volatile store will keep the alloca alive */
3097 store = mono_llvm_build_store (builder, convert (ctx, ctx->rgctx_arg, IntPtrType ()), rgctx_alloc, TRUE, LLVM_BARRIER_NONE);
3099 set_metadata_flag (rgctx_alloc, "mono.this");
3102 /* Initialize the method if needed */
3103 if (cfg->compile_aot && ctx->llvm_only) {
3104 /* Emit a location for the initialization code */
3105 ctx->init_bb = gen_bb (ctx, "INIT_BB");
3106 ctx->inited_bb = gen_bb (ctx, "INITED_BB");
3108 LLVMBuildBr (ctx->builder, ctx->init_bb);
3109 builder = ctx->builder = create_builder (ctx);
3110 LLVMPositionBuilderAtEnd (ctx->builder, ctx->inited_bb);
3111 ctx->bblocks [cfg->bb_entry->block_num].end_bblock = ctx->inited_bb;
3114 /* Compute nesting between clauses */
3115 ctx->nested_in = (GSList**)mono_mempool_alloc0 (cfg->mempool, sizeof (GSList*) * cfg->header->num_clauses);
3116 for (i = 0; i < cfg->header->num_clauses; ++i) {
3117 for (j = 0; j < cfg->header->num_clauses; ++j) {
3118 MonoExceptionClause *clause1 = &cfg->header->clauses [i];
3119 MonoExceptionClause *clause2 = &cfg->header->clauses [j];
3121 if (i != j && clause1->try_offset >= clause2->try_offset && clause1->handler_offset <= clause2->handler_offset)
3122 ctx->nested_in [i] = g_slist_prepend_mempool (cfg->mempool, ctx->nested_in [i], GINT_TO_POINTER (j));
3127 * For finally clauses, create an indicator variable telling OP_ENDFINALLY whenever
3128 * it needs to continue normally, or return back to the exception handling system.
3130 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
3134 if (!(bb->region != -1 && (bb->flags & BB_EXCEPTION_HANDLER)))
3137 clause_index = MONO_REGION_CLAUSE_INDEX (bb->region);
3138 g_hash_table_insert (ctx->region_to_handler, GUINT_TO_POINTER (mono_get_block_region_notry (cfg, bb->region)), bb);
3139 g_hash_table_insert (ctx->clause_to_handler, GINT_TO_POINTER (clause_index), bb);
3141 if (bb->in_scount == 0) {
3144 sprintf (name, "finally_ind_bb%d", bb->block_num);
3145 val = LLVMBuildAlloca (builder, LLVMInt32Type (), name);
3146 LLVMBuildStore (builder, LLVMConstInt (LLVMInt32Type (), 0, FALSE), val);
3148 ctx->bblocks [bb->block_num].finally_ind = val;
3150 /* Create a variable to hold the exception var */
3152 ctx->ex_var = LLVMBuildAlloca (builder, ObjRefType (), "exvar");
3156 * Create a new bblock which CALL_HANDLER/landing pads can branch to, because branching to the
3157 * LLVM bblock containing a landing pad causes problems for the
3158 * LLVM optimizer passes.
3160 sprintf (name, "BB%d_CALL_HANDLER_TARGET", bb->block_num);
3161 ctx->bblocks [bb->block_num].call_handler_target_bb = LLVMAppendBasicBlock (ctx->lmethod, name);
3163 ctx->builder = old_builder;
3167 process_call (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, MonoInst *ins)
3169 MonoCompile *cfg = ctx->cfg;
3170 LLVMValueRef *values = ctx->values;
3171 LLVMValueRef *addresses = ctx->addresses;
3172 MonoCallInst *call = (MonoCallInst*)ins;
3173 MonoMethodSignature *sig = call->signature;
3174 LLVMValueRef callee = NULL, lcall;
3176 LLVMCallInfo *cinfo;
3180 LLVMTypeRef llvm_sig;
3182 gboolean is_virtual, calli, preserveall;
3183 LLVMBuilderRef builder = *builder_ref;
3185 if ((call->signature->call_convention != MONO_CALL_DEFAULT) && !((call->signature->call_convention == MONO_CALL_C) && ctx->llvm_only)) {
3186 set_failure (ctx, "non-default callconv");
3190 cinfo = call->cinfo;
3192 if (call->rgctx_arg_reg)
3193 cinfo->rgctx_arg = TRUE;
3194 if (call->imt_arg_reg)
3195 cinfo->imt_arg = TRUE;
3197 vretaddr = (cinfo->ret.storage == LLVMArgVtypeRetAddr || cinfo->ret.storage == LLVMArgVtypeByRef || cinfo->ret.storage == LLVMArgGsharedvtFixed || cinfo->ret.storage == LLVMArgGsharedvtVariable || cinfo->ret.storage == LLVMArgGsharedvtFixedVtype);
3199 llvm_sig = sig_to_llvm_sig_full (ctx, sig, cinfo);
3203 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);
3204 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);
3206 preserveall = FALSE;
3208 /* FIXME: Avoid creating duplicate methods */
3210 if (ins->flags & MONO_INST_HAS_METHOD) {
3214 if (cfg->compile_aot) {
3215 callee = get_callee (ctx, llvm_sig, MONO_PATCH_INFO_METHOD, call->method);
3217 set_failure (ctx, "can't encode patch");
3220 if (cfg->llvm_only && call->method->klass->image->assembly == ctx->module->assembly) {
3222 * Collect instructions representing the callee into a hash so they can be replaced
3223 * by the llvm method for the callee if the callee turns out to be direct
3224 * callable. Currently this only requires it to not fail llvm compilation.
3226 GSList *l = (GSList*)g_hash_table_lookup (ctx->method_to_callers, call->method);
3227 l = g_slist_prepend (l, callee);
3228 g_hash_table_insert (ctx->method_to_callers, call->method, l);
3232 static int tramp_index;
3235 name = g_strdup_printf ("tramp_%d", tramp_index);
3238 #if LLVM_API_VERSION > 100
3240 * Use our trampoline infrastructure for lazy compilation instead of llvm's.
3241 * Make all calls through a global. The address of the global will be saved in
3242 * MonoJitDomainInfo.llvm_jit_callees and updated when the method it refers to is
3245 LLVMValueRef tramp_var = g_hash_table_lookup (ctx->jit_callees, call->method);
3248 mono_create_jit_trampoline (mono_domain_get (),
3249 call->method, &error);
3250 if (!is_ok (&error)) {
3251 set_failure (ctx, mono_error_get_message (&error));
3252 mono_error_cleanup (&error);
3256 tramp_var = LLVMAddGlobal (ctx->lmodule, LLVMPointerType (llvm_sig, 0), name);
3257 LLVMSetInitializer (tramp_var, LLVMConstIntToPtr (LLVMConstInt (LLVMInt64Type (), (guint64)(size_t)target, FALSE), LLVMPointerType (llvm_sig, 0)));
3258 LLVMSetLinkage (tramp_var, LLVMExternalLinkage);
3259 g_hash_table_insert (ctx->jit_callees, call->method, tramp_var);
3261 callee = LLVMBuildLoad (builder, tramp_var, "");
3264 mono_create_jit_trampoline (mono_domain_get (),
3265 call->method, &error);
3266 if (!is_ok (&error)) {
3268 set_failure (ctx, mono_error_get_message (&error));
3269 mono_error_cleanup (&error);
3273 callee = LLVMAddFunction (ctx->lmodule, name, llvm_sig);
3276 LLVMAddGlobalMapping (ctx->module->ee, callee, target);
3281 if (!cfg->llvm_only && call->method && strstr (call->method->klass->name, "AsyncVoidMethodBuilder")) {
3282 /* LLVM miscompiles async methods */
3283 set_failure (ctx, "#13734");
3288 MonoJitICallInfo *info = mono_find_jit_icall_by_addr (call->fptr);
3294 memset (&ji, 0, sizeof (ji));
3295 ji.type = MONO_PATCH_INFO_JIT_ICALL_ADDR;
3296 ji.data.target = info->name;
3298 target = mono_resolve_patch_target (cfg->method, cfg->domain, NULL, &ji, FALSE);
3300 if (cfg->compile_aot) {
3301 callee = get_callee (ctx, llvm_sig, MONO_PATCH_INFO_INTERNAL_METHOD, (char*)info->name);
3303 set_failure (ctx, "can't encode patch");
3307 target = (gpointer)mono_icall_get_wrapper (info);
3308 callee = emit_jit_callee (ctx, "", llvm_sig, target);
3311 if (cfg->compile_aot) {
3313 if (cfg->abs_patches) {
3314 MonoJumpInfo *abs_ji = (MonoJumpInfo*)g_hash_table_lookup (cfg->abs_patches, call->fptr);
3316 callee = get_callee (ctx, llvm_sig, abs_ji->type, abs_ji->data.target);
3318 set_failure (ctx, "can't encode patch");
3324 set_failure (ctx, "aot");
3328 #if LLVM_API_VERSION > 100
3329 if (cfg->abs_patches) {
3330 MonoJumpInfo *abs_ji = (MonoJumpInfo*)g_hash_table_lookup (cfg->abs_patches, call->fptr);
3334 target = mono_resolve_patch_target (cfg->method, cfg->domain, NULL, abs_ji, FALSE, &error);
3335 mono_error_assert_ok (&error);
3336 callee = emit_jit_callee (ctx, "", llvm_sig, target);
3338 g_assert_not_reached ();
3341 g_assert_not_reached ();
3344 callee = LLVMAddFunction (ctx->lmodule, "", llvm_sig);
3346 if (cfg->abs_patches) {
3347 MonoJumpInfo *abs_ji = (MonoJumpInfo*)g_hash_table_lookup (cfg->abs_patches, call->fptr);
3352 * FIXME: Some trampolines might have
3353 * their own calling convention on some platforms.
3355 target = mono_resolve_patch_target (cfg->method, cfg->domain, NULL, abs_ji, FALSE, &error);
3356 mono_error_assert_ok (&error);
3357 LLVMAddGlobalMapping (ctx->module->ee, callee, target);
3361 LLVMAddGlobalMapping (ctx->module->ee, callee, (gpointer)call->fptr);
3368 int size = sizeof (gpointer);
3371 g_assert (ins->inst_offset % size == 0);
3372 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
3374 callee = convert (ctx, LLVMBuildLoad (builder, LLVMBuildGEP (builder, convert (ctx, values [ins->inst_basereg], LLVMPointerType (LLVMPointerType (IntPtrType (), 0), 0)), &index, 1, ""), ""), LLVMPointerType (llvm_sig, 0));
3376 callee = convert (ctx, values [ins->sreg1], LLVMPointerType (llvm_sig, 0));
3378 if (ins->flags & MONO_INST_HAS_METHOD) {
3383 * Collect and convert arguments
3385 nargs = (sig->param_count * 16) + sig->hasthis + vretaddr + call->rgctx_reg + call->imt_arg_reg;
3386 len = sizeof (LLVMValueRef) * nargs;
3387 args = (LLVMValueRef*)alloca (len);
3388 memset (args, 0, len);
3389 l = call->out_ireg_args;
3391 if (call->rgctx_arg_reg) {
3392 g_assert (values [call->rgctx_arg_reg]);
3393 g_assert (cinfo->rgctx_arg_pindex < nargs);
3395 * On ARM, the imt/rgctx argument is passed in a caller save register, but some of our trampolines etc. clobber it, leading to
3396 * problems is LLVM moves the arg assignment earlier. To work around this, save the argument into a stack slot and load
3397 * it using a volatile load.
3400 if (!ctx->imt_rgctx_loc)
3401 ctx->imt_rgctx_loc = build_alloca_llvm_type (ctx, ctx->module->ptr_type, sizeof (gpointer));
3402 LLVMBuildStore (builder, convert (ctx, ctx->values [call->rgctx_arg_reg], ctx->module->ptr_type), ctx->imt_rgctx_loc);
3403 args [cinfo->rgctx_arg_pindex] = mono_llvm_build_load (builder, ctx->imt_rgctx_loc, "", TRUE);
3405 args [cinfo->rgctx_arg_pindex] = convert (ctx, values [call->rgctx_arg_reg], ctx->module->ptr_type);
3408 if (call->imt_arg_reg) {
3409 g_assert (!ctx->llvm_only);
3410 g_assert (values [call->imt_arg_reg]);
3411 g_assert (cinfo->imt_arg_pindex < nargs);
3413 if (!ctx->imt_rgctx_loc)
3414 ctx->imt_rgctx_loc = build_alloca_llvm_type (ctx, ctx->module->ptr_type, sizeof (gpointer));
3415 LLVMBuildStore (builder, convert (ctx, ctx->values [call->imt_arg_reg], ctx->module->ptr_type), ctx->imt_rgctx_loc);
3416 args [cinfo->imt_arg_pindex] = mono_llvm_build_load (builder, ctx->imt_rgctx_loc, "", TRUE);
3418 args [cinfo->imt_arg_pindex] = convert (ctx, values [call->imt_arg_reg], ctx->module->ptr_type);
3421 switch (cinfo->ret.storage) {
3422 case LLVMArgGsharedvtVariable: {
3423 MonoInst *var = get_vreg_to_inst (cfg, call->inst.dreg);
3425 if (var && var->opcode == OP_GSHAREDVT_LOCAL) {
3426 args [cinfo->vret_arg_pindex] = convert (ctx, emit_gsharedvt_ldaddr (ctx, var->dreg), IntPtrType ());
3428 g_assert (addresses [call->inst.dreg]);
3429 args [cinfo->vret_arg_pindex] = addresses [call->inst.dreg];
3435 if (!addresses [call->inst.dreg])
3436 addresses [call->inst.dreg] = build_alloca (ctx, sig->ret);
3437 g_assert (cinfo->vret_arg_pindex < nargs);
3438 if (cinfo->ret.storage == LLVMArgVtypeByRef)
3439 args [cinfo->vret_arg_pindex] = addresses [call->inst.dreg];
3441 args [cinfo->vret_arg_pindex] = LLVMBuildPtrToInt (builder, addresses [call->inst.dreg], IntPtrType (), "");
3447 * Sometimes the same method is called with two different signatures (i.e. with and without 'this'), so
3448 * use the real callee for argument type conversion.
3450 LLVMTypeRef callee_type = LLVMGetElementType (LLVMTypeOf (callee));
3451 LLVMTypeRef *param_types = (LLVMTypeRef*)g_alloca (sizeof (LLVMTypeRef) * LLVMCountParamTypes (callee_type));
3452 LLVMGetParamTypes (callee_type, param_types);
3454 for (i = 0; i < sig->param_count + sig->hasthis; ++i) {
3457 LLVMArgInfo *ainfo = &call->cinfo->args [i];
3459 pindex = ainfo->pindex;
3461 regpair = (guint32)(gssize)(l->data);
3462 reg = regpair & 0xffffff;
3463 args [pindex] = values [reg];
3464 switch (ainfo->storage) {
3465 case LLVMArgVtypeInReg:
3466 case LLVMArgAsFpArgs: {
3470 for (j = 0; j < ainfo->ndummy_fpargs; ++j)
3471 args [pindex + j] = LLVMConstNull (LLVMDoubleType ());
3472 pindex += ainfo->ndummy_fpargs;
3474 g_assert (addresses [reg]);
3475 emit_vtype_to_args (ctx, builder, ainfo->type, addresses [reg], ainfo, args + pindex, &nargs);
3479 // FIXME: Get rid of the VMOVE
3482 case LLVMArgVtypeByVal:
3483 g_assert (addresses [reg]);
3484 args [pindex] = addresses [reg];
3486 case LLVMArgVtypeByRef: {
3487 g_assert (addresses [reg]);
3488 args [pindex] = convert (ctx, addresses [reg], LLVMPointerType (type_to_llvm_arg_type (ctx, ainfo->type), 0));
3491 case LLVMArgAsIArgs:
3492 g_assert (addresses [reg]);
3493 args [pindex] = LLVMBuildLoad (ctx->builder, convert (ctx, addresses [reg], LLVMPointerType (LLVMArrayType (IntPtrType (), ainfo->nslots), 0)), "");
3495 case LLVMArgVtypeAsScalar:
3496 g_assert_not_reached ();
3498 case LLVMArgGsharedvtFixed:
3499 case LLVMArgGsharedvtFixedVtype:
3500 g_assert (addresses [reg]);
3501 args [pindex] = convert (ctx, addresses [reg], LLVMPointerType (type_to_llvm_arg_type (ctx, ainfo->type), 0));
3503 case LLVMArgGsharedvtVariable:
3504 g_assert (addresses [reg]);
3505 args [pindex] = convert (ctx, addresses [reg], LLVMPointerType (IntPtrType (), 0));
3508 g_assert (args [pindex]);
3509 if (i == 0 && sig->hasthis)
3510 args [pindex] = convert (ctx, args [pindex], param_types [pindex]);
3512 args [pindex] = convert (ctx, args [pindex], type_to_llvm_arg_type (ctx, ainfo->type));
3515 g_assert (pindex <= nargs);
3520 // FIXME: Align call sites
3526 lcall = emit_call (ctx, bb, &builder, callee, args, LLVMCountParamTypes (llvm_sig));
3528 if (ins->opcode != OP_TAILCALL && LLVMGetInstructionOpcode (lcall) == LLVMCall)
3529 mono_llvm_set_call_notail (lcall);
3532 * Modify cconv and parameter attributes to pass rgctx/imt correctly.
3534 #if defined(MONO_ARCH_IMT_REG) && defined(MONO_ARCH_RGCTX_REG)
3535 g_assert (MONO_ARCH_IMT_REG == MONO_ARCH_RGCTX_REG);
3537 /* The two can't be used together, so use only one LLVM calling conv to pass them */
3538 g_assert (!(call->rgctx_arg_reg && call->imt_arg_reg));
3539 if (!sig->pinvoke && !cfg->llvm_only)
3540 LLVMSetInstructionCallConv (lcall, LLVMMono1CallConv);
3542 mono_llvm_set_call_preserveall_cc (lcall);
3544 if (cinfo->ret.storage == LLVMArgVtypeByRef)
3545 LLVMAddInstrAttribute (lcall, 1 + cinfo->vret_arg_pindex, LLVMStructRetAttribute);
3546 if (!ctx->llvm_only && call->rgctx_arg_reg)
3547 LLVMAddInstrAttribute (lcall, 1 + cinfo->rgctx_arg_pindex, LLVMInRegAttribute);
3548 if (call->imt_arg_reg)
3549 LLVMAddInstrAttribute (lcall, 1 + cinfo->imt_arg_pindex, LLVMInRegAttribute);
3551 /* Add byval attributes if needed */
3552 for (i = 0; i < sig->param_count; ++i) {
3553 LLVMArgInfo *ainfo = &call->cinfo->args [i + sig->hasthis];
3555 if (ainfo && ainfo->storage == LLVMArgVtypeByVal)
3556 LLVMAddInstrAttribute (lcall, 1 + ainfo->pindex, LLVMByValAttribute);
3560 * Convert the result
3562 switch (cinfo->ret.storage) {
3563 case LLVMArgVtypeInReg: {
3564 LLVMValueRef regs [2];
3566 if (LLVMTypeOf (lcall) == LLVMVoidType ())
3570 if (!addresses [ins->dreg])
3571 addresses [ins->dreg] = build_alloca (ctx, sig->ret);
3573 regs [0] = LLVMBuildExtractValue (builder, lcall, 0, "");
3574 if (cinfo->ret.pair_storage [1] != LLVMArgNone)
3575 regs [1] = LLVMBuildExtractValue (builder, lcall, 1, "");
3576 emit_args_to_vtype (ctx, builder, sig->ret, addresses [ins->dreg], &cinfo->ret, regs);
3579 case LLVMArgVtypeByVal:
3580 if (!addresses [call->inst.dreg])
3581 addresses [call->inst.dreg] = build_alloca (ctx, sig->ret);
3582 LLVMBuildStore (builder, lcall, addresses [call->inst.dreg]);
3584 case LLVMArgAsIArgs:
3585 case LLVMArgFpStruct:
3586 if (!addresses [call->inst.dreg])
3587 addresses [call->inst.dreg] = build_alloca (ctx, sig->ret);
3588 LLVMBuildStore (builder, lcall, convert_full (ctx, addresses [call->inst.dreg], LLVMPointerType (LLVMTypeOf (lcall), 0), FALSE));
3590 case LLVMArgVtypeAsScalar:
3591 if (!addresses [call->inst.dreg])
3592 addresses [call->inst.dreg] = build_alloca (ctx, sig->ret);
3593 LLVMBuildStore (builder, lcall, convert_full (ctx, addresses [call->inst.dreg], LLVMPointerType (LLVMTypeOf (lcall), 0), FALSE));
3595 case LLVMArgVtypeRetAddr:
3596 case LLVMArgVtypeByRef:
3597 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (sig->ret))) {
3598 /* Some opcodes like STOREX_MEMBASE access these by value */
3599 g_assert (addresses [call->inst.dreg]);
3600 values [ins->dreg] = LLVMBuildLoad (builder, convert_full (ctx, addresses [call->inst.dreg], LLVMPointerType (type_to_llvm_type (ctx, sig->ret), 0), FALSE), "");
3603 case LLVMArgGsharedvtVariable:
3605 case LLVMArgGsharedvtFixed:
3606 case LLVMArgGsharedvtFixedVtype:
3607 values [ins->dreg] = LLVMBuildLoad (builder, convert_full (ctx, addresses [call->inst.dreg], LLVMPointerType (type_to_llvm_type (ctx, sig->ret), 0), FALSE), "");
3610 if (sig->ret->type != MONO_TYPE_VOID)
3611 /* If the method returns an unsigned value, need to zext it */
3612 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));
3616 *builder_ref = ctx->builder;
3620 emit_llvmonly_throw (EmitContext *ctx, MonoBasicBlock *bb, gboolean rethrow, LLVMValueRef exc)
3622 const char *icall_name = rethrow ? "mono_llvm_rethrow_exception" : "mono_llvm_throw_exception";
3623 LLVMValueRef callee = rethrow ? ctx->module->rethrow : ctx->module->throw_icall;
3625 LLVMTypeRef exc_type = type_to_llvm_type (ctx, &mono_get_exception_class ()->byval_arg);
3628 LLVMTypeRef fun_sig = LLVMFunctionType1 (LLVMVoidType (), exc_type, FALSE);
3630 if (ctx->cfg->compile_aot) {
3631 callee = get_callee (ctx, fun_sig, MONO_PATCH_INFO_JIT_ICALL_ADDR, icall_name);
3633 callee = LLVMAddFunction (ctx->lmodule, icall_name, fun_sig);
3634 LLVMAddGlobalMapping (ctx->module->ee, callee, resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name));
3635 mono_memory_barrier ();
3638 ctx->module->rethrow = callee;
3640 ctx->module->throw_icall = callee;
3644 LLVMValueRef args [2];
3646 args [0] = convert (ctx, exc, exc_type);
3647 emit_call (ctx, bb, &ctx->builder, callee, args, 1);
3649 LLVMBuildUnreachable (ctx->builder);
3651 ctx->builder = create_builder (ctx);
3655 emit_throw (EmitContext *ctx, MonoBasicBlock *bb, gboolean rethrow, LLVMValueRef exc)
3657 MonoMethodSignature *throw_sig;
3658 LLVMValueRef callee, arg;
3659 const char *icall_name;
3661 callee = rethrow ? ctx->module->rethrow : ctx->module->throw_icall;
3662 icall_name = rethrow ? "mono_arch_rethrow_exception" : "mono_arch_throw_exception";
3665 throw_sig = mono_metadata_signature_alloc (mono_get_corlib (), 1);
3666 throw_sig->ret = &mono_get_void_class ()->byval_arg;
3667 throw_sig->params [0] = &mono_get_object_class ()->byval_arg;
3668 if (ctx->cfg->compile_aot) {
3669 callee = get_callee (ctx, sig_to_llvm_sig (ctx, throw_sig), MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
3674 * LLVM doesn't push the exception argument, so we need a different
3677 target = resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, rethrow ? "llvm_rethrow_exception_trampoline" : "llvm_throw_exception_trampoline");
3679 target = resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
3681 callee = emit_jit_callee (ctx, icall_name, sig_to_llvm_sig (ctx, throw_sig), target);
3684 mono_memory_barrier ();
3685 #if LLVM_API_VERSION < 100
3687 ctx->module->rethrow = callee;
3689 ctx->module->throw_icall = callee;
3692 arg = convert (ctx, exc, type_to_llvm_type (ctx, &mono_get_object_class ()->byval_arg));
3693 emit_call (ctx, bb, &ctx->builder, callee, &arg, 1);
3697 emit_resume_eh (EmitContext *ctx, MonoBasicBlock *bb)
3699 const char *icall_name = "mono_llvm_resume_exception";
3700 LLVMValueRef callee = ctx->module->resume_eh;
3702 LLVMTypeRef fun_sig = LLVMFunctionType0 (LLVMVoidType (), FALSE);
3705 if (ctx->cfg->compile_aot) {
3706 callee = get_callee (ctx, fun_sig, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
3708 callee = LLVMAddFunction (ctx->lmodule, icall_name, fun_sig);
3709 LLVMAddGlobalMapping (ctx->module->ee, callee, resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name));
3710 mono_memory_barrier ();
3712 ctx->module->resume_eh = callee;
3716 emit_call (ctx, bb, &ctx->builder, callee, NULL, 0);
3718 LLVMBuildUnreachable (ctx->builder);
3720 ctx->builder = create_builder (ctx);
3724 mono_llvm_emit_clear_exception_call (EmitContext *ctx, LLVMBuilderRef builder)
3726 const char *icall_name = "mono_llvm_clear_exception";
3728 LLVMTypeRef call_sig = LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE);
3729 LLVMValueRef callee = NULL;
3732 if (ctx->cfg->compile_aot) {
3733 callee = get_callee (ctx, call_sig, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
3735 // FIXME: This is broken.
3736 callee = LLVMAddFunction (ctx->lmodule, icall_name, call_sig);
3740 g_assert (builder && callee);
3742 return LLVMBuildCall (builder, callee, NULL, 0, "");
3746 mono_llvm_emit_load_exception_call (EmitContext *ctx, LLVMBuilderRef builder)
3748 const char *icall_name = "mono_llvm_load_exception";
3750 LLVMTypeRef call_sig = LLVMFunctionType (ObjRefType (), NULL, 0, FALSE);
3751 LLVMValueRef callee = NULL;
3754 if (ctx->cfg->compile_aot) {
3755 callee = get_callee (ctx, call_sig, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
3757 // FIXME: This is broken.
3758 callee = LLVMAddFunction (ctx->lmodule, icall_name, call_sig);
3762 g_assert (builder && callee);
3764 return LLVMBuildCall (builder, callee, NULL, 0, icall_name);
3769 mono_llvm_emit_match_exception_call (EmitContext *ctx, LLVMBuilderRef builder, gint32 region_start, gint32 region_end)
3771 const char *icall_name = "mono_llvm_match_exception";
3773 ctx->builder = builder;
3775 const int num_args = 5;
3776 LLVMValueRef args [num_args];
3777 args [0] = convert (ctx, get_aotconst (ctx, MONO_PATCH_INFO_AOT_JIT_INFO, GINT_TO_POINTER (ctx->cfg->method_index)), IntPtrType ());
3778 args [1] = LLVMConstInt (LLVMInt32Type (), region_start, 0);
3779 args [2] = LLVMConstInt (LLVMInt32Type (), region_end, 0);
3780 if (ctx->cfg->rgctx_var) {
3781 LLVMValueRef rgctx_alloc = ctx->addresses [ctx->cfg->rgctx_var->dreg];
3782 g_assert (rgctx_alloc);
3783 args [3] = LLVMBuildLoad (builder, convert (ctx, rgctx_alloc, LLVMPointerType (IntPtrType (), 0)), "");
3785 args [3] = LLVMConstInt (IntPtrType (), 0, 0);
3788 args [4] = convert (ctx, ctx->this_arg, IntPtrType ());
3790 args [4] = LLVMConstInt (IntPtrType (), 0, 0);
3792 LLVMTypeRef match_sig = LLVMFunctionType5 (LLVMInt32Type (), IntPtrType (), LLVMInt32Type (), LLVMInt32Type (), IntPtrType (), IntPtrType (), FALSE);
3793 LLVMValueRef callee = ctx->module->match_exc;
3796 if (ctx->cfg->compile_aot) {
3797 ctx->builder = builder;
3798 // get_callee expects ctx->builder to be the emitting builder
3799 callee = get_callee (ctx, match_sig, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
3801 callee = ctx->module->match_exc = LLVMAddFunction (ctx->lmodule, icall_name, match_sig);
3802 LLVMAddGlobalMapping (ctx->module->ee, ctx->module->match_exc, resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name));
3803 ctx->module->match_exc = callee;
3804 mono_memory_barrier ();
3808 g_assert (builder && callee);
3810 g_assert (ctx->ex_var);
3812 return LLVMBuildCall (builder, callee, args, num_args, icall_name);
3815 // FIXME: This won't work because the code-finding makes this
3817 /*#define MONO_PERSONALITY_DEBUG*/
3819 #ifdef MONO_PERSONALITY_DEBUG
3820 static const gboolean use_debug_personality = TRUE;
3821 static const char *default_personality_name = "mono_debug_personality";
3823 static const gboolean use_debug_personality = FALSE;
3824 static const char *default_personality_name = "__gxx_personality_v0";
3828 default_cpp_lpad_exc_signature (void)
3830 static gboolean inited = FALSE;
3831 static LLVMTypeRef sig;
3834 LLVMTypeRef signature [2];
3835 signature [0] = LLVMPointerType (LLVMInt8Type (), 0);
3836 signature [1] = LLVMInt32Type ();
3837 sig = LLVMStructType (signature, 2, FALSE);
3845 get_mono_personality (EmitContext *ctx)
3847 LLVMValueRef personality = NULL;
3848 static gint32 mapping_inited = FALSE;
3849 LLVMTypeRef personality_type = LLVMFunctionType (LLVMInt32Type (), NULL, 0, TRUE);
3851 if (!use_debug_personality) {
3852 if (ctx->cfg->compile_aot) {
3853 personality = get_intrinsic (ctx, default_personality_name);
3854 } else if (InterlockedCompareExchange (&mapping_inited, 1, 0) == 0) {
3855 personality = LLVMAddFunction (ctx->lmodule, default_personality_name, personality_type);
3856 LLVMAddGlobalMapping (ctx->module->ee, personality, personality);
3859 if (ctx->cfg->compile_aot) {
3860 personality = get_callee (ctx, personality_type, MONO_PATCH_INFO_INTERNAL_METHOD, default_personality_name);
3862 personality = LLVMAddFunction (ctx->lmodule, default_personality_name, personality_type);
3863 LLVMAddGlobalMapping (ctx->module->ee, personality, resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, default_personality_name));
3864 mono_memory_barrier ();
3868 g_assert (personality);
3872 static LLVMBasicBlockRef
3873 emit_landing_pad (EmitContext *ctx, int group_index, int group_size)
3875 MonoCompile *cfg = ctx->cfg;
3876 LLVMBuilderRef old_builder = ctx->builder;
3877 MonoExceptionClause *group_start = cfg->header->clauses + group_index;
3879 LLVMBuilderRef lpadBuilder = create_builder (ctx);
3880 ctx->builder = lpadBuilder;
3882 MonoBasicBlock *handler_bb = cfg->cil_offset_to_bb [CLAUSE_START (group_start)];
3883 g_assert (handler_bb);
3885 // <resultval> = landingpad <somety> personality <type> <pers_fn> <clause>+
3886 LLVMValueRef personality = get_mono_personality (ctx);
3887 g_assert (personality);
3889 char *bb_name = g_strdup_printf ("LPAD%d_BB", group_index);
3890 LLVMBasicBlockRef lpad_bb = gen_bb (ctx, bb_name);
3892 LLVMPositionBuilderAtEnd (lpadBuilder, lpad_bb);
3893 LLVMValueRef landing_pad = LLVMBuildLandingPad (lpadBuilder, default_cpp_lpad_exc_signature (), personality, 0, "");
3894 g_assert (landing_pad);
3896 LLVMValueRef cast = LLVMBuildBitCast (lpadBuilder, ctx->module->sentinel_exception, LLVMPointerType (LLVMInt8Type (), 0), "int8TypeInfo");
3897 LLVMAddClause (landing_pad, cast);
3899 LLVMBasicBlockRef resume_bb = gen_bb (ctx, "RESUME_BB");
3900 LLVMBuilderRef resume_builder = create_builder (ctx);
3901 ctx->builder = resume_builder;
3902 LLVMPositionBuilderAtEnd (resume_builder, resume_bb);
3904 emit_resume_eh (ctx, handler_bb);
3907 ctx->builder = lpadBuilder;
3908 LLVMPositionBuilderAtEnd (lpadBuilder, lpad_bb);
3910 gboolean finally_only = TRUE;
3912 MonoExceptionClause *group_cursor = group_start;
3914 for (int i = 0; i < group_size; i ++) {
3915 if (!(group_cursor->flags & MONO_EXCEPTION_CLAUSE_FINALLY))
3916 finally_only = FALSE;
3922 // Handle landing pad inlining
3924 if (!finally_only) {
3925 // So at each level of the exception stack we will match the exception again.
3926 // During that match, we need to compare against the handler types for the current
3927 // protected region. We send the try start and end so that we can only check against
3928 // handlers for this lexical protected region.
3929 LLVMValueRef match = mono_llvm_emit_match_exception_call (ctx, lpadBuilder, group_start->try_offset, group_start->try_offset + group_start->try_len);
3931 // if returns -1, resume
3932 LLVMValueRef switch_ins = LLVMBuildSwitch (lpadBuilder, match, resume_bb, group_size);
3934 // else move to that target bb
3935 for (int i = 0; i < group_size; i++) {
3936 MonoExceptionClause *clause = group_start + i;
3937 int clause_index = clause - cfg->header->clauses;
3938 MonoBasicBlock *handler_bb = (MonoBasicBlock*)g_hash_table_lookup (ctx->clause_to_handler, GINT_TO_POINTER (clause_index));
3939 g_assert (handler_bb);
3940 g_assert (ctx->bblocks [handler_bb->block_num].call_handler_target_bb);
3941 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), clause_index, FALSE), ctx->bblocks [handler_bb->block_num].call_handler_target_bb);
3944 int clause_index = group_start - cfg->header->clauses;
3945 MonoBasicBlock *finally_bb = (MonoBasicBlock*)g_hash_table_lookup (ctx->clause_to_handler, GINT_TO_POINTER (clause_index));
3946 g_assert (finally_bb);
3948 LLVMBuildBr (ctx->builder, ctx->bblocks [finally_bb->block_num].call_handler_target_bb);
3951 ctx->builder = old_builder;
3958 emit_llvmonly_handler_start (EmitContext *ctx, MonoBasicBlock *bb, LLVMBasicBlockRef cbb)
3960 int clause_index = MONO_REGION_CLAUSE_INDEX (bb->region);
3961 MonoExceptionClause *clause = &ctx->cfg->header->clauses [clause_index];
3963 // Make exception available to catch blocks
3964 if (!(clause->flags & MONO_EXCEPTION_CLAUSE_FINALLY)) {
3965 LLVMValueRef mono_exc = mono_llvm_emit_load_exception_call (ctx, ctx->builder);
3967 g_assert (ctx->ex_var);
3968 LLVMBuildStore (ctx->builder, LLVMBuildBitCast (ctx->builder, mono_exc, ObjRefType (), ""), ctx->ex_var);
3970 if (bb->in_scount == 1) {
3971 MonoInst *exvar = bb->in_stack [0];
3972 g_assert (!ctx->values [exvar->dreg]);
3973 g_assert (ctx->ex_var);
3974 ctx->values [exvar->dreg] = LLVMBuildLoad (ctx->builder, ctx->ex_var, "save_exception");
3975 emit_volatile_store (ctx, exvar->dreg);
3978 mono_llvm_emit_clear_exception_call (ctx, ctx->builder);
3981 LLVMBuilderRef handler_builder = create_builder (ctx);
3982 LLVMBasicBlockRef target_bb = ctx->bblocks [bb->block_num].call_handler_target_bb;
3983 LLVMPositionBuilderAtEnd (handler_builder, target_bb);
3985 // Make the handler code end with a jump to cbb
3986 LLVMBuildBr (handler_builder, cbb);
3990 emit_handler_start (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef builder)
3992 MonoCompile *cfg = ctx->cfg;
3993 LLVMValueRef *values = ctx->values;
3994 LLVMModuleRef lmodule = ctx->lmodule;
3995 BBInfo *bblocks = ctx->bblocks;
3997 LLVMValueRef personality;
3998 LLVMValueRef landing_pad;
3999 LLVMBasicBlockRef target_bb;
4001 static int ti_generator;
4003 LLVMValueRef type_info;
4007 // <resultval> = landingpad <somety> personality <type> <pers_fn> <clause>+
4009 if (cfg->compile_aot) {
4010 /* Use a dummy personality function */
4011 personality = LLVMGetNamedFunction (lmodule, "mono_personality");
4012 g_assert (personality);
4014 #if LLVM_API_VERSION > 100
4015 personality = ctx->module->personality;
4017 LLVMTypeRef personality_type = LLVMFunctionType (LLVMInt32Type (), NULL, 0, TRUE);
4018 personality = LLVMAddFunction (ctx->lmodule, "mono_personality", personality_type);
4019 LLVMAddFunctionAttr (personality, LLVMNoUnwindAttribute);
4020 LLVMBasicBlockRef entry_bb = LLVMAppendBasicBlock (personality, "ENTRY");
4021 LLVMBuilderRef builder2 = LLVMCreateBuilder ();
4022 LLVMPositionBuilderAtEnd (builder2, entry_bb);
4023 LLVMBuildRet (builder2, LLVMConstInt (LLVMInt32Type (), 0, FALSE));
4024 ctx->module->personality = personality;
4025 LLVMDisposeBuilder (builder2);
4028 static gint32 mapping_inited;
4030 personality = LLVMGetNamedFunction (lmodule, "mono_personality");
4032 if (InterlockedCompareExchange (&mapping_inited, 1, 0) == 0)
4033 LLVMAddGlobalMapping (ctx->module->ee, personality, (gpointer)mono_personality);
4037 i8ptr = LLVMPointerType (LLVMInt8Type (), 0);
4039 clause_index = (mono_get_block_region_notry (cfg, bb->region) >> 8) - 1;
4042 * Create the type info
4044 sprintf (ti_name, "type_info_%d", ti_generator);
4047 if (cfg->compile_aot) {
4048 /* decode_eh_frame () in aot-runtime.c will decode this */
4049 type_info = LLVMAddGlobal (lmodule, LLVMInt32Type (), ti_name);
4050 LLVMSetInitializer (type_info, LLVMConstInt (LLVMInt32Type (), clause_index, FALSE));
4053 * These symbols are not really used, the clause_index is embedded into the EH tables generated by DwarfMonoException in LLVM.
4055 LLVMSetLinkage (type_info, LLVMInternalLinkage);
4057 #if LLVM_API_VERSION > 100
4058 type_info = LLVMAddGlobal (lmodule, LLVMInt32Type (), ti_name);
4059 LLVMSetInitializer (type_info, LLVMConstInt (LLVMInt32Type (), clause_index, FALSE));
4064 * After the cfg mempool is freed, the type info will point to stale memory,
4065 * but this is not a problem, since we decode it once in exception_cb during
4068 ti = (gint32*)mono_mempool_alloc (cfg->mempool, sizeof (gint32));
4069 *(gint32*)ti = clause_index;
4071 type_info = LLVMAddGlobal (lmodule, i8ptr, ti_name);
4073 LLVMAddGlobalMapping (ctx->module->ee, type_info, ti);
4078 LLVMTypeRef members [2], ret_type;
4080 members [0] = i8ptr;
4081 members [1] = LLVMInt32Type ();
4082 ret_type = LLVMStructType (members, 2, FALSE);
4084 landing_pad = LLVMBuildLandingPad (builder, ret_type, personality, 1, "");
4085 LLVMAddClause (landing_pad, type_info);
4087 /* Store the exception into the exvar */
4089 LLVMBuildStore (builder, convert (ctx, LLVMBuildExtractValue (builder, landing_pad, 0, "ex_obj"), ObjRefType ()), ctx->ex_var);
4093 * LLVM throw sites are associated with a one landing pad, and LLVM generated
4094 * code expects control to be transferred to this landing pad even in the
4095 * presence of nested clauses. The landing pad needs to branch to the landing
4096 * pads belonging to nested clauses based on the selector value returned by
4097 * the landing pad instruction, which is passed to the landing pad in a
4098 * register by the EH code.
4100 target_bb = bblocks [bb->block_num].call_handler_target_bb;
4101 g_assert (target_bb);
4104 * Branch to the correct landing pad
4106 LLVMValueRef ex_selector = LLVMBuildExtractValue (builder, landing_pad, 1, "ex_selector");
4107 LLVMValueRef switch_ins = LLVMBuildSwitch (builder, ex_selector, target_bb, 0);
4109 for (l = ctx->nested_in [clause_index]; l; l = l->next) {
4110 int nesting_clause_index = GPOINTER_TO_INT (l->data);
4111 MonoBasicBlock *handler_bb;
4113 handler_bb = (MonoBasicBlock*)g_hash_table_lookup (ctx->clause_to_handler, GINT_TO_POINTER (nesting_clause_index));
4114 g_assert (handler_bb);
4116 g_assert (ctx->bblocks [handler_bb->block_num].call_handler_target_bb);
4117 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), nesting_clause_index, FALSE), ctx->bblocks [handler_bb->block_num].call_handler_target_bb);
4120 /* Start a new bblock which CALL_HANDLER can branch to */
4121 target_bb = bblocks [bb->block_num].call_handler_target_bb;
4123 ctx->builder = builder = create_builder (ctx);
4124 LLVMPositionBuilderAtEnd (ctx->builder, target_bb);
4126 ctx->bblocks [bb->block_num].end_bblock = target_bb;
4128 /* Store the exception into the IL level exvar */
4129 if (bb->in_scount == 1) {
4130 g_assert (bb->in_scount == 1);
4131 exvar = bb->in_stack [0];
4133 // FIXME: This is shared with filter clauses ?
4134 g_assert (!values [exvar->dreg]);
4136 g_assert (ctx->ex_var);
4137 values [exvar->dreg] = LLVMBuildLoad (builder, ctx->ex_var, "");
4138 emit_volatile_store (ctx, exvar->dreg);
4144 process_bb (EmitContext *ctx, MonoBasicBlock *bb)
4146 MonoCompile *cfg = ctx->cfg;
4147 MonoMethodSignature *sig = ctx->sig;
4148 LLVMValueRef method = ctx->lmethod;
4149 LLVMValueRef *values = ctx->values;
4150 LLVMValueRef *addresses = ctx->addresses;
4151 LLVMCallInfo *linfo = ctx->linfo;
4152 BBInfo *bblocks = ctx->bblocks;
4154 LLVMBasicBlockRef cbb;
4155 LLVMBuilderRef builder, starting_builder;
4156 gboolean has_terminator;
4158 LLVMValueRef lhs, rhs;
4161 cbb = get_end_bb (ctx, bb);
4163 builder = create_builder (ctx);
4164 ctx->builder = builder;
4165 LLVMPositionBuilderAtEnd (builder, cbb);
4170 if (bb->flags & BB_EXCEPTION_HANDLER) {
4171 if (!ctx->llvm_only && !bblocks [bb->block_num].invoke_target) {
4172 set_failure (ctx, "handler without invokes");
4177 emit_llvmonly_handler_start (ctx, bb, cbb);
4179 emit_handler_start (ctx, bb, builder);
4182 builder = ctx->builder;
4185 has_terminator = FALSE;
4186 starting_builder = builder;
4187 for (ins = bb->code; ins; ins = ins->next) {
4188 const char *spec = LLVM_INS_INFO (ins->opcode);
4190 char dname_buf [128];
4192 emit_dbg_loc (ctx, builder, ins->cil_code);
4197 * Some steps in llc are non-linear in the size of basic blocks, see #5714.
4198 * Start a new bblock.
4199 * Prevent the bblocks to be merged by doing a volatile load + cond branch
4200 * from localloc-ed memory.
4202 if (!cfg->llvm_only)
4203 ;//set_failure (ctx, "basic block too long");
4205 if (!ctx->long_bb_break_var) {
4206 ctx->long_bb_break_var = build_alloca_llvm_type_name (ctx, LLVMInt32Type (), 0, "long_bb_break");
4207 mono_llvm_build_store (ctx->alloca_builder, LLVMConstInt (LLVMInt32Type (), 0, FALSE), ctx->long_bb_break_var, TRUE, LLVM_BARRIER_NONE);
4210 cbb = gen_bb (ctx, "CONT_LONG_BB");
4211 LLVMBasicBlockRef dummy_bb = gen_bb (ctx, "CONT_LONG_BB_DUMMY");
4213 LLVMValueRef load = mono_llvm_build_load (builder, ctx->long_bb_break_var, "", TRUE);
4215 * The long_bb_break_var is initialized to 0 in the prolog, so this branch will always go to 'cbb'
4216 * but llvm doesn't know that, so the branch is not going to be eliminated.
4218 LLVMValueRef cmp = LLVMBuildICmp (builder, LLVMIntEQ, load, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
4220 LLVMBuildCondBr (builder, cmp, cbb, dummy_bb);
4222 /* Emit a dummy false bblock which does nothing but contains a volatile store so it cannot be eliminated */
4223 ctx->builder = builder = create_builder (ctx);
4224 LLVMPositionBuilderAtEnd (builder, dummy_bb);
4225 mono_llvm_build_store (builder, LLVMConstInt (LLVMInt32Type (), 1, FALSE), ctx->long_bb_break_var, TRUE, LLVM_BARRIER_NONE);
4226 LLVMBuildBr (builder, cbb);
4228 ctx->builder = builder = create_builder (ctx);
4229 LLVMPositionBuilderAtEnd (builder, cbb);
4230 ctx->bblocks [bb->block_num].end_bblock = cbb;
4235 /* There could be instructions after a terminator, skip them */
4238 if (spec [MONO_INST_DEST] != ' ' && !MONO_IS_STORE_MEMBASE (ins)) {
4239 sprintf (dname_buf, "t%d", ins->dreg);
4243 if (spec [MONO_INST_SRC1] != ' ' && spec [MONO_INST_SRC1] != 'v') {
4244 MonoInst *var = get_vreg_to_inst (cfg, ins->sreg1);
4246 if (var && var->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT) && var->opcode != OP_GSHAREDVT_ARG_REGOFFSET) {
4247 lhs = emit_volatile_load (ctx, ins->sreg1);
4249 /* It is ok for SETRET to have an uninitialized argument */
4250 if (!values [ins->sreg1] && ins->opcode != OP_SETRET) {
4251 set_failure (ctx, "sreg1");
4254 lhs = values [ins->sreg1];
4260 if (spec [MONO_INST_SRC2] != ' ' && spec [MONO_INST_SRC2] != ' ') {
4261 MonoInst *var = get_vreg_to_inst (cfg, ins->sreg2);
4262 if (var && var->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT)) {
4263 rhs = emit_volatile_load (ctx, ins->sreg2);
4265 if (!values [ins->sreg2]) {
4266 set_failure (ctx, "sreg2");
4269 rhs = values [ins->sreg2];
4275 //mono_print_ins (ins);
4276 switch (ins->opcode) {
4279 case OP_LIVERANGE_START:
4280 case OP_LIVERANGE_END:
4283 values [ins->dreg] = LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE);
4286 #if SIZEOF_VOID_P == 4
4287 values [ins->dreg] = LLVMConstInt (LLVMInt64Type (), GET_LONG_IMM (ins), FALSE);
4289 values [ins->dreg] = LLVMConstInt (LLVMInt64Type (), (gint64)ins->inst_c0, FALSE);
4293 values [ins->dreg] = LLVMConstReal (LLVMDoubleType (), *(double*)ins->inst_p0);
4297 values [ins->dreg] = LLVMConstReal (LLVMFloatType (), *(float*)ins->inst_p0);
4299 values [ins->dreg] = LLVMConstFPExt (LLVMConstReal (LLVMFloatType (), *(float*)ins->inst_p0), LLVMDoubleType ());
4301 case OP_DUMMY_ICONST:
4302 values [ins->dreg] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
4304 case OP_DUMMY_I8CONST:
4305 values [ins->dreg] = LLVMConstInt (LLVMInt64Type (), 0, FALSE);
4307 case OP_DUMMY_R8CONST:
4308 values [ins->dreg] = LLVMConstReal (LLVMDoubleType (), 0.0f);
4311 LLVMBasicBlockRef target_bb = get_bb (ctx, ins->inst_target_bb);
4312 LLVMBuildBr (builder, target_bb);
4313 has_terminator = TRUE;
4320 LLVMBasicBlockRef new_bb;
4321 LLVMBuilderRef new_builder;
4323 // The default branch is already handled
4324 // FIXME: Handle it here
4326 /* Start new bblock */
4327 sprintf (bb_name, "SWITCH_DEFAULT_BB%d", ctx->default_index ++);
4328 new_bb = LLVMAppendBasicBlock (ctx->lmethod, bb_name);
4330 lhs = convert (ctx, lhs, LLVMInt32Type ());
4331 v = LLVMBuildSwitch (builder, lhs, new_bb, GPOINTER_TO_UINT (ins->klass));
4332 for (i = 0; i < GPOINTER_TO_UINT (ins->klass); ++i) {
4333 MonoBasicBlock *target_bb = ins->inst_many_bb [i];
4335 LLVMAddCase (v, LLVMConstInt (LLVMInt32Type (), i, FALSE), get_bb (ctx, target_bb));
4338 new_builder = create_builder (ctx);
4339 LLVMPositionBuilderAtEnd (new_builder, new_bb);
4340 LLVMBuildUnreachable (new_builder);
4342 has_terminator = TRUE;
4343 g_assert (!ins->next);
4349 switch (linfo->ret.storage) {
4350 case LLVMArgVtypeInReg: {
4351 LLVMTypeRef ret_type = LLVMGetReturnType (LLVMGetElementType (LLVMTypeOf (method)));
4352 LLVMValueRef val, addr, retval;
4355 retval = LLVMGetUndef (ret_type);
4357 if (!addresses [ins->sreg1]) {
4359 * The return type is an LLVM vector type, have to convert between it and the
4360 * real return type which is a struct type.
4362 g_assert (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (sig->ret)));
4363 /* Convert to 2xi64 first */
4364 val = LLVMBuildBitCast (builder, values [ins->sreg1], LLVMVectorType (IntPtrType (), 2), "");
4366 for (i = 0; i < 2; ++i) {
4367 if (linfo->ret.pair_storage [i] == LLVMArgInIReg) {
4368 retval = LLVMBuildInsertValue (builder, retval, LLVMBuildExtractElement (builder, val, LLVMConstInt (LLVMInt32Type (), i, FALSE), ""), i, "");
4370 g_assert (linfo->ret.pair_storage [i] == LLVMArgNone);
4374 addr = LLVMBuildBitCast (builder, addresses [ins->sreg1], LLVMPointerType (ret_type, 0), "");
4375 for (i = 0; i < 2; ++i) {
4376 if (linfo->ret.pair_storage [i] == LLVMArgInIReg) {
4377 LLVMValueRef indexes [2], part_addr;
4379 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
4380 indexes [1] = LLVMConstInt (LLVMInt32Type (), i, FALSE);
4381 part_addr = LLVMBuildGEP (builder, addr, indexes, 2, "");
4383 retval = LLVMBuildInsertValue (builder, retval, LLVMBuildLoad (builder, part_addr, ""), i, "");
4385 g_assert (linfo->ret.pair_storage [i] == LLVMArgNone);
4389 LLVMBuildRet (builder, retval);
4392 case LLVMArgVtypeAsScalar: {
4393 LLVMTypeRef ret_type = LLVMGetReturnType (LLVMGetElementType (LLVMTypeOf (method)));
4394 LLVMValueRef retval;
4396 g_assert (addresses [ins->sreg1]);
4398 retval = LLVMBuildLoad (builder, LLVMBuildBitCast (builder, addresses [ins->sreg1], LLVMPointerType (ret_type, 0), ""), "");
4399 LLVMBuildRet (builder, retval);
4402 case LLVMArgVtypeByVal: {
4403 LLVMValueRef retval;
4405 g_assert (addresses [ins->sreg1]);
4406 retval = LLVMBuildLoad (builder, addresses [ins->sreg1], "");
4407 LLVMBuildRet (builder, retval);
4410 case LLVMArgVtypeByRef: {
4411 LLVMBuildRetVoid (builder);
4414 case LLVMArgGsharedvtFixed: {
4415 LLVMTypeRef ret_type = type_to_llvm_type (ctx, sig->ret);
4416 /* The return value is in lhs, need to store to the vret argument */
4417 /* sreg1 might not be set */
4419 g_assert (cfg->vret_addr);
4420 g_assert (values [cfg->vret_addr->dreg]);
4421 LLVMBuildStore (builder, convert (ctx, lhs, ret_type), convert (ctx, values [cfg->vret_addr->dreg], LLVMPointerType (ret_type, 0)));
4423 LLVMBuildRetVoid (builder);
4426 case LLVMArgGsharedvtFixedVtype: {
4428 LLVMBuildRetVoid (builder);
4431 case LLVMArgGsharedvtVariable: {
4433 LLVMBuildRetVoid (builder);
4436 case LLVMArgVtypeRetAddr: {
4437 LLVMBuildRetVoid (builder);
4440 case LLVMArgAsIArgs:
4441 case LLVMArgFpStruct: {
4442 LLVMTypeRef ret_type = LLVMGetReturnType (LLVMGetElementType (LLVMTypeOf (method)));
4443 LLVMValueRef retval;
4445 g_assert (addresses [ins->sreg1]);
4446 retval = LLVMBuildLoad (builder, convert (ctx, addresses [ins->sreg1], LLVMPointerType (ret_type, 0)), "");
4447 LLVMBuildRet (builder, retval);
4451 case LLVMArgNormal: {
4452 if (!lhs || ctx->is_dead [ins->sreg1]) {
4454 * The method did not set its return value, probably because it
4455 * ends with a throw.
4458 LLVMBuildRetVoid (builder);
4460 LLVMBuildRet (builder, LLVMConstNull (type_to_llvm_type (ctx, sig->ret)));
4462 LLVMBuildRet (builder, convert (ctx, lhs, type_to_llvm_type (ctx, sig->ret)));
4464 has_terminator = TRUE;
4468 g_assert_not_reached ();
4477 case OP_ICOMPARE_IMM:
4478 case OP_LCOMPARE_IMM:
4479 case OP_COMPARE_IMM: {
4481 LLVMValueRef cmp, args [16];
4482 gboolean likely = (ins->flags & MONO_INST_LIKELY) != 0;
4484 if (ins->next->opcode == OP_NOP)
4487 if (ins->next->opcode == OP_BR)
4488 /* The comparison result is not needed */
4491 rel = mono_opcode_to_cond (ins->next->opcode);
4493 if (ins->opcode == OP_ICOMPARE_IMM) {
4494 lhs = convert (ctx, lhs, LLVMInt32Type ());
4495 rhs = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
4497 if (ins->opcode == OP_LCOMPARE_IMM) {
4498 lhs = convert (ctx, lhs, LLVMInt64Type ());
4499 rhs = LLVMConstInt (LLVMInt64Type (), GET_LONG_IMM (ins), FALSE);
4501 if (ins->opcode == OP_LCOMPARE) {
4502 lhs = convert (ctx, lhs, LLVMInt64Type ());
4503 rhs = convert (ctx, rhs, LLVMInt64Type ());
4505 if (ins->opcode == OP_ICOMPARE) {
4506 lhs = convert (ctx, lhs, LLVMInt32Type ());
4507 rhs = convert (ctx, rhs, LLVMInt32Type ());
4511 if (LLVMGetTypeKind (LLVMTypeOf (lhs)) == LLVMPointerTypeKind)
4512 rhs = convert (ctx, rhs, LLVMTypeOf (lhs));
4513 else if (LLVMGetTypeKind (LLVMTypeOf (rhs)) == LLVMPointerTypeKind)
4514 lhs = convert (ctx, lhs, LLVMTypeOf (rhs));
4517 /* We use COMPARE+SETcc/Bcc, llvm uses SETcc+br cond */
4518 if (ins->opcode == OP_FCOMPARE) {
4519 cmp = LLVMBuildFCmp (builder, fpcond_to_llvm_cond [rel], convert (ctx, lhs, LLVMDoubleType ()), convert (ctx, rhs, LLVMDoubleType ()), "");
4520 } else if (ins->opcode == OP_RCOMPARE) {
4521 cmp = LLVMBuildFCmp (builder, fpcond_to_llvm_cond [rel], convert (ctx, lhs, LLVMFloatType ()), convert (ctx, rhs, LLVMFloatType ()), "");
4522 } else if (ins->opcode == OP_COMPARE_IMM) {
4523 if (LLVMGetTypeKind (LLVMTypeOf (lhs)) == LLVMPointerTypeKind && ins->inst_imm == 0)
4524 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], lhs, LLVMConstNull (LLVMTypeOf (lhs)), "");
4526 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE), "");
4527 } else if (ins->opcode == OP_LCOMPARE_IMM) {
4528 if (SIZEOF_REGISTER == 4 && COMPILE_LLVM (cfg)) {
4529 /* The immediate is encoded in two fields */
4530 guint64 l = ((guint64)(guint32)ins->inst_offset << 32) | ((guint32)ins->inst_imm);
4531 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, LLVMInt64Type ()), LLVMConstInt (LLVMInt64Type (), l, FALSE), "");
4533 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, LLVMInt64Type ()), LLVMConstInt (LLVMInt64Type (), ins->inst_imm, FALSE), "");
4536 else if (ins->opcode == OP_COMPARE) {
4537 if (LLVMGetTypeKind (LLVMTypeOf (lhs)) == LLVMPointerTypeKind && LLVMTypeOf (lhs) == LLVMTypeOf (rhs))
4538 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], lhs, rhs, "");
4540 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, IntPtrType ()), convert (ctx, rhs, IntPtrType ()), "");
4542 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], lhs, rhs, "");
4546 args [1] = LLVMConstInt (LLVMInt1Type (), 1, FALSE);
4547 cmp = LLVMBuildCall (ctx->builder, get_intrinsic (ctx, "llvm.expect.i1"), args, 2, "");
4550 if (MONO_IS_COND_BRANCH_OP (ins->next)) {
4551 if (ins->next->inst_true_bb == ins->next->inst_false_bb) {
4553 * If the target bb contains PHI instructions, LLVM requires
4554 * two PHI entries for this bblock, while we only generate one.
4555 * So convert this to an unconditional bblock. (bxc #171).
4557 LLVMBuildBr (builder, get_bb (ctx, ins->next->inst_true_bb));
4559 LLVMBuildCondBr (builder, cmp, get_bb (ctx, ins->next->inst_true_bb), get_bb (ctx, ins->next->inst_false_bb));
4561 has_terminator = TRUE;
4562 } else if (MONO_IS_SETCC (ins->next)) {
4563 sprintf (dname_buf, "t%d", ins->next->dreg);
4565 values [ins->next->dreg] = LLVMBuildZExt (builder, cmp, LLVMInt32Type (), dname);
4567 /* Add stores for volatile variables */
4568 emit_volatile_store (ctx, ins->next->dreg);
4569 } else if (MONO_IS_COND_EXC (ins->next)) {
4570 emit_cond_system_exception (ctx, bb, (const char*)ins->next->inst_p1, cmp);
4573 builder = ctx->builder;
4575 set_failure (ctx, "next");
4593 rel = mono_opcode_to_cond (ins->opcode);
4595 cmp = LLVMBuildFCmp (builder, fpcond_to_llvm_cond [rel], convert (ctx, lhs, LLVMDoubleType ()), convert (ctx, rhs, LLVMDoubleType ()), "");
4596 values [ins->dreg] = LLVMBuildZExt (builder, cmp, LLVMInt32Type (), dname);
4607 rel = mono_opcode_to_cond (ins->opcode);
4609 cmp = LLVMBuildFCmp (builder, fpcond_to_llvm_cond [rel], convert (ctx, lhs, LLVMFloatType ()), convert (ctx, rhs, LLVMFloatType ()), "");
4610 values [ins->dreg] = LLVMBuildZExt (builder, cmp, LLVMInt32Type (), dname);
4618 gboolean empty = TRUE;
4620 /* Check that all input bblocks really branch to us */
4621 for (i = 0; i < bb->in_count; ++i) {
4622 if (bb->in_bb [i]->last_ins && bb->in_bb [i]->last_ins->opcode == OP_NOT_REACHED)
4623 ins->inst_phi_args [i + 1] = -1;
4629 /* LLVM doesn't like phi instructions with zero operands */
4630 ctx->is_dead [ins->dreg] = TRUE;
4634 /* Created earlier, insert it now */
4635 LLVMInsertIntoBuilder (builder, values [ins->dreg]);
4637 for (i = 0; i < ins->inst_phi_args [0]; i++) {
4638 int sreg1 = ins->inst_phi_args [i + 1];
4642 * Count the number of times the incoming bblock branches to us,
4643 * since llvm requires a separate entry for each.
4645 if (bb->in_bb [i]->last_ins && bb->in_bb [i]->last_ins->opcode == OP_SWITCH) {
4646 MonoInst *switch_ins = bb->in_bb [i]->last_ins;
4649 for (j = 0; j < GPOINTER_TO_UINT (switch_ins->klass); ++j) {
4650 if (switch_ins->inst_many_bb [j] == bb)
4657 /* Remember for later */
4658 for (j = 0; j < count; ++j) {
4659 PhiNode *node = (PhiNode*)mono_mempool_alloc0 (ctx->mempool, sizeof (PhiNode));
4662 node->in_bb = bb->in_bb [i];
4664 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);
4674 values [ins->dreg] = lhs;
4678 MonoInst *var = get_vreg_to_inst (cfg, ins->dreg);
4681 values [ins->dreg] = lhs;
4683 if (var && var->klass->byval_arg.type == MONO_TYPE_R4) {
4685 * This is added by the spilling pass in case of the JIT,
4686 * but we have to do it ourselves.
4688 values [ins->dreg] = convert (ctx, values [ins->dreg], LLVMFloatType ());
4692 case OP_MOVE_F_TO_I4: {
4693 values [ins->dreg] = LLVMBuildBitCast (builder, LLVMBuildFPTrunc (builder, lhs, LLVMFloatType (), ""), LLVMInt32Type (), "");
4696 case OP_MOVE_I4_TO_F: {
4697 values [ins->dreg] = LLVMBuildFPExt (builder, LLVMBuildBitCast (builder, lhs, LLVMFloatType (), ""), LLVMDoubleType (), "");
4700 case OP_MOVE_F_TO_I8: {
4701 values [ins->dreg] = LLVMBuildBitCast (builder, lhs, LLVMInt64Type (), "");
4704 case OP_MOVE_I8_TO_F: {
4705 values [ins->dreg] = LLVMBuildBitCast (builder, lhs, LLVMDoubleType (), "");
4738 lhs = convert (ctx, lhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
4739 rhs = convert (ctx, rhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
4741 emit_div_check (ctx, builder, bb, ins, lhs, rhs);
4744 builder = ctx->builder;
4746 switch (ins->opcode) {
4749 values [ins->dreg] = LLVMBuildAdd (builder, lhs, rhs, dname);
4753 values [ins->dreg] = LLVMBuildSub (builder, lhs, rhs, dname);
4757 values [ins->dreg] = LLVMBuildMul (builder, lhs, rhs, dname);
4761 values [ins->dreg] = LLVMBuildSRem (builder, lhs, rhs, dname);
4765 values [ins->dreg] = LLVMBuildURem (builder, lhs, rhs, dname);
4769 values [ins->dreg] = LLVMBuildSDiv (builder, lhs, rhs, dname);
4773 values [ins->dreg] = LLVMBuildUDiv (builder, lhs, rhs, dname);
4777 values [ins->dreg] = LLVMBuildFDiv (builder, lhs, rhs, dname);
4781 values [ins->dreg] = LLVMBuildAnd (builder, lhs, rhs, dname);
4785 values [ins->dreg] = LLVMBuildOr (builder, lhs, rhs, dname);
4789 values [ins->dreg] = LLVMBuildXor (builder, lhs, rhs, dname);
4793 values [ins->dreg] = LLVMBuildShl (builder, lhs, rhs, dname);
4797 values [ins->dreg] = LLVMBuildAShr (builder, lhs, rhs, dname);
4801 values [ins->dreg] = LLVMBuildLShr (builder, lhs, rhs, dname);
4805 values [ins->dreg] = LLVMBuildFAdd (builder, lhs, rhs, dname);
4808 values [ins->dreg] = LLVMBuildFSub (builder, lhs, rhs, dname);
4811 values [ins->dreg] = LLVMBuildFMul (builder, lhs, rhs, dname);
4815 g_assert_not_reached ();
4822 lhs = convert (ctx, lhs, LLVMFloatType ());
4823 rhs = convert (ctx, rhs, LLVMFloatType ());
4824 switch (ins->opcode) {
4826 values [ins->dreg] = LLVMBuildFAdd (builder, lhs, rhs, dname);
4829 values [ins->dreg] = LLVMBuildFSub (builder, lhs, rhs, dname);
4832 values [ins->dreg] = LLVMBuildFMul (builder, lhs, rhs, dname);
4835 values [ins->dreg] = LLVMBuildFDiv (builder, lhs, rhs, dname);
4838 g_assert_not_reached ();
4847 case OP_IREM_UN_IMM:
4849 case OP_IDIV_UN_IMM:
4855 case OP_ISHR_UN_IMM:
4865 case OP_LSHR_UN_IMM:
4871 case OP_SHR_UN_IMM: {
4874 if (spec [MONO_INST_SRC1] == 'l') {
4875 imm = LLVMConstInt (LLVMInt64Type (), GET_LONG_IMM (ins), FALSE);
4877 imm = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
4880 emit_div_check (ctx, builder, bb, ins, lhs, imm);
4883 builder = ctx->builder;
4885 #if SIZEOF_VOID_P == 4
4886 if (ins->opcode == OP_LSHL_IMM || ins->opcode == OP_LSHR_IMM || ins->opcode == OP_LSHR_UN_IMM)
4887 imm = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
4890 if (LLVMGetTypeKind (LLVMTypeOf (lhs)) == LLVMPointerTypeKind)
4891 lhs = convert (ctx, lhs, IntPtrType ());
4892 imm = convert (ctx, imm, LLVMTypeOf (lhs));
4893 switch (ins->opcode) {
4897 values [ins->dreg] = LLVMBuildAdd (builder, lhs, imm, dname);
4901 values [ins->dreg] = LLVMBuildSub (builder, lhs, imm, dname);
4906 values [ins->dreg] = LLVMBuildMul (builder, lhs, imm, dname);
4910 values [ins->dreg] = LLVMBuildSDiv (builder, lhs, imm, dname);
4912 case OP_IDIV_UN_IMM:
4913 case OP_LDIV_UN_IMM:
4914 values [ins->dreg] = LLVMBuildUDiv (builder, lhs, imm, dname);
4918 values [ins->dreg] = LLVMBuildSRem (builder, lhs, imm, dname);
4920 case OP_IREM_UN_IMM:
4921 values [ins->dreg] = LLVMBuildURem (builder, lhs, imm, dname);
4926 values [ins->dreg] = LLVMBuildAnd (builder, lhs, imm, dname);
4930 values [ins->dreg] = LLVMBuildOr (builder, lhs, imm, dname);
4934 values [ins->dreg] = LLVMBuildXor (builder, lhs, imm, dname);
4939 values [ins->dreg] = LLVMBuildShl (builder, lhs, imm, dname);
4944 values [ins->dreg] = LLVMBuildAShr (builder, lhs, imm, dname);
4946 case OP_ISHR_UN_IMM:
4947 /* This is used to implement conv.u4, so the lhs could be an i8 */
4948 lhs = convert (ctx, lhs, LLVMInt32Type ());
4949 imm = convert (ctx, imm, LLVMInt32Type ());
4950 values [ins->dreg] = LLVMBuildLShr (builder, lhs, imm, dname);
4952 case OP_LSHR_UN_IMM:
4954 values [ins->dreg] = LLVMBuildLShr (builder, lhs, imm, dname);
4957 g_assert_not_reached ();
4962 values [ins->dreg] = LLVMBuildSub (builder, LLVMConstInt (LLVMInt32Type (), 0, FALSE), convert (ctx, lhs, LLVMInt32Type ()), dname);
4965 values [ins->dreg] = LLVMBuildSub (builder, LLVMConstInt (LLVMInt64Type (), 0, FALSE), lhs, dname);
4968 lhs = convert (ctx, lhs, LLVMDoubleType ());
4969 values [ins->dreg] = LLVMBuildFSub (builder, LLVMConstReal (LLVMDoubleType (), 0.0), lhs, dname);
4972 lhs = convert (ctx, lhs, LLVMFloatType ());
4973 values [ins->dreg] = LLVMBuildFSub (builder, LLVMConstReal (LLVMFloatType (), 0.0), lhs, dname);
4976 guint32 v = 0xffffffff;
4977 values [ins->dreg] = LLVMBuildXor (builder, LLVMConstInt (LLVMInt32Type (), v, FALSE), convert (ctx, lhs, LLVMInt32Type ()), dname);
4981 guint64 v = 0xffffffffffffffffLL;
4982 values [ins->dreg] = LLVMBuildXor (builder, LLVMConstInt (LLVMInt64Type (), v, FALSE), lhs, dname);
4985 #if defined(TARGET_X86) || defined(TARGET_AMD64)
4987 LLVMValueRef v1, v2;
4989 v1 = LLVMBuildMul (builder, convert (ctx, rhs, IntPtrType ()), LLVMConstInt (IntPtrType (), (1 << ins->backend.shift_amount), FALSE), "");
4990 v2 = LLVMBuildAdd (builder, convert (ctx, lhs, IntPtrType ()), v1, "");
4991 values [ins->dreg] = LLVMBuildAdd (builder, v2, LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE), dname);
4996 case OP_ICONV_TO_I1:
4997 case OP_ICONV_TO_I2:
4998 case OP_ICONV_TO_I4:
4999 case OP_ICONV_TO_U1:
5000 case OP_ICONV_TO_U2:
5001 case OP_ICONV_TO_U4:
5002 case OP_LCONV_TO_I1:
5003 case OP_LCONV_TO_I2:
5004 case OP_LCONV_TO_U1:
5005 case OP_LCONV_TO_U2:
5006 case OP_LCONV_TO_U4: {
5009 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);
5011 /* Have to do two casts since our vregs have type int */
5012 v = LLVMBuildTrunc (builder, lhs, op_to_llvm_type (ins->opcode), "");
5014 values [ins->dreg] = LLVMBuildSExt (builder, v, LLVMInt32Type (), dname);
5016 values [ins->dreg] = LLVMBuildZExt (builder, v, LLVMInt32Type (), dname);
5019 case OP_ICONV_TO_I8:
5020 values [ins->dreg] = LLVMBuildSExt (builder, lhs, LLVMInt64Type (), dname);
5022 case OP_ICONV_TO_U8:
5023 values [ins->dreg] = LLVMBuildZExt (builder, lhs, LLVMInt64Type (), dname);
5025 case OP_FCONV_TO_I4:
5026 case OP_RCONV_TO_I4:
5027 values [ins->dreg] = LLVMBuildFPToSI (builder, lhs, LLVMInt32Type (), dname);
5029 case OP_FCONV_TO_I1:
5030 case OP_RCONV_TO_I1:
5031 values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildFPToSI (builder, lhs, LLVMInt8Type (), dname), LLVMInt32Type (), "");
5033 case OP_FCONV_TO_U1:
5034 case OP_RCONV_TO_U1:
5035 values [ins->dreg] = LLVMBuildZExt (builder, LLVMBuildTrunc (builder, LLVMBuildFPToUI (builder, lhs, IntPtrType (), dname), LLVMInt8Type (), ""), LLVMInt32Type (), "");
5037 case OP_FCONV_TO_I2:
5038 case OP_RCONV_TO_I2:
5039 values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildFPToSI (builder, lhs, LLVMInt16Type (), dname), LLVMInt32Type (), "");
5041 case OP_FCONV_TO_U2:
5042 case OP_RCONV_TO_U2:
5043 values [ins->dreg] = LLVMBuildZExt (builder, LLVMBuildFPToUI (builder, lhs, LLVMInt16Type (), dname), LLVMInt32Type (), "");
5045 case OP_RCONV_TO_U4:
5046 values [ins->dreg] = LLVMBuildFPToUI (builder, lhs, LLVMInt32Type (), dname);
5048 case OP_FCONV_TO_I8:
5049 case OP_RCONV_TO_I8:
5050 values [ins->dreg] = LLVMBuildFPToSI (builder, lhs, LLVMInt64Type (), dname);
5053 values [ins->dreg] = LLVMBuildFPToSI (builder, lhs, IntPtrType (), dname);
5055 case OP_ICONV_TO_R8:
5056 case OP_LCONV_TO_R8:
5057 values [ins->dreg] = LLVMBuildSIToFP (builder, lhs, LLVMDoubleType (), dname);
5059 case OP_ICONV_TO_R_UN:
5060 case OP_LCONV_TO_R_UN:
5061 values [ins->dreg] = LLVMBuildUIToFP (builder, lhs, LLVMDoubleType (), dname);
5063 #if SIZEOF_VOID_P == 4
5066 case OP_LCONV_TO_I4:
5067 values [ins->dreg] = LLVMBuildTrunc (builder, lhs, LLVMInt32Type (), dname);
5069 case OP_ICONV_TO_R4:
5070 case OP_LCONV_TO_R4:
5071 v = LLVMBuildSIToFP (builder, lhs, LLVMFloatType (), "");
5073 values [ins->dreg] = v;
5075 values [ins->dreg] = LLVMBuildFPExt (builder, v, LLVMDoubleType (), dname);
5077 case OP_FCONV_TO_R4:
5078 v = LLVMBuildFPTrunc (builder, lhs, LLVMFloatType (), "");
5080 values [ins->dreg] = v;
5082 values [ins->dreg] = LLVMBuildFPExt (builder, v, LLVMDoubleType (), dname);
5084 case OP_RCONV_TO_R8:
5085 values [ins->dreg] = LLVMBuildFPExt (builder, lhs, LLVMDoubleType (), dname);
5087 case OP_RCONV_TO_R4:
5088 values [ins->dreg] = lhs;
5091 values [ins->dreg] = LLVMBuildSExt (builder, convert (ctx, lhs, LLVMInt32Type ()), LLVMInt64Type (), dname);
5094 values [ins->dreg] = LLVMBuildZExt (builder, convert (ctx, lhs, LLVMInt32Type ()), LLVMInt64Type (), dname);
5097 values [ins->dreg] = LLVMBuildTrunc (builder, lhs, LLVMInt32Type (), dname);
5099 case OP_LOCALLOC_IMM: {
5102 guint32 size = ins->inst_imm;
5103 size = (size + (MONO_ARCH_FRAME_ALIGNMENT - 1)) & ~ (MONO_ARCH_FRAME_ALIGNMENT - 1);
5105 v = mono_llvm_build_alloca (builder, LLVMInt8Type (), LLVMConstInt (LLVMInt32Type (), size, FALSE), MONO_ARCH_FRAME_ALIGNMENT, "");
5107 if (ins->flags & MONO_INST_INIT) {
5108 LLVMValueRef args [5];
5111 args [1] = LLVMConstInt (LLVMInt8Type (), 0, FALSE);
5112 args [2] = LLVMConstInt (LLVMInt32Type (), size, FALSE);
5113 args [3] = LLVMConstInt (LLVMInt32Type (), MONO_ARCH_FRAME_ALIGNMENT, FALSE);
5114 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
5115 LLVMBuildCall (builder, get_intrinsic (ctx, "llvm.memset.p0i8.i32"), args, 5, "");
5118 values [ins->dreg] = v;
5122 LLVMValueRef v, size;
5124 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), "");
5126 v = mono_llvm_build_alloca (builder, LLVMInt8Type (), size, MONO_ARCH_FRAME_ALIGNMENT, "");
5128 if (ins->flags & MONO_INST_INIT) {
5129 LLVMValueRef args [5];
5132 args [1] = LLVMConstInt (LLVMInt8Type (), 0, FALSE);
5134 args [3] = LLVMConstInt (LLVMInt32Type (), MONO_ARCH_FRAME_ALIGNMENT, FALSE);
5135 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
5136 LLVMBuildCall (builder, get_intrinsic (ctx, "llvm.memset.p0i8.i32"), args, 5, "");
5138 values [ins->dreg] = v;
5142 case OP_LOADI1_MEMBASE:
5143 case OP_LOADU1_MEMBASE:
5144 case OP_LOADI2_MEMBASE:
5145 case OP_LOADU2_MEMBASE:
5146 case OP_LOADI4_MEMBASE:
5147 case OP_LOADU4_MEMBASE:
5148 case OP_LOADI8_MEMBASE:
5149 case OP_LOADR4_MEMBASE:
5150 case OP_LOADR8_MEMBASE:
5151 case OP_LOAD_MEMBASE:
5159 LLVMValueRef base, index, addr;
5161 gboolean sext = FALSE, zext = FALSE;
5162 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
5164 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
5169 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)) {
5170 addr = LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE);
5176 if (ins->inst_offset == 0) {
5178 } else if (ins->inst_offset % size != 0) {
5179 /* Unaligned load */
5180 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset, FALSE);
5181 addr = LLVMBuildGEP (builder, convert (ctx, base, LLVMPointerType (LLVMInt8Type (), 0)), &index, 1, "");
5183 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
5184 addr = LLVMBuildGEP (builder, convert (ctx, base, LLVMPointerType (t, 0)), &index, 1, "");
5188 addr = convert (ctx, addr, LLVMPointerType (t, 0));
5190 values [ins->dreg] = emit_load_general (ctx, bb, &builder, size, addr, base, dname, is_volatile, LLVM_BARRIER_NONE);
5192 if (!is_volatile && (ins->flags & MONO_INST_INVARIANT_LOAD)) {
5194 * These will signal LLVM that these loads do not alias any stores, and
5195 * they can't fail, allowing them to be hoisted out of loops.
5197 set_invariant_load_flag (values [ins->dreg]);
5198 #if LLVM_API_VERSION < 100
5199 set_metadata_flag (values [ins->dreg], "mono.nofail.load");
5204 values [ins->dreg] = LLVMBuildSExt (builder, values [ins->dreg], LLVMInt32Type (), dname);
5206 values [ins->dreg] = LLVMBuildZExt (builder, values [ins->dreg], LLVMInt32Type (), dname);
5207 else if (!cfg->r4fp && ins->opcode == OP_LOADR4_MEMBASE)
5208 values [ins->dreg] = LLVMBuildFPExt (builder, values [ins->dreg], LLVMDoubleType (), dname);
5212 case OP_STOREI1_MEMBASE_REG:
5213 case OP_STOREI2_MEMBASE_REG:
5214 case OP_STOREI4_MEMBASE_REG:
5215 case OP_STOREI8_MEMBASE_REG:
5216 case OP_STORER4_MEMBASE_REG:
5217 case OP_STORER8_MEMBASE_REG:
5218 case OP_STORE_MEMBASE_REG: {
5220 LLVMValueRef index, addr, base;
5222 gboolean sext = FALSE, zext = FALSE;
5223 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
5225 if (!values [ins->inst_destbasereg]) {
5226 set_failure (ctx, "inst_destbasereg");
5230 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
5232 base = values [ins->inst_destbasereg];
5233 if (ins->inst_offset % size != 0) {
5234 /* Unaligned store */
5235 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset, FALSE);
5236 addr = LLVMBuildGEP (builder, convert (ctx, base, LLVMPointerType (LLVMInt8Type (), 0)), &index, 1, "");
5238 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
5239 addr = LLVMBuildGEP (builder, convert (ctx, base, LLVMPointerType (t, 0)), &index, 1, "");
5241 emit_store (ctx, bb, &builder, size, convert (ctx, values [ins->sreg1], t), convert (ctx, addr, LLVMPointerType (t, 0)), base, is_volatile);
5245 case OP_STOREI1_MEMBASE_IMM:
5246 case OP_STOREI2_MEMBASE_IMM:
5247 case OP_STOREI4_MEMBASE_IMM:
5248 case OP_STOREI8_MEMBASE_IMM:
5249 case OP_STORE_MEMBASE_IMM: {
5251 LLVMValueRef index, addr, base;
5253 gboolean sext = FALSE, zext = FALSE;
5254 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
5256 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
5258 base = values [ins->inst_destbasereg];
5259 if (ins->inst_offset % size != 0) {
5260 /* Unaligned store */
5261 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset, FALSE);
5262 addr = LLVMBuildGEP (builder, convert (ctx, base, LLVMPointerType (LLVMInt8Type (), 0)), &index, 1, "");
5264 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
5265 addr = LLVMBuildGEP (builder, convert (ctx, base, LLVMPointerType (t, 0)), &index, 1, "");
5267 emit_store (ctx, bb, &builder, size, convert (ctx, LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE), t), convert (ctx, addr, LLVMPointerType (t, 0)), base, is_volatile);
5272 emit_load_general (ctx, bb, &builder, sizeof (gpointer), convert (ctx, lhs, LLVMPointerType (IntPtrType (), 0)), lhs, "", TRUE, LLVM_BARRIER_NONE);
5274 case OP_OUTARG_VTRETADDR:
5282 case OP_VOIDCALL_MEMBASE:
5283 case OP_CALL_MEMBASE:
5284 case OP_LCALL_MEMBASE:
5285 case OP_FCALL_MEMBASE:
5286 case OP_RCALL_MEMBASE:
5287 case OP_VCALL_MEMBASE:
5288 case OP_VOIDCALL_REG:
5293 case OP_VCALL_REG: {
5294 process_call (ctx, bb, &builder, ins);
5299 LLVMValueRef indexes [2];
5300 MonoJumpInfo *tmp_ji, *ji;
5301 LLVMValueRef got_entry_addr;
5305 * FIXME: Can't allocate from the cfg mempool since that is freed if
5306 * the LLVM compile fails.
5308 tmp_ji = g_new0 (MonoJumpInfo, 1);
5309 tmp_ji->type = (MonoJumpInfoType)ins->inst_c1;
5310 tmp_ji->data.target = ins->inst_p0;
5312 ji = mono_aot_patch_info_dup (tmp_ji);
5315 if (ji->type == MONO_PATCH_INFO_ICALL_ADDR) {
5316 char *symbol = mono_aot_get_direct_call_symbol (MONO_PATCH_INFO_ICALL_ADDR_CALL, ji->data.target);
5319 * Avoid emitting a got entry for these since the method is directly called, and it might not be
5320 * resolvable at runtime using dlsym ().
5323 values [ins->dreg] = LLVMConstInt (IntPtrType (), 0, FALSE);
5328 ji->next = cfg->patch_info;
5329 cfg->patch_info = ji;
5331 //mono_add_patch_info (cfg, 0, (MonoJumpInfoType)ins->inst_i1, ins->inst_p0);
5332 got_offset = mono_aot_get_got_offset (cfg->patch_info);
5333 ctx->module->max_got_offset = MAX (ctx->module->max_got_offset, got_offset);
5334 if (!mono_aot_is_shared_got_offset (got_offset)) {
5335 //mono_print_ji (ji);
5337 ctx->has_got_access = TRUE;
5340 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
5341 indexes [1] = LLVMConstInt (LLVMInt32Type (), (gssize)got_offset, FALSE);
5342 got_entry_addr = LLVMBuildGEP (builder, ctx->module->got_var, indexes, 2, "");
5344 name = get_aotconst_name (ji->type, ji->data.target, got_offset);
5345 values [ins->dreg] = LLVMBuildLoad (builder, got_entry_addr, name);
5347 /* Can't use this in llvmonly mode since the got slots are initialized by the methods themselves */
5348 if (!cfg->llvm_only)
5349 set_invariant_load_flag (values [ins->dreg]);
5352 case OP_NOT_REACHED:
5353 LLVMBuildUnreachable (builder);
5354 has_terminator = TRUE;
5355 g_assert (bb->block_num < cfg->max_block_num);
5356 ctx->unreachable [bb->block_num] = TRUE;
5357 /* Might have instructions after this */
5359 MonoInst *next = ins->next;
5361 * FIXME: If later code uses the regs defined by these instructions,
5362 * compilation will fail.
5364 MONO_DELETE_INS (bb, next);
5368 MonoInst *var = ins->inst_i0;
5370 if (var->opcode == OP_VTARG_ADDR) {
5371 /* The variable contains the vtype address */
5372 values [ins->dreg] = values [var->dreg];
5373 } else if (var->opcode == OP_GSHAREDVT_LOCAL) {
5374 values [ins->dreg] = emit_gsharedvt_ldaddr (ctx, var->dreg);
5376 values [ins->dreg] = addresses [var->dreg];
5381 LLVMValueRef args [1];
5383 args [0] = convert (ctx, lhs, LLVMDoubleType ());
5384 values [ins->dreg] = LLVMBuildCall (builder, get_intrinsic (ctx, "llvm.sin.f64"), args, 1, dname);
5388 LLVMValueRef args [1];
5390 args [0] = convert (ctx, lhs, LLVMDoubleType ());
5391 values [ins->dreg] = LLVMBuildCall (builder, get_intrinsic (ctx, "llvm.cos.f64"), args, 1, dname);
5395 LLVMValueRef args [1];
5397 args [0] = convert (ctx, lhs, LLVMDoubleType ());
5398 values [ins->dreg] = LLVMBuildCall (builder, get_intrinsic (ctx, "llvm.sqrt.f64"), args, 1, dname);
5402 LLVMValueRef args [1];
5404 args [0] = convert (ctx, lhs, LLVMDoubleType ());
5405 values [ins->dreg] = LLVMBuildCall (builder, get_intrinsic (ctx, "fabs"), args, 1, dname);
5419 lhs = convert (ctx, lhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
5420 rhs = convert (ctx, rhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
5422 switch (ins->opcode) {
5425 v = LLVMBuildICmp (builder, LLVMIntSLE, lhs, rhs, "");
5429 v = LLVMBuildICmp (builder, LLVMIntSGE, lhs, rhs, "");
5433 v = LLVMBuildICmp (builder, LLVMIntULE, lhs, rhs, "");
5437 v = LLVMBuildICmp (builder, LLVMIntUGE, lhs, rhs, "");
5440 g_assert_not_reached ();
5443 values [ins->dreg] = LLVMBuildSelect (builder, v, lhs, rhs, dname);
5448 * See the ARM64 comment in mono/utils/atomic.h for an explanation of why this
5449 * hack is necessary (for now).
5452 #define ARM64_ATOMIC_FENCE_FIX mono_llvm_build_fence (builder, LLVM_BARRIER_SEQ)
5454 #define ARM64_ATOMIC_FENCE_FIX
5457 case OP_ATOMIC_EXCHANGE_I4:
5458 case OP_ATOMIC_EXCHANGE_I8: {
5459 LLVMValueRef args [2];
5462 if (ins->opcode == OP_ATOMIC_EXCHANGE_I4)
5463 t = LLVMInt32Type ();
5465 t = LLVMInt64Type ();
5467 g_assert (ins->inst_offset == 0);
5469 args [0] = convert (ctx, lhs, LLVMPointerType (t, 0));
5470 args [1] = convert (ctx, rhs, t);
5472 ARM64_ATOMIC_FENCE_FIX;
5473 values [ins->dreg] = mono_llvm_build_atomic_rmw (builder, LLVM_ATOMICRMW_OP_XCHG, args [0], args [1]);
5474 ARM64_ATOMIC_FENCE_FIX;
5477 case OP_ATOMIC_ADD_I4:
5478 case OP_ATOMIC_ADD_I8: {
5479 LLVMValueRef args [2];
5482 if (ins->opcode == OP_ATOMIC_ADD_I4)
5483 t = LLVMInt32Type ();
5485 t = LLVMInt64Type ();
5487 g_assert (ins->inst_offset == 0);
5489 args [0] = convert (ctx, lhs, LLVMPointerType (t, 0));
5490 args [1] = convert (ctx, rhs, t);
5491 ARM64_ATOMIC_FENCE_FIX;
5492 values [ins->dreg] = LLVMBuildAdd (builder, mono_llvm_build_atomic_rmw (builder, LLVM_ATOMICRMW_OP_ADD, args [0], args [1]), args [1], dname);
5493 ARM64_ATOMIC_FENCE_FIX;
5496 case OP_ATOMIC_CAS_I4:
5497 case OP_ATOMIC_CAS_I8: {
5498 LLVMValueRef args [3], val;
5501 if (ins->opcode == OP_ATOMIC_CAS_I4)
5502 t = LLVMInt32Type ();
5504 t = LLVMInt64Type ();
5506 args [0] = convert (ctx, lhs, LLVMPointerType (t, 0));
5508 args [1] = convert (ctx, values [ins->sreg3], t);
5510 args [2] = convert (ctx, values [ins->sreg2], t);
5511 ARM64_ATOMIC_FENCE_FIX;
5512 val = mono_llvm_build_cmpxchg (builder, args [0], args [1], args [2]);
5513 ARM64_ATOMIC_FENCE_FIX;
5514 /* cmpxchg returns a pair */
5515 values [ins->dreg] = LLVMBuildExtractValue (builder, val, 0, "");
5518 case OP_MEMORY_BARRIER: {
5519 mono_llvm_build_fence (builder, (BarrierKind) ins->backend.memory_barrier_kind);
5522 case OP_ATOMIC_LOAD_I1:
5523 case OP_ATOMIC_LOAD_I2:
5524 case OP_ATOMIC_LOAD_I4:
5525 case OP_ATOMIC_LOAD_I8:
5526 case OP_ATOMIC_LOAD_U1:
5527 case OP_ATOMIC_LOAD_U2:
5528 case OP_ATOMIC_LOAD_U4:
5529 case OP_ATOMIC_LOAD_U8:
5530 case OP_ATOMIC_LOAD_R4:
5531 case OP_ATOMIC_LOAD_R8: {
5532 #if LLVM_API_VERSION > 100
5534 gboolean sext, zext;
5536 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
5537 BarrierKind barrier = (BarrierKind) ins->backend.memory_barrier_kind;
5538 LLVMValueRef index, addr;
5540 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
5545 if (ins->inst_offset != 0) {
5546 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
5547 addr = LLVMBuildGEP (builder, convert (ctx, lhs, LLVMPointerType (t, 0)), &index, 1, "");
5552 addr = convert (ctx, addr, LLVMPointerType (t, 0));
5554 ARM64_ATOMIC_FENCE_FIX;
5555 values [ins->dreg] = emit_load_general (ctx, bb, &builder, size, addr, lhs, dname, is_volatile, barrier);
5556 ARM64_ATOMIC_FENCE_FIX;
5559 values [ins->dreg] = LLVMBuildSExt (builder, values [ins->dreg], LLVMInt32Type (), dname);
5561 values [ins->dreg] = LLVMBuildZExt (builder, values [ins->dreg], LLVMInt32Type (), dname);
5564 set_failure (ctx, "atomic mono.load intrinsic");
5568 case OP_ATOMIC_STORE_I1:
5569 case OP_ATOMIC_STORE_I2:
5570 case OP_ATOMIC_STORE_I4:
5571 case OP_ATOMIC_STORE_I8:
5572 case OP_ATOMIC_STORE_U1:
5573 case OP_ATOMIC_STORE_U2:
5574 case OP_ATOMIC_STORE_U4:
5575 case OP_ATOMIC_STORE_U8:
5576 case OP_ATOMIC_STORE_R4:
5577 case OP_ATOMIC_STORE_R8: {
5579 gboolean sext, zext;
5581 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
5582 BarrierKind barrier = (BarrierKind) ins->backend.memory_barrier_kind;
5583 LLVMValueRef index, addr, value, base;
5585 #if LLVM_API_VERSION < 100
5586 if (!cfg->llvm_only) {
5587 set_failure (ctx, "atomic mono.store intrinsic");
5592 if (!values [ins->inst_destbasereg]) {
5593 set_failure (ctx, "inst_destbasereg");
5597 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
5599 base = values [ins->inst_destbasereg];
5600 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
5601 addr = LLVMBuildGEP (builder, convert (ctx, base, LLVMPointerType (t, 0)), &index, 1, "");
5602 value = convert (ctx, values [ins->sreg1], t);
5604 ARM64_ATOMIC_FENCE_FIX;
5605 emit_store_general (ctx, bb, &builder, size, value, addr, base, is_volatile, barrier);
5606 ARM64_ATOMIC_FENCE_FIX;
5609 case OP_RELAXED_NOP: {
5610 #if defined(TARGET_AMD64) || defined(TARGET_X86)
5611 emit_call (ctx, bb, &builder, get_intrinsic (ctx, "llvm.x86.sse2.pause"), NULL, 0);
5618 #if (defined(TARGET_AMD64) || defined(TARGET_X86)) && defined(__linux__)
5620 // 257 == FS segment register
5621 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 257);
5623 // 256 == GS segment register
5624 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 256);
5627 values [ins->dreg] = LLVMBuildLoad (builder, LLVMBuildIntToPtr (builder, LLVMConstInt (IntPtrType (), ins->inst_offset, TRUE), ptrtype, ""), "");
5628 #elif defined(TARGET_AMD64) && defined(TARGET_OSX)
5629 /* See mono_amd64_emit_tls_get () */
5630 int offset = mono_amd64_get_tls_gs_offset () + (ins->inst_offset * 8);
5632 // 256 == GS segment register
5633 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 256);
5634 values [ins->dreg] = LLVMBuildLoad (builder, LLVMBuildIntToPtr (builder, LLVMConstInt (IntPtrType (), offset, TRUE), ptrtype, ""), "");
5636 set_failure (ctx, "opcode tls-get");
5642 case OP_GC_SAFE_POINT: {
5643 LLVMValueRef val, cmp, callee;
5644 LLVMBasicBlockRef poll_bb, cont_bb;
5645 static LLVMTypeRef sig;
5646 const char *icall_name = "mono_threads_state_poll";
5649 sig = LLVMFunctionType0 (LLVMVoidType (), FALSE);
5653 * mono_threads_state_poll ();
5654 * FIXME: Use a preserveall wrapper
5656 val = mono_llvm_build_load (builder, convert (ctx, lhs, LLVMPointerType (IntPtrType (), 0)), "", TRUE);
5657 cmp = LLVMBuildICmp (builder, LLVMIntEQ, val, LLVMConstNull (LLVMTypeOf (val)), "");
5658 poll_bb = gen_bb (ctx, "POLL_BB");
5659 cont_bb = gen_bb (ctx, "CONT_BB");
5660 LLVMBuildCondBr (builder, cmp, cont_bb, poll_bb);
5662 ctx->builder = builder = create_builder (ctx);
5663 LLVMPositionBuilderAtEnd (builder, poll_bb);
5665 if (ctx->cfg->compile_aot) {
5666 callee = get_callee (ctx, sig, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
5668 gpointer target = resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
5669 callee = emit_jit_callee (ctx, icall_name, sig, target);
5671 LLVMBuildCall (builder, callee, NULL, 0, "");
5672 LLVMBuildBr (builder, cont_bb);
5674 ctx->builder = builder = create_builder (ctx);
5675 LLVMPositionBuilderAtEnd (builder, cont_bb);
5676 ctx->bblocks [bb->block_num].end_bblock = cont_bb;
5684 case OP_IADD_OVF_UN:
5686 case OP_ISUB_OVF_UN:
5688 case OP_IMUL_OVF_UN:
5690 case OP_LADD_OVF_UN:
5692 case OP_LSUB_OVF_UN:
5694 case OP_LMUL_OVF_UN:
5696 LLVMValueRef args [2], val, ovf, func;
5698 args [0] = convert (ctx, lhs, op_to_llvm_type (ins->opcode));
5699 args [1] = convert (ctx, rhs, op_to_llvm_type (ins->opcode));
5700 func = get_intrinsic (ctx, ovf_op_to_intrins (ins->opcode));
5702 val = LLVMBuildCall (builder, func, args, 2, "");
5703 values [ins->dreg] = LLVMBuildExtractValue (builder, val, 0, dname);
5704 ovf = LLVMBuildExtractValue (builder, val, 1, "");
5705 emit_cond_system_exception (ctx, bb, "OverflowException", ovf);
5708 builder = ctx->builder;
5714 * We currently model them using arrays. Promotion to local vregs is
5715 * disabled for them in mono_handle_global_vregs () in the LLVM case,
5716 * so we always have an entry in cfg->varinfo for them.
5717 * FIXME: Is this needed ?
5720 MonoClass *klass = ins->klass;
5721 LLVMValueRef args [5];
5725 set_failure (ctx, "!klass");
5729 if (!addresses [ins->dreg])
5730 addresses [ins->dreg] = build_alloca (ctx, &klass->byval_arg);
5731 args [0] = LLVMBuildBitCast (builder, addresses [ins->dreg], LLVMPointerType (LLVMInt8Type (), 0), "");
5732 args [1] = LLVMConstInt (LLVMInt8Type (), 0, FALSE);
5733 args [2] = LLVMConstInt (LLVMInt32Type (), mono_class_value_size (klass, NULL), FALSE);
5735 args [3] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
5736 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
5737 LLVMBuildCall (builder, get_intrinsic (ctx, "llvm.memset.p0i8.i32"), args, 5, "");
5740 case OP_DUMMY_VZERO:
5743 case OP_STOREV_MEMBASE:
5744 case OP_LOADV_MEMBASE:
5746 MonoClass *klass = ins->klass;
5747 LLVMValueRef src = NULL, dst, args [5];
5748 gboolean done = FALSE;
5752 set_failure (ctx, "!klass");
5756 if (mini_is_gsharedvt_klass (klass)) {
5758 set_failure (ctx, "gsharedvt");
5762 switch (ins->opcode) {
5763 case OP_STOREV_MEMBASE:
5764 if (cfg->gen_write_barriers && klass->has_references && ins->inst_destbasereg != cfg->frame_reg &&
5765 LLVMGetInstructionOpcode (values [ins->inst_destbasereg]) != LLVMAlloca) {
5766 /* Decomposed earlier */
5767 g_assert_not_reached ();
5770 if (!addresses [ins->sreg1]) {
5772 g_assert (values [ins->sreg1]);
5773 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));
5774 LLVMBuildStore (builder, values [ins->sreg1], dst);
5777 src = LLVMBuildBitCast (builder, addresses [ins->sreg1], LLVMPointerType (LLVMInt8Type (), 0), "");
5778 dst = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_destbasereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (LLVMInt8Type (), 0));
5781 case OP_LOADV_MEMBASE:
5782 if (!addresses [ins->dreg])
5783 addresses [ins->dreg] = build_alloca (ctx, &klass->byval_arg);
5784 src = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_basereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (LLVMInt8Type (), 0));
5785 dst = LLVMBuildBitCast (builder, addresses [ins->dreg], LLVMPointerType (LLVMInt8Type (), 0), "");
5788 if (!addresses [ins->sreg1])
5789 addresses [ins->sreg1] = build_alloca (ctx, &klass->byval_arg);
5790 if (!addresses [ins->dreg])
5791 addresses [ins->dreg] = build_alloca (ctx, &klass->byval_arg);
5792 src = LLVMBuildBitCast (builder, addresses [ins->sreg1], LLVMPointerType (LLVMInt8Type (), 0), "");
5793 dst = LLVMBuildBitCast (builder, addresses [ins->dreg], LLVMPointerType (LLVMInt8Type (), 0), "");
5796 g_assert_not_reached ();
5806 args [2] = LLVMConstInt (LLVMInt32Type (), mono_class_value_size (klass, NULL), FALSE);
5807 args [3] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
5809 args [3] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
5810 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
5811 LLVMBuildCall (builder, get_intrinsic (ctx, "llvm.memcpy.p0i8.p0i8.i32"), args, 5, "");
5814 case OP_LLVM_OUTARG_VT: {
5815 LLVMArgInfo *ainfo = (LLVMArgInfo*)ins->inst_p0;
5816 MonoType *t = mini_get_underlying_type (ins->inst_vtype);
5818 if (ainfo->storage == LLVMArgGsharedvtVariable) {
5819 MonoInst *var = get_vreg_to_inst (cfg, ins->sreg1);
5821 if (var && var->opcode == OP_GSHAREDVT_LOCAL) {
5822 addresses [ins->dreg] = convert (ctx, emit_gsharedvt_ldaddr (ctx, var->dreg), LLVMPointerType (IntPtrType (), 0));
5824 g_assert (addresses [ins->sreg1]);
5825 addresses [ins->dreg] = addresses [ins->sreg1];
5827 } else if (ainfo->storage == LLVMArgGsharedvtFixed) {
5828 if (!addresses [ins->sreg1]) {
5829 addresses [ins->sreg1] = build_alloca (ctx, t);
5830 g_assert (values [ins->sreg1]);
5832 LLVMBuildStore (builder, convert (ctx, values [ins->sreg1], LLVMGetElementType (LLVMTypeOf (addresses [ins->sreg1]))), addresses [ins->sreg1]);
5833 addresses [ins->dreg] = addresses [ins->sreg1];
5835 if (!addresses [ins->sreg1]) {
5836 addresses [ins->sreg1] = build_alloca (ctx, t);
5837 g_assert (values [ins->sreg1]);
5838 LLVMBuildStore (builder, convert (ctx, values [ins->sreg1], type_to_llvm_type (ctx, t)), addresses [ins->sreg1]);
5840 addresses [ins->dreg] = addresses [ins->sreg1];
5844 case OP_OBJC_GET_SELECTOR: {
5845 const char *name = (const char*)ins->inst_p0;
5848 if (!ctx->module->objc_selector_to_var) {
5849 ctx->module->objc_selector_to_var = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
5851 LLVMValueRef info_var = LLVMAddGlobal (ctx->lmodule, LLVMArrayType (LLVMInt8Type (), 8), "@OBJC_IMAGE_INFO");
5852 int32_t objc_imageinfo [] = { 0, 16 };
5853 LLVMSetInitializer (info_var, mono_llvm_create_constant_data_array ((uint8_t *) &objc_imageinfo, 8));
5854 LLVMSetLinkage (info_var, LLVMPrivateLinkage);
5855 LLVMSetExternallyInitialized (info_var, TRUE);
5856 LLVMSetSection (info_var, "__DATA, __objc_imageinfo,regular,no_dead_strip");
5857 LLVMSetAlignment (info_var, sizeof (mgreg_t));
5858 mark_as_used (ctx->module, info_var);
5861 var = g_hash_table_lookup (ctx->module->objc_selector_to_var, name);
5863 LLVMValueRef indexes [16];
5865 LLVMValueRef name_var = LLVMAddGlobal (ctx->lmodule, LLVMArrayType (LLVMInt8Type (), strlen (name) + 1), "@OBJC_METH_VAR_NAME_");
5866 LLVMSetInitializer (name_var, mono_llvm_create_constant_data_array ((const uint8_t*)name, strlen (name) + 1));
5867 LLVMSetLinkage (name_var, LLVMPrivateLinkage);
5868 LLVMSetSection (name_var, "__TEXT,__objc_methname,cstring_literals");
5869 mark_as_used (ctx->module, name_var);
5871 LLVMValueRef ref_var = LLVMAddGlobal (ctx->lmodule, LLVMPointerType (LLVMInt8Type (), 0), "@OBJC_SELECTOR_REFERENCES_");
5873 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, 0);
5874 indexes [1] = LLVMConstInt (LLVMInt32Type (), 0, 0);
5875 LLVMSetInitializer (ref_var, LLVMConstGEP (name_var, indexes, 2));
5876 LLVMSetLinkage (ref_var, LLVMPrivateLinkage);
5877 LLVMSetExternallyInitialized (ref_var, TRUE);
5878 LLVMSetSection (ref_var, "__DATA, __objc_selrefs, literal_pointers, no_dead_strip");
5879 LLVMSetAlignment (ref_var, sizeof (mgreg_t));
5880 mark_as_used (ctx->module, ref_var);
5882 g_hash_table_insert (ctx->module->objc_selector_to_var, g_strdup (name), ref_var);
5886 values [ins->dreg] = LLVMBuildLoad (builder, var, "");
5893 #if defined(TARGET_X86) || defined(TARGET_AMD64)
5895 values [ins->dreg] = LLVMConstNull (type_to_llvm_type (ctx, &ins->klass->byval_arg));
5898 case OP_LOADX_MEMBASE: {
5899 LLVMTypeRef t = type_to_llvm_type (ctx, &ins->klass->byval_arg);
5902 src = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_basereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (t, 0));
5903 values [ins->dreg] = mono_llvm_build_aligned_load (builder, src, "", FALSE, 1);
5906 case OP_STOREX_MEMBASE: {
5907 LLVMTypeRef t = LLVMTypeOf (values [ins->sreg1]);
5910 dest = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_destbasereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (t, 0));
5911 mono_llvm_build_aligned_store (builder, values [ins->sreg1], dest, FALSE, 1);
5918 values [ins->dreg] = LLVMBuildAdd (builder, lhs, rhs, "");
5922 values [ins->dreg] = LLVMBuildFAdd (builder, lhs, rhs, "");
5928 values [ins->dreg] = LLVMBuildSub (builder, lhs, rhs, "");
5932 values [ins->dreg] = LLVMBuildFSub (builder, lhs, rhs, "");
5936 values [ins->dreg] = LLVMBuildFMul (builder, lhs, rhs, "");
5940 values [ins->dreg] = LLVMBuildFDiv (builder, lhs, rhs, "");
5943 values [ins->dreg] = LLVMBuildAnd (builder, lhs, rhs, "");
5946 values [ins->dreg] = LLVMBuildOr (builder, lhs, rhs, "");
5949 values [ins->dreg] = LLVMBuildXor (builder, lhs, rhs, "");
5953 values [ins->dreg] = LLVMBuildMul (builder, lhs, rhs, "");
5964 LLVMValueRef v = NULL;
5966 switch (ins->opcode) {
5971 t = LLVMVectorType (LLVMInt32Type (), 4);
5972 rt = LLVMVectorType (LLVMFloatType (), 4);
5978 t = LLVMVectorType (LLVMInt64Type (), 2);
5979 rt = LLVMVectorType (LLVMDoubleType (), 2);
5982 t = LLVMInt32Type ();
5983 rt = LLVMInt32Type ();
5984 g_assert_not_reached ();
5987 lhs = LLVMBuildBitCast (builder, lhs, t, "");
5988 rhs = LLVMBuildBitCast (builder, rhs, t, "");
5989 switch (ins->opcode) {
5992 v = LLVMBuildAnd (builder, lhs, rhs, "");
5996 v = LLVMBuildOr (builder, lhs, rhs, "");
6000 v = LLVMBuildXor (builder, lhs, rhs, "");
6004 v = LLVMBuildAnd (builder, rhs, LLVMBuildNot (builder, lhs, ""), "");
6007 values [ins->dreg] = LLVMBuildBitCast (builder, v, rt, "");
6013 LLVMValueRef cmp = LLVMBuildICmp (builder, LLVMIntULT, lhs, rhs, "");
6014 values [ins->dreg] = LLVMBuildSelect (builder, cmp, lhs, rhs, "");
6020 LLVMValueRef cmp = LLVMBuildICmp (builder, LLVMIntUGT, lhs, rhs, "");
6021 values [ins->dreg] = LLVMBuildSelect (builder, cmp, lhs, rhs, "");
6025 LLVMValueRef cmp = LLVMBuildICmp (builder, LLVMIntSLT, lhs, rhs, "");
6026 values [ins->dreg] = LLVMBuildSelect (builder, cmp, lhs, rhs, "");
6043 case OP_PADDB_SAT_UN:
6044 case OP_PADDW_SAT_UN:
6045 case OP_PSUBB_SAT_UN:
6046 case OP_PSUBW_SAT_UN:
6054 case OP_PMULW_HIGH_UN: {
6055 LLVMValueRef args [2];
6060 values [ins->dreg] = LLVMBuildCall (builder, get_intrinsic (ctx, simd_op_to_intrins (ins->opcode)), args, 2, dname);
6067 values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildICmp (builder, LLVMIntEQ, lhs, rhs, ""), LLVMTypeOf (lhs), "");
6071 values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildICmp (builder, LLVMIntSGT, lhs, rhs, ""), LLVMTypeOf (lhs), "");
6079 case OP_EXTRACTX_U2:
6081 case OP_EXTRACT_U1: {
6083 gboolean zext = FALSE;
6085 t = simd_op_to_llvm_type (ins->opcode);
6087 switch (ins->opcode) {
6095 case OP_EXTRACTX_U2:
6100 t = LLVMInt32Type ();
6101 g_assert_not_reached ();
6104 lhs = LLVMBuildBitCast (builder, lhs, t, "");
6105 values [ins->dreg] = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), "");
6107 values [ins->dreg] = LLVMBuildZExt (builder, values [ins->dreg], LLVMInt32Type (), "");
6116 case OP_EXPAND_R8: {
6117 LLVMTypeRef t = simd_op_to_llvm_type (ins->opcode);
6118 LLVMValueRef mask [16], v;
6121 for (i = 0; i < 16; ++i)
6122 mask [i] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
6124 v = convert (ctx, values [ins->sreg1], LLVMGetElementType (t));
6126 values [ins->dreg] = LLVMBuildInsertElement (builder, LLVMConstNull (t), v, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
6127 values [ins->dreg] = LLVMBuildShuffleVector (builder, values [ins->dreg], LLVMGetUndef (t), LLVMConstVector (mask, LLVMGetVectorSize (t)), "");
6132 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt8Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
6135 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt16Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
6138 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt32Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
6141 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt64Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
6144 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMFloatType ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
6147 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMDoubleType ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
6150 #if LLVM_API_VERSION > 100
6152 LLVMValueRef indexes [16];
6154 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
6155 indexes [1] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
6156 LLVMValueRef mask = LLVMConstVector (indexes, 2);
6157 LLVMValueRef shuffle = LLVMBuildShuffleVector (builder, lhs, LLVMConstNull (LLVMTypeOf (lhs)), mask, "");
6158 values [ins->dreg] = LLVMBuildSIToFP (builder, shuffle, LLVMVectorType (LLVMDoubleType (), 2), dname);
6162 LLVMValueRef indexes [16];
6164 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
6165 indexes [1] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
6166 LLVMValueRef mask = LLVMConstVector (indexes, 2);
6167 LLVMValueRef shuffle = LLVMBuildShuffleVector (builder, lhs, LLVMConstNull (LLVMTypeOf (lhs)), mask, "");
6168 values [ins->dreg] = LLVMBuildFPExt (builder, shuffle, LLVMVectorType (LLVMDoubleType (), 2), dname);
6172 values [ins->dreg] = LLVMBuildFPToSI (builder, lhs, LLVMVectorType (LLVMInt32Type (), 4), dname);
6176 #if LLVM_API_VERSION <= 100
6186 case OP_EXTRACT_MASK:
6193 v = convert (ctx, values [ins->sreg1], simd_op_to_llvm_type (ins->opcode));
6195 values [ins->dreg] = LLVMBuildCall (builder, get_intrinsic (ctx, simd_op_to_intrins (ins->opcode)), &v, 1, dname);
6200 LLVMRealPredicate op;
6202 switch (ins->inst_c0) {
6212 case SIMD_COMP_UNORD:
6228 g_assert_not_reached ();
6231 LLVMValueRef cmp = LLVMBuildFCmp (builder, op, lhs, rhs, "");
6232 if (ins->opcode == OP_COMPPD)
6233 values [ins->dreg] = LLVMBuildBitCast (builder, LLVMBuildSExt (builder, cmp, LLVMVectorType (LLVMInt64Type (), 2), ""), LLVMTypeOf (lhs), "");
6235 values [ins->dreg] = LLVMBuildBitCast (builder, LLVMBuildSExt (builder, cmp, LLVMVectorType (LLVMInt32Type (), 4), ""), LLVMTypeOf (lhs), "");
6239 /* This is only used for implementing shifts by non-immediate */
6240 values [ins->dreg] = lhs;
6251 LLVMValueRef args [3];
6254 args [1] = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
6256 values [ins->dreg] = LLVMBuildCall (builder, get_intrinsic (ctx, simd_op_to_intrins (ins->opcode)), args, 2, dname);
6267 case OP_PSHLQ_REG: {
6268 LLVMValueRef args [3];
6271 args [1] = values [ins->sreg2];
6273 values [ins->dreg] = LLVMBuildCall (builder, get_intrinsic (ctx, simd_op_to_intrins (ins->opcode)), args, 2, dname);
6280 case OP_PSHUFLEW_LOW:
6281 case OP_PSHUFLEW_HIGH: {
6283 LLVMValueRef v1 = NULL, v2 = NULL, mask_values [16];
6284 int i, mask_size = 0;
6285 int imask = ins->inst_c0;
6287 /* Convert the x86 shuffle mask to LLVM's */
6288 switch (ins->opcode) {
6291 mask [0] = ((imask >> 0) & 3);
6292 mask [1] = ((imask >> 2) & 3);
6293 mask [2] = ((imask >> 4) & 3) + 4;
6294 mask [3] = ((imask >> 6) & 3) + 4;
6295 v1 = values [ins->sreg1];
6296 v2 = values [ins->sreg2];
6300 mask [0] = ((imask >> 0) & 1);
6301 mask [1] = ((imask >> 1) & 1) + 2;
6302 v1 = values [ins->sreg1];
6303 v2 = values [ins->sreg2];
6305 case OP_PSHUFLEW_LOW:
6307 mask [0] = ((imask >> 0) & 3);
6308 mask [1] = ((imask >> 2) & 3);
6309 mask [2] = ((imask >> 4) & 3);
6310 mask [3] = ((imask >> 6) & 3);
6315 v1 = values [ins->sreg1];
6316 v2 = LLVMGetUndef (LLVMTypeOf (v1));
6318 case OP_PSHUFLEW_HIGH:
6324 mask [4] = 4 + ((imask >> 0) & 3);
6325 mask [5] = 4 + ((imask >> 2) & 3);
6326 mask [6] = 4 + ((imask >> 4) & 3);
6327 mask [7] = 4 + ((imask >> 6) & 3);
6328 v1 = values [ins->sreg1];
6329 v2 = LLVMGetUndef (LLVMTypeOf (v1));
6333 mask [0] = ((imask >> 0) & 3);
6334 mask [1] = ((imask >> 2) & 3);
6335 mask [2] = ((imask >> 4) & 3);
6336 mask [3] = ((imask >> 6) & 3);
6337 v1 = values [ins->sreg1];
6338 v2 = LLVMGetUndef (LLVMTypeOf (v1));
6341 g_assert_not_reached ();
6343 for (i = 0; i < mask_size; ++i)
6344 mask_values [i] = LLVMConstInt (LLVMInt32Type (), mask [i], FALSE);
6346 values [ins->dreg] =
6347 LLVMBuildShuffleVector (builder, v1, v2,
6348 LLVMConstVector (mask_values, mask_size), dname);
6352 case OP_UNPACK_LOWB:
6353 case OP_UNPACK_LOWW:
6354 case OP_UNPACK_LOWD:
6355 case OP_UNPACK_LOWQ:
6356 case OP_UNPACK_LOWPS:
6357 case OP_UNPACK_LOWPD:
6358 case OP_UNPACK_HIGHB:
6359 case OP_UNPACK_HIGHW:
6360 case OP_UNPACK_HIGHD:
6361 case OP_UNPACK_HIGHQ:
6362 case OP_UNPACK_HIGHPS:
6363 case OP_UNPACK_HIGHPD: {
6365 LLVMValueRef mask_values [16];
6366 int i, mask_size = 0;
6367 gboolean low = FALSE;
6369 switch (ins->opcode) {
6370 case OP_UNPACK_LOWB:
6374 case OP_UNPACK_LOWW:
6378 case OP_UNPACK_LOWD:
6379 case OP_UNPACK_LOWPS:
6383 case OP_UNPACK_LOWQ:
6384 case OP_UNPACK_LOWPD:
6388 case OP_UNPACK_HIGHB:
6391 case OP_UNPACK_HIGHW:
6394 case OP_UNPACK_HIGHD:
6395 case OP_UNPACK_HIGHPS:
6398 case OP_UNPACK_HIGHQ:
6399 case OP_UNPACK_HIGHPD:
6403 g_assert_not_reached ();
6407 for (i = 0; i < (mask_size / 2); ++i) {
6409 mask [(i * 2) + 1] = mask_size + i;
6412 for (i = 0; i < (mask_size / 2); ++i) {
6413 mask [(i * 2)] = (mask_size / 2) + i;
6414 mask [(i * 2) + 1] = mask_size + (mask_size / 2) + i;
6418 for (i = 0; i < mask_size; ++i)
6419 mask_values [i] = LLVMConstInt (LLVMInt32Type (), mask [i], FALSE);
6421 values [ins->dreg] =
6422 LLVMBuildShuffleVector (builder, values [ins->sreg1], values [ins->sreg2],
6423 LLVMConstVector (mask_values, mask_size), dname);
6428 LLVMTypeRef t = simd_op_to_llvm_type (ins->opcode);
6429 LLVMValueRef v, val;
6431 v = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
6432 val = LLVMConstNull (t);
6433 val = LLVMBuildInsertElement (builder, val, v, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
6434 val = LLVMBuildInsertElement (builder, val, v, LLVMConstInt (LLVMInt32Type (), 1, FALSE), dname);
6436 values [ins->dreg] = val;
6440 case OP_DUPPS_HIGH: {
6441 LLVMTypeRef t = simd_op_to_llvm_type (ins->opcode);
6442 LLVMValueRef v1, v2, val;
6445 if (ins->opcode == OP_DUPPS_LOW) {
6446 v1 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
6447 v2 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 2, FALSE), "");
6449 v1 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 1, FALSE), "");
6450 v2 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 3, FALSE), "");
6452 val = LLVMConstNull (t);
6453 val = LLVMBuildInsertElement (builder, val, v1, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
6454 val = LLVMBuildInsertElement (builder, val, v1, LLVMConstInt (LLVMInt32Type (), 1, FALSE), "");
6455 val = LLVMBuildInsertElement (builder, val, v2, LLVMConstInt (LLVMInt32Type (), 2, FALSE), "");
6456 val = LLVMBuildInsertElement (builder, val, v2, LLVMConstInt (LLVMInt32Type (), 3, FALSE), "");
6458 values [ins->dreg] = val;
6463 LLVMValueRef args [3];
6467 /* 0xf1 == multiply all 4 elements, add them together, and store the result to the lowest element */
6468 args [2] = LLVMConstInt (LLVMInt32Type (), 0xf1, FALSE);
6470 values [ins->dreg] = LLVMBuildCall (builder, get_intrinsic (ctx, simd_op_to_intrins (ins->opcode)), args, 3, dname);
6480 * EXCEPTION HANDLING
6482 case OP_IMPLICIT_EXCEPTION:
6483 /* This marks a place where an implicit exception can happen */
6484 if (bb->region != -1)
6485 set_failure (ctx, "implicit-exception");
6489 gboolean rethrow = (ins->opcode == OP_RETHROW);
6490 if (ctx->llvm_only) {
6491 emit_llvmonly_throw (ctx, bb, rethrow, lhs);
6492 has_terminator = TRUE;
6493 ctx->unreachable [bb->block_num] = TRUE;
6495 emit_throw (ctx, bb, rethrow, lhs);
6496 builder = ctx->builder;
6500 case OP_CALL_HANDLER: {
6502 * We don't 'call' handlers, but instead simply branch to them.
6503 * The code generated by ENDFINALLY will branch back to us.
6505 LLVMBasicBlockRef noex_bb;
6507 BBInfo *info = &bblocks [ins->inst_target_bb->block_num];
6509 bb_list = info->call_handler_return_bbs;
6512 * Set the indicator variable for the finally clause.
6514 lhs = info->finally_ind;
6516 LLVMBuildStore (builder, LLVMConstInt (LLVMInt32Type (), g_slist_length (bb_list) + 1, FALSE), lhs);
6518 /* Branch to the finally clause */
6519 LLVMBuildBr (builder, info->call_handler_target_bb);
6521 noex_bb = gen_bb (ctx, "CALL_HANDLER_CONT_BB");
6522 info->call_handler_return_bbs = g_slist_append_mempool (cfg->mempool, info->call_handler_return_bbs, noex_bb);
6524 builder = ctx->builder = create_builder (ctx);
6525 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
6527 bblocks [bb->block_num].end_bblock = noex_bb;
6530 case OP_START_HANDLER: {
6533 case OP_ENDFINALLY: {
6534 LLVMBasicBlockRef resume_bb;
6535 MonoBasicBlock *handler_bb;
6536 LLVMValueRef val, switch_ins, callee;
6540 handler_bb = (MonoBasicBlock*)g_hash_table_lookup (ctx->region_to_handler, GUINT_TO_POINTER (mono_get_block_region_notry (cfg, bb->region)));
6541 g_assert (handler_bb);
6542 info = &bblocks [handler_bb->block_num];
6543 lhs = info->finally_ind;
6546 bb_list = info->call_handler_return_bbs;
6548 resume_bb = gen_bb (ctx, "ENDFINALLY_RESUME_BB");
6550 /* Load the finally variable */
6551 val = LLVMBuildLoad (builder, lhs, "");
6553 /* Reset the variable */
6554 LLVMBuildStore (builder, LLVMConstInt (LLVMInt32Type (), 0, FALSE), lhs);
6556 /* Branch to either resume_bb, or to the bblocks in bb_list */
6557 switch_ins = LLVMBuildSwitch (builder, val, resume_bb, g_slist_length (bb_list));
6559 * The other targets are added at the end to handle OP_CALL_HANDLER
6560 * opcodes processed later.
6562 info->endfinally_switch_ins_list = g_slist_append_mempool (cfg->mempool, info->endfinally_switch_ins_list, switch_ins);
6564 builder = ctx->builder = create_builder (ctx);
6565 LLVMPositionBuilderAtEnd (ctx->builder, resume_bb);
6567 if (ctx->llvm_only) {
6568 emit_resume_eh (ctx, bb);
6570 if (ctx->cfg->compile_aot) {
6571 callee = get_callee (ctx, LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE), MONO_PATCH_INFO_INTERNAL_METHOD, "llvm_resume_unwind_trampoline");
6573 #if LLVM_API_VERSION > 100
6574 MonoJitICallInfo *info;
6576 info = mono_find_jit_icall_by_name ("llvm_resume_unwind_trampoline");
6578 gpointer target = (void*)info->func;
6579 LLVMTypeRef icall_sig = LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE);
6580 callee = emit_jit_callee (ctx, "llvm_resume_unwind_trampoline", icall_sig, target);
6582 callee = LLVMGetNamedFunction (ctx->lmodule, "llvm_resume_unwind_trampoline");
6585 LLVMBuildCall (builder, callee, NULL, 0, "");
6586 LLVMBuildUnreachable (builder);
6589 has_terminator = TRUE;
6592 case OP_IL_SEQ_POINT:
6597 sprintf (reason, "opcode %s", mono_inst_name (ins->opcode));
6598 set_failure (ctx, reason);
6606 /* Convert the value to the type required by phi nodes */
6607 if (spec [MONO_INST_DEST] != ' ' && !MONO_IS_STORE_MEMBASE (ins) && ctx->vreg_types [ins->dreg]) {
6608 if (ctx->is_vphi [ins->dreg])
6610 values [ins->dreg] = addresses [ins->dreg];
6612 values [ins->dreg] = convert (ctx, values [ins->dreg], ctx->vreg_types [ins->dreg]);
6615 /* Add stores for volatile variables */
6616 if (spec [MONO_INST_DEST] != ' ' && spec [MONO_INST_DEST] != 'v' && !MONO_IS_STORE_MEMBASE (ins))
6617 emit_volatile_store (ctx, ins->dreg);
6623 if (!has_terminator && bb->next_bb && (bb == cfg->bb_entry || bb->in_count > 0)) {
6624 LLVMBuildBr (builder, get_bb (ctx, bb->next_bb));
6627 if (bb == cfg->bb_exit && sig->ret->type == MONO_TYPE_VOID) {
6628 emit_dbg_loc (ctx, builder, cfg->header->code + cfg->header->code_size - 1);
6629 LLVMBuildRetVoid (builder);
6632 if (bb == cfg->bb_entry)
6633 ctx->last_alloca = LLVMGetLastInstruction (get_bb (ctx, cfg->bb_entry));
6637 * mono_llvm_check_method_supported:
6639 * Do some quick checks to decide whenever cfg->method can be compiled by LLVM, to avoid
6640 * compiling a method twice.
6643 mono_llvm_check_method_supported (MonoCompile *cfg)
6650 if (cfg->method->save_lmf) {
6651 cfg->exception_message = g_strdup ("lmf");
6652 cfg->disable_llvm = TRUE;
6654 if (cfg->disable_llvm)
6658 * Nested clauses where one of the clauses is a finally clause is
6659 * not supported, because LLVM can't figure out the control flow,
6660 * probably because we resume exception handling by calling our
6661 * own function instead of using the 'resume' llvm instruction.
6663 for (i = 0; i < cfg->header->num_clauses; ++i) {
6664 for (j = 0; j < cfg->header->num_clauses; ++j) {
6665 MonoExceptionClause *clause1 = &cfg->header->clauses [i];
6666 MonoExceptionClause *clause2 = &cfg->header->clauses [j];
6668 // FIXME: Nested try clauses fail in some cases too, i.e. #37273
6669 if (i != j && clause1->try_offset >= clause2->try_offset && clause1->handler_offset <= clause2->handler_offset) {
6670 //(clause1->flags == MONO_EXCEPTION_CLAUSE_FINALLY || clause2->flags == MONO_EXCEPTION_CLAUSE_FINALLY)) {
6671 cfg->exception_message = g_strdup ("nested clauses");
6672 cfg->disable_llvm = TRUE;
6677 if (cfg->disable_llvm)
6681 if (cfg->method->dynamic) {
6682 cfg->exception_message = g_strdup ("dynamic.");
6683 cfg->disable_llvm = TRUE;
6685 if (cfg->disable_llvm)
6689 static LLVMCallInfo*
6690 get_llvm_call_info (MonoCompile *cfg, MonoMethodSignature *sig)
6692 LLVMCallInfo *linfo;
6695 if (cfg->gsharedvt && cfg->llvm_only && mini_is_gsharedvt_variable_signature (sig)) {
6699 * Gsharedvt methods have the following calling convention:
6700 * - all arguments are passed by ref, even non generic ones
6701 * - the return value is returned by ref too, using a vret
6702 * argument passed after 'this'.
6704 n = sig->param_count + sig->hasthis;
6705 linfo = (LLVMCallInfo*)mono_mempool_alloc0 (cfg->mempool, sizeof (LLVMCallInfo) + (sizeof (LLVMArgInfo) * n));
6709 linfo->args [pindex ++].storage = LLVMArgNormal;
6711 if (sig->ret->type != MONO_TYPE_VOID) {
6712 if (mini_is_gsharedvt_variable_type (sig->ret))
6713 linfo->ret.storage = LLVMArgGsharedvtVariable;
6714 else if (mini_type_is_vtype (sig->ret))
6715 linfo->ret.storage = LLVMArgGsharedvtFixedVtype;
6717 linfo->ret.storage = LLVMArgGsharedvtFixed;
6718 linfo->vret_arg_index = pindex;
6720 linfo->ret.storage = LLVMArgNone;
6723 for (i = 0; i < sig->param_count; ++i) {
6724 if (sig->params [i]->byref)
6725 linfo->args [pindex].storage = LLVMArgNormal;
6726 else if (mini_is_gsharedvt_variable_type (sig->params [i]))
6727 linfo->args [pindex].storage = LLVMArgGsharedvtVariable;
6728 else if (mini_type_is_vtype (sig->params [i]))
6729 linfo->args [pindex].storage = LLVMArgGsharedvtFixedVtype;
6731 linfo->args [pindex].storage = LLVMArgGsharedvtFixed;
6732 linfo->args [pindex].type = sig->params [i];
6739 linfo = mono_arch_get_llvm_call_info (cfg, sig);
6740 for (i = 0; i < sig->param_count; ++i)
6741 linfo->args [i + sig->hasthis].type = sig->params [i];
6747 emit_method_inner (EmitContext *ctx);
6750 free_ctx (EmitContext *ctx)
6754 g_free (ctx->values);
6755 g_free (ctx->addresses);
6756 g_free (ctx->vreg_types);
6757 g_free (ctx->is_vphi);
6758 g_free (ctx->vreg_cli_types);
6759 g_free (ctx->is_dead);
6760 g_free (ctx->unreachable);
6761 g_ptr_array_free (ctx->phi_values, TRUE);
6762 g_free (ctx->bblocks);
6763 g_hash_table_destroy (ctx->region_to_handler);
6764 g_hash_table_destroy (ctx->clause_to_handler);
6765 g_hash_table_destroy (ctx->jit_callees);
6767 GHashTableIter iter;
6768 g_hash_table_iter_init (&iter, ctx->method_to_callers);
6769 while (g_hash_table_iter_next (&iter, NULL, (gpointer)&l))
6772 g_hash_table_destroy (ctx->method_to_callers);
6774 g_free (ctx->method_name);
6775 g_ptr_array_free (ctx->bblock_list, TRUE);
6777 for (l = ctx->builders; l; l = l->next) {
6778 LLVMBuilderRef builder = (LLVMBuilderRef)l->data;
6779 LLVMDisposeBuilder (builder);
6786 * mono_llvm_emit_method:
6788 * Emit LLVM IL from the mono IL, and compile it to native code using LLVM.
6791 mono_llvm_emit_method (MonoCompile *cfg)
6795 gboolean is_linkonce = FALSE;
6798 /* The code below might acquire the loader lock, so use it for global locking */
6799 mono_loader_lock ();
6801 /* Used to communicate with the callbacks */
6802 mono_native_tls_set_value (current_cfg_tls_id, cfg);
6804 ctx = g_new0 (EmitContext, 1);
6806 ctx->mempool = cfg->mempool;
6809 * This maps vregs to the LLVM instruction defining them
6811 ctx->values = g_new0 (LLVMValueRef, cfg->next_vreg);
6813 * This maps vregs for volatile variables to the LLVM instruction defining their
6816 ctx->addresses = g_new0 (LLVMValueRef, cfg->next_vreg);
6817 ctx->vreg_types = g_new0 (LLVMTypeRef, cfg->next_vreg);
6818 ctx->is_vphi = g_new0 (gboolean, cfg->next_vreg);
6819 ctx->vreg_cli_types = g_new0 (MonoType*, cfg->next_vreg);
6820 ctx->phi_values = g_ptr_array_sized_new (256);
6822 * This signals whenever the vreg was defined by a phi node with no input vars
6823 * (i.e. all its input bblocks end with NOT_REACHABLE).
6825 ctx->is_dead = g_new0 (gboolean, cfg->next_vreg);
6826 /* Whenever the bblock is unreachable */
6827 ctx->unreachable = g_new0 (gboolean, cfg->max_block_num);
6828 ctx->bblock_list = g_ptr_array_sized_new (256);
6830 ctx->region_to_handler = g_hash_table_new (NULL, NULL);
6831 ctx->clause_to_handler = g_hash_table_new (NULL, NULL);
6832 ctx->method_to_callers = g_hash_table_new (NULL, NULL);
6833 ctx->jit_callees = g_hash_table_new (NULL, NULL);
6834 if (cfg->compile_aot) {
6835 ctx->module = &aot_module;
6839 * Allow the linker to discard duplicate copies of wrappers, generic instances etc. by using the 'linkonce'
6840 * linkage for them. This requires the following:
6841 * - the method needs to have a unique mangled name
6842 * - llvmonly mode, since the code in aot-runtime.c would initialize got slots in the wrong aot image etc.
6844 is_linkonce = ctx->module->llvm_only && ctx->module->static_link && mono_aot_is_linkonce_method (cfg->method);
6846 method_name = mono_aot_get_mangled_method_name (cfg->method);
6848 is_linkonce = FALSE;
6851 printf ("%s %s\n", mono_method_full_name (cfg->method, 1), method_name);
6853 printf ("%s\n", mono_method_full_name (cfg->method, 1));
6857 method_name = mono_aot_get_method_name (cfg);
6858 cfg->llvm_method_name = g_strdup (method_name);
6860 init_jit_module (cfg->domain);
6861 ctx->module = (MonoLLVMModule*)domain_jit_info (cfg->domain)->llvm_module;
6862 method_name = mono_method_full_name (cfg->method, TRUE);
6864 ctx->method_name = method_name;
6865 ctx->is_linkonce = is_linkonce;
6867 #if LLVM_API_VERSION > 100
6868 if (cfg->compile_aot)
6869 ctx->lmodule = ctx->module->lmodule;
6871 ctx->lmodule = LLVMModuleCreateWithName ("jit-module");
6873 ctx->lmodule = ctx->module->lmodule;
6875 ctx->llvm_only = ctx->module->llvm_only;
6877 emit_method_inner (ctx);
6879 if (!ctx_ok (ctx)) {
6881 /* Need to add unused phi nodes as they can be referenced by other values */
6882 LLVMBasicBlockRef phi_bb = LLVMAppendBasicBlock (ctx->lmethod, "PHI_BB");
6883 LLVMBuilderRef builder;
6885 builder = create_builder (ctx);
6886 LLVMPositionBuilderAtEnd (builder, phi_bb);
6888 for (i = 0; i < ctx->phi_values->len; ++i) {
6889 LLVMValueRef v = (LLVMValueRef)g_ptr_array_index (ctx->phi_values, i);
6890 if (LLVMGetInstructionParent (v) == NULL)
6891 LLVMInsertIntoBuilder (builder, v);
6894 LLVMDeleteFunction (ctx->lmethod);
6900 mono_native_tls_set_value (current_cfg_tls_id, NULL);
6902 mono_loader_unlock ();
6906 emit_method_inner (EmitContext *ctx)
6908 MonoCompile *cfg = ctx->cfg;
6909 MonoMethodSignature *sig;
6911 LLVMTypeRef method_type;
6912 LLVMValueRef method = NULL;
6913 LLVMValueRef *values = ctx->values;
6914 int i, max_block_num, bb_index;
6915 gboolean last = FALSE;
6916 LLVMCallInfo *linfo;
6917 LLVMModuleRef lmodule = ctx->lmodule;
6919 GPtrArray *bblock_list = ctx->bblock_list;
6920 MonoMethodHeader *header;
6921 MonoExceptionClause *clause;
6924 if (cfg->gsharedvt && !cfg->llvm_only) {
6925 set_failure (ctx, "gsharedvt");
6931 static int count = 0;
6934 if (g_getenv ("LLVM_COUNT")) {
6935 if (count == atoi (g_getenv ("LLVM_COUNT"))) {
6936 printf ("LAST: %s\n", mono_method_full_name (cfg->method, TRUE));
6940 if (count > atoi (g_getenv ("LLVM_COUNT"))) {
6941 set_failure (ctx, "count");
6948 sig = mono_method_signature (cfg->method);
6951 linfo = get_llvm_call_info (cfg, sig);
6957 linfo->rgctx_arg = TRUE;
6958 ctx->method_type = method_type = sig_to_llvm_sig_full (ctx, sig, linfo);
6962 method = LLVMAddFunction (lmodule, ctx->method_name, method_type);
6963 ctx->lmethod = method;
6965 if (!cfg->llvm_only)
6966 LLVMSetFunctionCallConv (method, LLVMMono1CallConv);
6967 LLVMSetLinkage (method, LLVMPrivateLinkage);
6969 LLVMAddFunctionAttr (method, LLVMUWTable);
6971 if (cfg->compile_aot) {
6972 LLVMSetLinkage (method, LLVMInternalLinkage);
6973 if (ctx->module->external_symbols) {
6974 LLVMSetLinkage (method, LLVMExternalLinkage);
6975 LLVMSetVisibility (method, LLVMHiddenVisibility);
6977 if (ctx->is_linkonce) {
6978 LLVMSetLinkage (method, LLVMLinkOnceAnyLinkage);
6979 LLVMSetVisibility (method, LLVMDefaultVisibility);
6982 #if LLVM_API_VERSION > 100
6983 LLVMSetLinkage (method, LLVMExternalLinkage);
6985 LLVMSetLinkage (method, LLVMPrivateLinkage);
6989 if (cfg->method->save_lmf && !cfg->llvm_only) {
6990 set_failure (ctx, "lmf");
6994 if (sig->pinvoke && cfg->method->wrapper_type != MONO_WRAPPER_RUNTIME_INVOKE && !cfg->llvm_only) {
6995 set_failure (ctx, "pinvoke signature");
6999 header = cfg->header;
7000 for (i = 0; i < header->num_clauses; ++i) {
7001 clause = &header->clauses [i];
7002 if (clause->flags != MONO_EXCEPTION_CLAUSE_FINALLY && clause->flags != MONO_EXCEPTION_CLAUSE_NONE) {
7003 set_failure (ctx, "non-finally/catch clause.");
7007 if (header->num_clauses || (cfg->method->iflags & METHOD_IMPL_ATTRIBUTE_NOINLINING) || cfg->no_inline)
7008 /* We can't handle inlined methods with clauses */
7009 LLVMAddFunctionAttr (method, LLVMNoInlineAttribute);
7011 if (linfo->rgctx_arg) {
7012 ctx->rgctx_arg = LLVMGetParam (method, linfo->rgctx_arg_pindex);
7013 ctx->rgctx_arg_pindex = linfo->rgctx_arg_pindex;
7015 * We mark the rgctx parameter with the inreg attribute, which is mapped to
7016 * MONO_ARCH_RGCTX_REG in the Mono calling convention in llvm, i.e.
7017 * CC_X86_64_Mono in X86CallingConv.td.
7019 if (!ctx->llvm_only)
7020 LLVMAddAttribute (ctx->rgctx_arg, LLVMInRegAttribute);
7021 LLVMSetValueName (ctx->rgctx_arg, "rgctx");
7023 ctx->rgctx_arg_pindex = -1;
7025 if (cfg->vret_addr) {
7026 values [cfg->vret_addr->dreg] = LLVMGetParam (method, linfo->vret_arg_pindex);
7027 LLVMSetValueName (values [cfg->vret_addr->dreg], "vret");
7028 if (linfo->ret.storage == LLVMArgVtypeByRef) {
7029 LLVMAddAttribute (LLVMGetParam (method, linfo->vret_arg_pindex), LLVMStructRetAttribute);
7030 LLVMAddAttribute (LLVMGetParam (method, linfo->vret_arg_pindex), LLVMNoAliasAttribute);
7035 ctx->this_arg_pindex = linfo->this_arg_pindex;
7036 ctx->this_arg = LLVMGetParam (method, linfo->this_arg_pindex);
7037 values [cfg->args [0]->dreg] = ctx->this_arg;
7038 LLVMSetValueName (values [cfg->args [0]->dreg], "this");
7041 names = g_new (char *, sig->param_count);
7042 mono_method_get_param_names (cfg->method, (const char **) names);
7044 /* Set parameter names/attributes */
7045 for (i = 0; i < sig->param_count; ++i) {
7046 LLVMArgInfo *ainfo = &linfo->args [i + sig->hasthis];
7048 int pindex = ainfo->pindex + ainfo->ndummy_fpargs;
7051 for (j = 0; j < ainfo->ndummy_fpargs; ++j) {
7052 name = g_strdup_printf ("dummy_%d_%d", i, j);
7053 LLVMSetValueName (LLVMGetParam (method, ainfo->pindex + j), name);
7057 if (ainfo->storage == LLVMArgVtypeInReg && ainfo->pair_storage [0] == LLVMArgNone && ainfo->pair_storage [1] == LLVMArgNone)
7060 values [cfg->args [i + sig->hasthis]->dreg] = LLVMGetParam (method, pindex);
7061 if (ainfo->storage == LLVMArgGsharedvtFixed || ainfo->storage == LLVMArgGsharedvtFixedVtype) {
7062 if (names [i] && names [i][0] != '\0')
7063 name = g_strdup_printf ("p_arg_%s", names [i]);
7065 name = g_strdup_printf ("p_arg_%d", i);
7067 if (names [i] && names [i][0] != '\0')
7068 name = g_strdup_printf ("arg_%s", names [i]);
7070 name = g_strdup_printf ("arg_%d", i);
7072 LLVMSetValueName (values [cfg->args [i + sig->hasthis]->dreg], name);
7074 if (ainfo->storage == LLVMArgVtypeByVal)
7075 LLVMAddAttribute (LLVMGetParam (method, pindex), LLVMByValAttribute);
7077 if (ainfo->storage == LLVMArgVtypeByRef) {
7079 cfg->args [i + sig->hasthis]->opcode = OP_VTARG_ADDR;
7084 if (ctx->module->emit_dwarf && cfg->compile_aot && mono_debug_enabled ()) {
7085 ctx->minfo = mono_debug_lookup_method (cfg->method);
7086 ctx->dbg_md = emit_dbg_subprogram (ctx, cfg, method, ctx->method_name);
7090 for (bb = cfg->bb_entry; bb; bb = bb->next_bb)
7091 max_block_num = MAX (max_block_num, bb->block_num);
7092 ctx->bblocks = bblocks = g_new0 (BBInfo, max_block_num + 1);
7094 /* Add branches between non-consecutive bblocks */
7095 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
7096 if (bb->last_ins && MONO_IS_COND_BRANCH_OP (bb->last_ins) &&
7097 bb->next_bb != bb->last_ins->inst_false_bb) {
7099 MonoInst *inst = (MonoInst*)mono_mempool_alloc0 (cfg->mempool, sizeof (MonoInst));
7100 inst->opcode = OP_BR;
7101 inst->inst_target_bb = bb->last_ins->inst_false_bb;
7102 mono_bblock_add_inst (bb, inst);
7107 * The INDIRECT flag added by OP_LDADDR inhibits optimizations, even if the LDADDR
7108 * was later optimized away, so clear these flags, and add them back for the still
7109 * present OP_LDADDR instructions.
7111 for (i = 0; i < cfg->next_vreg; ++i) {
7114 ins = get_vreg_to_inst (cfg, i);
7115 if (ins && ins != cfg->rgctx_var)
7116 ins->flags &= ~MONO_INST_INDIRECT;
7120 * Make a first pass over the code to precreate PHI nodes/set INDIRECT flags.
7122 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
7124 LLVMBuilderRef builder;
7126 char dname_buf[128];
7128 builder = create_builder (ctx);
7130 for (ins = bb->code; ins; ins = ins->next) {
7131 switch (ins->opcode) {
7136 LLVMTypeRef phi_type = llvm_type_to_stack_type (cfg, type_to_llvm_type (ctx, &ins->klass->byval_arg));
7141 if (ins->opcode == OP_VPHI) {
7142 /* Treat valuetype PHI nodes as operating on the address itself */
7143 g_assert (ins->klass);
7144 phi_type = LLVMPointerType (type_to_llvm_type (ctx, &ins->klass->byval_arg), 0);
7148 * Have to precreate these, as they can be referenced by
7149 * earlier instructions.
7151 sprintf (dname_buf, "t%d", ins->dreg);
7153 values [ins->dreg] = LLVMBuildPhi (builder, phi_type, dname);
7155 if (ins->opcode == OP_VPHI)
7156 ctx->addresses [ins->dreg] = values [ins->dreg];
7158 g_ptr_array_add (ctx->phi_values, values [ins->dreg]);
7161 * Set the expected type of the incoming arguments since these have
7162 * to have the same type.
7164 for (i = 0; i < ins->inst_phi_args [0]; i++) {
7165 int sreg1 = ins->inst_phi_args [i + 1];
7168 if (ins->opcode == OP_VPHI)
7169 ctx->is_vphi [sreg1] = TRUE;
7170 ctx->vreg_types [sreg1] = phi_type;
7176 ((MonoInst*)ins->inst_p0)->flags |= MONO_INST_INDIRECT;
7185 * Create an ordering for bblocks, use the depth first order first, then
7186 * put the exception handling bblocks last.
7188 for (bb_index = 0; bb_index < cfg->num_bblocks; ++bb_index) {
7189 bb = cfg->bblocks [bb_index];
7190 if (!(bb->region != -1 && !MONO_BBLOCK_IS_IN_REGION (bb, MONO_REGION_TRY))) {
7191 g_ptr_array_add (bblock_list, bb);
7192 bblocks [bb->block_num].added = TRUE;
7196 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
7197 if (!bblocks [bb->block_num].added)
7198 g_ptr_array_add (bblock_list, bb);
7202 * Second pass: generate code.
7205 LLVMBuilderRef entry_builder = create_builder (ctx);
7206 LLVMBasicBlockRef entry_bb = get_bb (ctx, cfg->bb_entry);
7207 LLVMPositionBuilderAtEnd (entry_builder, entry_bb);
7208 emit_entry_bb (ctx, entry_builder);
7210 // Make landing pads first
7211 ctx->exc_meta = g_hash_table_new_full (NULL, NULL, NULL, NULL);
7213 if (ctx->llvm_only) {
7214 size_t group_index = 0;
7215 while (group_index < cfg->header->num_clauses) {
7217 size_t cursor = group_index;
7218 while (cursor < cfg->header->num_clauses &&
7219 CLAUSE_START (&cfg->header->clauses [cursor]) == CLAUSE_START (&cfg->header->clauses [group_index]) &&
7220 CLAUSE_END (&cfg->header->clauses [cursor]) == CLAUSE_END (&cfg->header->clauses [group_index])) {
7225 LLVMBasicBlockRef lpad_bb = emit_landing_pad (ctx, group_index, count);
7226 intptr_t key = CLAUSE_END (&cfg->header->clauses [group_index]);
7227 g_hash_table_insert (ctx->exc_meta, (gpointer)key, lpad_bb);
7229 group_index = cursor;
7233 for (bb_index = 0; bb_index < bblock_list->len; ++bb_index) {
7234 bb = (MonoBasicBlock*)g_ptr_array_index (bblock_list, bb_index);
7236 // Prune unreachable mono BBs.
7237 if (!(bb == cfg->bb_entry || bb->in_count > 0))
7240 process_bb (ctx, bb);
7244 g_hash_table_destroy (ctx->exc_meta);
7246 mono_memory_barrier ();
7248 /* Add incoming phi values */
7249 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
7250 GSList *l, *ins_list;
7252 ins_list = bblocks [bb->block_num].phi_nodes;
7254 for (l = ins_list; l; l = l->next) {
7255 PhiNode *node = (PhiNode*)l->data;
7256 MonoInst *phi = node->phi;
7257 int sreg1 = node->sreg;
7258 LLVMBasicBlockRef in_bb;
7263 in_bb = get_end_bb (ctx, node->in_bb);
7265 if (ctx->unreachable [node->in_bb->block_num])
7268 if (!values [sreg1]) {
7269 /* Can happen with values in EH clauses */
7270 set_failure (ctx, "incoming phi sreg1");
7274 if (phi->opcode == OP_VPHI) {
7275 g_assert (LLVMTypeOf (ctx->addresses [sreg1]) == LLVMTypeOf (values [phi->dreg]));
7276 LLVMAddIncoming (values [phi->dreg], &ctx->addresses [sreg1], &in_bb, 1);
7278 if (LLVMTypeOf (values [sreg1]) != LLVMTypeOf (values [phi->dreg])) {
7279 set_failure (ctx, "incoming phi arg type mismatch");
7282 g_assert (LLVMTypeOf (values [sreg1]) == LLVMTypeOf (values [phi->dreg]));
7283 LLVMAddIncoming (values [phi->dreg], &values [sreg1], &in_bb, 1);
7288 /* Nullify empty phi instructions */
7289 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
7290 GSList *l, *ins_list;
7292 ins_list = bblocks [bb->block_num].phi_nodes;
7294 for (l = ins_list; l; l = l->next) {
7295 PhiNode *node = (PhiNode*)l->data;
7296 MonoInst *phi = node->phi;
7297 LLVMValueRef phi_ins = values [phi->dreg];
7300 /* Already removed */
7303 if (LLVMCountIncoming (phi_ins) == 0) {
7304 mono_llvm_replace_uses_of (phi_ins, LLVMConstNull (LLVMTypeOf (phi_ins)));
7305 LLVMInstructionEraseFromParent (phi_ins);
7306 values [phi->dreg] = NULL;
7311 /* Create the SWITCH statements for ENDFINALLY instructions */
7312 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
7313 BBInfo *info = &bblocks [bb->block_num];
7315 for (l = info->endfinally_switch_ins_list; l; l = l->next) {
7316 LLVMValueRef switch_ins = (LLVMValueRef)l->data;
7317 GSList *bb_list = info->call_handler_return_bbs;
7319 GSList *bb_list_iter;
7321 for (bb_list_iter = bb_list; bb_list_iter; bb_list_iter = g_slist_next (bb_list_iter)) {
7322 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), i + 1, FALSE), (LLVMBasicBlockRef)bb_list_iter->data);
7328 /* Initialize the method if needed */
7329 if (cfg->compile_aot && ctx->llvm_only) {
7330 // FIXME: Add more shared got entries
7331 ctx->builder = create_builder (ctx);
7332 LLVMPositionBuilderAtEnd (ctx->builder, ctx->init_bb);
7334 ctx->module->max_method_idx = MAX (ctx->module->max_method_idx, cfg->method_index);
7336 // FIXME: beforefieldinit
7338 * NATIVE_TO_MANAGED methods might be called on a thread not attached to the runtime, so they are initialized when loaded
7339 * in load_method ().
7341 if ((ctx->has_got_access || mono_class_get_cctor (cfg->method->klass)) && !(cfg->method->wrapper_type == MONO_WRAPPER_NATIVE_TO_MANAGED)) {
7343 * linkonce methods shouldn't have initialization,
7344 * because they might belong to assemblies which
7345 * haven't been loaded yet.
7347 g_assert (!ctx->is_linkonce);
7348 emit_init_method (ctx);
7350 LLVMBuildBr (ctx->builder, ctx->inited_bb);
7354 if (cfg->llvm_only) {
7355 GHashTableIter iter;
7357 GSList *callers, *l, *l2;
7360 * Add the contents of ctx->method_to_callers to module->method_to_callers.
7361 * We can't do this earlier, as it contains llvm instructions which can be
7362 * freed if compilation fails.
7363 * FIXME: Get rid of this when all methods can be llvm compiled.
7365 g_hash_table_iter_init (&iter, ctx->method_to_callers);
7366 while (g_hash_table_iter_next (&iter, (void**)&method, (void**)&callers)) {
7367 for (l = callers; l; l = l->next) {
7368 l2 = (GSList*)g_hash_table_lookup (ctx->module->method_to_callers, method);
7369 l2 = g_slist_prepend (l2, l->data);
7370 g_hash_table_insert (ctx->module->method_to_callers, method, l2);
7375 if (cfg->verbose_level > 1)
7376 mono_llvm_dump_value (method);
7378 if (cfg->compile_aot && !cfg->llvm_only)
7379 mark_as_used (ctx->module, method);
7381 if (!cfg->llvm_only) {
7382 LLVMValueRef md_args [16];
7383 LLVMValueRef md_node;
7386 if (cfg->compile_aot)
7387 method_index = mono_aot_get_method_index (cfg->orig_method);
7390 md_args [0] = LLVMMDString (ctx->method_name, strlen (ctx->method_name));
7391 md_args [1] = LLVMConstInt (LLVMInt32Type (), method_index, FALSE);
7392 md_node = LLVMMDNode (md_args, 2);
7393 LLVMAddNamedMetadataOperand (lmodule, "mono.function_indexes", md_node);
7394 //LLVMSetMetadata (method, md_kind, LLVMMDNode (&md_arg, 1));
7397 if (cfg->compile_aot) {
7398 /* Don't generate native code, keep the LLVM IR */
7399 if (cfg->verbose_level)
7400 printf ("%s emitted as %s\n", mono_method_full_name (cfg->method, TRUE), ctx->method_name);
7402 #if LLVM_API_VERSION < 100
7403 /* VerifyFunction can't handle some of the debug info created by DIBuilder in llvm 3.9 */
7404 int err = LLVMVerifyFunction(ctx->lmethod, LLVMPrintMessageAction);
7405 g_assert (err == 0);
7408 //LLVMVerifyFunction(method, 0);
7409 #if LLVM_API_VERSION > 100
7410 MonoDomain *domain = mono_domain_get ();
7411 MonoJitDomainInfo *domain_info;
7412 int nvars = g_hash_table_size (ctx->jit_callees);
7413 LLVMValueRef *callee_vars = g_new0 (LLVMValueRef, nvars);
7414 gpointer *callee_addrs = g_new0 (gpointer, nvars);
7415 GHashTableIter iter;
7421 * Compute the addresses of the LLVM globals pointing to the
7422 * methods called by the current method. Pass it to the trampoline
7423 * code so it can update them after their corresponding method was
7426 g_hash_table_iter_init (&iter, ctx->jit_callees);
7428 while (g_hash_table_iter_next (&iter, NULL, (void**)&var))
7429 callee_vars [i ++] = var;
7431 cfg->native_code = mono_llvm_compile_method (ctx->module->mono_ee, ctx->lmethod, nvars, callee_vars, callee_addrs, &eh_frame);
7433 decode_llvm_eh_info (ctx, eh_frame);
7435 mono_domain_lock (domain);
7436 domain_info = domain_jit_info (domain);
7437 if (!domain_info->llvm_jit_callees)
7438 domain_info->llvm_jit_callees = g_hash_table_new (NULL, NULL);
7439 g_hash_table_iter_init (&iter, ctx->jit_callees);
7441 while (g_hash_table_iter_next (&iter, (void**)&callee, (void**)&var)) {
7442 GSList *addrs = g_hash_table_lookup (domain_info->llvm_jit_callees, callee);
7443 addrs = g_slist_prepend (addrs, callee_addrs [i]);
7444 g_hash_table_insert (domain_info->llvm_jit_callees, callee, addrs);
7447 mono_domain_unlock (domain);
7449 mono_llvm_optimize_method (ctx->module->mono_ee, ctx->lmethod);
7451 if (cfg->verbose_level > 1)
7452 mono_llvm_dump_value (ctx->lmethod);
7454 cfg->native_code = (unsigned char*)LLVMGetPointerToGlobal (ctx->module->ee, ctx->lmethod);
7456 /* Set by emit_cb */
7457 g_assert (cfg->code_len);
7461 if (ctx->module->method_to_lmethod)
7462 g_hash_table_insert (ctx->module->method_to_lmethod, cfg->method, ctx->lmethod);
7463 if (ctx->module->idx_to_lmethod)
7464 g_hash_table_insert (ctx->module->idx_to_lmethod, GINT_TO_POINTER (cfg->method_index), ctx->lmethod);
7466 if (ctx->llvm_only && cfg->orig_method->klass->valuetype && !(cfg->orig_method->flags & METHOD_ATTRIBUTE_STATIC))
7467 emit_unbox_tramp (ctx, ctx->method_name, ctx->method_type, ctx->lmethod, cfg->method_index);
7471 * mono_llvm_create_vars:
7473 * Same as mono_arch_create_vars () for LLVM.
7476 mono_llvm_create_vars (MonoCompile *cfg)
7478 MonoMethodSignature *sig;
7480 sig = mono_method_signature (cfg->method);
7481 if (cfg->gsharedvt && cfg->llvm_only) {
7482 if (mini_is_gsharedvt_variable_signature (sig) && sig->ret->type != MONO_TYPE_VOID) {
7483 cfg->vret_addr = mono_compile_create_var (cfg, &mono_get_intptr_class ()->byval_arg, OP_ARG);
7484 if (G_UNLIKELY (cfg->verbose_level > 1)) {
7485 printf ("vret_addr = ");
7486 mono_print_ins (cfg->vret_addr);
7490 mono_arch_create_vars (cfg);
7495 * mono_llvm_emit_call:
7497 * Same as mono_arch_emit_call () for LLVM.
7500 mono_llvm_emit_call (MonoCompile *cfg, MonoCallInst *call)
7503 MonoMethodSignature *sig;
7504 int i, n, stack_size;
7509 sig = call->signature;
7510 n = sig->param_count + sig->hasthis;
7512 call->cinfo = get_llvm_call_info (cfg, sig);
7514 if (cfg->disable_llvm)
7517 if (sig->call_convention == MONO_CALL_VARARG) {
7518 cfg->exception_message = g_strdup ("varargs");
7519 cfg->disable_llvm = TRUE;
7522 for (i = 0; i < n; ++i) {
7525 ainfo = call->cinfo->args + i;
7527 in = call->args [i];
7529 /* Simply remember the arguments */
7530 switch (ainfo->storage) {
7531 case LLVMArgNormal: {
7532 MonoType *t = (sig->hasthis && i == 0) ? &mono_get_intptr_class ()->byval_arg : ainfo->type;
7535 opcode = mono_type_to_regmove (cfg, t);
7536 if (opcode == OP_FMOVE) {
7537 MONO_INST_NEW (cfg, ins, OP_FMOVE);
7538 ins->dreg = mono_alloc_freg (cfg);
7539 } else if (opcode == OP_LMOVE) {
7540 MONO_INST_NEW (cfg, ins, OP_LMOVE);
7541 ins->dreg = mono_alloc_lreg (cfg);
7542 } else if (opcode == OP_RMOVE) {
7543 MONO_INST_NEW (cfg, ins, OP_RMOVE);
7544 ins->dreg = mono_alloc_freg (cfg);
7546 MONO_INST_NEW (cfg, ins, OP_MOVE);
7547 ins->dreg = mono_alloc_ireg (cfg);
7549 ins->sreg1 = in->dreg;
7552 case LLVMArgVtypeByVal:
7553 case LLVMArgVtypeByRef:
7554 case LLVMArgVtypeInReg:
7555 case LLVMArgVtypeAsScalar:
7556 case LLVMArgAsIArgs:
7557 case LLVMArgAsFpArgs:
7558 case LLVMArgGsharedvtVariable:
7559 case LLVMArgGsharedvtFixed:
7560 case LLVMArgGsharedvtFixedVtype:
7561 MONO_INST_NEW (cfg, ins, OP_LLVM_OUTARG_VT);
7562 ins->dreg = mono_alloc_ireg (cfg);
7563 ins->sreg1 = in->dreg;
7564 ins->inst_p0 = mono_mempool_alloc0 (cfg->mempool, sizeof (LLVMArgInfo));
7565 memcpy (ins->inst_p0, ainfo, sizeof (LLVMArgInfo));
7566 ins->inst_vtype = ainfo->type;
7567 ins->klass = mono_class_from_mono_type (ainfo->type);
7570 cfg->exception_message = g_strdup ("ainfo->storage");
7571 cfg->disable_llvm = TRUE;
7575 if (!cfg->disable_llvm) {
7576 MONO_ADD_INS (cfg->cbb, ins);
7577 mono_call_inst_add_outarg_reg (cfg, call, ins->dreg, 0, FALSE);
7582 static unsigned char*
7583 alloc_cb (LLVMValueRef function, int size)
7587 cfg = (MonoCompile*)mono_native_tls_get_value (current_cfg_tls_id);
7591 return (unsigned char*)mono_domain_code_reserve (cfg->domain, size);
7593 return (unsigned char*)mono_domain_code_reserve (mono_domain_get (), size);
7598 emitted_cb (LLVMValueRef function, void *start, void *end)
7602 cfg = (MonoCompile*)mono_native_tls_get_value (current_cfg_tls_id);
7604 cfg->code_len = (guint8*)end - (guint8*)start;
7608 exception_cb (void *data)
7611 MonoJitExceptionInfo *ei;
7612 guint32 ei_len, i, j, nested_len, nindex;
7613 gpointer *type_info;
7614 int this_reg, this_offset;
7616 cfg = (MonoCompile*)mono_native_tls_get_value (current_cfg_tls_id);
7620 * data points to a DWARF FDE structure, convert it to our unwind format and
7622 * An alternative would be to save it directly, and modify our unwinder to work
7625 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);
7626 if (cfg->verbose_level > 1)
7627 mono_print_unwind_info (cfg->encoded_unwind_ops, cfg->encoded_unwind_ops_len);
7629 /* Count nested clauses */
7631 for (i = 0; i < ei_len; ++i) {
7632 gint32 cindex1 = *(gint32*)type_info [i];
7633 MonoExceptionClause *clause1 = &cfg->header->clauses [cindex1];
7635 for (j = 0; j < cfg->header->num_clauses; ++j) {
7637 MonoExceptionClause *clause2 = &cfg->header->clauses [cindex2];
7639 if (cindex1 != cindex2 && clause1->try_offset >= clause2->try_offset && clause1->handler_offset <= clause2->handler_offset) {
7645 cfg->llvm_ex_info = (MonoJitExceptionInfo*)mono_mempool_alloc0 (cfg->mempool, (ei_len + nested_len) * sizeof (MonoJitExceptionInfo));
7646 cfg->llvm_ex_info_len = ei_len + nested_len;
7647 memcpy (cfg->llvm_ex_info, ei, ei_len * sizeof (MonoJitExceptionInfo));
7648 /* Fill the rest of the information from the type info */
7649 for (i = 0; i < ei_len; ++i) {
7650 gint32 clause_index = *(gint32*)type_info [i];
7651 MonoExceptionClause *clause = &cfg->header->clauses [clause_index];
7653 cfg->llvm_ex_info [i].flags = clause->flags;
7654 cfg->llvm_ex_info [i].data.catch_class = clause->data.catch_class;
7655 cfg->llvm_ex_info [i].clause_index = clause_index;
7659 * For nested clauses, the LLVM produced exception info associates the try interval with
7660 * the innermost handler, while mono expects it to be associated with all nesting clauses.
7661 * So add new clauses which use the IL info (catch class etc.) from the nesting clause,
7662 * and everything else from the nested clause.
7665 for (i = 0; i < ei_len; ++i) {
7666 gint32 cindex1 = *(gint32*)type_info [i];
7667 MonoExceptionClause *clause1 = &cfg->header->clauses [cindex1];
7669 for (j = 0; j < cfg->header->num_clauses; ++j) {
7671 MonoExceptionClause *clause2 = &cfg->header->clauses [cindex2];
7672 MonoJitExceptionInfo *nesting_ei, *nested_ei;
7674 if (cindex1 != cindex2 && clause1->try_offset >= clause2->try_offset && clause1->handler_offset <= clause2->handler_offset) {
7675 /* clause1 is the nested clause */
7676 nested_ei = &cfg->llvm_ex_info [i];
7677 nesting_ei = &cfg->llvm_ex_info [nindex];
7680 memcpy (nesting_ei, nested_ei, sizeof (MonoJitExceptionInfo));
7682 nesting_ei->flags = clause2->flags;
7683 nesting_ei->data.catch_class = clause2->data.catch_class;
7684 nesting_ei->clause_index = cindex2;
7688 g_assert (nindex == ei_len + nested_len);
7689 cfg->llvm_this_reg = this_reg;
7690 cfg->llvm_this_offset = this_offset;
7692 /* type_info [i] is cfg mempool allocated, no need to free it */
7698 #if LLVM_API_VERSION > 100
7700 * decode_llvm_eh_info:
7702 * Decode the EH table emitted by llvm in jit mode, and store
7703 * the result into cfg.
7706 decode_llvm_eh_info (EmitContext *ctx, gpointer eh_frame)
7708 MonoCompile *cfg = ctx->cfg;
7711 MonoLLVMFDEInfo info;
7712 MonoJitExceptionInfo *ei;
7713 guint8 *p = eh_frame;
7714 int version, fde_count, fde_offset;
7715 guint32 ei_len, i, nested_len;
7716 gpointer *type_info;
7720 * Decode the one element EH table emitted by the MonoException class
7724 /* Similar to decode_llvm_mono_eh_frame () in aot-runtime.c */
7727 g_assert (version == 3);
7730 p = (guint8 *)ALIGN_PTR_TO (p, 4);
7732 fde_count = *(guint32*)p;
7736 g_assert (fde_count <= 2);
7738 /* The first entry is the real method */
7739 g_assert (table [0] == 1);
7740 fde_offset = table [1];
7741 table += fde_count * 2;
7743 cfg->code_len = table [0];
7744 fde_len = table [1] - fde_offset;
7747 fde = (guint8*)eh_frame + fde_offset;
7748 cie = (guint8*)table;
7750 mono_unwind_decode_llvm_mono_fde (fde, fde_len, cie, cfg->native_code, &info);
7752 cfg->encoded_unwind_ops = info.unw_info;
7753 cfg->encoded_unwind_ops_len = info.unw_info_len;
7754 if (cfg->verbose_level > 1)
7755 mono_print_unwind_info (cfg->encoded_unwind_ops, cfg->encoded_unwind_ops_len);
7756 if (info.this_reg != -1) {
7757 cfg->llvm_this_reg = info.this_reg;
7758 cfg->llvm_this_offset = info.this_offset;
7762 ei_len = info.ex_info_len;
7763 type_info = info.type_info;
7765 // Nested clauses are currently disabled
7768 cfg->llvm_ex_info = (MonoJitExceptionInfo*)mono_mempool_alloc0 (cfg->mempool, (ei_len + nested_len) * sizeof (MonoJitExceptionInfo));
7769 cfg->llvm_ex_info_len = ei_len + nested_len;
7770 memcpy (cfg->llvm_ex_info, ei, ei_len * sizeof (MonoJitExceptionInfo));
7771 /* Fill the rest of the information from the type info */
7772 for (i = 0; i < ei_len; ++i) {
7773 gint32 clause_index = *(gint32*)type_info [i];
7774 MonoExceptionClause *clause = &cfg->header->clauses [clause_index];
7776 cfg->llvm_ex_info [i].flags = clause->flags;
7777 cfg->llvm_ex_info [i].data.catch_class = clause->data.catch_class;
7778 cfg->llvm_ex_info [i].clause_index = clause_index;
7784 dlsym_cb (const char *name, void **symbol)
7790 if (!strcmp (name, "__bzero")) {
7791 *symbol = (void*)bzero;
7793 current = mono_dl_open (NULL, 0, NULL);
7796 err = mono_dl_symbol (current, name, symbol);
7798 mono_dl_close (current);
7800 #ifdef MONO_ARCH_HAVE_CREATE_LLVM_NATIVE_THUNK
7801 *symbol = (char*)mono_arch_create_llvm_native_thunk (mono_domain_get (), (guint8*)(*symbol));
7807 AddFunc (LLVMModuleRef module, const char *name, LLVMTypeRef ret_type, LLVMTypeRef *param_types, int nparams)
7809 LLVMAddFunction (module, name, LLVMFunctionType (ret_type, param_types, nparams, FALSE));
7813 AddFunc2 (LLVMModuleRef module, const char *name, LLVMTypeRef ret_type, LLVMTypeRef param_type1, LLVMTypeRef param_type2)
7815 LLVMTypeRef param_types [4];
7817 param_types [0] = param_type1;
7818 param_types [1] = param_type2;
7820 AddFunc (module, name, ret_type, param_types, 2);
7826 INTRINS_SADD_OVF_I32,
7827 INTRINS_UADD_OVF_I32,
7828 INTRINS_SSUB_OVF_I32,
7829 INTRINS_USUB_OVF_I32,
7830 INTRINS_SMUL_OVF_I32,
7831 INTRINS_UMUL_OVF_I32,
7832 INTRINS_SADD_OVF_I64,
7833 INTRINS_UADD_OVF_I64,
7834 INTRINS_SSUB_OVF_I64,
7835 INTRINS_USUB_OVF_I64,
7836 INTRINS_SMUL_OVF_I64,
7837 INTRINS_UMUL_OVF_I64,
7844 #if defined(TARGET_AMD64) || defined(TARGET_X86)
7845 INTRINS_SSE_PMOVMSKB,
7846 INTRINS_SSE_PSRLI_W,
7847 INTRINS_SSE_PSRAI_W,
7848 INTRINS_SSE_PSLLI_W,
7849 INTRINS_SSE_PSRLI_D,
7850 INTRINS_SSE_PSRAI_D,
7851 INTRINS_SSE_PSLLI_D,
7852 INTRINS_SSE_PSRLI_Q,
7853 INTRINS_SSE_PSLLI_Q,
7854 INTRINS_SSE_SQRT_PD,
7855 INTRINS_SSE_SQRT_PS,
7856 INTRINS_SSE_RSQRT_PS,
7858 INTRINS_SSE_CVTTPD2DQ,
7859 INTRINS_SSE_CVTTPS2DQ,
7860 INTRINS_SSE_CVTDQ2PD,
7861 INTRINS_SSE_CVTDQ2PS,
7862 INTRINS_SSE_CVTPD2DQ,
7863 INTRINS_SSE_CVTPS2DQ,
7864 INTRINS_SSE_CVTPD2PS,
7865 INTRINS_SSE_CVTPS2PD,
7868 INTRINS_SSE_PACKSSWB,
7869 INTRINS_SSE_PACKUSWB,
7870 INTRINS_SSE_PACKSSDW,
7871 INTRINS_SSE_PACKUSDW,
7876 INTRINS_SSE_ADDSUBPS,
7881 INTRINS_SSE_ADDSUBPD,
7884 INTRINS_SSE_PADDUSW,
7885 INTRINS_SSE_PSUBUSW,
7891 INTRINS_SSE_PADDUSB,
7892 INTRINS_SSE_PSUBUSB,
7905 static IntrinsicDesc intrinsics[] = {
7906 {INTRINS_MEMSET, "llvm.memset.p0i8.i32"},
7907 {INTRINS_MEMCPY, "llvm.memcpy.p0i8.p0i8.i32"},
7908 {INTRINS_SADD_OVF_I32, "llvm.sadd.with.overflow.i32"},
7909 {INTRINS_UADD_OVF_I32, "llvm.uadd.with.overflow.i32"},
7910 {INTRINS_SSUB_OVF_I32, "llvm.ssub.with.overflow.i32"},
7911 {INTRINS_USUB_OVF_I32, "llvm.usub.with.overflow.i32"},
7912 {INTRINS_SMUL_OVF_I32, "llvm.smul.with.overflow.i32"},
7913 {INTRINS_UMUL_OVF_I32, "llvm.umul.with.overflow.i32"},
7914 {INTRINS_SADD_OVF_I64, "llvm.sadd.with.overflow.i64"},
7915 {INTRINS_UADD_OVF_I64, "llvm.uadd.with.overflow.i64"},
7916 {INTRINS_SSUB_OVF_I64, "llvm.ssub.with.overflow.i64"},
7917 {INTRINS_USUB_OVF_I64, "llvm.usub.with.overflow.i64"},
7918 {INTRINS_SMUL_OVF_I64, "llvm.smul.with.overflow.i64"},
7919 {INTRINS_UMUL_OVF_I64, "llvm.umul.with.overflow.i64"},
7920 {INTRINS_SIN, "llvm.sin.f64"},
7921 {INTRINS_COS, "llvm.cos.f64"},
7922 {INTRINS_SQRT, "llvm.sqrt.f64"},
7923 /* This isn't an intrinsic, instead llvm seems to special case it by name */
7924 {INTRINS_FABS, "fabs"},
7925 {INTRINS_EXPECT_I8, "llvm.expect.i8"},
7926 {INTRINS_EXPECT_I1, "llvm.expect.i1"},
7927 #if defined(TARGET_AMD64) || defined(TARGET_X86)
7928 {INTRINS_SSE_PMOVMSKB, "llvm.x86.sse2.pmovmskb.128"},
7929 {INTRINS_SSE_PSRLI_W, "llvm.x86.sse2.psrli.w"},
7930 {INTRINS_SSE_PSRAI_W, "llvm.x86.sse2.psrai.w"},
7931 {INTRINS_SSE_PSLLI_W, "llvm.x86.sse2.pslli.w"},
7932 {INTRINS_SSE_PSRLI_D, "llvm.x86.sse2.psrli.d"},
7933 {INTRINS_SSE_PSRAI_D, "llvm.x86.sse2.psrai.d"},
7934 {INTRINS_SSE_PSLLI_D, "llvm.x86.sse2.pslli.d"},
7935 {INTRINS_SSE_PSRLI_Q, "llvm.x86.sse2.psrli.q"},
7936 {INTRINS_SSE_PSLLI_Q, "llvm.x86.sse2.pslli.q"},
7937 {INTRINS_SSE_SQRT_PD, "llvm.x86.sse2.sqrt.pd"},
7938 {INTRINS_SSE_SQRT_PS, "llvm.x86.sse.sqrt.ps"},
7939 {INTRINS_SSE_RSQRT_PS, "llvm.x86.sse.rsqrt.ps"},
7940 {INTRINS_SSE_RCP_PS, "llvm.x86.sse.rcp.ps"},
7941 {INTRINS_SSE_CVTTPD2DQ, "llvm.x86.sse2.cvttpd2dq"},
7942 {INTRINS_SSE_CVTTPS2DQ, "llvm.x86.sse2.cvttps2dq"},
7943 {INTRINS_SSE_CVTDQ2PD, "llvm.x86.sse2.cvtdq2pd"},
7944 {INTRINS_SSE_CVTDQ2PS, "llvm.x86.sse2.cvtdq2ps"},
7945 {INTRINS_SSE_CVTPD2DQ, "llvm.x86.sse2.cvtpd2dq"},
7946 {INTRINS_SSE_CVTPS2DQ, "llvm.x86.sse2.cvtps2dq"},
7947 {INTRINS_SSE_CVTPD2PS, "llvm.x86.sse2.cvtpd2ps"},
7948 {INTRINS_SSE_CVTPS2PD, "llvm.x86.sse2.cvtps2pd"},
7949 {INTRINS_SSE_CMPPD, "llvm.x86.sse2.cmp.pd"},
7950 {INTRINS_SSE_CMPPS, "llvm.x86.sse.cmp.ps"},
7951 {INTRINS_SSE_PACKSSWB, "llvm.x86.sse2.packsswb.128"},
7952 {INTRINS_SSE_PACKUSWB, "llvm.x86.sse2.packuswb.128"},
7953 {INTRINS_SSE_PACKSSDW, "llvm.x86.sse2.packssdw.128"},
7954 {INTRINS_SSE_PACKUSDW, "llvm.x86.sse41.packusdw"},
7955 {INTRINS_SSE_MINPS, "llvm.x86.sse.min.ps"},
7956 {INTRINS_SSE_MAXPS, "llvm.x86.sse.max.ps"},
7957 {INTRINS_SSE_HADDPS, "llvm.x86.sse3.hadd.ps"},
7958 {INTRINS_SSE_HSUBPS, "llvm.x86.sse3.hsub.ps"},
7959 {INTRINS_SSE_ADDSUBPS, "llvm.x86.sse3.addsub.ps"},
7960 {INTRINS_SSE_MINPD, "llvm.x86.sse2.min.pd"},
7961 {INTRINS_SSE_MAXPD, "llvm.x86.sse2.max.pd"},
7962 {INTRINS_SSE_HADDPD, "llvm.x86.sse3.hadd.pd"},
7963 {INTRINS_SSE_HSUBPD, "llvm.x86.sse3.hsub.pd"},
7964 {INTRINS_SSE_ADDSUBPD, "llvm.x86.sse3.addsub.pd"},
7965 {INTRINS_SSE_PADDSW, "llvm.x86.sse2.padds.w"},
7966 {INTRINS_SSE_PSUBSW, "llvm.x86.sse2.psubs.w"},
7967 {INTRINS_SSE_PADDUSW, "llvm.x86.sse2.paddus.w"},
7968 {INTRINS_SSE_PSUBUSW, "llvm.x86.sse2.psubus.w"},
7969 {INTRINS_SSE_PAVGW, "llvm.x86.sse2.pavg.w"},
7970 {INTRINS_SSE_PMULHW, "llvm.x86.sse2.pmulh.w"},
7971 {INTRINS_SSE_PMULHU, "llvm.x86.sse2.pmulhu.w"},
7972 {INTRINS_SE_PADDSB, "llvm.x86.sse2.padds.b"},
7973 {INTRINS_SSE_PSUBSB, "llvm.x86.sse2.psubs.b"},
7974 {INTRINS_SSE_PADDUSB, "llvm.x86.sse2.paddus.b"},
7975 {INTRINS_SSE_PSUBUSB, "llvm.x86.sse2.psubus.b"},
7976 {INTRINS_SSE_PAVGB, "llvm.x86.sse2.pavg.b"},
7977 {INTRINS_SSE_PAUSE, "llvm.x86.sse2.pause"},
7978 {INTRINS_SSE_DPPS, "llvm.x86.sse41.dpps"}
7983 add_sse_binary (LLVMModuleRef module, const char *name, int type)
7985 LLVMTypeRef ret_type = type_to_simd_type (type);
7986 AddFunc2 (module, name, ret_type, ret_type, ret_type);
7990 add_intrinsic (LLVMModuleRef module, int id)
7993 #if defined(TARGET_AMD64) || defined(TARGET_X86)
7994 LLVMTypeRef ret_type, arg_types [16];
7997 name = g_hash_table_lookup (intrins_id_to_name, GINT_TO_POINTER (id));
8001 case INTRINS_MEMSET: {
8002 LLVMTypeRef params [] = { LLVMPointerType (LLVMInt8Type (), 0), LLVMInt8Type (), LLVMInt32Type (), LLVMInt32Type (), LLVMInt1Type () };
8004 AddFunc (module, name, LLVMVoidType (), params, 5);
8007 case INTRINS_MEMCPY: {
8008 LLVMTypeRef params [] = { LLVMPointerType (LLVMInt8Type (), 0), LLVMPointerType (LLVMInt8Type (), 0), LLVMInt32Type (), LLVMInt32Type (), LLVMInt1Type () };
8010 AddFunc (module, name, LLVMVoidType (), params, 5);
8013 case INTRINS_SADD_OVF_I32:
8014 case INTRINS_UADD_OVF_I32:
8015 case INTRINS_SSUB_OVF_I32:
8016 case INTRINS_USUB_OVF_I32:
8017 case INTRINS_SMUL_OVF_I32:
8018 case INTRINS_UMUL_OVF_I32: {
8019 LLVMTypeRef ovf_res_i32 [] = { LLVMInt32Type (), LLVMInt1Type () };
8020 LLVMTypeRef params [] = { LLVMInt32Type (), LLVMInt32Type () };
8021 LLVMTypeRef ret_type = LLVMStructType (ovf_res_i32, 2, FALSE);
8023 AddFunc (module, name, ret_type, params, 2);
8026 case INTRINS_SADD_OVF_I64:
8027 case INTRINS_UADD_OVF_I64:
8028 case INTRINS_SSUB_OVF_I64:
8029 case INTRINS_USUB_OVF_I64:
8030 case INTRINS_SMUL_OVF_I64:
8031 case INTRINS_UMUL_OVF_I64: {
8032 LLVMTypeRef ovf_res_i64 [] = { LLVMInt64Type (), LLVMInt1Type () };
8033 LLVMTypeRef params [] = { LLVMInt64Type (), LLVMInt64Type () };
8034 LLVMTypeRef ret_type = LLVMStructType (ovf_res_i64, 2, FALSE);
8036 AddFunc (module, name, ret_type, params, 2);
8042 case INTRINS_FABS: {
8043 LLVMTypeRef params [] = { LLVMDoubleType () };
8045 AddFunc (module, name, LLVMDoubleType (), params, 1);
8048 case INTRINS_EXPECT_I8:
8049 AddFunc2 (module, name, LLVMInt8Type (), LLVMInt8Type (), LLVMInt8Type ());
8051 case INTRINS_EXPECT_I1:
8052 AddFunc2 (module, name, LLVMInt1Type (), LLVMInt1Type (), LLVMInt1Type ());
8054 #if defined(TARGET_AMD64) || defined(TARGET_X86)
8055 case INTRINS_SSE_PMOVMSKB:
8057 ret_type = LLVMInt32Type ();
8058 arg_types [0] = type_to_simd_type (MONO_TYPE_I1);
8059 AddFunc (module, name, ret_type, arg_types, 1);
8061 case INTRINS_SSE_PSRLI_W:
8062 case INTRINS_SSE_PSRAI_W:
8063 case INTRINS_SSE_PSLLI_W:
8065 ret_type = type_to_simd_type (MONO_TYPE_I2);
8066 arg_types [0] = ret_type;
8067 arg_types [1] = LLVMInt32Type ();
8068 AddFunc (module, name, ret_type, arg_types, 2);
8070 case INTRINS_SSE_PSRLI_D:
8071 case INTRINS_SSE_PSRAI_D:
8072 case INTRINS_SSE_PSLLI_D:
8073 ret_type = type_to_simd_type (MONO_TYPE_I4);
8074 arg_types [0] = ret_type;
8075 arg_types [1] = LLVMInt32Type ();
8076 AddFunc (module, name, ret_type, arg_types, 2);
8078 case INTRINS_SSE_PSRLI_Q:
8079 case INTRINS_SSE_PSLLI_Q:
8080 ret_type = type_to_simd_type (MONO_TYPE_I8);
8081 arg_types [0] = ret_type;
8082 arg_types [1] = LLVMInt32Type ();
8083 AddFunc (module, name, ret_type, arg_types, 2);
8085 case INTRINS_SSE_SQRT_PD:
8087 ret_type = type_to_simd_type (MONO_TYPE_R8);
8088 arg_types [0] = ret_type;
8089 AddFunc (module, name, ret_type, arg_types, 1);
8091 case INTRINS_SSE_SQRT_PS:
8092 ret_type = type_to_simd_type (MONO_TYPE_R4);
8093 arg_types [0] = ret_type;
8094 AddFunc (module, name, ret_type, arg_types, 1);
8096 case INTRINS_SSE_RSQRT_PS:
8097 ret_type = type_to_simd_type (MONO_TYPE_R4);
8098 arg_types [0] = ret_type;
8099 AddFunc (module, name, ret_type, arg_types, 1);
8101 case INTRINS_SSE_RCP_PS:
8102 ret_type = type_to_simd_type (MONO_TYPE_R4);
8103 arg_types [0] = ret_type;
8104 AddFunc (module, name, ret_type, arg_types, 1);
8106 case INTRINS_SSE_CVTTPD2DQ:
8107 ret_type = type_to_simd_type (MONO_TYPE_I4);
8108 arg_types [0] = type_to_simd_type (MONO_TYPE_R8);
8109 AddFunc (module, name, ret_type, arg_types, 1);
8111 case INTRINS_SSE_CVTTPS2DQ:
8112 ret_type = type_to_simd_type (MONO_TYPE_I4);
8113 arg_types [0] = type_to_simd_type (MONO_TYPE_R4);
8114 AddFunc (module, name, ret_type, arg_types, 1);
8116 case INTRINS_SSE_CVTDQ2PD:
8117 /* Conversion ops */
8118 ret_type = type_to_simd_type (MONO_TYPE_R8);
8119 arg_types [0] = type_to_simd_type (MONO_TYPE_I4);
8120 AddFunc (module, name, ret_type, arg_types, 1);
8122 case INTRINS_SSE_CVTDQ2PS:
8123 ret_type = type_to_simd_type (MONO_TYPE_R4);
8124 arg_types [0] = type_to_simd_type (MONO_TYPE_I4);
8125 AddFunc (module, name, ret_type, arg_types, 1);
8127 case INTRINS_SSE_CVTPD2DQ:
8128 ret_type = type_to_simd_type (MONO_TYPE_I4);
8129 arg_types [0] = type_to_simd_type (MONO_TYPE_R8);
8130 AddFunc (module, name, ret_type, arg_types, 1);
8132 case INTRINS_SSE_CVTPS2DQ:
8133 ret_type = type_to_simd_type (MONO_TYPE_I4);
8134 arg_types [0] = type_to_simd_type (MONO_TYPE_R4);
8135 AddFunc (module, name, ret_type, arg_types, 1);
8137 case INTRINS_SSE_CVTPD2PS:
8138 ret_type = type_to_simd_type (MONO_TYPE_R4);
8139 arg_types [0] = type_to_simd_type (MONO_TYPE_R8);
8140 AddFunc (module, name, ret_type, arg_types, 1);
8142 case INTRINS_SSE_CVTPS2PD:
8143 ret_type = type_to_simd_type (MONO_TYPE_R8);
8144 arg_types [0] = type_to_simd_type (MONO_TYPE_R4);
8145 AddFunc (module, name, ret_type, arg_types, 1);
8147 case INTRINS_SSE_CMPPD:
8149 ret_type = type_to_simd_type (MONO_TYPE_R8);
8150 arg_types [0] = ret_type;
8151 arg_types [1] = ret_type;
8152 arg_types [2] = LLVMInt8Type ();
8153 AddFunc (module, name, ret_type, arg_types, 3);
8155 case INTRINS_SSE_CMPPS:
8156 ret_type = type_to_simd_type (MONO_TYPE_R4);
8157 arg_types [0] = ret_type;
8158 arg_types [1] = ret_type;
8159 arg_types [2] = LLVMInt8Type ();
8160 AddFunc (module, name, ret_type, arg_types, 3);
8162 case INTRINS_SSE_PACKSSWB:
8163 case INTRINS_SSE_PACKUSWB:
8164 case INTRINS_SSE_PACKSSDW:
8166 ret_type = type_to_simd_type (MONO_TYPE_I1);
8167 arg_types [0] = type_to_simd_type (MONO_TYPE_I2);
8168 arg_types [1] = type_to_simd_type (MONO_TYPE_I2);
8169 AddFunc (module, name, ret_type, arg_types, 2);
8171 case INTRINS_SSE_PACKUSDW:
8172 ret_type = type_to_simd_type (MONO_TYPE_I2);
8173 arg_types [0] = type_to_simd_type (MONO_TYPE_I4);
8174 arg_types [1] = type_to_simd_type (MONO_TYPE_I4);
8175 AddFunc (module, name, ret_type, arg_types, 2);
8177 /* SSE Binary ops */
8178 case INTRINS_SSE_PADDSW:
8179 case INTRINS_SSE_PSUBSW:
8180 case INTRINS_SSE_PADDUSW:
8181 case INTRINS_SSE_PSUBUSW:
8182 case INTRINS_SSE_PAVGW:
8183 case INTRINS_SSE_PMULHW:
8184 case INTRINS_SSE_PMULHU:
8185 add_sse_binary (module, name, MONO_TYPE_I2);
8187 case INTRINS_SSE_MINPS:
8188 case INTRINS_SSE_MAXPS:
8189 case INTRINS_SSE_HADDPS:
8190 case INTRINS_SSE_HSUBPS:
8191 case INTRINS_SSE_ADDSUBPS:
8192 add_sse_binary (module, name, MONO_TYPE_R4);
8194 case INTRINS_SSE_MINPD:
8195 case INTRINS_SSE_MAXPD:
8196 case INTRINS_SSE_HADDPD:
8197 case INTRINS_SSE_HSUBPD:
8198 case INTRINS_SSE_ADDSUBPD:
8199 add_sse_binary (module, name, MONO_TYPE_R8);
8201 case INTRINS_SE_PADDSB:
8202 case INTRINS_SSE_PSUBSB:
8203 case INTRINS_SSE_PADDUSB:
8204 case INTRINS_SSE_PSUBUSB:
8205 case INTRINS_SSE_PAVGB:
8206 add_sse_binary (module, name, MONO_TYPE_I1);
8208 case INTRINS_SSE_PAUSE:
8209 AddFunc (module, "llvm.x86.sse2.pause", LLVMVoidType (), NULL, 0);
8211 case INTRINS_SSE_DPPS:
8212 ret_type = type_to_simd_type (MONO_TYPE_R4);
8213 arg_types [0] = type_to_simd_type (MONO_TYPE_R4);
8214 arg_types [1] = type_to_simd_type (MONO_TYPE_R4);
8215 arg_types [2] = LLVMInt32Type ();
8216 AddFunc (module, name, ret_type, arg_types, 3);
8220 g_assert_not_reached ();
8226 get_intrinsic (EmitContext *ctx, const char *name)
8228 #if LLVM_API_VERSION > 100
8232 * Every method is emitted into its own module so
8233 * we can add intrinsics on demand.
8235 res = LLVMGetNamedFunction (ctx->lmodule, name);
8239 /* No locking needed */
8240 id = GPOINTER_TO_INT (g_hash_table_lookup (intrins_name_to_id, name));
8243 printf ("%s\n", name);
8244 g_assert (id != -1);
8245 add_intrinsic (ctx->lmodule, id);
8246 res = LLVMGetNamedFunction (ctx->lmodule, name);
8254 res = LLVMGetNamedFunction (ctx->lmodule, name);
8261 add_intrinsics (LLVMModuleRef module)
8265 /* Emit declarations of instrinsics */
8267 * It would be nicer to emit only the intrinsics actually used, but LLVM's Module
8268 * type doesn't seem to do any locking.
8270 for (i = 0; i < INTRINS_NUM; ++i)
8271 add_intrinsic (module, i);
8275 AddFunc (module, "mono_personality", LLVMVoidType (), NULL, 0);
8277 AddFunc (module, "llvm_resume_unwind_trampoline", LLVMVoidType (), NULL, 0);
8280 /* Load/Store intrinsics */
8282 LLVMTypeRef arg_types [5];
8286 for (i = 1; i <= 8; i *= 2) {
8287 arg_types [0] = LLVMPointerType (LLVMIntType (i * 8), 0);
8288 arg_types [1] = LLVMInt32Type ();
8289 arg_types [2] = LLVMInt1Type ();
8290 arg_types [3] = LLVMInt32Type ();
8291 sprintf (name, "llvm.mono.load.i%d.p0i%d", i * 8, i * 8);
8292 AddFunc (module, name, LLVMIntType (i * 8), arg_types, 4);
8294 arg_types [0] = LLVMIntType (i * 8);
8295 arg_types [1] = LLVMPointerType (LLVMIntType (i * 8), 0);
8296 arg_types [2] = LLVMInt32Type ();
8297 arg_types [3] = LLVMInt1Type ();
8298 arg_types [4] = LLVMInt32Type ();
8299 sprintf (name, "llvm.mono.store.i%d.p0i%d", i * 8, i * 8);
8300 AddFunc (module, name, LLVMVoidType (), arg_types, 5);
8306 add_types (MonoLLVMModule *module)
8308 module->ptr_type = LLVMPointerType (sizeof (gpointer) == 8 ? LLVMInt64Type () : LLVMInt32Type (), 0);
8312 mono_llvm_init (void)
8317 mono_native_tls_alloc (¤t_cfg_tls_id, NULL);
8319 h = g_hash_table_new (NULL, NULL);
8320 for (i = 0; i < INTRINS_NUM; ++i)
8321 g_hash_table_insert (h, GINT_TO_POINTER (intrinsics [i].id), (gpointer)intrinsics [i].name);
8322 intrins_id_to_name = h;
8324 h = g_hash_table_new (g_str_hash, g_str_equal);
8325 for (i = 0; i < INTRINS_NUM; ++i)
8326 g_hash_table_insert (h, (gpointer)intrinsics [i].name, GINT_TO_POINTER (intrinsics [i].id + 1));
8327 intrins_name_to_id = h;
8331 init_jit_module (MonoDomain *domain)
8333 MonoJitDomainInfo *dinfo;
8334 MonoLLVMModule *module;
8337 dinfo = domain_jit_info (domain);
8338 if (dinfo->llvm_module)
8341 mono_loader_lock ();
8343 if (dinfo->llvm_module) {
8344 mono_loader_unlock ();
8348 module = g_new0 (MonoLLVMModule, 1);
8350 name = g_strdup_printf ("mono-%s", domain->friendly_name);
8351 module->lmodule = LLVMModuleCreateWithName (name);
8352 module->context = LLVMGetGlobalContext ();
8354 module->mono_ee = (MonoEERef*)mono_llvm_create_ee (LLVMCreateModuleProviderForExistingModule (module->lmodule), alloc_cb, emitted_cb, exception_cb, dlsym_cb, &module->ee);
8356 add_intrinsics (module->lmodule);
8359 module->llvm_types = g_hash_table_new (NULL, NULL);
8361 #if LLVM_API_VERSION < 100
8362 MonoJitICallInfo *info;
8364 info = mono_find_jit_icall_by_name ("llvm_resume_unwind_trampoline");
8366 LLVMAddGlobalMapping (module->ee, LLVMGetNamedFunction (module->lmodule, "llvm_resume_unwind_trampoline"), (void*)info->func);
8369 mono_memory_barrier ();
8371 dinfo->llvm_module = module;
8373 mono_loader_unlock ();
8377 mono_llvm_cleanup (void)
8379 MonoLLVMModule *module = &aot_module;
8381 if (module->lmodule)
8382 LLVMDisposeModule (module->lmodule);
8384 if (module->context)
8385 LLVMContextDispose (module->context);
8389 mono_llvm_free_domain_info (MonoDomain *domain)
8391 MonoJitDomainInfo *info = domain_jit_info (domain);
8392 MonoLLVMModule *module = (MonoLLVMModule*)info->llvm_module;
8398 if (module->llvm_types)
8399 g_hash_table_destroy (module->llvm_types);
8401 mono_llvm_dispose_ee (module->mono_ee);
8403 if (module->bb_names) {
8404 for (i = 0; i < module->bb_names_len; ++i)
8405 g_free (module->bb_names [i]);
8406 g_free (module->bb_names);
8408 //LLVMDisposeModule (module->module);
8412 info->llvm_module = NULL;
8416 mono_llvm_create_aot_module (MonoAssembly *assembly, const char *global_prefix, gboolean emit_dwarf, gboolean static_link, gboolean llvm_only)
8418 MonoLLVMModule *module = &aot_module;
8420 /* Delete previous module */
8421 if (module->plt_entries)
8422 g_hash_table_destroy (module->plt_entries);
8423 if (module->lmodule)
8424 LLVMDisposeModule (module->lmodule);
8426 memset (module, 0, sizeof (aot_module));
8428 module->lmodule = LLVMModuleCreateWithName ("aot");
8429 module->assembly = assembly;
8430 module->global_prefix = g_strdup (global_prefix);
8431 module->got_symbol = g_strdup_printf ("%s_llvm_got", global_prefix);
8432 module->eh_frame_symbol = g_strdup_printf ("%s_eh_frame", global_prefix);
8433 module->get_method_symbol = g_strdup_printf ("%s_get_method", global_prefix);
8434 module->get_unbox_tramp_symbol = g_strdup_printf ("%s_get_unbox_tramp", global_prefix);
8435 module->external_symbols = TRUE;
8436 module->emit_dwarf = emit_dwarf;
8437 module->static_link = static_link;
8438 module->llvm_only = llvm_only;
8439 /* The first few entries are reserved */
8440 module->max_got_offset = 16;
8441 module->context = LLVMGetGlobalContext ();
8444 /* clang ignores our debug info because it has an invalid version */
8445 module->emit_dwarf = FALSE;
8447 add_intrinsics (module->lmodule);
8450 #if LLVM_API_VERSION > 100
8451 if (module->emit_dwarf) {
8452 char *dir, *build_info, *s, *cu_name;
8454 module->di_builder = mono_llvm_create_di_builder (module->lmodule);
8457 dir = g_strdup (".");
8458 build_info = mono_get_runtime_build_info ();
8459 s = g_strdup_printf ("Mono AOT Compiler %s (LLVM)", build_info);
8460 cu_name = g_path_get_basename (assembly->image->name);
8461 module->cu = mono_llvm_di_create_compile_unit (module->di_builder, cu_name, dir, s);
8463 g_free (build_info);
8470 * We couldn't compute the type of the LLVM global representing the got because
8471 * its size is only known after all the methods have been emitted. So create
8472 * a dummy variable, and replace all uses it with the real got variable when
8473 * its size is known in mono_llvm_emit_aot_module ().
8476 LLVMTypeRef got_type = LLVMArrayType (module->ptr_type, 0);
8478 module->got_var = LLVMAddGlobal (module->lmodule, got_type, "mono_dummy_got");
8479 LLVMSetInitializer (module->got_var, LLVMConstNull (got_type));
8482 /* Add initialization array */
8484 LLVMTypeRef inited_type = LLVMArrayType (LLVMInt8Type (), 0);
8486 module->inited_var = LLVMAddGlobal (aot_module.lmodule, inited_type, "mono_inited_tmp");
8487 LLVMSetInitializer (module->inited_var, LLVMConstNull (inited_type));
8491 emit_init_icall_wrappers (module);
8493 emit_llvm_code_start (module);
8495 /* Add a dummy personality function */
8496 if (!use_debug_personality) {
8497 LLVMValueRef personality = LLVMAddFunction (module->lmodule, default_personality_name, LLVMFunctionType (LLVMInt32Type (), NULL, 0, TRUE));
8498 LLVMSetLinkage (personality, LLVMExternalLinkage);
8499 mark_as_used (module, personality);
8502 /* Add a reference to the c++ exception we throw/catch */
8504 LLVMTypeRef exc = LLVMPointerType (LLVMInt8Type (), 0);
8505 module->sentinel_exception = LLVMAddGlobal (module->lmodule, exc, "_ZTIPi");
8506 LLVMSetLinkage (module->sentinel_exception, LLVMExternalLinkage);
8507 mono_llvm_set_is_constant (module->sentinel_exception);
8510 module->llvm_types = g_hash_table_new (NULL, NULL);
8511 module->plt_entries = g_hash_table_new (g_str_hash, g_str_equal);
8512 module->plt_entries_ji = g_hash_table_new (NULL, NULL);
8513 module->direct_callables = g_hash_table_new (g_str_hash, g_str_equal);
8514 module->method_to_lmethod = g_hash_table_new (NULL, NULL);
8515 module->idx_to_lmethod = g_hash_table_new (NULL, NULL);
8516 module->idx_to_unbox_tramp = g_hash_table_new (NULL, NULL);
8517 module->method_to_callers = g_hash_table_new (NULL, NULL);
8521 llvm_array_from_uints (LLVMTypeRef el_type, guint32 *values, int nvalues)
8524 LLVMValueRef res, *vals;
8526 vals = g_new0 (LLVMValueRef, nvalues);
8527 for (i = 0; i < nvalues; ++i)
8528 vals [i] = LLVMConstInt (LLVMInt32Type (), values [i], FALSE);
8529 res = LLVMConstArray (LLVMInt32Type (), vals, nvalues);
8535 llvm_array_from_bytes (guint8 *values, int nvalues)
8538 LLVMValueRef res, *vals;
8540 vals = g_new0 (LLVMValueRef, nvalues);
8541 for (i = 0; i < nvalues; ++i)
8542 vals [i] = LLVMConstInt (LLVMInt8Type (), values [i], FALSE);
8543 res = LLVMConstArray (LLVMInt8Type (), vals, nvalues);
8548 * mono_llvm_emit_aot_file_info:
8550 * Emit the MonoAotFileInfo structure.
8551 * Same as emit_aot_file_info () in aot-compiler.c.
8554 mono_llvm_emit_aot_file_info (MonoAotFileInfo *info, gboolean has_jitted_code)
8556 MonoLLVMModule *module = &aot_module;
8558 /* Save these for later */
8559 memcpy (&module->aot_info, info, sizeof (MonoAotFileInfo));
8560 module->has_jitted_code = has_jitted_code;
8564 * mono_llvm_emit_aot_data:
8566 * Emit the binary data DATA pointed to by symbol SYMBOL.
8569 mono_llvm_emit_aot_data (const char *symbol, guint8 *data, int data_len)
8571 MonoLLVMModule *module = &aot_module;
8575 type = LLVMArrayType (LLVMInt8Type (), data_len);
8576 d = LLVMAddGlobal (module->lmodule, type, symbol);
8577 LLVMSetVisibility (d, LLVMHiddenVisibility);
8578 LLVMSetLinkage (d, LLVMInternalLinkage);
8579 LLVMSetInitializer (d, mono_llvm_create_constant_data_array (data, data_len));
8580 mono_llvm_set_is_constant (d);
8583 /* Add a reference to a global defined in JITted code */
8585 AddJitGlobal (MonoLLVMModule *module, LLVMTypeRef type, const char *name)
8590 s = g_strdup_printf ("%s%s", module->global_prefix, name);
8591 v = LLVMAddGlobal (module->lmodule, LLVMInt8Type (), s);
8597 emit_aot_file_info (MonoLLVMModule *module)
8599 LLVMTypeRef file_info_type;
8600 LLVMTypeRef *eltypes, eltype;
8601 LLVMValueRef info_var;
8602 LLVMValueRef *fields;
8603 int i, nfields, tindex;
8604 MonoAotFileInfo *info;
8605 LLVMModuleRef lmodule = module->lmodule;
8607 info = &module->aot_info;
8609 /* Create an LLVM type to represent MonoAotFileInfo */
8610 nfields = 2 + MONO_AOT_FILE_INFO_NUM_SYMBOLS + 16 + 5;
8611 eltypes = g_new (LLVMTypeRef, nfields);
8613 eltypes [tindex ++] = LLVMInt32Type ();
8614 eltypes [tindex ++] = LLVMInt32Type ();
8616 for (i = 0; i < MONO_AOT_FILE_INFO_NUM_SYMBOLS; ++i)
8617 eltypes [tindex ++] = LLVMPointerType (LLVMInt8Type (), 0);
8619 for (i = 0; i < 15; ++i)
8620 eltypes [tindex ++] = LLVMInt32Type ();
8622 eltypes [tindex ++] = LLVMArrayType (LLVMInt32Type (), MONO_AOT_TABLE_NUM);
8623 for (i = 0; i < 4; ++i)
8624 eltypes [tindex ++] = LLVMArrayType (LLVMInt32Type (), MONO_AOT_TRAMP_NUM);
8625 eltypes [tindex ++] = LLVMArrayType (LLVMInt8Type (), 16);
8626 g_assert (tindex == nfields);
8627 file_info_type = LLVMStructCreateNamed (module->context, "MonoAotFileInfo");
8628 LLVMStructSetBody (file_info_type, eltypes, nfields, FALSE);
8630 info_var = LLVMAddGlobal (lmodule, file_info_type, "mono_aot_file_info");
8631 if (module->static_link) {
8632 LLVMSetVisibility (info_var, LLVMHiddenVisibility);
8633 LLVMSetLinkage (info_var, LLVMInternalLinkage);
8635 fields = g_new (LLVMValueRef, nfields);
8637 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->version, FALSE);
8638 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->dummy, FALSE);
8642 * We use LLVMGetNamedGlobal () for symbol which are defined in LLVM code, and LLVMAddGlobal ()
8643 * for symbols defined in the .s file emitted by the aot compiler.
8645 eltype = eltypes [tindex];
8646 if (module->llvm_only)
8647 fields [tindex ++] = LLVMConstNull (eltype);
8649 fields [tindex ++] = AddJitGlobal (module, eltype, "jit_got");
8650 fields [tindex ++] = module->got_var;
8651 /* llc defines this directly */
8652 if (!module->llvm_only) {
8653 fields [tindex ++] = LLVMAddGlobal (lmodule, eltype, module->eh_frame_symbol);
8654 fields [tindex ++] = LLVMConstNull (eltype);
8655 fields [tindex ++] = LLVMConstNull (eltype);
8657 fields [tindex ++] = LLVMConstNull (eltype);
8658 fields [tindex ++] = module->get_method;
8659 fields [tindex ++] = module->get_unbox_tramp;
8661 if (module->has_jitted_code) {
8662 fields [tindex ++] = AddJitGlobal (module, eltype, "jit_code_start");
8663 fields [tindex ++] = AddJitGlobal (module, eltype, "jit_code_end");
8665 fields [tindex ++] = LLVMConstNull (eltype);
8666 fields [tindex ++] = LLVMConstNull (eltype);
8668 if (!module->llvm_only)
8669 fields [tindex ++] = AddJitGlobal (module, eltype, "method_addresses");
8671 fields [tindex ++] = LLVMConstNull (eltype);
8672 if (info->flags & MONO_AOT_FILE_FLAG_SEPARATE_DATA) {
8673 for (i = 0; i < MONO_AOT_TABLE_NUM; ++i)
8674 fields [tindex ++] = LLVMConstNull (eltype);
8676 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "blob");
8677 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "class_name_table");
8678 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "class_info_offsets");
8679 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "method_info_offsets");
8680 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "ex_info_offsets");
8681 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "extra_method_info_offsets");
8682 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "extra_method_table");
8683 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "got_info_offsets");
8684 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "llvm_got_info_offsets");
8685 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "image_table");
8687 /* Not needed (mem_end) */
8688 fields [tindex ++] = LLVMConstNull (eltype);
8689 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "assembly_guid");
8690 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "runtime_version");
8691 if (info->trampoline_size [0]) {
8692 fields [tindex ++] = AddJitGlobal (module, eltype, "specific_trampolines");
8693 fields [tindex ++] = AddJitGlobal (module, eltype, "static_rgctx_trampolines");
8694 fields [tindex ++] = AddJitGlobal (module, eltype, "imt_trampolines");
8695 fields [tindex ++] = AddJitGlobal (module, eltype, "gsharedvt_arg_trampolines");
8697 fields [tindex ++] = LLVMConstNull (eltype);
8698 fields [tindex ++] = LLVMConstNull (eltype);
8699 fields [tindex ++] = LLVMConstNull (eltype);
8700 fields [tindex ++] = LLVMConstNull (eltype);
8702 if (module->static_link && !module->llvm_only)
8703 fields [tindex ++] = AddJitGlobal (module, eltype, "globals");
8705 fields [tindex ++] = LLVMConstNull (eltype);
8706 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "assembly_name");
8707 if (!module->llvm_only) {
8708 fields [tindex ++] = AddJitGlobal (module, eltype, "plt");
8709 fields [tindex ++] = AddJitGlobal (module, eltype, "plt_end");
8710 fields [tindex ++] = AddJitGlobal (module, eltype, "unwind_info");
8711 fields [tindex ++] = AddJitGlobal (module, eltype, "unbox_trampolines");
8712 fields [tindex ++] = AddJitGlobal (module, eltype, "unbox_trampolines_end");
8713 fields [tindex ++] = AddJitGlobal (module, eltype, "unbox_trampoline_addresses");
8715 fields [tindex ++] = LLVMConstNull (eltype);
8716 fields [tindex ++] = LLVMConstNull (eltype);
8717 fields [tindex ++] = LLVMConstNull (eltype);
8718 fields [tindex ++] = LLVMConstNull (eltype);
8719 fields [tindex ++] = LLVMConstNull (eltype);
8720 fields [tindex ++] = LLVMConstNull (eltype);
8723 for (i = 0; i < MONO_AOT_FILE_INFO_NUM_SYMBOLS; ++i)
8724 fields [2 + i] = LLVMConstBitCast (fields [2 + i], eltype);
8727 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->plt_got_offset_base, FALSE);
8728 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->got_size, FALSE);
8729 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->plt_size, FALSE);
8730 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->nmethods, FALSE);
8731 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->flags, FALSE);
8732 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->opts, FALSE);
8733 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->simd_opts, FALSE);
8734 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->gc_name_index, FALSE);
8735 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->num_rgctx_fetch_trampolines, FALSE);
8736 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->double_align, FALSE);
8737 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->long_align, FALSE);
8738 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->generic_tramp_num, FALSE);
8739 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->tramp_page_size, FALSE);
8740 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->nshared_got_entries, FALSE);
8741 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->datafile_size, FALSE);
8743 fields [tindex ++] = llvm_array_from_uints (LLVMInt32Type (), info->table_offsets, MONO_AOT_TABLE_NUM);
8744 fields [tindex ++] = llvm_array_from_uints (LLVMInt32Type (), info->num_trampolines, MONO_AOT_TRAMP_NUM);
8745 fields [tindex ++] = llvm_array_from_uints (LLVMInt32Type (), info->trampoline_got_offset_base, MONO_AOT_TRAMP_NUM);
8746 fields [tindex ++] = llvm_array_from_uints (LLVMInt32Type (), info->trampoline_size, MONO_AOT_TRAMP_NUM);
8747 fields [tindex ++] = llvm_array_from_uints (LLVMInt32Type (), info->tramp_page_code_offsets, MONO_AOT_TRAMP_NUM);
8749 fields [tindex ++] = llvm_array_from_bytes (info->aotid, 16);
8750 g_assert (tindex == nfields);
8752 LLVMSetInitializer (info_var, LLVMConstNamedStruct (file_info_type, fields, nfields));
8754 if (module->static_link) {
8758 s = g_strdup_printf ("mono_aot_module_%s_info", module->assembly->aname.name);
8759 /* Get rid of characters which cannot occur in symbols */
8761 for (p = s; *p; ++p) {
8762 if (!(isalnum (*p) || *p == '_'))
8765 var = LLVMAddGlobal (module->lmodule, LLVMPointerType (LLVMInt8Type (), 0), s);
8767 LLVMSetInitializer (var, LLVMConstBitCast (LLVMGetNamedGlobal (module->lmodule, "mono_aot_file_info"), LLVMPointerType (LLVMInt8Type (), 0)));
8768 LLVMSetLinkage (var, LLVMExternalLinkage);
8773 * Emit the aot module into the LLVM bitcode file FILENAME.
8776 mono_llvm_emit_aot_module (const char *filename, const char *cu_name)
8778 LLVMTypeRef got_type, inited_type;
8779 LLVMValueRef real_got, real_inited;
8780 MonoLLVMModule *module = &aot_module;
8782 emit_llvm_code_end (module);
8785 * Create the real got variable and replace all uses of the dummy variable with
8788 got_type = LLVMArrayType (module->ptr_type, module->max_got_offset + 1);
8789 real_got = LLVMAddGlobal (module->lmodule, got_type, module->got_symbol);
8790 LLVMSetInitializer (real_got, LLVMConstNull (got_type));
8791 if (module->external_symbols) {
8792 LLVMSetLinkage (real_got, LLVMExternalLinkage);
8793 LLVMSetVisibility (real_got, LLVMHiddenVisibility);
8795 LLVMSetLinkage (real_got, LLVMInternalLinkage);
8797 mono_llvm_replace_uses_of (module->got_var, real_got);
8799 mark_as_used (&aot_module, real_got);
8801 /* Delete the dummy got so it doesn't become a global */
8802 LLVMDeleteGlobal (module->got_var);
8803 module->got_var = real_got;
8806 * Same for the init_var
8808 if (module->llvm_only) {
8809 inited_type = LLVMArrayType (LLVMInt8Type (), module->max_inited_idx + 1);
8810 real_inited = LLVMAddGlobal (module->lmodule, inited_type, "mono_inited");
8811 LLVMSetInitializer (real_inited, LLVMConstNull (inited_type));
8812 LLVMSetLinkage (real_inited, LLVMInternalLinkage);
8813 mono_llvm_replace_uses_of (module->inited_var, real_inited);
8814 LLVMDeleteGlobal (module->inited_var);
8817 if (module->llvm_only) {
8818 emit_get_method (&aot_module);
8819 emit_get_unbox_tramp (&aot_module);
8822 emit_llvm_used (&aot_module);
8823 emit_dbg_info (&aot_module, filename, cu_name);
8824 emit_aot_file_info (&aot_module);
8827 * Replace GOT entries for directly callable methods with the methods themselves.
8828 * It would be easier to implement this by predefining all methods before compiling
8829 * their bodies, but that couldn't handle the case when a method fails to compile
8832 if (module->llvm_only) {
8833 GHashTableIter iter;
8835 GSList *callers, *l;
8837 g_hash_table_iter_init (&iter, module->method_to_callers);
8838 while (g_hash_table_iter_next (&iter, (void**)&method, (void**)&callers)) {
8839 LLVMValueRef lmethod;
8841 if (method->iflags & METHOD_IMPL_ATTRIBUTE_SYNCHRONIZED)
8844 lmethod = (LLVMValueRef)g_hash_table_lookup (module->method_to_lmethod, method);
8846 for (l = callers; l; l = l->next) {
8847 LLVMValueRef caller = (LLVMValueRef)l->data;
8849 mono_llvm_replace_uses_of (caller, lmethod);
8855 /* Replace PLT entries for directly callable methods with the methods themselves */
8857 GHashTableIter iter;
8859 LLVMValueRef callee;
8861 g_hash_table_iter_init (&iter, module->plt_entries_ji);
8862 while (g_hash_table_iter_next (&iter, (void**)&ji, (void**)&callee)) {
8863 if (mono_aot_is_direct_callable (ji)) {
8864 LLVMValueRef lmethod;
8866 lmethod = (LLVMValueRef)g_hash_table_lookup (module->method_to_lmethod, ji->data.method);
8867 /* The types might not match because the caller might pass an rgctx */
8868 if (lmethod && LLVMTypeOf (callee) == LLVMTypeOf (lmethod)) {
8869 mono_llvm_replace_uses_of (callee, lmethod);
8870 mono_aot_mark_unused_llvm_plt_entry (ji);
8880 if (LLVMVerifyModule (module->lmodule, LLVMReturnStatusAction, &verifier_err)) {
8881 printf ("%s\n", verifier_err);
8882 g_assert_not_reached ();
8887 LLVMWriteBitcodeToFile (module->lmodule, filename);
8892 md_string (const char *s)
8894 return LLVMMDString (s, strlen (s));
8897 /* Debugging support */
8900 emit_dbg_info (MonoLLVMModule *module, const char *filename, const char *cu_name)
8902 LLVMModuleRef lmodule = module->lmodule;
8903 LLVMValueRef args [16], ver;
8906 * This can only be enabled when LLVM code is emitted into a separate object
8907 * file, since the AOT compiler also emits dwarf info,
8908 * and the abbrev indexes will not be correct since llvm has added its own
8911 if (!module->emit_dwarf)
8914 #if LLVM_API_VERSION > 100
8915 mono_llvm_di_builder_finalize (module->di_builder);
8917 LLVMValueRef cu_args [16], cu;
8919 char *build_info, *s, *dir;
8922 * Emit dwarf info in the form of LLVM metadata. There is some
8923 * out-of-date documentation at:
8924 * http://llvm.org/docs/SourceLevelDebugging.html
8925 * but most of this was gathered from the llvm and
8930 cu_args [n_cuargs ++] = LLVMConstInt (LLVMInt32Type (), DW_TAG_compile_unit, FALSE);
8931 /* CU name/compilation dir */
8932 dir = g_path_get_dirname (filename);
8933 args [0] = LLVMMDString (cu_name, strlen (cu_name));
8934 args [1] = LLVMMDString (dir, strlen (dir));
8935 cu_args [n_cuargs ++] = LLVMMDNode (args, 2);
8938 cu_args [n_cuargs ++] = LLVMConstInt (LLVMInt32Type (), DW_LANG_C99, FALSE);
8940 build_info = mono_get_runtime_build_info ();
8941 s = g_strdup_printf ("Mono AOT Compiler %s (LLVM)", build_info);
8942 cu_args [n_cuargs ++] = LLVMMDString (s, strlen (s));
8943 g_free (build_info);
8945 cu_args [n_cuargs ++] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
8947 cu_args [n_cuargs ++] = LLVMMDString ("", strlen (""));
8948 /* Runtime version */
8949 cu_args [n_cuargs ++] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
8951 cu_args [n_cuargs ++] = LLVMMDNode (args, 0);
8952 cu_args [n_cuargs ++] = LLVMMDNode (args, 0);
8954 if (module->subprogram_mds) {
8958 mds = g_new0 (LLVMValueRef, module->subprogram_mds->len);
8959 for (i = 0; i < module->subprogram_mds->len; ++i)
8960 mds [i] = (LLVMValueRef)g_ptr_array_index (module->subprogram_mds, i);
8961 cu_args [n_cuargs ++] = LLVMMDNode (mds, module->subprogram_mds->len);
8963 cu_args [n_cuargs ++] = LLVMMDNode (args, 0);
8966 cu_args [n_cuargs ++] = LLVMMDNode (args, 0);
8967 /* Imported modules */
8968 cu_args [n_cuargs ++] = LLVMMDNode (args, 0);
8970 cu_args [n_cuargs ++] = LLVMMDString ("", strlen (""));
8971 /* DebugEmissionKind = FullDebug */
8972 cu_args [n_cuargs ++] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
8973 cu = LLVMMDNode (cu_args, n_cuargs);
8974 LLVMAddNamedMetadataOperand (lmodule, "llvm.dbg.cu", cu);
8977 #if LLVM_API_VERSION > 100
8978 args [0] = LLVMConstInt (LLVMInt32Type (), 2, FALSE);
8979 args [1] = LLVMMDString ("Dwarf Version", strlen ("Dwarf Version"));
8980 args [2] = LLVMConstInt (LLVMInt32Type (), 2, FALSE);
8981 ver = LLVMMDNode (args, 3);
8982 LLVMAddNamedMetadataOperand (lmodule, "llvm.module.flags", ver);
8984 args [0] = LLVMConstInt (LLVMInt32Type (), 2, FALSE);
8985 args [1] = LLVMMDString ("Debug Info Version", strlen ("Debug Info Version"));
8986 args [2] = LLVMConstInt (LLVMInt64Type (), 3, FALSE);
8987 ver = LLVMMDNode (args, 3);
8988 LLVMAddNamedMetadataOperand (lmodule, "llvm.module.flags", ver);
8990 args [0] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
8991 args [1] = LLVMMDString ("Dwarf Version", strlen ("Dwarf Version"));
8992 args [2] = LLVMConstInt (LLVMInt32Type (), 2, FALSE);
8993 ver = LLVMMDNode (args, 3);
8994 LLVMAddNamedMetadataOperand (lmodule, "llvm.module.flags", ver);
8996 args [0] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
8997 args [1] = LLVMMDString ("Debug Info Version", strlen ("Debug Info Version"));
8998 args [2] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
8999 ver = LLVMMDNode (args, 3);
9000 LLVMAddNamedMetadataOperand (lmodule, "llvm.module.flags", ver);
9005 emit_dbg_subprogram (EmitContext *ctx, MonoCompile *cfg, LLVMValueRef method, const char *name)
9007 MonoLLVMModule *module = ctx->module;
9008 MonoDebugMethodInfo *minfo = ctx->minfo;
9009 char *source_file, *dir, *filename;
9010 LLVMValueRef md, args [16], ctx_args [16], md_args [64], type_args [16], ctx_md, type_md;
9011 MonoSymSeqPoint *sym_seq_points;
9017 mono_debug_symfile_get_seq_points (minfo, &source_file, NULL, NULL, &sym_seq_points, &n_seq_points);
9019 source_file = g_strdup ("<unknown>");
9020 dir = g_path_get_dirname (source_file);
9021 filename = g_path_get_basename (source_file);
9023 #if LLVM_API_VERSION > 100
9024 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);
9027 ctx_args [0] = LLVMConstInt (LLVMInt32Type (), 0x29, FALSE);
9028 args [0] = md_string (filename);
9029 args [1] = md_string (dir);
9030 ctx_args [1] = LLVMMDNode (args, 2);
9031 ctx_md = LLVMMDNode (ctx_args, 2);
9033 type_args [0] = LLVMConstInt (LLVMInt32Type (), DW_TAG_subroutine_type, FALSE);
9034 type_args [1] = NULL;
9035 type_args [2] = NULL;
9036 type_args [3] = LLVMMDString ("", 0);
9037 type_args [4] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
9038 type_args [5] = LLVMConstInt (LLVMInt64Type (), 0, FALSE);
9039 type_args [6] = LLVMConstInt (LLVMInt64Type (), 0, FALSE);
9040 type_args [7] = LLVMConstInt (LLVMInt64Type (), 0, FALSE);
9041 type_args [8] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
9042 type_args [9] = NULL;
9043 type_args [10] = NULL;
9044 type_args [11] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
9045 type_args [12] = NULL;
9046 type_args [13] = NULL;
9047 type_args [14] = NULL;
9048 type_md = LLVMMDNode (type_args, 14);
9050 /* http://llvm.org/docs/SourceLevelDebugging.html#subprogram-descriptors */
9051 md_args [0] = LLVMConstInt (LLVMInt32Type (), DW_TAG_subprogram, FALSE);
9052 /* Source directory + file pair */
9053 args [0] = md_string (filename);
9054 args [1] = md_string (dir);
9055 md_args [1] = LLVMMDNode (args ,2);
9056 md_args [2] = ctx_md;
9057 md_args [3] = md_string (cfg->method->name);
9058 md_args [4] = md_string (name);
9059 md_args [5] = md_string (name);
9062 md_args [6] = LLVMConstInt (LLVMInt32Type (), sym_seq_points [0].line, FALSE);
9064 md_args [6] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
9066 md_args [7] = type_md;
9068 md_args [8] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
9070 md_args [9] = LLVMConstInt (LLVMInt1Type (), 1, FALSE);
9072 md_args [10] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
9073 /* Index into a virtual function */
9074 md_args [11] = NULL;
9075 md_args [12] = NULL;
9077 md_args [13] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
9079 md_args [14] = LLVMConstInt (LLVMInt1Type (), 1, FALSE);
9080 /* Pointer to LLVM function */
9081 md_args [15] = method;
9082 /* Function template parameter */
9083 md_args [16] = NULL;
9084 /* Function declaration descriptor */
9085 md_args [17] = NULL;
9086 /* List of function variables */
9087 md_args [18] = LLVMMDNode (args, 0);
9089 md_args [19] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
9090 md = LLVMMDNode (md_args, 20);
9092 if (!module->subprogram_mds)
9093 module->subprogram_mds = g_ptr_array_new ();
9094 g_ptr_array_add (module->subprogram_mds, md);
9098 g_free (source_file);
9099 g_free (sym_seq_points);
9105 emit_dbg_loc (EmitContext *ctx, LLVMBuilderRef builder, const unsigned char *cil_code)
9107 MonoCompile *cfg = ctx->cfg;
9109 if (ctx->minfo && cil_code && cil_code >= cfg->header->code && cil_code < cfg->header->code + cfg->header->code_size) {
9110 MonoDebugSourceLocation *loc;
9111 LLVMValueRef loc_md;
9113 loc = mono_debug_symfile_lookup_location (ctx->minfo, cil_code - cfg->header->code);
9116 #if LLVM_API_VERSION > 100
9117 loc_md = mono_llvm_di_create_location (ctx->module->di_builder, ctx->dbg_md, loc->row, loc->column);
9118 mono_llvm_di_set_location (builder, loc_md);
9120 LLVMValueRef md_args [16];
9124 md_args [nmd_args ++] = LLVMConstInt (LLVMInt32Type (), loc->row, FALSE);
9125 md_args [nmd_args ++] = LLVMConstInt (LLVMInt32Type (), loc->column, FALSE);
9126 md_args [nmd_args ++] = ctx->dbg_md;
9127 md_args [nmd_args ++] = NULL;
9128 loc_md = LLVMMDNode (md_args, nmd_args);
9129 LLVMSetCurrentDebugLocation (builder, loc_md);
9131 mono_debug_symfile_free_location (loc);
9137 default_mono_llvm_unhandled_exception (void)
9139 MonoJitTlsData *jit_tls = mono_get_jit_tls ();
9140 MonoObject *target = mono_gchandle_get_target (jit_tls->thrown_exc);
9142 mono_unhandled_exception (target);
9143 mono_invoke_unhandled_exception_hook (target);
9144 g_assert_not_reached ();
9149 - Emit LLVM IR from the mono IR using the LLVM C API.
9150 - The original arch specific code remains, so we can fall back to it if we run
9151 into something we can't handle.
9155 A partial list of issues:
9156 - Handling of opcodes which can throw exceptions.
9158 In the mono JIT, these are implemented using code like this:
9165 push throw_pos - method
9166 call <exception trampoline>
9168 The problematic part is push throw_pos - method, which cannot be represented
9169 in the LLVM IR, since it does not support label values.
9170 -> this can be implemented in AOT mode using inline asm + labels, but cannot
9171 be implemented in JIT mode ?
9172 -> a possible but slower implementation would use the normal exception
9173 throwing code but it would need to control the placement of the throw code
9174 (it needs to be exactly after the compare+branch).
9175 -> perhaps add a PC offset intrinsics ?
9177 - efficient implementation of .ovf opcodes.
9179 These are currently implemented as:
9180 <ins which sets the condition codes>
9183 Some overflow opcodes are now supported by LLVM SVN.
9185 - exception handling, unwinding.
9186 - SSA is disabled for methods with exception handlers
9187 - How to obtain unwind info for LLVM compiled methods ?
9188 -> this is now solved by converting the unwind info generated by LLVM
9190 - LLVM uses the c++ exception handling framework, while we use our home grown
9191 code, and couldn't use the c++ one:
9192 - its not supported under VC++, other exotic platforms.
9193 - it might be impossible to support filter clauses with it.
9197 The trampolines need a predictable call sequence, since they need to disasm
9198 the calling code to obtain register numbers / offsets.
9200 LLVM currently generates this code in non-JIT mode:
9201 mov -0x98(%rax),%eax
9203 Here, the vtable pointer is lost.
9204 -> solution: use one vtable trampoline per class.
9206 - passing/receiving the IMT pointer/RGCTX.
9207 -> solution: pass them as normal arguments ?
9211 LLVM does not allow the specification of argument registers etc. This means
9212 that all calls are made according to the platform ABI.
9214 - passing/receiving vtypes.
9216 Vtypes passed/received in registers are handled by the front end by using
9217 a signature with scalar arguments, and loading the parts of the vtype into those
9220 Vtypes passed on the stack are handled using the 'byval' attribute.
9224 Supported though alloca, we need to emit the load/store code.
9228 The mono JIT uses pointer sized iregs/double fregs, while LLVM uses precisely
9229 typed registers, so we have to keep track of the precise LLVM type of each vreg.
9230 This is made easier because the IR is already in SSA form.
9231 An additional problem is that our IR is not consistent with types, i.e. i32/ia64
9232 types are frequently used incorrectly.
9237 Emit LLVM bytecode into a .bc file, compile it using llc into a .s file, then link
9238 it with the file containing the methods emitted by the JIT and the AOT data
9242 /* FIXME: Normalize some aspects of the mono IR to allow easier translation, like:
9243 * - each bblock should end with a branch
9244 * - setting the return value, making cfg->ret non-volatile
9245 * - avoid some transformations in the JIT which make it harder for us to generate
9247 * - use pointer types to help optimizations.
9250 #else /* DISABLE_JIT */
9253 mono_llvm_cleanup (void)
9258 mono_llvm_free_domain_info (MonoDomain *domain)
9263 mono_llvm_init (void)
9268 default_mono_llvm_unhandled_exception (void)
9272 #endif /* DISABLE_JIT */