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
438 eltypes = g_new (LLVMTypeRef, size);
439 for (i = 0; i < size; ++i)
440 eltypes [i] = esize == 4 ? LLVMFloatType () : LLVMDoubleType ();
442 size = get_vtype_size (t);
444 eltypes = g_new (LLVMTypeRef, size);
445 for (i = 0; i < size; ++i)
446 eltypes [i] = LLVMInt8Type ();
449 name = mono_type_full_name (&klass->byval_arg);
450 ltype = LLVMStructCreateNamed (module->context, name);
451 LLVMStructSetBody (ltype, eltypes, size, FALSE);
461 * Return the LLVM type corresponding to T.
464 type_to_llvm_type (EmitContext *ctx, MonoType *t)
466 t = mini_get_underlying_type (t);
470 return LLVMVoidType ();
472 return LLVMInt8Type ();
474 return LLVMInt16Type ();
476 return LLVMInt32Type ();
478 return LLVMInt8Type ();
480 return LLVMInt16Type ();
482 return LLVMInt32Type ();
483 case MONO_TYPE_BOOLEAN:
484 return LLVMInt8Type ();
487 return LLVMInt64Type ();
489 return LLVMInt16Type ();
491 return LLVMFloatType ();
493 return LLVMDoubleType ();
496 return IntPtrType ();
497 case MONO_TYPE_OBJECT:
498 case MONO_TYPE_CLASS:
499 case MONO_TYPE_ARRAY:
500 case MONO_TYPE_SZARRAY:
501 case MONO_TYPE_STRING:
503 return ObjRefType ();
506 /* Because of generic sharing */
507 return ObjRefType ();
508 case MONO_TYPE_GENERICINST:
509 if (!mono_type_generic_inst_is_valuetype (t))
510 return ObjRefType ();
512 case MONO_TYPE_VALUETYPE:
513 case MONO_TYPE_TYPEDBYREF: {
517 klass = mono_class_from_mono_type (t);
519 if (MONO_CLASS_IS_SIMD (ctx->cfg, klass))
520 return simd_class_to_llvm_type (ctx, klass);
523 return type_to_llvm_type (ctx, mono_class_enum_basetype (klass));
525 ltype = (LLVMTypeRef)g_hash_table_lookup (ctx->module->llvm_types, klass);
527 ltype = create_llvm_type_for_type (ctx->module, klass);
528 g_hash_table_insert (ctx->module->llvm_types, klass, ltype);
534 printf ("X: %d\n", t->type);
535 ctx->cfg->exception_message = g_strdup_printf ("type %s", mono_type_full_name (t));
536 ctx->cfg->disable_llvm = TRUE;
544 * Return whenever T is an unsigned int type.
547 type_is_unsigned (EmitContext *ctx, MonoType *t)
549 t = mini_get_underlying_type (t);
565 * type_to_llvm_arg_type:
567 * Same as type_to_llvm_type, but treat i8/i16 as i32.
570 type_to_llvm_arg_type (EmitContext *ctx, MonoType *t)
572 LLVMTypeRef ptype = type_to_llvm_type (ctx, t);
574 if (ctx->cfg->llvm_only)
578 * This works on all abis except arm64/ios which passes multiple
579 * arguments in one stack slot.
582 if (ptype == LLVMInt8Type () || ptype == LLVMInt16Type ()) {
584 * LLVM generates code which only sets the lower bits, while JITted
585 * code expects all the bits to be set.
587 ptype = LLVMInt32Type ();
595 * llvm_type_to_stack_type:
597 * Return the LLVM type which needs to be used when a value of type TYPE is pushed
600 static G_GNUC_UNUSED LLVMTypeRef
601 llvm_type_to_stack_type (MonoCompile *cfg, LLVMTypeRef type)
605 if (type == LLVMInt8Type ())
606 return LLVMInt32Type ();
607 else if (type == LLVMInt16Type ())
608 return LLVMInt32Type ();
609 else if (!cfg->r4fp && type == LLVMFloatType ())
610 return LLVMDoubleType ();
616 * regtype_to_llvm_type:
618 * Return the LLVM type corresponding to the regtype C used in instruction
622 regtype_to_llvm_type (char c)
626 return LLVMInt32Type ();
628 return LLVMInt64Type ();
630 return LLVMDoubleType ();
639 * Return the LLVM type corresponding to the unary/binary opcode OPCODE.
642 op_to_llvm_type (int opcode)
647 return LLVMInt8Type ();
650 return LLVMInt8Type ();
653 return LLVMInt16Type ();
656 return LLVMInt16Type ();
659 return LLVMInt32Type ();
662 return LLVMInt32Type ();
664 return LLVMInt64Type ();
666 return LLVMFloatType ();
668 return LLVMDoubleType ();
670 return LLVMInt64Type ();
672 return LLVMInt32Type ();
674 return LLVMInt64Type ();
679 return LLVMInt8Type ();
684 return LLVMInt16Type ();
686 return LLVMInt32Type ();
689 return sizeof (gpointer) == 8 ? LLVMInt64Type () : LLVMInt32Type ();
696 return LLVMInt32Type ();
703 return LLVMInt64Type ();
705 printf ("%s\n", mono_inst_name (opcode));
706 g_assert_not_reached ();
711 #define CLAUSE_START(clause) ((clause)->try_offset)
712 #define CLAUSE_END(clause) (((clause))->try_offset + ((clause))->try_len)
715 * load_store_to_llvm_type:
717 * Return the size/sign/zero extension corresponding to the load/store opcode
721 load_store_to_llvm_type (int opcode, int *size, gboolean *sext, gboolean *zext)
727 case OP_LOADI1_MEMBASE:
728 case OP_STOREI1_MEMBASE_REG:
729 case OP_STOREI1_MEMBASE_IMM:
730 case OP_ATOMIC_LOAD_I1:
731 case OP_ATOMIC_STORE_I1:
734 return LLVMInt8Type ();
735 case OP_LOADU1_MEMBASE:
737 case OP_ATOMIC_LOAD_U1:
738 case OP_ATOMIC_STORE_U1:
741 return LLVMInt8Type ();
742 case OP_LOADI2_MEMBASE:
743 case OP_STOREI2_MEMBASE_REG:
744 case OP_STOREI2_MEMBASE_IMM:
745 case OP_ATOMIC_LOAD_I2:
746 case OP_ATOMIC_STORE_I2:
749 return LLVMInt16Type ();
750 case OP_LOADU2_MEMBASE:
752 case OP_ATOMIC_LOAD_U2:
753 case OP_ATOMIC_STORE_U2:
756 return LLVMInt16Type ();
757 case OP_LOADI4_MEMBASE:
758 case OP_LOADU4_MEMBASE:
761 case OP_STOREI4_MEMBASE_REG:
762 case OP_STOREI4_MEMBASE_IMM:
763 case OP_ATOMIC_LOAD_I4:
764 case OP_ATOMIC_STORE_I4:
765 case OP_ATOMIC_LOAD_U4:
766 case OP_ATOMIC_STORE_U4:
768 return LLVMInt32Type ();
769 case OP_LOADI8_MEMBASE:
771 case OP_STOREI8_MEMBASE_REG:
772 case OP_STOREI8_MEMBASE_IMM:
773 case OP_ATOMIC_LOAD_I8:
774 case OP_ATOMIC_STORE_I8:
775 case OP_ATOMIC_LOAD_U8:
776 case OP_ATOMIC_STORE_U8:
778 return LLVMInt64Type ();
779 case OP_LOADR4_MEMBASE:
780 case OP_STORER4_MEMBASE_REG:
781 case OP_ATOMIC_LOAD_R4:
782 case OP_ATOMIC_STORE_R4:
784 return LLVMFloatType ();
785 case OP_LOADR8_MEMBASE:
786 case OP_STORER8_MEMBASE_REG:
787 case OP_ATOMIC_LOAD_R8:
788 case OP_ATOMIC_STORE_R8:
790 return LLVMDoubleType ();
791 case OP_LOAD_MEMBASE:
793 case OP_STORE_MEMBASE_REG:
794 case OP_STORE_MEMBASE_IMM:
795 *size = sizeof (gpointer);
796 return IntPtrType ();
798 g_assert_not_reached ();
806 * Return the LLVM intrinsics corresponding to the overflow opcode OPCODE.
809 ovf_op_to_intrins (int opcode)
813 return "llvm.sadd.with.overflow.i32";
815 return "llvm.uadd.with.overflow.i32";
817 return "llvm.ssub.with.overflow.i32";
819 return "llvm.usub.with.overflow.i32";
821 return "llvm.smul.with.overflow.i32";
823 return "llvm.umul.with.overflow.i32";
825 return "llvm.sadd.with.overflow.i64";
827 return "llvm.uadd.with.overflow.i64";
829 return "llvm.ssub.with.overflow.i64";
831 return "llvm.usub.with.overflow.i64";
833 return "llvm.smul.with.overflow.i64";
835 return "llvm.umul.with.overflow.i64";
837 g_assert_not_reached ();
843 simd_op_to_intrins (int opcode)
846 #if defined(TARGET_X86) || defined(TARGET_AMD64)
848 return "llvm.x86.sse2.min.pd";
850 return "llvm.x86.sse.min.ps";
852 return "llvm.x86.sse2.max.pd";
854 return "llvm.x86.sse.max.ps";
856 return "llvm.x86.sse3.hadd.pd";
858 return "llvm.x86.sse3.hadd.ps";
860 return "llvm.x86.sse3.hsub.pd";
862 return "llvm.x86.sse3.hsub.ps";
864 return "llvm.x86.sse3.addsub.ps";
866 return "llvm.x86.sse3.addsub.pd";
867 case OP_EXTRACT_MASK:
868 return "llvm.x86.sse2.pmovmskb.128";
871 return "llvm.x86.sse2.psrli.w";
874 return "llvm.x86.sse2.psrli.d";
877 return "llvm.x86.sse2.psrli.q";
880 return "llvm.x86.sse2.pslli.w";
883 return "llvm.x86.sse2.pslli.d";
886 return "llvm.x86.sse2.pslli.q";
889 return "llvm.x86.sse2.psrai.w";
892 return "llvm.x86.sse2.psrai.d";
894 return "llvm.x86.sse2.padds.b";
896 return "llvm.x86.sse2.padds.w";
898 return "llvm.x86.sse2.psubs.b";
900 return "llvm.x86.sse2.psubs.w";
901 case OP_PADDB_SAT_UN:
902 return "llvm.x86.sse2.paddus.b";
903 case OP_PADDW_SAT_UN:
904 return "llvm.x86.sse2.paddus.w";
905 case OP_PSUBB_SAT_UN:
906 return "llvm.x86.sse2.psubus.b";
907 case OP_PSUBW_SAT_UN:
908 return "llvm.x86.sse2.psubus.w";
910 return "llvm.x86.sse2.pavg.b";
912 return "llvm.x86.sse2.pavg.w";
914 return "llvm.x86.sse.sqrt.ps";
916 return "llvm.x86.sse2.sqrt.pd";
918 return "llvm.x86.sse.rsqrt.ps";
920 return "llvm.x86.sse.rcp.ps";
922 return "llvm.x86.sse2.cvtdq2pd";
924 return "llvm.x86.sse2.cvtdq2ps";
926 return "llvm.x86.sse2.cvtpd2dq";
928 return "llvm.x86.sse2.cvtps2dq";
930 return "llvm.x86.sse2.cvtpd2ps";
932 return "llvm.x86.sse2.cvtps2pd";
934 return "llvm.x86.sse2.cvttpd2dq";
936 return "llvm.x86.sse2.cvttps2dq";
938 return "llvm.x86.sse2.packsswb.128";
940 return "llvm.x86.sse2.packssdw.128";
942 return "llvm.x86.sse2.packuswb.128";
944 return "llvm.x86.sse41.packusdw";
946 return "llvm.x86.sse2.pmulh.w";
947 case OP_PMULW_HIGH_UN:
948 return "llvm.x86.sse2.pmulhu.w";
950 return "llvm.x86.sse41.dpps";
953 g_assert_not_reached ();
959 simd_op_to_llvm_type (int opcode)
961 #if defined(TARGET_X86) || defined(TARGET_AMD64)
965 return type_to_simd_type (MONO_TYPE_R8);
968 return type_to_simd_type (MONO_TYPE_I8);
971 return type_to_simd_type (MONO_TYPE_I4);
976 return type_to_simd_type (MONO_TYPE_I2);
980 return type_to_simd_type (MONO_TYPE_I1);
982 return type_to_simd_type (MONO_TYPE_R4);
985 return type_to_simd_type (MONO_TYPE_I4);
989 return type_to_simd_type (MONO_TYPE_R8);
993 return type_to_simd_type (MONO_TYPE_R4);
994 case OP_EXTRACT_MASK:
995 return type_to_simd_type (MONO_TYPE_I1);
1001 return type_to_simd_type (MONO_TYPE_R4);
1004 return type_to_simd_type (MONO_TYPE_R8);
1006 g_assert_not_reached ();
1017 * Return the LLVM basic block corresponding to BB.
1019 static LLVMBasicBlockRef
1020 get_bb (EmitContext *ctx, MonoBasicBlock *bb)
1022 char bb_name_buf [128];
1025 if (ctx->bblocks [bb->block_num].bblock == NULL) {
1026 if (bb->flags & BB_EXCEPTION_HANDLER) {
1027 int clause_index = (mono_get_block_region_notry (ctx->cfg, bb->region) >> 8) - 1;
1028 sprintf (bb_name_buf, "EH_CLAUSE%d_BB%d", clause_index, bb->block_num);
1029 bb_name = bb_name_buf;
1030 } else if (bb->block_num < 256) {
1031 if (!ctx->module->bb_names) {
1032 ctx->module->bb_names_len = 256;
1033 ctx->module->bb_names = g_new0 (char*, ctx->module->bb_names_len);
1035 if (!ctx->module->bb_names [bb->block_num]) {
1038 n = g_strdup_printf ("BB%d", bb->block_num);
1039 mono_memory_barrier ();
1040 ctx->module->bb_names [bb->block_num] = n;
1042 bb_name = ctx->module->bb_names [bb->block_num];
1044 sprintf (bb_name_buf, "BB%d", bb->block_num);
1045 bb_name = bb_name_buf;
1048 ctx->bblocks [bb->block_num].bblock = LLVMAppendBasicBlock (ctx->lmethod, bb_name);
1049 ctx->bblocks [bb->block_num].end_bblock = ctx->bblocks [bb->block_num].bblock;
1052 return ctx->bblocks [bb->block_num].bblock;
1058 * Return the last LLVM bblock corresponding to BB.
1059 * This might not be equal to the bb returned by get_bb () since we need to generate
1060 * multiple LLVM bblocks for a mono bblock to handle throwing exceptions.
1062 static LLVMBasicBlockRef
1063 get_end_bb (EmitContext *ctx, MonoBasicBlock *bb)
1066 return ctx->bblocks [bb->block_num].end_bblock;
1069 static LLVMBasicBlockRef
1070 gen_bb (EmitContext *ctx, const char *prefix)
1074 sprintf (bb_name, "%s%d", prefix, ++ ctx->ex_index);
1075 return LLVMAppendBasicBlock (ctx->lmethod, bb_name);
1081 * Return the target of the patch identified by TYPE and TARGET.
1084 resolve_patch (MonoCompile *cfg, MonoJumpInfoType type, gconstpointer target)
1090 memset (&ji, 0, sizeof (ji));
1092 ji.data.target = target;
1094 res = mono_resolve_patch_target (cfg->method, cfg->domain, NULL, &ji, FALSE, &error);
1095 mono_error_assert_ok (&error);
1103 * Emit code to convert the LLVM value V to DTYPE.
1106 convert_full (EmitContext *ctx, LLVMValueRef v, LLVMTypeRef dtype, gboolean is_unsigned)
1108 LLVMTypeRef stype = LLVMTypeOf (v);
1110 if (stype != dtype) {
1111 gboolean ext = FALSE;
1114 if (dtype == LLVMInt64Type () && (stype == LLVMInt32Type () || stype == LLVMInt16Type () || stype == LLVMInt8Type ()))
1116 else if (dtype == LLVMInt32Type () && (stype == LLVMInt16Type () || stype == LLVMInt8Type ()))
1118 else if (dtype == LLVMInt16Type () && (stype == LLVMInt8Type ()))
1122 return is_unsigned ? LLVMBuildZExt (ctx->builder, v, dtype, "") : LLVMBuildSExt (ctx->builder, v, dtype, "");
1124 if (dtype == LLVMDoubleType () && stype == LLVMFloatType ())
1125 return LLVMBuildFPExt (ctx->builder, v, dtype, "");
1128 if (stype == LLVMInt64Type () && (dtype == LLVMInt32Type () || dtype == LLVMInt16Type () || dtype == LLVMInt8Type ()))
1129 return LLVMBuildTrunc (ctx->builder, v, dtype, "");
1130 if (stype == LLVMInt32Type () && (dtype == LLVMInt16Type () || dtype == LLVMInt8Type ()))
1131 return LLVMBuildTrunc (ctx->builder, v, dtype, "");
1132 if (stype == LLVMInt16Type () && dtype == LLVMInt8Type ())
1133 return LLVMBuildTrunc (ctx->builder, v, dtype, "");
1134 if (stype == LLVMDoubleType () && dtype == LLVMFloatType ())
1135 return LLVMBuildFPTrunc (ctx->builder, v, dtype, "");
1137 if (LLVMGetTypeKind (stype) == LLVMPointerTypeKind && LLVMGetTypeKind (dtype) == LLVMPointerTypeKind)
1138 return LLVMBuildBitCast (ctx->builder, v, dtype, "");
1139 if (LLVMGetTypeKind (dtype) == LLVMPointerTypeKind)
1140 return LLVMBuildIntToPtr (ctx->builder, v, dtype, "");
1141 if (LLVMGetTypeKind (stype) == LLVMPointerTypeKind)
1142 return LLVMBuildPtrToInt (ctx->builder, v, dtype, "");
1144 if (mono_arch_is_soft_float ()) {
1145 if (stype == LLVMInt32Type () && dtype == LLVMFloatType ())
1146 return LLVMBuildBitCast (ctx->builder, v, dtype, "");
1147 if (stype == LLVMInt32Type () && dtype == LLVMDoubleType ())
1148 return LLVMBuildBitCast (ctx->builder, LLVMBuildZExt (ctx->builder, v, LLVMInt64Type (), ""), dtype, "");
1151 if (LLVMGetTypeKind (stype) == LLVMVectorTypeKind && LLVMGetTypeKind (dtype) == LLVMVectorTypeKind)
1152 return LLVMBuildBitCast (ctx->builder, v, dtype, "");
1155 LLVMDumpValue (LLVMConstNull (dtype));
1156 g_assert_not_reached ();
1164 convert (EmitContext *ctx, LLVMValueRef v, LLVMTypeRef dtype)
1166 return convert_full (ctx, v, dtype, FALSE);
1170 * emit_volatile_load:
1172 * If vreg is volatile, emit a load from its address.
1175 emit_volatile_load (EmitContext *ctx, int vreg)
1181 // FIXME: This hack is required because we pass the rgctx in a callee saved
1182 // register on arm64 (x15), and llvm might keep the value in that register
1183 // even through the register is marked as 'reserved' inside llvm.
1184 if (ctx->cfg->rgctx_var && ctx->cfg->rgctx_var->dreg == vreg)
1185 v = mono_llvm_build_load (ctx->builder, ctx->addresses [vreg], "", TRUE);
1187 v = LLVMBuildLoad (ctx->builder, ctx->addresses [vreg], "");
1189 v = LLVMBuildLoad (ctx->builder, ctx->addresses [vreg], "");
1191 t = ctx->vreg_cli_types [vreg];
1192 if (t && !t->byref) {
1194 * Might have to zero extend since llvm doesn't have
1197 if (t->type == MONO_TYPE_U1 || t->type == MONO_TYPE_U2 || t->type == MONO_TYPE_CHAR || t->type == MONO_TYPE_BOOLEAN)
1198 v = LLVMBuildZExt (ctx->builder, v, LLVMInt32Type (), "");
1199 else if (t->type == MONO_TYPE_I1 || t->type == MONO_TYPE_I2)
1200 v = LLVMBuildSExt (ctx->builder, v, LLVMInt32Type (), "");
1201 else if (t->type == MONO_TYPE_U8)
1202 v = LLVMBuildZExt (ctx->builder, v, LLVMInt64Type (), "");
1209 * emit_volatile_store:
1211 * If VREG is volatile, emit a store from its value to its address.
1214 emit_volatile_store (EmitContext *ctx, int vreg)
1216 MonoInst *var = get_vreg_to_inst (ctx->cfg, vreg);
1218 if (var && var->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT)) {
1219 g_assert (ctx->addresses [vreg]);
1220 LLVMBuildStore (ctx->builder, convert (ctx, ctx->values [vreg], type_to_llvm_type (ctx, var->inst_vtype)), ctx->addresses [vreg]);
1225 sig_to_llvm_sig_no_cinfo (EmitContext *ctx, MonoMethodSignature *sig)
1227 LLVMTypeRef ret_type;
1228 LLVMTypeRef *param_types = NULL;
1233 rtype = mini_get_underlying_type (sig->ret);
1234 ret_type = type_to_llvm_type (ctx, rtype);
1238 param_types = g_new0 (LLVMTypeRef, (sig->param_count * 8) + 3);
1242 param_types [pindex ++] = ThisType ();
1243 for (i = 0; i < sig->param_count; ++i)
1244 param_types [pindex ++] = type_to_llvm_arg_type (ctx, sig->params [i]);
1246 if (!ctx_ok (ctx)) {
1247 g_free (param_types);
1251 res = LLVMFunctionType (ret_type, param_types, pindex, FALSE);
1252 g_free (param_types);
1258 * sig_to_llvm_sig_full:
1260 * Return the LLVM signature corresponding to the mono signature SIG using the
1261 * calling convention information in CINFO. Fill out the parameter mapping information in CINFO.
1264 sig_to_llvm_sig_full (EmitContext *ctx, MonoMethodSignature *sig, LLVMCallInfo *cinfo)
1266 LLVMTypeRef ret_type;
1267 LLVMTypeRef *param_types = NULL;
1269 int i, j, pindex, vret_arg_pindex = 0;
1270 gboolean vretaddr = FALSE;
1274 return sig_to_llvm_sig_no_cinfo (ctx, sig);
1276 rtype = mini_get_underlying_type (sig->ret);
1277 ret_type = type_to_llvm_type (ctx, rtype);
1281 switch (cinfo->ret.storage) {
1282 case LLVMArgVtypeInReg:
1283 /* LLVM models this by returning an aggregate value */
1284 if (cinfo->ret.pair_storage [0] == LLVMArgInIReg && cinfo->ret.pair_storage [1] == LLVMArgNone) {
1285 LLVMTypeRef members [2];
1287 members [0] = IntPtrType ();
1288 ret_type = LLVMStructType (members, 1, FALSE);
1289 } else if (cinfo->ret.pair_storage [0] == LLVMArgNone && cinfo->ret.pair_storage [1] == LLVMArgNone) {
1291 ret_type = LLVMVoidType ();
1292 } else if (cinfo->ret.pair_storage [0] == LLVMArgInIReg && cinfo->ret.pair_storage [1] == LLVMArgInIReg) {
1293 LLVMTypeRef members [2];
1295 members [0] = IntPtrType ();
1296 members [1] = IntPtrType ();
1297 ret_type = LLVMStructType (members, 2, FALSE);
1299 g_assert_not_reached ();
1302 case LLVMArgVtypeByVal:
1303 /* Vtype returned normally by val */
1305 case LLVMArgVtypeAsScalar: {
1306 int size = mono_class_value_size (mono_class_from_mono_type (rtype), NULL);
1307 /* LLVM models this by returning an int */
1308 if (size < SIZEOF_VOID_P) {
1309 g_assert (cinfo->ret.nslots == 1);
1310 ret_type = LLVMIntType (size * 8);
1312 g_assert (cinfo->ret.nslots == 1 || cinfo->ret.nslots == 2);
1313 ret_type = LLVMIntType (cinfo->ret.nslots * sizeof (mgreg_t) * 8);
1317 case LLVMArgAsIArgs:
1318 ret_type = LLVMArrayType (IntPtrType (), cinfo->ret.nslots);
1320 case LLVMArgFpStruct: {
1321 /* Vtype returned as a fp struct */
1322 LLVMTypeRef members [16];
1324 /* Have to create our own structure since we don't map fp structures to LLVM fp structures yet */
1325 for (i = 0; i < cinfo->ret.nslots; ++i)
1326 members [i] = cinfo->ret.esize == 8 ? LLVMDoubleType () : LLVMFloatType ();
1327 ret_type = LLVMStructType (members, cinfo->ret.nslots, FALSE);
1330 case LLVMArgVtypeByRef:
1331 /* Vtype returned using a hidden argument */
1332 ret_type = LLVMVoidType ();
1334 case LLVMArgVtypeRetAddr:
1335 case LLVMArgGsharedvtFixed:
1336 case LLVMArgGsharedvtFixedVtype:
1337 case LLVMArgGsharedvtVariable:
1339 ret_type = LLVMVoidType ();
1345 param_types = g_new0 (LLVMTypeRef, (sig->param_count * 8) + 3);
1347 if (cinfo->ret.storage == LLVMArgVtypeByRef) {
1349 * Has to be the first argument because of the sret argument attribute
1350 * FIXME: This might conflict with passing 'this' as the first argument, but
1351 * this is only used on arm64 which has a dedicated struct return register.
1353 cinfo->vret_arg_pindex = pindex;
1354 param_types [pindex] = type_to_llvm_arg_type (ctx, sig->ret);
1355 if (!ctx_ok (ctx)) {
1356 g_free (param_types);
1359 param_types [pindex] = LLVMPointerType (param_types [pindex], 0);
1362 if (!ctx->llvm_only && cinfo->rgctx_arg) {
1363 cinfo->rgctx_arg_pindex = pindex;
1364 param_types [pindex] = ctx->module->ptr_type;
1367 if (cinfo->imt_arg) {
1368 cinfo->imt_arg_pindex = pindex;
1369 param_types [pindex] = ctx->module->ptr_type;
1373 /* Compute the index in the LLVM signature where the vret arg needs to be passed */
1374 vret_arg_pindex = pindex;
1375 if (cinfo->vret_arg_index == 1) {
1376 /* Add the slots consumed by the first argument */
1377 LLVMArgInfo *ainfo = &cinfo->args [0];
1378 switch (ainfo->storage) {
1379 case LLVMArgVtypeInReg:
1380 for (j = 0; j < 2; ++j) {
1381 if (ainfo->pair_storage [j] == LLVMArgInIReg)
1390 cinfo->vret_arg_pindex = vret_arg_pindex;
1393 if (vretaddr && vret_arg_pindex == pindex)
1394 param_types [pindex ++] = IntPtrType ();
1396 cinfo->this_arg_pindex = pindex;
1397 param_types [pindex ++] = ThisType ();
1398 cinfo->args [0].pindex = cinfo->this_arg_pindex;
1400 if (vretaddr && vret_arg_pindex == pindex)
1401 param_types [pindex ++] = IntPtrType ();
1402 for (i = 0; i < sig->param_count; ++i) {
1403 LLVMArgInfo *ainfo = &cinfo->args [i + sig->hasthis];
1405 if (vretaddr && vret_arg_pindex == pindex)
1406 param_types [pindex ++] = IntPtrType ();
1407 ainfo->pindex = pindex;
1409 switch (ainfo->storage) {
1410 case LLVMArgVtypeInReg:
1411 for (j = 0; j < 2; ++j) {
1412 switch (ainfo->pair_storage [j]) {
1414 param_types [pindex ++] = LLVMIntType (sizeof (gpointer) * 8);
1419 g_assert_not_reached ();
1423 case LLVMArgVtypeByVal:
1424 param_types [pindex] = type_to_llvm_arg_type (ctx, ainfo->type);
1427 param_types [pindex] = LLVMPointerType (param_types [pindex], 0);
1430 case LLVMArgAsIArgs:
1431 param_types [pindex] = LLVMArrayType (IntPtrType (), ainfo->nslots);
1434 case LLVMArgVtypeByRef:
1435 param_types [pindex] = type_to_llvm_arg_type (ctx, ainfo->type);
1438 param_types [pindex] = LLVMPointerType (param_types [pindex], 0);
1441 case LLVMArgAsFpArgs: {
1444 /* Emit dummy fp arguments if needed so the rest is passed on the stack */
1445 for (j = 0; j < ainfo->ndummy_fpargs; ++j)
1446 param_types [pindex ++] = LLVMDoubleType ();
1447 for (j = 0; j < ainfo->nslots; ++j)
1448 param_types [pindex ++] = ainfo->esize == 8 ? LLVMDoubleType () : LLVMFloatType ();
1451 case LLVMArgVtypeAsScalar:
1452 g_assert_not_reached ();
1454 case LLVMArgGsharedvtFixed:
1455 case LLVMArgGsharedvtFixedVtype:
1456 param_types [pindex ++] = LLVMPointerType (type_to_llvm_arg_type (ctx, ainfo->type), 0);
1458 case LLVMArgGsharedvtVariable:
1459 param_types [pindex ++] = LLVMPointerType (IntPtrType (), 0);
1462 param_types [pindex ++] = type_to_llvm_arg_type (ctx, ainfo->type);
1466 if (!ctx_ok (ctx)) {
1467 g_free (param_types);
1470 if (vretaddr && vret_arg_pindex == pindex)
1471 param_types [pindex ++] = IntPtrType ();
1472 if (ctx->llvm_only && cinfo->rgctx_arg) {
1473 /* Pass the rgctx as the last argument */
1474 cinfo->rgctx_arg_pindex = pindex;
1475 param_types [pindex] = ctx->module->ptr_type;
1479 res = LLVMFunctionType (ret_type, param_types, pindex, FALSE);
1480 g_free (param_types);
1486 sig_to_llvm_sig (EmitContext *ctx, MonoMethodSignature *sig)
1488 return sig_to_llvm_sig_full (ctx, sig, NULL);
1492 * LLVMFunctionType1:
1494 * Create an LLVM function type from the arguments.
1496 static G_GNUC_UNUSED LLVMTypeRef
1497 LLVMFunctionType0 (LLVMTypeRef ReturnType,
1500 return LLVMFunctionType (ReturnType, NULL, 0, IsVarArg);
1504 * LLVMFunctionType1:
1506 * Create an LLVM function type from the arguments.
1508 static G_GNUC_UNUSED LLVMTypeRef
1509 LLVMFunctionType1 (LLVMTypeRef ReturnType,
1510 LLVMTypeRef ParamType1,
1513 LLVMTypeRef param_types [1];
1515 param_types [0] = ParamType1;
1517 return LLVMFunctionType (ReturnType, param_types, 1, IsVarArg);
1521 * LLVMFunctionType2:
1523 * Create an LLVM function type from the arguments.
1525 static G_GNUC_UNUSED LLVMTypeRef
1526 LLVMFunctionType2 (LLVMTypeRef ReturnType,
1527 LLVMTypeRef ParamType1,
1528 LLVMTypeRef ParamType2,
1531 LLVMTypeRef param_types [2];
1533 param_types [0] = ParamType1;
1534 param_types [1] = ParamType2;
1536 return LLVMFunctionType (ReturnType, param_types, 2, IsVarArg);
1540 * LLVMFunctionType3:
1542 * Create an LLVM function type from the arguments.
1544 static G_GNUC_UNUSED LLVMTypeRef
1545 LLVMFunctionType3 (LLVMTypeRef ReturnType,
1546 LLVMTypeRef ParamType1,
1547 LLVMTypeRef ParamType2,
1548 LLVMTypeRef ParamType3,
1551 LLVMTypeRef param_types [3];
1553 param_types [0] = ParamType1;
1554 param_types [1] = ParamType2;
1555 param_types [2] = ParamType3;
1557 return LLVMFunctionType (ReturnType, param_types, 3, IsVarArg);
1560 static G_GNUC_UNUSED LLVMTypeRef
1561 LLVMFunctionType5 (LLVMTypeRef ReturnType,
1562 LLVMTypeRef ParamType1,
1563 LLVMTypeRef ParamType2,
1564 LLVMTypeRef ParamType3,
1565 LLVMTypeRef ParamType4,
1566 LLVMTypeRef ParamType5,
1569 LLVMTypeRef param_types [5];
1571 param_types [0] = ParamType1;
1572 param_types [1] = ParamType2;
1573 param_types [2] = ParamType3;
1574 param_types [3] = ParamType4;
1575 param_types [4] = ParamType5;
1577 return LLVMFunctionType (ReturnType, param_types, 5, IsVarArg);
1583 * Create an LLVM builder and remember it so it can be freed later.
1585 static LLVMBuilderRef
1586 create_builder (EmitContext *ctx)
1588 LLVMBuilderRef builder = LLVMCreateBuilder ();
1590 ctx->builders = g_slist_prepend_mempool (ctx->cfg->mempool, ctx->builders, builder);
1596 get_aotconst_name (MonoJumpInfoType type, gconstpointer data, int got_offset)
1601 case MONO_PATCH_INFO_INTERNAL_METHOD:
1602 name = g_strdup_printf ("jit_icall_%s", data);
1604 case MONO_PATCH_INFO_RGCTX_SLOT_INDEX: {
1605 MonoJumpInfoRgctxEntry *entry = (MonoJumpInfoRgctxEntry*)data;
1606 name = g_strdup_printf ("RGCTX_SLOT_INDEX_%s", mono_rgctx_info_type_to_str (entry->info_type));
1610 name = g_strdup_printf ("%s_%d", mono_ji_type_to_string (type), got_offset);
1618 get_aotconst_typed (EmitContext *ctx, MonoJumpInfoType type, gconstpointer data, LLVMTypeRef llvm_type)
1622 LLVMValueRef indexes [2];
1623 LLVMValueRef got_entry_addr, load;
1624 LLVMBuilderRef builder = ctx->builder;
1629 MonoJumpInfo tmp_ji;
1631 tmp_ji.data.target = data;
1633 MonoJumpInfo *ji = mono_aot_patch_info_dup (&tmp_ji);
1635 ji->next = cfg->patch_info;
1636 cfg->patch_info = ji;
1638 got_offset = mono_aot_get_got_offset (cfg->patch_info);
1639 ctx->module->max_got_offset = MAX (ctx->module->max_got_offset, got_offset);
1641 * If the got slot is shared, it means its initialized when the aot image is loaded, so we don't need to
1642 * explicitly initialize it.
1644 if (!mono_aot_is_shared_got_offset (got_offset)) {
1645 //mono_print_ji (ji);
1647 ctx->has_got_access = TRUE;
1650 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
1651 indexes [1] = LLVMConstInt (LLVMInt32Type (), (gssize)got_offset, FALSE);
1652 got_entry_addr = LLVMBuildGEP (builder, ctx->module->got_var, indexes, 2, "");
1654 name = get_aotconst_name (type, data, got_offset);
1656 load = LLVMBuildLoad (builder, got_entry_addr, "");
1657 load = convert (ctx, load, llvm_type);
1658 LLVMSetValueName (load, name ? name : "");
1660 load = LLVMBuildLoad (builder, got_entry_addr, name ? name : "");
1663 //set_invariant_load_flag (load);
1669 get_aotconst (EmitContext *ctx, MonoJumpInfoType type, gconstpointer data)
1671 return get_aotconst_typed (ctx, type, data, NULL);
1675 get_callee (EmitContext *ctx, LLVMTypeRef llvm_sig, MonoJumpInfoType type, gconstpointer data)
1677 LLVMValueRef callee;
1679 if (ctx->llvm_only) {
1680 callee_name = mono_aot_get_direct_call_symbol (type, data);
1682 /* Directly callable */
1684 callee = (LLVMValueRef)g_hash_table_lookup (ctx->module->direct_callables, callee_name);
1686 callee = LLVMAddFunction (ctx->lmodule, callee_name, llvm_sig);
1688 LLVMSetVisibility (callee, LLVMHiddenVisibility);
1690 g_hash_table_insert (ctx->module->direct_callables, (char*)callee_name, callee);
1692 /* LLVMTypeRef's are uniqued */
1693 if (LLVMGetElementType (LLVMTypeOf (callee)) != llvm_sig)
1694 return LLVMConstBitCast (callee, LLVMPointerType (llvm_sig, 0));
1696 g_free (callee_name);
1702 * Calls are made through the GOT.
1704 return get_aotconst_typed (ctx, type, data, LLVMPointerType (llvm_sig, 0));
1706 MonoJumpInfo *ji = NULL;
1708 callee_name = mono_aot_get_plt_symbol (type, data);
1712 if (ctx->cfg->compile_aot)
1713 /* Add a patch so referenced wrappers can be compiled in full aot mode */
1714 mono_add_patch_info (ctx->cfg, 0, type, data);
1717 callee = (LLVMValueRef)g_hash_table_lookup (ctx->module->plt_entries, callee_name);
1719 callee = LLVMAddFunction (ctx->lmodule, callee_name, llvm_sig);
1721 LLVMSetVisibility (callee, LLVMHiddenVisibility);
1723 g_hash_table_insert (ctx->module->plt_entries, (char*)callee_name, callee);
1726 if (ctx->cfg->compile_aot) {
1727 ji = g_new0 (MonoJumpInfo, 1);
1729 ji->data.target = data;
1731 g_hash_table_insert (ctx->module->plt_entries_ji, ji, callee);
1739 emit_jit_callee (EmitContext *ctx, const char *name, LLVMTypeRef llvm_sig, gpointer target)
1741 #if LLVM_API_VERSION > 100
1742 LLVMValueRef tramp_var = LLVMAddGlobal (ctx->lmodule, LLVMPointerType (llvm_sig, 0), name);
1743 LLVMSetInitializer (tramp_var, LLVMConstIntToPtr (LLVMConstInt (LLVMInt64Type (), (guint64)(size_t)target, FALSE), LLVMPointerType (llvm_sig, 0)));
1744 LLVMSetLinkage (tramp_var, LLVMExternalLinkage);
1745 LLVMValueRef callee = LLVMBuildLoad (ctx->builder, tramp_var, "");
1748 LLVMValueRef callee = LLVMAddFunction (ctx->lmodule, "", llvm_sig);
1749 LLVMAddGlobalMapping (ctx->module->ee, callee, target);
1755 get_handler_clause (MonoCompile *cfg, MonoBasicBlock *bb)
1757 MonoMethodHeader *header = cfg->header;
1758 MonoExceptionClause *clause;
1762 if (bb->region != -1 && MONO_BBLOCK_IS_IN_REGION (bb, MONO_REGION_TRY))
1763 return (bb->region >> 8) - 1;
1766 for (i = 0; i < header->num_clauses; ++i) {
1767 clause = &header->clauses [i];
1769 if (MONO_OFFSET_IN_CLAUSE (clause, bb->real_offset) && clause->flags == MONO_EXCEPTION_CLAUSE_NONE)
1776 static MonoExceptionClause *
1777 get_most_deep_clause (MonoCompile *cfg, EmitContext *ctx, MonoBasicBlock *bb)
1779 if (bb == cfg->bb_init)
1781 // Since they're sorted by nesting we just need
1782 // the first one that the bb is a member of
1783 for (int i = 0; i < cfg->header->num_clauses; i++) {
1784 MonoExceptionClause *curr = &cfg->header->clauses [i];
1786 if (MONO_OFFSET_IN_CLAUSE (curr, bb->real_offset))
1794 set_metadata_flag (LLVMValueRef v, const char *flag_name)
1796 LLVMValueRef md_arg;
1799 md_kind = LLVMGetMDKindID (flag_name, strlen (flag_name));
1800 md_arg = LLVMMDString ("mono", 4);
1801 LLVMSetMetadata (v, md_kind, LLVMMDNode (&md_arg, 1));
1805 set_invariant_load_flag (LLVMValueRef v)
1807 LLVMValueRef md_arg;
1809 const char *flag_name;
1811 // FIXME: Cache this
1812 flag_name = "invariant.load";
1813 md_kind = LLVMGetMDKindID (flag_name, strlen (flag_name));
1814 md_arg = LLVMMDString ("<index>", strlen ("<index>"));
1815 LLVMSetMetadata (v, md_kind, LLVMMDNode (&md_arg, 1));
1821 * Emit an LLVM call or invoke instruction depending on whenever the call is inside
1825 emit_call (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, LLVMValueRef callee, LLVMValueRef *args, int pindex)
1827 MonoCompile *cfg = ctx->cfg;
1828 LLVMValueRef lcall = NULL;
1829 LLVMBuilderRef builder = *builder_ref;
1830 MonoExceptionClause *clause;
1832 if (ctx->llvm_only) {
1833 clause = get_most_deep_clause (cfg, ctx, bb);
1836 g_assert (clause->flags == MONO_EXCEPTION_CLAUSE_NONE || clause->flags == MONO_EXCEPTION_CLAUSE_FINALLY);
1839 * Have to use an invoke instead of a call, branching to the
1840 * handler bblock of the clause containing this bblock.
1842 intptr_t key = CLAUSE_END(clause);
1844 LLVMBasicBlockRef lpad_bb = (LLVMBasicBlockRef)g_hash_table_lookup (ctx->exc_meta, (gconstpointer)key);
1846 // FIXME: Find the one that has the lowest end bound for the right start address
1847 // FIXME: Finally + nesting
1850 LLVMBasicBlockRef noex_bb = gen_bb (ctx, "CALL_NOEX_BB");
1853 lcall = LLVMBuildInvoke (builder, callee, args, pindex, noex_bb, lpad_bb, "");
1855 builder = ctx->builder = create_builder (ctx);
1856 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
1858 ctx->bblocks [bb->block_num].end_bblock = noex_bb;
1862 int clause_index = get_handler_clause (cfg, bb);
1864 if (clause_index != -1) {
1865 MonoMethodHeader *header = cfg->header;
1866 MonoExceptionClause *ec = &header->clauses [clause_index];
1867 MonoBasicBlock *tblock;
1868 LLVMBasicBlockRef ex_bb, noex_bb;
1871 * Have to use an invoke instead of a call, branching to the
1872 * handler bblock of the clause containing this bblock.
1875 g_assert (ec->flags == MONO_EXCEPTION_CLAUSE_NONE || ec->flags == MONO_EXCEPTION_CLAUSE_FINALLY);
1877 tblock = cfg->cil_offset_to_bb [ec->handler_offset];
1880 ctx->bblocks [tblock->block_num].invoke_target = TRUE;
1882 ex_bb = get_bb (ctx, tblock);
1884 noex_bb = gen_bb (ctx, "NOEX_BB");
1887 lcall = LLVMBuildInvoke (builder, callee, args, pindex, noex_bb, ex_bb, "");
1889 builder = ctx->builder = create_builder (ctx);
1890 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
1892 ctx->bblocks [bb->block_num].end_bblock = noex_bb;
1897 lcall = LLVMBuildCall (builder, callee, args, pindex, "");
1898 ctx->builder = builder;
1902 *builder_ref = ctx->builder;
1908 emit_load_general (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, int size, LLVMValueRef addr, LLVMValueRef base, const char *name, gboolean is_faulting, BarrierKind barrier)
1910 const char *intrins_name;
1911 LLVMValueRef args [16], res;
1912 LLVMTypeRef addr_type;
1913 gboolean use_intrinsics = TRUE;
1915 #if LLVM_API_VERSION > 100
1916 if (is_faulting && bb->region != -1 && !ctx->cfg->llvm_only) {
1917 /* The llvm.mono.load/store intrinsics are not supported by this llvm version, emit an explicit null check instead */
1920 cmp = LLVMBuildICmp (*builder_ref, LLVMIntEQ, base, LLVMConstNull (LLVMTypeOf (base)), "");
1921 emit_cond_system_exception (ctx, bb, "NullReferenceException", cmp);
1922 *builder_ref = ctx->builder;
1923 use_intrinsics = FALSE;
1927 if (is_faulting && bb->region != -1 && !ctx->cfg->llvm_only && use_intrinsics) {
1928 LLVMAtomicOrdering ordering;
1931 case LLVM_BARRIER_NONE:
1932 ordering = LLVMAtomicOrderingNotAtomic;
1934 case LLVM_BARRIER_ACQ:
1935 ordering = LLVMAtomicOrderingAcquire;
1937 case LLVM_BARRIER_SEQ:
1938 ordering = LLVMAtomicOrderingSequentiallyConsistent;
1941 g_assert_not_reached ();
1946 * We handle loads which can fault by calling a mono specific intrinsic
1947 * using an invoke, so they are handled properly inside try blocks.
1948 * We can't use this outside clauses, since LLVM optimizes intrinsics which
1949 * are marked with IntrReadArgMem.
1953 intrins_name = "llvm.mono.load.i8.p0i8";
1956 intrins_name = "llvm.mono.load.i16.p0i16";
1959 intrins_name = "llvm.mono.load.i32.p0i32";
1962 intrins_name = "llvm.mono.load.i64.p0i64";
1965 g_assert_not_reached ();
1968 addr_type = LLVMTypeOf (addr);
1969 if (addr_type == LLVMPointerType (LLVMDoubleType (), 0) || addr_type == LLVMPointerType (LLVMFloatType (), 0))
1970 addr = LLVMBuildBitCast (*builder_ref, addr, LLVMPointerType (LLVMIntType (size * 8), 0), "");
1973 args [1] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
1974 args [2] = LLVMConstInt (LLVMInt1Type (), TRUE, FALSE);
1975 args [3] = LLVMConstInt (LLVMInt32Type (), ordering, FALSE);
1976 res = emit_call (ctx, bb, builder_ref, get_intrinsic (ctx, intrins_name), args, 4);
1978 if (addr_type == LLVMPointerType (LLVMDoubleType (), 0))
1979 res = LLVMBuildBitCast (*builder_ref, res, LLVMDoubleType (), "");
1980 else if (addr_type == LLVMPointerType (LLVMFloatType (), 0))
1981 res = LLVMBuildBitCast (*builder_ref, res, LLVMFloatType (), "");
1988 * We emit volatile loads for loads which can fault, because otherwise
1989 * LLVM will generate invalid code when encountering a load from a
1992 if (barrier != LLVM_BARRIER_NONE)
1993 res = mono_llvm_build_atomic_load (*builder_ref, addr, name, is_faulting, size, barrier);
1995 res = mono_llvm_build_load (*builder_ref, addr, name, is_faulting);
1997 /* Mark it with a custom metadata */
2000 set_metadata_flag (res, "mono.faulting.load");
2008 emit_load (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, int size, LLVMValueRef addr, const char *name, gboolean is_faulting)
2010 return emit_load_general (ctx, bb, builder_ref, size, addr, addr, name, is_faulting, LLVM_BARRIER_NONE);
2014 emit_store_general (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, int size, LLVMValueRef value, LLVMValueRef addr, LLVMValueRef base, gboolean is_faulting, BarrierKind barrier)
2016 const char *intrins_name;
2017 LLVMValueRef args [16];
2018 gboolean use_intrinsics = TRUE;
2020 #if LLVM_API_VERSION > 100
2021 if (is_faulting && bb->region != -1 && !ctx->cfg->llvm_only) {
2022 /* The llvm.mono.load/store intrinsics are not supported by this llvm version, emit an explicit null check instead */
2023 LLVMValueRef cmp = LLVMBuildICmp (*builder_ref, LLVMIntEQ, base, LLVMConstNull (LLVMTypeOf (base)), "");
2024 emit_cond_system_exception (ctx, bb, "NullReferenceException", cmp);
2025 *builder_ref = ctx->builder;
2026 use_intrinsics = FALSE;
2030 if (is_faulting && bb->region != -1 && !ctx->cfg->llvm_only && use_intrinsics) {
2031 LLVMAtomicOrdering ordering;
2034 case LLVM_BARRIER_NONE:
2035 ordering = LLVMAtomicOrderingNotAtomic;
2037 case LLVM_BARRIER_REL:
2038 ordering = LLVMAtomicOrderingRelease;
2040 case LLVM_BARRIER_SEQ:
2041 ordering = LLVMAtomicOrderingSequentiallyConsistent;
2044 g_assert_not_reached ();
2050 intrins_name = "llvm.mono.store.i8.p0i8";
2053 intrins_name = "llvm.mono.store.i16.p0i16";
2056 intrins_name = "llvm.mono.store.i32.p0i32";
2059 intrins_name = "llvm.mono.store.i64.p0i64";
2062 g_assert_not_reached ();
2065 if (LLVMTypeOf (value) == LLVMDoubleType () || LLVMTypeOf (value) == LLVMFloatType ()) {
2066 value = LLVMBuildBitCast (*builder_ref, value, LLVMIntType (size * 8), "");
2067 addr = LLVMBuildBitCast (*builder_ref, addr, LLVMPointerType (LLVMIntType (size * 8), 0), "");
2072 args [2] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
2073 args [3] = LLVMConstInt (LLVMInt1Type (), TRUE, FALSE);
2074 args [4] = LLVMConstInt (LLVMInt32Type (), ordering, FALSE);
2075 emit_call (ctx, bb, builder_ref, get_intrinsic (ctx, intrins_name), args, 5);
2077 if (barrier != LLVM_BARRIER_NONE)
2078 mono_llvm_build_aligned_store (*builder_ref, value, addr, barrier, size);
2080 mono_llvm_build_store (*builder_ref, value, addr, is_faulting, barrier);
2085 emit_store (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, int size, LLVMValueRef value, LLVMValueRef addr, LLVMValueRef base, gboolean is_faulting)
2087 emit_store_general (ctx, bb, builder_ref, size, value, addr, base, is_faulting, LLVM_BARRIER_NONE);
2091 * emit_cond_system_exception:
2093 * Emit code to throw the exception EXC_TYPE if the condition CMP is false.
2094 * Might set the ctx exception.
2097 emit_cond_system_exception (EmitContext *ctx, MonoBasicBlock *bb, const char *exc_type, LLVMValueRef cmp)
2099 LLVMBasicBlockRef ex_bb, ex2_bb = NULL, noex_bb;
2100 LLVMBuilderRef builder;
2101 MonoClass *exc_class;
2102 LLVMValueRef args [2];
2103 LLVMValueRef callee;
2104 gboolean no_pc = FALSE;
2106 if (IS_TARGET_AMD64)
2107 /* Some platforms don't require the pc argument */
2110 ex_bb = gen_bb (ctx, "EX_BB");
2112 ex2_bb = gen_bb (ctx, "EX2_BB");
2113 noex_bb = gen_bb (ctx, "NOEX_BB");
2115 LLVMBuildCondBr (ctx->builder, cmp, ex_bb, noex_bb);
2117 exc_class = mono_class_load_from_name (mono_get_corlib (), "System", exc_type);
2119 /* Emit exception throwing code */
2120 ctx->builder = builder = create_builder (ctx);
2121 LLVMPositionBuilderAtEnd (builder, ex_bb);
2123 if (ctx->cfg->llvm_only) {
2124 static LLVMTypeRef sig;
2127 sig = LLVMFunctionType1 (LLVMVoidType (), LLVMInt32Type (), FALSE);
2128 callee = get_callee (ctx, sig, MONO_PATCH_INFO_JIT_ICALL_ADDR, "mono_llvm_throw_corlib_exception");
2130 LLVMBuildBr (builder, ex2_bb);
2132 ctx->builder = builder = create_builder (ctx);
2133 LLVMPositionBuilderAtEnd (ctx->builder, ex2_bb);
2135 args [0] = LLVMConstInt (LLVMInt32Type (), exc_class->type_token - MONO_TOKEN_TYPE_DEF, FALSE);
2136 emit_call (ctx, bb, &builder, callee, args, 1);
2137 LLVMBuildUnreachable (builder);
2139 ctx->builder = builder = create_builder (ctx);
2140 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
2142 ctx->bblocks [bb->block_num].end_bblock = noex_bb;
2148 callee = ctx->module->throw_corlib_exception;
2151 const char *icall_name;
2154 sig = LLVMFunctionType1 (LLVMVoidType (), LLVMInt32Type (), FALSE);
2156 sig = LLVMFunctionType2 (LLVMVoidType (), LLVMInt32Type (), LLVMPointerType (LLVMInt8Type (), 0), FALSE);
2157 icall_name = "llvm_throw_corlib_exception_abs_trampoline";
2159 if (ctx->cfg->compile_aot) {
2160 callee = get_callee (ctx, sig, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
2163 * Differences between the LLVM/non-LLVM throw corlib exception trampoline:
2164 * - On x86, LLVM generated code doesn't push the arguments
2165 * - The trampoline takes the throw address as an arguments, not a pc offset.
2167 gpointer target = resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
2168 callee = emit_jit_callee (ctx, "llvm_throw_corlib_exception_trampoline", sig, target);
2170 #if LLVM_API_VERSION > 100
2172 * Make sure that ex_bb starts with the invoke, so the block address points to it, and not to the load
2173 * added by emit_jit_callee ().
2175 ex2_bb = gen_bb (ctx, "EX2_BB");
2176 LLVMBuildBr (builder, ex2_bb);
2179 ctx->builder = builder = create_builder (ctx);
2180 LLVMPositionBuilderAtEnd (ctx->builder, ex2_bb);
2182 mono_memory_barrier ();
2183 ctx->module->throw_corlib_exception = callee;
2188 args [0] = LLVMConstInt (LLVMInt32Type (), exc_class->type_token - MONO_TOKEN_TYPE_DEF, FALSE);
2191 * The LLVM mono branch contains changes so a block address can be passed as an
2192 * argument to a call.
2195 emit_call (ctx, bb, &builder, callee, args, 1);
2197 args [1] = LLVMBlockAddress (ctx->lmethod, ex_bb);
2198 emit_call (ctx, bb, &builder, callee, args, 2);
2201 LLVMBuildUnreachable (builder);
2203 ctx->builder = builder = create_builder (ctx);
2204 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
2206 ctx->bblocks [bb->block_num].end_bblock = noex_bb;
2213 * emit_args_to_vtype:
2215 * Emit code to store the vtype in the arguments args to the address ADDRESS.
2218 emit_args_to_vtype (EmitContext *ctx, LLVMBuilderRef builder, MonoType *t, LLVMValueRef address, LLVMArgInfo *ainfo, LLVMValueRef *args)
2220 int j, size, nslots;
2222 size = mono_class_value_size (mono_class_from_mono_type (t), NULL);
2224 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (t))) {
2225 address = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (LLVMInt8Type (), 0), "");
2228 if (ainfo->storage == LLVMArgAsFpArgs)
2229 nslots = ainfo->nslots;
2233 for (j = 0; j < nslots; ++j) {
2234 LLVMValueRef index [2], addr, daddr;
2235 int part_size = size > sizeof (gpointer) ? sizeof (gpointer) : size;
2236 LLVMTypeRef part_type;
2238 while (part_size != 1 && part_size != 2 && part_size != 4 && part_size < 8)
2241 if (ainfo->pair_storage [j] == LLVMArgNone)
2244 switch (ainfo->pair_storage [j]) {
2245 case LLVMArgInIReg: {
2246 part_type = LLVMIntType (part_size * 8);
2247 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (t))) {
2248 index [0] = LLVMConstInt (LLVMInt32Type (), j * sizeof (gpointer), FALSE);
2249 addr = LLVMBuildGEP (builder, address, index, 1, "");
2251 daddr = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (IntPtrType (), 0), "");
2252 index [0] = LLVMConstInt (LLVMInt32Type (), j, FALSE);
2253 addr = LLVMBuildGEP (builder, daddr, index, 1, "");
2255 LLVMBuildStore (builder, convert (ctx, args [j], part_type), LLVMBuildBitCast (ctx->builder, addr, LLVMPointerType (part_type, 0), ""));
2258 case LLVMArgInFPReg: {
2259 LLVMTypeRef arg_type;
2261 if (ainfo->esize == 8)
2262 arg_type = LLVMDoubleType ();
2264 arg_type = LLVMFloatType ();
2266 index [0] = LLVMConstInt (LLVMInt32Type (), j, FALSE);
2267 daddr = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (arg_type, 0), "");
2268 addr = LLVMBuildGEP (builder, daddr, index, 1, "");
2269 LLVMBuildStore (builder, args [j], addr);
2275 g_assert_not_reached ();
2278 size -= sizeof (gpointer);
2283 * emit_vtype_to_args:
2285 * Emit code to load a vtype at address ADDRESS into scalar arguments. Store the arguments
2286 * into ARGS, and the number of arguments into NARGS.
2289 emit_vtype_to_args (EmitContext *ctx, LLVMBuilderRef builder, MonoType *t, LLVMValueRef address, LLVMArgInfo *ainfo, LLVMValueRef *args, guint32 *nargs)
2292 int j, size, nslots;
2293 LLVMTypeRef arg_type;
2295 size = get_vtype_size (t);
2297 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (t)))
2298 address = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (LLVMInt8Type (), 0), "");
2300 if (ainfo->storage == LLVMArgAsFpArgs)
2301 nslots = ainfo->nslots;
2304 for (j = 0; j < nslots; ++j) {
2305 LLVMValueRef index [2], addr, daddr;
2306 int partsize = size > sizeof (gpointer) ? sizeof (gpointer) : size;
2308 if (ainfo->pair_storage [j] == LLVMArgNone)
2311 switch (ainfo->pair_storage [j]) {
2313 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (t))) {
2314 index [0] = LLVMConstInt (LLVMInt32Type (), j * sizeof (gpointer), FALSE);
2315 addr = LLVMBuildGEP (builder, address, index, 1, "");
2317 daddr = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (IntPtrType (), 0), "");
2318 index [0] = LLVMConstInt (LLVMInt32Type (), j, FALSE);
2319 addr = LLVMBuildGEP (builder, daddr, index, 1, "");
2321 args [pindex ++] = convert (ctx, LLVMBuildLoad (builder, LLVMBuildBitCast (ctx->builder, addr, LLVMPointerType (LLVMIntType (partsize * 8), 0), ""), ""), IntPtrType ());
2323 case LLVMArgInFPReg:
2324 if (ainfo->esize == 8)
2325 arg_type = LLVMDoubleType ();
2327 arg_type = LLVMFloatType ();
2328 daddr = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (arg_type, 0), "");
2329 index [0] = LLVMConstInt (LLVMInt32Type (), j, FALSE);
2330 addr = LLVMBuildGEP (builder, daddr, index, 1, "");
2331 args [pindex ++] = LLVMBuildLoad (builder, addr, "");
2336 g_assert_not_reached ();
2338 size -= sizeof (gpointer);
2345 build_alloca_llvm_type_name (EmitContext *ctx, LLVMTypeRef t, int align, const char *name)
2348 * Have to place all alloca's at the end of the entry bb, since otherwise they would
2349 * get executed every time control reaches them.
2351 LLVMPositionBuilder (ctx->alloca_builder, get_bb (ctx, ctx->cfg->bb_entry), ctx->last_alloca);
2353 ctx->last_alloca = mono_llvm_build_alloca (ctx->alloca_builder, t, NULL, align, name);
2354 return ctx->last_alloca;
2358 build_alloca_llvm_type (EmitContext *ctx, LLVMTypeRef t, int align)
2360 return build_alloca_llvm_type_name (ctx, t, align, "");
2364 build_alloca (EmitContext *ctx, MonoType *t)
2366 MonoClass *k = mono_class_from_mono_type (t);
2369 g_assert (!mini_is_gsharedvt_variable_type (t));
2371 if (MONO_CLASS_IS_SIMD (ctx->cfg, k))
2374 align = mono_class_min_align (k);
2376 /* Sometimes align is not a power of 2 */
2377 while (mono_is_power_of_two (align) == -1)
2380 return build_alloca_llvm_type (ctx, type_to_llvm_type (ctx, t), align);
2384 emit_gsharedvt_ldaddr (EmitContext *ctx, int vreg)
2388 * Compute the address of the local as gsharedvt_locals_var + gsharedvt_info_var->locals_offsets [idx].
2390 MonoCompile *cfg = ctx->cfg;
2391 LLVMBuilderRef builder = ctx->builder;
2392 LLVMValueRef offset, offset_var;
2393 LLVMValueRef info_var = ctx->values [cfg->gsharedvt_info_var->dreg];
2394 LLVMValueRef locals_var = ctx->values [cfg->gsharedvt_locals_var->dreg];
2398 g_assert (info_var);
2399 g_assert (locals_var);
2401 int idx = cfg->gsharedvt_vreg_to_idx [vreg] - 1;
2403 offset = LLVMConstInt (LLVMInt32Type (), MONO_STRUCT_OFFSET (MonoGSharedVtMethodRuntimeInfo, entries) + (idx * sizeof (gpointer)), FALSE);
2404 ptr = LLVMBuildAdd (builder, convert (ctx, info_var, IntPtrType ()), convert (ctx, offset, IntPtrType ()), "");
2406 name = g_strdup_printf ("gsharedvt_local_%d_offset", vreg);
2407 offset_var = LLVMBuildLoad (builder, convert (ctx, ptr, LLVMPointerType (LLVMInt32Type (), 0)), name);
2409 return LLVMBuildAdd (builder, convert (ctx, locals_var, IntPtrType ()), convert (ctx, offset_var, IntPtrType ()), "");
2413 * Put the global into the 'llvm.used' array to prevent it from being optimized away.
2416 mark_as_used (MonoLLVMModule *module, LLVMValueRef global)
2419 module->used = g_ptr_array_sized_new (16);
2420 g_ptr_array_add (module->used, global);
2424 emit_llvm_used (MonoLLVMModule *module)
2426 LLVMModuleRef lmodule = module->lmodule;
2427 LLVMTypeRef used_type;
2428 LLVMValueRef used, *used_elem;
2434 used_type = LLVMArrayType (LLVMPointerType (LLVMInt8Type (), 0), module->used->len);
2435 used = LLVMAddGlobal (lmodule, used_type, "llvm.used");
2436 used_elem = g_new0 (LLVMValueRef, module->used->len);
2437 for (i = 0; i < module->used->len; ++i)
2438 used_elem [i] = LLVMConstBitCast ((LLVMValueRef)g_ptr_array_index (module->used, i), LLVMPointerType (LLVMInt8Type (), 0));
2439 LLVMSetInitializer (used, LLVMConstArray (LLVMPointerType (LLVMInt8Type (), 0), used_elem, module->used->len));
2440 LLVMSetLinkage (used, LLVMAppendingLinkage);
2441 LLVMSetSection (used, "llvm.metadata");
2447 * Emit a function mapping method indexes to their code
2450 emit_get_method (MonoLLVMModule *module)
2452 LLVMModuleRef lmodule = module->lmodule;
2453 LLVMValueRef func, switch_ins, m;
2454 LLVMBasicBlockRef entry_bb, fail_bb, bb, code_start_bb, code_end_bb;
2455 LLVMBasicBlockRef *bbs;
2457 LLVMBuilderRef builder = LLVMCreateBuilder ();
2462 * Emit a switch statement. Emitting a table of function addresses is smaller/faster,
2463 * but generating code seems safer.
2465 rtype = LLVMPointerType (LLVMInt8Type (), 0);
2466 func = LLVMAddFunction (lmodule, module->get_method_symbol, LLVMFunctionType1 (rtype, LLVMInt32Type (), FALSE));
2467 LLVMSetLinkage (func, LLVMExternalLinkage);
2468 LLVMSetVisibility (func, LLVMHiddenVisibility);
2469 LLVMAddFunctionAttr (func, LLVMNoUnwindAttribute);
2470 module->get_method = func;
2472 entry_bb = LLVMAppendBasicBlock (func, "ENTRY");
2475 * Return llvm_code_start/llvm_code_end when called with -1/-2.
2476 * Hopefully, the toolchain doesn't reorder these functions. If it does,
2477 * then we will have to find another solution.
2480 name = g_strdup_printf ("BB_CODE_START");
2481 code_start_bb = LLVMAppendBasicBlock (func, name);
2483 LLVMPositionBuilderAtEnd (builder, code_start_bb);
2484 LLVMBuildRet (builder, LLVMBuildBitCast (builder, module->code_start, rtype, ""));
2486 name = g_strdup_printf ("BB_CODE_END");
2487 code_end_bb = LLVMAppendBasicBlock (func, name);
2489 LLVMPositionBuilderAtEnd (builder, code_end_bb);
2490 LLVMBuildRet (builder, LLVMBuildBitCast (builder, module->code_end, rtype, ""));
2492 bbs = g_new0 (LLVMBasicBlockRef, module->max_method_idx + 1);
2493 for (i = 0; i < module->max_method_idx + 1; ++i) {
2494 name = g_strdup_printf ("BB_%d", i);
2495 bb = LLVMAppendBasicBlock (func, name);
2499 LLVMPositionBuilderAtEnd (builder, bb);
2501 m = (LLVMValueRef)g_hash_table_lookup (module->idx_to_lmethod, GINT_TO_POINTER (i));
2503 LLVMBuildRet (builder, LLVMBuildBitCast (builder, m, rtype, ""));
2505 LLVMBuildRet (builder, LLVMConstNull (rtype));
2508 fail_bb = LLVMAppendBasicBlock (func, "FAIL");
2509 LLVMPositionBuilderAtEnd (builder, fail_bb);
2510 LLVMBuildRet (builder, LLVMConstNull (rtype));
2512 LLVMPositionBuilderAtEnd (builder, entry_bb);
2514 switch_ins = LLVMBuildSwitch (builder, LLVMGetParam (func, 0), fail_bb, 0);
2515 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), -1, FALSE), code_start_bb);
2516 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), -2, FALSE), code_end_bb);
2517 for (i = 0; i < module->max_method_idx + 1; ++i) {
2518 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), i, FALSE), bbs [i]);
2521 mark_as_used (module, func);
2523 LLVMDisposeBuilder (builder);
2527 * emit_get_unbox_tramp:
2529 * Emit a function mapping method indexes to their unbox trampoline
2532 emit_get_unbox_tramp (MonoLLVMModule *module)
2534 LLVMModuleRef lmodule = module->lmodule;
2535 LLVMValueRef func, switch_ins, m;
2536 LLVMBasicBlockRef entry_bb, fail_bb, bb;
2537 LLVMBasicBlockRef *bbs;
2539 LLVMBuilderRef builder = LLVMCreateBuilder ();
2543 /* Similar to emit_get_method () */
2545 rtype = LLVMPointerType (LLVMInt8Type (), 0);
2546 func = LLVMAddFunction (lmodule, module->get_unbox_tramp_symbol, LLVMFunctionType1 (rtype, LLVMInt32Type (), FALSE));
2547 LLVMSetLinkage (func, LLVMExternalLinkage);
2548 LLVMSetVisibility (func, LLVMHiddenVisibility);
2549 LLVMAddFunctionAttr (func, LLVMNoUnwindAttribute);
2550 module->get_unbox_tramp = func;
2552 entry_bb = LLVMAppendBasicBlock (func, "ENTRY");
2554 bbs = g_new0 (LLVMBasicBlockRef, module->max_method_idx + 1);
2555 for (i = 0; i < module->max_method_idx + 1; ++i) {
2556 m = (LLVMValueRef)g_hash_table_lookup (module->idx_to_unbox_tramp, GINT_TO_POINTER (i));
2560 name = g_strdup_printf ("BB_%d", i);
2561 bb = LLVMAppendBasicBlock (func, name);
2565 LLVMPositionBuilderAtEnd (builder, bb);
2567 LLVMBuildRet (builder, LLVMBuildBitCast (builder, m, rtype, ""));
2570 fail_bb = LLVMAppendBasicBlock (func, "FAIL");
2571 LLVMPositionBuilderAtEnd (builder, fail_bb);
2572 LLVMBuildRet (builder, LLVMConstNull (rtype));
2574 LLVMPositionBuilderAtEnd (builder, entry_bb);
2576 switch_ins = LLVMBuildSwitch (builder, LLVMGetParam (func, 0), fail_bb, 0);
2577 for (i = 0; i < module->max_method_idx + 1; ++i) {
2578 m = (LLVMValueRef)g_hash_table_lookup (module->idx_to_unbox_tramp, GINT_TO_POINTER (i));
2582 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), i, FALSE), bbs [i]);
2585 mark_as_used (module, func);
2586 LLVMDisposeBuilder (builder);
2589 /* Add a function to mark the beginning of LLVM code */
2591 emit_llvm_code_start (MonoLLVMModule *module)
2593 LLVMModuleRef lmodule = module->lmodule;
2595 LLVMBasicBlockRef entry_bb;
2596 LLVMBuilderRef builder;
2598 func = LLVMAddFunction (lmodule, "llvm_code_start", LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE));
2599 LLVMSetLinkage (func, LLVMInternalLinkage);
2600 LLVMAddFunctionAttr (func, LLVMNoUnwindAttribute);
2601 module->code_start = func;
2602 entry_bb = LLVMAppendBasicBlock (func, "ENTRY");
2603 builder = LLVMCreateBuilder ();
2604 LLVMPositionBuilderAtEnd (builder, entry_bb);
2605 LLVMBuildRetVoid (builder);
2606 LLVMDisposeBuilder (builder);
2610 emit_init_icall_wrapper (MonoLLVMModule *module, const char *name, const char *icall_name, int subtype)
2612 LLVMModuleRef lmodule = module->lmodule;
2613 LLVMValueRef func, indexes [2], got_entry_addr, args [16], callee;
2614 LLVMBasicBlockRef entry_bb;
2615 LLVMBuilderRef builder;
2622 func = LLVMAddFunction (lmodule, name, LLVMFunctionType1 (LLVMVoidType (), LLVMInt32Type (), FALSE));
2623 sig = LLVMFunctionType2 (LLVMVoidType (), IntPtrType (), LLVMInt32Type (), FALSE);
2628 func = LLVMAddFunction (lmodule, name, LLVMFunctionType2 (LLVMVoidType (), LLVMInt32Type (), IntPtrType (), FALSE));
2629 sig = LLVMFunctionType3 (LLVMVoidType (), IntPtrType (), LLVMInt32Type (), IntPtrType (), FALSE);
2632 func = LLVMAddFunction (lmodule, name, LLVMFunctionType2 (LLVMVoidType (), LLVMInt32Type (), ObjRefType (), FALSE));
2633 sig = LLVMFunctionType3 (LLVMVoidType (), IntPtrType (), LLVMInt32Type (), ObjRefType (), FALSE);
2636 g_assert_not_reached ();
2638 LLVMSetLinkage (func, LLVMInternalLinkage);
2639 LLVMAddFunctionAttr (func, LLVMNoInlineAttribute);
2640 mono_llvm_set_preserveall_cc (func);
2641 entry_bb = LLVMAppendBasicBlock (func, "ENTRY");
2642 builder = LLVMCreateBuilder ();
2643 LLVMPositionBuilderAtEnd (builder, entry_bb);
2646 ji = g_new0 (MonoJumpInfo, 1);
2647 ji->type = MONO_PATCH_INFO_AOT_MODULE;
2648 ji = mono_aot_patch_info_dup (ji);
2649 got_offset = mono_aot_get_got_offset (ji);
2650 module->max_got_offset = MAX (module->max_got_offset, got_offset);
2651 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
2652 indexes [1] = LLVMConstInt (LLVMInt32Type (), got_offset, FALSE);
2653 got_entry_addr = LLVMBuildGEP (builder, module->got_var, indexes, 2, "");
2654 args [0] = LLVMBuildPtrToInt (builder, LLVMBuildLoad (builder, got_entry_addr, ""), IntPtrType (), "");
2655 args [1] = LLVMGetParam (func, 0);
2657 args [2] = LLVMGetParam (func, 1);
2659 ji = g_new0 (MonoJumpInfo, 1);
2660 ji->type = MONO_PATCH_INFO_INTERNAL_METHOD;
2661 ji->data.name = icall_name;
2662 ji = mono_aot_patch_info_dup (ji);
2663 got_offset = mono_aot_get_got_offset (ji);
2664 module->max_got_offset = MAX (module->max_got_offset, got_offset);
2665 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
2666 indexes [1] = LLVMConstInt (LLVMInt32Type (), got_offset, FALSE);
2667 got_entry_addr = LLVMBuildGEP (builder, module->got_var, indexes, 2, "");
2668 callee = LLVMBuildLoad (builder, got_entry_addr, "");
2669 callee = LLVMBuildBitCast (builder, callee, LLVMPointerType (sig, 0), "");
2670 LLVMBuildCall (builder, callee, args, LLVMCountParamTypes (sig), "");
2672 // Set the inited flag
2673 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
2674 indexes [1] = LLVMGetParam (func, 0);
2675 LLVMBuildStore (builder, LLVMConstInt (LLVMInt8Type (), 1, FALSE), LLVMBuildGEP (builder, module->inited_var, indexes, 2, ""));
2677 LLVMBuildRetVoid (builder);
2679 LLVMVerifyFunction(func, LLVMAbortProcessAction);
2680 LLVMDisposeBuilder (builder);
2685 * Emit wrappers around the C icalls used to initialize llvm methods, to
2686 * make the calling code smaller and to enable usage of the llvm
2687 * PreserveAll calling convention.
2690 emit_init_icall_wrappers (MonoLLVMModule *module)
2692 module->init_method = emit_init_icall_wrapper (module, "init_method", "mono_aot_init_llvm_method", 0);
2693 module->init_method_gshared_mrgctx = emit_init_icall_wrapper (module, "init_method_gshared_mrgctx", "mono_aot_init_gshared_method_mrgctx", 1);
2694 module->init_method_gshared_this = emit_init_icall_wrapper (module, "init_method_gshared_this", "mono_aot_init_gshared_method_this", 2);
2695 module->init_method_gshared_vtable = emit_init_icall_wrapper (module, "init_method_gshared_vtable", "mono_aot_init_gshared_method_vtable", 3);
2699 emit_llvm_code_end (MonoLLVMModule *module)
2701 LLVMModuleRef lmodule = module->lmodule;
2703 LLVMBasicBlockRef entry_bb;
2704 LLVMBuilderRef builder;
2706 func = LLVMAddFunction (lmodule, "llvm_code_end", LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE));
2707 LLVMSetLinkage (func, LLVMInternalLinkage);
2708 LLVMAddFunctionAttr (func, LLVMNoUnwindAttribute);
2709 module->code_end = func;
2710 entry_bb = LLVMAppendBasicBlock (func, "ENTRY");
2711 builder = LLVMCreateBuilder ();
2712 LLVMPositionBuilderAtEnd (builder, entry_bb);
2713 LLVMBuildRetVoid (builder);
2714 LLVMDisposeBuilder (builder);
2718 emit_div_check (EmitContext *ctx, LLVMBuilderRef builder, MonoBasicBlock *bb, MonoInst *ins, LLVMValueRef lhs, LLVMValueRef rhs)
2720 gboolean need_div_check = ctx->cfg->backend->need_div_check;
2723 /* LLVM doesn't know that these can throw an exception since they are not called through an intrinsic */
2724 need_div_check = TRUE;
2726 if (!need_div_check)
2729 switch (ins->opcode) {
2742 case OP_IDIV_UN_IMM:
2743 case OP_LDIV_UN_IMM:
2744 case OP_IREM_UN_IMM:
2745 case OP_LREM_UN_IMM: {
2747 gboolean is_signed = (ins->opcode == OP_IDIV || ins->opcode == OP_LDIV || ins->opcode == OP_IREM || ins->opcode == OP_LREM ||
2748 ins->opcode == OP_IDIV_IMM || ins->opcode == OP_LDIV_IMM || ins->opcode == OP_IREM_IMM || ins->opcode == OP_LREM_IMM);
2750 cmp = LLVMBuildICmp (builder, LLVMIntEQ, rhs, LLVMConstInt (LLVMTypeOf (rhs), 0, FALSE), "");
2751 emit_cond_system_exception (ctx, bb, "DivideByZeroException", cmp);
2754 builder = ctx->builder;
2756 /* b == -1 && a == 0x80000000 */
2758 LLVMValueRef c = (LLVMTypeOf (lhs) == LLVMInt32Type ()) ? LLVMConstInt (LLVMTypeOf (lhs), 0x80000000, FALSE) : LLVMConstInt (LLVMTypeOf (lhs), 0x8000000000000000LL, FALSE);
2759 LLVMValueRef cond1 = LLVMBuildICmp (builder, LLVMIntEQ, rhs, LLVMConstInt (LLVMTypeOf (rhs), -1, FALSE), "");
2760 LLVMValueRef cond2 = LLVMBuildICmp (builder, LLVMIntEQ, lhs, c, "");
2762 cmp = LLVMBuildICmp (builder, LLVMIntEQ, LLVMBuildAnd (builder, cond1, cond2, ""), LLVMConstInt (LLVMInt1Type (), 1, FALSE), "");
2763 emit_cond_system_exception (ctx, bb, "OverflowException", cmp);
2766 builder = ctx->builder;
2778 * Emit code to initialize the GOT slots used by the method.
2781 emit_init_method (EmitContext *ctx)
2783 LLVMValueRef indexes [16], args [16], callee;
2784 LLVMValueRef inited_var, cmp, call;
2785 LLVMBasicBlockRef inited_bb, notinited_bb;
2786 LLVMBuilderRef builder = ctx->builder;
2787 MonoCompile *cfg = ctx->cfg;
2789 ctx->module->max_inited_idx = MAX (ctx->module->max_inited_idx, cfg->method_index);
2791 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
2792 indexes [1] = LLVMConstInt (LLVMInt32Type (), cfg->method_index, FALSE);
2793 inited_var = LLVMBuildLoad (builder, LLVMBuildGEP (builder, ctx->module->inited_var, indexes, 2, ""), "is_inited");
2795 args [0] = inited_var;
2796 args [1] = LLVMConstInt (LLVMInt8Type (), 1, FALSE);
2797 inited_var = LLVMBuildCall (ctx->builder, get_intrinsic (ctx, "llvm.expect.i8"), args, 2, "");
2799 cmp = LLVMBuildICmp (builder, LLVMIntEQ, inited_var, LLVMConstInt (LLVMTypeOf (inited_var), 0, FALSE), "");
2801 inited_bb = ctx->inited_bb;
2802 notinited_bb = gen_bb (ctx, "NOTINITED_BB");
2804 LLVMBuildCondBr (ctx->builder, cmp, notinited_bb, inited_bb);
2806 builder = ctx->builder = create_builder (ctx);
2807 LLVMPositionBuilderAtEnd (ctx->builder, notinited_bb);
2810 if (ctx->rgctx_arg && cfg->method->is_inflated && mono_method_get_context (cfg->method)->method_inst) {
2811 args [0] = LLVMConstInt (LLVMInt32Type (), cfg->method_index, 0);
2812 args [1] = convert (ctx, ctx->rgctx_arg, IntPtrType ());
2813 callee = ctx->module->init_method_gshared_mrgctx;
2814 call = LLVMBuildCall (builder, callee, args, 2, "");
2815 } else if (ctx->rgctx_arg) {
2816 /* A vtable is passed as the rgctx argument */
2817 args [0] = LLVMConstInt (LLVMInt32Type (), cfg->method_index, 0);
2818 args [1] = convert (ctx, ctx->rgctx_arg, IntPtrType ());
2819 callee = ctx->module->init_method_gshared_vtable;
2820 call = LLVMBuildCall (builder, callee, args, 2, "");
2821 } else if (cfg->gshared) {
2822 args [0] = LLVMConstInt (LLVMInt32Type (), cfg->method_index, 0);
2823 args [1] = convert (ctx, ctx->this_arg, ObjRefType ());
2824 callee = ctx->module->init_method_gshared_this;
2825 call = LLVMBuildCall (builder, callee, args, 2, "");
2827 args [0] = LLVMConstInt (LLVMInt32Type (), cfg->method_index, 0);
2828 callee = ctx->module->init_method;
2829 call = LLVMBuildCall (builder, callee, args, 1, "");
2833 * This enables llvm to keep arguments in their original registers/
2834 * scratch registers, since the call will not clobber them.
2836 mono_llvm_set_call_preserveall_cc (call);
2838 LLVMBuildBr (builder, inited_bb);
2839 ctx->bblocks [cfg->bb_entry->block_num].end_bblock = inited_bb;
2841 builder = ctx->builder = create_builder (ctx);
2842 LLVMPositionBuilderAtEnd (ctx->builder, inited_bb);
2846 emit_unbox_tramp (EmitContext *ctx, const char *method_name, LLVMTypeRef method_type, LLVMValueRef method, int method_index)
2849 * Emit unbox trampoline using a tail call
2851 LLVMValueRef tramp, call, *args;
2852 LLVMBuilderRef builder;
2853 LLVMBasicBlockRef lbb;
2854 LLVMCallInfo *linfo;
2858 tramp_name = g_strdup_printf ("ut_%s", method_name);
2859 tramp = LLVMAddFunction (ctx->module->lmodule, tramp_name, method_type);
2860 LLVMSetLinkage (tramp, LLVMInternalLinkage);
2861 LLVMAddFunctionAttr (tramp, LLVMOptimizeForSizeAttribute);
2862 //LLVMAddFunctionAttr (tramp, LLVMNoUnwindAttribute);
2864 // FIXME: Reduce code duplication with mono_llvm_compile_method () etc.
2865 if (!ctx->llvm_only && ctx->rgctx_arg_pindex != -1)
2866 LLVMAddAttribute (LLVMGetParam (tramp, ctx->rgctx_arg_pindex), LLVMInRegAttribute);
2867 if (ctx->cfg->vret_addr) {
2868 LLVMSetValueName (LLVMGetParam (tramp, linfo->vret_arg_pindex), "vret");
2869 if (linfo->ret.storage == LLVMArgVtypeByRef) {
2870 LLVMAddAttribute (LLVMGetParam (tramp, linfo->vret_arg_pindex), LLVMStructRetAttribute);
2871 LLVMAddAttribute (LLVMGetParam (tramp, linfo->vret_arg_pindex), LLVMNoAliasAttribute);
2875 lbb = LLVMAppendBasicBlock (tramp, "");
2876 builder = LLVMCreateBuilder ();
2877 LLVMPositionBuilderAtEnd (builder, lbb);
2879 nargs = LLVMCountParamTypes (method_type);
2880 args = g_new0 (LLVMValueRef, nargs);
2881 for (i = 0; i < nargs; ++i) {
2882 args [i] = LLVMGetParam (tramp, i);
2883 if (i == ctx->this_arg_pindex) {
2884 LLVMTypeRef arg_type = LLVMTypeOf (args [i]);
2886 args [i] = LLVMBuildPtrToInt (builder, args [i], IntPtrType (), "");
2887 args [i] = LLVMBuildAdd (builder, args [i], LLVMConstInt (IntPtrType (), sizeof (MonoObject), FALSE), "");
2888 args [i] = LLVMBuildIntToPtr (builder, args [i], arg_type, "");
2891 call = LLVMBuildCall (builder, method, args, nargs, "");
2892 if (!ctx->llvm_only && ctx->rgctx_arg_pindex != -1)
2893 LLVMAddInstrAttribute (call, 1 + ctx->rgctx_arg_pindex, LLVMInRegAttribute);
2894 if (linfo->ret.storage == LLVMArgVtypeByRef)
2895 LLVMAddInstrAttribute (call, 1 + linfo->vret_arg_pindex, LLVMStructRetAttribute);
2897 // FIXME: This causes assertions in clang
2898 //mono_llvm_set_must_tail (call);
2899 if (LLVMGetReturnType (method_type) == LLVMVoidType ())
2900 LLVMBuildRetVoid (builder);
2902 LLVMBuildRet (builder, call);
2904 g_hash_table_insert (ctx->module->idx_to_unbox_tramp, GINT_TO_POINTER (method_index), tramp);
2905 LLVMDisposeBuilder (builder);
2911 * Emit code to load/convert arguments.
2914 emit_entry_bb (EmitContext *ctx, LLVMBuilderRef builder)
2917 MonoCompile *cfg = ctx->cfg;
2918 MonoMethodSignature *sig = ctx->sig;
2919 LLVMCallInfo *linfo = ctx->linfo;
2923 LLVMBuilderRef old_builder = ctx->builder;
2924 ctx->builder = builder;
2926 ctx->alloca_builder = create_builder (ctx);
2929 * Handle indirect/volatile variables by allocating memory for them
2930 * using 'alloca', and storing their address in a temporary.
2932 for (i = 0; i < cfg->num_varinfo; ++i) {
2933 MonoInst *var = cfg->varinfo [i];
2936 if (var->opcode == OP_GSHAREDVT_LOCAL || var->opcode == OP_GSHAREDVT_ARG_REGOFFSET) {
2937 } 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))) {
2938 vtype = type_to_llvm_type (ctx, var->inst_vtype);
2941 /* Could be already created by an OP_VPHI */
2942 if (!ctx->addresses [var->dreg]) {
2943 ctx->addresses [var->dreg] = build_alloca (ctx, var->inst_vtype);
2944 //LLVMSetValueName (ctx->addresses [var->dreg], g_strdup_printf ("vreg_loc_%d", var->dreg));
2946 ctx->vreg_cli_types [var->dreg] = var->inst_vtype;
2950 names = g_new (char *, sig->param_count);
2951 mono_method_get_param_names (cfg->method, (const char **) names);
2953 for (i = 0; i < sig->param_count; ++i) {
2954 LLVMArgInfo *ainfo = &linfo->args [i + sig->hasthis];
2955 int reg = cfg->args [i + sig->hasthis]->dreg;
2958 pindex = ainfo->pindex;
2960 switch (ainfo->storage) {
2961 case LLVMArgVtypeInReg:
2962 case LLVMArgAsFpArgs: {
2963 LLVMValueRef args [8];
2966 pindex += ainfo->ndummy_fpargs;
2968 /* The argument is received as a set of int/fp arguments, store them into the real argument */
2969 memset (args, 0, sizeof (args));
2970 if (ainfo->storage == LLVMArgVtypeInReg) {
2971 args [0] = LLVMGetParam (ctx->lmethod, pindex);
2972 if (ainfo->pair_storage [1] != LLVMArgNone)
2973 args [1] = LLVMGetParam (ctx->lmethod, pindex + 1);
2975 g_assert (ainfo->nslots <= 8);
2976 for (j = 0; j < ainfo->nslots; ++j)
2977 args [j] = LLVMGetParam (ctx->lmethod, pindex + j);
2979 ctx->addresses [reg] = build_alloca (ctx, ainfo->type);
2981 emit_args_to_vtype (ctx, builder, ainfo->type, ctx->addresses [reg], ainfo, args);
2983 if (ainfo->storage == LLVMArgVtypeInReg && MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (ainfo->type))) {
2984 /* Treat these as normal values */
2985 ctx->values [reg] = LLVMBuildLoad (builder, ctx->addresses [reg], "");
2989 case LLVMArgVtypeByVal: {
2990 ctx->addresses [reg] = LLVMGetParam (ctx->lmethod, pindex);
2992 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (ainfo->type))) {
2993 /* Treat these as normal values */
2994 ctx->values [reg] = LLVMBuildLoad (builder, ctx->addresses [reg], "");
2998 case LLVMArgVtypeByRef: {
2999 /* The argument is passed by ref */
3000 ctx->addresses [reg] = LLVMGetParam (ctx->lmethod, pindex);
3003 case LLVMArgAsIArgs: {
3004 LLVMValueRef arg = LLVMGetParam (ctx->lmethod, pindex);
3007 /* The argument is received as an array of ints, store it into the real argument */
3008 ctx->addresses [reg] = build_alloca (ctx, ainfo->type);
3010 size = mono_class_value_size (mono_class_from_mono_type (ainfo->type), NULL);
3011 if (size < SIZEOF_VOID_P) {
3012 /* The upper bits of the registers might not be valid */
3013 LLVMValueRef val = LLVMBuildExtractValue (builder, arg, 0, "");
3014 LLVMValueRef dest = convert (ctx, ctx->addresses [reg], LLVMPointerType (LLVMIntType (size * 8), 0));
3015 LLVMBuildStore (ctx->builder, LLVMBuildTrunc (builder, val, LLVMIntType (size * 8), ""), dest);
3017 LLVMBuildStore (ctx->builder, arg, convert (ctx, ctx->addresses [reg], LLVMPointerType (LLVMTypeOf (arg), 0)));
3021 case LLVMArgVtypeAsScalar:
3022 g_assert_not_reached ();
3024 case LLVMArgGsharedvtFixed: {
3025 /* These are non-gsharedvt arguments passed by ref, the rest of the IR treats them as scalars */
3026 LLVMValueRef arg = LLVMGetParam (ctx->lmethod, pindex);
3029 name = g_strdup_printf ("arg_%s", names [i]);
3031 name = g_strdup_printf ("arg_%d", i);
3033 ctx->values [reg] = LLVMBuildLoad (builder, convert (ctx, arg, LLVMPointerType (type_to_llvm_type (ctx, ainfo->type), 0)), name);
3036 case LLVMArgGsharedvtFixedVtype: {
3037 LLVMValueRef arg = LLVMGetParam (ctx->lmethod, pindex);
3040 name = g_strdup_printf ("vtype_arg_%s", names [i]);
3042 name = g_strdup_printf ("vtype_arg_%d", i);
3044 /* Non-gsharedvt vtype argument passed by ref, the rest of the IR treats it as a vtype */
3045 g_assert (ctx->addresses [reg]);
3046 LLVMSetValueName (ctx->addresses [reg], name);
3047 LLVMBuildStore (builder, LLVMBuildLoad (builder, convert (ctx, arg, LLVMPointerType (type_to_llvm_type (ctx, ainfo->type), 0)), ""), ctx->addresses [reg]);
3050 case LLVMArgGsharedvtVariable:
3051 /* The IR treats these as variables with addresses */
3052 ctx->addresses [reg] = LLVMGetParam (ctx->lmethod, pindex);
3055 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));
3062 emit_volatile_store (ctx, cfg->vret_addr->dreg);
3064 emit_volatile_store (ctx, cfg->args [0]->dreg);
3065 for (i = 0; i < sig->param_count; ++i)
3066 if (!mini_type_is_vtype (sig->params [i]))
3067 emit_volatile_store (ctx, cfg->args [i + sig->hasthis]->dreg);
3069 if (sig->hasthis && !cfg->rgctx_var && cfg->gshared) {
3070 LLVMValueRef this_alloc;
3073 * The exception handling code needs the location where the this argument was
3074 * stored for gshared methods. We create a separate alloca to hold it, and mark it
3075 * with the "mono.this" custom metadata to tell llvm that it needs to save its
3076 * location into the LSDA.
3078 this_alloc = mono_llvm_build_alloca (builder, ThisType (), LLVMConstInt (LLVMInt32Type (), 1, FALSE), 0, "");
3079 /* This volatile store will keep the alloca alive */
3080 mono_llvm_build_store (builder, ctx->values [cfg->args [0]->dreg], this_alloc, TRUE, LLVM_BARRIER_NONE);
3082 set_metadata_flag (this_alloc, "mono.this");
3085 if (cfg->rgctx_var) {
3086 LLVMValueRef rgctx_alloc, store;
3089 * We handle the rgctx arg similarly to the this pointer.
3091 g_assert (ctx->addresses [cfg->rgctx_var->dreg]);
3092 rgctx_alloc = ctx->addresses [cfg->rgctx_var->dreg];
3093 /* This volatile store will keep the alloca alive */
3094 store = mono_llvm_build_store (builder, convert (ctx, ctx->rgctx_arg, IntPtrType ()), rgctx_alloc, TRUE, LLVM_BARRIER_NONE);
3096 set_metadata_flag (rgctx_alloc, "mono.this");
3099 /* Initialize the method if needed */
3100 if (cfg->compile_aot && ctx->llvm_only) {
3101 /* Emit a location for the initialization code */
3102 ctx->init_bb = gen_bb (ctx, "INIT_BB");
3103 ctx->inited_bb = gen_bb (ctx, "INITED_BB");
3105 LLVMBuildBr (ctx->builder, ctx->init_bb);
3106 builder = ctx->builder = create_builder (ctx);
3107 LLVMPositionBuilderAtEnd (ctx->builder, ctx->inited_bb);
3108 ctx->bblocks [cfg->bb_entry->block_num].end_bblock = ctx->inited_bb;
3111 /* Compute nesting between clauses */
3112 ctx->nested_in = (GSList**)mono_mempool_alloc0 (cfg->mempool, sizeof (GSList*) * cfg->header->num_clauses);
3113 for (i = 0; i < cfg->header->num_clauses; ++i) {
3114 for (j = 0; j < cfg->header->num_clauses; ++j) {
3115 MonoExceptionClause *clause1 = &cfg->header->clauses [i];
3116 MonoExceptionClause *clause2 = &cfg->header->clauses [j];
3118 if (i != j && clause1->try_offset >= clause2->try_offset && clause1->handler_offset <= clause2->handler_offset)
3119 ctx->nested_in [i] = g_slist_prepend_mempool (cfg->mempool, ctx->nested_in [i], GINT_TO_POINTER (j));
3124 * For finally clauses, create an indicator variable telling OP_ENDFINALLY whenever
3125 * it needs to continue normally, or return back to the exception handling system.
3127 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
3131 if (!(bb->region != -1 && (bb->flags & BB_EXCEPTION_HANDLER)))
3134 clause_index = MONO_REGION_CLAUSE_INDEX (bb->region);
3135 g_hash_table_insert (ctx->region_to_handler, GUINT_TO_POINTER (mono_get_block_region_notry (cfg, bb->region)), bb);
3136 g_hash_table_insert (ctx->clause_to_handler, GINT_TO_POINTER (clause_index), bb);
3138 if (bb->in_scount == 0) {
3141 sprintf (name, "finally_ind_bb%d", bb->block_num);
3142 val = LLVMBuildAlloca (builder, LLVMInt32Type (), name);
3143 LLVMBuildStore (builder, LLVMConstInt (LLVMInt32Type (), 0, FALSE), val);
3145 ctx->bblocks [bb->block_num].finally_ind = val;
3147 /* Create a variable to hold the exception var */
3149 ctx->ex_var = LLVMBuildAlloca (builder, ObjRefType (), "exvar");
3153 * Create a new bblock which CALL_HANDLER/landing pads can branch to, because branching to the
3154 * LLVM bblock containing a landing pad causes problems for the
3155 * LLVM optimizer passes.
3157 sprintf (name, "BB%d_CALL_HANDLER_TARGET", bb->block_num);
3158 ctx->bblocks [bb->block_num].call_handler_target_bb = LLVMAppendBasicBlock (ctx->lmethod, name);
3160 ctx->builder = old_builder;
3164 process_call (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, MonoInst *ins)
3166 MonoCompile *cfg = ctx->cfg;
3167 LLVMValueRef *values = ctx->values;
3168 LLVMValueRef *addresses = ctx->addresses;
3169 MonoCallInst *call = (MonoCallInst*)ins;
3170 MonoMethodSignature *sig = call->signature;
3171 LLVMValueRef callee = NULL, lcall;
3173 LLVMCallInfo *cinfo;
3177 LLVMTypeRef llvm_sig;
3179 gboolean is_virtual, calli, preserveall;
3180 LLVMBuilderRef builder = *builder_ref;
3182 if ((call->signature->call_convention != MONO_CALL_DEFAULT) && !((call->signature->call_convention == MONO_CALL_C) && ctx->llvm_only)) {
3183 set_failure (ctx, "non-default callconv");
3187 cinfo = call->cinfo;
3189 if (call->rgctx_arg_reg)
3190 cinfo->rgctx_arg = TRUE;
3191 if (call->imt_arg_reg)
3192 cinfo->imt_arg = TRUE;
3194 vretaddr = (cinfo->ret.storage == LLVMArgVtypeRetAddr || cinfo->ret.storage == LLVMArgVtypeByRef || cinfo->ret.storage == LLVMArgGsharedvtFixed || cinfo->ret.storage == LLVMArgGsharedvtVariable || cinfo->ret.storage == LLVMArgGsharedvtFixedVtype);
3196 llvm_sig = sig_to_llvm_sig_full (ctx, sig, cinfo);
3200 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);
3201 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);
3203 preserveall = FALSE;
3205 /* FIXME: Avoid creating duplicate methods */
3207 if (ins->flags & MONO_INST_HAS_METHOD) {
3211 if (cfg->compile_aot) {
3212 callee = get_callee (ctx, llvm_sig, MONO_PATCH_INFO_METHOD, call->method);
3214 set_failure (ctx, "can't encode patch");
3217 if (cfg->llvm_only && call->method->klass->image->assembly == ctx->module->assembly) {
3219 * Collect instructions representing the callee into a hash so they can be replaced
3220 * by the llvm method for the callee if the callee turns out to be direct
3221 * callable. Currently this only requires it to not fail llvm compilation.
3223 GSList *l = (GSList*)g_hash_table_lookup (ctx->method_to_callers, call->method);
3224 l = g_slist_prepend (l, callee);
3225 g_hash_table_insert (ctx->method_to_callers, call->method, l);
3229 static int tramp_index;
3232 name = g_strdup_printf ("tramp_%d", tramp_index);
3235 #if LLVM_API_VERSION > 100
3237 * Use our trampoline infrastructure for lazy compilation instead of llvm's.
3238 * Make all calls through a global. The address of the global will be saved in
3239 * MonoJitDomainInfo.llvm_jit_callees and updated when the method it refers to is
3242 LLVMValueRef tramp_var = g_hash_table_lookup (ctx->jit_callees, call->method);
3245 mono_create_jit_trampoline (mono_domain_get (),
3246 call->method, &error);
3247 if (!is_ok (&error)) {
3248 set_failure (ctx, mono_error_get_message (&error));
3249 mono_error_cleanup (&error);
3253 tramp_var = LLVMAddGlobal (ctx->lmodule, LLVMPointerType (llvm_sig, 0), name);
3254 LLVMSetInitializer (tramp_var, LLVMConstIntToPtr (LLVMConstInt (LLVMInt64Type (), (guint64)(size_t)target, FALSE), LLVMPointerType (llvm_sig, 0)));
3255 LLVMSetLinkage (tramp_var, LLVMExternalLinkage);
3256 g_hash_table_insert (ctx->jit_callees, call->method, tramp_var);
3258 callee = LLVMBuildLoad (builder, tramp_var, "");
3261 mono_create_jit_trampoline (mono_domain_get (),
3262 call->method, &error);
3263 if (!is_ok (&error)) {
3265 set_failure (ctx, mono_error_get_message (&error));
3266 mono_error_cleanup (&error);
3270 callee = LLVMAddFunction (ctx->lmodule, name, llvm_sig);
3273 LLVMAddGlobalMapping (ctx->module->ee, callee, target);
3278 if (!cfg->llvm_only && call->method && strstr (call->method->klass->name, "AsyncVoidMethodBuilder")) {
3279 /* LLVM miscompiles async methods */
3280 set_failure (ctx, "#13734");
3285 MonoJitICallInfo *info = mono_find_jit_icall_by_addr (call->fptr);
3291 memset (&ji, 0, sizeof (ji));
3292 ji.type = MONO_PATCH_INFO_JIT_ICALL_ADDR;
3293 ji.data.target = info->name;
3295 target = mono_resolve_patch_target (cfg->method, cfg->domain, NULL, &ji, FALSE);
3297 if (cfg->compile_aot) {
3298 callee = get_callee (ctx, llvm_sig, MONO_PATCH_INFO_INTERNAL_METHOD, (char*)info->name);
3300 set_failure (ctx, "can't encode patch");
3304 target = (gpointer)mono_icall_get_wrapper (info);
3305 callee = emit_jit_callee (ctx, "", llvm_sig, target);
3308 if (cfg->compile_aot) {
3310 if (cfg->abs_patches) {
3311 MonoJumpInfo *abs_ji = (MonoJumpInfo*)g_hash_table_lookup (cfg->abs_patches, call->fptr);
3313 callee = get_callee (ctx, llvm_sig, abs_ji->type, abs_ji->data.target);
3315 set_failure (ctx, "can't encode patch");
3321 set_failure (ctx, "aot");
3325 #if LLVM_API_VERSION > 100
3326 if (cfg->abs_patches) {
3327 MonoJumpInfo *abs_ji = (MonoJumpInfo*)g_hash_table_lookup (cfg->abs_patches, call->fptr);
3331 target = mono_resolve_patch_target (cfg->method, cfg->domain, NULL, abs_ji, FALSE, &error);
3332 mono_error_assert_ok (&error);
3333 callee = emit_jit_callee (ctx, "", llvm_sig, target);
3335 g_assert_not_reached ();
3338 g_assert_not_reached ();
3341 callee = LLVMAddFunction (ctx->lmodule, "", llvm_sig);
3343 if (cfg->abs_patches) {
3344 MonoJumpInfo *abs_ji = (MonoJumpInfo*)g_hash_table_lookup (cfg->abs_patches, call->fptr);
3349 * FIXME: Some trampolines might have
3350 * their own calling convention on some platforms.
3352 target = mono_resolve_patch_target (cfg->method, cfg->domain, NULL, abs_ji, FALSE, &error);
3353 mono_error_assert_ok (&error);
3354 LLVMAddGlobalMapping (ctx->module->ee, callee, target);
3358 LLVMAddGlobalMapping (ctx->module->ee, callee, (gpointer)call->fptr);
3365 int size = sizeof (gpointer);
3368 g_assert (ins->inst_offset % size == 0);
3369 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
3371 callee = convert (ctx, LLVMBuildLoad (builder, LLVMBuildGEP (builder, convert (ctx, values [ins->inst_basereg], LLVMPointerType (LLVMPointerType (IntPtrType (), 0), 0)), &index, 1, ""), ""), LLVMPointerType (llvm_sig, 0));
3373 callee = convert (ctx, values [ins->sreg1], LLVMPointerType (llvm_sig, 0));
3375 if (ins->flags & MONO_INST_HAS_METHOD) {
3380 * Collect and convert arguments
3382 nargs = (sig->param_count * 16) + sig->hasthis + vretaddr + call->rgctx_reg + call->imt_arg_reg;
3383 len = sizeof (LLVMValueRef) * nargs;
3384 args = (LLVMValueRef*)alloca (len);
3385 memset (args, 0, len);
3386 l = call->out_ireg_args;
3388 if (call->rgctx_arg_reg) {
3389 g_assert (values [call->rgctx_arg_reg]);
3390 g_assert (cinfo->rgctx_arg_pindex < nargs);
3392 * On ARM, the imt/rgctx argument is passed in a caller save register, but some of our trampolines etc. clobber it, leading to
3393 * problems is LLVM moves the arg assignment earlier. To work around this, save the argument into a stack slot and load
3394 * it using a volatile load.
3397 if (!ctx->imt_rgctx_loc)
3398 ctx->imt_rgctx_loc = build_alloca_llvm_type (ctx, ctx->module->ptr_type, sizeof (gpointer));
3399 LLVMBuildStore (builder, convert (ctx, ctx->values [call->rgctx_arg_reg], ctx->module->ptr_type), ctx->imt_rgctx_loc);
3400 args [cinfo->rgctx_arg_pindex] = mono_llvm_build_load (builder, ctx->imt_rgctx_loc, "", TRUE);
3402 args [cinfo->rgctx_arg_pindex] = convert (ctx, values [call->rgctx_arg_reg], ctx->module->ptr_type);
3405 if (call->imt_arg_reg) {
3406 g_assert (!ctx->llvm_only);
3407 g_assert (values [call->imt_arg_reg]);
3408 g_assert (cinfo->imt_arg_pindex < nargs);
3410 if (!ctx->imt_rgctx_loc)
3411 ctx->imt_rgctx_loc = build_alloca_llvm_type (ctx, ctx->module->ptr_type, sizeof (gpointer));
3412 LLVMBuildStore (builder, convert (ctx, ctx->values [call->imt_arg_reg], ctx->module->ptr_type), ctx->imt_rgctx_loc);
3413 args [cinfo->imt_arg_pindex] = mono_llvm_build_load (builder, ctx->imt_rgctx_loc, "", TRUE);
3415 args [cinfo->imt_arg_pindex] = convert (ctx, values [call->imt_arg_reg], ctx->module->ptr_type);
3418 switch (cinfo->ret.storage) {
3419 case LLVMArgGsharedvtVariable: {
3420 MonoInst *var = get_vreg_to_inst (cfg, call->inst.dreg);
3422 if (var && var->opcode == OP_GSHAREDVT_LOCAL) {
3423 args [cinfo->vret_arg_pindex] = convert (ctx, emit_gsharedvt_ldaddr (ctx, var->dreg), IntPtrType ());
3425 g_assert (addresses [call->inst.dreg]);
3426 args [cinfo->vret_arg_pindex] = addresses [call->inst.dreg];
3432 if (!addresses [call->inst.dreg])
3433 addresses [call->inst.dreg] = build_alloca (ctx, sig->ret);
3434 g_assert (cinfo->vret_arg_pindex < nargs);
3435 if (cinfo->ret.storage == LLVMArgVtypeByRef)
3436 args [cinfo->vret_arg_pindex] = addresses [call->inst.dreg];
3438 args [cinfo->vret_arg_pindex] = LLVMBuildPtrToInt (builder, addresses [call->inst.dreg], IntPtrType (), "");
3444 * Sometimes the same method is called with two different signatures (i.e. with and without 'this'), so
3445 * use the real callee for argument type conversion.
3447 LLVMTypeRef callee_type = LLVMGetElementType (LLVMTypeOf (callee));
3448 LLVMTypeRef *param_types = (LLVMTypeRef*)g_alloca (sizeof (LLVMTypeRef) * LLVMCountParamTypes (callee_type));
3449 LLVMGetParamTypes (callee_type, param_types);
3451 for (i = 0; i < sig->param_count + sig->hasthis; ++i) {
3454 LLVMArgInfo *ainfo = &call->cinfo->args [i];
3456 pindex = ainfo->pindex;
3458 regpair = (guint32)(gssize)(l->data);
3459 reg = regpair & 0xffffff;
3460 args [pindex] = values [reg];
3461 switch (ainfo->storage) {
3462 case LLVMArgVtypeInReg:
3463 case LLVMArgAsFpArgs: {
3467 for (j = 0; j < ainfo->ndummy_fpargs; ++j)
3468 args [pindex + j] = LLVMConstNull (LLVMDoubleType ());
3469 pindex += ainfo->ndummy_fpargs;
3471 g_assert (addresses [reg]);
3472 emit_vtype_to_args (ctx, builder, ainfo->type, addresses [reg], ainfo, args + pindex, &nargs);
3476 // FIXME: Get rid of the VMOVE
3479 case LLVMArgVtypeByVal:
3480 g_assert (addresses [reg]);
3481 args [pindex] = addresses [reg];
3483 case LLVMArgVtypeByRef: {
3484 g_assert (addresses [reg]);
3485 args [pindex] = convert (ctx, addresses [reg], LLVMPointerType (type_to_llvm_arg_type (ctx, ainfo->type), 0));
3488 case LLVMArgAsIArgs:
3489 g_assert (addresses [reg]);
3490 args [pindex] = LLVMBuildLoad (ctx->builder, convert (ctx, addresses [reg], LLVMPointerType (LLVMArrayType (IntPtrType (), ainfo->nslots), 0)), "");
3492 case LLVMArgVtypeAsScalar:
3493 g_assert_not_reached ();
3495 case LLVMArgGsharedvtFixed:
3496 case LLVMArgGsharedvtFixedVtype:
3497 g_assert (addresses [reg]);
3498 args [pindex] = convert (ctx, addresses [reg], LLVMPointerType (type_to_llvm_arg_type (ctx, ainfo->type), 0));
3500 case LLVMArgGsharedvtVariable:
3501 g_assert (addresses [reg]);
3502 args [pindex] = convert (ctx, addresses [reg], LLVMPointerType (IntPtrType (), 0));
3505 g_assert (args [pindex]);
3506 if (i == 0 && sig->hasthis)
3507 args [pindex] = convert (ctx, args [pindex], param_types [pindex]);
3509 args [pindex] = convert (ctx, args [pindex], type_to_llvm_arg_type (ctx, ainfo->type));
3512 g_assert (pindex <= nargs);
3517 // FIXME: Align call sites
3523 lcall = emit_call (ctx, bb, &builder, callee, args, LLVMCountParamTypes (llvm_sig));
3525 if (ins->opcode != OP_TAILCALL && LLVMGetInstructionOpcode (lcall) == LLVMCall)
3526 mono_llvm_set_call_notail (lcall);
3529 * Modify cconv and parameter attributes to pass rgctx/imt correctly.
3531 #if defined(MONO_ARCH_IMT_REG) && defined(MONO_ARCH_RGCTX_REG)
3532 g_assert (MONO_ARCH_IMT_REG == MONO_ARCH_RGCTX_REG);
3534 /* The two can't be used together, so use only one LLVM calling conv to pass them */
3535 g_assert (!(call->rgctx_arg_reg && call->imt_arg_reg));
3536 if (!sig->pinvoke && !cfg->llvm_only)
3537 LLVMSetInstructionCallConv (lcall, LLVMMono1CallConv);
3539 mono_llvm_set_call_preserveall_cc (lcall);
3541 if (cinfo->ret.storage == LLVMArgVtypeByRef)
3542 LLVMAddInstrAttribute (lcall, 1 + cinfo->vret_arg_pindex, LLVMStructRetAttribute);
3543 if (!ctx->llvm_only && call->rgctx_arg_reg)
3544 LLVMAddInstrAttribute (lcall, 1 + cinfo->rgctx_arg_pindex, LLVMInRegAttribute);
3545 if (call->imt_arg_reg)
3546 LLVMAddInstrAttribute (lcall, 1 + cinfo->imt_arg_pindex, LLVMInRegAttribute);
3548 /* Add byval attributes if needed */
3549 for (i = 0; i < sig->param_count; ++i) {
3550 LLVMArgInfo *ainfo = &call->cinfo->args [i + sig->hasthis];
3552 if (ainfo && ainfo->storage == LLVMArgVtypeByVal)
3553 LLVMAddInstrAttribute (lcall, 1 + ainfo->pindex, LLVMByValAttribute);
3557 * Convert the result
3559 switch (cinfo->ret.storage) {
3560 case LLVMArgVtypeInReg: {
3561 LLVMValueRef regs [2];
3563 if (LLVMTypeOf (lcall) == LLVMVoidType ())
3567 if (!addresses [ins->dreg])
3568 addresses [ins->dreg] = build_alloca (ctx, sig->ret);
3570 regs [0] = LLVMBuildExtractValue (builder, lcall, 0, "");
3571 if (cinfo->ret.pair_storage [1] != LLVMArgNone)
3572 regs [1] = LLVMBuildExtractValue (builder, lcall, 1, "");
3573 emit_args_to_vtype (ctx, builder, sig->ret, addresses [ins->dreg], &cinfo->ret, regs);
3576 case LLVMArgVtypeByVal:
3577 if (!addresses [call->inst.dreg])
3578 addresses [call->inst.dreg] = build_alloca (ctx, sig->ret);
3579 LLVMBuildStore (builder, lcall, addresses [call->inst.dreg]);
3581 case LLVMArgAsIArgs:
3582 case LLVMArgFpStruct:
3583 if (!addresses [call->inst.dreg])
3584 addresses [call->inst.dreg] = build_alloca (ctx, sig->ret);
3585 LLVMBuildStore (builder, lcall, convert_full (ctx, addresses [call->inst.dreg], LLVMPointerType (LLVMTypeOf (lcall), 0), FALSE));
3587 case LLVMArgVtypeAsScalar:
3588 if (!addresses [call->inst.dreg])
3589 addresses [call->inst.dreg] = build_alloca (ctx, sig->ret);
3590 LLVMBuildStore (builder, lcall, convert_full (ctx, addresses [call->inst.dreg], LLVMPointerType (LLVMTypeOf (lcall), 0), FALSE));
3592 case LLVMArgVtypeRetAddr:
3593 case LLVMArgVtypeByRef:
3594 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (sig->ret))) {
3595 /* Some opcodes like STOREX_MEMBASE access these by value */
3596 g_assert (addresses [call->inst.dreg]);
3597 values [ins->dreg] = LLVMBuildLoad (builder, convert_full (ctx, addresses [call->inst.dreg], LLVMPointerType (type_to_llvm_type (ctx, sig->ret), 0), FALSE), "");
3600 case LLVMArgGsharedvtVariable:
3602 case LLVMArgGsharedvtFixed:
3603 case LLVMArgGsharedvtFixedVtype:
3604 values [ins->dreg] = LLVMBuildLoad (builder, convert_full (ctx, addresses [call->inst.dreg], LLVMPointerType (type_to_llvm_type (ctx, sig->ret), 0), FALSE), "");
3607 if (sig->ret->type != MONO_TYPE_VOID)
3608 /* If the method returns an unsigned value, need to zext it */
3609 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));
3613 *builder_ref = ctx->builder;
3617 emit_llvmonly_throw (EmitContext *ctx, MonoBasicBlock *bb, gboolean rethrow, LLVMValueRef exc)
3619 const char *icall_name = rethrow ? "mono_llvm_rethrow_exception" : "mono_llvm_throw_exception";
3620 LLVMValueRef callee = rethrow ? ctx->module->rethrow : ctx->module->throw_icall;
3622 LLVMTypeRef exc_type = type_to_llvm_type (ctx, &mono_get_exception_class ()->byval_arg);
3625 LLVMTypeRef fun_sig = LLVMFunctionType1 (LLVMVoidType (), exc_type, FALSE);
3627 if (ctx->cfg->compile_aot) {
3628 callee = get_callee (ctx, fun_sig, MONO_PATCH_INFO_JIT_ICALL_ADDR, icall_name);
3630 callee = LLVMAddFunction (ctx->lmodule, icall_name, fun_sig);
3631 LLVMAddGlobalMapping (ctx->module->ee, callee, resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name));
3632 mono_memory_barrier ();
3635 ctx->module->rethrow = callee;
3637 ctx->module->throw_icall = callee;
3641 LLVMValueRef args [2];
3643 args [0] = convert (ctx, exc, exc_type);
3644 emit_call (ctx, bb, &ctx->builder, callee, args, 1);
3646 LLVMBuildUnreachable (ctx->builder);
3648 ctx->builder = create_builder (ctx);
3652 emit_throw (EmitContext *ctx, MonoBasicBlock *bb, gboolean rethrow, LLVMValueRef exc)
3654 MonoMethodSignature *throw_sig;
3655 LLVMValueRef callee, arg;
3656 const char *icall_name;
3658 callee = rethrow ? ctx->module->rethrow : ctx->module->throw_icall;
3659 icall_name = rethrow ? "mono_arch_rethrow_exception" : "mono_arch_throw_exception";
3662 throw_sig = mono_metadata_signature_alloc (mono_get_corlib (), 1);
3663 throw_sig->ret = &mono_get_void_class ()->byval_arg;
3664 throw_sig->params [0] = &mono_get_object_class ()->byval_arg;
3665 if (ctx->cfg->compile_aot) {
3666 callee = get_callee (ctx, sig_to_llvm_sig (ctx, throw_sig), MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
3671 * LLVM doesn't push the exception argument, so we need a different
3674 target = resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, rethrow ? "llvm_rethrow_exception_trampoline" : "llvm_throw_exception_trampoline");
3676 target = resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
3678 callee = emit_jit_callee (ctx, icall_name, sig_to_llvm_sig (ctx, throw_sig), target);
3681 mono_memory_barrier ();
3682 #if LLVM_API_VERSION < 100
3684 ctx->module->rethrow = callee;
3686 ctx->module->throw_icall = callee;
3689 arg = convert (ctx, exc, type_to_llvm_type (ctx, &mono_get_object_class ()->byval_arg));
3690 emit_call (ctx, bb, &ctx->builder, callee, &arg, 1);
3694 emit_resume_eh (EmitContext *ctx, MonoBasicBlock *bb)
3696 const char *icall_name = "mono_llvm_resume_exception";
3697 LLVMValueRef callee = ctx->module->resume_eh;
3699 LLVMTypeRef fun_sig = LLVMFunctionType0 (LLVMVoidType (), FALSE);
3702 if (ctx->cfg->compile_aot) {
3703 callee = get_callee (ctx, fun_sig, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
3705 callee = LLVMAddFunction (ctx->lmodule, icall_name, fun_sig);
3706 LLVMAddGlobalMapping (ctx->module->ee, callee, resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name));
3707 mono_memory_barrier ();
3709 ctx->module->resume_eh = callee;
3713 emit_call (ctx, bb, &ctx->builder, callee, NULL, 0);
3715 LLVMBuildUnreachable (ctx->builder);
3717 ctx->builder = create_builder (ctx);
3721 mono_llvm_emit_clear_exception_call (EmitContext *ctx, LLVMBuilderRef builder)
3723 const char *icall_name = "mono_llvm_clear_exception";
3725 LLVMTypeRef call_sig = LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE);
3726 LLVMValueRef callee = NULL;
3729 if (ctx->cfg->compile_aot) {
3730 callee = get_callee (ctx, call_sig, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
3732 // FIXME: This is broken.
3733 callee = LLVMAddFunction (ctx->lmodule, icall_name, call_sig);
3737 g_assert (builder && callee);
3739 return LLVMBuildCall (builder, callee, NULL, 0, "");
3743 mono_llvm_emit_load_exception_call (EmitContext *ctx, LLVMBuilderRef builder)
3745 const char *icall_name = "mono_llvm_load_exception";
3747 LLVMTypeRef call_sig = LLVMFunctionType (ObjRefType (), NULL, 0, FALSE);
3748 LLVMValueRef callee = NULL;
3751 if (ctx->cfg->compile_aot) {
3752 callee = get_callee (ctx, call_sig, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
3754 // FIXME: This is broken.
3755 callee = LLVMAddFunction (ctx->lmodule, icall_name, call_sig);
3759 g_assert (builder && callee);
3761 return LLVMBuildCall (builder, callee, NULL, 0, icall_name);
3766 mono_llvm_emit_match_exception_call (EmitContext *ctx, LLVMBuilderRef builder, gint32 region_start, gint32 region_end)
3768 const char *icall_name = "mono_llvm_match_exception";
3770 ctx->builder = builder;
3772 const int num_args = 5;
3773 LLVMValueRef args [num_args];
3774 args [0] = convert (ctx, get_aotconst (ctx, MONO_PATCH_INFO_AOT_JIT_INFO, GINT_TO_POINTER (ctx->cfg->method_index)), IntPtrType ());
3775 args [1] = LLVMConstInt (LLVMInt32Type (), region_start, 0);
3776 args [2] = LLVMConstInt (LLVMInt32Type (), region_end, 0);
3777 if (ctx->cfg->rgctx_var) {
3778 LLVMValueRef rgctx_alloc = ctx->addresses [ctx->cfg->rgctx_var->dreg];
3779 g_assert (rgctx_alloc);
3780 args [3] = LLVMBuildLoad (builder, convert (ctx, rgctx_alloc, LLVMPointerType (IntPtrType (), 0)), "");
3782 args [3] = LLVMConstInt (IntPtrType (), 0, 0);
3785 args [4] = convert (ctx, ctx->this_arg, IntPtrType ());
3787 args [4] = LLVMConstInt (IntPtrType (), 0, 0);
3789 LLVMTypeRef match_sig = LLVMFunctionType5 (LLVMInt32Type (), IntPtrType (), LLVMInt32Type (), LLVMInt32Type (), IntPtrType (), IntPtrType (), FALSE);
3790 LLVMValueRef callee = ctx->module->match_exc;
3793 if (ctx->cfg->compile_aot) {
3794 ctx->builder = builder;
3795 // get_callee expects ctx->builder to be the emitting builder
3796 callee = get_callee (ctx, match_sig, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
3798 callee = ctx->module->match_exc = LLVMAddFunction (ctx->lmodule, icall_name, match_sig);
3799 LLVMAddGlobalMapping (ctx->module->ee, ctx->module->match_exc, resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name));
3800 ctx->module->match_exc = callee;
3801 mono_memory_barrier ();
3805 g_assert (builder && callee);
3807 g_assert (ctx->ex_var);
3809 return LLVMBuildCall (builder, callee, args, num_args, icall_name);
3812 // FIXME: This won't work because the code-finding makes this
3814 /*#define MONO_PERSONALITY_DEBUG*/
3816 #ifdef MONO_PERSONALITY_DEBUG
3817 static const gboolean use_debug_personality = TRUE;
3818 static const char *default_personality_name = "mono_debug_personality";
3820 static const gboolean use_debug_personality = FALSE;
3821 static const char *default_personality_name = "__gxx_personality_v0";
3825 default_cpp_lpad_exc_signature (void)
3827 static gboolean inited = FALSE;
3828 static LLVMTypeRef sig;
3831 LLVMTypeRef signature [2];
3832 signature [0] = LLVMPointerType (LLVMInt8Type (), 0);
3833 signature [1] = LLVMInt32Type ();
3834 sig = LLVMStructType (signature, 2, FALSE);
3842 get_mono_personality (EmitContext *ctx)
3844 LLVMValueRef personality = NULL;
3845 static gint32 mapping_inited = FALSE;
3846 LLVMTypeRef personality_type = LLVMFunctionType (LLVMInt32Type (), NULL, 0, TRUE);
3848 if (!use_debug_personality) {
3849 if (ctx->cfg->compile_aot) {
3850 personality = get_intrinsic (ctx, default_personality_name);
3851 } else if (InterlockedCompareExchange (&mapping_inited, 1, 0) == 0) {
3852 personality = LLVMAddFunction (ctx->lmodule, default_personality_name, personality_type);
3853 LLVMAddGlobalMapping (ctx->module->ee, personality, personality);
3856 if (ctx->cfg->compile_aot) {
3857 personality = get_callee (ctx, personality_type, MONO_PATCH_INFO_INTERNAL_METHOD, default_personality_name);
3859 personality = LLVMAddFunction (ctx->lmodule, default_personality_name, personality_type);
3860 LLVMAddGlobalMapping (ctx->module->ee, personality, resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, default_personality_name));
3861 mono_memory_barrier ();
3865 g_assert (personality);
3869 static LLVMBasicBlockRef
3870 emit_landing_pad (EmitContext *ctx, int group_index, int group_size)
3872 MonoCompile *cfg = ctx->cfg;
3873 LLVMBuilderRef old_builder = ctx->builder;
3874 MonoExceptionClause *group_start = cfg->header->clauses + group_index;
3876 LLVMBuilderRef lpadBuilder = create_builder (ctx);
3877 ctx->builder = lpadBuilder;
3879 MonoBasicBlock *handler_bb = cfg->cil_offset_to_bb [CLAUSE_START (group_start)];
3880 g_assert (handler_bb);
3882 // <resultval> = landingpad <somety> personality <type> <pers_fn> <clause>+
3883 LLVMValueRef personality = get_mono_personality (ctx);
3884 g_assert (personality);
3886 char *bb_name = g_strdup_printf ("LPAD%d_BB", group_index);
3887 LLVMBasicBlockRef lpad_bb = gen_bb (ctx, bb_name);
3889 LLVMPositionBuilderAtEnd (lpadBuilder, lpad_bb);
3890 LLVMValueRef landing_pad = LLVMBuildLandingPad (lpadBuilder, default_cpp_lpad_exc_signature (), personality, 0, "");
3891 g_assert (landing_pad);
3893 LLVMValueRef cast = LLVMBuildBitCast (lpadBuilder, ctx->module->sentinel_exception, LLVMPointerType (LLVMInt8Type (), 0), "int8TypeInfo");
3894 LLVMAddClause (landing_pad, cast);
3896 LLVMBasicBlockRef resume_bb = gen_bb (ctx, "RESUME_BB");
3897 LLVMBuilderRef resume_builder = create_builder (ctx);
3898 ctx->builder = resume_builder;
3899 LLVMPositionBuilderAtEnd (resume_builder, resume_bb);
3901 emit_resume_eh (ctx, handler_bb);
3904 ctx->builder = lpadBuilder;
3905 LLVMPositionBuilderAtEnd (lpadBuilder, lpad_bb);
3907 gboolean finally_only = TRUE;
3909 MonoExceptionClause *group_cursor = group_start;
3911 for (int i = 0; i < group_size; i ++) {
3912 if (!(group_cursor->flags & MONO_EXCEPTION_CLAUSE_FINALLY))
3913 finally_only = FALSE;
3919 // Handle landing pad inlining
3921 if (!finally_only) {
3922 // So at each level of the exception stack we will match the exception again.
3923 // During that match, we need to compare against the handler types for the current
3924 // protected region. We send the try start and end so that we can only check against
3925 // handlers for this lexical protected region.
3926 LLVMValueRef match = mono_llvm_emit_match_exception_call (ctx, lpadBuilder, group_start->try_offset, group_start->try_offset + group_start->try_len);
3928 // if returns -1, resume
3929 LLVMValueRef switch_ins = LLVMBuildSwitch (lpadBuilder, match, resume_bb, group_size);
3931 // else move to that target bb
3932 for (int i = 0; i < group_size; i++) {
3933 MonoExceptionClause *clause = group_start + i;
3934 int clause_index = clause - cfg->header->clauses;
3935 MonoBasicBlock *handler_bb = (MonoBasicBlock*)g_hash_table_lookup (ctx->clause_to_handler, GINT_TO_POINTER (clause_index));
3936 g_assert (handler_bb);
3937 g_assert (ctx->bblocks [handler_bb->block_num].call_handler_target_bb);
3938 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), clause_index, FALSE), ctx->bblocks [handler_bb->block_num].call_handler_target_bb);
3941 int clause_index = group_start - cfg->header->clauses;
3942 MonoBasicBlock *finally_bb = (MonoBasicBlock*)g_hash_table_lookup (ctx->clause_to_handler, GINT_TO_POINTER (clause_index));
3943 g_assert (finally_bb);
3945 LLVMBuildBr (ctx->builder, ctx->bblocks [finally_bb->block_num].call_handler_target_bb);
3948 ctx->builder = old_builder;
3955 emit_llvmonly_handler_start (EmitContext *ctx, MonoBasicBlock *bb, LLVMBasicBlockRef cbb)
3957 int clause_index = MONO_REGION_CLAUSE_INDEX (bb->region);
3958 MonoExceptionClause *clause = &ctx->cfg->header->clauses [clause_index];
3960 // Make exception available to catch blocks
3961 if (!(clause->flags & MONO_EXCEPTION_CLAUSE_FINALLY)) {
3962 LLVMValueRef mono_exc = mono_llvm_emit_load_exception_call (ctx, ctx->builder);
3964 g_assert (ctx->ex_var);
3965 LLVMBuildStore (ctx->builder, LLVMBuildBitCast (ctx->builder, mono_exc, ObjRefType (), ""), ctx->ex_var);
3967 if (bb->in_scount == 1) {
3968 MonoInst *exvar = bb->in_stack [0];
3969 g_assert (!ctx->values [exvar->dreg]);
3970 g_assert (ctx->ex_var);
3971 ctx->values [exvar->dreg] = LLVMBuildLoad (ctx->builder, ctx->ex_var, "save_exception");
3972 emit_volatile_store (ctx, exvar->dreg);
3975 mono_llvm_emit_clear_exception_call (ctx, ctx->builder);
3978 LLVMBuilderRef handler_builder = create_builder (ctx);
3979 LLVMBasicBlockRef target_bb = ctx->bblocks [bb->block_num].call_handler_target_bb;
3980 LLVMPositionBuilderAtEnd (handler_builder, target_bb);
3982 // Make the handler code end with a jump to cbb
3983 LLVMBuildBr (handler_builder, cbb);
3987 emit_handler_start (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef builder)
3989 MonoCompile *cfg = ctx->cfg;
3990 LLVMValueRef *values = ctx->values;
3991 LLVMModuleRef lmodule = ctx->lmodule;
3992 BBInfo *bblocks = ctx->bblocks;
3994 LLVMValueRef personality;
3995 LLVMValueRef landing_pad;
3996 LLVMBasicBlockRef target_bb;
3998 static int ti_generator;
4000 LLVMValueRef type_info;
4004 // <resultval> = landingpad <somety> personality <type> <pers_fn> <clause>+
4006 if (cfg->compile_aot) {
4007 /* Use a dummy personality function */
4008 personality = LLVMGetNamedFunction (lmodule, "mono_personality");
4009 g_assert (personality);
4011 #if LLVM_API_VERSION > 100
4012 personality = ctx->module->personality;
4014 LLVMTypeRef personality_type = LLVMFunctionType (LLVMInt32Type (), NULL, 0, TRUE);
4015 personality = LLVMAddFunction (ctx->lmodule, "mono_personality", personality_type);
4016 LLVMAddFunctionAttr (personality, LLVMNoUnwindAttribute);
4017 LLVMBasicBlockRef entry_bb = LLVMAppendBasicBlock (personality, "ENTRY");
4018 LLVMBuilderRef builder2 = LLVMCreateBuilder ();
4019 LLVMPositionBuilderAtEnd (builder2, entry_bb);
4020 LLVMBuildRet (builder2, LLVMConstInt (LLVMInt32Type (), 0, FALSE));
4021 ctx->module->personality = personality;
4022 LLVMDisposeBuilder (builder2);
4025 static gint32 mapping_inited;
4027 personality = LLVMGetNamedFunction (lmodule, "mono_personality");
4029 if (InterlockedCompareExchange (&mapping_inited, 1, 0) == 0)
4030 LLVMAddGlobalMapping (ctx->module->ee, personality, (gpointer)mono_personality);
4034 i8ptr = LLVMPointerType (LLVMInt8Type (), 0);
4036 clause_index = (mono_get_block_region_notry (cfg, bb->region) >> 8) - 1;
4039 * Create the type info
4041 sprintf (ti_name, "type_info_%d", ti_generator);
4044 if (cfg->compile_aot) {
4045 /* decode_eh_frame () in aot-runtime.c will decode this */
4046 type_info = LLVMAddGlobal (lmodule, LLVMInt32Type (), ti_name);
4047 LLVMSetInitializer (type_info, LLVMConstInt (LLVMInt32Type (), clause_index, FALSE));
4050 * These symbols are not really used, the clause_index is embedded into the EH tables generated by DwarfMonoException in LLVM.
4052 LLVMSetLinkage (type_info, LLVMInternalLinkage);
4054 #if LLVM_API_VERSION > 100
4055 type_info = LLVMAddGlobal (lmodule, LLVMInt32Type (), ti_name);
4056 LLVMSetInitializer (type_info, LLVMConstInt (LLVMInt32Type (), clause_index, FALSE));
4061 * After the cfg mempool is freed, the type info will point to stale memory,
4062 * but this is not a problem, since we decode it once in exception_cb during
4065 ti = (gint32*)mono_mempool_alloc (cfg->mempool, sizeof (gint32));
4066 *(gint32*)ti = clause_index;
4068 type_info = LLVMAddGlobal (lmodule, i8ptr, ti_name);
4070 LLVMAddGlobalMapping (ctx->module->ee, type_info, ti);
4075 LLVMTypeRef members [2], ret_type;
4077 members [0] = i8ptr;
4078 members [1] = LLVMInt32Type ();
4079 ret_type = LLVMStructType (members, 2, FALSE);
4081 landing_pad = LLVMBuildLandingPad (builder, ret_type, personality, 1, "");
4082 LLVMAddClause (landing_pad, type_info);
4084 /* Store the exception into the exvar */
4086 LLVMBuildStore (builder, convert (ctx, LLVMBuildExtractValue (builder, landing_pad, 0, "ex_obj"), ObjRefType ()), ctx->ex_var);
4090 * LLVM throw sites are associated with a one landing pad, and LLVM generated
4091 * code expects control to be transferred to this landing pad even in the
4092 * presence of nested clauses. The landing pad needs to branch to the landing
4093 * pads belonging to nested clauses based on the selector value returned by
4094 * the landing pad instruction, which is passed to the landing pad in a
4095 * register by the EH code.
4097 target_bb = bblocks [bb->block_num].call_handler_target_bb;
4098 g_assert (target_bb);
4101 * Branch to the correct landing pad
4103 LLVMValueRef ex_selector = LLVMBuildExtractValue (builder, landing_pad, 1, "ex_selector");
4104 LLVMValueRef switch_ins = LLVMBuildSwitch (builder, ex_selector, target_bb, 0);
4106 for (l = ctx->nested_in [clause_index]; l; l = l->next) {
4107 int nesting_clause_index = GPOINTER_TO_INT (l->data);
4108 MonoBasicBlock *handler_bb;
4110 handler_bb = (MonoBasicBlock*)g_hash_table_lookup (ctx->clause_to_handler, GINT_TO_POINTER (nesting_clause_index));
4111 g_assert (handler_bb);
4113 g_assert (ctx->bblocks [handler_bb->block_num].call_handler_target_bb);
4114 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), nesting_clause_index, FALSE), ctx->bblocks [handler_bb->block_num].call_handler_target_bb);
4117 /* Start a new bblock which CALL_HANDLER can branch to */
4118 target_bb = bblocks [bb->block_num].call_handler_target_bb;
4120 ctx->builder = builder = create_builder (ctx);
4121 LLVMPositionBuilderAtEnd (ctx->builder, target_bb);
4123 ctx->bblocks [bb->block_num].end_bblock = target_bb;
4125 /* Store the exception into the IL level exvar */
4126 if (bb->in_scount == 1) {
4127 g_assert (bb->in_scount == 1);
4128 exvar = bb->in_stack [0];
4130 // FIXME: This is shared with filter clauses ?
4131 g_assert (!values [exvar->dreg]);
4133 g_assert (ctx->ex_var);
4134 values [exvar->dreg] = LLVMBuildLoad (builder, ctx->ex_var, "");
4135 emit_volatile_store (ctx, exvar->dreg);
4141 process_bb (EmitContext *ctx, MonoBasicBlock *bb)
4143 MonoCompile *cfg = ctx->cfg;
4144 MonoMethodSignature *sig = ctx->sig;
4145 LLVMValueRef method = ctx->lmethod;
4146 LLVMValueRef *values = ctx->values;
4147 LLVMValueRef *addresses = ctx->addresses;
4148 LLVMCallInfo *linfo = ctx->linfo;
4149 BBInfo *bblocks = ctx->bblocks;
4151 LLVMBasicBlockRef cbb;
4152 LLVMBuilderRef builder, starting_builder;
4153 gboolean has_terminator;
4155 LLVMValueRef lhs, rhs;
4158 cbb = get_end_bb (ctx, bb);
4160 builder = create_builder (ctx);
4161 ctx->builder = builder;
4162 LLVMPositionBuilderAtEnd (builder, cbb);
4167 if (bb->flags & BB_EXCEPTION_HANDLER) {
4168 if (!ctx->llvm_only && !bblocks [bb->block_num].invoke_target) {
4169 set_failure (ctx, "handler without invokes");
4174 emit_llvmonly_handler_start (ctx, bb, cbb);
4176 emit_handler_start (ctx, bb, builder);
4179 builder = ctx->builder;
4182 has_terminator = FALSE;
4183 starting_builder = builder;
4184 for (ins = bb->code; ins; ins = ins->next) {
4185 const char *spec = LLVM_INS_INFO (ins->opcode);
4187 char dname_buf [128];
4189 emit_dbg_loc (ctx, builder, ins->cil_code);
4194 * Some steps in llc are non-linear in the size of basic blocks, see #5714.
4195 * Start a new bblock.
4196 * Prevent the bblocks to be merged by doing a volatile load + cond branch
4197 * from localloc-ed memory.
4199 if (!cfg->llvm_only)
4200 ;//set_failure (ctx, "basic block too long");
4202 if (!ctx->long_bb_break_var) {
4203 ctx->long_bb_break_var = build_alloca_llvm_type_name (ctx, LLVMInt32Type (), 0, "long_bb_break");
4204 mono_llvm_build_store (ctx->alloca_builder, LLVMConstInt (LLVMInt32Type (), 0, FALSE), ctx->long_bb_break_var, TRUE, LLVM_BARRIER_NONE);
4207 cbb = gen_bb (ctx, "CONT_LONG_BB");
4208 LLVMBasicBlockRef dummy_bb = gen_bb (ctx, "CONT_LONG_BB_DUMMY");
4210 LLVMValueRef load = mono_llvm_build_load (builder, ctx->long_bb_break_var, "", TRUE);
4212 * The long_bb_break_var is initialized to 0 in the prolog, so this branch will always go to 'cbb'
4213 * but llvm doesn't know that, so the branch is not going to be eliminated.
4215 LLVMValueRef cmp = LLVMBuildICmp (builder, LLVMIntEQ, load, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
4217 LLVMBuildCondBr (builder, cmp, cbb, dummy_bb);
4219 /* Emit a dummy false bblock which does nothing but contains a volatile store so it cannot be eliminated */
4220 ctx->builder = builder = create_builder (ctx);
4221 LLVMPositionBuilderAtEnd (builder, dummy_bb);
4222 mono_llvm_build_store (builder, LLVMConstInt (LLVMInt32Type (), 1, FALSE), ctx->long_bb_break_var, TRUE, LLVM_BARRIER_NONE);
4223 LLVMBuildBr (builder, cbb);
4225 ctx->builder = builder = create_builder (ctx);
4226 LLVMPositionBuilderAtEnd (builder, cbb);
4227 ctx->bblocks [bb->block_num].end_bblock = cbb;
4232 /* There could be instructions after a terminator, skip them */
4235 if (spec [MONO_INST_DEST] != ' ' && !MONO_IS_STORE_MEMBASE (ins)) {
4236 sprintf (dname_buf, "t%d", ins->dreg);
4240 if (spec [MONO_INST_SRC1] != ' ' && spec [MONO_INST_SRC1] != 'v') {
4241 MonoInst *var = get_vreg_to_inst (cfg, ins->sreg1);
4243 if (var && var->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT) && var->opcode != OP_GSHAREDVT_ARG_REGOFFSET) {
4244 lhs = emit_volatile_load (ctx, ins->sreg1);
4246 /* It is ok for SETRET to have an uninitialized argument */
4247 if (!values [ins->sreg1] && ins->opcode != OP_SETRET) {
4248 set_failure (ctx, "sreg1");
4251 lhs = values [ins->sreg1];
4257 if (spec [MONO_INST_SRC2] != ' ' && spec [MONO_INST_SRC2] != ' ') {
4258 MonoInst *var = get_vreg_to_inst (cfg, ins->sreg2);
4259 if (var && var->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT)) {
4260 rhs = emit_volatile_load (ctx, ins->sreg2);
4262 if (!values [ins->sreg2]) {
4263 set_failure (ctx, "sreg2");
4266 rhs = values [ins->sreg2];
4272 //mono_print_ins (ins);
4273 switch (ins->opcode) {
4276 case OP_LIVERANGE_START:
4277 case OP_LIVERANGE_END:
4280 values [ins->dreg] = LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE);
4283 #if SIZEOF_VOID_P == 4
4284 values [ins->dreg] = LLVMConstInt (LLVMInt64Type (), GET_LONG_IMM (ins), FALSE);
4286 values [ins->dreg] = LLVMConstInt (LLVMInt64Type (), (gint64)ins->inst_c0, FALSE);
4290 values [ins->dreg] = LLVMConstReal (LLVMDoubleType (), *(double*)ins->inst_p0);
4294 values [ins->dreg] = LLVMConstReal (LLVMFloatType (), *(float*)ins->inst_p0);
4296 values [ins->dreg] = LLVMConstFPExt (LLVMConstReal (LLVMFloatType (), *(float*)ins->inst_p0), LLVMDoubleType ());
4298 case OP_DUMMY_ICONST:
4299 values [ins->dreg] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
4301 case OP_DUMMY_I8CONST:
4302 values [ins->dreg] = LLVMConstInt (LLVMInt64Type (), 0, FALSE);
4304 case OP_DUMMY_R8CONST:
4305 values [ins->dreg] = LLVMConstReal (LLVMDoubleType (), 0.0f);
4308 LLVMBasicBlockRef target_bb = get_bb (ctx, ins->inst_target_bb);
4309 LLVMBuildBr (builder, target_bb);
4310 has_terminator = TRUE;
4317 LLVMBasicBlockRef new_bb;
4318 LLVMBuilderRef new_builder;
4320 // The default branch is already handled
4321 // FIXME: Handle it here
4323 /* Start new bblock */
4324 sprintf (bb_name, "SWITCH_DEFAULT_BB%d", ctx->default_index ++);
4325 new_bb = LLVMAppendBasicBlock (ctx->lmethod, bb_name);
4327 lhs = convert (ctx, lhs, LLVMInt32Type ());
4328 v = LLVMBuildSwitch (builder, lhs, new_bb, GPOINTER_TO_UINT (ins->klass));
4329 for (i = 0; i < GPOINTER_TO_UINT (ins->klass); ++i) {
4330 MonoBasicBlock *target_bb = ins->inst_many_bb [i];
4332 LLVMAddCase (v, LLVMConstInt (LLVMInt32Type (), i, FALSE), get_bb (ctx, target_bb));
4335 new_builder = create_builder (ctx);
4336 LLVMPositionBuilderAtEnd (new_builder, new_bb);
4337 LLVMBuildUnreachable (new_builder);
4339 has_terminator = TRUE;
4340 g_assert (!ins->next);
4346 switch (linfo->ret.storage) {
4347 case LLVMArgVtypeInReg: {
4348 LLVMTypeRef ret_type = LLVMGetReturnType (LLVMGetElementType (LLVMTypeOf (method)));
4349 LLVMValueRef val, addr, retval;
4352 retval = LLVMGetUndef (ret_type);
4354 if (!addresses [ins->sreg1]) {
4356 * The return type is an LLVM vector type, have to convert between it and the
4357 * real return type which is a struct type.
4359 g_assert (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (sig->ret)));
4360 /* Convert to 2xi64 first */
4361 val = LLVMBuildBitCast (builder, values [ins->sreg1], LLVMVectorType (IntPtrType (), 2), "");
4363 for (i = 0; i < 2; ++i) {
4364 if (linfo->ret.pair_storage [i] == LLVMArgInIReg) {
4365 retval = LLVMBuildInsertValue (builder, retval, LLVMBuildExtractElement (builder, val, LLVMConstInt (LLVMInt32Type (), i, FALSE), ""), i, "");
4367 g_assert (linfo->ret.pair_storage [i] == LLVMArgNone);
4371 addr = LLVMBuildBitCast (builder, addresses [ins->sreg1], LLVMPointerType (ret_type, 0), "");
4372 for (i = 0; i < 2; ++i) {
4373 if (linfo->ret.pair_storage [i] == LLVMArgInIReg) {
4374 LLVMValueRef indexes [2], part_addr;
4376 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
4377 indexes [1] = LLVMConstInt (LLVMInt32Type (), i, FALSE);
4378 part_addr = LLVMBuildGEP (builder, addr, indexes, 2, "");
4380 retval = LLVMBuildInsertValue (builder, retval, LLVMBuildLoad (builder, part_addr, ""), i, "");
4382 g_assert (linfo->ret.pair_storage [i] == LLVMArgNone);
4386 LLVMBuildRet (builder, retval);
4389 case LLVMArgVtypeAsScalar: {
4390 LLVMTypeRef ret_type = LLVMGetReturnType (LLVMGetElementType (LLVMTypeOf (method)));
4391 LLVMValueRef retval;
4393 g_assert (addresses [ins->sreg1]);
4395 retval = LLVMBuildLoad (builder, LLVMBuildBitCast (builder, addresses [ins->sreg1], LLVMPointerType (ret_type, 0), ""), "");
4396 LLVMBuildRet (builder, retval);
4399 case LLVMArgVtypeByVal: {
4400 LLVMValueRef retval;
4402 g_assert (addresses [ins->sreg1]);
4403 retval = LLVMBuildLoad (builder, addresses [ins->sreg1], "");
4404 LLVMBuildRet (builder, retval);
4407 case LLVMArgVtypeByRef: {
4408 LLVMBuildRetVoid (builder);
4411 case LLVMArgGsharedvtFixed: {
4412 LLVMTypeRef ret_type = type_to_llvm_type (ctx, sig->ret);
4413 /* The return value is in lhs, need to store to the vret argument */
4414 /* sreg1 might not be set */
4416 g_assert (cfg->vret_addr);
4417 g_assert (values [cfg->vret_addr->dreg]);
4418 LLVMBuildStore (builder, convert (ctx, lhs, ret_type), convert (ctx, values [cfg->vret_addr->dreg], LLVMPointerType (ret_type, 0)));
4420 LLVMBuildRetVoid (builder);
4423 case LLVMArgGsharedvtFixedVtype: {
4425 LLVMBuildRetVoid (builder);
4428 case LLVMArgGsharedvtVariable: {
4430 LLVMBuildRetVoid (builder);
4433 case LLVMArgVtypeRetAddr: {
4434 LLVMBuildRetVoid (builder);
4437 case LLVMArgAsIArgs:
4438 case LLVMArgFpStruct: {
4439 LLVMTypeRef ret_type = LLVMGetReturnType (LLVMGetElementType (LLVMTypeOf (method)));
4440 LLVMValueRef retval;
4442 g_assert (addresses [ins->sreg1]);
4443 retval = LLVMBuildLoad (builder, convert (ctx, addresses [ins->sreg1], LLVMPointerType (ret_type, 0)), "");
4444 LLVMBuildRet (builder, retval);
4448 case LLVMArgNormal: {
4449 if (!lhs || ctx->is_dead [ins->sreg1]) {
4451 * The method did not set its return value, probably because it
4452 * ends with a throw.
4455 LLVMBuildRetVoid (builder);
4457 LLVMBuildRet (builder, LLVMConstNull (type_to_llvm_type (ctx, sig->ret)));
4459 LLVMBuildRet (builder, convert (ctx, lhs, type_to_llvm_type (ctx, sig->ret)));
4461 has_terminator = TRUE;
4465 g_assert_not_reached ();
4474 case OP_ICOMPARE_IMM:
4475 case OP_LCOMPARE_IMM:
4476 case OP_COMPARE_IMM: {
4478 LLVMValueRef cmp, args [16];
4479 gboolean likely = (ins->flags & MONO_INST_LIKELY) != 0;
4481 if (ins->next->opcode == OP_NOP)
4484 if (ins->next->opcode == OP_BR)
4485 /* The comparison result is not needed */
4488 rel = mono_opcode_to_cond (ins->next->opcode);
4490 if (ins->opcode == OP_ICOMPARE_IMM) {
4491 lhs = convert (ctx, lhs, LLVMInt32Type ());
4492 rhs = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
4494 if (ins->opcode == OP_LCOMPARE_IMM) {
4495 lhs = convert (ctx, lhs, LLVMInt64Type ());
4496 rhs = LLVMConstInt (LLVMInt64Type (), GET_LONG_IMM (ins), FALSE);
4498 if (ins->opcode == OP_LCOMPARE) {
4499 lhs = convert (ctx, lhs, LLVMInt64Type ());
4500 rhs = convert (ctx, rhs, LLVMInt64Type ());
4502 if (ins->opcode == OP_ICOMPARE) {
4503 lhs = convert (ctx, lhs, LLVMInt32Type ());
4504 rhs = convert (ctx, rhs, LLVMInt32Type ());
4508 if (LLVMGetTypeKind (LLVMTypeOf (lhs)) == LLVMPointerTypeKind)
4509 rhs = convert (ctx, rhs, LLVMTypeOf (lhs));
4510 else if (LLVMGetTypeKind (LLVMTypeOf (rhs)) == LLVMPointerTypeKind)
4511 lhs = convert (ctx, lhs, LLVMTypeOf (rhs));
4514 /* We use COMPARE+SETcc/Bcc, llvm uses SETcc+br cond */
4515 if (ins->opcode == OP_FCOMPARE) {
4516 cmp = LLVMBuildFCmp (builder, fpcond_to_llvm_cond [rel], convert (ctx, lhs, LLVMDoubleType ()), convert (ctx, rhs, LLVMDoubleType ()), "");
4517 } else if (ins->opcode == OP_RCOMPARE) {
4518 cmp = LLVMBuildFCmp (builder, fpcond_to_llvm_cond [rel], convert (ctx, lhs, LLVMFloatType ()), convert (ctx, rhs, LLVMFloatType ()), "");
4519 } else if (ins->opcode == OP_COMPARE_IMM) {
4520 if (LLVMGetTypeKind (LLVMTypeOf (lhs)) == LLVMPointerTypeKind && ins->inst_imm == 0)
4521 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], lhs, LLVMConstNull (LLVMTypeOf (lhs)), "");
4523 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE), "");
4524 } else if (ins->opcode == OP_LCOMPARE_IMM) {
4525 if (SIZEOF_REGISTER == 4 && COMPILE_LLVM (cfg)) {
4526 /* The immediate is encoded in two fields */
4527 guint64 l = ((guint64)(guint32)ins->inst_offset << 32) | ((guint32)ins->inst_imm);
4528 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, LLVMInt64Type ()), LLVMConstInt (LLVMInt64Type (), l, FALSE), "");
4530 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, LLVMInt64Type ()), LLVMConstInt (LLVMInt64Type (), ins->inst_imm, FALSE), "");
4533 else if (ins->opcode == OP_COMPARE) {
4534 if (LLVMGetTypeKind (LLVMTypeOf (lhs)) == LLVMPointerTypeKind && LLVMTypeOf (lhs) == LLVMTypeOf (rhs))
4535 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], lhs, rhs, "");
4537 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, IntPtrType ()), convert (ctx, rhs, IntPtrType ()), "");
4539 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], lhs, rhs, "");
4543 args [1] = LLVMConstInt (LLVMInt1Type (), 1, FALSE);
4544 cmp = LLVMBuildCall (ctx->builder, get_intrinsic (ctx, "llvm.expect.i1"), args, 2, "");
4547 if (MONO_IS_COND_BRANCH_OP (ins->next)) {
4548 if (ins->next->inst_true_bb == ins->next->inst_false_bb) {
4550 * If the target bb contains PHI instructions, LLVM requires
4551 * two PHI entries for this bblock, while we only generate one.
4552 * So convert this to an unconditional bblock. (bxc #171).
4554 LLVMBuildBr (builder, get_bb (ctx, ins->next->inst_true_bb));
4556 LLVMBuildCondBr (builder, cmp, get_bb (ctx, ins->next->inst_true_bb), get_bb (ctx, ins->next->inst_false_bb));
4558 has_terminator = TRUE;
4559 } else if (MONO_IS_SETCC (ins->next)) {
4560 sprintf (dname_buf, "t%d", ins->next->dreg);
4562 values [ins->next->dreg] = LLVMBuildZExt (builder, cmp, LLVMInt32Type (), dname);
4564 /* Add stores for volatile variables */
4565 emit_volatile_store (ctx, ins->next->dreg);
4566 } else if (MONO_IS_COND_EXC (ins->next)) {
4567 emit_cond_system_exception (ctx, bb, (const char*)ins->next->inst_p1, cmp);
4570 builder = ctx->builder;
4572 set_failure (ctx, "next");
4590 rel = mono_opcode_to_cond (ins->opcode);
4592 cmp = LLVMBuildFCmp (builder, fpcond_to_llvm_cond [rel], convert (ctx, lhs, LLVMDoubleType ()), convert (ctx, rhs, LLVMDoubleType ()), "");
4593 values [ins->dreg] = LLVMBuildZExt (builder, cmp, LLVMInt32Type (), dname);
4604 rel = mono_opcode_to_cond (ins->opcode);
4606 cmp = LLVMBuildFCmp (builder, fpcond_to_llvm_cond [rel], convert (ctx, lhs, LLVMFloatType ()), convert (ctx, rhs, LLVMFloatType ()), "");
4607 values [ins->dreg] = LLVMBuildZExt (builder, cmp, LLVMInt32Type (), dname);
4615 gboolean empty = TRUE;
4617 /* Check that all input bblocks really branch to us */
4618 for (i = 0; i < bb->in_count; ++i) {
4619 if (bb->in_bb [i]->last_ins && bb->in_bb [i]->last_ins->opcode == OP_NOT_REACHED)
4620 ins->inst_phi_args [i + 1] = -1;
4626 /* LLVM doesn't like phi instructions with zero operands */
4627 ctx->is_dead [ins->dreg] = TRUE;
4631 /* Created earlier, insert it now */
4632 LLVMInsertIntoBuilder (builder, values [ins->dreg]);
4634 for (i = 0; i < ins->inst_phi_args [0]; i++) {
4635 int sreg1 = ins->inst_phi_args [i + 1];
4639 * Count the number of times the incoming bblock branches to us,
4640 * since llvm requires a separate entry for each.
4642 if (bb->in_bb [i]->last_ins && bb->in_bb [i]->last_ins->opcode == OP_SWITCH) {
4643 MonoInst *switch_ins = bb->in_bb [i]->last_ins;
4646 for (j = 0; j < GPOINTER_TO_UINT (switch_ins->klass); ++j) {
4647 if (switch_ins->inst_many_bb [j] == bb)
4654 /* Remember for later */
4655 for (j = 0; j < count; ++j) {
4656 PhiNode *node = (PhiNode*)mono_mempool_alloc0 (ctx->mempool, sizeof (PhiNode));
4659 node->in_bb = bb->in_bb [i];
4661 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);
4671 values [ins->dreg] = lhs;
4675 MonoInst *var = get_vreg_to_inst (cfg, ins->dreg);
4678 values [ins->dreg] = lhs;
4680 if (var && var->klass->byval_arg.type == MONO_TYPE_R4) {
4682 * This is added by the spilling pass in case of the JIT,
4683 * but we have to do it ourselves.
4685 values [ins->dreg] = convert (ctx, values [ins->dreg], LLVMFloatType ());
4689 case OP_MOVE_F_TO_I4: {
4690 values [ins->dreg] = LLVMBuildBitCast (builder, LLVMBuildFPTrunc (builder, lhs, LLVMFloatType (), ""), LLVMInt32Type (), "");
4693 case OP_MOVE_I4_TO_F: {
4694 values [ins->dreg] = LLVMBuildFPExt (builder, LLVMBuildBitCast (builder, lhs, LLVMFloatType (), ""), LLVMDoubleType (), "");
4697 case OP_MOVE_F_TO_I8: {
4698 values [ins->dreg] = LLVMBuildBitCast (builder, lhs, LLVMInt64Type (), "");
4701 case OP_MOVE_I8_TO_F: {
4702 values [ins->dreg] = LLVMBuildBitCast (builder, lhs, LLVMDoubleType (), "");
4735 lhs = convert (ctx, lhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
4736 rhs = convert (ctx, rhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
4738 emit_div_check (ctx, builder, bb, ins, lhs, rhs);
4741 builder = ctx->builder;
4743 switch (ins->opcode) {
4746 values [ins->dreg] = LLVMBuildAdd (builder, lhs, rhs, dname);
4750 values [ins->dreg] = LLVMBuildSub (builder, lhs, rhs, dname);
4754 values [ins->dreg] = LLVMBuildMul (builder, lhs, rhs, dname);
4758 values [ins->dreg] = LLVMBuildSRem (builder, lhs, rhs, dname);
4762 values [ins->dreg] = LLVMBuildURem (builder, lhs, rhs, dname);
4766 values [ins->dreg] = LLVMBuildSDiv (builder, lhs, rhs, dname);
4770 values [ins->dreg] = LLVMBuildUDiv (builder, lhs, rhs, dname);
4774 values [ins->dreg] = LLVMBuildFDiv (builder, lhs, rhs, dname);
4778 values [ins->dreg] = LLVMBuildAnd (builder, lhs, rhs, dname);
4782 values [ins->dreg] = LLVMBuildOr (builder, lhs, rhs, dname);
4786 values [ins->dreg] = LLVMBuildXor (builder, lhs, rhs, dname);
4790 values [ins->dreg] = LLVMBuildShl (builder, lhs, rhs, dname);
4794 values [ins->dreg] = LLVMBuildAShr (builder, lhs, rhs, dname);
4798 values [ins->dreg] = LLVMBuildLShr (builder, lhs, rhs, dname);
4802 values [ins->dreg] = LLVMBuildFAdd (builder, lhs, rhs, dname);
4805 values [ins->dreg] = LLVMBuildFSub (builder, lhs, rhs, dname);
4808 values [ins->dreg] = LLVMBuildFMul (builder, lhs, rhs, dname);
4812 g_assert_not_reached ();
4819 lhs = convert (ctx, lhs, LLVMFloatType ());
4820 rhs = convert (ctx, rhs, LLVMFloatType ());
4821 switch (ins->opcode) {
4823 values [ins->dreg] = LLVMBuildFAdd (builder, lhs, rhs, dname);
4826 values [ins->dreg] = LLVMBuildFSub (builder, lhs, rhs, dname);
4829 values [ins->dreg] = LLVMBuildFMul (builder, lhs, rhs, dname);
4832 values [ins->dreg] = LLVMBuildFDiv (builder, lhs, rhs, dname);
4835 g_assert_not_reached ();
4844 case OP_IREM_UN_IMM:
4846 case OP_IDIV_UN_IMM:
4852 case OP_ISHR_UN_IMM:
4862 case OP_LSHR_UN_IMM:
4868 case OP_SHR_UN_IMM: {
4871 if (spec [MONO_INST_SRC1] == 'l') {
4872 imm = LLVMConstInt (LLVMInt64Type (), GET_LONG_IMM (ins), FALSE);
4874 imm = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
4877 emit_div_check (ctx, builder, bb, ins, lhs, imm);
4880 builder = ctx->builder;
4882 #if SIZEOF_VOID_P == 4
4883 if (ins->opcode == OP_LSHL_IMM || ins->opcode == OP_LSHR_IMM || ins->opcode == OP_LSHR_UN_IMM)
4884 imm = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
4887 if (LLVMGetTypeKind (LLVMTypeOf (lhs)) == LLVMPointerTypeKind)
4888 lhs = convert (ctx, lhs, IntPtrType ());
4889 imm = convert (ctx, imm, LLVMTypeOf (lhs));
4890 switch (ins->opcode) {
4894 values [ins->dreg] = LLVMBuildAdd (builder, lhs, imm, dname);
4898 values [ins->dreg] = LLVMBuildSub (builder, lhs, imm, dname);
4903 values [ins->dreg] = LLVMBuildMul (builder, lhs, imm, dname);
4907 values [ins->dreg] = LLVMBuildSDiv (builder, lhs, imm, dname);
4909 case OP_IDIV_UN_IMM:
4910 case OP_LDIV_UN_IMM:
4911 values [ins->dreg] = LLVMBuildUDiv (builder, lhs, imm, dname);
4915 values [ins->dreg] = LLVMBuildSRem (builder, lhs, imm, dname);
4917 case OP_IREM_UN_IMM:
4918 values [ins->dreg] = LLVMBuildURem (builder, lhs, imm, dname);
4923 values [ins->dreg] = LLVMBuildAnd (builder, lhs, imm, dname);
4927 values [ins->dreg] = LLVMBuildOr (builder, lhs, imm, dname);
4931 values [ins->dreg] = LLVMBuildXor (builder, lhs, imm, dname);
4936 values [ins->dreg] = LLVMBuildShl (builder, lhs, imm, dname);
4941 values [ins->dreg] = LLVMBuildAShr (builder, lhs, imm, dname);
4943 case OP_ISHR_UN_IMM:
4944 /* This is used to implement conv.u4, so the lhs could be an i8 */
4945 lhs = convert (ctx, lhs, LLVMInt32Type ());
4946 imm = convert (ctx, imm, LLVMInt32Type ());
4947 values [ins->dreg] = LLVMBuildLShr (builder, lhs, imm, dname);
4949 case OP_LSHR_UN_IMM:
4951 values [ins->dreg] = LLVMBuildLShr (builder, lhs, imm, dname);
4954 g_assert_not_reached ();
4959 values [ins->dreg] = LLVMBuildSub (builder, LLVMConstInt (LLVMInt32Type (), 0, FALSE), convert (ctx, lhs, LLVMInt32Type ()), dname);
4962 values [ins->dreg] = LLVMBuildSub (builder, LLVMConstInt (LLVMInt64Type (), 0, FALSE), lhs, dname);
4965 lhs = convert (ctx, lhs, LLVMDoubleType ());
4966 values [ins->dreg] = LLVMBuildFSub (builder, LLVMConstReal (LLVMDoubleType (), 0.0), lhs, dname);
4969 lhs = convert (ctx, lhs, LLVMFloatType ());
4970 values [ins->dreg] = LLVMBuildFSub (builder, LLVMConstReal (LLVMFloatType (), 0.0), lhs, dname);
4973 guint32 v = 0xffffffff;
4974 values [ins->dreg] = LLVMBuildXor (builder, LLVMConstInt (LLVMInt32Type (), v, FALSE), convert (ctx, lhs, LLVMInt32Type ()), dname);
4978 guint64 v = 0xffffffffffffffffLL;
4979 values [ins->dreg] = LLVMBuildXor (builder, LLVMConstInt (LLVMInt64Type (), v, FALSE), lhs, dname);
4982 #if defined(TARGET_X86) || defined(TARGET_AMD64)
4984 LLVMValueRef v1, v2;
4986 v1 = LLVMBuildMul (builder, convert (ctx, rhs, IntPtrType ()), LLVMConstInt (IntPtrType (), (1 << ins->backend.shift_amount), FALSE), "");
4987 v2 = LLVMBuildAdd (builder, convert (ctx, lhs, IntPtrType ()), v1, "");
4988 values [ins->dreg] = LLVMBuildAdd (builder, v2, LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE), dname);
4993 case OP_ICONV_TO_I1:
4994 case OP_ICONV_TO_I2:
4995 case OP_ICONV_TO_I4:
4996 case OP_ICONV_TO_U1:
4997 case OP_ICONV_TO_U2:
4998 case OP_ICONV_TO_U4:
4999 case OP_LCONV_TO_I1:
5000 case OP_LCONV_TO_I2:
5001 case OP_LCONV_TO_U1:
5002 case OP_LCONV_TO_U2:
5003 case OP_LCONV_TO_U4: {
5006 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);
5008 /* Have to do two casts since our vregs have type int */
5009 v = LLVMBuildTrunc (builder, lhs, op_to_llvm_type (ins->opcode), "");
5011 values [ins->dreg] = LLVMBuildSExt (builder, v, LLVMInt32Type (), dname);
5013 values [ins->dreg] = LLVMBuildZExt (builder, v, LLVMInt32Type (), dname);
5016 case OP_ICONV_TO_I8:
5017 values [ins->dreg] = LLVMBuildSExt (builder, lhs, LLVMInt64Type (), dname);
5019 case OP_ICONV_TO_U8:
5020 values [ins->dreg] = LLVMBuildZExt (builder, lhs, LLVMInt64Type (), dname);
5022 case OP_FCONV_TO_I4:
5023 case OP_RCONV_TO_I4:
5024 values [ins->dreg] = LLVMBuildFPToSI (builder, lhs, LLVMInt32Type (), dname);
5026 case OP_FCONV_TO_I1:
5027 case OP_RCONV_TO_I1:
5028 values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildFPToSI (builder, lhs, LLVMInt8Type (), dname), LLVMInt32Type (), "");
5030 case OP_FCONV_TO_U1:
5031 case OP_RCONV_TO_U1:
5032 values [ins->dreg] = LLVMBuildZExt (builder, LLVMBuildTrunc (builder, LLVMBuildFPToUI (builder, lhs, IntPtrType (), dname), LLVMInt8Type (), ""), LLVMInt32Type (), "");
5034 case OP_FCONV_TO_I2:
5035 case OP_RCONV_TO_I2:
5036 values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildFPToSI (builder, lhs, LLVMInt16Type (), dname), LLVMInt32Type (), "");
5038 case OP_FCONV_TO_U2:
5039 case OP_RCONV_TO_U2:
5040 values [ins->dreg] = LLVMBuildZExt (builder, LLVMBuildFPToUI (builder, lhs, LLVMInt16Type (), dname), LLVMInt32Type (), "");
5042 case OP_RCONV_TO_U4:
5043 values [ins->dreg] = LLVMBuildFPToUI (builder, lhs, LLVMInt32Type (), dname);
5045 case OP_FCONV_TO_I8:
5046 case OP_RCONV_TO_I8:
5047 values [ins->dreg] = LLVMBuildFPToSI (builder, lhs, LLVMInt64Type (), dname);
5050 values [ins->dreg] = LLVMBuildFPToSI (builder, lhs, IntPtrType (), dname);
5052 case OP_ICONV_TO_R8:
5053 case OP_LCONV_TO_R8:
5054 values [ins->dreg] = LLVMBuildSIToFP (builder, lhs, LLVMDoubleType (), dname);
5056 case OP_ICONV_TO_R_UN:
5057 case OP_LCONV_TO_R_UN:
5058 values [ins->dreg] = LLVMBuildUIToFP (builder, lhs, LLVMDoubleType (), dname);
5060 #if SIZEOF_VOID_P == 4
5063 case OP_LCONV_TO_I4:
5064 values [ins->dreg] = LLVMBuildTrunc (builder, lhs, LLVMInt32Type (), dname);
5066 case OP_ICONV_TO_R4:
5067 case OP_LCONV_TO_R4:
5068 v = LLVMBuildSIToFP (builder, lhs, LLVMFloatType (), "");
5070 values [ins->dreg] = v;
5072 values [ins->dreg] = LLVMBuildFPExt (builder, v, LLVMDoubleType (), dname);
5074 case OP_FCONV_TO_R4:
5075 v = LLVMBuildFPTrunc (builder, lhs, LLVMFloatType (), "");
5077 values [ins->dreg] = v;
5079 values [ins->dreg] = LLVMBuildFPExt (builder, v, LLVMDoubleType (), dname);
5081 case OP_RCONV_TO_R8:
5082 values [ins->dreg] = LLVMBuildFPExt (builder, lhs, LLVMDoubleType (), dname);
5084 case OP_RCONV_TO_R4:
5085 values [ins->dreg] = lhs;
5088 values [ins->dreg] = LLVMBuildSExt (builder, convert (ctx, lhs, LLVMInt32Type ()), LLVMInt64Type (), dname);
5091 values [ins->dreg] = LLVMBuildZExt (builder, convert (ctx, lhs, LLVMInt32Type ()), LLVMInt64Type (), dname);
5094 values [ins->dreg] = LLVMBuildTrunc (builder, lhs, LLVMInt32Type (), dname);
5096 case OP_LOCALLOC_IMM: {
5099 guint32 size = ins->inst_imm;
5100 size = (size + (MONO_ARCH_FRAME_ALIGNMENT - 1)) & ~ (MONO_ARCH_FRAME_ALIGNMENT - 1);
5102 v = mono_llvm_build_alloca (builder, LLVMInt8Type (), LLVMConstInt (LLVMInt32Type (), size, FALSE), MONO_ARCH_FRAME_ALIGNMENT, "");
5104 if (ins->flags & MONO_INST_INIT) {
5105 LLVMValueRef args [5];
5108 args [1] = LLVMConstInt (LLVMInt8Type (), 0, FALSE);
5109 args [2] = LLVMConstInt (LLVMInt32Type (), size, FALSE);
5110 args [3] = LLVMConstInt (LLVMInt32Type (), MONO_ARCH_FRAME_ALIGNMENT, FALSE);
5111 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
5112 LLVMBuildCall (builder, get_intrinsic (ctx, "llvm.memset.p0i8.i32"), args, 5, "");
5115 values [ins->dreg] = v;
5119 LLVMValueRef v, size;
5121 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), "");
5123 v = mono_llvm_build_alloca (builder, LLVMInt8Type (), size, MONO_ARCH_FRAME_ALIGNMENT, "");
5125 if (ins->flags & MONO_INST_INIT) {
5126 LLVMValueRef args [5];
5129 args [1] = LLVMConstInt (LLVMInt8Type (), 0, FALSE);
5131 args [3] = LLVMConstInt (LLVMInt32Type (), MONO_ARCH_FRAME_ALIGNMENT, FALSE);
5132 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
5133 LLVMBuildCall (builder, get_intrinsic (ctx, "llvm.memset.p0i8.i32"), args, 5, "");
5135 values [ins->dreg] = v;
5139 case OP_LOADI1_MEMBASE:
5140 case OP_LOADU1_MEMBASE:
5141 case OP_LOADI2_MEMBASE:
5142 case OP_LOADU2_MEMBASE:
5143 case OP_LOADI4_MEMBASE:
5144 case OP_LOADU4_MEMBASE:
5145 case OP_LOADI8_MEMBASE:
5146 case OP_LOADR4_MEMBASE:
5147 case OP_LOADR8_MEMBASE:
5148 case OP_LOAD_MEMBASE:
5156 LLVMValueRef base, index, addr;
5158 gboolean sext = FALSE, zext = FALSE;
5159 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
5161 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
5166 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)) {
5167 addr = LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE);
5173 if (ins->inst_offset == 0) {
5175 } else if (ins->inst_offset % size != 0) {
5176 /* Unaligned load */
5177 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset, FALSE);
5178 addr = LLVMBuildGEP (builder, convert (ctx, base, LLVMPointerType (LLVMInt8Type (), 0)), &index, 1, "");
5180 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
5181 addr = LLVMBuildGEP (builder, convert (ctx, base, LLVMPointerType (t, 0)), &index, 1, "");
5185 addr = convert (ctx, addr, LLVMPointerType (t, 0));
5187 values [ins->dreg] = emit_load_general (ctx, bb, &builder, size, addr, base, dname, is_volatile, LLVM_BARRIER_NONE);
5189 if (!is_volatile && (ins->flags & MONO_INST_INVARIANT_LOAD)) {
5191 * These will signal LLVM that these loads do not alias any stores, and
5192 * they can't fail, allowing them to be hoisted out of loops.
5194 set_invariant_load_flag (values [ins->dreg]);
5195 #if LLVM_API_VERSION < 100
5196 set_metadata_flag (values [ins->dreg], "mono.nofail.load");
5201 values [ins->dreg] = LLVMBuildSExt (builder, values [ins->dreg], LLVMInt32Type (), dname);
5203 values [ins->dreg] = LLVMBuildZExt (builder, values [ins->dreg], LLVMInt32Type (), dname);
5204 else if (!cfg->r4fp && ins->opcode == OP_LOADR4_MEMBASE)
5205 values [ins->dreg] = LLVMBuildFPExt (builder, values [ins->dreg], LLVMDoubleType (), dname);
5209 case OP_STOREI1_MEMBASE_REG:
5210 case OP_STOREI2_MEMBASE_REG:
5211 case OP_STOREI4_MEMBASE_REG:
5212 case OP_STOREI8_MEMBASE_REG:
5213 case OP_STORER4_MEMBASE_REG:
5214 case OP_STORER8_MEMBASE_REG:
5215 case OP_STORE_MEMBASE_REG: {
5217 LLVMValueRef index, addr, base;
5219 gboolean sext = FALSE, zext = FALSE;
5220 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
5222 if (!values [ins->inst_destbasereg]) {
5223 set_failure (ctx, "inst_destbasereg");
5227 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
5229 base = values [ins->inst_destbasereg];
5230 if (ins->inst_offset % size != 0) {
5231 /* Unaligned store */
5232 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset, FALSE);
5233 addr = LLVMBuildGEP (builder, convert (ctx, base, LLVMPointerType (LLVMInt8Type (), 0)), &index, 1, "");
5235 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
5236 addr = LLVMBuildGEP (builder, convert (ctx, base, LLVMPointerType (t, 0)), &index, 1, "");
5238 emit_store (ctx, bb, &builder, size, convert (ctx, values [ins->sreg1], t), convert (ctx, addr, LLVMPointerType (t, 0)), base, is_volatile);
5242 case OP_STOREI1_MEMBASE_IMM:
5243 case OP_STOREI2_MEMBASE_IMM:
5244 case OP_STOREI4_MEMBASE_IMM:
5245 case OP_STOREI8_MEMBASE_IMM:
5246 case OP_STORE_MEMBASE_IMM: {
5248 LLVMValueRef index, addr, base;
5250 gboolean sext = FALSE, zext = FALSE;
5251 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
5253 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
5255 base = values [ins->inst_destbasereg];
5256 if (ins->inst_offset % size != 0) {
5257 /* Unaligned store */
5258 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset, FALSE);
5259 addr = LLVMBuildGEP (builder, convert (ctx, base, LLVMPointerType (LLVMInt8Type (), 0)), &index, 1, "");
5261 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
5262 addr = LLVMBuildGEP (builder, convert (ctx, base, LLVMPointerType (t, 0)), &index, 1, "");
5264 emit_store (ctx, bb, &builder, size, convert (ctx, LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE), t), convert (ctx, addr, LLVMPointerType (t, 0)), base, is_volatile);
5269 emit_load_general (ctx, bb, &builder, sizeof (gpointer), convert (ctx, lhs, LLVMPointerType (IntPtrType (), 0)), lhs, "", TRUE, LLVM_BARRIER_NONE);
5271 case OP_OUTARG_VTRETADDR:
5279 case OP_VOIDCALL_MEMBASE:
5280 case OP_CALL_MEMBASE:
5281 case OP_LCALL_MEMBASE:
5282 case OP_FCALL_MEMBASE:
5283 case OP_RCALL_MEMBASE:
5284 case OP_VCALL_MEMBASE:
5285 case OP_VOIDCALL_REG:
5290 case OP_VCALL_REG: {
5291 process_call (ctx, bb, &builder, ins);
5296 LLVMValueRef indexes [2];
5297 MonoJumpInfo *tmp_ji, *ji;
5298 LLVMValueRef got_entry_addr;
5302 * FIXME: Can't allocate from the cfg mempool since that is freed if
5303 * the LLVM compile fails.
5305 tmp_ji = g_new0 (MonoJumpInfo, 1);
5306 tmp_ji->type = (MonoJumpInfoType)ins->inst_c1;
5307 tmp_ji->data.target = ins->inst_p0;
5309 ji = mono_aot_patch_info_dup (tmp_ji);
5312 if (ji->type == MONO_PATCH_INFO_ICALL_ADDR) {
5313 char *symbol = mono_aot_get_direct_call_symbol (MONO_PATCH_INFO_ICALL_ADDR_CALL, ji->data.target);
5316 * Avoid emitting a got entry for these since the method is directly called, and it might not be
5317 * resolvable at runtime using dlsym ().
5320 values [ins->dreg] = LLVMConstInt (IntPtrType (), 0, FALSE);
5325 ji->next = cfg->patch_info;
5326 cfg->patch_info = ji;
5328 //mono_add_patch_info (cfg, 0, (MonoJumpInfoType)ins->inst_i1, ins->inst_p0);
5329 got_offset = mono_aot_get_got_offset (cfg->patch_info);
5330 ctx->module->max_got_offset = MAX (ctx->module->max_got_offset, got_offset);
5331 if (!mono_aot_is_shared_got_offset (got_offset)) {
5332 //mono_print_ji (ji);
5334 ctx->has_got_access = TRUE;
5337 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
5338 indexes [1] = LLVMConstInt (LLVMInt32Type (), (gssize)got_offset, FALSE);
5339 got_entry_addr = LLVMBuildGEP (builder, ctx->module->got_var, indexes, 2, "");
5341 name = get_aotconst_name (ji->type, ji->data.target, got_offset);
5342 values [ins->dreg] = LLVMBuildLoad (builder, got_entry_addr, name);
5344 /* Can't use this in llvmonly mode since the got slots are initialized by the methods themselves */
5345 if (!cfg->llvm_only)
5346 set_invariant_load_flag (values [ins->dreg]);
5349 case OP_NOT_REACHED:
5350 LLVMBuildUnreachable (builder);
5351 has_terminator = TRUE;
5352 g_assert (bb->block_num < cfg->max_block_num);
5353 ctx->unreachable [bb->block_num] = TRUE;
5354 /* Might have instructions after this */
5356 MonoInst *next = ins->next;
5358 * FIXME: If later code uses the regs defined by these instructions,
5359 * compilation will fail.
5361 MONO_DELETE_INS (bb, next);
5365 MonoInst *var = ins->inst_i0;
5367 if (var->opcode == OP_VTARG_ADDR) {
5368 /* The variable contains the vtype address */
5369 values [ins->dreg] = values [var->dreg];
5370 } else if (var->opcode == OP_GSHAREDVT_LOCAL) {
5371 values [ins->dreg] = emit_gsharedvt_ldaddr (ctx, var->dreg);
5373 values [ins->dreg] = addresses [var->dreg];
5378 LLVMValueRef args [1];
5380 args [0] = convert (ctx, lhs, LLVMDoubleType ());
5381 values [ins->dreg] = LLVMBuildCall (builder, get_intrinsic (ctx, "llvm.sin.f64"), args, 1, dname);
5385 LLVMValueRef args [1];
5387 args [0] = convert (ctx, lhs, LLVMDoubleType ());
5388 values [ins->dreg] = LLVMBuildCall (builder, get_intrinsic (ctx, "llvm.cos.f64"), args, 1, dname);
5392 LLVMValueRef args [1];
5394 args [0] = convert (ctx, lhs, LLVMDoubleType ());
5395 values [ins->dreg] = LLVMBuildCall (builder, get_intrinsic (ctx, "llvm.sqrt.f64"), args, 1, dname);
5399 LLVMValueRef args [1];
5401 args [0] = convert (ctx, lhs, LLVMDoubleType ());
5402 values [ins->dreg] = LLVMBuildCall (builder, get_intrinsic (ctx, "fabs"), args, 1, dname);
5416 lhs = convert (ctx, lhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
5417 rhs = convert (ctx, rhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
5419 switch (ins->opcode) {
5422 v = LLVMBuildICmp (builder, LLVMIntSLE, lhs, rhs, "");
5426 v = LLVMBuildICmp (builder, LLVMIntSGE, lhs, rhs, "");
5430 v = LLVMBuildICmp (builder, LLVMIntULE, lhs, rhs, "");
5434 v = LLVMBuildICmp (builder, LLVMIntUGE, lhs, rhs, "");
5437 g_assert_not_reached ();
5440 values [ins->dreg] = LLVMBuildSelect (builder, v, lhs, rhs, dname);
5445 * See the ARM64 comment in mono/utils/atomic.h for an explanation of why this
5446 * hack is necessary (for now).
5449 #define ARM64_ATOMIC_FENCE_FIX mono_llvm_build_fence (builder, LLVM_BARRIER_SEQ)
5451 #define ARM64_ATOMIC_FENCE_FIX
5454 case OP_ATOMIC_EXCHANGE_I4:
5455 case OP_ATOMIC_EXCHANGE_I8: {
5456 LLVMValueRef args [2];
5459 if (ins->opcode == OP_ATOMIC_EXCHANGE_I4)
5460 t = LLVMInt32Type ();
5462 t = LLVMInt64Type ();
5464 g_assert (ins->inst_offset == 0);
5466 args [0] = convert (ctx, lhs, LLVMPointerType (t, 0));
5467 args [1] = convert (ctx, rhs, t);
5469 ARM64_ATOMIC_FENCE_FIX;
5470 values [ins->dreg] = mono_llvm_build_atomic_rmw (builder, LLVM_ATOMICRMW_OP_XCHG, args [0], args [1]);
5471 ARM64_ATOMIC_FENCE_FIX;
5474 case OP_ATOMIC_ADD_I4:
5475 case OP_ATOMIC_ADD_I8: {
5476 LLVMValueRef args [2];
5479 if (ins->opcode == OP_ATOMIC_ADD_I4)
5480 t = LLVMInt32Type ();
5482 t = LLVMInt64Type ();
5484 g_assert (ins->inst_offset == 0);
5486 args [0] = convert (ctx, lhs, LLVMPointerType (t, 0));
5487 args [1] = convert (ctx, rhs, t);
5488 ARM64_ATOMIC_FENCE_FIX;
5489 values [ins->dreg] = LLVMBuildAdd (builder, mono_llvm_build_atomic_rmw (builder, LLVM_ATOMICRMW_OP_ADD, args [0], args [1]), args [1], dname);
5490 ARM64_ATOMIC_FENCE_FIX;
5493 case OP_ATOMIC_CAS_I4:
5494 case OP_ATOMIC_CAS_I8: {
5495 LLVMValueRef args [3], val;
5498 if (ins->opcode == OP_ATOMIC_CAS_I4)
5499 t = LLVMInt32Type ();
5501 t = LLVMInt64Type ();
5503 args [0] = convert (ctx, lhs, LLVMPointerType (t, 0));
5505 args [1] = convert (ctx, values [ins->sreg3], t);
5507 args [2] = convert (ctx, values [ins->sreg2], t);
5508 ARM64_ATOMIC_FENCE_FIX;
5509 val = mono_llvm_build_cmpxchg (builder, args [0], args [1], args [2]);
5510 ARM64_ATOMIC_FENCE_FIX;
5511 /* cmpxchg returns a pair */
5512 values [ins->dreg] = LLVMBuildExtractValue (builder, val, 0, "");
5515 case OP_MEMORY_BARRIER: {
5516 mono_llvm_build_fence (builder, (BarrierKind) ins->backend.memory_barrier_kind);
5519 case OP_ATOMIC_LOAD_I1:
5520 case OP_ATOMIC_LOAD_I2:
5521 case OP_ATOMIC_LOAD_I4:
5522 case OP_ATOMIC_LOAD_I8:
5523 case OP_ATOMIC_LOAD_U1:
5524 case OP_ATOMIC_LOAD_U2:
5525 case OP_ATOMIC_LOAD_U4:
5526 case OP_ATOMIC_LOAD_U8:
5527 case OP_ATOMIC_LOAD_R4:
5528 case OP_ATOMIC_LOAD_R8: {
5529 #if LLVM_API_VERSION > 100
5531 gboolean sext, zext;
5533 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
5534 BarrierKind barrier = (BarrierKind) ins->backend.memory_barrier_kind;
5535 LLVMValueRef index, addr;
5537 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
5542 if (ins->inst_offset != 0) {
5543 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
5544 addr = LLVMBuildGEP (builder, convert (ctx, lhs, LLVMPointerType (t, 0)), &index, 1, "");
5549 addr = convert (ctx, addr, LLVMPointerType (t, 0));
5551 ARM64_ATOMIC_FENCE_FIX;
5552 values [ins->dreg] = emit_load_general (ctx, bb, &builder, size, addr, lhs, dname, is_volatile, barrier);
5553 ARM64_ATOMIC_FENCE_FIX;
5556 values [ins->dreg] = LLVMBuildSExt (builder, values [ins->dreg], LLVMInt32Type (), dname);
5558 values [ins->dreg] = LLVMBuildZExt (builder, values [ins->dreg], LLVMInt32Type (), dname);
5561 set_failure (ctx, "atomic mono.load intrinsic");
5565 case OP_ATOMIC_STORE_I1:
5566 case OP_ATOMIC_STORE_I2:
5567 case OP_ATOMIC_STORE_I4:
5568 case OP_ATOMIC_STORE_I8:
5569 case OP_ATOMIC_STORE_U1:
5570 case OP_ATOMIC_STORE_U2:
5571 case OP_ATOMIC_STORE_U4:
5572 case OP_ATOMIC_STORE_U8:
5573 case OP_ATOMIC_STORE_R4:
5574 case OP_ATOMIC_STORE_R8: {
5576 gboolean sext, zext;
5578 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
5579 BarrierKind barrier = (BarrierKind) ins->backend.memory_barrier_kind;
5580 LLVMValueRef index, addr, value, base;
5582 #if LLVM_API_VERSION < 100
5583 if (!cfg->llvm_only) {
5584 set_failure (ctx, "atomic mono.store intrinsic");
5589 if (!values [ins->inst_destbasereg]) {
5590 set_failure (ctx, "inst_destbasereg");
5594 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
5596 base = values [ins->inst_destbasereg];
5597 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
5598 addr = LLVMBuildGEP (builder, convert (ctx, base, LLVMPointerType (t, 0)), &index, 1, "");
5599 value = convert (ctx, values [ins->sreg1], t);
5601 ARM64_ATOMIC_FENCE_FIX;
5602 emit_store_general (ctx, bb, &builder, size, value, addr, base, is_volatile, barrier);
5603 ARM64_ATOMIC_FENCE_FIX;
5606 case OP_RELAXED_NOP: {
5607 #if defined(TARGET_AMD64) || defined(TARGET_X86)
5608 emit_call (ctx, bb, &builder, get_intrinsic (ctx, "llvm.x86.sse2.pause"), NULL, 0);
5614 case OP_GC_SAFE_POINT: {
5615 LLVMValueRef val, cmp, callee;
5616 LLVMBasicBlockRef poll_bb, cont_bb;
5617 static LLVMTypeRef sig;
5618 const char *icall_name = "mono_threads_state_poll";
5621 sig = LLVMFunctionType0 (LLVMVoidType (), FALSE);
5625 * mono_threads_state_poll ();
5626 * FIXME: Use a preserveall wrapper
5628 val = mono_llvm_build_load (builder, convert (ctx, lhs, LLVMPointerType (IntPtrType (), 0)), "", TRUE);
5629 cmp = LLVMBuildICmp (builder, LLVMIntEQ, val, LLVMConstNull (LLVMTypeOf (val)), "");
5630 poll_bb = gen_bb (ctx, "POLL_BB");
5631 cont_bb = gen_bb (ctx, "CONT_BB");
5632 LLVMBuildCondBr (builder, cmp, cont_bb, poll_bb);
5634 ctx->builder = builder = create_builder (ctx);
5635 LLVMPositionBuilderAtEnd (builder, poll_bb);
5637 if (ctx->cfg->compile_aot) {
5638 callee = get_callee (ctx, sig, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
5640 gpointer target = resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
5641 callee = emit_jit_callee (ctx, icall_name, sig, target);
5643 LLVMBuildCall (builder, callee, NULL, 0, "");
5644 LLVMBuildBr (builder, cont_bb);
5646 ctx->builder = builder = create_builder (ctx);
5647 LLVMPositionBuilderAtEnd (builder, cont_bb);
5648 ctx->bblocks [bb->block_num].end_bblock = cont_bb;
5656 case OP_IADD_OVF_UN:
5658 case OP_ISUB_OVF_UN:
5660 case OP_IMUL_OVF_UN:
5662 case OP_LADD_OVF_UN:
5664 case OP_LSUB_OVF_UN:
5666 case OP_LMUL_OVF_UN:
5668 LLVMValueRef args [2], val, ovf, func;
5670 args [0] = convert (ctx, lhs, op_to_llvm_type (ins->opcode));
5671 args [1] = convert (ctx, rhs, op_to_llvm_type (ins->opcode));
5672 func = get_intrinsic (ctx, ovf_op_to_intrins (ins->opcode));
5674 val = LLVMBuildCall (builder, func, args, 2, "");
5675 values [ins->dreg] = LLVMBuildExtractValue (builder, val, 0, dname);
5676 ovf = LLVMBuildExtractValue (builder, val, 1, "");
5677 emit_cond_system_exception (ctx, bb, "OverflowException", ovf);
5680 builder = ctx->builder;
5686 * We currently model them using arrays. Promotion to local vregs is
5687 * disabled for them in mono_handle_global_vregs () in the LLVM case,
5688 * so we always have an entry in cfg->varinfo for them.
5689 * FIXME: Is this needed ?
5692 MonoClass *klass = ins->klass;
5693 LLVMValueRef args [5];
5697 set_failure (ctx, "!klass");
5701 if (!addresses [ins->dreg])
5702 addresses [ins->dreg] = build_alloca (ctx, &klass->byval_arg);
5703 args [0] = LLVMBuildBitCast (builder, addresses [ins->dreg], LLVMPointerType (LLVMInt8Type (), 0), "");
5704 args [1] = LLVMConstInt (LLVMInt8Type (), 0, FALSE);
5705 args [2] = LLVMConstInt (LLVMInt32Type (), mono_class_value_size (klass, NULL), FALSE);
5707 args [3] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
5708 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
5709 LLVMBuildCall (builder, get_intrinsic (ctx, "llvm.memset.p0i8.i32"), args, 5, "");
5712 case OP_DUMMY_VZERO:
5715 case OP_STOREV_MEMBASE:
5716 case OP_LOADV_MEMBASE:
5718 MonoClass *klass = ins->klass;
5719 LLVMValueRef src = NULL, dst, args [5];
5720 gboolean done = FALSE;
5724 set_failure (ctx, "!klass");
5728 if (mini_is_gsharedvt_klass (klass)) {
5730 set_failure (ctx, "gsharedvt");
5734 switch (ins->opcode) {
5735 case OP_STOREV_MEMBASE:
5736 if (cfg->gen_write_barriers && klass->has_references && ins->inst_destbasereg != cfg->frame_reg &&
5737 LLVMGetInstructionOpcode (values [ins->inst_destbasereg]) != LLVMAlloca) {
5738 /* Decomposed earlier */
5739 g_assert_not_reached ();
5742 if (!addresses [ins->sreg1]) {
5744 g_assert (values [ins->sreg1]);
5745 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));
5746 LLVMBuildStore (builder, values [ins->sreg1], dst);
5749 src = LLVMBuildBitCast (builder, addresses [ins->sreg1], LLVMPointerType (LLVMInt8Type (), 0), "");
5750 dst = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_destbasereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (LLVMInt8Type (), 0));
5753 case OP_LOADV_MEMBASE:
5754 if (!addresses [ins->dreg])
5755 addresses [ins->dreg] = build_alloca (ctx, &klass->byval_arg);
5756 src = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_basereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (LLVMInt8Type (), 0));
5757 dst = LLVMBuildBitCast (builder, addresses [ins->dreg], LLVMPointerType (LLVMInt8Type (), 0), "");
5760 if (!addresses [ins->sreg1])
5761 addresses [ins->sreg1] = build_alloca (ctx, &klass->byval_arg);
5762 if (!addresses [ins->dreg])
5763 addresses [ins->dreg] = build_alloca (ctx, &klass->byval_arg);
5764 src = LLVMBuildBitCast (builder, addresses [ins->sreg1], LLVMPointerType (LLVMInt8Type (), 0), "");
5765 dst = LLVMBuildBitCast (builder, addresses [ins->dreg], LLVMPointerType (LLVMInt8Type (), 0), "");
5768 g_assert_not_reached ();
5778 args [2] = LLVMConstInt (LLVMInt32Type (), mono_class_value_size (klass, NULL), FALSE);
5779 args [3] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
5781 args [3] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
5782 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
5783 LLVMBuildCall (builder, get_intrinsic (ctx, "llvm.memcpy.p0i8.p0i8.i32"), args, 5, "");
5786 case OP_LLVM_OUTARG_VT: {
5787 LLVMArgInfo *ainfo = (LLVMArgInfo*)ins->inst_p0;
5788 MonoType *t = mini_get_underlying_type (ins->inst_vtype);
5790 if (ainfo->storage == LLVMArgGsharedvtVariable) {
5791 MonoInst *var = get_vreg_to_inst (cfg, ins->sreg1);
5793 if (var && var->opcode == OP_GSHAREDVT_LOCAL) {
5794 addresses [ins->dreg] = convert (ctx, emit_gsharedvt_ldaddr (ctx, var->dreg), LLVMPointerType (IntPtrType (), 0));
5796 g_assert (addresses [ins->sreg1]);
5797 addresses [ins->dreg] = addresses [ins->sreg1];
5799 } else if (ainfo->storage == LLVMArgGsharedvtFixed) {
5800 if (!addresses [ins->sreg1]) {
5801 addresses [ins->sreg1] = build_alloca (ctx, t);
5802 g_assert (values [ins->sreg1]);
5804 LLVMBuildStore (builder, convert (ctx, values [ins->sreg1], LLVMGetElementType (LLVMTypeOf (addresses [ins->sreg1]))), addresses [ins->sreg1]);
5805 addresses [ins->dreg] = addresses [ins->sreg1];
5807 if (!addresses [ins->sreg1]) {
5808 addresses [ins->sreg1] = build_alloca (ctx, t);
5809 g_assert (values [ins->sreg1]);
5810 LLVMBuildStore (builder, convert (ctx, values [ins->sreg1], type_to_llvm_type (ctx, t)), addresses [ins->sreg1]);
5812 addresses [ins->dreg] = addresses [ins->sreg1];
5816 case OP_OBJC_GET_SELECTOR: {
5817 const char *name = (const char*)ins->inst_p0;
5820 if (!ctx->module->objc_selector_to_var) {
5821 ctx->module->objc_selector_to_var = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
5823 LLVMValueRef info_var = LLVMAddGlobal (ctx->lmodule, LLVMArrayType (LLVMInt8Type (), 8), "@OBJC_IMAGE_INFO");
5824 int32_t objc_imageinfo [] = { 0, 16 };
5825 LLVMSetInitializer (info_var, mono_llvm_create_constant_data_array ((uint8_t *) &objc_imageinfo, 8));
5826 LLVMSetLinkage (info_var, LLVMPrivateLinkage);
5827 LLVMSetExternallyInitialized (info_var, TRUE);
5828 LLVMSetSection (info_var, "__DATA, __objc_imageinfo,regular,no_dead_strip");
5829 LLVMSetAlignment (info_var, sizeof (mgreg_t));
5830 mark_as_used (ctx->module, info_var);
5833 var = g_hash_table_lookup (ctx->module->objc_selector_to_var, name);
5835 LLVMValueRef indexes [16];
5837 LLVMValueRef name_var = LLVMAddGlobal (ctx->lmodule, LLVMArrayType (LLVMInt8Type (), strlen (name) + 1), "@OBJC_METH_VAR_NAME_");
5838 LLVMSetInitializer (name_var, mono_llvm_create_constant_data_array ((const uint8_t*)name, strlen (name) + 1));
5839 LLVMSetLinkage (name_var, LLVMPrivateLinkage);
5840 LLVMSetSection (name_var, "__TEXT,__objc_methname,cstring_literals");
5841 mark_as_used (ctx->module, name_var);
5843 LLVMValueRef ref_var = LLVMAddGlobal (ctx->lmodule, LLVMPointerType (LLVMInt8Type (), 0), "@OBJC_SELECTOR_REFERENCES_");
5845 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, 0);
5846 indexes [1] = LLVMConstInt (LLVMInt32Type (), 0, 0);
5847 LLVMSetInitializer (ref_var, LLVMConstGEP (name_var, indexes, 2));
5848 LLVMSetLinkage (ref_var, LLVMPrivateLinkage);
5849 LLVMSetExternallyInitialized (ref_var, TRUE);
5850 LLVMSetSection (ref_var, "__DATA, __objc_selrefs, literal_pointers, no_dead_strip");
5851 LLVMSetAlignment (ref_var, sizeof (mgreg_t));
5852 mark_as_used (ctx->module, ref_var);
5854 g_hash_table_insert (ctx->module->objc_selector_to_var, g_strdup (name), ref_var);
5858 values [ins->dreg] = LLVMBuildLoad (builder, var, "");
5865 #if defined(TARGET_X86) || defined(TARGET_AMD64)
5867 values [ins->dreg] = LLVMConstNull (type_to_llvm_type (ctx, &ins->klass->byval_arg));
5870 case OP_LOADX_MEMBASE: {
5871 LLVMTypeRef t = type_to_llvm_type (ctx, &ins->klass->byval_arg);
5874 src = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_basereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (t, 0));
5875 values [ins->dreg] = mono_llvm_build_aligned_load (builder, src, "", FALSE, 1);
5878 case OP_STOREX_MEMBASE: {
5879 LLVMTypeRef t = LLVMTypeOf (values [ins->sreg1]);
5882 dest = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_destbasereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (t, 0));
5883 mono_llvm_build_aligned_store (builder, values [ins->sreg1], dest, FALSE, 1);
5890 values [ins->dreg] = LLVMBuildAdd (builder, lhs, rhs, "");
5894 values [ins->dreg] = LLVMBuildFAdd (builder, lhs, rhs, "");
5900 values [ins->dreg] = LLVMBuildSub (builder, lhs, rhs, "");
5904 values [ins->dreg] = LLVMBuildFSub (builder, lhs, rhs, "");
5908 values [ins->dreg] = LLVMBuildFMul (builder, lhs, rhs, "");
5912 values [ins->dreg] = LLVMBuildFDiv (builder, lhs, rhs, "");
5915 values [ins->dreg] = LLVMBuildAnd (builder, lhs, rhs, "");
5918 values [ins->dreg] = LLVMBuildOr (builder, lhs, rhs, "");
5921 values [ins->dreg] = LLVMBuildXor (builder, lhs, rhs, "");
5925 values [ins->dreg] = LLVMBuildMul (builder, lhs, rhs, "");
5936 LLVMValueRef v = NULL;
5938 switch (ins->opcode) {
5943 t = LLVMVectorType (LLVMInt32Type (), 4);
5944 rt = LLVMVectorType (LLVMFloatType (), 4);
5950 t = LLVMVectorType (LLVMInt64Type (), 2);
5951 rt = LLVMVectorType (LLVMDoubleType (), 2);
5954 t = LLVMInt32Type ();
5955 rt = LLVMInt32Type ();
5956 g_assert_not_reached ();
5959 lhs = LLVMBuildBitCast (builder, lhs, t, "");
5960 rhs = LLVMBuildBitCast (builder, rhs, t, "");
5961 switch (ins->opcode) {
5964 v = LLVMBuildAnd (builder, lhs, rhs, "");
5968 v = LLVMBuildOr (builder, lhs, rhs, "");
5972 v = LLVMBuildXor (builder, lhs, rhs, "");
5976 v = LLVMBuildAnd (builder, rhs, LLVMBuildNot (builder, lhs, ""), "");
5979 values [ins->dreg] = LLVMBuildBitCast (builder, v, rt, "");
5985 LLVMValueRef cmp = LLVMBuildICmp (builder, LLVMIntULT, lhs, rhs, "");
5986 values [ins->dreg] = LLVMBuildSelect (builder, cmp, lhs, rhs, "");
5992 LLVMValueRef cmp = LLVMBuildICmp (builder, LLVMIntUGT, lhs, rhs, "");
5993 values [ins->dreg] = LLVMBuildSelect (builder, cmp, lhs, rhs, "");
5997 LLVMValueRef cmp = LLVMBuildICmp (builder, LLVMIntSLT, lhs, rhs, "");
5998 values [ins->dreg] = LLVMBuildSelect (builder, cmp, lhs, rhs, "");
6015 case OP_PADDB_SAT_UN:
6016 case OP_PADDW_SAT_UN:
6017 case OP_PSUBB_SAT_UN:
6018 case OP_PSUBW_SAT_UN:
6026 case OP_PMULW_HIGH_UN: {
6027 LLVMValueRef args [2];
6032 values [ins->dreg] = LLVMBuildCall (builder, get_intrinsic (ctx, simd_op_to_intrins (ins->opcode)), args, 2, dname);
6039 values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildICmp (builder, LLVMIntEQ, lhs, rhs, ""), LLVMTypeOf (lhs), "");
6043 values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildICmp (builder, LLVMIntSGT, lhs, rhs, ""), LLVMTypeOf (lhs), "");
6051 case OP_EXTRACTX_U2:
6053 case OP_EXTRACT_U1: {
6055 gboolean zext = FALSE;
6057 t = simd_op_to_llvm_type (ins->opcode);
6059 switch (ins->opcode) {
6067 case OP_EXTRACTX_U2:
6072 t = LLVMInt32Type ();
6073 g_assert_not_reached ();
6076 lhs = LLVMBuildBitCast (builder, lhs, t, "");
6077 values [ins->dreg] = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), "");
6079 values [ins->dreg] = LLVMBuildZExt (builder, values [ins->dreg], LLVMInt32Type (), "");
6088 case OP_EXPAND_R8: {
6089 LLVMTypeRef t = simd_op_to_llvm_type (ins->opcode);
6090 LLVMValueRef mask [16], v;
6093 for (i = 0; i < 16; ++i)
6094 mask [i] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
6096 v = convert (ctx, values [ins->sreg1], LLVMGetElementType (t));
6098 values [ins->dreg] = LLVMBuildInsertElement (builder, LLVMConstNull (t), v, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
6099 values [ins->dreg] = LLVMBuildShuffleVector (builder, values [ins->dreg], LLVMGetUndef (t), LLVMConstVector (mask, LLVMGetVectorSize (t)), "");
6104 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt8Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
6107 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt16Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
6110 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt32Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
6113 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt64Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
6116 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMFloatType ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
6119 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMDoubleType ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
6123 // Requires a later llvm version
6125 LLVMValueRef indexes [16];
6127 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
6128 indexes [1] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
6129 LLVMValueRef mask = LLVMConstVector (indexes, 2);
6130 LLVMValueRef shuffle = LLVMBuildShuffleVector (builder, lhs, LLVMConstNull (LLVMTypeOf (lhs)), mask, "");
6131 values [ins->dreg] = LLVMBuildSIToFP (builder, shuffle, LLVMVectorType (LLVMDoubleType (), 2), dname);
6135 LLVMValueRef indexes [16];
6137 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
6138 indexes [1] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
6139 LLVMValueRef mask = LLVMConstVector (indexes, 2);
6140 LLVMValueRef shuffle = LLVMBuildShuffleVector (builder, lhs, LLVMConstNull (LLVMTypeOf (lhs)), mask, "");
6141 values [ins->dreg] = LLVMBuildFPExt (builder, shuffle, LLVMVectorType (LLVMDoubleType (), 2), dname);
6145 values [ins->dreg] = LLVMBuildFPToSI (builder, lhs, LLVMVectorType (LLVMInt32Type (), 4), dname);
6157 case OP_EXTRACT_MASK:
6164 v = convert (ctx, values [ins->sreg1], simd_op_to_llvm_type (ins->opcode));
6166 values [ins->dreg] = LLVMBuildCall (builder, get_intrinsic (ctx, simd_op_to_intrins (ins->opcode)), &v, 1, dname);
6171 LLVMRealPredicate op;
6173 switch (ins->inst_c0) {
6183 case SIMD_COMP_UNORD:
6199 g_assert_not_reached ();
6202 LLVMValueRef cmp = LLVMBuildFCmp (builder, op, lhs, rhs, "");
6203 if (ins->opcode == OP_COMPPD)
6204 values [ins->dreg] = LLVMBuildBitCast (builder, LLVMBuildSExt (builder, cmp, LLVMVectorType (LLVMInt64Type (), 2), ""), LLVMTypeOf (lhs), "");
6206 values [ins->dreg] = LLVMBuildBitCast (builder, LLVMBuildSExt (builder, cmp, LLVMVectorType (LLVMInt32Type (), 4), ""), LLVMTypeOf (lhs), "");
6210 /* This is only used for implementing shifts by non-immediate */
6211 values [ins->dreg] = lhs;
6222 LLVMValueRef args [3];
6225 args [1] = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
6227 values [ins->dreg] = LLVMBuildCall (builder, get_intrinsic (ctx, simd_op_to_intrins (ins->opcode)), args, 2, dname);
6238 case OP_PSHLQ_REG: {
6239 LLVMValueRef args [3];
6242 args [1] = values [ins->sreg2];
6244 values [ins->dreg] = LLVMBuildCall (builder, get_intrinsic (ctx, simd_op_to_intrins (ins->opcode)), args, 2, dname);
6251 case OP_PSHUFLEW_LOW:
6252 case OP_PSHUFLEW_HIGH: {
6254 LLVMValueRef v1 = NULL, v2 = NULL, mask_values [16];
6255 int i, mask_size = 0;
6256 int imask = ins->inst_c0;
6258 /* Convert the x86 shuffle mask to LLVM's */
6259 switch (ins->opcode) {
6262 mask [0] = ((imask >> 0) & 3);
6263 mask [1] = ((imask >> 2) & 3);
6264 mask [2] = ((imask >> 4) & 3) + 4;
6265 mask [3] = ((imask >> 6) & 3) + 4;
6266 v1 = values [ins->sreg1];
6267 v2 = values [ins->sreg2];
6271 mask [0] = ((imask >> 0) & 1);
6272 mask [1] = ((imask >> 1) & 1) + 2;
6273 v1 = values [ins->sreg1];
6274 v2 = values [ins->sreg2];
6276 case OP_PSHUFLEW_LOW:
6278 mask [0] = ((imask >> 0) & 3);
6279 mask [1] = ((imask >> 2) & 3);
6280 mask [2] = ((imask >> 4) & 3);
6281 mask [3] = ((imask >> 6) & 3);
6286 v1 = values [ins->sreg1];
6287 v2 = LLVMGetUndef (LLVMTypeOf (v1));
6289 case OP_PSHUFLEW_HIGH:
6295 mask [4] = 4 + ((imask >> 0) & 3);
6296 mask [5] = 4 + ((imask >> 2) & 3);
6297 mask [6] = 4 + ((imask >> 4) & 3);
6298 mask [7] = 4 + ((imask >> 6) & 3);
6299 v1 = values [ins->sreg1];
6300 v2 = LLVMGetUndef (LLVMTypeOf (v1));
6304 mask [0] = ((imask >> 0) & 3);
6305 mask [1] = ((imask >> 2) & 3);
6306 mask [2] = ((imask >> 4) & 3);
6307 mask [3] = ((imask >> 6) & 3);
6308 v1 = values [ins->sreg1];
6309 v2 = LLVMGetUndef (LLVMTypeOf (v1));
6312 g_assert_not_reached ();
6314 for (i = 0; i < mask_size; ++i)
6315 mask_values [i] = LLVMConstInt (LLVMInt32Type (), mask [i], FALSE);
6317 values [ins->dreg] =
6318 LLVMBuildShuffleVector (builder, v1, v2,
6319 LLVMConstVector (mask_values, mask_size), dname);
6323 case OP_UNPACK_LOWB:
6324 case OP_UNPACK_LOWW:
6325 case OP_UNPACK_LOWD:
6326 case OP_UNPACK_LOWQ:
6327 case OP_UNPACK_LOWPS:
6328 case OP_UNPACK_LOWPD:
6329 case OP_UNPACK_HIGHB:
6330 case OP_UNPACK_HIGHW:
6331 case OP_UNPACK_HIGHD:
6332 case OP_UNPACK_HIGHQ:
6333 case OP_UNPACK_HIGHPS:
6334 case OP_UNPACK_HIGHPD: {
6336 LLVMValueRef mask_values [16];
6337 int i, mask_size = 0;
6338 gboolean low = FALSE;
6340 switch (ins->opcode) {
6341 case OP_UNPACK_LOWB:
6345 case OP_UNPACK_LOWW:
6349 case OP_UNPACK_LOWD:
6350 case OP_UNPACK_LOWPS:
6354 case OP_UNPACK_LOWQ:
6355 case OP_UNPACK_LOWPD:
6359 case OP_UNPACK_HIGHB:
6362 case OP_UNPACK_HIGHW:
6365 case OP_UNPACK_HIGHD:
6366 case OP_UNPACK_HIGHPS:
6369 case OP_UNPACK_HIGHQ:
6370 case OP_UNPACK_HIGHPD:
6374 g_assert_not_reached ();
6378 for (i = 0; i < (mask_size / 2); ++i) {
6380 mask [(i * 2) + 1] = mask_size + i;
6383 for (i = 0; i < (mask_size / 2); ++i) {
6384 mask [(i * 2)] = (mask_size / 2) + i;
6385 mask [(i * 2) + 1] = mask_size + (mask_size / 2) + i;
6389 for (i = 0; i < mask_size; ++i)
6390 mask_values [i] = LLVMConstInt (LLVMInt32Type (), mask [i], FALSE);
6392 values [ins->dreg] =
6393 LLVMBuildShuffleVector (builder, values [ins->sreg1], values [ins->sreg2],
6394 LLVMConstVector (mask_values, mask_size), dname);
6399 LLVMTypeRef t = simd_op_to_llvm_type (ins->opcode);
6400 LLVMValueRef v, val;
6402 v = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
6403 val = LLVMConstNull (t);
6404 val = LLVMBuildInsertElement (builder, val, v, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
6405 val = LLVMBuildInsertElement (builder, val, v, LLVMConstInt (LLVMInt32Type (), 1, FALSE), dname);
6407 values [ins->dreg] = val;
6411 case OP_DUPPS_HIGH: {
6412 LLVMTypeRef t = simd_op_to_llvm_type (ins->opcode);
6413 LLVMValueRef v1, v2, val;
6416 if (ins->opcode == OP_DUPPS_LOW) {
6417 v1 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
6418 v2 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 2, FALSE), "");
6420 v1 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 1, FALSE), "");
6421 v2 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 3, FALSE), "");
6423 val = LLVMConstNull (t);
6424 val = LLVMBuildInsertElement (builder, val, v1, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
6425 val = LLVMBuildInsertElement (builder, val, v1, LLVMConstInt (LLVMInt32Type (), 1, FALSE), "");
6426 val = LLVMBuildInsertElement (builder, val, v2, LLVMConstInt (LLVMInt32Type (), 2, FALSE), "");
6427 val = LLVMBuildInsertElement (builder, val, v2, LLVMConstInt (LLVMInt32Type (), 3, FALSE), "");
6429 values [ins->dreg] = val;
6434 LLVMValueRef args [3];
6438 /* 0xf1 == multiply all 4 elements, add them together, and store the result to the lowest element */
6439 args [2] = LLVMConstInt (LLVMInt32Type (), 0xf1, FALSE);
6441 values [ins->dreg] = LLVMBuildCall (builder, get_intrinsic (ctx, simd_op_to_intrins (ins->opcode)), args, 3, dname);
6451 * EXCEPTION HANDLING
6453 case OP_IMPLICIT_EXCEPTION:
6454 /* This marks a place where an implicit exception can happen */
6455 if (bb->region != -1)
6456 set_failure (ctx, "implicit-exception");
6460 gboolean rethrow = (ins->opcode == OP_RETHROW);
6461 if (ctx->llvm_only) {
6462 emit_llvmonly_throw (ctx, bb, rethrow, lhs);
6463 has_terminator = TRUE;
6464 ctx->unreachable [bb->block_num] = TRUE;
6466 emit_throw (ctx, bb, rethrow, lhs);
6467 builder = ctx->builder;
6471 case OP_CALL_HANDLER: {
6473 * We don't 'call' handlers, but instead simply branch to them.
6474 * The code generated by ENDFINALLY will branch back to us.
6476 LLVMBasicBlockRef noex_bb;
6478 BBInfo *info = &bblocks [ins->inst_target_bb->block_num];
6480 bb_list = info->call_handler_return_bbs;
6483 * Set the indicator variable for the finally clause.
6485 lhs = info->finally_ind;
6487 LLVMBuildStore (builder, LLVMConstInt (LLVMInt32Type (), g_slist_length (bb_list) + 1, FALSE), lhs);
6489 /* Branch to the finally clause */
6490 LLVMBuildBr (builder, info->call_handler_target_bb);
6492 noex_bb = gen_bb (ctx, "CALL_HANDLER_CONT_BB");
6493 info->call_handler_return_bbs = g_slist_append_mempool (cfg->mempool, info->call_handler_return_bbs, noex_bb);
6495 builder = ctx->builder = create_builder (ctx);
6496 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
6498 bblocks [bb->block_num].end_bblock = noex_bb;
6501 case OP_START_HANDLER: {
6504 case OP_ENDFINALLY: {
6505 LLVMBasicBlockRef resume_bb;
6506 MonoBasicBlock *handler_bb;
6507 LLVMValueRef val, switch_ins, callee;
6511 handler_bb = (MonoBasicBlock*)g_hash_table_lookup (ctx->region_to_handler, GUINT_TO_POINTER (mono_get_block_region_notry (cfg, bb->region)));
6512 g_assert (handler_bb);
6513 info = &bblocks [handler_bb->block_num];
6514 lhs = info->finally_ind;
6517 bb_list = info->call_handler_return_bbs;
6519 resume_bb = gen_bb (ctx, "ENDFINALLY_RESUME_BB");
6521 /* Load the finally variable */
6522 val = LLVMBuildLoad (builder, lhs, "");
6524 /* Reset the variable */
6525 LLVMBuildStore (builder, LLVMConstInt (LLVMInt32Type (), 0, FALSE), lhs);
6527 /* Branch to either resume_bb, or to the bblocks in bb_list */
6528 switch_ins = LLVMBuildSwitch (builder, val, resume_bb, g_slist_length (bb_list));
6530 * The other targets are added at the end to handle OP_CALL_HANDLER
6531 * opcodes processed later.
6533 info->endfinally_switch_ins_list = g_slist_append_mempool (cfg->mempool, info->endfinally_switch_ins_list, switch_ins);
6535 builder = ctx->builder = create_builder (ctx);
6536 LLVMPositionBuilderAtEnd (ctx->builder, resume_bb);
6538 if (ctx->llvm_only) {
6539 emit_resume_eh (ctx, bb);
6541 if (ctx->cfg->compile_aot) {
6542 callee = get_callee (ctx, LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE), MONO_PATCH_INFO_INTERNAL_METHOD, "llvm_resume_unwind_trampoline");
6544 #if LLVM_API_VERSION > 100
6545 MonoJitICallInfo *info;
6547 info = mono_find_jit_icall_by_name ("llvm_resume_unwind_trampoline");
6549 gpointer target = (void*)info->func;
6550 LLVMTypeRef icall_sig = LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE);
6551 callee = emit_jit_callee (ctx, "llvm_resume_unwind_trampoline", icall_sig, target);
6553 callee = LLVMGetNamedFunction (ctx->lmodule, "llvm_resume_unwind_trampoline");
6556 LLVMBuildCall (builder, callee, NULL, 0, "");
6557 LLVMBuildUnreachable (builder);
6560 has_terminator = TRUE;
6563 case OP_IL_SEQ_POINT:
6568 sprintf (reason, "opcode %s", mono_inst_name (ins->opcode));
6569 set_failure (ctx, reason);
6577 /* Convert the value to the type required by phi nodes */
6578 if (spec [MONO_INST_DEST] != ' ' && !MONO_IS_STORE_MEMBASE (ins) && ctx->vreg_types [ins->dreg]) {
6579 if (ctx->is_vphi [ins->dreg])
6581 values [ins->dreg] = addresses [ins->dreg];
6583 values [ins->dreg] = convert (ctx, values [ins->dreg], ctx->vreg_types [ins->dreg]);
6586 /* Add stores for volatile variables */
6587 if (spec [MONO_INST_DEST] != ' ' && spec [MONO_INST_DEST] != 'v' && !MONO_IS_STORE_MEMBASE (ins))
6588 emit_volatile_store (ctx, ins->dreg);
6594 if (!has_terminator && bb->next_bb && (bb == cfg->bb_entry || bb->in_count > 0)) {
6595 LLVMBuildBr (builder, get_bb (ctx, bb->next_bb));
6598 if (bb == cfg->bb_exit && sig->ret->type == MONO_TYPE_VOID) {
6599 emit_dbg_loc (ctx, builder, cfg->header->code + cfg->header->code_size - 1);
6600 LLVMBuildRetVoid (builder);
6603 if (bb == cfg->bb_entry)
6604 ctx->last_alloca = LLVMGetLastInstruction (get_bb (ctx, cfg->bb_entry));
6608 * mono_llvm_check_method_supported:
6610 * Do some quick checks to decide whenever cfg->method can be compiled by LLVM, to avoid
6611 * compiling a method twice.
6614 mono_llvm_check_method_supported (MonoCompile *cfg)
6621 if (cfg->method->save_lmf) {
6622 cfg->exception_message = g_strdup ("lmf");
6623 cfg->disable_llvm = TRUE;
6625 if (cfg->disable_llvm)
6629 * Nested clauses where one of the clauses is a finally clause is
6630 * not supported, because LLVM can't figure out the control flow,
6631 * probably because we resume exception handling by calling our
6632 * own function instead of using the 'resume' llvm instruction.
6634 for (i = 0; i < cfg->header->num_clauses; ++i) {
6635 for (j = 0; j < cfg->header->num_clauses; ++j) {
6636 MonoExceptionClause *clause1 = &cfg->header->clauses [i];
6637 MonoExceptionClause *clause2 = &cfg->header->clauses [j];
6639 // FIXME: Nested try clauses fail in some cases too, i.e. #37273
6640 if (i != j && clause1->try_offset >= clause2->try_offset && clause1->handler_offset <= clause2->handler_offset) {
6641 //(clause1->flags == MONO_EXCEPTION_CLAUSE_FINALLY || clause2->flags == MONO_EXCEPTION_CLAUSE_FINALLY)) {
6642 cfg->exception_message = g_strdup ("nested clauses");
6643 cfg->disable_llvm = TRUE;
6648 if (cfg->disable_llvm)
6652 if (cfg->method->dynamic) {
6653 cfg->exception_message = g_strdup ("dynamic.");
6654 cfg->disable_llvm = TRUE;
6656 if (cfg->disable_llvm)
6660 static LLVMCallInfo*
6661 get_llvm_call_info (MonoCompile *cfg, MonoMethodSignature *sig)
6663 LLVMCallInfo *linfo;
6666 if (cfg->gsharedvt && cfg->llvm_only && mini_is_gsharedvt_variable_signature (sig)) {
6670 * Gsharedvt methods have the following calling convention:
6671 * - all arguments are passed by ref, even non generic ones
6672 * - the return value is returned by ref too, using a vret
6673 * argument passed after 'this'.
6675 n = sig->param_count + sig->hasthis;
6676 linfo = (LLVMCallInfo*)mono_mempool_alloc0 (cfg->mempool, sizeof (LLVMCallInfo) + (sizeof (LLVMArgInfo) * n));
6680 linfo->args [pindex ++].storage = LLVMArgNormal;
6682 if (sig->ret->type != MONO_TYPE_VOID) {
6683 if (mini_is_gsharedvt_variable_type (sig->ret))
6684 linfo->ret.storage = LLVMArgGsharedvtVariable;
6685 else if (mini_type_is_vtype (sig->ret))
6686 linfo->ret.storage = LLVMArgGsharedvtFixedVtype;
6688 linfo->ret.storage = LLVMArgGsharedvtFixed;
6689 linfo->vret_arg_index = pindex;
6691 linfo->ret.storage = LLVMArgNone;
6694 for (i = 0; i < sig->param_count; ++i) {
6695 if (sig->params [i]->byref)
6696 linfo->args [pindex].storage = LLVMArgNormal;
6697 else if (mini_is_gsharedvt_variable_type (sig->params [i]))
6698 linfo->args [pindex].storage = LLVMArgGsharedvtVariable;
6699 else if (mini_type_is_vtype (sig->params [i]))
6700 linfo->args [pindex].storage = LLVMArgGsharedvtFixedVtype;
6702 linfo->args [pindex].storage = LLVMArgGsharedvtFixed;
6703 linfo->args [pindex].type = sig->params [i];
6710 linfo = mono_arch_get_llvm_call_info (cfg, sig);
6711 for (i = 0; i < sig->param_count; ++i)
6712 linfo->args [i + sig->hasthis].type = sig->params [i];
6718 emit_method_inner (EmitContext *ctx);
6721 free_ctx (EmitContext *ctx)
6725 g_free (ctx->values);
6726 g_free (ctx->addresses);
6727 g_free (ctx->vreg_types);
6728 g_free (ctx->is_vphi);
6729 g_free (ctx->vreg_cli_types);
6730 g_free (ctx->is_dead);
6731 g_free (ctx->unreachable);
6732 g_ptr_array_free (ctx->phi_values, TRUE);
6733 g_free (ctx->bblocks);
6734 g_hash_table_destroy (ctx->region_to_handler);
6735 g_hash_table_destroy (ctx->clause_to_handler);
6736 g_hash_table_destroy (ctx->jit_callees);
6738 GHashTableIter iter;
6739 g_hash_table_iter_init (&iter, ctx->method_to_callers);
6740 while (g_hash_table_iter_next (&iter, NULL, (gpointer)&l))
6743 g_hash_table_destroy (ctx->method_to_callers);
6745 g_free (ctx->method_name);
6746 g_ptr_array_free (ctx->bblock_list, TRUE);
6748 for (l = ctx->builders; l; l = l->next) {
6749 LLVMBuilderRef builder = (LLVMBuilderRef)l->data;
6750 LLVMDisposeBuilder (builder);
6757 * mono_llvm_emit_method:
6759 * Emit LLVM IL from the mono IL, and compile it to native code using LLVM.
6762 mono_llvm_emit_method (MonoCompile *cfg)
6766 gboolean is_linkonce = FALSE;
6769 /* The code below might acquire the loader lock, so use it for global locking */
6770 mono_loader_lock ();
6772 /* Used to communicate with the callbacks */
6773 mono_native_tls_set_value (current_cfg_tls_id, cfg);
6775 ctx = g_new0 (EmitContext, 1);
6777 ctx->mempool = cfg->mempool;
6780 * This maps vregs to the LLVM instruction defining them
6782 ctx->values = g_new0 (LLVMValueRef, cfg->next_vreg);
6784 * This maps vregs for volatile variables to the LLVM instruction defining their
6787 ctx->addresses = g_new0 (LLVMValueRef, cfg->next_vreg);
6788 ctx->vreg_types = g_new0 (LLVMTypeRef, cfg->next_vreg);
6789 ctx->is_vphi = g_new0 (gboolean, cfg->next_vreg);
6790 ctx->vreg_cli_types = g_new0 (MonoType*, cfg->next_vreg);
6791 ctx->phi_values = g_ptr_array_sized_new (256);
6793 * This signals whenever the vreg was defined by a phi node with no input vars
6794 * (i.e. all its input bblocks end with NOT_REACHABLE).
6796 ctx->is_dead = g_new0 (gboolean, cfg->next_vreg);
6797 /* Whenever the bblock is unreachable */
6798 ctx->unreachable = g_new0 (gboolean, cfg->max_block_num);
6799 ctx->bblock_list = g_ptr_array_sized_new (256);
6801 ctx->region_to_handler = g_hash_table_new (NULL, NULL);
6802 ctx->clause_to_handler = g_hash_table_new (NULL, NULL);
6803 ctx->method_to_callers = g_hash_table_new (NULL, NULL);
6804 ctx->jit_callees = g_hash_table_new (NULL, NULL);
6805 if (cfg->compile_aot) {
6806 ctx->module = &aot_module;
6810 * Allow the linker to discard duplicate copies of wrappers, generic instances etc. by using the 'linkonce'
6811 * linkage for them. This requires the following:
6812 * - the method needs to have a unique mangled name
6813 * - llvmonly mode, since the code in aot-runtime.c would initialize got slots in the wrong aot image etc.
6815 is_linkonce = ctx->module->llvm_only && ctx->module->static_link && mono_aot_is_linkonce_method (cfg->method);
6817 method_name = mono_aot_get_mangled_method_name (cfg->method);
6819 is_linkonce = FALSE;
6822 printf ("%s %s\n", mono_method_full_name (cfg->method, 1), method_name);
6824 printf ("%s\n", mono_method_full_name (cfg->method, 1));
6828 method_name = mono_aot_get_method_name (cfg);
6829 cfg->llvm_method_name = g_strdup (method_name);
6831 init_jit_module (cfg->domain);
6832 ctx->module = (MonoLLVMModule*)domain_jit_info (cfg->domain)->llvm_module;
6833 method_name = mono_method_full_name (cfg->method, TRUE);
6835 ctx->method_name = method_name;
6836 ctx->is_linkonce = is_linkonce;
6838 #if LLVM_API_VERSION > 100
6839 if (cfg->compile_aot)
6840 ctx->lmodule = ctx->module->lmodule;
6842 ctx->lmodule = LLVMModuleCreateWithName ("jit-module");
6844 ctx->lmodule = ctx->module->lmodule;
6846 ctx->llvm_only = ctx->module->llvm_only;
6848 emit_method_inner (ctx);
6850 if (!ctx_ok (ctx)) {
6852 /* Need to add unused phi nodes as they can be referenced by other values */
6853 LLVMBasicBlockRef phi_bb = LLVMAppendBasicBlock (ctx->lmethod, "PHI_BB");
6854 LLVMBuilderRef builder;
6856 builder = create_builder (ctx);
6857 LLVMPositionBuilderAtEnd (builder, phi_bb);
6859 for (i = 0; i < ctx->phi_values->len; ++i) {
6860 LLVMValueRef v = (LLVMValueRef)g_ptr_array_index (ctx->phi_values, i);
6861 if (LLVMGetInstructionParent (v) == NULL)
6862 LLVMInsertIntoBuilder (builder, v);
6865 LLVMDeleteFunction (ctx->lmethod);
6871 mono_native_tls_set_value (current_cfg_tls_id, NULL);
6873 mono_loader_unlock ();
6877 emit_method_inner (EmitContext *ctx)
6879 MonoCompile *cfg = ctx->cfg;
6880 MonoMethodSignature *sig;
6882 LLVMTypeRef method_type;
6883 LLVMValueRef method = NULL;
6884 LLVMValueRef *values = ctx->values;
6885 int i, max_block_num, bb_index;
6886 gboolean last = FALSE;
6887 LLVMCallInfo *linfo;
6888 LLVMModuleRef lmodule = ctx->lmodule;
6890 GPtrArray *bblock_list = ctx->bblock_list;
6891 MonoMethodHeader *header;
6892 MonoExceptionClause *clause;
6895 if (cfg->gsharedvt && !cfg->llvm_only) {
6896 set_failure (ctx, "gsharedvt");
6902 static int count = 0;
6905 if (g_getenv ("LLVM_COUNT")) {
6906 if (count == atoi (g_getenv ("LLVM_COUNT"))) {
6907 printf ("LAST: %s\n", mono_method_full_name (cfg->method, TRUE));
6911 if (count > atoi (g_getenv ("LLVM_COUNT"))) {
6912 set_failure (ctx, "count");
6919 sig = mono_method_signature (cfg->method);
6922 linfo = get_llvm_call_info (cfg, sig);
6928 linfo->rgctx_arg = TRUE;
6929 ctx->method_type = method_type = sig_to_llvm_sig_full (ctx, sig, linfo);
6933 method = LLVMAddFunction (lmodule, ctx->method_name, method_type);
6934 ctx->lmethod = method;
6936 if (!cfg->llvm_only)
6937 LLVMSetFunctionCallConv (method, LLVMMono1CallConv);
6938 LLVMSetLinkage (method, LLVMPrivateLinkage);
6940 LLVMAddFunctionAttr (method, LLVMUWTable);
6942 if (cfg->compile_aot) {
6943 LLVMSetLinkage (method, LLVMInternalLinkage);
6944 if (ctx->module->external_symbols) {
6945 LLVMSetLinkage (method, LLVMExternalLinkage);
6946 LLVMSetVisibility (method, LLVMHiddenVisibility);
6948 if (ctx->is_linkonce) {
6949 LLVMSetLinkage (method, LLVMLinkOnceAnyLinkage);
6950 LLVMSetVisibility (method, LLVMDefaultVisibility);
6953 #if LLVM_API_VERSION > 100
6954 LLVMSetLinkage (method, LLVMExternalLinkage);
6956 LLVMSetLinkage (method, LLVMPrivateLinkage);
6960 if (cfg->method->save_lmf && !cfg->llvm_only) {
6961 set_failure (ctx, "lmf");
6965 if (sig->pinvoke && cfg->method->wrapper_type != MONO_WRAPPER_RUNTIME_INVOKE && !cfg->llvm_only) {
6966 set_failure (ctx, "pinvoke signature");
6970 header = cfg->header;
6971 for (i = 0; i < header->num_clauses; ++i) {
6972 clause = &header->clauses [i];
6973 if (clause->flags != MONO_EXCEPTION_CLAUSE_FINALLY && clause->flags != MONO_EXCEPTION_CLAUSE_NONE) {
6974 set_failure (ctx, "non-finally/catch clause.");
6978 if (header->num_clauses || (cfg->method->iflags & METHOD_IMPL_ATTRIBUTE_NOINLINING) || cfg->no_inline)
6979 /* We can't handle inlined methods with clauses */
6980 LLVMAddFunctionAttr (method, LLVMNoInlineAttribute);
6982 if (linfo->rgctx_arg) {
6983 ctx->rgctx_arg = LLVMGetParam (method, linfo->rgctx_arg_pindex);
6984 ctx->rgctx_arg_pindex = linfo->rgctx_arg_pindex;
6986 * We mark the rgctx parameter with the inreg attribute, which is mapped to
6987 * MONO_ARCH_RGCTX_REG in the Mono calling convention in llvm, i.e.
6988 * CC_X86_64_Mono in X86CallingConv.td.
6990 if (!ctx->llvm_only)
6991 LLVMAddAttribute (ctx->rgctx_arg, LLVMInRegAttribute);
6992 LLVMSetValueName (ctx->rgctx_arg, "rgctx");
6994 ctx->rgctx_arg_pindex = -1;
6996 if (cfg->vret_addr) {
6997 values [cfg->vret_addr->dreg] = LLVMGetParam (method, linfo->vret_arg_pindex);
6998 LLVMSetValueName (values [cfg->vret_addr->dreg], "vret");
6999 if (linfo->ret.storage == LLVMArgVtypeByRef) {
7000 LLVMAddAttribute (LLVMGetParam (method, linfo->vret_arg_pindex), LLVMStructRetAttribute);
7001 LLVMAddAttribute (LLVMGetParam (method, linfo->vret_arg_pindex), LLVMNoAliasAttribute);
7006 ctx->this_arg_pindex = linfo->this_arg_pindex;
7007 ctx->this_arg = LLVMGetParam (method, linfo->this_arg_pindex);
7008 values [cfg->args [0]->dreg] = ctx->this_arg;
7009 LLVMSetValueName (values [cfg->args [0]->dreg], "this");
7012 names = g_new (char *, sig->param_count);
7013 mono_method_get_param_names (cfg->method, (const char **) names);
7015 /* Set parameter names/attributes */
7016 for (i = 0; i < sig->param_count; ++i) {
7017 LLVMArgInfo *ainfo = &linfo->args [i + sig->hasthis];
7019 int pindex = ainfo->pindex + ainfo->ndummy_fpargs;
7022 for (j = 0; j < ainfo->ndummy_fpargs; ++j) {
7023 name = g_strdup_printf ("dummy_%d_%d", i, j);
7024 LLVMSetValueName (LLVMGetParam (method, ainfo->pindex + j), name);
7028 if (ainfo->storage == LLVMArgVtypeInReg && ainfo->pair_storage [0] == LLVMArgNone && ainfo->pair_storage [1] == LLVMArgNone)
7031 values [cfg->args [i + sig->hasthis]->dreg] = LLVMGetParam (method, pindex);
7032 if (ainfo->storage == LLVMArgGsharedvtFixed || ainfo->storage == LLVMArgGsharedvtFixedVtype) {
7033 if (names [i] && names [i][0] != '\0')
7034 name = g_strdup_printf ("p_arg_%s", names [i]);
7036 name = g_strdup_printf ("p_arg_%d", i);
7038 if (names [i] && names [i][0] != '\0')
7039 name = g_strdup_printf ("arg_%s", names [i]);
7041 name = g_strdup_printf ("arg_%d", i);
7043 LLVMSetValueName (values [cfg->args [i + sig->hasthis]->dreg], name);
7045 if (ainfo->storage == LLVMArgVtypeByVal)
7046 LLVMAddAttribute (LLVMGetParam (method, pindex), LLVMByValAttribute);
7048 if (ainfo->storage == LLVMArgVtypeByRef) {
7050 cfg->args [i + sig->hasthis]->opcode = OP_VTARG_ADDR;
7055 if (ctx->module->emit_dwarf && cfg->compile_aot && mono_debug_enabled ()) {
7056 ctx->minfo = mono_debug_lookup_method (cfg->method);
7057 ctx->dbg_md = emit_dbg_subprogram (ctx, cfg, method, ctx->method_name);
7061 for (bb = cfg->bb_entry; bb; bb = bb->next_bb)
7062 max_block_num = MAX (max_block_num, bb->block_num);
7063 ctx->bblocks = bblocks = g_new0 (BBInfo, max_block_num + 1);
7065 /* Add branches between non-consecutive bblocks */
7066 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
7067 if (bb->last_ins && MONO_IS_COND_BRANCH_OP (bb->last_ins) &&
7068 bb->next_bb != bb->last_ins->inst_false_bb) {
7070 MonoInst *inst = (MonoInst*)mono_mempool_alloc0 (cfg->mempool, sizeof (MonoInst));
7071 inst->opcode = OP_BR;
7072 inst->inst_target_bb = bb->last_ins->inst_false_bb;
7073 mono_bblock_add_inst (bb, inst);
7078 * The INDIRECT flag added by OP_LDADDR inhibits optimizations, even if the LDADDR
7079 * was later optimized away, so clear these flags, and add them back for the still
7080 * present OP_LDADDR instructions.
7082 for (i = 0; i < cfg->next_vreg; ++i) {
7085 ins = get_vreg_to_inst (cfg, i);
7086 if (ins && ins != cfg->rgctx_var)
7087 ins->flags &= ~MONO_INST_INDIRECT;
7091 * Make a first pass over the code to precreate PHI nodes/set INDIRECT flags.
7093 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
7095 LLVMBuilderRef builder;
7097 char dname_buf[128];
7099 builder = create_builder (ctx);
7101 for (ins = bb->code; ins; ins = ins->next) {
7102 switch (ins->opcode) {
7107 LLVMTypeRef phi_type = llvm_type_to_stack_type (cfg, type_to_llvm_type (ctx, &ins->klass->byval_arg));
7112 if (ins->opcode == OP_VPHI) {
7113 /* Treat valuetype PHI nodes as operating on the address itself */
7114 g_assert (ins->klass);
7115 phi_type = LLVMPointerType (type_to_llvm_type (ctx, &ins->klass->byval_arg), 0);
7119 * Have to precreate these, as they can be referenced by
7120 * earlier instructions.
7122 sprintf (dname_buf, "t%d", ins->dreg);
7124 values [ins->dreg] = LLVMBuildPhi (builder, phi_type, dname);
7126 if (ins->opcode == OP_VPHI)
7127 ctx->addresses [ins->dreg] = values [ins->dreg];
7129 g_ptr_array_add (ctx->phi_values, values [ins->dreg]);
7132 * Set the expected type of the incoming arguments since these have
7133 * to have the same type.
7135 for (i = 0; i < ins->inst_phi_args [0]; i++) {
7136 int sreg1 = ins->inst_phi_args [i + 1];
7139 if (ins->opcode == OP_VPHI)
7140 ctx->is_vphi [sreg1] = TRUE;
7141 ctx->vreg_types [sreg1] = phi_type;
7147 ((MonoInst*)ins->inst_p0)->flags |= MONO_INST_INDIRECT;
7156 * Create an ordering for bblocks, use the depth first order first, then
7157 * put the exception handling bblocks last.
7159 for (bb_index = 0; bb_index < cfg->num_bblocks; ++bb_index) {
7160 bb = cfg->bblocks [bb_index];
7161 if (!(bb->region != -1 && !MONO_BBLOCK_IS_IN_REGION (bb, MONO_REGION_TRY))) {
7162 g_ptr_array_add (bblock_list, bb);
7163 bblocks [bb->block_num].added = TRUE;
7167 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
7168 if (!bblocks [bb->block_num].added)
7169 g_ptr_array_add (bblock_list, bb);
7173 * Second pass: generate code.
7176 LLVMBuilderRef entry_builder = create_builder (ctx);
7177 LLVMBasicBlockRef entry_bb = get_bb (ctx, cfg->bb_entry);
7178 LLVMPositionBuilderAtEnd (entry_builder, entry_bb);
7179 emit_entry_bb (ctx, entry_builder);
7181 // Make landing pads first
7182 ctx->exc_meta = g_hash_table_new_full (NULL, NULL, NULL, NULL);
7184 if (ctx->llvm_only) {
7185 size_t group_index = 0;
7186 while (group_index < cfg->header->num_clauses) {
7188 size_t cursor = group_index;
7189 while (cursor < cfg->header->num_clauses &&
7190 CLAUSE_START (&cfg->header->clauses [cursor]) == CLAUSE_START (&cfg->header->clauses [group_index]) &&
7191 CLAUSE_END (&cfg->header->clauses [cursor]) == CLAUSE_END (&cfg->header->clauses [group_index])) {
7196 LLVMBasicBlockRef lpad_bb = emit_landing_pad (ctx, group_index, count);
7197 intptr_t key = CLAUSE_END (&cfg->header->clauses [group_index]);
7198 g_hash_table_insert (ctx->exc_meta, (gpointer)key, lpad_bb);
7200 group_index = cursor;
7204 for (bb_index = 0; bb_index < bblock_list->len; ++bb_index) {
7205 bb = (MonoBasicBlock*)g_ptr_array_index (bblock_list, bb_index);
7207 // Prune unreachable mono BBs.
7208 if (!(bb == cfg->bb_entry || bb->in_count > 0))
7211 process_bb (ctx, bb);
7215 g_hash_table_destroy (ctx->exc_meta);
7217 mono_memory_barrier ();
7219 /* Add incoming phi values */
7220 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
7221 GSList *l, *ins_list;
7223 ins_list = bblocks [bb->block_num].phi_nodes;
7225 for (l = ins_list; l; l = l->next) {
7226 PhiNode *node = (PhiNode*)l->data;
7227 MonoInst *phi = node->phi;
7228 int sreg1 = node->sreg;
7229 LLVMBasicBlockRef in_bb;
7234 in_bb = get_end_bb (ctx, node->in_bb);
7236 if (ctx->unreachable [node->in_bb->block_num])
7239 if (!values [sreg1]) {
7240 /* Can happen with values in EH clauses */
7241 set_failure (ctx, "incoming phi sreg1");
7245 if (phi->opcode == OP_VPHI) {
7246 g_assert (LLVMTypeOf (ctx->addresses [sreg1]) == LLVMTypeOf (values [phi->dreg]));
7247 LLVMAddIncoming (values [phi->dreg], &ctx->addresses [sreg1], &in_bb, 1);
7249 if (LLVMTypeOf (values [sreg1]) != LLVMTypeOf (values [phi->dreg])) {
7250 set_failure (ctx, "incoming phi arg type mismatch");
7253 g_assert (LLVMTypeOf (values [sreg1]) == LLVMTypeOf (values [phi->dreg]));
7254 LLVMAddIncoming (values [phi->dreg], &values [sreg1], &in_bb, 1);
7259 /* Nullify empty phi instructions */
7260 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
7261 GSList *l, *ins_list;
7263 ins_list = bblocks [bb->block_num].phi_nodes;
7265 for (l = ins_list; l; l = l->next) {
7266 PhiNode *node = (PhiNode*)l->data;
7267 MonoInst *phi = node->phi;
7268 LLVMValueRef phi_ins = values [phi->dreg];
7271 /* Already removed */
7274 if (LLVMCountIncoming (phi_ins) == 0) {
7275 mono_llvm_replace_uses_of (phi_ins, LLVMConstNull (LLVMTypeOf (phi_ins)));
7276 LLVMInstructionEraseFromParent (phi_ins);
7277 values [phi->dreg] = NULL;
7282 /* Create the SWITCH statements for ENDFINALLY instructions */
7283 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
7284 BBInfo *info = &bblocks [bb->block_num];
7286 for (l = info->endfinally_switch_ins_list; l; l = l->next) {
7287 LLVMValueRef switch_ins = (LLVMValueRef)l->data;
7288 GSList *bb_list = info->call_handler_return_bbs;
7290 GSList *bb_list_iter;
7292 for (bb_list_iter = bb_list; bb_list_iter; bb_list_iter = g_slist_next (bb_list_iter)) {
7293 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), i + 1, FALSE), (LLVMBasicBlockRef)bb_list_iter->data);
7299 /* Initialize the method if needed */
7300 if (cfg->compile_aot && ctx->llvm_only) {
7301 // FIXME: Add more shared got entries
7302 ctx->builder = create_builder (ctx);
7303 LLVMPositionBuilderAtEnd (ctx->builder, ctx->init_bb);
7305 ctx->module->max_method_idx = MAX (ctx->module->max_method_idx, cfg->method_index);
7307 // FIXME: beforefieldinit
7309 * NATIVE_TO_MANAGED methods might be called on a thread not attached to the runtime, so they are initialized when loaded
7310 * in load_method ().
7312 if ((ctx->has_got_access || mono_class_get_cctor (cfg->method->klass)) && !(cfg->method->wrapper_type == MONO_WRAPPER_NATIVE_TO_MANAGED)) {
7314 * linkonce methods shouldn't have initialization,
7315 * because they might belong to assemblies which
7316 * haven't been loaded yet.
7318 g_assert (!ctx->is_linkonce);
7319 emit_init_method (ctx);
7321 LLVMBuildBr (ctx->builder, ctx->inited_bb);
7325 if (cfg->llvm_only) {
7326 GHashTableIter iter;
7328 GSList *callers, *l, *l2;
7331 * Add the contents of ctx->method_to_callers to module->method_to_callers.
7332 * We can't do this earlier, as it contains llvm instructions which can be
7333 * freed if compilation fails.
7334 * FIXME: Get rid of this when all methods can be llvm compiled.
7336 g_hash_table_iter_init (&iter, ctx->method_to_callers);
7337 while (g_hash_table_iter_next (&iter, (void**)&method, (void**)&callers)) {
7338 for (l = callers; l; l = l->next) {
7339 l2 = (GSList*)g_hash_table_lookup (ctx->module->method_to_callers, method);
7340 l2 = g_slist_prepend (l2, l->data);
7341 g_hash_table_insert (ctx->module->method_to_callers, method, l2);
7346 if (cfg->verbose_level > 1)
7347 mono_llvm_dump_value (method);
7349 if (cfg->compile_aot && !cfg->llvm_only)
7350 mark_as_used (ctx->module, method);
7352 if (!cfg->llvm_only) {
7353 LLVMValueRef md_args [16];
7354 LLVMValueRef md_node;
7357 if (cfg->compile_aot)
7358 method_index = mono_aot_get_method_index (cfg->orig_method);
7361 md_args [0] = LLVMMDString (ctx->method_name, strlen (ctx->method_name));
7362 md_args [1] = LLVMConstInt (LLVMInt32Type (), method_index, FALSE);
7363 md_node = LLVMMDNode (md_args, 2);
7364 LLVMAddNamedMetadataOperand (lmodule, "mono.function_indexes", md_node);
7365 //LLVMSetMetadata (method, md_kind, LLVMMDNode (&md_arg, 1));
7368 if (cfg->compile_aot) {
7369 /* Don't generate native code, keep the LLVM IR */
7370 if (cfg->verbose_level)
7371 printf ("%s emitted as %s\n", mono_method_full_name (cfg->method, TRUE), ctx->method_name);
7373 #if LLVM_API_VERSION < 100
7374 /* VerifyFunction can't handle some of the debug info created by DIBuilder in llvm 3.9 */
7375 int err = LLVMVerifyFunction(ctx->lmethod, LLVMPrintMessageAction);
7376 g_assert (err == 0);
7379 //LLVMVerifyFunction(method, 0);
7380 #if LLVM_API_VERSION > 100
7381 MonoDomain *domain = mono_domain_get ();
7382 MonoJitDomainInfo *domain_info;
7383 int nvars = g_hash_table_size (ctx->jit_callees);
7384 LLVMValueRef *callee_vars = g_new0 (LLVMValueRef, nvars);
7385 gpointer *callee_addrs = g_new0 (gpointer, nvars);
7386 GHashTableIter iter;
7392 * Compute the addresses of the LLVM globals pointing to the
7393 * methods called by the current method. Pass it to the trampoline
7394 * code so it can update them after their corresponding method was
7397 g_hash_table_iter_init (&iter, ctx->jit_callees);
7399 while (g_hash_table_iter_next (&iter, NULL, (void**)&var))
7400 callee_vars [i ++] = var;
7402 cfg->native_code = mono_llvm_compile_method (ctx->module->mono_ee, ctx->lmethod, nvars, callee_vars, callee_addrs, &eh_frame);
7404 decode_llvm_eh_info (ctx, eh_frame);
7406 mono_domain_lock (domain);
7407 domain_info = domain_jit_info (domain);
7408 if (!domain_info->llvm_jit_callees)
7409 domain_info->llvm_jit_callees = g_hash_table_new (NULL, NULL);
7410 g_hash_table_iter_init (&iter, ctx->jit_callees);
7412 while (g_hash_table_iter_next (&iter, (void**)&callee, (void**)&var)) {
7413 GSList *addrs = g_hash_table_lookup (domain_info->llvm_jit_callees, callee);
7414 addrs = g_slist_prepend (addrs, callee_addrs [i]);
7415 g_hash_table_insert (domain_info->llvm_jit_callees, callee, addrs);
7418 mono_domain_unlock (domain);
7420 mono_llvm_optimize_method (ctx->module->mono_ee, ctx->lmethod);
7422 if (cfg->verbose_level > 1)
7423 mono_llvm_dump_value (ctx->lmethod);
7425 cfg->native_code = (unsigned char*)LLVMGetPointerToGlobal (ctx->module->ee, ctx->lmethod);
7427 /* Set by emit_cb */
7428 g_assert (cfg->code_len);
7432 if (ctx->module->method_to_lmethod)
7433 g_hash_table_insert (ctx->module->method_to_lmethod, cfg->method, ctx->lmethod);
7434 if (ctx->module->idx_to_lmethod)
7435 g_hash_table_insert (ctx->module->idx_to_lmethod, GINT_TO_POINTER (cfg->method_index), ctx->lmethod);
7437 if (ctx->llvm_only && cfg->orig_method->klass->valuetype && !(cfg->orig_method->flags & METHOD_ATTRIBUTE_STATIC))
7438 emit_unbox_tramp (ctx, ctx->method_name, ctx->method_type, ctx->lmethod, cfg->method_index);
7442 * mono_llvm_create_vars:
7444 * Same as mono_arch_create_vars () for LLVM.
7447 mono_llvm_create_vars (MonoCompile *cfg)
7449 MonoMethodSignature *sig;
7451 sig = mono_method_signature (cfg->method);
7452 if (cfg->gsharedvt && cfg->llvm_only) {
7453 if (mini_is_gsharedvt_variable_signature (sig) && sig->ret->type != MONO_TYPE_VOID) {
7454 cfg->vret_addr = mono_compile_create_var (cfg, &mono_get_intptr_class ()->byval_arg, OP_ARG);
7455 if (G_UNLIKELY (cfg->verbose_level > 1)) {
7456 printf ("vret_addr = ");
7457 mono_print_ins (cfg->vret_addr);
7461 mono_arch_create_vars (cfg);
7466 * mono_llvm_emit_call:
7468 * Same as mono_arch_emit_call () for LLVM.
7471 mono_llvm_emit_call (MonoCompile *cfg, MonoCallInst *call)
7474 MonoMethodSignature *sig;
7475 int i, n, stack_size;
7480 sig = call->signature;
7481 n = sig->param_count + sig->hasthis;
7483 call->cinfo = get_llvm_call_info (cfg, sig);
7485 if (cfg->disable_llvm)
7488 if (sig->call_convention == MONO_CALL_VARARG) {
7489 cfg->exception_message = g_strdup ("varargs");
7490 cfg->disable_llvm = TRUE;
7493 for (i = 0; i < n; ++i) {
7496 ainfo = call->cinfo->args + i;
7498 in = call->args [i];
7500 /* Simply remember the arguments */
7501 switch (ainfo->storage) {
7502 case LLVMArgNormal: {
7503 MonoType *t = (sig->hasthis && i == 0) ? &mono_get_intptr_class ()->byval_arg : ainfo->type;
7506 opcode = mono_type_to_regmove (cfg, t);
7507 if (opcode == OP_FMOVE) {
7508 MONO_INST_NEW (cfg, ins, OP_FMOVE);
7509 ins->dreg = mono_alloc_freg (cfg);
7510 } else if (opcode == OP_LMOVE) {
7511 MONO_INST_NEW (cfg, ins, OP_LMOVE);
7512 ins->dreg = mono_alloc_lreg (cfg);
7513 } else if (opcode == OP_RMOVE) {
7514 MONO_INST_NEW (cfg, ins, OP_RMOVE);
7515 ins->dreg = mono_alloc_freg (cfg);
7517 MONO_INST_NEW (cfg, ins, OP_MOVE);
7518 ins->dreg = mono_alloc_ireg (cfg);
7520 ins->sreg1 = in->dreg;
7523 case LLVMArgVtypeByVal:
7524 case LLVMArgVtypeByRef:
7525 case LLVMArgVtypeInReg:
7526 case LLVMArgVtypeAsScalar:
7527 case LLVMArgAsIArgs:
7528 case LLVMArgAsFpArgs:
7529 case LLVMArgGsharedvtVariable:
7530 case LLVMArgGsharedvtFixed:
7531 case LLVMArgGsharedvtFixedVtype:
7532 MONO_INST_NEW (cfg, ins, OP_LLVM_OUTARG_VT);
7533 ins->dreg = mono_alloc_ireg (cfg);
7534 ins->sreg1 = in->dreg;
7535 ins->inst_p0 = mono_mempool_alloc0 (cfg->mempool, sizeof (LLVMArgInfo));
7536 memcpy (ins->inst_p0, ainfo, sizeof (LLVMArgInfo));
7537 ins->inst_vtype = ainfo->type;
7538 ins->klass = mono_class_from_mono_type (ainfo->type);
7541 cfg->exception_message = g_strdup ("ainfo->storage");
7542 cfg->disable_llvm = TRUE;
7546 if (!cfg->disable_llvm) {
7547 MONO_ADD_INS (cfg->cbb, ins);
7548 mono_call_inst_add_outarg_reg (cfg, call, ins->dreg, 0, FALSE);
7553 static unsigned char*
7554 alloc_cb (LLVMValueRef function, int size)
7558 cfg = (MonoCompile*)mono_native_tls_get_value (current_cfg_tls_id);
7562 return (unsigned char*)mono_domain_code_reserve (cfg->domain, size);
7564 return (unsigned char*)mono_domain_code_reserve (mono_domain_get (), size);
7569 emitted_cb (LLVMValueRef function, void *start, void *end)
7573 cfg = (MonoCompile*)mono_native_tls_get_value (current_cfg_tls_id);
7575 cfg->code_len = (guint8*)end - (guint8*)start;
7579 exception_cb (void *data)
7582 MonoJitExceptionInfo *ei;
7583 guint32 ei_len, i, j, nested_len, nindex;
7584 gpointer *type_info;
7585 int this_reg, this_offset;
7587 cfg = (MonoCompile*)mono_native_tls_get_value (current_cfg_tls_id);
7591 * data points to a DWARF FDE structure, convert it to our unwind format and
7593 * An alternative would be to save it directly, and modify our unwinder to work
7596 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);
7597 if (cfg->verbose_level > 1)
7598 mono_print_unwind_info (cfg->encoded_unwind_ops, cfg->encoded_unwind_ops_len);
7600 /* Count nested clauses */
7602 for (i = 0; i < ei_len; ++i) {
7603 gint32 cindex1 = *(gint32*)type_info [i];
7604 MonoExceptionClause *clause1 = &cfg->header->clauses [cindex1];
7606 for (j = 0; j < cfg->header->num_clauses; ++j) {
7608 MonoExceptionClause *clause2 = &cfg->header->clauses [cindex2];
7610 if (cindex1 != cindex2 && clause1->try_offset >= clause2->try_offset && clause1->handler_offset <= clause2->handler_offset) {
7616 cfg->llvm_ex_info = (MonoJitExceptionInfo*)mono_mempool_alloc0 (cfg->mempool, (ei_len + nested_len) * sizeof (MonoJitExceptionInfo));
7617 cfg->llvm_ex_info_len = ei_len + nested_len;
7618 memcpy (cfg->llvm_ex_info, ei, ei_len * sizeof (MonoJitExceptionInfo));
7619 /* Fill the rest of the information from the type info */
7620 for (i = 0; i < ei_len; ++i) {
7621 gint32 clause_index = *(gint32*)type_info [i];
7622 MonoExceptionClause *clause = &cfg->header->clauses [clause_index];
7624 cfg->llvm_ex_info [i].flags = clause->flags;
7625 cfg->llvm_ex_info [i].data.catch_class = clause->data.catch_class;
7626 cfg->llvm_ex_info [i].clause_index = clause_index;
7630 * For nested clauses, the LLVM produced exception info associates the try interval with
7631 * the innermost handler, while mono expects it to be associated with all nesting clauses.
7632 * So add new clauses which use the IL info (catch class etc.) from the nesting clause,
7633 * and everything else from the nested clause.
7636 for (i = 0; i < ei_len; ++i) {
7637 gint32 cindex1 = *(gint32*)type_info [i];
7638 MonoExceptionClause *clause1 = &cfg->header->clauses [cindex1];
7640 for (j = 0; j < cfg->header->num_clauses; ++j) {
7642 MonoExceptionClause *clause2 = &cfg->header->clauses [cindex2];
7643 MonoJitExceptionInfo *nesting_ei, *nested_ei;
7645 if (cindex1 != cindex2 && clause1->try_offset >= clause2->try_offset && clause1->handler_offset <= clause2->handler_offset) {
7646 /* clause1 is the nested clause */
7647 nested_ei = &cfg->llvm_ex_info [i];
7648 nesting_ei = &cfg->llvm_ex_info [nindex];
7651 memcpy (nesting_ei, nested_ei, sizeof (MonoJitExceptionInfo));
7653 nesting_ei->flags = clause2->flags;
7654 nesting_ei->data.catch_class = clause2->data.catch_class;
7655 nesting_ei->clause_index = cindex2;
7659 g_assert (nindex == ei_len + nested_len);
7660 cfg->llvm_this_reg = this_reg;
7661 cfg->llvm_this_offset = this_offset;
7663 /* type_info [i] is cfg mempool allocated, no need to free it */
7669 #if LLVM_API_VERSION > 100
7671 * decode_llvm_eh_info:
7673 * Decode the EH table emitted by llvm in jit mode, and store
7674 * the result into cfg.
7677 decode_llvm_eh_info (EmitContext *ctx, gpointer eh_frame)
7679 MonoCompile *cfg = ctx->cfg;
7682 MonoLLVMFDEInfo info;
7683 MonoJitExceptionInfo *ei;
7684 guint8 *p = eh_frame;
7685 int version, fde_count, fde_offset;
7686 guint32 ei_len, i, nested_len;
7687 gpointer *type_info;
7691 * Decode the one element EH table emitted by the MonoException class
7695 /* Similar to decode_llvm_mono_eh_frame () in aot-runtime.c */
7698 g_assert (version == 3);
7701 p = (guint8 *)ALIGN_PTR_TO (p, 4);
7703 fde_count = *(guint32*)p;
7707 g_assert (fde_count <= 2);
7709 /* The first entry is the real method */
7710 g_assert (table [0] == 1);
7711 fde_offset = table [1];
7712 table += fde_count * 2;
7714 cfg->code_len = table [0];
7715 fde_len = table [1] - fde_offset;
7718 fde = (guint8*)eh_frame + fde_offset;
7719 cie = (guint8*)table;
7721 mono_unwind_decode_llvm_mono_fde (fde, fde_len, cie, cfg->native_code, &info);
7723 cfg->encoded_unwind_ops = info.unw_info;
7724 cfg->encoded_unwind_ops_len = info.unw_info_len;
7725 if (cfg->verbose_level > 1)
7726 mono_print_unwind_info (cfg->encoded_unwind_ops, cfg->encoded_unwind_ops_len);
7727 if (info.this_reg != -1) {
7728 cfg->llvm_this_reg = info.this_reg;
7729 cfg->llvm_this_offset = info.this_offset;
7733 ei_len = info.ex_info_len;
7734 type_info = info.type_info;
7736 // Nested clauses are currently disabled
7739 cfg->llvm_ex_info = (MonoJitExceptionInfo*)mono_mempool_alloc0 (cfg->mempool, (ei_len + nested_len) * sizeof (MonoJitExceptionInfo));
7740 cfg->llvm_ex_info_len = ei_len + nested_len;
7741 memcpy (cfg->llvm_ex_info, ei, ei_len * sizeof (MonoJitExceptionInfo));
7742 /* Fill the rest of the information from the type info */
7743 for (i = 0; i < ei_len; ++i) {
7744 gint32 clause_index = *(gint32*)type_info [i];
7745 MonoExceptionClause *clause = &cfg->header->clauses [clause_index];
7747 cfg->llvm_ex_info [i].flags = clause->flags;
7748 cfg->llvm_ex_info [i].data.catch_class = clause->data.catch_class;
7749 cfg->llvm_ex_info [i].clause_index = clause_index;
7755 dlsym_cb (const char *name, void **symbol)
7761 if (!strcmp (name, "__bzero")) {
7762 *symbol = (void*)bzero;
7764 current = mono_dl_open (NULL, 0, NULL);
7767 err = mono_dl_symbol (current, name, symbol);
7769 mono_dl_close (current);
7771 #ifdef MONO_ARCH_HAVE_CREATE_LLVM_NATIVE_THUNK
7772 *symbol = (char*)mono_arch_create_llvm_native_thunk (mono_domain_get (), (guint8*)(*symbol));
7778 AddFunc (LLVMModuleRef module, const char *name, LLVMTypeRef ret_type, LLVMTypeRef *param_types, int nparams)
7780 LLVMAddFunction (module, name, LLVMFunctionType (ret_type, param_types, nparams, FALSE));
7784 AddFunc2 (LLVMModuleRef module, const char *name, LLVMTypeRef ret_type, LLVMTypeRef param_type1, LLVMTypeRef param_type2)
7786 LLVMTypeRef param_types [4];
7788 param_types [0] = param_type1;
7789 param_types [1] = param_type2;
7791 AddFunc (module, name, ret_type, param_types, 2);
7797 INTRINS_SADD_OVF_I32,
7798 INTRINS_UADD_OVF_I32,
7799 INTRINS_SSUB_OVF_I32,
7800 INTRINS_USUB_OVF_I32,
7801 INTRINS_SMUL_OVF_I32,
7802 INTRINS_UMUL_OVF_I32,
7803 INTRINS_SADD_OVF_I64,
7804 INTRINS_UADD_OVF_I64,
7805 INTRINS_SSUB_OVF_I64,
7806 INTRINS_USUB_OVF_I64,
7807 INTRINS_SMUL_OVF_I64,
7808 INTRINS_UMUL_OVF_I64,
7815 #if defined(TARGET_AMD64) || defined(TARGET_X86)
7816 INTRINS_SSE_PMOVMSKB,
7817 INTRINS_SSE_PSRLI_W,
7818 INTRINS_SSE_PSRAI_W,
7819 INTRINS_SSE_PSLLI_W,
7820 INTRINS_SSE_PSRLI_D,
7821 INTRINS_SSE_PSRAI_D,
7822 INTRINS_SSE_PSLLI_D,
7823 INTRINS_SSE_PSRLI_Q,
7824 INTRINS_SSE_PSLLI_Q,
7825 INTRINS_SSE_SQRT_PD,
7826 INTRINS_SSE_SQRT_PS,
7827 INTRINS_SSE_RSQRT_PS,
7829 INTRINS_SSE_CVTTPD2DQ,
7830 INTRINS_SSE_CVTTPS2DQ,
7831 INTRINS_SSE_CVTDQ2PD,
7832 INTRINS_SSE_CVTDQ2PS,
7833 INTRINS_SSE_CVTPD2DQ,
7834 INTRINS_SSE_CVTPS2DQ,
7835 INTRINS_SSE_CVTPD2PS,
7836 INTRINS_SSE_CVTPS2PD,
7839 INTRINS_SSE_PACKSSWB,
7840 INTRINS_SSE_PACKUSWB,
7841 INTRINS_SSE_PACKSSDW,
7842 INTRINS_SSE_PACKUSDW,
7847 INTRINS_SSE_ADDSUBPS,
7852 INTRINS_SSE_ADDSUBPD,
7855 INTRINS_SSE_PADDUSW,
7856 INTRINS_SSE_PSUBUSW,
7862 INTRINS_SSE_PADDUSB,
7863 INTRINS_SSE_PSUBUSB,
7876 static IntrinsicDesc intrinsics[] = {
7877 {INTRINS_MEMSET, "llvm.memset.p0i8.i32"},
7878 {INTRINS_MEMCPY, "llvm.memcpy.p0i8.p0i8.i32"},
7879 {INTRINS_SADD_OVF_I32, "llvm.sadd.with.overflow.i32"},
7880 {INTRINS_UADD_OVF_I32, "llvm.uadd.with.overflow.i32"},
7881 {INTRINS_SSUB_OVF_I32, "llvm.ssub.with.overflow.i32"},
7882 {INTRINS_USUB_OVF_I32, "llvm.usub.with.overflow.i32"},
7883 {INTRINS_SMUL_OVF_I32, "llvm.smul.with.overflow.i32"},
7884 {INTRINS_UMUL_OVF_I32, "llvm.umul.with.overflow.i32"},
7885 {INTRINS_SADD_OVF_I64, "llvm.sadd.with.overflow.i64"},
7886 {INTRINS_UADD_OVF_I64, "llvm.uadd.with.overflow.i64"},
7887 {INTRINS_SSUB_OVF_I64, "llvm.ssub.with.overflow.i64"},
7888 {INTRINS_USUB_OVF_I64, "llvm.usub.with.overflow.i64"},
7889 {INTRINS_SMUL_OVF_I64, "llvm.smul.with.overflow.i64"},
7890 {INTRINS_UMUL_OVF_I64, "llvm.umul.with.overflow.i64"},
7891 {INTRINS_SIN, "llvm.sin.f64"},
7892 {INTRINS_COS, "llvm.cos.f64"},
7893 {INTRINS_SQRT, "llvm.sqrt.f64"},
7894 /* This isn't an intrinsic, instead llvm seems to special case it by name */
7895 {INTRINS_FABS, "fabs"},
7896 {INTRINS_EXPECT_I8, "llvm.expect.i8"},
7897 {INTRINS_EXPECT_I1, "llvm.expect.i1"},
7898 #if defined(TARGET_AMD64) || defined(TARGET_X86)
7899 {INTRINS_SSE_PMOVMSKB, "llvm.x86.sse2.pmovmskb.128"},
7900 {INTRINS_SSE_PSRLI_W, "llvm.x86.sse2.psrli.w"},
7901 {INTRINS_SSE_PSRAI_W, "llvm.x86.sse2.psrai.w"},
7902 {INTRINS_SSE_PSLLI_W, "llvm.x86.sse2.pslli.w"},
7903 {INTRINS_SSE_PSRLI_D, "llvm.x86.sse2.psrli.d"},
7904 {INTRINS_SSE_PSRAI_D, "llvm.x86.sse2.psrai.d"},
7905 {INTRINS_SSE_PSLLI_D, "llvm.x86.sse2.pslli.d"},
7906 {INTRINS_SSE_PSRLI_Q, "llvm.x86.sse2.psrli.q"},
7907 {INTRINS_SSE_PSLLI_Q, "llvm.x86.sse2.pslli.q"},
7908 {INTRINS_SSE_SQRT_PD, "llvm.x86.sse2.sqrt.pd"},
7909 {INTRINS_SSE_SQRT_PS, "llvm.x86.sse.sqrt.ps"},
7910 {INTRINS_SSE_RSQRT_PS, "llvm.x86.sse.rsqrt.ps"},
7911 {INTRINS_SSE_RCP_PS, "llvm.x86.sse.rcp.ps"},
7912 {INTRINS_SSE_CVTTPD2DQ, "llvm.x86.sse2.cvttpd2dq"},
7913 {INTRINS_SSE_CVTTPS2DQ, "llvm.x86.sse2.cvttps2dq"},
7914 {INTRINS_SSE_CVTDQ2PD, "llvm.x86.sse2.cvtdq2pd"},
7915 {INTRINS_SSE_CVTDQ2PS, "llvm.x86.sse2.cvtdq2ps"},
7916 {INTRINS_SSE_CVTPD2DQ, "llvm.x86.sse2.cvtpd2dq"},
7917 {INTRINS_SSE_CVTPS2DQ, "llvm.x86.sse2.cvtps2dq"},
7918 {INTRINS_SSE_CVTPD2PS, "llvm.x86.sse2.cvtpd2ps"},
7919 {INTRINS_SSE_CVTPS2PD, "llvm.x86.sse2.cvtps2pd"},
7920 {INTRINS_SSE_CMPPD, "llvm.x86.sse2.cmp.pd"},
7921 {INTRINS_SSE_CMPPS, "llvm.x86.sse.cmp.ps"},
7922 {INTRINS_SSE_PACKSSWB, "llvm.x86.sse2.packsswb.128"},
7923 {INTRINS_SSE_PACKUSWB, "llvm.x86.sse2.packuswb.128"},
7924 {INTRINS_SSE_PACKSSDW, "llvm.x86.sse2.packssdw.128"},
7925 {INTRINS_SSE_PACKUSDW, "llvm.x86.sse41.packusdw"},
7926 {INTRINS_SSE_MINPS, "llvm.x86.sse.min.ps"},
7927 {INTRINS_SSE_MAXPS, "llvm.x86.sse.max.ps"},
7928 {INTRINS_SSE_HADDPS, "llvm.x86.sse3.hadd.ps"},
7929 {INTRINS_SSE_HSUBPS, "llvm.x86.sse3.hsub.ps"},
7930 {INTRINS_SSE_ADDSUBPS, "llvm.x86.sse3.addsub.ps"},
7931 {INTRINS_SSE_MINPD, "llvm.x86.sse2.min.pd"},
7932 {INTRINS_SSE_MAXPD, "llvm.x86.sse2.max.pd"},
7933 {INTRINS_SSE_HADDPD, "llvm.x86.sse3.hadd.pd"},
7934 {INTRINS_SSE_HSUBPD, "llvm.x86.sse3.hsub.pd"},
7935 {INTRINS_SSE_ADDSUBPD, "llvm.x86.sse3.addsub.pd"},
7936 {INTRINS_SSE_PADDSW, "llvm.x86.sse2.padds.w"},
7937 {INTRINS_SSE_PSUBSW, "llvm.x86.sse2.psubs.w"},
7938 {INTRINS_SSE_PADDUSW, "llvm.x86.sse2.paddus.w"},
7939 {INTRINS_SSE_PSUBUSW, "llvm.x86.sse2.psubus.w"},
7940 {INTRINS_SSE_PAVGW, "llvm.x86.sse2.pavg.w"},
7941 {INTRINS_SSE_PMULHW, "llvm.x86.sse2.pmulh.w"},
7942 {INTRINS_SSE_PMULHU, "llvm.x86.sse2.pmulhu.w"},
7943 {INTRINS_SE_PADDSB, "llvm.x86.sse2.padds.b"},
7944 {INTRINS_SSE_PSUBSB, "llvm.x86.sse2.psubs.b"},
7945 {INTRINS_SSE_PADDUSB, "llvm.x86.sse2.paddus.b"},
7946 {INTRINS_SSE_PSUBUSB, "llvm.x86.sse2.psubus.b"},
7947 {INTRINS_SSE_PAVGB, "llvm.x86.sse2.pavg.b"},
7948 {INTRINS_SSE_PAUSE, "llvm.x86.sse2.pause"},
7949 {INTRINS_SSE_DPPS, "llvm.x86.sse41.dpps"}
7954 add_sse_binary (LLVMModuleRef module, const char *name, int type)
7956 LLVMTypeRef ret_type = type_to_simd_type (type);
7957 AddFunc2 (module, name, ret_type, ret_type, ret_type);
7961 add_intrinsic (LLVMModuleRef module, int id)
7964 #if defined(TARGET_AMD64) || defined(TARGET_X86)
7965 LLVMTypeRef ret_type, arg_types [16];
7968 name = g_hash_table_lookup (intrins_id_to_name, GINT_TO_POINTER (id));
7972 case INTRINS_MEMSET: {
7973 LLVMTypeRef params [] = { LLVMPointerType (LLVMInt8Type (), 0), LLVMInt8Type (), LLVMInt32Type (), LLVMInt32Type (), LLVMInt1Type () };
7975 AddFunc (module, name, LLVMVoidType (), params, 5);
7978 case INTRINS_MEMCPY: {
7979 LLVMTypeRef params [] = { LLVMPointerType (LLVMInt8Type (), 0), LLVMPointerType (LLVMInt8Type (), 0), LLVMInt32Type (), LLVMInt32Type (), LLVMInt1Type () };
7981 AddFunc (module, name, LLVMVoidType (), params, 5);
7984 case INTRINS_SADD_OVF_I32:
7985 case INTRINS_UADD_OVF_I32:
7986 case INTRINS_SSUB_OVF_I32:
7987 case INTRINS_USUB_OVF_I32:
7988 case INTRINS_SMUL_OVF_I32:
7989 case INTRINS_UMUL_OVF_I32: {
7990 LLVMTypeRef ovf_res_i32 [] = { LLVMInt32Type (), LLVMInt1Type () };
7991 LLVMTypeRef params [] = { LLVMInt32Type (), LLVMInt32Type () };
7992 LLVMTypeRef ret_type = LLVMStructType (ovf_res_i32, 2, FALSE);
7994 AddFunc (module, name, ret_type, params, 2);
7997 case INTRINS_SADD_OVF_I64:
7998 case INTRINS_UADD_OVF_I64:
7999 case INTRINS_SSUB_OVF_I64:
8000 case INTRINS_USUB_OVF_I64:
8001 case INTRINS_SMUL_OVF_I64:
8002 case INTRINS_UMUL_OVF_I64: {
8003 LLVMTypeRef ovf_res_i64 [] = { LLVMInt64Type (), LLVMInt1Type () };
8004 LLVMTypeRef params [] = { LLVMInt64Type (), LLVMInt64Type () };
8005 LLVMTypeRef ret_type = LLVMStructType (ovf_res_i64, 2, FALSE);
8007 AddFunc (module, name, ret_type, params, 2);
8013 case INTRINS_FABS: {
8014 LLVMTypeRef params [] = { LLVMDoubleType () };
8016 AddFunc (module, name, LLVMDoubleType (), params, 1);
8019 case INTRINS_EXPECT_I8:
8020 AddFunc2 (module, name, LLVMInt8Type (), LLVMInt8Type (), LLVMInt8Type ());
8022 case INTRINS_EXPECT_I1:
8023 AddFunc2 (module, name, LLVMInt1Type (), LLVMInt1Type (), LLVMInt1Type ());
8025 #if defined(TARGET_AMD64) || defined(TARGET_X86)
8026 case INTRINS_SSE_PMOVMSKB:
8028 ret_type = LLVMInt32Type ();
8029 arg_types [0] = type_to_simd_type (MONO_TYPE_I1);
8030 AddFunc (module, name, ret_type, arg_types, 1);
8032 case INTRINS_SSE_PSRLI_W:
8033 case INTRINS_SSE_PSRAI_W:
8034 case INTRINS_SSE_PSLLI_W:
8036 ret_type = type_to_simd_type (MONO_TYPE_I2);
8037 arg_types [0] = ret_type;
8038 arg_types [1] = LLVMInt32Type ();
8039 AddFunc (module, name, ret_type, arg_types, 2);
8041 case INTRINS_SSE_PSRLI_D:
8042 case INTRINS_SSE_PSRAI_D:
8043 case INTRINS_SSE_PSLLI_D:
8044 ret_type = type_to_simd_type (MONO_TYPE_I4);
8045 arg_types [0] = ret_type;
8046 arg_types [1] = LLVMInt32Type ();
8047 AddFunc (module, name, ret_type, arg_types, 2);
8049 case INTRINS_SSE_PSRLI_Q:
8050 case INTRINS_SSE_PSLLI_Q:
8051 ret_type = type_to_simd_type (MONO_TYPE_I8);
8052 arg_types [0] = ret_type;
8053 arg_types [1] = LLVMInt32Type ();
8054 AddFunc (module, name, ret_type, arg_types, 2);
8056 case INTRINS_SSE_SQRT_PD:
8058 ret_type = type_to_simd_type (MONO_TYPE_R8);
8059 arg_types [0] = ret_type;
8060 AddFunc (module, name, ret_type, arg_types, 1);
8062 case INTRINS_SSE_SQRT_PS:
8063 ret_type = type_to_simd_type (MONO_TYPE_R4);
8064 arg_types [0] = ret_type;
8065 AddFunc (module, name, ret_type, arg_types, 1);
8067 case INTRINS_SSE_RSQRT_PS:
8068 ret_type = type_to_simd_type (MONO_TYPE_R4);
8069 arg_types [0] = ret_type;
8070 AddFunc (module, name, ret_type, arg_types, 1);
8072 case INTRINS_SSE_RCP_PS:
8073 ret_type = type_to_simd_type (MONO_TYPE_R4);
8074 arg_types [0] = ret_type;
8075 AddFunc (module, name, ret_type, arg_types, 1);
8077 case INTRINS_SSE_CVTTPD2DQ:
8078 ret_type = type_to_simd_type (MONO_TYPE_I4);
8079 arg_types [0] = type_to_simd_type (MONO_TYPE_R8);
8080 AddFunc (module, name, ret_type, arg_types, 1);
8082 case INTRINS_SSE_CVTTPS2DQ:
8083 ret_type = type_to_simd_type (MONO_TYPE_I4);
8084 arg_types [0] = type_to_simd_type (MONO_TYPE_R4);
8085 AddFunc (module, name, ret_type, arg_types, 1);
8087 case INTRINS_SSE_CVTDQ2PD:
8088 /* Conversion ops */
8089 ret_type = type_to_simd_type (MONO_TYPE_R8);
8090 arg_types [0] = type_to_simd_type (MONO_TYPE_I4);
8091 AddFunc (module, name, ret_type, arg_types, 1);
8093 case INTRINS_SSE_CVTDQ2PS:
8094 ret_type = type_to_simd_type (MONO_TYPE_R4);
8095 arg_types [0] = type_to_simd_type (MONO_TYPE_I4);
8096 AddFunc (module, name, ret_type, arg_types, 1);
8098 case INTRINS_SSE_CVTPD2DQ:
8099 ret_type = type_to_simd_type (MONO_TYPE_I4);
8100 arg_types [0] = type_to_simd_type (MONO_TYPE_R8);
8101 AddFunc (module, name, ret_type, arg_types, 1);
8103 case INTRINS_SSE_CVTPS2DQ:
8104 ret_type = type_to_simd_type (MONO_TYPE_I4);
8105 arg_types [0] = type_to_simd_type (MONO_TYPE_R4);
8106 AddFunc (module, name, ret_type, arg_types, 1);
8108 case INTRINS_SSE_CVTPD2PS:
8109 ret_type = type_to_simd_type (MONO_TYPE_R4);
8110 arg_types [0] = type_to_simd_type (MONO_TYPE_R8);
8111 AddFunc (module, name, ret_type, arg_types, 1);
8113 case INTRINS_SSE_CVTPS2PD:
8114 ret_type = type_to_simd_type (MONO_TYPE_R8);
8115 arg_types [0] = type_to_simd_type (MONO_TYPE_R4);
8116 AddFunc (module, name, ret_type, arg_types, 1);
8118 case INTRINS_SSE_CMPPD:
8120 ret_type = type_to_simd_type (MONO_TYPE_R8);
8121 arg_types [0] = ret_type;
8122 arg_types [1] = ret_type;
8123 arg_types [2] = LLVMInt8Type ();
8124 AddFunc (module, name, ret_type, arg_types, 3);
8126 case INTRINS_SSE_CMPPS:
8127 ret_type = type_to_simd_type (MONO_TYPE_R4);
8128 arg_types [0] = ret_type;
8129 arg_types [1] = ret_type;
8130 arg_types [2] = LLVMInt8Type ();
8131 AddFunc (module, name, ret_type, arg_types, 3);
8133 case INTRINS_SSE_PACKSSWB:
8134 case INTRINS_SSE_PACKUSWB:
8135 case INTRINS_SSE_PACKSSDW:
8137 ret_type = type_to_simd_type (MONO_TYPE_I1);
8138 arg_types [0] = type_to_simd_type (MONO_TYPE_I2);
8139 arg_types [1] = type_to_simd_type (MONO_TYPE_I2);
8140 AddFunc (module, name, ret_type, arg_types, 2);
8142 case INTRINS_SSE_PACKUSDW:
8143 ret_type = type_to_simd_type (MONO_TYPE_I2);
8144 arg_types [0] = type_to_simd_type (MONO_TYPE_I4);
8145 arg_types [1] = type_to_simd_type (MONO_TYPE_I4);
8146 AddFunc (module, name, ret_type, arg_types, 2);
8148 /* SSE Binary ops */
8149 case INTRINS_SSE_PADDSW:
8150 case INTRINS_SSE_PSUBSW:
8151 case INTRINS_SSE_PADDUSW:
8152 case INTRINS_SSE_PSUBUSW:
8153 case INTRINS_SSE_PAVGW:
8154 case INTRINS_SSE_PMULHW:
8155 case INTRINS_SSE_PMULHU:
8156 add_sse_binary (module, name, MONO_TYPE_I2);
8158 case INTRINS_SSE_MINPS:
8159 case INTRINS_SSE_MAXPS:
8160 case INTRINS_SSE_HADDPS:
8161 case INTRINS_SSE_HSUBPS:
8162 case INTRINS_SSE_ADDSUBPS:
8163 add_sse_binary (module, name, MONO_TYPE_R4);
8165 case INTRINS_SSE_MINPD:
8166 case INTRINS_SSE_MAXPD:
8167 case INTRINS_SSE_HADDPD:
8168 case INTRINS_SSE_HSUBPD:
8169 case INTRINS_SSE_ADDSUBPD:
8170 add_sse_binary (module, name, MONO_TYPE_R8);
8172 case INTRINS_SE_PADDSB:
8173 case INTRINS_SSE_PSUBSB:
8174 case INTRINS_SSE_PADDUSB:
8175 case INTRINS_SSE_PSUBUSB:
8176 case INTRINS_SSE_PAVGB:
8177 add_sse_binary (module, name, MONO_TYPE_I1);
8179 case INTRINS_SSE_PAUSE:
8180 AddFunc (module, "llvm.x86.sse2.pause", LLVMVoidType (), NULL, 0);
8182 case INTRINS_SSE_DPPS:
8183 ret_type = type_to_simd_type (MONO_TYPE_R4);
8184 arg_types [0] = type_to_simd_type (MONO_TYPE_R4);
8185 arg_types [1] = type_to_simd_type (MONO_TYPE_R4);
8186 arg_types [2] = LLVMInt32Type ();
8187 AddFunc (module, name, ret_type, arg_types, 3);
8191 g_assert_not_reached ();
8197 get_intrinsic (EmitContext *ctx, const char *name)
8199 #if LLVM_API_VERSION > 100
8203 * Every method is emitted into its own module so
8204 * we can add intrinsics on demand.
8206 res = LLVMGetNamedFunction (ctx->lmodule, name);
8210 /* No locking needed */
8211 id = GPOINTER_TO_INT (g_hash_table_lookup (intrins_name_to_id, name));
8214 printf ("%s\n", name);
8215 g_assert (id != -1);
8216 add_intrinsic (ctx->lmodule, id);
8217 res = LLVMGetNamedFunction (ctx->lmodule, name);
8225 res = LLVMGetNamedFunction (ctx->lmodule, name);
8232 add_intrinsics (LLVMModuleRef module)
8236 /* Emit declarations of instrinsics */
8238 * It would be nicer to emit only the intrinsics actually used, but LLVM's Module
8239 * type doesn't seem to do any locking.
8241 for (i = 0; i < INTRINS_NUM; ++i)
8242 add_intrinsic (module, i);
8246 AddFunc (module, "mono_personality", LLVMVoidType (), NULL, 0);
8248 AddFunc (module, "llvm_resume_unwind_trampoline", LLVMVoidType (), NULL, 0);
8251 /* Load/Store intrinsics */
8253 LLVMTypeRef arg_types [5];
8257 for (i = 1; i <= 8; i *= 2) {
8258 arg_types [0] = LLVMPointerType (LLVMIntType (i * 8), 0);
8259 arg_types [1] = LLVMInt32Type ();
8260 arg_types [2] = LLVMInt1Type ();
8261 arg_types [3] = LLVMInt32Type ();
8262 sprintf (name, "llvm.mono.load.i%d.p0i%d", i * 8, i * 8);
8263 AddFunc (module, name, LLVMIntType (i * 8), arg_types, 4);
8265 arg_types [0] = LLVMIntType (i * 8);
8266 arg_types [1] = LLVMPointerType (LLVMIntType (i * 8), 0);
8267 arg_types [2] = LLVMInt32Type ();
8268 arg_types [3] = LLVMInt1Type ();
8269 arg_types [4] = LLVMInt32Type ();
8270 sprintf (name, "llvm.mono.store.i%d.p0i%d", i * 8, i * 8);
8271 AddFunc (module, name, LLVMVoidType (), arg_types, 5);
8277 add_types (MonoLLVMModule *module)
8279 module->ptr_type = LLVMPointerType (sizeof (gpointer) == 8 ? LLVMInt64Type () : LLVMInt32Type (), 0);
8283 mono_llvm_init (void)
8288 mono_native_tls_alloc (¤t_cfg_tls_id, NULL);
8290 h = g_hash_table_new (NULL, NULL);
8291 for (i = 0; i < INTRINS_NUM; ++i)
8292 g_hash_table_insert (h, GINT_TO_POINTER (intrinsics [i].id), (gpointer)intrinsics [i].name);
8293 intrins_id_to_name = h;
8295 h = g_hash_table_new (g_str_hash, g_str_equal);
8296 for (i = 0; i < INTRINS_NUM; ++i)
8297 g_hash_table_insert (h, (gpointer)intrinsics [i].name, GINT_TO_POINTER (intrinsics [i].id + 1));
8298 intrins_name_to_id = h;
8302 init_jit_module (MonoDomain *domain)
8304 MonoJitDomainInfo *dinfo;
8305 MonoLLVMModule *module;
8308 dinfo = domain_jit_info (domain);
8309 if (dinfo->llvm_module)
8312 mono_loader_lock ();
8314 if (dinfo->llvm_module) {
8315 mono_loader_unlock ();
8319 module = g_new0 (MonoLLVMModule, 1);
8321 name = g_strdup_printf ("mono-%s", domain->friendly_name);
8322 module->lmodule = LLVMModuleCreateWithName (name);
8323 module->context = LLVMGetGlobalContext ();
8325 module->mono_ee = (MonoEERef*)mono_llvm_create_ee (LLVMCreateModuleProviderForExistingModule (module->lmodule), alloc_cb, emitted_cb, exception_cb, dlsym_cb, &module->ee);
8327 add_intrinsics (module->lmodule);
8330 module->llvm_types = g_hash_table_new (NULL, NULL);
8332 #if LLVM_API_VERSION < 100
8333 MonoJitICallInfo *info;
8335 info = mono_find_jit_icall_by_name ("llvm_resume_unwind_trampoline");
8337 LLVMAddGlobalMapping (module->ee, LLVMGetNamedFunction (module->lmodule, "llvm_resume_unwind_trampoline"), (void*)info->func);
8340 mono_memory_barrier ();
8342 dinfo->llvm_module = module;
8344 mono_loader_unlock ();
8348 mono_llvm_cleanup (void)
8350 MonoLLVMModule *module = &aot_module;
8352 if (module->lmodule)
8353 LLVMDisposeModule (module->lmodule);
8355 if (module->context)
8356 LLVMContextDispose (module->context);
8360 mono_llvm_free_domain_info (MonoDomain *domain)
8362 MonoJitDomainInfo *info = domain_jit_info (domain);
8363 MonoLLVMModule *module = (MonoLLVMModule*)info->llvm_module;
8369 if (module->llvm_types)
8370 g_hash_table_destroy (module->llvm_types);
8372 mono_llvm_dispose_ee (module->mono_ee);
8374 if (module->bb_names) {
8375 for (i = 0; i < module->bb_names_len; ++i)
8376 g_free (module->bb_names [i]);
8377 g_free (module->bb_names);
8379 //LLVMDisposeModule (module->module);
8383 info->llvm_module = NULL;
8387 mono_llvm_create_aot_module (MonoAssembly *assembly, const char *global_prefix, gboolean emit_dwarf, gboolean static_link, gboolean llvm_only)
8389 MonoLLVMModule *module = &aot_module;
8391 /* Delete previous module */
8392 if (module->plt_entries)
8393 g_hash_table_destroy (module->plt_entries);
8394 if (module->lmodule)
8395 LLVMDisposeModule (module->lmodule);
8397 memset (module, 0, sizeof (aot_module));
8399 module->lmodule = LLVMModuleCreateWithName ("aot");
8400 module->assembly = assembly;
8401 module->global_prefix = g_strdup (global_prefix);
8402 module->got_symbol = g_strdup_printf ("%s_llvm_got", global_prefix);
8403 module->eh_frame_symbol = g_strdup_printf ("%s_eh_frame", global_prefix);
8404 module->get_method_symbol = g_strdup_printf ("%s_get_method", global_prefix);
8405 module->get_unbox_tramp_symbol = g_strdup_printf ("%s_get_unbox_tramp", global_prefix);
8406 module->external_symbols = TRUE;
8407 module->emit_dwarf = emit_dwarf;
8408 module->static_link = static_link;
8409 module->llvm_only = llvm_only;
8410 /* The first few entries are reserved */
8411 module->max_got_offset = 16;
8412 module->context = LLVMGetGlobalContext ();
8415 /* clang ignores our debug info because it has an invalid version */
8416 module->emit_dwarf = FALSE;
8418 add_intrinsics (module->lmodule);
8421 #if LLVM_API_VERSION > 100
8422 if (module->emit_dwarf) {
8423 char *dir, *build_info, *s, *cu_name;
8425 module->di_builder = mono_llvm_create_di_builder (module->lmodule);
8428 dir = g_strdup (".");
8429 build_info = mono_get_runtime_build_info ();
8430 s = g_strdup_printf ("Mono AOT Compiler %s (LLVM)", build_info);
8431 cu_name = g_path_get_basename (assembly->image->name);
8432 module->cu = mono_llvm_di_create_compile_unit (module->di_builder, cu_name, dir, s);
8434 g_free (build_info);
8441 * We couldn't compute the type of the LLVM global representing the got because
8442 * its size is only known after all the methods have been emitted. So create
8443 * a dummy variable, and replace all uses it with the real got variable when
8444 * its size is known in mono_llvm_emit_aot_module ().
8447 LLVMTypeRef got_type = LLVMArrayType (module->ptr_type, 0);
8449 module->got_var = LLVMAddGlobal (module->lmodule, got_type, "mono_dummy_got");
8450 LLVMSetInitializer (module->got_var, LLVMConstNull (got_type));
8453 /* Add initialization array */
8455 LLVMTypeRef inited_type = LLVMArrayType (LLVMInt8Type (), 0);
8457 module->inited_var = LLVMAddGlobal (aot_module.lmodule, inited_type, "mono_inited_tmp");
8458 LLVMSetInitializer (module->inited_var, LLVMConstNull (inited_type));
8462 emit_init_icall_wrappers (module);
8464 emit_llvm_code_start (module);
8466 /* Add a dummy personality function */
8467 if (!use_debug_personality) {
8468 LLVMValueRef personality = LLVMAddFunction (module->lmodule, default_personality_name, LLVMFunctionType (LLVMInt32Type (), NULL, 0, TRUE));
8469 LLVMSetLinkage (personality, LLVMExternalLinkage);
8470 mark_as_used (module, personality);
8473 /* Add a reference to the c++ exception we throw/catch */
8475 LLVMTypeRef exc = LLVMPointerType (LLVMInt8Type (), 0);
8476 module->sentinel_exception = LLVMAddGlobal (module->lmodule, exc, "_ZTIPi");
8477 LLVMSetLinkage (module->sentinel_exception, LLVMExternalLinkage);
8478 mono_llvm_set_is_constant (module->sentinel_exception);
8481 module->llvm_types = g_hash_table_new (NULL, NULL);
8482 module->plt_entries = g_hash_table_new (g_str_hash, g_str_equal);
8483 module->plt_entries_ji = g_hash_table_new (NULL, NULL);
8484 module->direct_callables = g_hash_table_new (g_str_hash, g_str_equal);
8485 module->method_to_lmethod = g_hash_table_new (NULL, NULL);
8486 module->idx_to_lmethod = g_hash_table_new (NULL, NULL);
8487 module->idx_to_unbox_tramp = g_hash_table_new (NULL, NULL);
8488 module->method_to_callers = g_hash_table_new (NULL, NULL);
8492 llvm_array_from_uints (LLVMTypeRef el_type, guint32 *values, int nvalues)
8495 LLVMValueRef res, *vals;
8497 vals = g_new0 (LLVMValueRef, nvalues);
8498 for (i = 0; i < nvalues; ++i)
8499 vals [i] = LLVMConstInt (LLVMInt32Type (), values [i], FALSE);
8500 res = LLVMConstArray (LLVMInt32Type (), vals, nvalues);
8506 llvm_array_from_bytes (guint8 *values, int nvalues)
8509 LLVMValueRef res, *vals;
8511 vals = g_new0 (LLVMValueRef, nvalues);
8512 for (i = 0; i < nvalues; ++i)
8513 vals [i] = LLVMConstInt (LLVMInt8Type (), values [i], FALSE);
8514 res = LLVMConstArray (LLVMInt8Type (), vals, nvalues);
8519 * mono_llvm_emit_aot_file_info:
8521 * Emit the MonoAotFileInfo structure.
8522 * Same as emit_aot_file_info () in aot-compiler.c.
8525 mono_llvm_emit_aot_file_info (MonoAotFileInfo *info, gboolean has_jitted_code)
8527 MonoLLVMModule *module = &aot_module;
8529 /* Save these for later */
8530 memcpy (&module->aot_info, info, sizeof (MonoAotFileInfo));
8531 module->has_jitted_code = has_jitted_code;
8535 * mono_llvm_emit_aot_data:
8537 * Emit the binary data DATA pointed to by symbol SYMBOL.
8540 mono_llvm_emit_aot_data (const char *symbol, guint8 *data, int data_len)
8542 MonoLLVMModule *module = &aot_module;
8546 type = LLVMArrayType (LLVMInt8Type (), data_len);
8547 d = LLVMAddGlobal (module->lmodule, type, symbol);
8548 LLVMSetVisibility (d, LLVMHiddenVisibility);
8549 LLVMSetLinkage (d, LLVMInternalLinkage);
8550 LLVMSetInitializer (d, mono_llvm_create_constant_data_array (data, data_len));
8551 mono_llvm_set_is_constant (d);
8554 /* Add a reference to a global defined in JITted code */
8556 AddJitGlobal (MonoLLVMModule *module, LLVMTypeRef type, const char *name)
8561 s = g_strdup_printf ("%s%s", module->global_prefix, name);
8562 v = LLVMAddGlobal (module->lmodule, LLVMInt8Type (), s);
8568 emit_aot_file_info (MonoLLVMModule *module)
8570 LLVMTypeRef file_info_type;
8571 LLVMTypeRef *eltypes, eltype;
8572 LLVMValueRef info_var;
8573 LLVMValueRef *fields;
8574 int i, nfields, tindex;
8575 MonoAotFileInfo *info;
8576 LLVMModuleRef lmodule = module->lmodule;
8578 info = &module->aot_info;
8580 /* Create an LLVM type to represent MonoAotFileInfo */
8581 nfields = 2 + MONO_AOT_FILE_INFO_NUM_SYMBOLS + 16 + 5;
8582 eltypes = g_new (LLVMTypeRef, nfields);
8584 eltypes [tindex ++] = LLVMInt32Type ();
8585 eltypes [tindex ++] = LLVMInt32Type ();
8587 for (i = 0; i < MONO_AOT_FILE_INFO_NUM_SYMBOLS; ++i)
8588 eltypes [tindex ++] = LLVMPointerType (LLVMInt8Type (), 0);
8590 for (i = 0; i < 15; ++i)
8591 eltypes [tindex ++] = LLVMInt32Type ();
8593 eltypes [tindex ++] = LLVMArrayType (LLVMInt32Type (), MONO_AOT_TABLE_NUM);
8594 for (i = 0; i < 4; ++i)
8595 eltypes [tindex ++] = LLVMArrayType (LLVMInt32Type (), MONO_AOT_TRAMP_NUM);
8596 eltypes [tindex ++] = LLVMArrayType (LLVMInt8Type (), 16);
8597 g_assert (tindex == nfields);
8598 file_info_type = LLVMStructCreateNamed (module->context, "MonoAotFileInfo");
8599 LLVMStructSetBody (file_info_type, eltypes, nfields, FALSE);
8601 info_var = LLVMAddGlobal (lmodule, file_info_type, "mono_aot_file_info");
8602 if (module->static_link) {
8603 LLVMSetVisibility (info_var, LLVMHiddenVisibility);
8604 LLVMSetLinkage (info_var, LLVMInternalLinkage);
8606 fields = g_new (LLVMValueRef, nfields);
8608 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->version, FALSE);
8609 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->dummy, FALSE);
8613 * We use LLVMGetNamedGlobal () for symbol which are defined in LLVM code, and LLVMAddGlobal ()
8614 * for symbols defined in the .s file emitted by the aot compiler.
8616 eltype = eltypes [tindex];
8617 if (module->llvm_only)
8618 fields [tindex ++] = LLVMConstNull (eltype);
8620 fields [tindex ++] = AddJitGlobal (module, eltype, "jit_got");
8621 fields [tindex ++] = module->got_var;
8622 /* llc defines this directly */
8623 if (!module->llvm_only) {
8624 fields [tindex ++] = LLVMAddGlobal (lmodule, eltype, module->eh_frame_symbol);
8625 fields [tindex ++] = LLVMConstNull (eltype);
8626 fields [tindex ++] = LLVMConstNull (eltype);
8628 fields [tindex ++] = LLVMConstNull (eltype);
8629 fields [tindex ++] = module->get_method;
8630 fields [tindex ++] = module->get_unbox_tramp;
8632 if (module->has_jitted_code) {
8633 fields [tindex ++] = AddJitGlobal (module, eltype, "jit_code_start");
8634 fields [tindex ++] = AddJitGlobal (module, eltype, "jit_code_end");
8636 fields [tindex ++] = LLVMConstNull (eltype);
8637 fields [tindex ++] = LLVMConstNull (eltype);
8639 if (!module->llvm_only)
8640 fields [tindex ++] = AddJitGlobal (module, eltype, "method_addresses");
8642 fields [tindex ++] = LLVMConstNull (eltype);
8643 if (info->flags & MONO_AOT_FILE_FLAG_SEPARATE_DATA) {
8644 for (i = 0; i < MONO_AOT_TABLE_NUM; ++i)
8645 fields [tindex ++] = LLVMConstNull (eltype);
8647 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "blob");
8648 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "class_name_table");
8649 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "class_info_offsets");
8650 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "method_info_offsets");
8651 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "ex_info_offsets");
8652 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "extra_method_info_offsets");
8653 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "extra_method_table");
8654 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "got_info_offsets");
8655 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "llvm_got_info_offsets");
8656 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "image_table");
8658 /* Not needed (mem_end) */
8659 fields [tindex ++] = LLVMConstNull (eltype);
8660 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "assembly_guid");
8661 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "runtime_version");
8662 if (info->trampoline_size [0]) {
8663 fields [tindex ++] = AddJitGlobal (module, eltype, "specific_trampolines");
8664 fields [tindex ++] = AddJitGlobal (module, eltype, "static_rgctx_trampolines");
8665 fields [tindex ++] = AddJitGlobal (module, eltype, "imt_trampolines");
8666 fields [tindex ++] = AddJitGlobal (module, eltype, "gsharedvt_arg_trampolines");
8668 fields [tindex ++] = LLVMConstNull (eltype);
8669 fields [tindex ++] = LLVMConstNull (eltype);
8670 fields [tindex ++] = LLVMConstNull (eltype);
8671 fields [tindex ++] = LLVMConstNull (eltype);
8673 if (module->static_link && !module->llvm_only)
8674 fields [tindex ++] = AddJitGlobal (module, eltype, "globals");
8676 fields [tindex ++] = LLVMConstNull (eltype);
8677 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "assembly_name");
8678 if (!module->llvm_only) {
8679 fields [tindex ++] = AddJitGlobal (module, eltype, "plt");
8680 fields [tindex ++] = AddJitGlobal (module, eltype, "plt_end");
8681 fields [tindex ++] = AddJitGlobal (module, eltype, "unwind_info");
8682 fields [tindex ++] = AddJitGlobal (module, eltype, "unbox_trampolines");
8683 fields [tindex ++] = AddJitGlobal (module, eltype, "unbox_trampolines_end");
8684 fields [tindex ++] = AddJitGlobal (module, eltype, "unbox_trampoline_addresses");
8686 fields [tindex ++] = LLVMConstNull (eltype);
8687 fields [tindex ++] = LLVMConstNull (eltype);
8688 fields [tindex ++] = LLVMConstNull (eltype);
8689 fields [tindex ++] = LLVMConstNull (eltype);
8690 fields [tindex ++] = LLVMConstNull (eltype);
8691 fields [tindex ++] = LLVMConstNull (eltype);
8694 for (i = 0; i < MONO_AOT_FILE_INFO_NUM_SYMBOLS; ++i)
8695 fields [2 + i] = LLVMConstBitCast (fields [2 + i], eltype);
8698 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->plt_got_offset_base, FALSE);
8699 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->got_size, FALSE);
8700 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->plt_size, FALSE);
8701 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->nmethods, FALSE);
8702 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->flags, FALSE);
8703 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->opts, FALSE);
8704 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->simd_opts, FALSE);
8705 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->gc_name_index, FALSE);
8706 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->num_rgctx_fetch_trampolines, FALSE);
8707 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->double_align, FALSE);
8708 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->long_align, FALSE);
8709 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->generic_tramp_num, FALSE);
8710 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->tramp_page_size, FALSE);
8711 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->nshared_got_entries, FALSE);
8712 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->datafile_size, FALSE);
8714 fields [tindex ++] = llvm_array_from_uints (LLVMInt32Type (), info->table_offsets, MONO_AOT_TABLE_NUM);
8715 fields [tindex ++] = llvm_array_from_uints (LLVMInt32Type (), info->num_trampolines, MONO_AOT_TRAMP_NUM);
8716 fields [tindex ++] = llvm_array_from_uints (LLVMInt32Type (), info->trampoline_got_offset_base, MONO_AOT_TRAMP_NUM);
8717 fields [tindex ++] = llvm_array_from_uints (LLVMInt32Type (), info->trampoline_size, MONO_AOT_TRAMP_NUM);
8718 fields [tindex ++] = llvm_array_from_uints (LLVMInt32Type (), info->tramp_page_code_offsets, MONO_AOT_TRAMP_NUM);
8720 fields [tindex ++] = llvm_array_from_bytes (info->aotid, 16);
8721 g_assert (tindex == nfields);
8723 LLVMSetInitializer (info_var, LLVMConstNamedStruct (file_info_type, fields, nfields));
8725 if (module->static_link) {
8729 s = g_strdup_printf ("mono_aot_module_%s_info", module->assembly->aname.name);
8730 /* Get rid of characters which cannot occur in symbols */
8732 for (p = s; *p; ++p) {
8733 if (!(isalnum (*p) || *p == '_'))
8736 var = LLVMAddGlobal (module->lmodule, LLVMPointerType (LLVMInt8Type (), 0), s);
8738 LLVMSetInitializer (var, LLVMConstBitCast (LLVMGetNamedGlobal (module->lmodule, "mono_aot_file_info"), LLVMPointerType (LLVMInt8Type (), 0)));
8739 LLVMSetLinkage (var, LLVMExternalLinkage);
8744 * Emit the aot module into the LLVM bitcode file FILENAME.
8747 mono_llvm_emit_aot_module (const char *filename, const char *cu_name)
8749 LLVMTypeRef got_type, inited_type;
8750 LLVMValueRef real_got, real_inited;
8751 MonoLLVMModule *module = &aot_module;
8753 emit_llvm_code_end (module);
8756 * Create the real got variable and replace all uses of the dummy variable with
8759 got_type = LLVMArrayType (module->ptr_type, module->max_got_offset + 1);
8760 real_got = LLVMAddGlobal (module->lmodule, got_type, module->got_symbol);
8761 LLVMSetInitializer (real_got, LLVMConstNull (got_type));
8762 if (module->external_symbols) {
8763 LLVMSetLinkage (real_got, LLVMExternalLinkage);
8764 LLVMSetVisibility (real_got, LLVMHiddenVisibility);
8766 LLVMSetLinkage (real_got, LLVMInternalLinkage);
8768 mono_llvm_replace_uses_of (module->got_var, real_got);
8770 mark_as_used (&aot_module, real_got);
8772 /* Delete the dummy got so it doesn't become a global */
8773 LLVMDeleteGlobal (module->got_var);
8774 module->got_var = real_got;
8777 * Same for the init_var
8779 if (module->llvm_only) {
8780 inited_type = LLVMArrayType (LLVMInt8Type (), module->max_inited_idx + 1);
8781 real_inited = LLVMAddGlobal (module->lmodule, inited_type, "mono_inited");
8782 LLVMSetInitializer (real_inited, LLVMConstNull (inited_type));
8783 LLVMSetLinkage (real_inited, LLVMInternalLinkage);
8784 mono_llvm_replace_uses_of (module->inited_var, real_inited);
8785 LLVMDeleteGlobal (module->inited_var);
8788 if (module->llvm_only) {
8789 emit_get_method (&aot_module);
8790 emit_get_unbox_tramp (&aot_module);
8793 emit_llvm_used (&aot_module);
8794 emit_dbg_info (&aot_module, filename, cu_name);
8795 emit_aot_file_info (&aot_module);
8798 * Replace GOT entries for directly callable methods with the methods themselves.
8799 * It would be easier to implement this by predefining all methods before compiling
8800 * their bodies, but that couldn't handle the case when a method fails to compile
8803 if (module->llvm_only) {
8804 GHashTableIter iter;
8806 GSList *callers, *l;
8808 g_hash_table_iter_init (&iter, module->method_to_callers);
8809 while (g_hash_table_iter_next (&iter, (void**)&method, (void**)&callers)) {
8810 LLVMValueRef lmethod;
8812 if (method->iflags & METHOD_IMPL_ATTRIBUTE_SYNCHRONIZED)
8815 lmethod = (LLVMValueRef)g_hash_table_lookup (module->method_to_lmethod, method);
8817 for (l = callers; l; l = l->next) {
8818 LLVMValueRef caller = (LLVMValueRef)l->data;
8820 mono_llvm_replace_uses_of (caller, lmethod);
8826 /* Replace PLT entries for directly callable methods with the methods themselves */
8828 GHashTableIter iter;
8830 LLVMValueRef callee;
8832 g_hash_table_iter_init (&iter, module->plt_entries_ji);
8833 while (g_hash_table_iter_next (&iter, (void**)&ji, (void**)&callee)) {
8834 if (mono_aot_is_direct_callable (ji)) {
8835 LLVMValueRef lmethod;
8837 lmethod = (LLVMValueRef)g_hash_table_lookup (module->method_to_lmethod, ji->data.method);
8838 /* The types might not match because the caller might pass an rgctx */
8839 if (lmethod && LLVMTypeOf (callee) == LLVMTypeOf (lmethod)) {
8840 mono_llvm_replace_uses_of (callee, lmethod);
8841 mono_aot_mark_unused_llvm_plt_entry (ji);
8851 if (LLVMVerifyModule (module->lmodule, LLVMReturnStatusAction, &verifier_err)) {
8852 printf ("%s\n", verifier_err);
8853 g_assert_not_reached ();
8858 LLVMWriteBitcodeToFile (module->lmodule, filename);
8863 md_string (const char *s)
8865 return LLVMMDString (s, strlen (s));
8868 /* Debugging support */
8871 emit_dbg_info (MonoLLVMModule *module, const char *filename, const char *cu_name)
8873 LLVMModuleRef lmodule = module->lmodule;
8874 LLVMValueRef args [16], ver;
8877 * This can only be enabled when LLVM code is emitted into a separate object
8878 * file, since the AOT compiler also emits dwarf info,
8879 * and the abbrev indexes will not be correct since llvm has added its own
8882 if (!module->emit_dwarf)
8885 #if LLVM_API_VERSION > 100
8886 mono_llvm_di_builder_finalize (module->di_builder);
8888 LLVMValueRef cu_args [16], cu;
8890 char *build_info, *s, *dir;
8893 * Emit dwarf info in the form of LLVM metadata. There is some
8894 * out-of-date documentation at:
8895 * http://llvm.org/docs/SourceLevelDebugging.html
8896 * but most of this was gathered from the llvm and
8901 cu_args [n_cuargs ++] = LLVMConstInt (LLVMInt32Type (), DW_TAG_compile_unit, FALSE);
8902 /* CU name/compilation dir */
8903 dir = g_path_get_dirname (filename);
8904 args [0] = LLVMMDString (cu_name, strlen (cu_name));
8905 args [1] = LLVMMDString (dir, strlen (dir));
8906 cu_args [n_cuargs ++] = LLVMMDNode (args, 2);
8909 cu_args [n_cuargs ++] = LLVMConstInt (LLVMInt32Type (), DW_LANG_C99, FALSE);
8911 build_info = mono_get_runtime_build_info ();
8912 s = g_strdup_printf ("Mono AOT Compiler %s (LLVM)", build_info);
8913 cu_args [n_cuargs ++] = LLVMMDString (s, strlen (s));
8914 g_free (build_info);
8916 cu_args [n_cuargs ++] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
8918 cu_args [n_cuargs ++] = LLVMMDString ("", strlen (""));
8919 /* Runtime version */
8920 cu_args [n_cuargs ++] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
8922 cu_args [n_cuargs ++] = LLVMMDNode (args, 0);
8923 cu_args [n_cuargs ++] = LLVMMDNode (args, 0);
8925 if (module->subprogram_mds) {
8929 mds = g_new0 (LLVMValueRef, module->subprogram_mds->len);
8930 for (i = 0; i < module->subprogram_mds->len; ++i)
8931 mds [i] = (LLVMValueRef)g_ptr_array_index (module->subprogram_mds, i);
8932 cu_args [n_cuargs ++] = LLVMMDNode (mds, module->subprogram_mds->len);
8934 cu_args [n_cuargs ++] = LLVMMDNode (args, 0);
8937 cu_args [n_cuargs ++] = LLVMMDNode (args, 0);
8938 /* Imported modules */
8939 cu_args [n_cuargs ++] = LLVMMDNode (args, 0);
8941 cu_args [n_cuargs ++] = LLVMMDString ("", strlen (""));
8942 /* DebugEmissionKind = FullDebug */
8943 cu_args [n_cuargs ++] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
8944 cu = LLVMMDNode (cu_args, n_cuargs);
8945 LLVMAddNamedMetadataOperand (lmodule, "llvm.dbg.cu", cu);
8948 #if LLVM_API_VERSION > 100
8949 args [0] = LLVMConstInt (LLVMInt32Type (), 2, FALSE);
8950 args [1] = LLVMMDString ("Dwarf Version", strlen ("Dwarf Version"));
8951 args [2] = LLVMConstInt (LLVMInt32Type (), 2, FALSE);
8952 ver = LLVMMDNode (args, 3);
8953 LLVMAddNamedMetadataOperand (lmodule, "llvm.module.flags", ver);
8955 args [0] = LLVMConstInt (LLVMInt32Type (), 2, FALSE);
8956 args [1] = LLVMMDString ("Debug Info Version", strlen ("Debug Info Version"));
8957 args [2] = LLVMConstInt (LLVMInt64Type (), 3, FALSE);
8958 ver = LLVMMDNode (args, 3);
8959 LLVMAddNamedMetadataOperand (lmodule, "llvm.module.flags", ver);
8961 args [0] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
8962 args [1] = LLVMMDString ("Dwarf Version", strlen ("Dwarf Version"));
8963 args [2] = LLVMConstInt (LLVMInt32Type (), 2, FALSE);
8964 ver = LLVMMDNode (args, 3);
8965 LLVMAddNamedMetadataOperand (lmodule, "llvm.module.flags", ver);
8967 args [0] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
8968 args [1] = LLVMMDString ("Debug Info Version", strlen ("Debug Info Version"));
8969 args [2] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
8970 ver = LLVMMDNode (args, 3);
8971 LLVMAddNamedMetadataOperand (lmodule, "llvm.module.flags", ver);
8976 emit_dbg_subprogram (EmitContext *ctx, MonoCompile *cfg, LLVMValueRef method, const char *name)
8978 MonoLLVMModule *module = ctx->module;
8979 MonoDebugMethodInfo *minfo = ctx->minfo;
8980 char *source_file, *dir, *filename;
8981 LLVMValueRef md, args [16], ctx_args [16], md_args [64], type_args [16], ctx_md, type_md;
8982 MonoSymSeqPoint *sym_seq_points;
8988 mono_debug_symfile_get_seq_points (minfo, &source_file, NULL, NULL, &sym_seq_points, &n_seq_points);
8990 source_file = g_strdup ("<unknown>");
8991 dir = g_path_get_dirname (source_file);
8992 filename = g_path_get_basename (source_file);
8994 #if LLVM_API_VERSION > 100
8995 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);
8998 ctx_args [0] = LLVMConstInt (LLVMInt32Type (), 0x29, FALSE);
8999 args [0] = md_string (filename);
9000 args [1] = md_string (dir);
9001 ctx_args [1] = LLVMMDNode (args, 2);
9002 ctx_md = LLVMMDNode (ctx_args, 2);
9004 type_args [0] = LLVMConstInt (LLVMInt32Type (), DW_TAG_subroutine_type, FALSE);
9005 type_args [1] = NULL;
9006 type_args [2] = NULL;
9007 type_args [3] = LLVMMDString ("", 0);
9008 type_args [4] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
9009 type_args [5] = LLVMConstInt (LLVMInt64Type (), 0, FALSE);
9010 type_args [6] = LLVMConstInt (LLVMInt64Type (), 0, FALSE);
9011 type_args [7] = LLVMConstInt (LLVMInt64Type (), 0, FALSE);
9012 type_args [8] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
9013 type_args [9] = NULL;
9014 type_args [10] = NULL;
9015 type_args [11] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
9016 type_args [12] = NULL;
9017 type_args [13] = NULL;
9018 type_args [14] = NULL;
9019 type_md = LLVMMDNode (type_args, 14);
9021 /* http://llvm.org/docs/SourceLevelDebugging.html#subprogram-descriptors */
9022 md_args [0] = LLVMConstInt (LLVMInt32Type (), DW_TAG_subprogram, FALSE);
9023 /* Source directory + file pair */
9024 args [0] = md_string (filename);
9025 args [1] = md_string (dir);
9026 md_args [1] = LLVMMDNode (args ,2);
9027 md_args [2] = ctx_md;
9028 md_args [3] = md_string (cfg->method->name);
9029 md_args [4] = md_string (name);
9030 md_args [5] = md_string (name);
9033 md_args [6] = LLVMConstInt (LLVMInt32Type (), sym_seq_points [0].line, FALSE);
9035 md_args [6] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
9037 md_args [7] = type_md;
9039 md_args [8] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
9041 md_args [9] = LLVMConstInt (LLVMInt1Type (), 1, FALSE);
9043 md_args [10] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
9044 /* Index into a virtual function */
9045 md_args [11] = NULL;
9046 md_args [12] = NULL;
9048 md_args [13] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
9050 md_args [14] = LLVMConstInt (LLVMInt1Type (), 1, FALSE);
9051 /* Pointer to LLVM function */
9052 md_args [15] = method;
9053 /* Function template parameter */
9054 md_args [16] = NULL;
9055 /* Function declaration descriptor */
9056 md_args [17] = NULL;
9057 /* List of function variables */
9058 md_args [18] = LLVMMDNode (args, 0);
9060 md_args [19] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
9061 md = LLVMMDNode (md_args, 20);
9063 if (!module->subprogram_mds)
9064 module->subprogram_mds = g_ptr_array_new ();
9065 g_ptr_array_add (module->subprogram_mds, md);
9069 g_free (source_file);
9070 g_free (sym_seq_points);
9076 emit_dbg_loc (EmitContext *ctx, LLVMBuilderRef builder, const unsigned char *cil_code)
9078 MonoCompile *cfg = ctx->cfg;
9080 if (ctx->minfo && cil_code && cil_code >= cfg->header->code && cil_code < cfg->header->code + cfg->header->code_size) {
9081 MonoDebugSourceLocation *loc;
9082 LLVMValueRef loc_md;
9084 loc = mono_debug_symfile_lookup_location (ctx->minfo, cil_code - cfg->header->code);
9087 #if LLVM_API_VERSION > 100
9088 loc_md = mono_llvm_di_create_location (ctx->module->di_builder, ctx->dbg_md, loc->row, loc->column);
9089 mono_llvm_di_set_location (builder, loc_md);
9091 LLVMValueRef md_args [16];
9095 md_args [nmd_args ++] = LLVMConstInt (LLVMInt32Type (), loc->row, FALSE);
9096 md_args [nmd_args ++] = LLVMConstInt (LLVMInt32Type (), loc->column, FALSE);
9097 md_args [nmd_args ++] = ctx->dbg_md;
9098 md_args [nmd_args ++] = NULL;
9099 loc_md = LLVMMDNode (md_args, nmd_args);
9100 LLVMSetCurrentDebugLocation (builder, loc_md);
9102 mono_debug_symfile_free_location (loc);
9108 default_mono_llvm_unhandled_exception (void)
9110 MonoJitTlsData *jit_tls = mono_get_jit_tls ();
9111 MonoObject *target = mono_gchandle_get_target (jit_tls->thrown_exc);
9113 mono_unhandled_exception (target);
9114 mono_invoke_unhandled_exception_hook (target);
9115 g_assert_not_reached ();
9120 - Emit LLVM IR from the mono IR using the LLVM C API.
9121 - The original arch specific code remains, so we can fall back to it if we run
9122 into something we can't handle.
9126 A partial list of issues:
9127 - Handling of opcodes which can throw exceptions.
9129 In the mono JIT, these are implemented using code like this:
9136 push throw_pos - method
9137 call <exception trampoline>
9139 The problematic part is push throw_pos - method, which cannot be represented
9140 in the LLVM IR, since it does not support label values.
9141 -> this can be implemented in AOT mode using inline asm + labels, but cannot
9142 be implemented in JIT mode ?
9143 -> a possible but slower implementation would use the normal exception
9144 throwing code but it would need to control the placement of the throw code
9145 (it needs to be exactly after the compare+branch).
9146 -> perhaps add a PC offset intrinsics ?
9148 - efficient implementation of .ovf opcodes.
9150 These are currently implemented as:
9151 <ins which sets the condition codes>
9154 Some overflow opcodes are now supported by LLVM SVN.
9156 - exception handling, unwinding.
9157 - SSA is disabled for methods with exception handlers
9158 - How to obtain unwind info for LLVM compiled methods ?
9159 -> this is now solved by converting the unwind info generated by LLVM
9161 - LLVM uses the c++ exception handling framework, while we use our home grown
9162 code, and couldn't use the c++ one:
9163 - its not supported under VC++, other exotic platforms.
9164 - it might be impossible to support filter clauses with it.
9168 The trampolines need a predictable call sequence, since they need to disasm
9169 the calling code to obtain register numbers / offsets.
9171 LLVM currently generates this code in non-JIT mode:
9172 mov -0x98(%rax),%eax
9174 Here, the vtable pointer is lost.
9175 -> solution: use one vtable trampoline per class.
9177 - passing/receiving the IMT pointer/RGCTX.
9178 -> solution: pass them as normal arguments ?
9182 LLVM does not allow the specification of argument registers etc. This means
9183 that all calls are made according to the platform ABI.
9185 - passing/receiving vtypes.
9187 Vtypes passed/received in registers are handled by the front end by using
9188 a signature with scalar arguments, and loading the parts of the vtype into those
9191 Vtypes passed on the stack are handled using the 'byval' attribute.
9195 Supported though alloca, we need to emit the load/store code.
9199 The mono JIT uses pointer sized iregs/double fregs, while LLVM uses precisely
9200 typed registers, so we have to keep track of the precise LLVM type of each vreg.
9201 This is made easier because the IR is already in SSA form.
9202 An additional problem is that our IR is not consistent with types, i.e. i32/ia64
9203 types are frequently used incorrectly.
9208 Emit LLVM bytecode into a .bc file, compile it using llc into a .s file, then link
9209 it with the file containing the methods emitted by the JIT and the AOT data
9213 /* FIXME: Normalize some aspects of the mono IR to allow easier translation, like:
9214 * - each bblock should end with a branch
9215 * - setting the return value, making cfg->ret non-volatile
9216 * - avoid some transformations in the JIT which make it harder for us to generate
9218 * - use pointer types to help optimizations.
9221 #else /* DISABLE_JIT */
9224 mono_llvm_cleanup (void)
9229 mono_llvm_free_domain_info (MonoDomain *domain)
9234 mono_llvm_init (void)
9239 default_mono_llvm_unhandled_exception (void)
9243 #endif /* DISABLE_JIT */