2 * mini-llvm.c: llvm "Backend" for the mono JIT
4 * Copyright 2009-2011 Novell Inc (http://www.novell.com)
5 * Copyright 2011 Xamarin Inc (http://www.xamarin.com)
6 * Licensed under the MIT license. See LICENSE file in the project root for full license information.
10 #include <mono/metadata/debug-helpers.h>
11 #include <mono/metadata/debug-mono-symfile.h>
12 #include <mono/metadata/mempool-internals.h>
13 #include <mono/metadata/environment.h>
14 #include <mono/metadata/object-internals.h>
15 #include <mono/metadata/abi-details.h>
16 #include <mono/utils/mono-tls.h>
17 #include <mono/utils/mono-dl.h>
18 #include <mono/utils/mono-time.h>
19 #include <mono/utils/freebsd-dwarf.h>
21 #ifndef __STDC_LIMIT_MACROS
22 #define __STDC_LIMIT_MACROS
24 #ifndef __STDC_CONSTANT_MACROS
25 #define __STDC_CONSTANT_MACROS
28 #include "llvm-c/BitWriter.h"
29 #include "llvm-c/Analysis.h"
31 #include "mini-llvm-cpp.h"
33 #include "aot-compiler.h"
34 #include "mini-llvm.h"
39 extern void *memset(void *, int, size_t);
40 void bzero (void *to, size_t count) { memset (to, 0, count); }
44 #if LLVM_API_VERSION < 4
45 #error "The version of the mono llvm repository is too old."
48 #define ALIGN_PTR_TO(ptr,align) (gpointer)((((gssize)(ptr)) + (align - 1)) & (~(align - 1)))
51 * Information associated by mono with LLVM modules.
54 LLVMModuleRef lmodule;
55 LLVMValueRef throw_icall, rethrow, match_exc, throw_corlib_exception, resume_eh;
56 GHashTable *llvm_types;
58 const char *got_symbol;
59 const char *get_method_symbol;
60 const char *get_unbox_tramp_symbol;
61 GHashTable *plt_entries;
62 GHashTable *plt_entries_ji;
63 GHashTable *method_to_lmethod;
64 GHashTable *direct_callables;
69 GPtrArray *subprogram_mds;
71 LLVMExecutionEngineRef ee;
72 gboolean external_symbols;
75 LLVMValueRef personality;
78 MonoAssembly *assembly;
80 MonoAotFileInfo aot_info;
81 const char *jit_got_symbol;
82 const char *eh_frame_symbol;
83 LLVMValueRef get_method, get_unbox_tramp;
84 LLVMValueRef init_method, init_method_gshared_mrgctx, init_method_gshared_this, init_method_gshared_vtable;
85 LLVMValueRef code_start, code_end;
86 LLVMValueRef inited_var;
87 int max_inited_idx, max_method_idx;
88 gboolean has_jitted_code;
91 GHashTable *idx_to_lmethod;
92 GHashTable *idx_to_unbox_tramp;
93 /* Maps a MonoMethod to LLVM instructions representing it */
94 GHashTable *method_to_callers;
95 LLVMContextRef context;
96 LLVMValueRef sentinel_exception;
97 void *di_builder, *cu;
98 GHashTable *objc_selector_to_var;
102 * Information associated by the backend with mono basic blocks.
105 LLVMBasicBlockRef bblock, end_bblock;
106 LLVMValueRef finally_ind;
107 gboolean added, invoke_target;
109 * If this bblock is the start of a finally clause, this is a list of bblocks it
110 * needs to branch to in ENDFINALLY.
112 GSList *call_handler_return_bbs;
114 * If this bblock is the start of a finally clause, this is the bblock that
115 * CALL_HANDLER needs to branch to.
117 LLVMBasicBlockRef call_handler_target_bb;
118 /* The list of switch statements generated by ENDFINALLY instructions */
119 GSList *endfinally_switch_ins_list;
124 * Structure containing emit state
127 MonoMemPool *mempool;
129 /* Maps method names to the corresponding LLVMValueRef */
130 GHashTable *emitted_method_decls;
133 LLVMValueRef lmethod;
134 MonoLLVMModule *module;
135 LLVMModuleRef lmodule;
137 int sindex, default_index, ex_index;
138 LLVMBuilderRef builder;
139 LLVMValueRef *values, *addresses;
140 MonoType **vreg_cli_types;
142 MonoMethodSignature *sig;
144 GHashTable *region_to_handler;
145 GHashTable *clause_to_handler;
146 LLVMBuilderRef alloca_builder;
147 LLVMValueRef last_alloca;
148 LLVMValueRef rgctx_arg;
149 LLVMValueRef this_arg;
150 LLVMTypeRef *vreg_types;
152 LLVMTypeRef method_type;
153 LLVMBasicBlockRef init_bb, inited_bb;
155 gboolean *unreachable;
157 gboolean has_got_access;
158 gboolean is_linkonce;
159 int this_arg_pindex, rgctx_arg_pindex;
160 LLVMValueRef imt_rgctx_loc;
161 GHashTable *llvm_types;
163 MonoDebugMethodInfo *minfo;
165 /* For every clause, the clauses it is nested in */
168 GHashTable *exc_meta;
169 GHashTable *method_to_callers;
170 GPtrArray *phi_values;
171 GPtrArray *bblock_list;
173 GHashTable *jit_callees;
174 LLVMValueRef long_bb_break_var;
180 MonoBasicBlock *in_bb;
185 * Instruction metadata
186 * This is the same as ins_info, but LREG != IREG.
194 #define MINI_OP(a,b,dest,src1,src2) dest, src1, src2, ' ',
195 #define MINI_OP3(a,b,dest,src1,src2,src3) dest, src1, src2, src3,
202 /* keep in sync with the enum in mini.h */
205 #include "mini-ops.h"
210 #if SIZEOF_VOID_P == 4
211 #define GET_LONG_IMM(ins) (((guint64)(ins)->inst_ms_word << 32) | (guint64)(guint32)(ins)->inst_ls_word)
213 #define GET_LONG_IMM(ins) ((ins)->inst_imm)
216 #define LLVM_INS_INFO(opcode) (&llvm_ins_info [((opcode) - OP_START - 1) * 4])
219 #define TRACE_FAILURE(msg) do { printf ("%s\n", msg); } while (0)
221 #define TRACE_FAILURE(msg)
225 #define IS_TARGET_X86 1
227 #define IS_TARGET_X86 0
231 #define IS_TARGET_AMD64 1
233 #define IS_TARGET_AMD64 0
236 #define ctx_ok(ctx) (!(ctx)->cfg->disable_llvm)
238 static LLVMIntPredicate cond_to_llvm_cond [] = {
251 static LLVMRealPredicate fpcond_to_llvm_cond [] = {
264 static MonoNativeTlsKey current_cfg_tls_id;
266 static MonoLLVMModule aot_module;
268 static GHashTable *intrins_id_to_name;
269 static GHashTable *intrins_name_to_id;
271 static void init_jit_module (MonoDomain *domain);
273 static void emit_dbg_loc (EmitContext *ctx, LLVMBuilderRef builder, const unsigned char *cil_code);
274 static LLVMValueRef emit_dbg_subprogram (EmitContext *ctx, MonoCompile *cfg, LLVMValueRef method, const char *name);
275 static void emit_dbg_info (MonoLLVMModule *module, const char *filename, const char *cu_name);
276 static void emit_cond_system_exception (EmitContext *ctx, MonoBasicBlock *bb, const char *exc_type, LLVMValueRef cmp);
277 static LLVMValueRef get_intrinsic (EmitContext *ctx, const char *name);
278 static void decode_llvm_eh_info (EmitContext *ctx, gpointer eh_frame);
281 set_failure (EmitContext *ctx, const char *message)
283 TRACE_FAILURE (reason);
284 ctx->cfg->exception_message = g_strdup (message);
285 ctx->cfg->disable_llvm = TRUE;
291 * The LLVM type with width == sizeof (gpointer)
296 return sizeof (gpointer) == 8 ? LLVMInt64Type () : LLVMInt32Type ();
302 return sizeof (gpointer) == 8 ? LLVMPointerType (LLVMInt64Type (), 0) : LLVMPointerType (LLVMInt32Type (), 0);
308 return sizeof (gpointer) == 8 ? LLVMPointerType (LLVMInt64Type (), 0) : LLVMPointerType (LLVMInt32Type (), 0);
314 * Return the size of the LLVM representation of the vtype T.
317 get_vtype_size (MonoType *t)
321 size = mono_class_value_size (mono_class_from_mono_type (t), NULL);
323 /* LLVMArgAsIArgs depends on this since it stores whole words */
324 while (size < 2 * sizeof (gpointer) && mono_is_power_of_two (size) == -1)
331 * simd_class_to_llvm_type:
333 * Return the LLVM type corresponding to the Mono.SIMD class KLASS
336 simd_class_to_llvm_type (EmitContext *ctx, MonoClass *klass)
338 if (!strcmp (klass->name, "Vector2d")) {
339 return LLVMVectorType (LLVMDoubleType (), 2);
340 } else if (!strcmp (klass->name, "Vector2l")) {
341 return LLVMVectorType (LLVMInt64Type (), 2);
342 } else if (!strcmp (klass->name, "Vector2ul")) {
343 return LLVMVectorType (LLVMInt64Type (), 2);
344 } else if (!strcmp (klass->name, "Vector4i")) {
345 return LLVMVectorType (LLVMInt32Type (), 4);
346 } else if (!strcmp (klass->name, "Vector4ui")) {
347 return LLVMVectorType (LLVMInt32Type (), 4);
348 } else if (!strcmp (klass->name, "Vector4f")) {
349 return LLVMVectorType (LLVMFloatType (), 4);
350 } else if (!strcmp (klass->name, "Vector8s")) {
351 return LLVMVectorType (LLVMInt16Type (), 8);
352 } else if (!strcmp (klass->name, "Vector8us")) {
353 return LLVMVectorType (LLVMInt16Type (), 8);
354 } else if (!strcmp (klass->name, "Vector16sb")) {
355 return LLVMVectorType (LLVMInt8Type (), 16);
356 } else if (!strcmp (klass->name, "Vector16b")) {
357 return LLVMVectorType (LLVMInt8Type (), 16);
359 printf ("%s\n", klass->name);
365 /* Return the 128 bit SIMD type corresponding to the mono type TYPE */
366 static inline G_GNUC_UNUSED LLVMTypeRef
367 type_to_simd_type (int type)
371 return LLVMVectorType (LLVMInt8Type (), 16);
373 return LLVMVectorType (LLVMInt16Type (), 8);
375 return LLVMVectorType (LLVMInt32Type (), 4);
377 return LLVMVectorType (LLVMInt64Type (), 2);
379 return LLVMVectorType (LLVMDoubleType (), 2);
381 return LLVMVectorType (LLVMFloatType (), 4);
383 g_assert_not_reached ();
389 create_llvm_type_for_type (MonoLLVMModule *module, MonoClass *klass)
391 int i, size, nfields, esize;
392 LLVMTypeRef *eltypes;
397 t = &klass->byval_arg;
399 if (mini_type_is_hfa (t, &nfields, &esize)) {
401 * This is needed on arm64 where HFAs are returned in
405 eltypes = g_new (LLVMTypeRef, size);
406 for (i = 0; i < size; ++i)
407 eltypes [i] = esize == 4 ? LLVMFloatType () : LLVMDoubleType ();
409 size = get_vtype_size (t);
411 eltypes = g_new (LLVMTypeRef, size);
412 for (i = 0; i < size; ++i)
413 eltypes [i] = LLVMInt8Type ();
416 name = mono_type_full_name (&klass->byval_arg);
417 ltype = LLVMStructCreateNamed (module->context, name);
418 LLVMStructSetBody (ltype, eltypes, size, FALSE);
428 * Return the LLVM type corresponding to T.
431 type_to_llvm_type (EmitContext *ctx, MonoType *t)
433 t = mini_get_underlying_type (t);
437 return LLVMVoidType ();
439 return LLVMInt8Type ();
441 return LLVMInt16Type ();
443 return LLVMInt32Type ();
445 return LLVMInt8Type ();
447 return LLVMInt16Type ();
449 return LLVMInt32Type ();
450 case MONO_TYPE_BOOLEAN:
451 return LLVMInt8Type ();
454 return LLVMInt64Type ();
456 return LLVMInt16Type ();
458 return LLVMFloatType ();
460 return LLVMDoubleType ();
463 return IntPtrType ();
464 case MONO_TYPE_OBJECT:
465 case MONO_TYPE_CLASS:
466 case MONO_TYPE_ARRAY:
467 case MONO_TYPE_SZARRAY:
468 case MONO_TYPE_STRING:
470 return ObjRefType ();
473 /* Because of generic sharing */
474 return ObjRefType ();
475 case MONO_TYPE_GENERICINST:
476 if (!mono_type_generic_inst_is_valuetype (t))
477 return ObjRefType ();
479 case MONO_TYPE_VALUETYPE:
480 case MONO_TYPE_TYPEDBYREF: {
484 klass = mono_class_from_mono_type (t);
486 if (MONO_CLASS_IS_SIMD (ctx->cfg, klass))
487 return simd_class_to_llvm_type (ctx, klass);
490 return type_to_llvm_type (ctx, mono_class_enum_basetype (klass));
492 ltype = (LLVMTypeRef)g_hash_table_lookup (ctx->module->llvm_types, klass);
494 ltype = create_llvm_type_for_type (ctx->module, klass);
495 g_hash_table_insert (ctx->module->llvm_types, klass, ltype);
501 printf ("X: %d\n", t->type);
502 ctx->cfg->exception_message = g_strdup_printf ("type %s", mono_type_full_name (t));
503 ctx->cfg->disable_llvm = TRUE;
511 * Return whenever T is an unsigned int type.
514 type_is_unsigned (EmitContext *ctx, MonoType *t)
516 t = mini_get_underlying_type (t);
532 * type_to_llvm_arg_type:
534 * Same as type_to_llvm_type, but treat i8/i16 as i32.
537 type_to_llvm_arg_type (EmitContext *ctx, MonoType *t)
539 LLVMTypeRef ptype = type_to_llvm_type (ctx, t);
541 if (ctx->cfg->llvm_only)
545 * This works on all abis except arm64/ios which passes multiple
546 * arguments in one stack slot.
549 if (ptype == LLVMInt8Type () || ptype == LLVMInt16Type ()) {
551 * LLVM generates code which only sets the lower bits, while JITted
552 * code expects all the bits to be set.
554 ptype = LLVMInt32Type ();
562 * llvm_type_to_stack_type:
564 * Return the LLVM type which needs to be used when a value of type TYPE is pushed
567 static G_GNUC_UNUSED LLVMTypeRef
568 llvm_type_to_stack_type (MonoCompile *cfg, LLVMTypeRef type)
572 if (type == LLVMInt8Type ())
573 return LLVMInt32Type ();
574 else if (type == LLVMInt16Type ())
575 return LLVMInt32Type ();
576 else if (!cfg->r4fp && type == LLVMFloatType ())
577 return LLVMDoubleType ();
583 * regtype_to_llvm_type:
585 * Return the LLVM type corresponding to the regtype C used in instruction
589 regtype_to_llvm_type (char c)
593 return LLVMInt32Type ();
595 return LLVMInt64Type ();
597 return LLVMDoubleType ();
606 * Return the LLVM type corresponding to the unary/binary opcode OPCODE.
609 op_to_llvm_type (int opcode)
614 return LLVMInt8Type ();
617 return LLVMInt8Type ();
620 return LLVMInt16Type ();
623 return LLVMInt16Type ();
626 return LLVMInt32Type ();
629 return LLVMInt32Type ();
631 return LLVMInt64Type ();
633 return LLVMFloatType ();
635 return LLVMDoubleType ();
637 return LLVMInt64Type ();
639 return LLVMInt32Type ();
641 return LLVMInt64Type ();
646 return LLVMInt8Type ();
651 return LLVMInt16Type ();
653 return LLVMInt32Type ();
656 return sizeof (gpointer) == 8 ? LLVMInt64Type () : LLVMInt32Type ();
663 return LLVMInt32Type ();
670 return LLVMInt64Type ();
672 printf ("%s\n", mono_inst_name (opcode));
673 g_assert_not_reached ();
678 #define CLAUSE_START(clause) ((clause)->try_offset)
679 #define CLAUSE_END(clause) (((clause))->try_offset + ((clause))->try_len)
682 * load_store_to_llvm_type:
684 * Return the size/sign/zero extension corresponding to the load/store opcode
688 load_store_to_llvm_type (int opcode, int *size, gboolean *sext, gboolean *zext)
694 case OP_LOADI1_MEMBASE:
695 case OP_STOREI1_MEMBASE_REG:
696 case OP_STOREI1_MEMBASE_IMM:
697 case OP_ATOMIC_LOAD_I1:
698 case OP_ATOMIC_STORE_I1:
701 return LLVMInt8Type ();
702 case OP_LOADU1_MEMBASE:
704 case OP_ATOMIC_LOAD_U1:
705 case OP_ATOMIC_STORE_U1:
708 return LLVMInt8Type ();
709 case OP_LOADI2_MEMBASE:
710 case OP_STOREI2_MEMBASE_REG:
711 case OP_STOREI2_MEMBASE_IMM:
712 case OP_ATOMIC_LOAD_I2:
713 case OP_ATOMIC_STORE_I2:
716 return LLVMInt16Type ();
717 case OP_LOADU2_MEMBASE:
719 case OP_ATOMIC_LOAD_U2:
720 case OP_ATOMIC_STORE_U2:
723 return LLVMInt16Type ();
724 case OP_LOADI4_MEMBASE:
725 case OP_LOADU4_MEMBASE:
728 case OP_STOREI4_MEMBASE_REG:
729 case OP_STOREI4_MEMBASE_IMM:
730 case OP_ATOMIC_LOAD_I4:
731 case OP_ATOMIC_STORE_I4:
732 case OP_ATOMIC_LOAD_U4:
733 case OP_ATOMIC_STORE_U4:
735 return LLVMInt32Type ();
736 case OP_LOADI8_MEMBASE:
738 case OP_STOREI8_MEMBASE_REG:
739 case OP_STOREI8_MEMBASE_IMM:
740 case OP_ATOMIC_LOAD_I8:
741 case OP_ATOMIC_STORE_I8:
742 case OP_ATOMIC_LOAD_U8:
743 case OP_ATOMIC_STORE_U8:
745 return LLVMInt64Type ();
746 case OP_LOADR4_MEMBASE:
747 case OP_STORER4_MEMBASE_REG:
748 case OP_ATOMIC_LOAD_R4:
749 case OP_ATOMIC_STORE_R4:
751 return LLVMFloatType ();
752 case OP_LOADR8_MEMBASE:
753 case OP_STORER8_MEMBASE_REG:
754 case OP_ATOMIC_LOAD_R8:
755 case OP_ATOMIC_STORE_R8:
757 return LLVMDoubleType ();
758 case OP_LOAD_MEMBASE:
760 case OP_STORE_MEMBASE_REG:
761 case OP_STORE_MEMBASE_IMM:
762 *size = sizeof (gpointer);
763 return IntPtrType ();
765 g_assert_not_reached ();
773 * Return the LLVM intrinsics corresponding to the overflow opcode OPCODE.
776 ovf_op_to_intrins (int opcode)
780 return "llvm.sadd.with.overflow.i32";
782 return "llvm.uadd.with.overflow.i32";
784 return "llvm.ssub.with.overflow.i32";
786 return "llvm.usub.with.overflow.i32";
788 return "llvm.smul.with.overflow.i32";
790 return "llvm.umul.with.overflow.i32";
792 return "llvm.sadd.with.overflow.i64";
794 return "llvm.uadd.with.overflow.i64";
796 return "llvm.ssub.with.overflow.i64";
798 return "llvm.usub.with.overflow.i64";
800 return "llvm.smul.with.overflow.i64";
802 return "llvm.umul.with.overflow.i64";
804 g_assert_not_reached ();
810 simd_op_to_intrins (int opcode)
813 #if defined(TARGET_X86) || defined(TARGET_AMD64)
815 return "llvm.x86.sse2.min.pd";
817 return "llvm.x86.sse.min.ps";
819 return "llvm.x86.sse2.max.pd";
821 return "llvm.x86.sse.max.ps";
823 return "llvm.x86.sse3.hadd.pd";
825 return "llvm.x86.sse3.hadd.ps";
827 return "llvm.x86.sse3.hsub.pd";
829 return "llvm.x86.sse3.hsub.ps";
831 return "llvm.x86.sse3.addsub.ps";
833 return "llvm.x86.sse3.addsub.pd";
834 case OP_EXTRACT_MASK:
835 return "llvm.x86.sse2.pmovmskb.128";
838 return "llvm.x86.sse2.psrli.w";
841 return "llvm.x86.sse2.psrli.d";
844 return "llvm.x86.sse2.psrli.q";
847 return "llvm.x86.sse2.pslli.w";
850 return "llvm.x86.sse2.pslli.d";
853 return "llvm.x86.sse2.pslli.q";
856 return "llvm.x86.sse2.psrai.w";
859 return "llvm.x86.sse2.psrai.d";
861 return "llvm.x86.sse2.padds.b";
863 return "llvm.x86.sse2.padds.w";
865 return "llvm.x86.sse2.psubs.b";
867 return "llvm.x86.sse2.psubs.w";
868 case OP_PADDB_SAT_UN:
869 return "llvm.x86.sse2.paddus.b";
870 case OP_PADDW_SAT_UN:
871 return "llvm.x86.sse2.paddus.w";
872 case OP_PSUBB_SAT_UN:
873 return "llvm.x86.sse2.psubus.b";
874 case OP_PSUBW_SAT_UN:
875 return "llvm.x86.sse2.psubus.w";
877 return "llvm.x86.sse2.pavg.b";
879 return "llvm.x86.sse2.pavg.w";
881 return "llvm.x86.sse.sqrt.ps";
883 return "llvm.x86.sse2.sqrt.pd";
885 return "llvm.x86.sse.rsqrt.ps";
887 return "llvm.x86.sse.rcp.ps";
889 return "llvm.x86.sse2.cvtdq2pd";
891 return "llvm.x86.sse2.cvtdq2ps";
893 return "llvm.x86.sse2.cvtpd2dq";
895 return "llvm.x86.sse2.cvtps2dq";
897 return "llvm.x86.sse2.cvtpd2ps";
899 return "llvm.x86.sse2.cvtps2pd";
901 return "llvm.x86.sse2.cvttpd2dq";
903 return "llvm.x86.sse2.cvttps2dq";
905 return "llvm.x86.sse2.packsswb.128";
907 return "llvm.x86.sse2.packssdw.128";
909 return "llvm.x86.sse2.packuswb.128";
911 return "llvm.x86.sse41.packusdw";
913 return "llvm.x86.sse2.pmulh.w";
914 case OP_PMULW_HIGH_UN:
915 return "llvm.x86.sse2.pmulhu.w";
918 g_assert_not_reached ();
924 simd_op_to_llvm_type (int opcode)
926 #if defined(TARGET_X86) || defined(TARGET_AMD64)
930 return type_to_simd_type (MONO_TYPE_R8);
933 return type_to_simd_type (MONO_TYPE_I8);
936 return type_to_simd_type (MONO_TYPE_I4);
941 return type_to_simd_type (MONO_TYPE_I2);
945 return type_to_simd_type (MONO_TYPE_I1);
947 return type_to_simd_type (MONO_TYPE_R4);
950 return type_to_simd_type (MONO_TYPE_I4);
954 return type_to_simd_type (MONO_TYPE_R8);
958 return type_to_simd_type (MONO_TYPE_R4);
959 case OP_EXTRACT_MASK:
960 return type_to_simd_type (MONO_TYPE_I1);
966 return type_to_simd_type (MONO_TYPE_R4);
969 return type_to_simd_type (MONO_TYPE_R8);
971 g_assert_not_reached ();
982 * Return the LLVM basic block corresponding to BB.
984 static LLVMBasicBlockRef
985 get_bb (EmitContext *ctx, MonoBasicBlock *bb)
987 char bb_name_buf [128];
990 if (ctx->bblocks [bb->block_num].bblock == NULL) {
991 if (bb->flags & BB_EXCEPTION_HANDLER) {
992 int clause_index = (mono_get_block_region_notry (ctx->cfg, bb->region) >> 8) - 1;
993 sprintf (bb_name_buf, "EH_CLAUSE%d_BB%d", clause_index, bb->block_num);
994 bb_name = bb_name_buf;
995 } else if (bb->block_num < 256) {
996 if (!ctx->module->bb_names) {
997 ctx->module->bb_names_len = 256;
998 ctx->module->bb_names = g_new0 (char*, ctx->module->bb_names_len);
1000 if (!ctx->module->bb_names [bb->block_num]) {
1003 n = g_strdup_printf ("BB%d", bb->block_num);
1004 mono_memory_barrier ();
1005 ctx->module->bb_names [bb->block_num] = n;
1007 bb_name = ctx->module->bb_names [bb->block_num];
1009 sprintf (bb_name_buf, "BB%d", bb->block_num);
1010 bb_name = bb_name_buf;
1013 ctx->bblocks [bb->block_num].bblock = LLVMAppendBasicBlock (ctx->lmethod, bb_name);
1014 ctx->bblocks [bb->block_num].end_bblock = ctx->bblocks [bb->block_num].bblock;
1017 return ctx->bblocks [bb->block_num].bblock;
1023 * Return the last LLVM bblock corresponding to BB.
1024 * This might not be equal to the bb returned by get_bb () since we need to generate
1025 * multiple LLVM bblocks for a mono bblock to handle throwing exceptions.
1027 static LLVMBasicBlockRef
1028 get_end_bb (EmitContext *ctx, MonoBasicBlock *bb)
1031 return ctx->bblocks [bb->block_num].end_bblock;
1034 static LLVMBasicBlockRef
1035 gen_bb (EmitContext *ctx, const char *prefix)
1039 sprintf (bb_name, "%s%d", prefix, ++ ctx->ex_index);
1040 return LLVMAppendBasicBlock (ctx->lmethod, bb_name);
1046 * Return the target of the patch identified by TYPE and TARGET.
1049 resolve_patch (MonoCompile *cfg, MonoJumpInfoType type, gconstpointer target)
1055 memset (&ji, 0, sizeof (ji));
1057 ji.data.target = target;
1059 res = mono_resolve_patch_target (cfg->method, cfg->domain, NULL, &ji, FALSE, &error);
1060 mono_error_assert_ok (&error);
1068 * Emit code to convert the LLVM value V to DTYPE.
1071 convert_full (EmitContext *ctx, LLVMValueRef v, LLVMTypeRef dtype, gboolean is_unsigned)
1073 LLVMTypeRef stype = LLVMTypeOf (v);
1075 if (stype != dtype) {
1076 gboolean ext = FALSE;
1079 if (dtype == LLVMInt64Type () && (stype == LLVMInt32Type () || stype == LLVMInt16Type () || stype == LLVMInt8Type ()))
1081 else if (dtype == LLVMInt32Type () && (stype == LLVMInt16Type () || stype == LLVMInt8Type ()))
1083 else if (dtype == LLVMInt16Type () && (stype == LLVMInt8Type ()))
1087 return is_unsigned ? LLVMBuildZExt (ctx->builder, v, dtype, "") : LLVMBuildSExt (ctx->builder, v, dtype, "");
1089 if (dtype == LLVMDoubleType () && stype == LLVMFloatType ())
1090 return LLVMBuildFPExt (ctx->builder, v, dtype, "");
1093 if (stype == LLVMInt64Type () && (dtype == LLVMInt32Type () || dtype == LLVMInt16Type () || dtype == LLVMInt8Type ()))
1094 return LLVMBuildTrunc (ctx->builder, v, dtype, "");
1095 if (stype == LLVMInt32Type () && (dtype == LLVMInt16Type () || dtype == LLVMInt8Type ()))
1096 return LLVMBuildTrunc (ctx->builder, v, dtype, "");
1097 if (stype == LLVMInt16Type () && dtype == LLVMInt8Type ())
1098 return LLVMBuildTrunc (ctx->builder, v, dtype, "");
1099 if (stype == LLVMDoubleType () && dtype == LLVMFloatType ())
1100 return LLVMBuildFPTrunc (ctx->builder, v, dtype, "");
1102 if (LLVMGetTypeKind (stype) == LLVMPointerTypeKind && LLVMGetTypeKind (dtype) == LLVMPointerTypeKind)
1103 return LLVMBuildBitCast (ctx->builder, v, dtype, "");
1104 if (LLVMGetTypeKind (dtype) == LLVMPointerTypeKind)
1105 return LLVMBuildIntToPtr (ctx->builder, v, dtype, "");
1106 if (LLVMGetTypeKind (stype) == LLVMPointerTypeKind)
1107 return LLVMBuildPtrToInt (ctx->builder, v, dtype, "");
1109 if (mono_arch_is_soft_float ()) {
1110 if (stype == LLVMInt32Type () && dtype == LLVMFloatType ())
1111 return LLVMBuildBitCast (ctx->builder, v, dtype, "");
1112 if (stype == LLVMInt32Type () && dtype == LLVMDoubleType ())
1113 return LLVMBuildBitCast (ctx->builder, LLVMBuildZExt (ctx->builder, v, LLVMInt64Type (), ""), dtype, "");
1116 if (LLVMGetTypeKind (stype) == LLVMVectorTypeKind && LLVMGetTypeKind (dtype) == LLVMVectorTypeKind)
1117 return LLVMBuildBitCast (ctx->builder, v, dtype, "");
1120 LLVMDumpValue (LLVMConstNull (dtype));
1121 g_assert_not_reached ();
1129 convert (EmitContext *ctx, LLVMValueRef v, LLVMTypeRef dtype)
1131 return convert_full (ctx, v, dtype, FALSE);
1135 * emit_volatile_load:
1137 * If vreg is volatile, emit a load from its address.
1140 emit_volatile_load (EmitContext *ctx, int vreg)
1146 // FIXME: This hack is required because we pass the rgctx in a callee saved
1147 // register on arm64 (x15), and llvm might keep the value in that register
1148 // even through the register is marked as 'reserved' inside llvm.
1149 if (ctx->cfg->rgctx_var && ctx->cfg->rgctx_var->dreg == vreg)
1150 v = mono_llvm_build_load (ctx->builder, ctx->addresses [vreg], "", TRUE);
1152 v = LLVMBuildLoad (ctx->builder, ctx->addresses [vreg], "");
1154 v = LLVMBuildLoad (ctx->builder, ctx->addresses [vreg], "");
1156 t = ctx->vreg_cli_types [vreg];
1157 if (t && !t->byref) {
1159 * Might have to zero extend since llvm doesn't have
1162 if (t->type == MONO_TYPE_U1 || t->type == MONO_TYPE_U2 || t->type == MONO_TYPE_CHAR || t->type == MONO_TYPE_BOOLEAN)
1163 v = LLVMBuildZExt (ctx->builder, v, LLVMInt32Type (), "");
1164 else if (t->type == MONO_TYPE_I1 || t->type == MONO_TYPE_I2)
1165 v = LLVMBuildSExt (ctx->builder, v, LLVMInt32Type (), "");
1166 else if (t->type == MONO_TYPE_U8)
1167 v = LLVMBuildZExt (ctx->builder, v, LLVMInt64Type (), "");
1174 * emit_volatile_store:
1176 * If VREG is volatile, emit a store from its value to its address.
1179 emit_volatile_store (EmitContext *ctx, int vreg)
1181 MonoInst *var = get_vreg_to_inst (ctx->cfg, vreg);
1183 if (var && var->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT)) {
1184 g_assert (ctx->addresses [vreg]);
1185 LLVMBuildStore (ctx->builder, convert (ctx, ctx->values [vreg], type_to_llvm_type (ctx, var->inst_vtype)), ctx->addresses [vreg]);
1190 sig_to_llvm_sig_no_cinfo (EmitContext *ctx, MonoMethodSignature *sig)
1192 LLVMTypeRef ret_type;
1193 LLVMTypeRef *param_types = NULL;
1198 rtype = mini_get_underlying_type (sig->ret);
1199 ret_type = type_to_llvm_type (ctx, rtype);
1203 param_types = g_new0 (LLVMTypeRef, (sig->param_count * 8) + 3);
1207 param_types [pindex ++] = ThisType ();
1208 for (i = 0; i < sig->param_count; ++i)
1209 param_types [pindex ++] = type_to_llvm_arg_type (ctx, sig->params [i]);
1211 if (!ctx_ok (ctx)) {
1212 g_free (param_types);
1216 res = LLVMFunctionType (ret_type, param_types, pindex, FALSE);
1217 g_free (param_types);
1223 * sig_to_llvm_sig_full:
1225 * Return the LLVM signature corresponding to the mono signature SIG using the
1226 * calling convention information in CINFO. Fill out the parameter mapping information in CINFO.
1229 sig_to_llvm_sig_full (EmitContext *ctx, MonoMethodSignature *sig, LLVMCallInfo *cinfo)
1231 LLVMTypeRef ret_type;
1232 LLVMTypeRef *param_types = NULL;
1234 int i, j, pindex, vret_arg_pindex = 0;
1235 gboolean vretaddr = FALSE;
1239 return sig_to_llvm_sig_no_cinfo (ctx, sig);
1241 rtype = mini_get_underlying_type (sig->ret);
1242 ret_type = type_to_llvm_type (ctx, rtype);
1246 switch (cinfo->ret.storage) {
1247 case LLVMArgVtypeInReg:
1248 /* LLVM models this by returning an aggregate value */
1249 if (cinfo->ret.pair_storage [0] == LLVMArgInIReg && cinfo->ret.pair_storage [1] == LLVMArgNone) {
1250 LLVMTypeRef members [2];
1252 members [0] = IntPtrType ();
1253 ret_type = LLVMStructType (members, 1, FALSE);
1254 } else if (cinfo->ret.pair_storage [0] == LLVMArgNone && cinfo->ret.pair_storage [1] == LLVMArgNone) {
1256 ret_type = LLVMVoidType ();
1257 } else if (cinfo->ret.pair_storage [0] == LLVMArgInIReg && cinfo->ret.pair_storage [1] == LLVMArgInIReg) {
1258 LLVMTypeRef members [2];
1260 members [0] = IntPtrType ();
1261 members [1] = IntPtrType ();
1262 ret_type = LLVMStructType (members, 2, FALSE);
1264 g_assert_not_reached ();
1267 case LLVMArgVtypeByVal:
1268 /* Vtype returned normally by val */
1270 case LLVMArgVtypeAsScalar: {
1271 int size = mono_class_value_size (mono_class_from_mono_type (rtype), NULL);
1272 /* LLVM models this by returning an int */
1273 if (size < SIZEOF_VOID_P) {
1274 g_assert (cinfo->ret.nslots == 1);
1275 ret_type = LLVMIntType (size * 8);
1277 g_assert (cinfo->ret.nslots == 1 || cinfo->ret.nslots == 2);
1278 ret_type = LLVMIntType (cinfo->ret.nslots * sizeof (mgreg_t) * 8);
1282 case LLVMArgAsIArgs:
1283 ret_type = LLVMArrayType (IntPtrType (), cinfo->ret.nslots);
1285 case LLVMArgFpStruct: {
1286 /* Vtype returned as a fp struct */
1287 LLVMTypeRef members [16];
1289 /* Have to create our own structure since we don't map fp structures to LLVM fp structures yet */
1290 for (i = 0; i < cinfo->ret.nslots; ++i)
1291 members [i] = cinfo->ret.esize == 8 ? LLVMDoubleType () : LLVMFloatType ();
1292 ret_type = LLVMStructType (members, cinfo->ret.nslots, FALSE);
1295 case LLVMArgVtypeByRef:
1296 /* Vtype returned using a hidden argument */
1297 ret_type = LLVMVoidType ();
1299 case LLVMArgVtypeRetAddr:
1300 case LLVMArgGsharedvtFixed:
1301 case LLVMArgGsharedvtFixedVtype:
1302 case LLVMArgGsharedvtVariable:
1304 ret_type = LLVMVoidType ();
1310 param_types = g_new0 (LLVMTypeRef, (sig->param_count * 8) + 3);
1312 if (cinfo->ret.storage == LLVMArgVtypeByRef) {
1314 * Has to be the first argument because of the sret argument attribute
1315 * FIXME: This might conflict with passing 'this' as the first argument, but
1316 * this is only used on arm64 which has a dedicated struct return register.
1318 cinfo->vret_arg_pindex = pindex;
1319 param_types [pindex] = type_to_llvm_arg_type (ctx, sig->ret);
1320 if (!ctx_ok (ctx)) {
1321 g_free (param_types);
1324 param_types [pindex] = LLVMPointerType (param_types [pindex], 0);
1327 if (!ctx->llvm_only && cinfo->rgctx_arg) {
1328 cinfo->rgctx_arg_pindex = pindex;
1329 param_types [pindex] = ctx->module->ptr_type;
1332 if (cinfo->imt_arg) {
1333 cinfo->imt_arg_pindex = pindex;
1334 param_types [pindex] = ctx->module->ptr_type;
1338 /* Compute the index in the LLVM signature where the vret arg needs to be passed */
1339 vret_arg_pindex = pindex;
1340 if (cinfo->vret_arg_index == 1) {
1341 /* Add the slots consumed by the first argument */
1342 LLVMArgInfo *ainfo = &cinfo->args [0];
1343 switch (ainfo->storage) {
1344 case LLVMArgVtypeInReg:
1345 for (j = 0; j < 2; ++j) {
1346 if (ainfo->pair_storage [j] == LLVMArgInIReg)
1355 cinfo->vret_arg_pindex = vret_arg_pindex;
1358 if (vretaddr && vret_arg_pindex == pindex)
1359 param_types [pindex ++] = IntPtrType ();
1361 cinfo->this_arg_pindex = pindex;
1362 param_types [pindex ++] = ThisType ();
1363 cinfo->args [0].pindex = cinfo->this_arg_pindex;
1365 if (vretaddr && vret_arg_pindex == pindex)
1366 param_types [pindex ++] = IntPtrType ();
1367 for (i = 0; i < sig->param_count; ++i) {
1368 LLVMArgInfo *ainfo = &cinfo->args [i + sig->hasthis];
1370 if (vretaddr && vret_arg_pindex == pindex)
1371 param_types [pindex ++] = IntPtrType ();
1372 ainfo->pindex = pindex;
1374 switch (ainfo->storage) {
1375 case LLVMArgVtypeInReg:
1376 for (j = 0; j < 2; ++j) {
1377 switch (ainfo->pair_storage [j]) {
1379 param_types [pindex ++] = LLVMIntType (sizeof (gpointer) * 8);
1384 g_assert_not_reached ();
1388 case LLVMArgVtypeByVal:
1389 param_types [pindex] = type_to_llvm_arg_type (ctx, ainfo->type);
1392 param_types [pindex] = LLVMPointerType (param_types [pindex], 0);
1395 case LLVMArgAsIArgs:
1396 param_types [pindex] = LLVMArrayType (IntPtrType (), ainfo->nslots);
1399 case LLVMArgVtypeByRef:
1400 param_types [pindex] = type_to_llvm_arg_type (ctx, ainfo->type);
1403 param_types [pindex] = LLVMPointerType (param_types [pindex], 0);
1406 case LLVMArgAsFpArgs: {
1409 /* Emit dummy fp arguments if needed so the rest is passed on the stack */
1410 for (j = 0; j < ainfo->ndummy_fpargs; ++j)
1411 param_types [pindex ++] = LLVMDoubleType ();
1412 for (j = 0; j < ainfo->nslots; ++j)
1413 param_types [pindex ++] = ainfo->esize == 8 ? LLVMDoubleType () : LLVMFloatType ();
1416 case LLVMArgVtypeAsScalar:
1417 g_assert_not_reached ();
1419 case LLVMArgGsharedvtFixed:
1420 case LLVMArgGsharedvtFixedVtype:
1421 param_types [pindex ++] = LLVMPointerType (type_to_llvm_arg_type (ctx, ainfo->type), 0);
1423 case LLVMArgGsharedvtVariable:
1424 param_types [pindex ++] = LLVMPointerType (IntPtrType (), 0);
1427 param_types [pindex ++] = type_to_llvm_arg_type (ctx, ainfo->type);
1431 if (!ctx_ok (ctx)) {
1432 g_free (param_types);
1435 if (vretaddr && vret_arg_pindex == pindex)
1436 param_types [pindex ++] = IntPtrType ();
1437 if (ctx->llvm_only && cinfo->rgctx_arg) {
1438 /* Pass the rgctx as the last argument */
1439 cinfo->rgctx_arg_pindex = pindex;
1440 param_types [pindex] = ctx->module->ptr_type;
1444 res = LLVMFunctionType (ret_type, param_types, pindex, FALSE);
1445 g_free (param_types);
1451 sig_to_llvm_sig (EmitContext *ctx, MonoMethodSignature *sig)
1453 return sig_to_llvm_sig_full (ctx, sig, NULL);
1457 * LLVMFunctionType1:
1459 * Create an LLVM function type from the arguments.
1461 static G_GNUC_UNUSED LLVMTypeRef
1462 LLVMFunctionType0 (LLVMTypeRef ReturnType,
1465 return LLVMFunctionType (ReturnType, NULL, 0, IsVarArg);
1469 * LLVMFunctionType1:
1471 * Create an LLVM function type from the arguments.
1473 static G_GNUC_UNUSED LLVMTypeRef
1474 LLVMFunctionType1 (LLVMTypeRef ReturnType,
1475 LLVMTypeRef ParamType1,
1478 LLVMTypeRef param_types [1];
1480 param_types [0] = ParamType1;
1482 return LLVMFunctionType (ReturnType, param_types, 1, IsVarArg);
1486 * LLVMFunctionType2:
1488 * Create an LLVM function type from the arguments.
1490 static G_GNUC_UNUSED LLVMTypeRef
1491 LLVMFunctionType2 (LLVMTypeRef ReturnType,
1492 LLVMTypeRef ParamType1,
1493 LLVMTypeRef ParamType2,
1496 LLVMTypeRef param_types [2];
1498 param_types [0] = ParamType1;
1499 param_types [1] = ParamType2;
1501 return LLVMFunctionType (ReturnType, param_types, 2, IsVarArg);
1505 * LLVMFunctionType3:
1507 * Create an LLVM function type from the arguments.
1509 static G_GNUC_UNUSED LLVMTypeRef
1510 LLVMFunctionType3 (LLVMTypeRef ReturnType,
1511 LLVMTypeRef ParamType1,
1512 LLVMTypeRef ParamType2,
1513 LLVMTypeRef ParamType3,
1516 LLVMTypeRef param_types [3];
1518 param_types [0] = ParamType1;
1519 param_types [1] = ParamType2;
1520 param_types [2] = ParamType3;
1522 return LLVMFunctionType (ReturnType, param_types, 3, IsVarArg);
1525 static G_GNUC_UNUSED LLVMTypeRef
1526 LLVMFunctionType5 (LLVMTypeRef ReturnType,
1527 LLVMTypeRef ParamType1,
1528 LLVMTypeRef ParamType2,
1529 LLVMTypeRef ParamType3,
1530 LLVMTypeRef ParamType4,
1531 LLVMTypeRef ParamType5,
1534 LLVMTypeRef param_types [5];
1536 param_types [0] = ParamType1;
1537 param_types [1] = ParamType2;
1538 param_types [2] = ParamType3;
1539 param_types [3] = ParamType4;
1540 param_types [4] = ParamType5;
1542 return LLVMFunctionType (ReturnType, param_types, 5, IsVarArg);
1548 * Create an LLVM builder and remember it so it can be freed later.
1550 static LLVMBuilderRef
1551 create_builder (EmitContext *ctx)
1553 LLVMBuilderRef builder = LLVMCreateBuilder ();
1555 ctx->builders = g_slist_prepend_mempool (ctx->cfg->mempool, ctx->builders, builder);
1561 get_aotconst_name (MonoJumpInfoType type, gconstpointer data, int got_offset)
1566 case MONO_PATCH_INFO_INTERNAL_METHOD:
1567 name = g_strdup_printf ("jit_icall_%s", data);
1569 case MONO_PATCH_INFO_RGCTX_SLOT_INDEX: {
1570 MonoJumpInfoRgctxEntry *entry = (MonoJumpInfoRgctxEntry*)data;
1571 name = g_strdup_printf ("RGCTX_SLOT_INDEX_%s", mono_rgctx_info_type_to_str (entry->info_type));
1575 name = g_strdup_printf ("%s_%d", mono_ji_type_to_string (type), got_offset);
1583 get_aotconst_typed (EmitContext *ctx, MonoJumpInfoType type, gconstpointer data, LLVMTypeRef llvm_type)
1587 LLVMValueRef indexes [2];
1588 LLVMValueRef got_entry_addr, load;
1589 LLVMBuilderRef builder = ctx->builder;
1594 MonoJumpInfo tmp_ji;
1596 tmp_ji.data.target = data;
1598 MonoJumpInfo *ji = mono_aot_patch_info_dup (&tmp_ji);
1600 ji->next = cfg->patch_info;
1601 cfg->patch_info = ji;
1603 got_offset = mono_aot_get_got_offset (cfg->patch_info);
1604 ctx->module->max_got_offset = MAX (ctx->module->max_got_offset, got_offset);
1606 * If the got slot is shared, it means its initialized when the aot image is loaded, so we don't need to
1607 * explicitly initialize it.
1609 if (!mono_aot_is_shared_got_offset (got_offset)) {
1610 //mono_print_ji (ji);
1612 ctx->has_got_access = TRUE;
1615 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
1616 indexes [1] = LLVMConstInt (LLVMInt32Type (), (gssize)got_offset, FALSE);
1617 got_entry_addr = LLVMBuildGEP (builder, ctx->module->got_var, indexes, 2, "");
1619 name = get_aotconst_name (type, data, got_offset);
1621 load = LLVMBuildLoad (builder, got_entry_addr, "");
1622 load = convert (ctx, load, llvm_type);
1623 LLVMSetValueName (load, name ? name : "");
1625 load = LLVMBuildLoad (builder, got_entry_addr, name ? name : "");
1628 //set_invariant_load_flag (load);
1634 get_aotconst (EmitContext *ctx, MonoJumpInfoType type, gconstpointer data)
1636 return get_aotconst_typed (ctx, type, data, NULL);
1640 get_callee (EmitContext *ctx, LLVMTypeRef llvm_sig, MonoJumpInfoType type, gconstpointer data)
1642 LLVMValueRef callee;
1644 if (ctx->llvm_only) {
1645 callee_name = mono_aot_get_direct_call_symbol (type, data);
1647 /* Directly callable */
1649 callee = (LLVMValueRef)g_hash_table_lookup (ctx->module->direct_callables, callee_name);
1651 callee = LLVMAddFunction (ctx->lmodule, callee_name, llvm_sig);
1653 LLVMSetVisibility (callee, LLVMHiddenVisibility);
1655 g_hash_table_insert (ctx->module->direct_callables, (char*)callee_name, callee);
1657 /* LLVMTypeRef's are uniqued */
1658 if (LLVMGetElementType (LLVMTypeOf (callee)) != llvm_sig)
1659 return LLVMConstBitCast (callee, LLVMPointerType (llvm_sig, 0));
1661 g_free (callee_name);
1667 * Calls are made through the GOT.
1669 return get_aotconst_typed (ctx, type, data, LLVMPointerType (llvm_sig, 0));
1671 MonoJumpInfo *ji = NULL;
1673 callee_name = mono_aot_get_plt_symbol (type, data);
1677 if (ctx->cfg->compile_aot)
1678 /* Add a patch so referenced wrappers can be compiled in full aot mode */
1679 mono_add_patch_info (ctx->cfg, 0, type, data);
1682 callee = (LLVMValueRef)g_hash_table_lookup (ctx->module->plt_entries, callee_name);
1684 callee = LLVMAddFunction (ctx->lmodule, callee_name, llvm_sig);
1686 LLVMSetVisibility (callee, LLVMHiddenVisibility);
1688 g_hash_table_insert (ctx->module->plt_entries, (char*)callee_name, callee);
1691 if (ctx->cfg->compile_aot) {
1692 ji = g_new0 (MonoJumpInfo, 1);
1694 ji->data.target = data;
1696 g_hash_table_insert (ctx->module->plt_entries_ji, ji, callee);
1704 emit_jit_callee (EmitContext *ctx, const char *name, LLVMTypeRef llvm_sig, gpointer target)
1706 #if LLVM_API_VERSION > 100
1707 LLVMValueRef tramp_var = LLVMAddGlobal (ctx->lmodule, LLVMPointerType (llvm_sig, 0), name);
1708 LLVMSetInitializer (tramp_var, LLVMConstIntToPtr (LLVMConstInt (LLVMInt64Type (), (guint64)(size_t)target, FALSE), LLVMPointerType (llvm_sig, 0)));
1709 LLVMSetLinkage (tramp_var, LLVMExternalLinkage);
1710 LLVMValueRef callee = LLVMBuildLoad (ctx->builder, tramp_var, "");
1713 LLVMValueRef callee = LLVMAddFunction (ctx->lmodule, "", llvm_sig);
1714 LLVMAddGlobalMapping (ctx->module->ee, callee, target);
1720 get_handler_clause (MonoCompile *cfg, MonoBasicBlock *bb)
1722 MonoMethodHeader *header = cfg->header;
1723 MonoExceptionClause *clause;
1727 if (bb->region != -1 && MONO_BBLOCK_IS_IN_REGION (bb, MONO_REGION_TRY))
1728 return (bb->region >> 8) - 1;
1731 for (i = 0; i < header->num_clauses; ++i) {
1732 clause = &header->clauses [i];
1734 if (MONO_OFFSET_IN_CLAUSE (clause, bb->real_offset) && clause->flags == MONO_EXCEPTION_CLAUSE_NONE)
1741 static MonoExceptionClause *
1742 get_most_deep_clause (MonoCompile *cfg, EmitContext *ctx, MonoBasicBlock *bb)
1744 if (bb == cfg->bb_init)
1746 // Since they're sorted by nesting we just need
1747 // the first one that the bb is a member of
1748 for (int i = 0; i < cfg->header->num_clauses; i++) {
1749 MonoExceptionClause *curr = &cfg->header->clauses [i];
1751 if (MONO_OFFSET_IN_CLAUSE (curr, bb->real_offset))
1759 set_metadata_flag (LLVMValueRef v, const char *flag_name)
1761 LLVMValueRef md_arg;
1764 md_kind = LLVMGetMDKindID (flag_name, strlen (flag_name));
1765 md_arg = LLVMMDString ("mono", 4);
1766 LLVMSetMetadata (v, md_kind, LLVMMDNode (&md_arg, 1));
1770 set_invariant_load_flag (LLVMValueRef v)
1772 LLVMValueRef md_arg;
1774 const char *flag_name;
1776 // FIXME: Cache this
1777 flag_name = "invariant.load";
1778 md_kind = LLVMGetMDKindID (flag_name, strlen (flag_name));
1779 md_arg = LLVMMDString ("<index>", strlen ("<index>"));
1780 LLVMSetMetadata (v, md_kind, LLVMMDNode (&md_arg, 1));
1786 * Emit an LLVM call or invoke instruction depending on whenever the call is inside
1790 emit_call (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, LLVMValueRef callee, LLVMValueRef *args, int pindex)
1792 MonoCompile *cfg = ctx->cfg;
1793 LLVMValueRef lcall = NULL;
1794 LLVMBuilderRef builder = *builder_ref;
1795 MonoExceptionClause *clause;
1797 if (ctx->llvm_only) {
1798 clause = get_most_deep_clause (cfg, ctx, bb);
1801 g_assert (clause->flags == MONO_EXCEPTION_CLAUSE_NONE || clause->flags == MONO_EXCEPTION_CLAUSE_FINALLY);
1804 * Have to use an invoke instead of a call, branching to the
1805 * handler bblock of the clause containing this bblock.
1807 intptr_t key = CLAUSE_END(clause);
1809 LLVMBasicBlockRef lpad_bb = (LLVMBasicBlockRef)g_hash_table_lookup (ctx->exc_meta, (gconstpointer)key);
1811 // FIXME: Find the one that has the lowest end bound for the right start address
1812 // FIXME: Finally + nesting
1815 LLVMBasicBlockRef noex_bb = gen_bb (ctx, "CALL_NOEX_BB");
1818 lcall = LLVMBuildInvoke (builder, callee, args, pindex, noex_bb, lpad_bb, "");
1820 builder = ctx->builder = create_builder (ctx);
1821 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
1823 ctx->bblocks [bb->block_num].end_bblock = noex_bb;
1827 int clause_index = get_handler_clause (cfg, bb);
1829 if (clause_index != -1) {
1830 MonoMethodHeader *header = cfg->header;
1831 MonoExceptionClause *ec = &header->clauses [clause_index];
1832 MonoBasicBlock *tblock;
1833 LLVMBasicBlockRef ex_bb, noex_bb;
1836 * Have to use an invoke instead of a call, branching to the
1837 * handler bblock of the clause containing this bblock.
1840 g_assert (ec->flags == MONO_EXCEPTION_CLAUSE_NONE || ec->flags == MONO_EXCEPTION_CLAUSE_FINALLY);
1842 tblock = cfg->cil_offset_to_bb [ec->handler_offset];
1845 ctx->bblocks [tblock->block_num].invoke_target = TRUE;
1847 ex_bb = get_bb (ctx, tblock);
1849 noex_bb = gen_bb (ctx, "NOEX_BB");
1852 lcall = LLVMBuildInvoke (builder, callee, args, pindex, noex_bb, ex_bb, "");
1854 builder = ctx->builder = create_builder (ctx);
1855 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
1857 ctx->bblocks [bb->block_num].end_bblock = noex_bb;
1862 lcall = LLVMBuildCall (builder, callee, args, pindex, "");
1863 ctx->builder = builder;
1867 *builder_ref = ctx->builder;
1873 emit_load_general (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, int size, LLVMValueRef addr, LLVMValueRef base, const char *name, gboolean is_faulting, BarrierKind barrier)
1875 const char *intrins_name;
1876 LLVMValueRef args [16], res;
1877 LLVMTypeRef addr_type;
1878 gboolean use_intrinsics = TRUE;
1880 #if LLVM_API_VERSION > 100
1881 if (is_faulting && bb->region != -1 && !ctx->cfg->llvm_only) {
1882 /* The llvm.mono.load/store intrinsics are not supported by this llvm version, emit an explicit null check instead */
1885 cmp = LLVMBuildICmp (*builder_ref, LLVMIntEQ, base, LLVMConstNull (LLVMTypeOf (base)), "");
1886 emit_cond_system_exception (ctx, bb, "NullReferenceException", cmp);
1887 *builder_ref = ctx->builder;
1888 use_intrinsics = FALSE;
1892 if (is_faulting && bb->region != -1 && !ctx->cfg->llvm_only && use_intrinsics) {
1893 LLVMAtomicOrdering ordering;
1896 case LLVM_BARRIER_NONE:
1897 ordering = LLVMAtomicOrderingNotAtomic;
1899 case LLVM_BARRIER_ACQ:
1900 ordering = LLVMAtomicOrderingAcquire;
1902 case LLVM_BARRIER_SEQ:
1903 ordering = LLVMAtomicOrderingSequentiallyConsistent;
1906 g_assert_not_reached ();
1911 * We handle loads which can fault by calling a mono specific intrinsic
1912 * using an invoke, so they are handled properly inside try blocks.
1913 * We can't use this outside clauses, since LLVM optimizes intrinsics which
1914 * are marked with IntrReadArgMem.
1918 intrins_name = "llvm.mono.load.i8.p0i8";
1921 intrins_name = "llvm.mono.load.i16.p0i16";
1924 intrins_name = "llvm.mono.load.i32.p0i32";
1927 intrins_name = "llvm.mono.load.i64.p0i64";
1930 g_assert_not_reached ();
1933 addr_type = LLVMTypeOf (addr);
1934 if (addr_type == LLVMPointerType (LLVMDoubleType (), 0) || addr_type == LLVMPointerType (LLVMFloatType (), 0))
1935 addr = LLVMBuildBitCast (*builder_ref, addr, LLVMPointerType (LLVMIntType (size * 8), 0), "");
1938 args [1] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
1939 args [2] = LLVMConstInt (LLVMInt1Type (), TRUE, FALSE);
1940 args [3] = LLVMConstInt (LLVMInt32Type (), ordering, FALSE);
1941 res = emit_call (ctx, bb, builder_ref, get_intrinsic (ctx, intrins_name), args, 4);
1943 if (addr_type == LLVMPointerType (LLVMDoubleType (), 0))
1944 res = LLVMBuildBitCast (*builder_ref, res, LLVMDoubleType (), "");
1945 else if (addr_type == LLVMPointerType (LLVMFloatType (), 0))
1946 res = LLVMBuildBitCast (*builder_ref, res, LLVMFloatType (), "");
1953 * We emit volatile loads for loads which can fault, because otherwise
1954 * LLVM will generate invalid code when encountering a load from a
1957 if (barrier != LLVM_BARRIER_NONE)
1958 res = mono_llvm_build_atomic_load (*builder_ref, addr, name, is_faulting, size, barrier);
1960 res = mono_llvm_build_load (*builder_ref, addr, name, is_faulting);
1962 /* Mark it with a custom metadata */
1965 set_metadata_flag (res, "mono.faulting.load");
1973 emit_load (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, int size, LLVMValueRef addr, const char *name, gboolean is_faulting)
1975 return emit_load_general (ctx, bb, builder_ref, size, addr, addr, name, is_faulting, LLVM_BARRIER_NONE);
1979 emit_store_general (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, int size, LLVMValueRef value, LLVMValueRef addr, LLVMValueRef base, gboolean is_faulting, BarrierKind barrier)
1981 const char *intrins_name;
1982 LLVMValueRef args [16];
1983 gboolean use_intrinsics = TRUE;
1985 #if LLVM_API_VERSION > 100
1986 if (is_faulting && bb->region != -1 && !ctx->cfg->llvm_only) {
1987 /* The llvm.mono.load/store intrinsics are not supported by this llvm version, emit an explicit null check instead */
1988 LLVMValueRef cmp = LLVMBuildICmp (*builder_ref, LLVMIntEQ, base, LLVMConstNull (LLVMTypeOf (base)), "");
1989 emit_cond_system_exception (ctx, bb, "NullReferenceException", cmp);
1990 *builder_ref = ctx->builder;
1991 use_intrinsics = FALSE;
1995 if (is_faulting && bb->region != -1 && !ctx->cfg->llvm_only && use_intrinsics) {
1996 LLVMAtomicOrdering ordering;
1999 case LLVM_BARRIER_NONE:
2000 ordering = LLVMAtomicOrderingNotAtomic;
2002 case LLVM_BARRIER_REL:
2003 ordering = LLVMAtomicOrderingRelease;
2005 case LLVM_BARRIER_SEQ:
2006 ordering = LLVMAtomicOrderingSequentiallyConsistent;
2009 g_assert_not_reached ();
2015 intrins_name = "llvm.mono.store.i8.p0i8";
2018 intrins_name = "llvm.mono.store.i16.p0i16";
2021 intrins_name = "llvm.mono.store.i32.p0i32";
2024 intrins_name = "llvm.mono.store.i64.p0i64";
2027 g_assert_not_reached ();
2030 if (LLVMTypeOf (value) == LLVMDoubleType () || LLVMTypeOf (value) == LLVMFloatType ()) {
2031 value = LLVMBuildBitCast (*builder_ref, value, LLVMIntType (size * 8), "");
2032 addr = LLVMBuildBitCast (*builder_ref, addr, LLVMPointerType (LLVMIntType (size * 8), 0), "");
2037 args [2] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
2038 args [3] = LLVMConstInt (LLVMInt1Type (), TRUE, FALSE);
2039 args [4] = LLVMConstInt (LLVMInt32Type (), ordering, FALSE);
2040 emit_call (ctx, bb, builder_ref, get_intrinsic (ctx, intrins_name), args, 5);
2042 if (barrier != LLVM_BARRIER_NONE)
2043 mono_llvm_build_aligned_store (*builder_ref, value, addr, barrier, size);
2045 mono_llvm_build_store (*builder_ref, value, addr, is_faulting, barrier);
2050 emit_store (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, int size, LLVMValueRef value, LLVMValueRef addr, LLVMValueRef base, gboolean is_faulting)
2052 emit_store_general (ctx, bb, builder_ref, size, value, addr, base, is_faulting, LLVM_BARRIER_NONE);
2056 * emit_cond_system_exception:
2058 * Emit code to throw the exception EXC_TYPE if the condition CMP is false.
2059 * Might set the ctx exception.
2062 emit_cond_system_exception (EmitContext *ctx, MonoBasicBlock *bb, const char *exc_type, LLVMValueRef cmp)
2064 LLVMBasicBlockRef ex_bb, ex2_bb = NULL, noex_bb;
2065 LLVMBuilderRef builder;
2066 MonoClass *exc_class;
2067 LLVMValueRef args [2];
2068 LLVMValueRef callee;
2069 gboolean no_pc = FALSE;
2071 if (IS_TARGET_AMD64)
2072 /* Some platforms don't require the pc argument */
2075 ex_bb = gen_bb (ctx, "EX_BB");
2077 ex2_bb = gen_bb (ctx, "EX2_BB");
2078 noex_bb = gen_bb (ctx, "NOEX_BB");
2080 LLVMBuildCondBr (ctx->builder, cmp, ex_bb, noex_bb);
2082 exc_class = mono_class_load_from_name (mono_get_corlib (), "System", exc_type);
2084 /* Emit exception throwing code */
2085 ctx->builder = builder = create_builder (ctx);
2086 LLVMPositionBuilderAtEnd (builder, ex_bb);
2088 if (ctx->cfg->llvm_only) {
2089 static LLVMTypeRef sig;
2092 sig = LLVMFunctionType1 (LLVMVoidType (), LLVMInt32Type (), FALSE);
2093 callee = get_callee (ctx, sig, MONO_PATCH_INFO_JIT_ICALL_ADDR, "mono_llvm_throw_corlib_exception");
2095 LLVMBuildBr (builder, ex2_bb);
2097 ctx->builder = builder = create_builder (ctx);
2098 LLVMPositionBuilderAtEnd (ctx->builder, ex2_bb);
2100 args [0] = LLVMConstInt (LLVMInt32Type (), exc_class->type_token - MONO_TOKEN_TYPE_DEF, FALSE);
2101 emit_call (ctx, bb, &builder, callee, args, 1);
2102 LLVMBuildUnreachable (builder);
2104 ctx->builder = builder = create_builder (ctx);
2105 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
2107 ctx->bblocks [bb->block_num].end_bblock = noex_bb;
2113 callee = ctx->module->throw_corlib_exception;
2116 const char *icall_name;
2119 sig = LLVMFunctionType1 (LLVMVoidType (), LLVMInt32Type (), FALSE);
2121 sig = LLVMFunctionType2 (LLVMVoidType (), LLVMInt32Type (), LLVMPointerType (LLVMInt8Type (), 0), FALSE);
2122 icall_name = "llvm_throw_corlib_exception_abs_trampoline";
2124 if (ctx->cfg->compile_aot) {
2125 callee = get_callee (ctx, sig, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
2128 * Differences between the LLVM/non-LLVM throw corlib exception trampoline:
2129 * - On x86, LLVM generated code doesn't push the arguments
2130 * - The trampoline takes the throw address as an arguments, not a pc offset.
2132 gpointer target = resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
2133 callee = emit_jit_callee (ctx, "llvm_throw_corlib_exception_trampoline", sig, target);
2135 #if LLVM_API_VERSION > 100
2137 * Make sure that ex_bb starts with the invoke, so the block address points to it, and not to the load
2138 * added by emit_jit_callee ().
2140 ex2_bb = gen_bb (ctx, "EX2_BB");
2141 LLVMBuildBr (builder, ex2_bb);
2144 ctx->builder = builder = create_builder (ctx);
2145 LLVMPositionBuilderAtEnd (ctx->builder, ex2_bb);
2147 mono_memory_barrier ();
2148 ctx->module->throw_corlib_exception = callee;
2153 args [0] = LLVMConstInt (LLVMInt32Type (), exc_class->type_token - MONO_TOKEN_TYPE_DEF, FALSE);
2156 * The LLVM mono branch contains changes so a block address can be passed as an
2157 * argument to a call.
2160 emit_call (ctx, bb, &builder, callee, args, 1);
2162 args [1] = LLVMBlockAddress (ctx->lmethod, ex_bb);
2163 emit_call (ctx, bb, &builder, callee, args, 2);
2166 LLVMBuildUnreachable (builder);
2168 ctx->builder = builder = create_builder (ctx);
2169 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
2171 ctx->bblocks [bb->block_num].end_bblock = noex_bb;
2178 * emit_args_to_vtype:
2180 * Emit code to store the vtype in the arguments args to the address ADDRESS.
2183 emit_args_to_vtype (EmitContext *ctx, LLVMBuilderRef builder, MonoType *t, LLVMValueRef address, LLVMArgInfo *ainfo, LLVMValueRef *args)
2185 int j, size, nslots;
2187 size = mono_class_value_size (mono_class_from_mono_type (t), NULL);
2189 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (t))) {
2190 address = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (LLVMInt8Type (), 0), "");
2193 if (ainfo->storage == LLVMArgAsFpArgs)
2194 nslots = ainfo->nslots;
2198 for (j = 0; j < nslots; ++j) {
2199 LLVMValueRef index [2], addr, daddr;
2200 int part_size = size > sizeof (gpointer) ? sizeof (gpointer) : size;
2201 LLVMTypeRef part_type;
2203 while (part_size != 1 && part_size != 2 && part_size != 4 && part_size < 8)
2206 if (ainfo->pair_storage [j] == LLVMArgNone)
2209 switch (ainfo->pair_storage [j]) {
2210 case LLVMArgInIReg: {
2211 part_type = LLVMIntType (part_size * 8);
2212 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (t))) {
2213 index [0] = LLVMConstInt (LLVMInt32Type (), j * sizeof (gpointer), FALSE);
2214 addr = LLVMBuildGEP (builder, address, index, 1, "");
2216 daddr = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (IntPtrType (), 0), "");
2217 index [0] = LLVMConstInt (LLVMInt32Type (), j, FALSE);
2218 addr = LLVMBuildGEP (builder, daddr, index, 1, "");
2220 LLVMBuildStore (builder, convert (ctx, args [j], part_type), LLVMBuildBitCast (ctx->builder, addr, LLVMPointerType (part_type, 0), ""));
2223 case LLVMArgInFPReg: {
2224 LLVMTypeRef arg_type;
2226 if (ainfo->esize == 8)
2227 arg_type = LLVMDoubleType ();
2229 arg_type = LLVMFloatType ();
2231 index [0] = LLVMConstInt (LLVMInt32Type (), j, FALSE);
2232 daddr = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (arg_type, 0), "");
2233 addr = LLVMBuildGEP (builder, daddr, index, 1, "");
2234 LLVMBuildStore (builder, args [j], addr);
2240 g_assert_not_reached ();
2243 size -= sizeof (gpointer);
2248 * emit_vtype_to_args:
2250 * Emit code to load a vtype at address ADDRESS into scalar arguments. Store the arguments
2251 * into ARGS, and the number of arguments into NARGS.
2254 emit_vtype_to_args (EmitContext *ctx, LLVMBuilderRef builder, MonoType *t, LLVMValueRef address, LLVMArgInfo *ainfo, LLVMValueRef *args, guint32 *nargs)
2257 int j, size, nslots;
2258 LLVMTypeRef arg_type;
2260 size = get_vtype_size (t);
2262 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (t)))
2263 address = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (LLVMInt8Type (), 0), "");
2265 if (ainfo->storage == LLVMArgAsFpArgs)
2266 nslots = ainfo->nslots;
2269 for (j = 0; j < nslots; ++j) {
2270 LLVMValueRef index [2], addr, daddr;
2271 int partsize = size > sizeof (gpointer) ? sizeof (gpointer) : size;
2273 if (ainfo->pair_storage [j] == LLVMArgNone)
2276 switch (ainfo->pair_storage [j]) {
2278 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (t))) {
2279 index [0] = LLVMConstInt (LLVMInt32Type (), j * sizeof (gpointer), FALSE);
2280 addr = LLVMBuildGEP (builder, address, index, 1, "");
2282 daddr = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (IntPtrType (), 0), "");
2283 index [0] = LLVMConstInt (LLVMInt32Type (), j, FALSE);
2284 addr = LLVMBuildGEP (builder, daddr, index, 1, "");
2286 args [pindex ++] = convert (ctx, LLVMBuildLoad (builder, LLVMBuildBitCast (ctx->builder, addr, LLVMPointerType (LLVMIntType (partsize * 8), 0), ""), ""), IntPtrType ());
2288 case LLVMArgInFPReg:
2289 if (ainfo->esize == 8)
2290 arg_type = LLVMDoubleType ();
2292 arg_type = LLVMFloatType ();
2293 daddr = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (arg_type, 0), "");
2294 index [0] = LLVMConstInt (LLVMInt32Type (), j, FALSE);
2295 addr = LLVMBuildGEP (builder, daddr, index, 1, "");
2296 args [pindex ++] = LLVMBuildLoad (builder, addr, "");
2301 g_assert_not_reached ();
2303 size -= sizeof (gpointer);
2310 build_alloca_llvm_type_name (EmitContext *ctx, LLVMTypeRef t, int align, const char *name)
2313 * Have to place all alloca's at the end of the entry bb, since otherwise they would
2314 * get executed every time control reaches them.
2316 LLVMPositionBuilder (ctx->alloca_builder, get_bb (ctx, ctx->cfg->bb_entry), ctx->last_alloca);
2318 ctx->last_alloca = mono_llvm_build_alloca (ctx->alloca_builder, t, NULL, align, name);
2319 return ctx->last_alloca;
2323 build_alloca_llvm_type (EmitContext *ctx, LLVMTypeRef t, int align)
2325 return build_alloca_llvm_type_name (ctx, t, align, "");
2329 build_alloca (EmitContext *ctx, MonoType *t)
2331 MonoClass *k = mono_class_from_mono_type (t);
2334 g_assert (!mini_is_gsharedvt_variable_type (t));
2336 if (MONO_CLASS_IS_SIMD (ctx->cfg, k))
2339 align = mono_class_min_align (k);
2341 /* Sometimes align is not a power of 2 */
2342 while (mono_is_power_of_two (align) == -1)
2345 return build_alloca_llvm_type (ctx, type_to_llvm_type (ctx, t), align);
2349 emit_gsharedvt_ldaddr (EmitContext *ctx, int vreg)
2353 * Compute the address of the local as gsharedvt_locals_var + gsharedvt_info_var->locals_offsets [idx].
2355 MonoCompile *cfg = ctx->cfg;
2356 LLVMBuilderRef builder = ctx->builder;
2357 LLVMValueRef offset, offset_var;
2358 LLVMValueRef info_var = ctx->values [cfg->gsharedvt_info_var->dreg];
2359 LLVMValueRef locals_var = ctx->values [cfg->gsharedvt_locals_var->dreg];
2363 g_assert (info_var);
2364 g_assert (locals_var);
2366 int idx = cfg->gsharedvt_vreg_to_idx [vreg] - 1;
2368 offset = LLVMConstInt (LLVMInt32Type (), MONO_STRUCT_OFFSET (MonoGSharedVtMethodRuntimeInfo, entries) + (idx * sizeof (gpointer)), FALSE);
2369 ptr = LLVMBuildAdd (builder, convert (ctx, info_var, IntPtrType ()), convert (ctx, offset, IntPtrType ()), "");
2371 name = g_strdup_printf ("gsharedvt_local_%d_offset", vreg);
2372 offset_var = LLVMBuildLoad (builder, convert (ctx, ptr, LLVMPointerType (LLVMInt32Type (), 0)), name);
2374 return LLVMBuildAdd (builder, convert (ctx, locals_var, IntPtrType ()), convert (ctx, offset_var, IntPtrType ()), "");
2378 * Put the global into the 'llvm.used' array to prevent it from being optimized away.
2381 mark_as_used (MonoLLVMModule *module, LLVMValueRef global)
2384 module->used = g_ptr_array_sized_new (16);
2385 g_ptr_array_add (module->used, global);
2389 emit_llvm_used (MonoLLVMModule *module)
2391 LLVMModuleRef lmodule = module->lmodule;
2392 LLVMTypeRef used_type;
2393 LLVMValueRef used, *used_elem;
2399 used_type = LLVMArrayType (LLVMPointerType (LLVMInt8Type (), 0), module->used->len);
2400 used = LLVMAddGlobal (lmodule, used_type, "llvm.used");
2401 used_elem = g_new0 (LLVMValueRef, module->used->len);
2402 for (i = 0; i < module->used->len; ++i)
2403 used_elem [i] = LLVMConstBitCast ((LLVMValueRef)g_ptr_array_index (module->used, i), LLVMPointerType (LLVMInt8Type (), 0));
2404 LLVMSetInitializer (used, LLVMConstArray (LLVMPointerType (LLVMInt8Type (), 0), used_elem, module->used->len));
2405 LLVMSetLinkage (used, LLVMAppendingLinkage);
2406 LLVMSetSection (used, "llvm.metadata");
2412 * Emit a function mapping method indexes to their code
2415 emit_get_method (MonoLLVMModule *module)
2417 LLVMModuleRef lmodule = module->lmodule;
2418 LLVMValueRef func, switch_ins, m;
2419 LLVMBasicBlockRef entry_bb, fail_bb, bb, code_start_bb, code_end_bb;
2420 LLVMBasicBlockRef *bbs;
2422 LLVMBuilderRef builder = LLVMCreateBuilder ();
2427 * Emit a switch statement. Emitting a table of function addresses is smaller/faster,
2428 * but generating code seems safer.
2430 rtype = LLVMPointerType (LLVMInt8Type (), 0);
2431 func = LLVMAddFunction (lmodule, module->get_method_symbol, LLVMFunctionType1 (rtype, LLVMInt32Type (), FALSE));
2432 LLVMSetLinkage (func, LLVMExternalLinkage);
2433 LLVMSetVisibility (func, LLVMHiddenVisibility);
2434 LLVMAddFunctionAttr (func, LLVMNoUnwindAttribute);
2435 module->get_method = func;
2437 entry_bb = LLVMAppendBasicBlock (func, "ENTRY");
2440 * Return llvm_code_start/llvm_code_end when called with -1/-2.
2441 * Hopefully, the toolchain doesn't reorder these functions. If it does,
2442 * then we will have to find another solution.
2445 name = g_strdup_printf ("BB_CODE_START");
2446 code_start_bb = LLVMAppendBasicBlock (func, name);
2448 LLVMPositionBuilderAtEnd (builder, code_start_bb);
2449 LLVMBuildRet (builder, LLVMBuildBitCast (builder, module->code_start, rtype, ""));
2451 name = g_strdup_printf ("BB_CODE_END");
2452 code_end_bb = LLVMAppendBasicBlock (func, name);
2454 LLVMPositionBuilderAtEnd (builder, code_end_bb);
2455 LLVMBuildRet (builder, LLVMBuildBitCast (builder, module->code_end, rtype, ""));
2457 bbs = g_new0 (LLVMBasicBlockRef, module->max_method_idx + 1);
2458 for (i = 0; i < module->max_method_idx + 1; ++i) {
2459 name = g_strdup_printf ("BB_%d", i);
2460 bb = LLVMAppendBasicBlock (func, name);
2464 LLVMPositionBuilderAtEnd (builder, bb);
2466 m = (LLVMValueRef)g_hash_table_lookup (module->idx_to_lmethod, GINT_TO_POINTER (i));
2468 LLVMBuildRet (builder, LLVMBuildBitCast (builder, m, rtype, ""));
2470 LLVMBuildRet (builder, LLVMConstNull (rtype));
2473 fail_bb = LLVMAppendBasicBlock (func, "FAIL");
2474 LLVMPositionBuilderAtEnd (builder, fail_bb);
2475 LLVMBuildRet (builder, LLVMConstNull (rtype));
2477 LLVMPositionBuilderAtEnd (builder, entry_bb);
2479 switch_ins = LLVMBuildSwitch (builder, LLVMGetParam (func, 0), fail_bb, 0);
2480 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), -1, FALSE), code_start_bb);
2481 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), -2, FALSE), code_end_bb);
2482 for (i = 0; i < module->max_method_idx + 1; ++i) {
2483 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), i, FALSE), bbs [i]);
2486 mark_as_used (module, func);
2488 LLVMDisposeBuilder (builder);
2492 * emit_get_unbox_tramp:
2494 * Emit a function mapping method indexes to their unbox trampoline
2497 emit_get_unbox_tramp (MonoLLVMModule *module)
2499 LLVMModuleRef lmodule = module->lmodule;
2500 LLVMValueRef func, switch_ins, m;
2501 LLVMBasicBlockRef entry_bb, fail_bb, bb;
2502 LLVMBasicBlockRef *bbs;
2504 LLVMBuilderRef builder = LLVMCreateBuilder ();
2508 /* Similar to emit_get_method () */
2510 rtype = LLVMPointerType (LLVMInt8Type (), 0);
2511 func = LLVMAddFunction (lmodule, module->get_unbox_tramp_symbol, LLVMFunctionType1 (rtype, LLVMInt32Type (), FALSE));
2512 LLVMSetLinkage (func, LLVMExternalLinkage);
2513 LLVMSetVisibility (func, LLVMHiddenVisibility);
2514 LLVMAddFunctionAttr (func, LLVMNoUnwindAttribute);
2515 module->get_unbox_tramp = func;
2517 entry_bb = LLVMAppendBasicBlock (func, "ENTRY");
2519 bbs = g_new0 (LLVMBasicBlockRef, module->max_method_idx + 1);
2520 for (i = 0; i < module->max_method_idx + 1; ++i) {
2521 m = (LLVMValueRef)g_hash_table_lookup (module->idx_to_unbox_tramp, GINT_TO_POINTER (i));
2525 name = g_strdup_printf ("BB_%d", i);
2526 bb = LLVMAppendBasicBlock (func, name);
2530 LLVMPositionBuilderAtEnd (builder, bb);
2532 LLVMBuildRet (builder, LLVMBuildBitCast (builder, m, rtype, ""));
2535 fail_bb = LLVMAppendBasicBlock (func, "FAIL");
2536 LLVMPositionBuilderAtEnd (builder, fail_bb);
2537 LLVMBuildRet (builder, LLVMConstNull (rtype));
2539 LLVMPositionBuilderAtEnd (builder, entry_bb);
2541 switch_ins = LLVMBuildSwitch (builder, LLVMGetParam (func, 0), fail_bb, 0);
2542 for (i = 0; i < module->max_method_idx + 1; ++i) {
2543 m = (LLVMValueRef)g_hash_table_lookup (module->idx_to_unbox_tramp, GINT_TO_POINTER (i));
2547 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), i, FALSE), bbs [i]);
2550 mark_as_used (module, func);
2551 LLVMDisposeBuilder (builder);
2554 /* Add a function to mark the beginning of LLVM code */
2556 emit_llvm_code_start (MonoLLVMModule *module)
2558 LLVMModuleRef lmodule = module->lmodule;
2560 LLVMBasicBlockRef entry_bb;
2561 LLVMBuilderRef builder;
2563 func = LLVMAddFunction (lmodule, "llvm_code_start", LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE));
2564 LLVMSetLinkage (func, LLVMInternalLinkage);
2565 LLVMAddFunctionAttr (func, LLVMNoUnwindAttribute);
2566 module->code_start = func;
2567 entry_bb = LLVMAppendBasicBlock (func, "ENTRY");
2568 builder = LLVMCreateBuilder ();
2569 LLVMPositionBuilderAtEnd (builder, entry_bb);
2570 LLVMBuildRetVoid (builder);
2571 LLVMDisposeBuilder (builder);
2575 emit_init_icall_wrapper (MonoLLVMModule *module, const char *name, const char *icall_name, int subtype)
2577 LLVMModuleRef lmodule = module->lmodule;
2578 LLVMValueRef func, indexes [2], got_entry_addr, args [16], callee;
2579 LLVMBasicBlockRef entry_bb;
2580 LLVMBuilderRef builder;
2587 func = LLVMAddFunction (lmodule, name, LLVMFunctionType1 (LLVMVoidType (), LLVMInt32Type (), FALSE));
2588 sig = LLVMFunctionType2 (LLVMVoidType (), IntPtrType (), LLVMInt32Type (), FALSE);
2593 func = LLVMAddFunction (lmodule, name, LLVMFunctionType2 (LLVMVoidType (), LLVMInt32Type (), IntPtrType (), FALSE));
2594 sig = LLVMFunctionType3 (LLVMVoidType (), IntPtrType (), LLVMInt32Type (), IntPtrType (), FALSE);
2597 func = LLVMAddFunction (lmodule, name, LLVMFunctionType2 (LLVMVoidType (), LLVMInt32Type (), ObjRefType (), FALSE));
2598 sig = LLVMFunctionType3 (LLVMVoidType (), IntPtrType (), LLVMInt32Type (), ObjRefType (), FALSE);
2601 g_assert_not_reached ();
2603 LLVMSetLinkage (func, LLVMInternalLinkage);
2604 LLVMAddFunctionAttr (func, LLVMNoInlineAttribute);
2605 mono_llvm_set_preserveall_cc (func);
2606 entry_bb = LLVMAppendBasicBlock (func, "ENTRY");
2607 builder = LLVMCreateBuilder ();
2608 LLVMPositionBuilderAtEnd (builder, entry_bb);
2611 ji = g_new0 (MonoJumpInfo, 1);
2612 ji->type = MONO_PATCH_INFO_AOT_MODULE;
2613 ji = mono_aot_patch_info_dup (ji);
2614 got_offset = mono_aot_get_got_offset (ji);
2615 module->max_got_offset = MAX (module->max_got_offset, got_offset);
2616 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
2617 indexes [1] = LLVMConstInt (LLVMInt32Type (), got_offset, FALSE);
2618 got_entry_addr = LLVMBuildGEP (builder, module->got_var, indexes, 2, "");
2619 args [0] = LLVMBuildPtrToInt (builder, LLVMBuildLoad (builder, got_entry_addr, ""), IntPtrType (), "");
2620 args [1] = LLVMGetParam (func, 0);
2622 args [2] = LLVMGetParam (func, 1);
2624 ji = g_new0 (MonoJumpInfo, 1);
2625 ji->type = MONO_PATCH_INFO_INTERNAL_METHOD;
2626 ji->data.name = icall_name;
2627 ji = mono_aot_patch_info_dup (ji);
2628 got_offset = mono_aot_get_got_offset (ji);
2629 module->max_got_offset = MAX (module->max_got_offset, got_offset);
2630 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
2631 indexes [1] = LLVMConstInt (LLVMInt32Type (), got_offset, FALSE);
2632 got_entry_addr = LLVMBuildGEP (builder, module->got_var, indexes, 2, "");
2633 callee = LLVMBuildLoad (builder, got_entry_addr, "");
2634 callee = LLVMBuildBitCast (builder, callee, LLVMPointerType (sig, 0), "");
2635 LLVMBuildCall (builder, callee, args, LLVMCountParamTypes (sig), "");
2637 // Set the inited flag
2638 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
2639 indexes [1] = LLVMGetParam (func, 0);
2640 LLVMBuildStore (builder, LLVMConstInt (LLVMInt8Type (), 1, FALSE), LLVMBuildGEP (builder, module->inited_var, indexes, 2, ""));
2642 LLVMBuildRetVoid (builder);
2644 LLVMVerifyFunction(func, LLVMAbortProcessAction);
2645 LLVMDisposeBuilder (builder);
2650 * Emit wrappers around the C icalls used to initialize llvm methods, to
2651 * make the calling code smaller and to enable usage of the llvm
2652 * PreserveAll calling convention.
2655 emit_init_icall_wrappers (MonoLLVMModule *module)
2657 module->init_method = emit_init_icall_wrapper (module, "init_method", "mono_aot_init_llvm_method", 0);
2658 module->init_method_gshared_mrgctx = emit_init_icall_wrapper (module, "init_method_gshared_mrgctx", "mono_aot_init_gshared_method_mrgctx", 1);
2659 module->init_method_gshared_this = emit_init_icall_wrapper (module, "init_method_gshared_this", "mono_aot_init_gshared_method_this", 2);
2660 module->init_method_gshared_vtable = emit_init_icall_wrapper (module, "init_method_gshared_vtable", "mono_aot_init_gshared_method_vtable", 3);
2664 emit_llvm_code_end (MonoLLVMModule *module)
2666 LLVMModuleRef lmodule = module->lmodule;
2668 LLVMBasicBlockRef entry_bb;
2669 LLVMBuilderRef builder;
2671 func = LLVMAddFunction (lmodule, "llvm_code_end", LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE));
2672 LLVMSetLinkage (func, LLVMInternalLinkage);
2673 LLVMAddFunctionAttr (func, LLVMNoUnwindAttribute);
2674 module->code_end = func;
2675 entry_bb = LLVMAppendBasicBlock (func, "ENTRY");
2676 builder = LLVMCreateBuilder ();
2677 LLVMPositionBuilderAtEnd (builder, entry_bb);
2678 LLVMBuildRetVoid (builder);
2679 LLVMDisposeBuilder (builder);
2683 emit_div_check (EmitContext *ctx, LLVMBuilderRef builder, MonoBasicBlock *bb, MonoInst *ins, LLVMValueRef lhs, LLVMValueRef rhs)
2685 gboolean need_div_check = ctx->cfg->backend->need_div_check;
2688 /* LLVM doesn't know that these can throw an exception since they are not called through an intrinsic */
2689 need_div_check = TRUE;
2691 if (!need_div_check)
2694 switch (ins->opcode) {
2707 case OP_IDIV_UN_IMM:
2708 case OP_LDIV_UN_IMM:
2709 case OP_IREM_UN_IMM:
2710 case OP_LREM_UN_IMM: {
2712 gboolean is_signed = (ins->opcode == OP_IDIV || ins->opcode == OP_LDIV || ins->opcode == OP_IREM || ins->opcode == OP_LREM ||
2713 ins->opcode == OP_IDIV_IMM || ins->opcode == OP_LDIV_IMM || ins->opcode == OP_IREM_IMM || ins->opcode == OP_LREM_IMM);
2715 cmp = LLVMBuildICmp (builder, LLVMIntEQ, rhs, LLVMConstInt (LLVMTypeOf (rhs), 0, FALSE), "");
2716 emit_cond_system_exception (ctx, bb, "DivideByZeroException", cmp);
2719 builder = ctx->builder;
2721 /* b == -1 && a == 0x80000000 */
2723 LLVMValueRef c = (LLVMTypeOf (lhs) == LLVMInt32Type ()) ? LLVMConstInt (LLVMTypeOf (lhs), 0x80000000, FALSE) : LLVMConstInt (LLVMTypeOf (lhs), 0x8000000000000000LL, FALSE);
2724 LLVMValueRef cond1 = LLVMBuildICmp (builder, LLVMIntEQ, rhs, LLVMConstInt (LLVMTypeOf (rhs), -1, FALSE), "");
2725 LLVMValueRef cond2 = LLVMBuildICmp (builder, LLVMIntEQ, lhs, c, "");
2727 cmp = LLVMBuildICmp (builder, LLVMIntEQ, LLVMBuildAnd (builder, cond1, cond2, ""), LLVMConstInt (LLVMInt1Type (), 1, FALSE), "");
2728 emit_cond_system_exception (ctx, bb, "OverflowException", cmp);
2731 builder = ctx->builder;
2743 * Emit code to initialize the GOT slots used by the method.
2746 emit_init_method (EmitContext *ctx)
2748 LLVMValueRef indexes [16], args [16], callee;
2749 LLVMValueRef inited_var, cmp, call;
2750 LLVMBasicBlockRef inited_bb, notinited_bb;
2751 LLVMBuilderRef builder = ctx->builder;
2752 MonoCompile *cfg = ctx->cfg;
2754 ctx->module->max_inited_idx = MAX (ctx->module->max_inited_idx, cfg->method_index);
2756 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
2757 indexes [1] = LLVMConstInt (LLVMInt32Type (), cfg->method_index, FALSE);
2758 inited_var = LLVMBuildLoad (builder, LLVMBuildGEP (builder, ctx->module->inited_var, indexes, 2, ""), "is_inited");
2760 args [0] = inited_var;
2761 args [1] = LLVMConstInt (LLVMInt8Type (), 1, FALSE);
2762 inited_var = LLVMBuildCall (ctx->builder, get_intrinsic (ctx, "llvm.expect.i8"), args, 2, "");
2764 cmp = LLVMBuildICmp (builder, LLVMIntEQ, inited_var, LLVMConstInt (LLVMTypeOf (inited_var), 0, FALSE), "");
2766 inited_bb = ctx->inited_bb;
2767 notinited_bb = gen_bb (ctx, "NOTINITED_BB");
2769 LLVMBuildCondBr (ctx->builder, cmp, notinited_bb, inited_bb);
2771 builder = ctx->builder = create_builder (ctx);
2772 LLVMPositionBuilderAtEnd (ctx->builder, notinited_bb);
2775 if (ctx->rgctx_arg && cfg->method->is_inflated && mono_method_get_context (cfg->method)->method_inst) {
2776 args [0] = LLVMConstInt (LLVMInt32Type (), cfg->method_index, 0);
2777 args [1] = convert (ctx, ctx->rgctx_arg, IntPtrType ());
2778 callee = ctx->module->init_method_gshared_mrgctx;
2779 call = LLVMBuildCall (builder, callee, args, 2, "");
2780 } else if (ctx->rgctx_arg) {
2781 /* A vtable is passed as the rgctx argument */
2782 args [0] = LLVMConstInt (LLVMInt32Type (), cfg->method_index, 0);
2783 args [1] = convert (ctx, ctx->rgctx_arg, IntPtrType ());
2784 callee = ctx->module->init_method_gshared_vtable;
2785 call = LLVMBuildCall (builder, callee, args, 2, "");
2786 } else if (cfg->gshared) {
2787 args [0] = LLVMConstInt (LLVMInt32Type (), cfg->method_index, 0);
2788 args [1] = convert (ctx, ctx->this_arg, ObjRefType ());
2789 callee = ctx->module->init_method_gshared_this;
2790 call = LLVMBuildCall (builder, callee, args, 2, "");
2792 args [0] = LLVMConstInt (LLVMInt32Type (), cfg->method_index, 0);
2793 callee = ctx->module->init_method;
2794 call = LLVMBuildCall (builder, callee, args, 1, "");
2798 * This enables llvm to keep arguments in their original registers/
2799 * scratch registers, since the call will not clobber them.
2801 mono_llvm_set_call_preserveall_cc (call);
2803 LLVMBuildBr (builder, inited_bb);
2804 ctx->bblocks [cfg->bb_entry->block_num].end_bblock = inited_bb;
2806 builder = ctx->builder = create_builder (ctx);
2807 LLVMPositionBuilderAtEnd (ctx->builder, inited_bb);
2811 emit_unbox_tramp (EmitContext *ctx, const char *method_name, LLVMTypeRef method_type, LLVMValueRef method, int method_index)
2814 * Emit unbox trampoline using a tail call
2816 LLVMValueRef tramp, call, *args;
2817 LLVMBuilderRef builder;
2818 LLVMBasicBlockRef lbb;
2819 LLVMCallInfo *linfo;
2823 tramp_name = g_strdup_printf ("ut_%s", method_name);
2824 tramp = LLVMAddFunction (ctx->module->lmodule, tramp_name, method_type);
2825 LLVMSetLinkage (tramp, LLVMInternalLinkage);
2826 LLVMAddFunctionAttr (tramp, LLVMOptimizeForSizeAttribute);
2827 //LLVMAddFunctionAttr (tramp, LLVMNoUnwindAttribute);
2829 // FIXME: Reduce code duplication with mono_llvm_compile_method () etc.
2830 if (!ctx->llvm_only && ctx->rgctx_arg_pindex != -1)
2831 LLVMAddAttribute (LLVMGetParam (tramp, ctx->rgctx_arg_pindex), LLVMInRegAttribute);
2832 if (ctx->cfg->vret_addr) {
2833 LLVMSetValueName (LLVMGetParam (tramp, linfo->vret_arg_pindex), "vret");
2834 if (linfo->ret.storage == LLVMArgVtypeByRef) {
2835 LLVMAddAttribute (LLVMGetParam (tramp, linfo->vret_arg_pindex), LLVMStructRetAttribute);
2836 LLVMAddAttribute (LLVMGetParam (tramp, linfo->vret_arg_pindex), LLVMNoAliasAttribute);
2840 lbb = LLVMAppendBasicBlock (tramp, "");
2841 builder = LLVMCreateBuilder ();
2842 LLVMPositionBuilderAtEnd (builder, lbb);
2844 nargs = LLVMCountParamTypes (method_type);
2845 args = g_new0 (LLVMValueRef, nargs);
2846 for (i = 0; i < nargs; ++i) {
2847 args [i] = LLVMGetParam (tramp, i);
2848 if (i == ctx->this_arg_pindex) {
2849 LLVMTypeRef arg_type = LLVMTypeOf (args [i]);
2851 args [i] = LLVMBuildPtrToInt (builder, args [i], IntPtrType (), "");
2852 args [i] = LLVMBuildAdd (builder, args [i], LLVMConstInt (IntPtrType (), sizeof (MonoObject), FALSE), "");
2853 args [i] = LLVMBuildIntToPtr (builder, args [i], arg_type, "");
2856 call = LLVMBuildCall (builder, method, args, nargs, "");
2857 if (!ctx->llvm_only && ctx->rgctx_arg_pindex != -1)
2858 LLVMAddInstrAttribute (call, 1 + ctx->rgctx_arg_pindex, LLVMInRegAttribute);
2859 if (linfo->ret.storage == LLVMArgVtypeByRef)
2860 LLVMAddInstrAttribute (call, 1 + linfo->vret_arg_pindex, LLVMStructRetAttribute);
2862 // FIXME: This causes assertions in clang
2863 //mono_llvm_set_must_tail (call);
2864 if (LLVMGetReturnType (method_type) == LLVMVoidType ())
2865 LLVMBuildRetVoid (builder);
2867 LLVMBuildRet (builder, call);
2869 g_hash_table_insert (ctx->module->idx_to_unbox_tramp, GINT_TO_POINTER (method_index), tramp);
2870 LLVMDisposeBuilder (builder);
2876 * Emit code to load/convert arguments.
2879 emit_entry_bb (EmitContext *ctx, LLVMBuilderRef builder)
2882 MonoCompile *cfg = ctx->cfg;
2883 MonoMethodSignature *sig = ctx->sig;
2884 LLVMCallInfo *linfo = ctx->linfo;
2888 LLVMBuilderRef old_builder = ctx->builder;
2889 ctx->builder = builder;
2891 ctx->alloca_builder = create_builder (ctx);
2894 * Handle indirect/volatile variables by allocating memory for them
2895 * using 'alloca', and storing their address in a temporary.
2897 for (i = 0; i < cfg->num_varinfo; ++i) {
2898 MonoInst *var = cfg->varinfo [i];
2901 if (var->opcode == OP_GSHAREDVT_LOCAL || var->opcode == OP_GSHAREDVT_ARG_REGOFFSET) {
2902 } 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))) {
2903 vtype = type_to_llvm_type (ctx, var->inst_vtype);
2906 /* Could be already created by an OP_VPHI */
2907 if (!ctx->addresses [var->dreg]) {
2908 ctx->addresses [var->dreg] = build_alloca (ctx, var->inst_vtype);
2909 //LLVMSetValueName (ctx->addresses [var->dreg], g_strdup_printf ("vreg_loc_%d", var->dreg));
2911 ctx->vreg_cli_types [var->dreg] = var->inst_vtype;
2915 names = g_new (char *, sig->param_count);
2916 mono_method_get_param_names (cfg->method, (const char **) names);
2918 for (i = 0; i < sig->param_count; ++i) {
2919 LLVMArgInfo *ainfo = &linfo->args [i + sig->hasthis];
2920 int reg = cfg->args [i + sig->hasthis]->dreg;
2923 pindex = ainfo->pindex;
2925 switch (ainfo->storage) {
2926 case LLVMArgVtypeInReg:
2927 case LLVMArgAsFpArgs: {
2928 LLVMValueRef args [8];
2931 pindex += ainfo->ndummy_fpargs;
2933 /* The argument is received as a set of int/fp arguments, store them into the real argument */
2934 memset (args, 0, sizeof (args));
2935 if (ainfo->storage == LLVMArgVtypeInReg) {
2936 args [0] = LLVMGetParam (ctx->lmethod, pindex);
2937 if (ainfo->pair_storage [1] != LLVMArgNone)
2938 args [1] = LLVMGetParam (ctx->lmethod, pindex + 1);
2940 g_assert (ainfo->nslots <= 8);
2941 for (j = 0; j < ainfo->nslots; ++j)
2942 args [j] = LLVMGetParam (ctx->lmethod, pindex + j);
2944 ctx->addresses [reg] = build_alloca (ctx, ainfo->type);
2946 emit_args_to_vtype (ctx, builder, ainfo->type, ctx->addresses [reg], ainfo, args);
2948 if (ainfo->storage == LLVMArgVtypeInReg && MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (ainfo->type))) {
2949 /* Treat these as normal values */
2950 ctx->values [reg] = LLVMBuildLoad (builder, ctx->addresses [reg], "");
2954 case LLVMArgVtypeByVal: {
2955 ctx->addresses [reg] = LLVMGetParam (ctx->lmethod, pindex);
2957 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (ainfo->type))) {
2958 /* Treat these as normal values */
2959 ctx->values [reg] = LLVMBuildLoad (builder, ctx->addresses [reg], "");
2963 case LLVMArgVtypeByRef: {
2964 /* The argument is passed by ref */
2965 ctx->addresses [reg] = LLVMGetParam (ctx->lmethod, pindex);
2968 case LLVMArgAsIArgs: {
2969 LLVMValueRef arg = LLVMGetParam (ctx->lmethod, pindex);
2972 /* The argument is received as an array of ints, store it into the real argument */
2973 ctx->addresses [reg] = build_alloca (ctx, ainfo->type);
2975 size = mono_class_value_size (mono_class_from_mono_type (ainfo->type), NULL);
2976 if (size < SIZEOF_VOID_P) {
2977 /* The upper bits of the registers might not be valid */
2978 LLVMValueRef val = LLVMBuildExtractValue (builder, arg, 0, "");
2979 LLVMValueRef dest = convert (ctx, ctx->addresses [reg], LLVMPointerType (LLVMIntType (size * 8), 0));
2980 LLVMBuildStore (ctx->builder, LLVMBuildTrunc (builder, val, LLVMIntType (size * 8), ""), dest);
2982 LLVMBuildStore (ctx->builder, arg, convert (ctx, ctx->addresses [reg], LLVMPointerType (LLVMTypeOf (arg), 0)));
2986 case LLVMArgVtypeAsScalar:
2987 g_assert_not_reached ();
2989 case LLVMArgGsharedvtFixed: {
2990 /* These are non-gsharedvt arguments passed by ref, the rest of the IR treats them as scalars */
2991 LLVMValueRef arg = LLVMGetParam (ctx->lmethod, pindex);
2994 name = g_strdup_printf ("arg_%s", names [i]);
2996 name = g_strdup_printf ("arg_%d", i);
2998 ctx->values [reg] = LLVMBuildLoad (builder, convert (ctx, arg, LLVMPointerType (type_to_llvm_type (ctx, ainfo->type), 0)), name);
3001 case LLVMArgGsharedvtFixedVtype: {
3002 LLVMValueRef arg = LLVMGetParam (ctx->lmethod, pindex);
3005 name = g_strdup_printf ("vtype_arg_%s", names [i]);
3007 name = g_strdup_printf ("vtype_arg_%d", i);
3009 /* Non-gsharedvt vtype argument passed by ref, the rest of the IR treats it as a vtype */
3010 g_assert (ctx->addresses [reg]);
3011 LLVMSetValueName (ctx->addresses [reg], name);
3012 LLVMBuildStore (builder, LLVMBuildLoad (builder, convert (ctx, arg, LLVMPointerType (type_to_llvm_type (ctx, ainfo->type), 0)), ""), ctx->addresses [reg]);
3015 case LLVMArgGsharedvtVariable:
3016 /* The IR treats these as variables with addresses */
3017 ctx->addresses [reg] = LLVMGetParam (ctx->lmethod, pindex);
3020 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));
3027 emit_volatile_store (ctx, cfg->vret_addr->dreg);
3029 emit_volatile_store (ctx, cfg->args [0]->dreg);
3030 for (i = 0; i < sig->param_count; ++i)
3031 if (!mini_type_is_vtype (sig->params [i]))
3032 emit_volatile_store (ctx, cfg->args [i + sig->hasthis]->dreg);
3034 if (sig->hasthis && !cfg->rgctx_var && cfg->gshared) {
3035 LLVMValueRef this_alloc;
3038 * The exception handling code needs the location where the this argument was
3039 * stored for gshared methods. We create a separate alloca to hold it, and mark it
3040 * with the "mono.this" custom metadata to tell llvm that it needs to save its
3041 * location into the LSDA.
3043 this_alloc = mono_llvm_build_alloca (builder, ThisType (), LLVMConstInt (LLVMInt32Type (), 1, FALSE), 0, "");
3044 /* This volatile store will keep the alloca alive */
3045 mono_llvm_build_store (builder, ctx->values [cfg->args [0]->dreg], this_alloc, TRUE, LLVM_BARRIER_NONE);
3047 set_metadata_flag (this_alloc, "mono.this");
3050 if (cfg->rgctx_var) {
3051 LLVMValueRef rgctx_alloc, store;
3054 * We handle the rgctx arg similarly to the this pointer.
3056 g_assert (ctx->addresses [cfg->rgctx_var->dreg]);
3057 rgctx_alloc = ctx->addresses [cfg->rgctx_var->dreg];
3058 /* This volatile store will keep the alloca alive */
3059 store = mono_llvm_build_store (builder, convert (ctx, ctx->rgctx_arg, IntPtrType ()), rgctx_alloc, TRUE, LLVM_BARRIER_NONE);
3061 set_metadata_flag (rgctx_alloc, "mono.this");
3064 /* Initialize the method if needed */
3065 if (cfg->compile_aot && ctx->llvm_only) {
3066 /* Emit a location for the initialization code */
3067 ctx->init_bb = gen_bb (ctx, "INIT_BB");
3068 ctx->inited_bb = gen_bb (ctx, "INITED_BB");
3070 LLVMBuildBr (ctx->builder, ctx->init_bb);
3071 builder = ctx->builder = create_builder (ctx);
3072 LLVMPositionBuilderAtEnd (ctx->builder, ctx->inited_bb);
3073 ctx->bblocks [cfg->bb_entry->block_num].end_bblock = ctx->inited_bb;
3076 /* Compute nesting between clauses */
3077 ctx->nested_in = (GSList**)mono_mempool_alloc0 (cfg->mempool, sizeof (GSList*) * cfg->header->num_clauses);
3078 for (i = 0; i < cfg->header->num_clauses; ++i) {
3079 for (j = 0; j < cfg->header->num_clauses; ++j) {
3080 MonoExceptionClause *clause1 = &cfg->header->clauses [i];
3081 MonoExceptionClause *clause2 = &cfg->header->clauses [j];
3083 if (i != j && clause1->try_offset >= clause2->try_offset && clause1->handler_offset <= clause2->handler_offset)
3084 ctx->nested_in [i] = g_slist_prepend_mempool (cfg->mempool, ctx->nested_in [i], GINT_TO_POINTER (j));
3089 * For finally clauses, create an indicator variable telling OP_ENDFINALLY whenever
3090 * it needs to continue normally, or return back to the exception handling system.
3092 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
3096 if (!(bb->region != -1 && (bb->flags & BB_EXCEPTION_HANDLER)))
3099 clause_index = MONO_REGION_CLAUSE_INDEX (bb->region);
3100 g_hash_table_insert (ctx->region_to_handler, GUINT_TO_POINTER (mono_get_block_region_notry (cfg, bb->region)), bb);
3101 g_hash_table_insert (ctx->clause_to_handler, GINT_TO_POINTER (clause_index), bb);
3103 if (bb->in_scount == 0) {
3106 sprintf (name, "finally_ind_bb%d", bb->block_num);
3107 val = LLVMBuildAlloca (builder, LLVMInt32Type (), name);
3108 LLVMBuildStore (builder, LLVMConstInt (LLVMInt32Type (), 0, FALSE), val);
3110 ctx->bblocks [bb->block_num].finally_ind = val;
3112 /* Create a variable to hold the exception var */
3114 ctx->ex_var = LLVMBuildAlloca (builder, ObjRefType (), "exvar");
3118 * Create a new bblock which CALL_HANDLER/landing pads can branch to, because branching to the
3119 * LLVM bblock containing a landing pad causes problems for the
3120 * LLVM optimizer passes.
3122 sprintf (name, "BB%d_CALL_HANDLER_TARGET", bb->block_num);
3123 ctx->bblocks [bb->block_num].call_handler_target_bb = LLVMAppendBasicBlock (ctx->lmethod, name);
3125 ctx->builder = old_builder;
3129 process_call (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, MonoInst *ins)
3131 MonoCompile *cfg = ctx->cfg;
3132 LLVMValueRef *values = ctx->values;
3133 LLVMValueRef *addresses = ctx->addresses;
3134 MonoCallInst *call = (MonoCallInst*)ins;
3135 MonoMethodSignature *sig = call->signature;
3136 LLVMValueRef callee = NULL, lcall;
3138 LLVMCallInfo *cinfo;
3142 LLVMTypeRef llvm_sig;
3144 gboolean is_virtual, calli, preserveall;
3145 LLVMBuilderRef builder = *builder_ref;
3147 if ((call->signature->call_convention != MONO_CALL_DEFAULT) && !((call->signature->call_convention == MONO_CALL_C) && ctx->llvm_only)) {
3148 set_failure (ctx, "non-default callconv");
3152 cinfo = call->cinfo;
3154 if (call->rgctx_arg_reg)
3155 cinfo->rgctx_arg = TRUE;
3156 if (call->imt_arg_reg)
3157 cinfo->imt_arg = TRUE;
3159 vretaddr = (cinfo->ret.storage == LLVMArgVtypeRetAddr || cinfo->ret.storage == LLVMArgVtypeByRef || cinfo->ret.storage == LLVMArgGsharedvtFixed || cinfo->ret.storage == LLVMArgGsharedvtVariable || cinfo->ret.storage == LLVMArgGsharedvtFixedVtype);
3161 llvm_sig = sig_to_llvm_sig_full (ctx, sig, cinfo);
3165 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);
3166 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);
3168 preserveall = FALSE;
3170 /* FIXME: Avoid creating duplicate methods */
3172 if (ins->flags & MONO_INST_HAS_METHOD) {
3176 if (cfg->compile_aot) {
3177 callee = get_callee (ctx, llvm_sig, MONO_PATCH_INFO_METHOD, call->method);
3179 set_failure (ctx, "can't encode patch");
3182 if (cfg->llvm_only && call->method->klass->image->assembly == ctx->module->assembly) {
3184 * Collect instructions representing the callee into a hash so they can be replaced
3185 * by the llvm method for the callee if the callee turns out to be direct
3186 * callable. Currently this only requires it to not fail llvm compilation.
3188 GSList *l = (GSList*)g_hash_table_lookup (ctx->method_to_callers, call->method);
3189 l = g_slist_prepend (l, callee);
3190 g_hash_table_insert (ctx->method_to_callers, call->method, l);
3194 static int tramp_index;
3197 name = g_strdup_printf ("tramp_%d", tramp_index);
3200 #if LLVM_API_VERSION > 100
3202 * Use our trampoline infrastructure for lazy compilation instead of llvm's.
3203 * Make all calls through a global. The address of the global will be saved in
3204 * MonoJitDomainInfo.llvm_jit_callees and updated when the method it refers to is
3207 LLVMValueRef tramp_var = g_hash_table_lookup (ctx->jit_callees, call->method);
3210 mono_create_jit_trampoline (mono_domain_get (),
3211 call->method, &error);
3212 if (!is_ok (&error)) {
3213 set_failure (ctx, mono_error_get_message (&error));
3214 mono_error_cleanup (&error);
3218 tramp_var = LLVMAddGlobal (ctx->lmodule, LLVMPointerType (llvm_sig, 0), name);
3219 LLVMSetInitializer (tramp_var, LLVMConstIntToPtr (LLVMConstInt (LLVMInt64Type (), (guint64)(size_t)target, FALSE), LLVMPointerType (llvm_sig, 0)));
3220 LLVMSetLinkage (tramp_var, LLVMExternalLinkage);
3221 g_hash_table_insert (ctx->jit_callees, call->method, tramp_var);
3223 callee = LLVMBuildLoad (builder, tramp_var, "");
3226 mono_create_jit_trampoline (mono_domain_get (),
3227 call->method, &error);
3228 if (!is_ok (&error)) {
3230 set_failure (ctx, mono_error_get_message (&error));
3231 mono_error_cleanup (&error);
3235 callee = LLVMAddFunction (ctx->lmodule, name, llvm_sig);
3238 LLVMAddGlobalMapping (ctx->module->ee, callee, target);
3243 if (!cfg->llvm_only && call->method && strstr (call->method->klass->name, "AsyncVoidMethodBuilder")) {
3244 /* LLVM miscompiles async methods */
3245 set_failure (ctx, "#13734");
3250 MonoJitICallInfo *info = mono_find_jit_icall_by_addr (call->fptr);
3256 memset (&ji, 0, sizeof (ji));
3257 ji.type = MONO_PATCH_INFO_JIT_ICALL_ADDR;
3258 ji.data.target = info->name;
3260 target = mono_resolve_patch_target (cfg->method, cfg->domain, NULL, &ji, FALSE);
3262 if (cfg->compile_aot) {
3263 callee = get_callee (ctx, llvm_sig, MONO_PATCH_INFO_INTERNAL_METHOD, (char*)info->name);
3265 set_failure (ctx, "can't encode patch");
3269 target = (gpointer)mono_icall_get_wrapper (info);
3270 callee = emit_jit_callee (ctx, "", llvm_sig, target);
3273 if (cfg->compile_aot) {
3275 if (cfg->abs_patches) {
3276 MonoJumpInfo *abs_ji = (MonoJumpInfo*)g_hash_table_lookup (cfg->abs_patches, call->fptr);
3278 callee = get_callee (ctx, llvm_sig, abs_ji->type, abs_ji->data.target);
3280 set_failure (ctx, "can't encode patch");
3286 set_failure (ctx, "aot");
3290 #if LLVM_API_VERSION > 100
3291 if (cfg->abs_patches) {
3292 MonoJumpInfo *abs_ji = (MonoJumpInfo*)g_hash_table_lookup (cfg->abs_patches, call->fptr);
3296 target = mono_resolve_patch_target (cfg->method, cfg->domain, NULL, abs_ji, FALSE, &error);
3297 mono_error_assert_ok (&error);
3298 callee = emit_jit_callee (ctx, "", llvm_sig, target);
3300 g_assert_not_reached ();
3303 g_assert_not_reached ();
3306 callee = LLVMAddFunction (ctx->lmodule, "", llvm_sig);
3308 if (cfg->abs_patches) {
3309 MonoJumpInfo *abs_ji = (MonoJumpInfo*)g_hash_table_lookup (cfg->abs_patches, call->fptr);
3314 * FIXME: Some trampolines might have
3315 * their own calling convention on some platforms.
3317 target = mono_resolve_patch_target (cfg->method, cfg->domain, NULL, abs_ji, FALSE, &error);
3318 mono_error_assert_ok (&error);
3319 LLVMAddGlobalMapping (ctx->module->ee, callee, target);
3323 LLVMAddGlobalMapping (ctx->module->ee, callee, (gpointer)call->fptr);
3330 int size = sizeof (gpointer);
3333 g_assert (ins->inst_offset % size == 0);
3334 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
3336 callee = convert (ctx, LLVMBuildLoad (builder, LLVMBuildGEP (builder, convert (ctx, values [ins->inst_basereg], LLVMPointerType (LLVMPointerType (IntPtrType (), 0), 0)), &index, 1, ""), ""), LLVMPointerType (llvm_sig, 0));
3338 callee = convert (ctx, values [ins->sreg1], LLVMPointerType (llvm_sig, 0));
3340 if (ins->flags & MONO_INST_HAS_METHOD) {
3345 * Collect and convert arguments
3347 nargs = (sig->param_count * 16) + sig->hasthis + vretaddr + call->rgctx_reg + call->imt_arg_reg;
3348 len = sizeof (LLVMValueRef) * nargs;
3349 args = (LLVMValueRef*)alloca (len);
3350 memset (args, 0, len);
3351 l = call->out_ireg_args;
3353 if (call->rgctx_arg_reg) {
3354 g_assert (values [call->rgctx_arg_reg]);
3355 g_assert (cinfo->rgctx_arg_pindex < nargs);
3357 * On ARM, the imt/rgctx argument is passed in a caller save register, but some of our trampolines etc. clobber it, leading to
3358 * problems is LLVM moves the arg assignment earlier. To work around this, save the argument into a stack slot and load
3359 * it using a volatile load.
3362 if (!ctx->imt_rgctx_loc)
3363 ctx->imt_rgctx_loc = build_alloca_llvm_type (ctx, ctx->module->ptr_type, sizeof (gpointer));
3364 LLVMBuildStore (builder, convert (ctx, ctx->values [call->rgctx_arg_reg], ctx->module->ptr_type), ctx->imt_rgctx_loc);
3365 args [cinfo->rgctx_arg_pindex] = mono_llvm_build_load (builder, ctx->imt_rgctx_loc, "", TRUE);
3367 args [cinfo->rgctx_arg_pindex] = convert (ctx, values [call->rgctx_arg_reg], ctx->module->ptr_type);
3370 if (call->imt_arg_reg) {
3371 g_assert (!ctx->llvm_only);
3372 g_assert (values [call->imt_arg_reg]);
3373 g_assert (cinfo->imt_arg_pindex < nargs);
3375 if (!ctx->imt_rgctx_loc)
3376 ctx->imt_rgctx_loc = build_alloca_llvm_type (ctx, ctx->module->ptr_type, sizeof (gpointer));
3377 LLVMBuildStore (builder, convert (ctx, ctx->values [call->imt_arg_reg], ctx->module->ptr_type), ctx->imt_rgctx_loc);
3378 args [cinfo->imt_arg_pindex] = mono_llvm_build_load (builder, ctx->imt_rgctx_loc, "", TRUE);
3380 args [cinfo->imt_arg_pindex] = convert (ctx, values [call->imt_arg_reg], ctx->module->ptr_type);
3383 switch (cinfo->ret.storage) {
3384 case LLVMArgGsharedvtVariable: {
3385 MonoInst *var = get_vreg_to_inst (cfg, call->inst.dreg);
3387 if (var && var->opcode == OP_GSHAREDVT_LOCAL) {
3388 args [cinfo->vret_arg_pindex] = convert (ctx, emit_gsharedvt_ldaddr (ctx, var->dreg), IntPtrType ());
3390 g_assert (addresses [call->inst.dreg]);
3391 args [cinfo->vret_arg_pindex] = addresses [call->inst.dreg];
3397 if (!addresses [call->inst.dreg])
3398 addresses [call->inst.dreg] = build_alloca (ctx, sig->ret);
3399 g_assert (cinfo->vret_arg_pindex < nargs);
3400 if (cinfo->ret.storage == LLVMArgVtypeByRef)
3401 args [cinfo->vret_arg_pindex] = addresses [call->inst.dreg];
3403 args [cinfo->vret_arg_pindex] = LLVMBuildPtrToInt (builder, addresses [call->inst.dreg], IntPtrType (), "");
3409 * Sometimes the same method is called with two different signatures (i.e. with and without 'this'), so
3410 * use the real callee for argument type conversion.
3412 LLVMTypeRef callee_type = LLVMGetElementType (LLVMTypeOf (callee));
3413 LLVMTypeRef *param_types = (LLVMTypeRef*)g_alloca (sizeof (LLVMTypeRef) * LLVMCountParamTypes (callee_type));
3414 LLVMGetParamTypes (callee_type, param_types);
3416 for (i = 0; i < sig->param_count + sig->hasthis; ++i) {
3419 LLVMArgInfo *ainfo = &call->cinfo->args [i];
3421 pindex = ainfo->pindex;
3423 regpair = (guint32)(gssize)(l->data);
3424 reg = regpair & 0xffffff;
3425 args [pindex] = values [reg];
3426 switch (ainfo->storage) {
3427 case LLVMArgVtypeInReg:
3428 case LLVMArgAsFpArgs: {
3432 for (j = 0; j < ainfo->ndummy_fpargs; ++j)
3433 args [pindex + j] = LLVMConstNull (LLVMDoubleType ());
3434 pindex += ainfo->ndummy_fpargs;
3436 g_assert (addresses [reg]);
3437 emit_vtype_to_args (ctx, builder, ainfo->type, addresses [reg], ainfo, args + pindex, &nargs);
3441 // FIXME: Get rid of the VMOVE
3444 case LLVMArgVtypeByVal:
3445 g_assert (addresses [reg]);
3446 args [pindex] = addresses [reg];
3448 case LLVMArgVtypeByRef: {
3449 g_assert (addresses [reg]);
3450 args [pindex] = convert (ctx, addresses [reg], LLVMPointerType (type_to_llvm_arg_type (ctx, ainfo->type), 0));
3453 case LLVMArgAsIArgs:
3454 g_assert (addresses [reg]);
3455 args [pindex] = LLVMBuildLoad (ctx->builder, convert (ctx, addresses [reg], LLVMPointerType (LLVMArrayType (IntPtrType (), ainfo->nslots), 0)), "");
3457 case LLVMArgVtypeAsScalar:
3458 g_assert_not_reached ();
3460 case LLVMArgGsharedvtFixed:
3461 case LLVMArgGsharedvtFixedVtype:
3462 g_assert (addresses [reg]);
3463 args [pindex] = convert (ctx, addresses [reg], LLVMPointerType (type_to_llvm_arg_type (ctx, ainfo->type), 0));
3465 case LLVMArgGsharedvtVariable:
3466 g_assert (addresses [reg]);
3467 args [pindex] = convert (ctx, addresses [reg], LLVMPointerType (IntPtrType (), 0));
3470 g_assert (args [pindex]);
3471 if (i == 0 && sig->hasthis)
3472 args [pindex] = convert (ctx, args [pindex], param_types [pindex]);
3474 args [pindex] = convert (ctx, args [pindex], type_to_llvm_arg_type (ctx, ainfo->type));
3477 g_assert (pindex <= nargs);
3482 // FIXME: Align call sites
3488 lcall = emit_call (ctx, bb, &builder, callee, args, LLVMCountParamTypes (llvm_sig));
3491 * Modify cconv and parameter attributes to pass rgctx/imt correctly.
3493 #if defined(MONO_ARCH_IMT_REG) && defined(MONO_ARCH_RGCTX_REG)
3494 g_assert (MONO_ARCH_IMT_REG == MONO_ARCH_RGCTX_REG);
3496 /* The two can't be used together, so use only one LLVM calling conv to pass them */
3497 g_assert (!(call->rgctx_arg_reg && call->imt_arg_reg));
3498 if (!sig->pinvoke && !cfg->llvm_only)
3499 LLVMSetInstructionCallConv (lcall, LLVMMono1CallConv);
3501 mono_llvm_set_call_preserveall_cc (lcall);
3503 if (cinfo->ret.storage == LLVMArgVtypeByRef)
3504 LLVMAddInstrAttribute (lcall, 1 + cinfo->vret_arg_pindex, LLVMStructRetAttribute);
3505 if (!ctx->llvm_only && call->rgctx_arg_reg)
3506 LLVMAddInstrAttribute (lcall, 1 + cinfo->rgctx_arg_pindex, LLVMInRegAttribute);
3507 if (call->imt_arg_reg)
3508 LLVMAddInstrAttribute (lcall, 1 + cinfo->imt_arg_pindex, LLVMInRegAttribute);
3510 /* Add byval attributes if needed */
3511 for (i = 0; i < sig->param_count; ++i) {
3512 LLVMArgInfo *ainfo = &call->cinfo->args [i + sig->hasthis];
3514 if (ainfo && ainfo->storage == LLVMArgVtypeByVal)
3515 LLVMAddInstrAttribute (lcall, 1 + ainfo->pindex, LLVMByValAttribute);
3519 * Convert the result
3521 switch (cinfo->ret.storage) {
3522 case LLVMArgVtypeInReg: {
3523 LLVMValueRef regs [2];
3525 if (LLVMTypeOf (lcall) == LLVMVoidType ())
3529 if (!addresses [ins->dreg])
3530 addresses [ins->dreg] = build_alloca (ctx, sig->ret);
3532 regs [0] = LLVMBuildExtractValue (builder, lcall, 0, "");
3533 if (cinfo->ret.pair_storage [1] != LLVMArgNone)
3534 regs [1] = LLVMBuildExtractValue (builder, lcall, 1, "");
3535 emit_args_to_vtype (ctx, builder, sig->ret, addresses [ins->dreg], &cinfo->ret, regs);
3538 case LLVMArgVtypeByVal:
3539 if (!addresses [call->inst.dreg])
3540 addresses [call->inst.dreg] = build_alloca (ctx, sig->ret);
3541 LLVMBuildStore (builder, lcall, addresses [call->inst.dreg]);
3543 case LLVMArgAsIArgs:
3544 case LLVMArgFpStruct:
3545 if (!addresses [call->inst.dreg])
3546 addresses [call->inst.dreg] = build_alloca (ctx, sig->ret);
3547 LLVMBuildStore (builder, lcall, convert_full (ctx, addresses [call->inst.dreg], LLVMPointerType (LLVMTypeOf (lcall), 0), FALSE));
3549 case LLVMArgVtypeAsScalar:
3550 if (!addresses [call->inst.dreg])
3551 addresses [call->inst.dreg] = build_alloca (ctx, sig->ret);
3552 LLVMBuildStore (builder, lcall, convert_full (ctx, addresses [call->inst.dreg], LLVMPointerType (LLVMTypeOf (lcall), 0), FALSE));
3554 case LLVMArgVtypeRetAddr:
3555 case LLVMArgVtypeByRef:
3556 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (sig->ret))) {
3557 /* Some opcodes like STOREX_MEMBASE access these by value */
3558 g_assert (addresses [call->inst.dreg]);
3559 values [ins->dreg] = LLVMBuildLoad (builder, convert_full (ctx, addresses [call->inst.dreg], LLVMPointerType (type_to_llvm_type (ctx, sig->ret), 0), FALSE), "");
3562 case LLVMArgGsharedvtVariable:
3564 case LLVMArgGsharedvtFixed:
3565 case LLVMArgGsharedvtFixedVtype:
3566 values [ins->dreg] = LLVMBuildLoad (builder, convert_full (ctx, addresses [call->inst.dreg], LLVMPointerType (type_to_llvm_type (ctx, sig->ret), 0), FALSE), "");
3569 if (sig->ret->type != MONO_TYPE_VOID)
3570 /* If the method returns an unsigned value, need to zext it */
3571 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));
3575 *builder_ref = ctx->builder;
3579 emit_llvmonly_throw (EmitContext *ctx, MonoBasicBlock *bb, gboolean rethrow, LLVMValueRef exc)
3581 const char *icall_name = rethrow ? "mono_llvm_rethrow_exception" : "mono_llvm_throw_exception";
3582 LLVMValueRef callee = rethrow ? ctx->module->rethrow : ctx->module->throw_icall;
3584 LLVMTypeRef exc_type = type_to_llvm_type (ctx, &mono_get_exception_class ()->byval_arg);
3587 LLVMTypeRef fun_sig = LLVMFunctionType1 (LLVMVoidType (), exc_type, FALSE);
3589 if (ctx->cfg->compile_aot) {
3590 callee = get_callee (ctx, fun_sig, MONO_PATCH_INFO_JIT_ICALL_ADDR, icall_name);
3592 callee = LLVMAddFunction (ctx->lmodule, icall_name, fun_sig);
3593 LLVMAddGlobalMapping (ctx->module->ee, callee, resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name));
3594 mono_memory_barrier ();
3597 ctx->module->rethrow = callee;
3599 ctx->module->throw_icall = callee;
3603 LLVMValueRef args [2];
3605 args [0] = convert (ctx, exc, exc_type);
3606 emit_call (ctx, bb, &ctx->builder, callee, args, 1);
3608 LLVMBuildUnreachable (ctx->builder);
3610 ctx->builder = create_builder (ctx);
3614 emit_throw (EmitContext *ctx, MonoBasicBlock *bb, gboolean rethrow, LLVMValueRef exc)
3616 MonoMethodSignature *throw_sig;
3617 LLVMValueRef callee, arg;
3618 const char *icall_name;
3620 callee = rethrow ? ctx->module->rethrow : ctx->module->throw_icall;
3621 icall_name = rethrow ? "mono_arch_rethrow_exception" : "mono_arch_throw_exception";
3624 throw_sig = mono_metadata_signature_alloc (mono_get_corlib (), 1);
3625 throw_sig->ret = &mono_get_void_class ()->byval_arg;
3626 throw_sig->params [0] = &mono_get_object_class ()->byval_arg;
3627 if (ctx->cfg->compile_aot) {
3628 callee = get_callee (ctx, sig_to_llvm_sig (ctx, throw_sig), MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
3633 * LLVM doesn't push the exception argument, so we need a different
3636 target = resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, rethrow ? "llvm_rethrow_exception_trampoline" : "llvm_throw_exception_trampoline");
3638 target = resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
3640 callee = emit_jit_callee (ctx, icall_name, sig_to_llvm_sig (ctx, throw_sig), target);
3643 mono_memory_barrier ();
3644 #if LLVM_API_VERSION < 100
3646 ctx->module->rethrow = callee;
3648 ctx->module->throw_icall = callee;
3651 arg = convert (ctx, exc, type_to_llvm_type (ctx, &mono_get_object_class ()->byval_arg));
3652 emit_call (ctx, bb, &ctx->builder, callee, &arg, 1);
3656 emit_resume_eh (EmitContext *ctx, MonoBasicBlock *bb)
3658 const char *icall_name = "mono_llvm_resume_exception";
3659 LLVMValueRef callee = ctx->module->resume_eh;
3661 LLVMTypeRef fun_sig = LLVMFunctionType0 (LLVMVoidType (), FALSE);
3664 if (ctx->cfg->compile_aot) {
3665 callee = get_callee (ctx, fun_sig, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
3667 callee = LLVMAddFunction (ctx->lmodule, icall_name, fun_sig);
3668 LLVMAddGlobalMapping (ctx->module->ee, callee, resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name));
3669 mono_memory_barrier ();
3671 ctx->module->resume_eh = callee;
3675 emit_call (ctx, bb, &ctx->builder, callee, NULL, 0);
3677 LLVMBuildUnreachable (ctx->builder);
3679 ctx->builder = create_builder (ctx);
3683 mono_llvm_emit_clear_exception_call (EmitContext *ctx, LLVMBuilderRef builder)
3685 const char *icall_name = "mono_llvm_clear_exception";
3687 LLVMTypeRef call_sig = LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE);
3688 LLVMValueRef callee = NULL;
3691 if (ctx->cfg->compile_aot) {
3692 callee = get_callee (ctx, call_sig, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
3694 // FIXME: This is broken.
3695 callee = LLVMAddFunction (ctx->lmodule, icall_name, call_sig);
3699 g_assert (builder && callee);
3701 return LLVMBuildCall (builder, callee, NULL, 0, "");
3705 mono_llvm_emit_load_exception_call (EmitContext *ctx, LLVMBuilderRef builder)
3707 const char *icall_name = "mono_llvm_load_exception";
3709 LLVMTypeRef call_sig = LLVMFunctionType (ObjRefType (), NULL, 0, FALSE);
3710 LLVMValueRef callee = NULL;
3713 if (ctx->cfg->compile_aot) {
3714 callee = get_callee (ctx, call_sig, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
3716 // FIXME: This is broken.
3717 callee = LLVMAddFunction (ctx->lmodule, icall_name, call_sig);
3721 g_assert (builder && callee);
3723 return LLVMBuildCall (builder, callee, NULL, 0, icall_name);
3728 mono_llvm_emit_match_exception_call (EmitContext *ctx, LLVMBuilderRef builder, gint32 region_start, gint32 region_end)
3730 const char *icall_name = "mono_llvm_match_exception";
3732 ctx->builder = builder;
3734 const int num_args = 5;
3735 LLVMValueRef args [num_args];
3736 args [0] = convert (ctx, get_aotconst (ctx, MONO_PATCH_INFO_AOT_JIT_INFO, GINT_TO_POINTER (ctx->cfg->method_index)), IntPtrType ());
3737 args [1] = LLVMConstInt (LLVMInt32Type (), region_start, 0);
3738 args [2] = LLVMConstInt (LLVMInt32Type (), region_end, 0);
3739 if (ctx->cfg->rgctx_var) {
3740 LLVMValueRef rgctx_alloc = ctx->addresses [ctx->cfg->rgctx_var->dreg];
3741 g_assert (rgctx_alloc);
3742 args [3] = LLVMBuildLoad (builder, convert (ctx, rgctx_alloc, LLVMPointerType (IntPtrType (), 0)), "");
3744 args [3] = LLVMConstInt (IntPtrType (), 0, 0);
3747 args [4] = convert (ctx, ctx->this_arg, IntPtrType ());
3749 args [4] = LLVMConstInt (IntPtrType (), 0, 0);
3751 LLVMTypeRef match_sig = LLVMFunctionType5 (LLVMInt32Type (), IntPtrType (), LLVMInt32Type (), LLVMInt32Type (), IntPtrType (), IntPtrType (), FALSE);
3752 LLVMValueRef callee = ctx->module->match_exc;
3755 if (ctx->cfg->compile_aot) {
3756 ctx->builder = builder;
3757 // get_callee expects ctx->builder to be the emitting builder
3758 callee = get_callee (ctx, match_sig, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
3760 callee = ctx->module->match_exc = LLVMAddFunction (ctx->lmodule, icall_name, match_sig);
3761 LLVMAddGlobalMapping (ctx->module->ee, ctx->module->match_exc, resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name));
3762 ctx->module->match_exc = callee;
3763 mono_memory_barrier ();
3767 g_assert (builder && callee);
3769 g_assert (ctx->ex_var);
3771 return LLVMBuildCall (builder, callee, args, num_args, icall_name);
3774 // FIXME: This won't work because the code-finding makes this
3776 /*#define MONO_PERSONALITY_DEBUG*/
3778 #ifdef MONO_PERSONALITY_DEBUG
3779 static const gboolean use_debug_personality = TRUE;
3780 static const char *default_personality_name = "mono_debug_personality";
3782 static const gboolean use_debug_personality = FALSE;
3783 static const char *default_personality_name = "__gxx_personality_v0";
3787 default_cpp_lpad_exc_signature (void)
3789 static gboolean inited = FALSE;
3790 static LLVMTypeRef sig;
3793 LLVMTypeRef signature [2];
3794 signature [0] = LLVMPointerType (LLVMInt8Type (), 0);
3795 signature [1] = LLVMInt32Type ();
3796 sig = LLVMStructType (signature, 2, FALSE);
3804 get_mono_personality (EmitContext *ctx)
3806 LLVMValueRef personality = NULL;
3807 static gint32 mapping_inited = FALSE;
3808 LLVMTypeRef personality_type = LLVMFunctionType (LLVMInt32Type (), NULL, 0, TRUE);
3810 if (!use_debug_personality) {
3811 if (ctx->cfg->compile_aot) {
3812 personality = get_intrinsic (ctx, default_personality_name);
3813 } else if (InterlockedCompareExchange (&mapping_inited, 1, 0) == 0) {
3814 personality = LLVMAddFunction (ctx->lmodule, default_personality_name, personality_type);
3815 LLVMAddGlobalMapping (ctx->module->ee, personality, personality);
3818 if (ctx->cfg->compile_aot) {
3819 personality = get_callee (ctx, personality_type, MONO_PATCH_INFO_INTERNAL_METHOD, default_personality_name);
3821 personality = LLVMAddFunction (ctx->lmodule, default_personality_name, personality_type);
3822 LLVMAddGlobalMapping (ctx->module->ee, personality, resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, default_personality_name));
3823 mono_memory_barrier ();
3827 g_assert (personality);
3831 static LLVMBasicBlockRef
3832 emit_landing_pad (EmitContext *ctx, int group_index, int group_size)
3834 MonoCompile *cfg = ctx->cfg;
3835 LLVMBuilderRef old_builder = ctx->builder;
3836 MonoExceptionClause *group_start = cfg->header->clauses + group_index;
3838 LLVMBuilderRef lpadBuilder = create_builder (ctx);
3839 ctx->builder = lpadBuilder;
3841 MonoBasicBlock *handler_bb = cfg->cil_offset_to_bb [CLAUSE_START (group_start)];
3842 g_assert (handler_bb);
3844 // <resultval> = landingpad <somety> personality <type> <pers_fn> <clause>+
3845 LLVMValueRef personality = get_mono_personality (ctx);
3846 g_assert (personality);
3848 char *bb_name = g_strdup_printf ("LPAD%d_BB", group_index);
3849 LLVMBasicBlockRef lpad_bb = gen_bb (ctx, bb_name);
3851 LLVMPositionBuilderAtEnd (lpadBuilder, lpad_bb);
3852 LLVMValueRef landing_pad = LLVMBuildLandingPad (lpadBuilder, default_cpp_lpad_exc_signature (), personality, 0, "");
3853 g_assert (landing_pad);
3855 LLVMValueRef cast = LLVMBuildBitCast (lpadBuilder, ctx->module->sentinel_exception, LLVMPointerType (LLVMInt8Type (), 0), "int8TypeInfo");
3856 LLVMAddClause (landing_pad, cast);
3858 LLVMBasicBlockRef resume_bb = gen_bb (ctx, "RESUME_BB");
3859 LLVMBuilderRef resume_builder = create_builder (ctx);
3860 ctx->builder = resume_builder;
3861 LLVMPositionBuilderAtEnd (resume_builder, resume_bb);
3863 emit_resume_eh (ctx, handler_bb);
3866 ctx->builder = lpadBuilder;
3867 LLVMPositionBuilderAtEnd (lpadBuilder, lpad_bb);
3869 gboolean finally_only = TRUE;
3871 MonoExceptionClause *group_cursor = group_start;
3873 for (int i = 0; i < group_size; i ++) {
3874 if (!(group_cursor->flags & MONO_EXCEPTION_CLAUSE_FINALLY))
3875 finally_only = FALSE;
3881 // Handle landing pad inlining
3883 if (!finally_only) {
3884 // So at each level of the exception stack we will match the exception again.
3885 // During that match, we need to compare against the handler types for the current
3886 // protected region. We send the try start and end so that we can only check against
3887 // handlers for this lexical protected region.
3888 LLVMValueRef match = mono_llvm_emit_match_exception_call (ctx, lpadBuilder, group_start->try_offset, group_start->try_offset + group_start->try_len);
3890 // if returns -1, resume
3891 LLVMValueRef switch_ins = LLVMBuildSwitch (lpadBuilder, match, resume_bb, group_size);
3893 // else move to that target bb
3894 for (int i=0; i < group_size; i++) {
3895 MonoExceptionClause *clause = group_start + i;
3896 int clause_index = clause - cfg->header->clauses;
3897 MonoBasicBlock *handler_bb = (MonoBasicBlock*)g_hash_table_lookup (ctx->clause_to_handler, GINT_TO_POINTER (clause_index));
3898 g_assert (handler_bb);
3899 g_assert (ctx->bblocks [handler_bb->block_num].call_handler_target_bb);
3900 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), clause_index, FALSE), ctx->bblocks [handler_bb->block_num].call_handler_target_bb);
3903 int clause_index = group_start - cfg->header->clauses;
3904 MonoBasicBlock *finally_bb = (MonoBasicBlock*)g_hash_table_lookup (ctx->clause_to_handler, GINT_TO_POINTER (clause_index));
3905 g_assert (finally_bb);
3907 LLVMBuildBr (ctx->builder, ctx->bblocks [finally_bb->block_num].call_handler_target_bb);
3910 ctx->builder = old_builder;
3917 emit_llvmonly_handler_start (EmitContext *ctx, MonoBasicBlock *bb, LLVMBasicBlockRef cbb)
3919 int clause_index = MONO_REGION_CLAUSE_INDEX (bb->region);
3920 MonoExceptionClause *clause = &ctx->cfg->header->clauses [clause_index];
3922 // Make exception available to catch blocks
3923 if (!(clause->flags & MONO_EXCEPTION_CLAUSE_FINALLY)) {
3924 LLVMValueRef mono_exc = mono_llvm_emit_load_exception_call (ctx, ctx->builder);
3926 g_assert (ctx->ex_var);
3927 LLVMBuildStore (ctx->builder, LLVMBuildBitCast (ctx->builder, mono_exc, ObjRefType (), ""), ctx->ex_var);
3929 if (bb->in_scount == 1) {
3930 MonoInst *exvar = bb->in_stack [0];
3931 g_assert (!ctx->values [exvar->dreg]);
3932 g_assert (ctx->ex_var);
3933 ctx->values [exvar->dreg] = LLVMBuildLoad (ctx->builder, ctx->ex_var, "save_exception");
3934 emit_volatile_store (ctx, exvar->dreg);
3937 mono_llvm_emit_clear_exception_call (ctx, ctx->builder);
3940 LLVMBuilderRef handler_builder = create_builder (ctx);
3941 LLVMBasicBlockRef target_bb = ctx->bblocks [bb->block_num].call_handler_target_bb;
3942 LLVMPositionBuilderAtEnd (handler_builder, target_bb);
3944 // Make the handler code end with a jump to cbb
3945 LLVMBuildBr (handler_builder, cbb);
3949 emit_handler_start (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef builder)
3951 MonoCompile *cfg = ctx->cfg;
3952 LLVMValueRef *values = ctx->values;
3953 LLVMModuleRef lmodule = ctx->lmodule;
3954 BBInfo *bblocks = ctx->bblocks;
3956 LLVMValueRef personality;
3957 LLVMValueRef landing_pad;
3958 LLVMBasicBlockRef target_bb;
3960 static int ti_generator;
3962 LLVMValueRef type_info;
3966 // <resultval> = landingpad <somety> personality <type> <pers_fn> <clause>+
3968 if (cfg->compile_aot) {
3969 /* Use a dummy personality function */
3970 personality = LLVMGetNamedFunction (lmodule, "mono_personality");
3971 g_assert (personality);
3973 #if LLVM_API_VERSION > 100
3974 personality = ctx->module->personality;
3976 LLVMTypeRef personality_type = LLVMFunctionType (LLVMInt32Type (), NULL, 0, TRUE);
3977 personality = LLVMAddFunction (ctx->lmodule, "mono_personality", personality_type);
3978 LLVMAddFunctionAttr (personality, LLVMNoUnwindAttribute);
3979 LLVMBasicBlockRef entry_bb = LLVMAppendBasicBlock (personality, "ENTRY");
3980 LLVMBuilderRef builder2 = LLVMCreateBuilder ();
3981 LLVMPositionBuilderAtEnd (builder2, entry_bb);
3982 LLVMBuildRet (builder2, LLVMConstInt (LLVMInt32Type (), 0, FALSE));
3983 ctx->module->personality = personality;
3984 LLVMDisposeBuilder (builder2);
3987 static gint32 mapping_inited;
3989 personality = LLVMGetNamedFunction (lmodule, "mono_personality");
3991 if (InterlockedCompareExchange (&mapping_inited, 1, 0) == 0)
3992 LLVMAddGlobalMapping (ctx->module->ee, personality, (gpointer)mono_personality);
3996 i8ptr = LLVMPointerType (LLVMInt8Type (), 0);
3998 clause_index = (mono_get_block_region_notry (cfg, bb->region) >> 8) - 1;
4001 * Create the type info
4003 sprintf (ti_name, "type_info_%d", ti_generator);
4006 if (cfg->compile_aot) {
4007 /* decode_eh_frame () in aot-runtime.c will decode this */
4008 type_info = LLVMAddGlobal (lmodule, LLVMInt32Type (), ti_name);
4009 LLVMSetInitializer (type_info, LLVMConstInt (LLVMInt32Type (), clause_index, FALSE));
4012 * These symbols are not really used, the clause_index is embedded into the EH tables generated by DwarfMonoException in LLVM.
4014 LLVMSetLinkage (type_info, LLVMInternalLinkage);
4016 #if LLVM_API_VERSION > 100
4017 type_info = LLVMAddGlobal (lmodule, LLVMInt32Type (), ti_name);
4018 LLVMSetInitializer (type_info, LLVMConstInt (LLVMInt32Type (), clause_index, FALSE));
4023 * After the cfg mempool is freed, the type info will point to stale memory,
4024 * but this is not a problem, since we decode it once in exception_cb during
4027 ti = (gint32*)mono_mempool_alloc (cfg->mempool, sizeof (gint32));
4028 *(gint32*)ti = clause_index;
4030 type_info = LLVMAddGlobal (lmodule, i8ptr, ti_name);
4032 LLVMAddGlobalMapping (ctx->module->ee, type_info, ti);
4037 LLVMTypeRef members [2], ret_type;
4039 members [0] = i8ptr;
4040 members [1] = LLVMInt32Type ();
4041 ret_type = LLVMStructType (members, 2, FALSE);
4043 landing_pad = LLVMBuildLandingPad (builder, ret_type, personality, 1, "");
4044 LLVMAddClause (landing_pad, type_info);
4046 /* Store the exception into the exvar */
4048 LLVMBuildStore (builder, convert (ctx, LLVMBuildExtractValue (builder, landing_pad, 0, "ex_obj"), ObjRefType ()), ctx->ex_var);
4052 * LLVM throw sites are associated with a one landing pad, and LLVM generated
4053 * code expects control to be transferred to this landing pad even in the
4054 * presence of nested clauses. The landing pad needs to branch to the landing
4055 * pads belonging to nested clauses based on the selector value returned by
4056 * the landing pad instruction, which is passed to the landing pad in a
4057 * register by the EH code.
4059 target_bb = bblocks [bb->block_num].call_handler_target_bb;
4060 g_assert (target_bb);
4063 * Branch to the correct landing pad
4065 LLVMValueRef ex_selector = LLVMBuildExtractValue (builder, landing_pad, 1, "ex_selector");
4066 LLVMValueRef switch_ins = LLVMBuildSwitch (builder, ex_selector, target_bb, 0);
4068 for (l = ctx->nested_in [clause_index]; l; l = l->next) {
4069 int nesting_clause_index = GPOINTER_TO_INT (l->data);
4070 MonoBasicBlock *handler_bb;
4072 handler_bb = (MonoBasicBlock*)g_hash_table_lookup (ctx->clause_to_handler, GINT_TO_POINTER (nesting_clause_index));
4073 g_assert (handler_bb);
4075 g_assert (ctx->bblocks [handler_bb->block_num].call_handler_target_bb);
4076 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), nesting_clause_index, FALSE), ctx->bblocks [handler_bb->block_num].call_handler_target_bb);
4079 /* Start a new bblock which CALL_HANDLER can branch to */
4080 target_bb = bblocks [bb->block_num].call_handler_target_bb;
4082 ctx->builder = builder = create_builder (ctx);
4083 LLVMPositionBuilderAtEnd (ctx->builder, target_bb);
4085 ctx->bblocks [bb->block_num].end_bblock = target_bb;
4087 /* Store the exception into the IL level exvar */
4088 if (bb->in_scount == 1) {
4089 g_assert (bb->in_scount == 1);
4090 exvar = bb->in_stack [0];
4092 // FIXME: This is shared with filter clauses ?
4093 g_assert (!values [exvar->dreg]);
4095 g_assert (ctx->ex_var);
4096 values [exvar->dreg] = LLVMBuildLoad (builder, ctx->ex_var, "");
4097 emit_volatile_store (ctx, exvar->dreg);
4103 process_bb (EmitContext *ctx, MonoBasicBlock *bb)
4105 MonoCompile *cfg = ctx->cfg;
4106 MonoMethodSignature *sig = ctx->sig;
4107 LLVMValueRef method = ctx->lmethod;
4108 LLVMValueRef *values = ctx->values;
4109 LLVMValueRef *addresses = ctx->addresses;
4110 LLVMCallInfo *linfo = ctx->linfo;
4111 BBInfo *bblocks = ctx->bblocks;
4113 LLVMBasicBlockRef cbb;
4114 LLVMBuilderRef builder, starting_builder;
4115 gboolean has_terminator;
4117 LLVMValueRef lhs, rhs;
4120 cbb = get_end_bb (ctx, bb);
4122 builder = create_builder (ctx);
4123 ctx->builder = builder;
4124 LLVMPositionBuilderAtEnd (builder, cbb);
4129 if (bb->flags & BB_EXCEPTION_HANDLER) {
4130 if (!ctx->llvm_only && !bblocks [bb->block_num].invoke_target) {
4131 set_failure (ctx, "handler without invokes");
4136 emit_llvmonly_handler_start (ctx, bb, cbb);
4138 emit_handler_start (ctx, bb, builder);
4141 builder = ctx->builder;
4144 has_terminator = FALSE;
4145 starting_builder = builder;
4146 for (ins = bb->code; ins; ins = ins->next) {
4147 const char *spec = LLVM_INS_INFO (ins->opcode);
4149 char dname_buf [128];
4151 emit_dbg_loc (ctx, builder, ins->cil_code);
4156 * Some steps in llc are non-linear in the size of basic blocks, see #5714.
4157 * Start a new bblock.
4158 * Prevent the bblocks to be merged by doing a volatile load + cond branch
4159 * from localloc-ed memory.
4161 if (!cfg->llvm_only)
4162 ;//set_failure (ctx, "basic block too long");
4164 if (!ctx->long_bb_break_var) {
4165 ctx->long_bb_break_var = build_alloca_llvm_type_name (ctx, LLVMInt32Type (), 0, "long_bb_break");
4166 mono_llvm_build_store (ctx->alloca_builder, LLVMConstInt (LLVMInt32Type (), 0, FALSE), ctx->long_bb_break_var, TRUE, LLVM_BARRIER_NONE);
4169 cbb = gen_bb (ctx, "CONT_LONG_BB");
4170 LLVMBasicBlockRef dummy_bb = gen_bb (ctx, "CONT_LONG_BB_DUMMY");
4172 LLVMValueRef load = mono_llvm_build_load (builder, ctx->long_bb_break_var, "", TRUE);
4174 * The long_bb_break_var is initialized to 0 in the prolog, so this branch will always go to 'cbb'
4175 * but llvm doesn't know that, so the branch is not going to be eliminated.
4177 LLVMValueRef cmp = LLVMBuildICmp (builder, LLVMIntEQ, load, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
4179 LLVMBuildCondBr (builder, cmp, cbb, dummy_bb);
4181 /* Emit a dummy false bblock which does nothing but contains a volatile store so it cannot be eliminated */
4182 ctx->builder = builder = create_builder (ctx);
4183 LLVMPositionBuilderAtEnd (builder, dummy_bb);
4184 mono_llvm_build_store (builder, LLVMConstInt (LLVMInt32Type (), 1, FALSE), ctx->long_bb_break_var, TRUE, LLVM_BARRIER_NONE);
4185 LLVMBuildBr (builder, cbb);
4187 ctx->builder = builder = create_builder (ctx);
4188 LLVMPositionBuilderAtEnd (builder, cbb);
4189 ctx->bblocks [bb->block_num].end_bblock = cbb;
4194 /* There could be instructions after a terminator, skip them */
4197 if (spec [MONO_INST_DEST] != ' ' && !MONO_IS_STORE_MEMBASE (ins)) {
4198 sprintf (dname_buf, "t%d", ins->dreg);
4202 if (spec [MONO_INST_SRC1] != ' ' && spec [MONO_INST_SRC1] != 'v') {
4203 MonoInst *var = get_vreg_to_inst (cfg, ins->sreg1);
4205 if (var && var->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT) && var->opcode != OP_GSHAREDVT_ARG_REGOFFSET) {
4206 lhs = emit_volatile_load (ctx, ins->sreg1);
4208 /* It is ok for SETRET to have an uninitialized argument */
4209 if (!values [ins->sreg1] && ins->opcode != OP_SETRET) {
4210 set_failure (ctx, "sreg1");
4213 lhs = values [ins->sreg1];
4219 if (spec [MONO_INST_SRC2] != ' ' && spec [MONO_INST_SRC2] != ' ') {
4220 MonoInst *var = get_vreg_to_inst (cfg, ins->sreg2);
4221 if (var && var->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT)) {
4222 rhs = emit_volatile_load (ctx, ins->sreg2);
4224 if (!values [ins->sreg2]) {
4225 set_failure (ctx, "sreg2");
4228 rhs = values [ins->sreg2];
4234 //mono_print_ins (ins);
4235 switch (ins->opcode) {
4238 case OP_LIVERANGE_START:
4239 case OP_LIVERANGE_END:
4242 values [ins->dreg] = LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE);
4245 #if SIZEOF_VOID_P == 4
4246 values [ins->dreg] = LLVMConstInt (LLVMInt64Type (), GET_LONG_IMM (ins), FALSE);
4248 values [ins->dreg] = LLVMConstInt (LLVMInt64Type (), (gint64)ins->inst_c0, FALSE);
4252 values [ins->dreg] = LLVMConstReal (LLVMDoubleType (), *(double*)ins->inst_p0);
4256 values [ins->dreg] = LLVMConstReal (LLVMFloatType (), *(float*)ins->inst_p0);
4258 values [ins->dreg] = LLVMConstFPExt (LLVMConstReal (LLVMFloatType (), *(float*)ins->inst_p0), LLVMDoubleType ());
4260 case OP_DUMMY_ICONST:
4261 values [ins->dreg] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
4263 case OP_DUMMY_I8CONST:
4264 values [ins->dreg] = LLVMConstInt (LLVMInt64Type (), 0, FALSE);
4266 case OP_DUMMY_R8CONST:
4267 values [ins->dreg] = LLVMConstReal (LLVMDoubleType (), 0.0f);
4270 LLVMBasicBlockRef target_bb = get_bb (ctx, ins->inst_target_bb);
4271 LLVMBuildBr (builder, target_bb);
4272 has_terminator = TRUE;
4279 LLVMBasicBlockRef new_bb;
4280 LLVMBuilderRef new_builder;
4282 // The default branch is already handled
4283 // FIXME: Handle it here
4285 /* Start new bblock */
4286 sprintf (bb_name, "SWITCH_DEFAULT_BB%d", ctx->default_index ++);
4287 new_bb = LLVMAppendBasicBlock (ctx->lmethod, bb_name);
4289 lhs = convert (ctx, lhs, LLVMInt32Type ());
4290 v = LLVMBuildSwitch (builder, lhs, new_bb, GPOINTER_TO_UINT (ins->klass));
4291 for (i = 0; i < GPOINTER_TO_UINT (ins->klass); ++i) {
4292 MonoBasicBlock *target_bb = ins->inst_many_bb [i];
4294 LLVMAddCase (v, LLVMConstInt (LLVMInt32Type (), i, FALSE), get_bb (ctx, target_bb));
4297 new_builder = create_builder (ctx);
4298 LLVMPositionBuilderAtEnd (new_builder, new_bb);
4299 LLVMBuildUnreachable (new_builder);
4301 has_terminator = TRUE;
4302 g_assert (!ins->next);
4308 switch (linfo->ret.storage) {
4309 case LLVMArgVtypeInReg: {
4310 LLVMTypeRef ret_type = LLVMGetReturnType (LLVMGetElementType (LLVMTypeOf (method)));
4311 LLVMValueRef val, addr, retval;
4314 retval = LLVMGetUndef (ret_type);
4316 if (!addresses [ins->sreg1]) {
4318 * The return type is an LLVM vector type, have to convert between it and the
4319 * real return type which is a struct type.
4321 g_assert (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (sig->ret)));
4322 /* Convert to 2xi64 first */
4323 val = LLVMBuildBitCast (builder, values [ins->sreg1], LLVMVectorType (IntPtrType (), 2), "");
4325 for (i = 0; i < 2; ++i) {
4326 if (linfo->ret.pair_storage [i] == LLVMArgInIReg) {
4327 retval = LLVMBuildInsertValue (builder, retval, LLVMBuildExtractElement (builder, val, LLVMConstInt (LLVMInt32Type (), i, FALSE), ""), i, "");
4329 g_assert (linfo->ret.pair_storage [i] == LLVMArgNone);
4333 addr = LLVMBuildBitCast (builder, addresses [ins->sreg1], LLVMPointerType (ret_type, 0), "");
4334 for (i = 0; i < 2; ++i) {
4335 if (linfo->ret.pair_storage [i] == LLVMArgInIReg) {
4336 LLVMValueRef indexes [2], part_addr;
4338 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
4339 indexes [1] = LLVMConstInt (LLVMInt32Type (), i, FALSE);
4340 part_addr = LLVMBuildGEP (builder, addr, indexes, 2, "");
4342 retval = LLVMBuildInsertValue (builder, retval, LLVMBuildLoad (builder, part_addr, ""), i, "");
4344 g_assert (linfo->ret.pair_storage [i] == LLVMArgNone);
4348 LLVMBuildRet (builder, retval);
4351 case LLVMArgVtypeAsScalar: {
4352 LLVMTypeRef ret_type = LLVMGetReturnType (LLVMGetElementType (LLVMTypeOf (method)));
4353 LLVMValueRef retval;
4355 g_assert (addresses [ins->sreg1]);
4357 retval = LLVMBuildLoad (builder, LLVMBuildBitCast (builder, addresses [ins->sreg1], LLVMPointerType (ret_type, 0), ""), "");
4358 LLVMBuildRet (builder, retval);
4361 case LLVMArgVtypeByVal: {
4362 LLVMValueRef retval;
4364 g_assert (addresses [ins->sreg1]);
4365 retval = LLVMBuildLoad (builder, addresses [ins->sreg1], "");
4366 LLVMBuildRet (builder, retval);
4369 case LLVMArgVtypeByRef: {
4370 LLVMBuildRetVoid (builder);
4373 case LLVMArgGsharedvtFixed: {
4374 LLVMTypeRef ret_type = type_to_llvm_type (ctx, sig->ret);
4375 /* The return value is in lhs, need to store to the vret argument */
4376 /* sreg1 might not be set */
4378 g_assert (cfg->vret_addr);
4379 g_assert (values [cfg->vret_addr->dreg]);
4380 LLVMBuildStore (builder, convert (ctx, lhs, ret_type), convert (ctx, values [cfg->vret_addr->dreg], LLVMPointerType (ret_type, 0)));
4382 LLVMBuildRetVoid (builder);
4385 case LLVMArgGsharedvtFixedVtype: {
4387 LLVMBuildRetVoid (builder);
4390 case LLVMArgGsharedvtVariable: {
4392 LLVMBuildRetVoid (builder);
4395 case LLVMArgVtypeRetAddr: {
4396 LLVMBuildRetVoid (builder);
4399 case LLVMArgAsIArgs:
4400 case LLVMArgFpStruct: {
4401 LLVMTypeRef ret_type = LLVMGetReturnType (LLVMGetElementType (LLVMTypeOf (method)));
4402 LLVMValueRef retval;
4404 g_assert (addresses [ins->sreg1]);
4405 retval = LLVMBuildLoad (builder, convert (ctx, addresses [ins->sreg1], LLVMPointerType (ret_type, 0)), "");
4406 LLVMBuildRet (builder, retval);
4410 case LLVMArgNormal: {
4411 if (!lhs || ctx->is_dead [ins->sreg1]) {
4413 * The method did not set its return value, probably because it
4414 * ends with a throw.
4417 LLVMBuildRetVoid (builder);
4419 LLVMBuildRet (builder, LLVMConstNull (type_to_llvm_type (ctx, sig->ret)));
4421 LLVMBuildRet (builder, convert (ctx, lhs, type_to_llvm_type (ctx, sig->ret)));
4423 has_terminator = TRUE;
4427 g_assert_not_reached ();
4436 case OP_ICOMPARE_IMM:
4437 case OP_LCOMPARE_IMM:
4438 case OP_COMPARE_IMM: {
4440 LLVMValueRef cmp, args [16];
4441 gboolean likely = (ins->flags & MONO_INST_LIKELY) != 0;
4443 if (ins->next->opcode == OP_NOP)
4446 if (ins->next->opcode == OP_BR)
4447 /* The comparison result is not needed */
4450 rel = mono_opcode_to_cond (ins->next->opcode);
4452 if (ins->opcode == OP_ICOMPARE_IMM) {
4453 lhs = convert (ctx, lhs, LLVMInt32Type ());
4454 rhs = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
4456 if (ins->opcode == OP_LCOMPARE_IMM) {
4457 lhs = convert (ctx, lhs, LLVMInt64Type ());
4458 rhs = LLVMConstInt (LLVMInt64Type (), GET_LONG_IMM (ins), FALSE);
4460 if (ins->opcode == OP_LCOMPARE) {
4461 lhs = convert (ctx, lhs, LLVMInt64Type ());
4462 rhs = convert (ctx, rhs, LLVMInt64Type ());
4464 if (ins->opcode == OP_ICOMPARE) {
4465 lhs = convert (ctx, lhs, LLVMInt32Type ());
4466 rhs = convert (ctx, rhs, LLVMInt32Type ());
4470 if (LLVMGetTypeKind (LLVMTypeOf (lhs)) == LLVMPointerTypeKind)
4471 rhs = convert (ctx, rhs, LLVMTypeOf (lhs));
4472 else if (LLVMGetTypeKind (LLVMTypeOf (rhs)) == LLVMPointerTypeKind)
4473 lhs = convert (ctx, lhs, LLVMTypeOf (rhs));
4476 /* We use COMPARE+SETcc/Bcc, llvm uses SETcc+br cond */
4477 if (ins->opcode == OP_FCOMPARE) {
4478 cmp = LLVMBuildFCmp (builder, fpcond_to_llvm_cond [rel], convert (ctx, lhs, LLVMDoubleType ()), convert (ctx, rhs, LLVMDoubleType ()), "");
4479 } else if (ins->opcode == OP_RCOMPARE) {
4480 cmp = LLVMBuildFCmp (builder, fpcond_to_llvm_cond [rel], convert (ctx, lhs, LLVMFloatType ()), convert (ctx, rhs, LLVMFloatType ()), "");
4481 } else if (ins->opcode == OP_COMPARE_IMM) {
4482 if (LLVMGetTypeKind (LLVMTypeOf (lhs)) == LLVMPointerTypeKind && ins->inst_imm == 0)
4483 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], lhs, LLVMConstNull (LLVMTypeOf (lhs)), "");
4485 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE), "");
4486 } else if (ins->opcode == OP_LCOMPARE_IMM) {
4487 if (SIZEOF_REGISTER == 4 && COMPILE_LLVM (cfg)) {
4488 /* The immediate is encoded in two fields */
4489 guint64 l = ((guint64)(guint32)ins->inst_offset << 32) | ((guint32)ins->inst_imm);
4490 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, LLVMInt64Type ()), LLVMConstInt (LLVMInt64Type (), l, FALSE), "");
4492 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, LLVMInt64Type ()), LLVMConstInt (LLVMInt64Type (), ins->inst_imm, FALSE), "");
4495 else if (ins->opcode == OP_COMPARE) {
4496 if (LLVMGetTypeKind (LLVMTypeOf (lhs)) == LLVMPointerTypeKind && LLVMTypeOf (lhs) == LLVMTypeOf (rhs))
4497 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], lhs, rhs, "");
4499 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, IntPtrType ()), convert (ctx, rhs, IntPtrType ()), "");
4501 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], lhs, rhs, "");
4505 args [1] = LLVMConstInt (LLVMInt1Type (), 1, FALSE);
4506 cmp = LLVMBuildCall (ctx->builder, get_intrinsic (ctx, "llvm.expect.i1"), args, 2, "");
4509 if (MONO_IS_COND_BRANCH_OP (ins->next)) {
4510 if (ins->next->inst_true_bb == ins->next->inst_false_bb) {
4512 * If the target bb contains PHI instructions, LLVM requires
4513 * two PHI entries for this bblock, while we only generate one.
4514 * So convert this to an unconditional bblock. (bxc #171).
4516 LLVMBuildBr (builder, get_bb (ctx, ins->next->inst_true_bb));
4518 LLVMBuildCondBr (builder, cmp, get_bb (ctx, ins->next->inst_true_bb), get_bb (ctx, ins->next->inst_false_bb));
4520 has_terminator = TRUE;
4521 } else if (MONO_IS_SETCC (ins->next)) {
4522 sprintf (dname_buf, "t%d", ins->next->dreg);
4524 values [ins->next->dreg] = LLVMBuildZExt (builder, cmp, LLVMInt32Type (), dname);
4526 /* Add stores for volatile variables */
4527 emit_volatile_store (ctx, ins->next->dreg);
4528 } else if (MONO_IS_COND_EXC (ins->next)) {
4529 emit_cond_system_exception (ctx, bb, (const char*)ins->next->inst_p1, cmp);
4532 builder = ctx->builder;
4534 set_failure (ctx, "next");
4552 rel = mono_opcode_to_cond (ins->opcode);
4554 cmp = LLVMBuildFCmp (builder, fpcond_to_llvm_cond [rel], convert (ctx, lhs, LLVMDoubleType ()), convert (ctx, rhs, LLVMDoubleType ()), "");
4555 values [ins->dreg] = LLVMBuildZExt (builder, cmp, LLVMInt32Type (), dname);
4566 rel = mono_opcode_to_cond (ins->opcode);
4568 cmp = LLVMBuildFCmp (builder, fpcond_to_llvm_cond [rel], convert (ctx, lhs, LLVMFloatType ()), convert (ctx, rhs, LLVMFloatType ()), "");
4569 values [ins->dreg] = LLVMBuildZExt (builder, cmp, LLVMInt32Type (), dname);
4577 gboolean empty = TRUE;
4579 /* Check that all input bblocks really branch to us */
4580 for (i = 0; i < bb->in_count; ++i) {
4581 if (bb->in_bb [i]->last_ins && bb->in_bb [i]->last_ins->opcode == OP_NOT_REACHED)
4582 ins->inst_phi_args [i + 1] = -1;
4588 /* LLVM doesn't like phi instructions with zero operands */
4589 ctx->is_dead [ins->dreg] = TRUE;
4593 /* Created earlier, insert it now */
4594 LLVMInsertIntoBuilder (builder, values [ins->dreg]);
4596 for (i = 0; i < ins->inst_phi_args [0]; i++) {
4597 int sreg1 = ins->inst_phi_args [i + 1];
4601 * Count the number of times the incoming bblock branches to us,
4602 * since llvm requires a separate entry for each.
4604 if (bb->in_bb [i]->last_ins && bb->in_bb [i]->last_ins->opcode == OP_SWITCH) {
4605 MonoInst *switch_ins = bb->in_bb [i]->last_ins;
4608 for (j = 0; j < GPOINTER_TO_UINT (switch_ins->klass); ++j) {
4609 if (switch_ins->inst_many_bb [j] == bb)
4616 /* Remember for later */
4617 for (j = 0; j < count; ++j) {
4618 PhiNode *node = (PhiNode*)mono_mempool_alloc0 (ctx->mempool, sizeof (PhiNode));
4621 node->in_bb = bb->in_bb [i];
4623 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);
4633 values [ins->dreg] = lhs;
4637 MonoInst *var = get_vreg_to_inst (cfg, ins->dreg);
4640 values [ins->dreg] = lhs;
4642 if (var && var->klass->byval_arg.type == MONO_TYPE_R4) {
4644 * This is added by the spilling pass in case of the JIT,
4645 * but we have to do it ourselves.
4647 values [ins->dreg] = convert (ctx, values [ins->dreg], LLVMFloatType ());
4651 case OP_MOVE_F_TO_I4: {
4652 values [ins->dreg] = LLVMBuildBitCast (builder, LLVMBuildFPTrunc (builder, lhs, LLVMFloatType (), ""), LLVMInt32Type (), "");
4655 case OP_MOVE_I4_TO_F: {
4656 values [ins->dreg] = LLVMBuildFPExt (builder, LLVMBuildBitCast (builder, lhs, LLVMFloatType (), ""), LLVMDoubleType (), "");
4659 case OP_MOVE_F_TO_I8: {
4660 values [ins->dreg] = LLVMBuildBitCast (builder, lhs, LLVMInt64Type (), "");
4663 case OP_MOVE_I8_TO_F: {
4664 values [ins->dreg] = LLVMBuildBitCast (builder, lhs, LLVMDoubleType (), "");
4697 lhs = convert (ctx, lhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
4698 rhs = convert (ctx, rhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
4700 emit_div_check (ctx, builder, bb, ins, lhs, rhs);
4703 builder = ctx->builder;
4705 switch (ins->opcode) {
4708 values [ins->dreg] = LLVMBuildAdd (builder, lhs, rhs, dname);
4712 values [ins->dreg] = LLVMBuildSub (builder, lhs, rhs, dname);
4716 values [ins->dreg] = LLVMBuildMul (builder, lhs, rhs, dname);
4720 values [ins->dreg] = LLVMBuildSRem (builder, lhs, rhs, dname);
4724 values [ins->dreg] = LLVMBuildURem (builder, lhs, rhs, dname);
4728 values [ins->dreg] = LLVMBuildSDiv (builder, lhs, rhs, dname);
4732 values [ins->dreg] = LLVMBuildUDiv (builder, lhs, rhs, dname);
4736 values [ins->dreg] = LLVMBuildFDiv (builder, lhs, rhs, dname);
4740 values [ins->dreg] = LLVMBuildAnd (builder, lhs, rhs, dname);
4744 values [ins->dreg] = LLVMBuildOr (builder, lhs, rhs, dname);
4748 values [ins->dreg] = LLVMBuildXor (builder, lhs, rhs, dname);
4752 values [ins->dreg] = LLVMBuildShl (builder, lhs, rhs, dname);
4756 values [ins->dreg] = LLVMBuildAShr (builder, lhs, rhs, dname);
4760 values [ins->dreg] = LLVMBuildLShr (builder, lhs, rhs, dname);
4764 values [ins->dreg] = LLVMBuildFAdd (builder, lhs, rhs, dname);
4767 values [ins->dreg] = LLVMBuildFSub (builder, lhs, rhs, dname);
4770 values [ins->dreg] = LLVMBuildFMul (builder, lhs, rhs, dname);
4774 g_assert_not_reached ();
4781 lhs = convert (ctx, lhs, LLVMFloatType ());
4782 rhs = convert (ctx, rhs, LLVMFloatType ());
4783 switch (ins->opcode) {
4785 values [ins->dreg] = LLVMBuildFAdd (builder, lhs, rhs, dname);
4788 values [ins->dreg] = LLVMBuildFSub (builder, lhs, rhs, dname);
4791 values [ins->dreg] = LLVMBuildFMul (builder, lhs, rhs, dname);
4794 values [ins->dreg] = LLVMBuildFDiv (builder, lhs, rhs, dname);
4797 g_assert_not_reached ();
4806 case OP_IREM_UN_IMM:
4808 case OP_IDIV_UN_IMM:
4814 case OP_ISHR_UN_IMM:
4824 case OP_LSHR_UN_IMM:
4830 case OP_SHR_UN_IMM: {
4833 if (spec [MONO_INST_SRC1] == 'l') {
4834 imm = LLVMConstInt (LLVMInt64Type (), GET_LONG_IMM (ins), FALSE);
4836 imm = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
4839 emit_div_check (ctx, builder, bb, ins, lhs, imm);
4842 builder = ctx->builder;
4844 #if SIZEOF_VOID_P == 4
4845 if (ins->opcode == OP_LSHL_IMM || ins->opcode == OP_LSHR_IMM || ins->opcode == OP_LSHR_UN_IMM)
4846 imm = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
4849 if (LLVMGetTypeKind (LLVMTypeOf (lhs)) == LLVMPointerTypeKind)
4850 lhs = convert (ctx, lhs, IntPtrType ());
4851 imm = convert (ctx, imm, LLVMTypeOf (lhs));
4852 switch (ins->opcode) {
4856 values [ins->dreg] = LLVMBuildAdd (builder, lhs, imm, dname);
4860 values [ins->dreg] = LLVMBuildSub (builder, lhs, imm, dname);
4865 values [ins->dreg] = LLVMBuildMul (builder, lhs, imm, dname);
4869 values [ins->dreg] = LLVMBuildSDiv (builder, lhs, imm, dname);
4871 case OP_IDIV_UN_IMM:
4872 case OP_LDIV_UN_IMM:
4873 values [ins->dreg] = LLVMBuildUDiv (builder, lhs, imm, dname);
4877 values [ins->dreg] = LLVMBuildSRem (builder, lhs, imm, dname);
4879 case OP_IREM_UN_IMM:
4880 values [ins->dreg] = LLVMBuildURem (builder, lhs, imm, dname);
4885 values [ins->dreg] = LLVMBuildAnd (builder, lhs, imm, dname);
4889 values [ins->dreg] = LLVMBuildOr (builder, lhs, imm, dname);
4893 values [ins->dreg] = LLVMBuildXor (builder, lhs, imm, dname);
4898 values [ins->dreg] = LLVMBuildShl (builder, lhs, imm, dname);
4903 values [ins->dreg] = LLVMBuildAShr (builder, lhs, imm, dname);
4905 case OP_ISHR_UN_IMM:
4906 /* This is used to implement conv.u4, so the lhs could be an i8 */
4907 lhs = convert (ctx, lhs, LLVMInt32Type ());
4908 imm = convert (ctx, imm, LLVMInt32Type ());
4909 values [ins->dreg] = LLVMBuildLShr (builder, lhs, imm, dname);
4911 case OP_LSHR_UN_IMM:
4913 values [ins->dreg] = LLVMBuildLShr (builder, lhs, imm, dname);
4916 g_assert_not_reached ();
4921 values [ins->dreg] = LLVMBuildSub (builder, LLVMConstInt (LLVMInt32Type (), 0, FALSE), convert (ctx, lhs, LLVMInt32Type ()), dname);
4924 values [ins->dreg] = LLVMBuildSub (builder, LLVMConstInt (LLVMInt64Type (), 0, FALSE), lhs, dname);
4927 lhs = convert (ctx, lhs, LLVMDoubleType ());
4928 values [ins->dreg] = LLVMBuildFSub (builder, LLVMConstReal (LLVMDoubleType (), 0.0), lhs, dname);
4931 lhs = convert (ctx, lhs, LLVMFloatType ());
4932 values [ins->dreg] = LLVMBuildFSub (builder, LLVMConstReal (LLVMFloatType (), 0.0), lhs, dname);
4935 guint32 v = 0xffffffff;
4936 values [ins->dreg] = LLVMBuildXor (builder, LLVMConstInt (LLVMInt32Type (), v, FALSE), convert (ctx, lhs, LLVMInt32Type ()), dname);
4940 guint64 v = 0xffffffffffffffffLL;
4941 values [ins->dreg] = LLVMBuildXor (builder, LLVMConstInt (LLVMInt64Type (), v, FALSE), lhs, dname);
4944 #if defined(TARGET_X86) || defined(TARGET_AMD64)
4946 LLVMValueRef v1, v2;
4948 v1 = LLVMBuildMul (builder, convert (ctx, rhs, IntPtrType ()), LLVMConstInt (IntPtrType (), (1 << ins->backend.shift_amount), FALSE), "");
4949 v2 = LLVMBuildAdd (builder, convert (ctx, lhs, IntPtrType ()), v1, "");
4950 values [ins->dreg] = LLVMBuildAdd (builder, v2, LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE), dname);
4955 case OP_ICONV_TO_I1:
4956 case OP_ICONV_TO_I2:
4957 case OP_ICONV_TO_I4:
4958 case OP_ICONV_TO_U1:
4959 case OP_ICONV_TO_U2:
4960 case OP_ICONV_TO_U4:
4961 case OP_LCONV_TO_I1:
4962 case OP_LCONV_TO_I2:
4963 case OP_LCONV_TO_U1:
4964 case OP_LCONV_TO_U2:
4965 case OP_LCONV_TO_U4: {
4968 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);
4970 /* Have to do two casts since our vregs have type int */
4971 v = LLVMBuildTrunc (builder, lhs, op_to_llvm_type (ins->opcode), "");
4973 values [ins->dreg] = LLVMBuildSExt (builder, v, LLVMInt32Type (), dname);
4975 values [ins->dreg] = LLVMBuildZExt (builder, v, LLVMInt32Type (), dname);
4978 case OP_ICONV_TO_I8:
4979 values [ins->dreg] = LLVMBuildSExt (builder, lhs, LLVMInt64Type (), dname);
4981 case OP_ICONV_TO_U8:
4982 values [ins->dreg] = LLVMBuildZExt (builder, lhs, LLVMInt64Type (), dname);
4984 case OP_FCONV_TO_I4:
4985 case OP_RCONV_TO_I4:
4986 values [ins->dreg] = LLVMBuildFPToSI (builder, lhs, LLVMInt32Type (), dname);
4988 case OP_FCONV_TO_I1:
4989 case OP_RCONV_TO_I1:
4990 values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildFPToSI (builder, lhs, LLVMInt8Type (), dname), LLVMInt32Type (), "");
4992 case OP_FCONV_TO_U1:
4993 case OP_RCONV_TO_U1:
4994 values [ins->dreg] = LLVMBuildZExt (builder, LLVMBuildTrunc (builder, LLVMBuildFPToUI (builder, lhs, IntPtrType (), dname), LLVMInt8Type (), ""), LLVMInt32Type (), "");
4996 case OP_FCONV_TO_I2:
4997 case OP_RCONV_TO_I2:
4998 values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildFPToSI (builder, lhs, LLVMInt16Type (), dname), LLVMInt32Type (), "");
5000 case OP_FCONV_TO_U2:
5001 case OP_RCONV_TO_U2:
5002 values [ins->dreg] = LLVMBuildZExt (builder, LLVMBuildFPToUI (builder, lhs, LLVMInt16Type (), dname), LLVMInt32Type (), "");
5004 case OP_RCONV_TO_U4:
5005 values [ins->dreg] = LLVMBuildFPToUI (builder, lhs, LLVMInt32Type (), dname);
5007 case OP_FCONV_TO_I8:
5008 case OP_RCONV_TO_I8:
5009 values [ins->dreg] = LLVMBuildFPToSI (builder, lhs, LLVMInt64Type (), dname);
5012 values [ins->dreg] = LLVMBuildFPToSI (builder, lhs, IntPtrType (), dname);
5014 case OP_ICONV_TO_R8:
5015 case OP_LCONV_TO_R8:
5016 values [ins->dreg] = LLVMBuildSIToFP (builder, lhs, LLVMDoubleType (), dname);
5018 case OP_ICONV_TO_R_UN:
5019 case OP_LCONV_TO_R_UN:
5020 values [ins->dreg] = LLVMBuildUIToFP (builder, lhs, LLVMDoubleType (), dname);
5022 #if SIZEOF_VOID_P == 4
5025 case OP_LCONV_TO_I4:
5026 values [ins->dreg] = LLVMBuildTrunc (builder, lhs, LLVMInt32Type (), dname);
5028 case OP_ICONV_TO_R4:
5029 case OP_LCONV_TO_R4:
5030 v = LLVMBuildSIToFP (builder, lhs, LLVMFloatType (), "");
5032 values [ins->dreg] = v;
5034 values [ins->dreg] = LLVMBuildFPExt (builder, v, LLVMDoubleType (), dname);
5036 case OP_FCONV_TO_R4:
5037 v = LLVMBuildFPTrunc (builder, lhs, LLVMFloatType (), "");
5039 values [ins->dreg] = v;
5041 values [ins->dreg] = LLVMBuildFPExt (builder, v, LLVMDoubleType (), dname);
5043 case OP_RCONV_TO_R8:
5044 values [ins->dreg] = LLVMBuildFPExt (builder, lhs, LLVMDoubleType (), dname);
5046 case OP_RCONV_TO_R4:
5047 values [ins->dreg] = lhs;
5050 values [ins->dreg] = LLVMBuildSExt (builder, convert (ctx, lhs, LLVMInt32Type ()), LLVMInt64Type (), dname);
5053 values [ins->dreg] = LLVMBuildZExt (builder, convert (ctx, lhs, LLVMInt32Type ()), LLVMInt64Type (), dname);
5056 values [ins->dreg] = LLVMBuildTrunc (builder, lhs, LLVMInt32Type (), dname);
5058 case OP_LOCALLOC_IMM: {
5061 guint32 size = ins->inst_imm;
5062 size = (size + (MONO_ARCH_FRAME_ALIGNMENT - 1)) & ~ (MONO_ARCH_FRAME_ALIGNMENT - 1);
5064 v = mono_llvm_build_alloca (builder, LLVMInt8Type (), LLVMConstInt (LLVMInt32Type (), size, FALSE), MONO_ARCH_FRAME_ALIGNMENT, "");
5066 if (ins->flags & MONO_INST_INIT) {
5067 LLVMValueRef args [5];
5070 args [1] = LLVMConstInt (LLVMInt8Type (), 0, FALSE);
5071 args [2] = LLVMConstInt (LLVMInt32Type (), size, FALSE);
5072 args [3] = LLVMConstInt (LLVMInt32Type (), MONO_ARCH_FRAME_ALIGNMENT, FALSE);
5073 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
5074 LLVMBuildCall (builder, get_intrinsic (ctx, "llvm.memset.p0i8.i32"), args, 5, "");
5077 values [ins->dreg] = v;
5081 LLVMValueRef v, size;
5083 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), "");
5085 v = mono_llvm_build_alloca (builder, LLVMInt8Type (), size, MONO_ARCH_FRAME_ALIGNMENT, "");
5087 if (ins->flags & MONO_INST_INIT) {
5088 LLVMValueRef args [5];
5091 args [1] = LLVMConstInt (LLVMInt8Type (), 0, FALSE);
5093 args [3] = LLVMConstInt (LLVMInt32Type (), MONO_ARCH_FRAME_ALIGNMENT, FALSE);
5094 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
5095 LLVMBuildCall (builder, get_intrinsic (ctx, "llvm.memset.p0i8.i32"), args, 5, "");
5097 values [ins->dreg] = v;
5101 case OP_LOADI1_MEMBASE:
5102 case OP_LOADU1_MEMBASE:
5103 case OP_LOADI2_MEMBASE:
5104 case OP_LOADU2_MEMBASE:
5105 case OP_LOADI4_MEMBASE:
5106 case OP_LOADU4_MEMBASE:
5107 case OP_LOADI8_MEMBASE:
5108 case OP_LOADR4_MEMBASE:
5109 case OP_LOADR8_MEMBASE:
5110 case OP_LOAD_MEMBASE:
5118 LLVMValueRef base, index, addr;
5120 gboolean sext = FALSE, zext = FALSE;
5121 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
5123 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
5128 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)) {
5129 addr = LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE);
5135 if (ins->inst_offset == 0) {
5137 } else if (ins->inst_offset % size != 0) {
5138 /* Unaligned load */
5139 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset, FALSE);
5140 addr = LLVMBuildGEP (builder, convert (ctx, base, LLVMPointerType (LLVMInt8Type (), 0)), &index, 1, "");
5142 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
5143 addr = LLVMBuildGEP (builder, convert (ctx, base, LLVMPointerType (t, 0)), &index, 1, "");
5147 addr = convert (ctx, addr, LLVMPointerType (t, 0));
5149 values [ins->dreg] = emit_load_general (ctx, bb, &builder, size, addr, base, dname, is_volatile, LLVM_BARRIER_NONE);
5151 if (!is_volatile && (ins->flags & MONO_INST_INVARIANT_LOAD)) {
5153 * These will signal LLVM that these loads do not alias any stores, and
5154 * they can't fail, allowing them to be hoisted out of loops.
5156 set_invariant_load_flag (values [ins->dreg]);
5157 #if LLVM_API_VERSION < 100
5158 set_metadata_flag (values [ins->dreg], "mono.nofail.load");
5163 values [ins->dreg] = LLVMBuildSExt (builder, values [ins->dreg], LLVMInt32Type (), dname);
5165 values [ins->dreg] = LLVMBuildZExt (builder, values [ins->dreg], LLVMInt32Type (), dname);
5166 else if (!cfg->r4fp && ins->opcode == OP_LOADR4_MEMBASE)
5167 values [ins->dreg] = LLVMBuildFPExt (builder, values [ins->dreg], LLVMDoubleType (), dname);
5171 case OP_STOREI1_MEMBASE_REG:
5172 case OP_STOREI2_MEMBASE_REG:
5173 case OP_STOREI4_MEMBASE_REG:
5174 case OP_STOREI8_MEMBASE_REG:
5175 case OP_STORER4_MEMBASE_REG:
5176 case OP_STORER8_MEMBASE_REG:
5177 case OP_STORE_MEMBASE_REG: {
5179 LLVMValueRef index, addr, base;
5181 gboolean sext = FALSE, zext = FALSE;
5182 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
5184 if (!values [ins->inst_destbasereg]) {
5185 set_failure (ctx, "inst_destbasereg");
5189 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
5191 base = values [ins->inst_destbasereg];
5192 if (ins->inst_offset % size != 0) {
5193 /* Unaligned store */
5194 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset, FALSE);
5195 addr = LLVMBuildGEP (builder, convert (ctx, base, LLVMPointerType (LLVMInt8Type (), 0)), &index, 1, "");
5197 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
5198 addr = LLVMBuildGEP (builder, convert (ctx, base, LLVMPointerType (t, 0)), &index, 1, "");
5200 emit_store (ctx, bb, &builder, size, convert (ctx, values [ins->sreg1], t), convert (ctx, addr, LLVMPointerType (t, 0)), base, is_volatile);
5204 case OP_STOREI1_MEMBASE_IMM:
5205 case OP_STOREI2_MEMBASE_IMM:
5206 case OP_STOREI4_MEMBASE_IMM:
5207 case OP_STOREI8_MEMBASE_IMM:
5208 case OP_STORE_MEMBASE_IMM: {
5210 LLVMValueRef index, addr, base;
5212 gboolean sext = FALSE, zext = FALSE;
5213 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
5215 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
5217 base = values [ins->inst_destbasereg];
5218 if (ins->inst_offset % size != 0) {
5219 /* Unaligned store */
5220 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset, FALSE);
5221 addr = LLVMBuildGEP (builder, convert (ctx, base, LLVMPointerType (LLVMInt8Type (), 0)), &index, 1, "");
5223 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
5224 addr = LLVMBuildGEP (builder, convert (ctx, base, LLVMPointerType (t, 0)), &index, 1, "");
5226 emit_store (ctx, bb, &builder, size, convert (ctx, LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE), t), convert (ctx, addr, LLVMPointerType (t, 0)), base, is_volatile);
5231 emit_load_general (ctx, bb, &builder, sizeof (gpointer), convert (ctx, lhs, LLVMPointerType (IntPtrType (), 0)), lhs, "", TRUE, LLVM_BARRIER_NONE);
5233 case OP_OUTARG_VTRETADDR:
5241 case OP_VOIDCALL_MEMBASE:
5242 case OP_CALL_MEMBASE:
5243 case OP_LCALL_MEMBASE:
5244 case OP_FCALL_MEMBASE:
5245 case OP_RCALL_MEMBASE:
5246 case OP_VCALL_MEMBASE:
5247 case OP_VOIDCALL_REG:
5252 case OP_VCALL_REG: {
5253 process_call (ctx, bb, &builder, ins);
5258 LLVMValueRef indexes [2];
5259 MonoJumpInfo *tmp_ji, *ji;
5260 LLVMValueRef got_entry_addr;
5264 * FIXME: Can't allocate from the cfg mempool since that is freed if
5265 * the LLVM compile fails.
5267 tmp_ji = g_new0 (MonoJumpInfo, 1);
5268 tmp_ji->type = (MonoJumpInfoType)ins->inst_c1;
5269 tmp_ji->data.target = ins->inst_p0;
5271 ji = mono_aot_patch_info_dup (tmp_ji);
5274 if (ji->type == MONO_PATCH_INFO_ICALL_ADDR) {
5275 char *symbol = mono_aot_get_direct_call_symbol (MONO_PATCH_INFO_ICALL_ADDR_CALL, ji->data.target);
5278 * Avoid emitting a got entry for these since the method is directly called, and it might not be
5279 * resolvable at runtime using dlsym ().
5282 values [ins->dreg] = LLVMConstInt (IntPtrType (), 0, FALSE);
5287 ji->next = cfg->patch_info;
5288 cfg->patch_info = ji;
5290 //mono_add_patch_info (cfg, 0, (MonoJumpInfoType)ins->inst_i1, ins->inst_p0);
5291 got_offset = mono_aot_get_got_offset (cfg->patch_info);
5292 ctx->module->max_got_offset = MAX (ctx->module->max_got_offset, got_offset);
5293 if (!mono_aot_is_shared_got_offset (got_offset)) {
5294 //mono_print_ji (ji);
5296 ctx->has_got_access = TRUE;
5299 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
5300 indexes [1] = LLVMConstInt (LLVMInt32Type (), (gssize)got_offset, FALSE);
5301 got_entry_addr = LLVMBuildGEP (builder, ctx->module->got_var, indexes, 2, "");
5303 name = get_aotconst_name (ji->type, ji->data.target, got_offset);
5304 values [ins->dreg] = LLVMBuildLoad (builder, got_entry_addr, name);
5306 /* Can't use this in llvmonly mode since the got slots are initialized by the methods themselves */
5307 if (!cfg->llvm_only)
5308 set_invariant_load_flag (values [ins->dreg]);
5311 case OP_NOT_REACHED:
5312 LLVMBuildUnreachable (builder);
5313 has_terminator = TRUE;
5314 g_assert (bb->block_num < cfg->max_block_num);
5315 ctx->unreachable [bb->block_num] = TRUE;
5316 /* Might have instructions after this */
5318 MonoInst *next = ins->next;
5320 * FIXME: If later code uses the regs defined by these instructions,
5321 * compilation will fail.
5323 MONO_DELETE_INS (bb, next);
5327 MonoInst *var = ins->inst_i0;
5329 if (var->opcode == OP_VTARG_ADDR) {
5330 /* The variable contains the vtype address */
5331 values [ins->dreg] = values [var->dreg];
5332 } else if (var->opcode == OP_GSHAREDVT_LOCAL) {
5333 values [ins->dreg] = emit_gsharedvt_ldaddr (ctx, var->dreg);
5335 values [ins->dreg] = addresses [var->dreg];
5340 LLVMValueRef args [1];
5342 args [0] = convert (ctx, lhs, LLVMDoubleType ());
5343 values [ins->dreg] = LLVMBuildCall (builder, get_intrinsic (ctx, "llvm.sin.f64"), args, 1, dname);
5347 LLVMValueRef args [1];
5349 args [0] = convert (ctx, lhs, LLVMDoubleType ());
5350 values [ins->dreg] = LLVMBuildCall (builder, get_intrinsic (ctx, "llvm.cos.f64"), args, 1, dname);
5354 LLVMValueRef args [1];
5356 args [0] = convert (ctx, lhs, LLVMDoubleType ());
5357 values [ins->dreg] = LLVMBuildCall (builder, get_intrinsic (ctx, "llvm.sqrt.f64"), args, 1, dname);
5361 LLVMValueRef args [1];
5363 args [0] = convert (ctx, lhs, LLVMDoubleType ());
5364 values [ins->dreg] = LLVMBuildCall (builder, get_intrinsic (ctx, "fabs"), args, 1, dname);
5378 lhs = convert (ctx, lhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
5379 rhs = convert (ctx, rhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
5381 switch (ins->opcode) {
5384 v = LLVMBuildICmp (builder, LLVMIntSLE, lhs, rhs, "");
5388 v = LLVMBuildICmp (builder, LLVMIntSGE, lhs, rhs, "");
5392 v = LLVMBuildICmp (builder, LLVMIntULE, lhs, rhs, "");
5396 v = LLVMBuildICmp (builder, LLVMIntUGE, lhs, rhs, "");
5399 g_assert_not_reached ();
5402 values [ins->dreg] = LLVMBuildSelect (builder, v, lhs, rhs, dname);
5407 * See the ARM64 comment in mono/utils/atomic.h for an explanation of why this
5408 * hack is necessary (for now).
5411 #define ARM64_ATOMIC_FENCE_FIX mono_llvm_build_fence (builder, LLVM_BARRIER_SEQ)
5413 #define ARM64_ATOMIC_FENCE_FIX
5416 case OP_ATOMIC_EXCHANGE_I4:
5417 case OP_ATOMIC_EXCHANGE_I8: {
5418 LLVMValueRef args [2];
5421 if (ins->opcode == OP_ATOMIC_EXCHANGE_I4)
5422 t = LLVMInt32Type ();
5424 t = LLVMInt64Type ();
5426 g_assert (ins->inst_offset == 0);
5428 args [0] = convert (ctx, lhs, LLVMPointerType (t, 0));
5429 args [1] = convert (ctx, rhs, t);
5431 ARM64_ATOMIC_FENCE_FIX;
5432 values [ins->dreg] = mono_llvm_build_atomic_rmw (builder, LLVM_ATOMICRMW_OP_XCHG, args [0], args [1]);
5433 ARM64_ATOMIC_FENCE_FIX;
5436 case OP_ATOMIC_ADD_I4:
5437 case OP_ATOMIC_ADD_I8: {
5438 LLVMValueRef args [2];
5441 if (ins->opcode == OP_ATOMIC_ADD_I4)
5442 t = LLVMInt32Type ();
5444 t = LLVMInt64Type ();
5446 g_assert (ins->inst_offset == 0);
5448 args [0] = convert (ctx, lhs, LLVMPointerType (t, 0));
5449 args [1] = convert (ctx, rhs, t);
5450 ARM64_ATOMIC_FENCE_FIX;
5451 values [ins->dreg] = LLVMBuildAdd (builder, mono_llvm_build_atomic_rmw (builder, LLVM_ATOMICRMW_OP_ADD, args [0], args [1]), args [1], dname);
5452 ARM64_ATOMIC_FENCE_FIX;
5455 case OP_ATOMIC_CAS_I4:
5456 case OP_ATOMIC_CAS_I8: {
5457 LLVMValueRef args [3], val;
5460 if (ins->opcode == OP_ATOMIC_CAS_I4)
5461 t = LLVMInt32Type ();
5463 t = LLVMInt64Type ();
5465 args [0] = convert (ctx, lhs, LLVMPointerType (t, 0));
5467 args [1] = convert (ctx, values [ins->sreg3], t);
5469 args [2] = convert (ctx, values [ins->sreg2], t);
5470 ARM64_ATOMIC_FENCE_FIX;
5471 val = mono_llvm_build_cmpxchg (builder, args [0], args [1], args [2]);
5472 ARM64_ATOMIC_FENCE_FIX;
5473 /* cmpxchg returns a pair */
5474 values [ins->dreg] = LLVMBuildExtractValue (builder, val, 0, "");
5477 case OP_MEMORY_BARRIER: {
5478 mono_llvm_build_fence (builder, (BarrierKind) ins->backend.memory_barrier_kind);
5481 case OP_ATOMIC_LOAD_I1:
5482 case OP_ATOMIC_LOAD_I2:
5483 case OP_ATOMIC_LOAD_I4:
5484 case OP_ATOMIC_LOAD_I8:
5485 case OP_ATOMIC_LOAD_U1:
5486 case OP_ATOMIC_LOAD_U2:
5487 case OP_ATOMIC_LOAD_U4:
5488 case OP_ATOMIC_LOAD_U8:
5489 case OP_ATOMIC_LOAD_R4:
5490 case OP_ATOMIC_LOAD_R8: {
5491 #if LLVM_API_VERSION > 100
5493 gboolean sext, zext;
5495 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
5496 BarrierKind barrier = (BarrierKind) ins->backend.memory_barrier_kind;
5497 LLVMValueRef index, addr;
5499 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
5504 if (ins->inst_offset != 0) {
5505 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
5506 addr = LLVMBuildGEP (builder, convert (ctx, lhs, LLVMPointerType (t, 0)), &index, 1, "");
5511 addr = convert (ctx, addr, LLVMPointerType (t, 0));
5513 ARM64_ATOMIC_FENCE_FIX;
5514 values [ins->dreg] = emit_load_general (ctx, bb, &builder, size, addr, lhs, dname, is_volatile, barrier);
5515 ARM64_ATOMIC_FENCE_FIX;
5518 values [ins->dreg] = LLVMBuildSExt (builder, values [ins->dreg], LLVMInt32Type (), dname);
5520 values [ins->dreg] = LLVMBuildZExt (builder, values [ins->dreg], LLVMInt32Type (), dname);
5523 set_failure (ctx, "atomic mono.load intrinsic");
5527 case OP_ATOMIC_STORE_I1:
5528 case OP_ATOMIC_STORE_I2:
5529 case OP_ATOMIC_STORE_I4:
5530 case OP_ATOMIC_STORE_I8:
5531 case OP_ATOMIC_STORE_U1:
5532 case OP_ATOMIC_STORE_U2:
5533 case OP_ATOMIC_STORE_U4:
5534 case OP_ATOMIC_STORE_U8:
5535 case OP_ATOMIC_STORE_R4:
5536 case OP_ATOMIC_STORE_R8: {
5538 gboolean sext, zext;
5540 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
5541 BarrierKind barrier = (BarrierKind) ins->backend.memory_barrier_kind;
5542 LLVMValueRef index, addr, value, base;
5544 #if LLVM_API_VERSION < 100
5545 if (!cfg->llvm_only) {
5546 set_failure (ctx, "atomic mono.store intrinsic");
5551 if (!values [ins->inst_destbasereg]) {
5552 set_failure (ctx, "inst_destbasereg");
5556 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
5558 base = values [ins->inst_destbasereg];
5559 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
5560 addr = LLVMBuildGEP (builder, convert (ctx, base, LLVMPointerType (t, 0)), &index, 1, "");
5561 value = convert (ctx, values [ins->sreg1], t);
5563 ARM64_ATOMIC_FENCE_FIX;
5564 emit_store_general (ctx, bb, &builder, size, value, addr, base, is_volatile, barrier);
5565 ARM64_ATOMIC_FENCE_FIX;
5568 case OP_RELAXED_NOP: {
5569 #if defined(TARGET_AMD64) || defined(TARGET_X86)
5570 emit_call (ctx, bb, &builder, get_intrinsic (ctx, "llvm.x86.sse2.pause"), NULL, 0);
5577 #if (defined(TARGET_AMD64) || defined(TARGET_X86)) && defined(__linux__)
5579 // 257 == FS segment register
5580 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 257);
5582 // 256 == GS segment register
5583 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 256);
5586 values [ins->dreg] = LLVMBuildLoad (builder, LLVMBuildIntToPtr (builder, LLVMConstInt (IntPtrType (), ins->inst_offset, TRUE), ptrtype, ""), "");
5587 #elif defined(TARGET_AMD64) && defined(TARGET_OSX)
5588 /* See mono_amd64_emit_tls_get () */
5589 int offset = mono_amd64_get_tls_gs_offset () + (ins->inst_offset * 8);
5591 // 256 == GS segment register
5592 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 256);
5593 values [ins->dreg] = LLVMBuildLoad (builder, LLVMBuildIntToPtr (builder, LLVMConstInt (IntPtrType (), offset, TRUE), ptrtype, ""), "");
5595 set_failure (ctx, "opcode tls-get");
5601 case OP_TLS_GET_REG: {
5602 #if defined(TARGET_AMD64) && defined(__linux__)
5603 // 257 == FS segment register
5604 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 257);
5605 values [ins->dreg] = LLVMBuildLoad (builder, LLVMBuildIntToPtr (builder, convert (ctx, lhs, LLVMInt64Type ()), ptrtype, ""), "");
5606 #elif defined(TARGET_AMD64) && defined(TARGET_OSX)
5607 /* See emit_tls_get_reg () */
5608 // 256 == GS segment register
5609 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 256);
5610 values [ins->dreg] = LLVMBuildLoad (builder, LLVMBuildIntToPtr (builder, convert (ctx, lhs, LLVMInt32Type ()), ptrtype, ""), "");
5612 set_failure (ctx, "opcode tls-get");
5618 case OP_TLS_SET_REG: {
5619 #if defined(TARGET_AMD64) && defined(TARGET_OSX)
5620 /* See emit_tls_get_reg () */
5621 // 256 == GS segment register
5622 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 256);
5623 LLVMBuildStore (builder, convert (ctx, lhs, IntPtrType ()), LLVMBuildIntToPtr (builder, convert (ctx, rhs, LLVMInt32Type ()), ptrtype, ""));
5625 set_failure (ctx, "opcode tls-set-reg");
5630 case OP_GC_SAFE_POINT: {
5631 LLVMValueRef val, cmp, callee;
5632 LLVMBasicBlockRef poll_bb, cont_bb;
5633 static LLVMTypeRef sig;
5634 const char *icall_name = "mono_threads_state_poll";
5637 sig = LLVMFunctionType0 (LLVMVoidType (), FALSE);
5641 * mono_threads_state_poll ();
5642 * FIXME: Use a preserveall wrapper
5644 val = mono_llvm_build_load (builder, convert (ctx, lhs, LLVMPointerType (IntPtrType (), 0)), "", TRUE);
5645 cmp = LLVMBuildICmp (builder, LLVMIntEQ, val, LLVMConstNull (LLVMTypeOf (val)), "");
5646 poll_bb = gen_bb (ctx, "POLL_BB");
5647 cont_bb = gen_bb (ctx, "CONT_BB");
5648 LLVMBuildCondBr (builder, cmp, cont_bb, poll_bb);
5650 ctx->builder = builder = create_builder (ctx);
5651 LLVMPositionBuilderAtEnd (builder, poll_bb);
5653 if (ctx->cfg->compile_aot) {
5654 callee = get_callee (ctx, sig, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
5656 gpointer target = resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
5657 callee = emit_jit_callee (ctx, icall_name, sig, target);
5659 LLVMBuildCall (builder, callee, NULL, 0, "");
5660 LLVMBuildBr (builder, cont_bb);
5662 ctx->builder = builder = create_builder (ctx);
5663 LLVMPositionBuilderAtEnd (builder, cont_bb);
5664 ctx->bblocks [bb->block_num].end_bblock = cont_bb;
5672 case OP_IADD_OVF_UN:
5674 case OP_ISUB_OVF_UN:
5676 case OP_IMUL_OVF_UN:
5678 case OP_LADD_OVF_UN:
5680 case OP_LSUB_OVF_UN:
5682 case OP_LMUL_OVF_UN:
5684 LLVMValueRef args [2], val, ovf, func;
5686 args [0] = convert (ctx, lhs, op_to_llvm_type (ins->opcode));
5687 args [1] = convert (ctx, rhs, op_to_llvm_type (ins->opcode));
5688 func = get_intrinsic (ctx, ovf_op_to_intrins (ins->opcode));
5690 val = LLVMBuildCall (builder, func, args, 2, "");
5691 values [ins->dreg] = LLVMBuildExtractValue (builder, val, 0, dname);
5692 ovf = LLVMBuildExtractValue (builder, val, 1, "");
5693 emit_cond_system_exception (ctx, bb, "OverflowException", ovf);
5696 builder = ctx->builder;
5702 * We currently model them using arrays. Promotion to local vregs is
5703 * disabled for them in mono_handle_global_vregs () in the LLVM case,
5704 * so we always have an entry in cfg->varinfo for them.
5705 * FIXME: Is this needed ?
5708 MonoClass *klass = ins->klass;
5709 LLVMValueRef args [5];
5713 set_failure (ctx, "!klass");
5717 if (!addresses [ins->dreg])
5718 addresses [ins->dreg] = build_alloca (ctx, &klass->byval_arg);
5719 args [0] = LLVMBuildBitCast (builder, addresses [ins->dreg], LLVMPointerType (LLVMInt8Type (), 0), "");
5720 args [1] = LLVMConstInt (LLVMInt8Type (), 0, FALSE);
5721 args [2] = LLVMConstInt (LLVMInt32Type (), mono_class_value_size (klass, NULL), FALSE);
5723 args [3] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
5724 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
5725 LLVMBuildCall (builder, get_intrinsic (ctx, "llvm.memset.p0i8.i32"), args, 5, "");
5728 case OP_DUMMY_VZERO:
5731 case OP_STOREV_MEMBASE:
5732 case OP_LOADV_MEMBASE:
5734 MonoClass *klass = ins->klass;
5735 LLVMValueRef src = NULL, dst, args [5];
5736 gboolean done = FALSE;
5740 set_failure (ctx, "!klass");
5744 if (mini_is_gsharedvt_klass (klass)) {
5746 set_failure (ctx, "gsharedvt");
5750 switch (ins->opcode) {
5751 case OP_STOREV_MEMBASE:
5752 if (cfg->gen_write_barriers && klass->has_references && ins->inst_destbasereg != cfg->frame_reg &&
5753 LLVMGetInstructionOpcode (values [ins->inst_destbasereg]) != LLVMAlloca) {
5754 /* Decomposed earlier */
5755 g_assert_not_reached ();
5758 if (!addresses [ins->sreg1]) {
5760 g_assert (values [ins->sreg1]);
5761 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));
5762 LLVMBuildStore (builder, values [ins->sreg1], dst);
5765 src = LLVMBuildBitCast (builder, addresses [ins->sreg1], LLVMPointerType (LLVMInt8Type (), 0), "");
5766 dst = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_destbasereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (LLVMInt8Type (), 0));
5769 case OP_LOADV_MEMBASE:
5770 if (!addresses [ins->dreg])
5771 addresses [ins->dreg] = build_alloca (ctx, &klass->byval_arg);
5772 src = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_basereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (LLVMInt8Type (), 0));
5773 dst = LLVMBuildBitCast (builder, addresses [ins->dreg], LLVMPointerType (LLVMInt8Type (), 0), "");
5776 if (!addresses [ins->sreg1])
5777 addresses [ins->sreg1] = build_alloca (ctx, &klass->byval_arg);
5778 if (!addresses [ins->dreg])
5779 addresses [ins->dreg] = build_alloca (ctx, &klass->byval_arg);
5780 src = LLVMBuildBitCast (builder, addresses [ins->sreg1], LLVMPointerType (LLVMInt8Type (), 0), "");
5781 dst = LLVMBuildBitCast (builder, addresses [ins->dreg], LLVMPointerType (LLVMInt8Type (), 0), "");
5784 g_assert_not_reached ();
5794 args [2] = LLVMConstInt (LLVMInt32Type (), mono_class_value_size (klass, NULL), FALSE);
5795 args [3] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
5797 args [3] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
5798 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
5799 LLVMBuildCall (builder, get_intrinsic (ctx, "llvm.memcpy.p0i8.p0i8.i32"), args, 5, "");
5802 case OP_LLVM_OUTARG_VT: {
5803 LLVMArgInfo *ainfo = (LLVMArgInfo*)ins->inst_p0;
5804 MonoType *t = mini_get_underlying_type (ins->inst_vtype);
5806 if (ainfo->storage == LLVMArgGsharedvtVariable) {
5807 MonoInst *var = get_vreg_to_inst (cfg, ins->sreg1);
5809 if (var && var->opcode == OP_GSHAREDVT_LOCAL) {
5810 addresses [ins->dreg] = convert (ctx, emit_gsharedvt_ldaddr (ctx, var->dreg), LLVMPointerType (IntPtrType (), 0));
5812 g_assert (addresses [ins->sreg1]);
5813 addresses [ins->dreg] = addresses [ins->sreg1];
5815 } else if (ainfo->storage == LLVMArgGsharedvtFixed) {
5816 if (!addresses [ins->sreg1]) {
5817 addresses [ins->sreg1] = build_alloca (ctx, t);
5818 g_assert (values [ins->sreg1]);
5820 LLVMBuildStore (builder, convert (ctx, values [ins->sreg1], LLVMGetElementType (LLVMTypeOf (addresses [ins->sreg1]))), addresses [ins->sreg1]);
5821 addresses [ins->dreg] = addresses [ins->sreg1];
5823 if (!addresses [ins->sreg1]) {
5824 addresses [ins->sreg1] = build_alloca (ctx, t);
5825 g_assert (values [ins->sreg1]);
5826 LLVMBuildStore (builder, convert (ctx, values [ins->sreg1], type_to_llvm_type (ctx, t)), addresses [ins->sreg1]);
5828 addresses [ins->dreg] = addresses [ins->sreg1];
5832 case OP_OBJC_GET_SELECTOR: {
5833 const char *name = (const char*)ins->inst_p0;
5836 if (!ctx->module->objc_selector_to_var)
5837 ctx->module->objc_selector_to_var = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
5838 var = g_hash_table_lookup (ctx->module->objc_selector_to_var, name);
5840 LLVMValueRef indexes [16];
5842 LLVMValueRef name_var = LLVMAddGlobal (ctx->lmodule, LLVMArrayType (LLVMInt8Type (), strlen (name) + 1), "@OBJC_METH_VAR_NAME_");
5843 LLVMSetInitializer (name_var, mono_llvm_create_constant_data_array ((const uint8_t*)name, strlen (name) + 1));
5844 LLVMSetLinkage (name_var, LLVMPrivateLinkage);
5845 LLVMSetSection (name_var, "__TEXT,__objc_methname,cstring_literals");
5846 mark_as_used (ctx->module, name_var);
5848 LLVMValueRef ref_var = LLVMAddGlobal (ctx->lmodule, LLVMPointerType (LLVMInt8Type (), 0), "@OBJC_SELECTOR_REFERENCES_");
5850 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, 0);
5851 indexes [1] = LLVMConstInt (LLVMInt32Type (), 0, 0);
5852 LLVMSetInitializer (ref_var, LLVMConstGEP (name_var, indexes, 2));
5853 LLVMSetLinkage (ref_var, LLVMPrivateLinkage);
5854 LLVMSetExternallyInitialized (ref_var, TRUE);
5855 LLVMSetSection (ref_var, "__DATA, __objc_selrefs, literal_pointers, no_dead_strip");
5856 LLVMSetAlignment (ref_var, sizeof (mgreg_t));
5857 mark_as_used (ctx->module, ref_var);
5859 g_hash_table_insert (ctx->module->objc_selector_to_var, g_strdup (name), ref_var);
5863 values [ins->dreg] = LLVMBuildLoad (builder, var, "");
5870 #if defined(TARGET_X86) || defined(TARGET_AMD64)
5872 values [ins->dreg] = LLVMConstNull (type_to_llvm_type (ctx, &ins->klass->byval_arg));
5875 case OP_LOADX_MEMBASE: {
5876 LLVMTypeRef t = type_to_llvm_type (ctx, &ins->klass->byval_arg);
5879 src = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_basereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (t, 0));
5880 values [ins->dreg] = mono_llvm_build_aligned_load (builder, src, "", FALSE, 1);
5883 case OP_STOREX_MEMBASE: {
5884 LLVMTypeRef t = LLVMTypeOf (values [ins->sreg1]);
5887 dest = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_destbasereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (t, 0));
5888 mono_llvm_build_aligned_store (builder, values [ins->sreg1], dest, FALSE, 1);
5895 values [ins->dreg] = LLVMBuildAdd (builder, lhs, rhs, "");
5899 values [ins->dreg] = LLVMBuildFAdd (builder, lhs, rhs, "");
5905 values [ins->dreg] = LLVMBuildSub (builder, lhs, rhs, "");
5909 values [ins->dreg] = LLVMBuildFSub (builder, lhs, rhs, "");
5913 values [ins->dreg] = LLVMBuildFMul (builder, lhs, rhs, "");
5917 values [ins->dreg] = LLVMBuildFDiv (builder, lhs, rhs, "");
5920 values [ins->dreg] = LLVMBuildAnd (builder, lhs, rhs, "");
5923 values [ins->dreg] = LLVMBuildOr (builder, lhs, rhs, "");
5926 values [ins->dreg] = LLVMBuildXor (builder, lhs, rhs, "");
5930 values [ins->dreg] = LLVMBuildMul (builder, lhs, rhs, "");
5941 LLVMValueRef v = NULL;
5943 switch (ins->opcode) {
5948 t = LLVMVectorType (LLVMInt32Type (), 4);
5949 rt = LLVMVectorType (LLVMFloatType (), 4);
5955 t = LLVMVectorType (LLVMInt64Type (), 2);
5956 rt = LLVMVectorType (LLVMDoubleType (), 2);
5959 t = LLVMInt32Type ();
5960 rt = LLVMInt32Type ();
5961 g_assert_not_reached ();
5964 lhs = LLVMBuildBitCast (builder, lhs, t, "");
5965 rhs = LLVMBuildBitCast (builder, rhs, t, "");
5966 switch (ins->opcode) {
5969 v = LLVMBuildAnd (builder, lhs, rhs, "");
5973 v = LLVMBuildOr (builder, lhs, rhs, "");
5977 v = LLVMBuildXor (builder, lhs, rhs, "");
5981 v = LLVMBuildAnd (builder, rhs, LLVMBuildNot (builder, lhs, ""), "");
5984 values [ins->dreg] = LLVMBuildBitCast (builder, v, rt, "");
5990 LLVMValueRef cmp = LLVMBuildICmp (builder, LLVMIntULT, lhs, rhs, "");
5991 values [ins->dreg] = LLVMBuildSelect (builder, cmp, lhs, rhs, "");
5997 LLVMValueRef cmp = LLVMBuildICmp (builder, LLVMIntUGT, lhs, rhs, "");
5998 values [ins->dreg] = LLVMBuildSelect (builder, cmp, lhs, rhs, "");
6002 LLVMValueRef cmp = LLVMBuildICmp (builder, LLVMIntSLT, lhs, rhs, "");
6003 values [ins->dreg] = LLVMBuildSelect (builder, cmp, lhs, rhs, "");
6020 case OP_PADDB_SAT_UN:
6021 case OP_PADDW_SAT_UN:
6022 case OP_PSUBB_SAT_UN:
6023 case OP_PSUBW_SAT_UN:
6031 case OP_PMULW_HIGH_UN: {
6032 LLVMValueRef args [2];
6037 values [ins->dreg] = LLVMBuildCall (builder, get_intrinsic (ctx, simd_op_to_intrins (ins->opcode)), args, 2, dname);
6044 values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildICmp (builder, LLVMIntEQ, lhs, rhs, ""), LLVMTypeOf (lhs), "");
6048 values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildICmp (builder, LLVMIntSGT, lhs, rhs, ""), LLVMTypeOf (lhs), "");
6056 case OP_EXTRACTX_U2:
6058 case OP_EXTRACT_U1: {
6060 gboolean zext = FALSE;
6062 t = simd_op_to_llvm_type (ins->opcode);
6064 switch (ins->opcode) {
6072 case OP_EXTRACTX_U2:
6077 t = LLVMInt32Type ();
6078 g_assert_not_reached ();
6081 lhs = LLVMBuildBitCast (builder, lhs, t, "");
6082 values [ins->dreg] = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), "");
6084 values [ins->dreg] = LLVMBuildZExt (builder, values [ins->dreg], LLVMInt32Type (), "");
6093 case OP_EXPAND_R8: {
6094 LLVMTypeRef t = simd_op_to_llvm_type (ins->opcode);
6095 LLVMValueRef mask [16], v;
6098 for (i = 0; i < 16; ++i)
6099 mask [i] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
6101 v = convert (ctx, values [ins->sreg1], LLVMGetElementType (t));
6103 values [ins->dreg] = LLVMBuildInsertElement (builder, LLVMConstNull (t), v, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
6104 values [ins->dreg] = LLVMBuildShuffleVector (builder, values [ins->dreg], LLVMGetUndef (t), LLVMConstVector (mask, LLVMGetVectorSize (t)), "");
6109 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt8Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
6112 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt16Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
6115 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt32Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
6118 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt64Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
6121 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMFloatType ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
6124 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMDoubleType ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
6128 // Requires a later llvm version
6130 LLVMValueRef indexes [16];
6132 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
6133 indexes [1] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
6134 LLVMValueRef mask = LLVMConstVector (indexes, 2);
6135 LLVMValueRef shuffle = LLVMBuildShuffleVector (builder, lhs, LLVMConstNull (LLVMTypeOf (lhs)), mask, "");
6136 values [ins->dreg] = LLVMBuildSIToFP (builder, shuffle, LLVMVectorType (LLVMDoubleType (), 2), dname);
6140 LLVMValueRef indexes [16];
6142 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
6143 indexes [1] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
6144 LLVMValueRef mask = LLVMConstVector (indexes, 2);
6145 LLVMValueRef shuffle = LLVMBuildShuffleVector (builder, lhs, LLVMConstNull (LLVMTypeOf (lhs)), mask, "");
6146 values [ins->dreg] = LLVMBuildFPExt (builder, shuffle, LLVMVectorType (LLVMDoubleType (), 2), dname);
6150 values [ins->dreg] = LLVMBuildFPToSI (builder, lhs, LLVMVectorType (LLVMInt32Type (), 4), dname);
6162 case OP_EXTRACT_MASK:
6169 v = convert (ctx, values [ins->sreg1], simd_op_to_llvm_type (ins->opcode));
6171 values [ins->dreg] = LLVMBuildCall (builder, get_intrinsic (ctx, simd_op_to_intrins (ins->opcode)), &v, 1, dname);
6176 LLVMRealPredicate op;
6178 switch (ins->inst_c0) {
6188 case SIMD_COMP_UNORD:
6204 g_assert_not_reached ();
6207 LLVMValueRef cmp = LLVMBuildFCmp (builder, op, lhs, rhs, "");
6208 if (ins->opcode == OP_COMPPD)
6209 values [ins->dreg] = LLVMBuildBitCast (builder, LLVMBuildSExt (builder, cmp, LLVMVectorType (LLVMInt64Type (), 2), ""), LLVMTypeOf (lhs), "");
6211 values [ins->dreg] = LLVMBuildBitCast (builder, LLVMBuildSExt (builder, cmp, LLVMVectorType (LLVMInt32Type (), 4), ""), LLVMTypeOf (lhs), "");
6215 /* This is only used for implementing shifts by non-immediate */
6216 values [ins->dreg] = lhs;
6227 LLVMValueRef args [3];
6230 args [1] = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
6232 values [ins->dreg] = LLVMBuildCall (builder, get_intrinsic (ctx, simd_op_to_intrins (ins->opcode)), args, 2, dname);
6243 case OP_PSHLQ_REG: {
6244 LLVMValueRef args [3];
6247 args [1] = values [ins->sreg2];
6249 values [ins->dreg] = LLVMBuildCall (builder, get_intrinsic (ctx, simd_op_to_intrins (ins->opcode)), args, 2, dname);
6256 case OP_PSHUFLEW_LOW:
6257 case OP_PSHUFLEW_HIGH: {
6259 LLVMValueRef v1 = NULL, v2 = NULL, mask_values [16];
6260 int i, mask_size = 0;
6261 int imask = ins->inst_c0;
6263 /* Convert the x86 shuffle mask to LLVM's */
6264 switch (ins->opcode) {
6267 mask [0] = ((imask >> 0) & 3);
6268 mask [1] = ((imask >> 2) & 3);
6269 mask [2] = ((imask >> 4) & 3) + 4;
6270 mask [3] = ((imask >> 6) & 3) + 4;
6271 v1 = values [ins->sreg1];
6272 v2 = values [ins->sreg2];
6276 mask [0] = ((imask >> 0) & 1);
6277 mask [1] = ((imask >> 1) & 1) + 2;
6278 v1 = values [ins->sreg1];
6279 v2 = values [ins->sreg2];
6281 case OP_PSHUFLEW_LOW:
6283 mask [0] = ((imask >> 0) & 3);
6284 mask [1] = ((imask >> 2) & 3);
6285 mask [2] = ((imask >> 4) & 3);
6286 mask [3] = ((imask >> 6) & 3);
6291 v1 = values [ins->sreg1];
6292 v2 = LLVMGetUndef (LLVMTypeOf (v1));
6294 case OP_PSHUFLEW_HIGH:
6300 mask [4] = 4 + ((imask >> 0) & 3);
6301 mask [5] = 4 + ((imask >> 2) & 3);
6302 mask [6] = 4 + ((imask >> 4) & 3);
6303 mask [7] = 4 + ((imask >> 6) & 3);
6304 v1 = values [ins->sreg1];
6305 v2 = LLVMGetUndef (LLVMTypeOf (v1));
6309 mask [0] = ((imask >> 0) & 3);
6310 mask [1] = ((imask >> 2) & 3);
6311 mask [2] = ((imask >> 4) & 3);
6312 mask [3] = ((imask >> 6) & 3);
6313 v1 = values [ins->sreg1];
6314 v2 = LLVMGetUndef (LLVMTypeOf (v1));
6317 g_assert_not_reached ();
6319 for (i = 0; i < mask_size; ++i)
6320 mask_values [i] = LLVMConstInt (LLVMInt32Type (), mask [i], FALSE);
6322 values [ins->dreg] =
6323 LLVMBuildShuffleVector (builder, v1, v2,
6324 LLVMConstVector (mask_values, mask_size), dname);
6328 case OP_UNPACK_LOWB:
6329 case OP_UNPACK_LOWW:
6330 case OP_UNPACK_LOWD:
6331 case OP_UNPACK_LOWQ:
6332 case OP_UNPACK_LOWPS:
6333 case OP_UNPACK_LOWPD:
6334 case OP_UNPACK_HIGHB:
6335 case OP_UNPACK_HIGHW:
6336 case OP_UNPACK_HIGHD:
6337 case OP_UNPACK_HIGHQ:
6338 case OP_UNPACK_HIGHPS:
6339 case OP_UNPACK_HIGHPD: {
6341 LLVMValueRef mask_values [16];
6342 int i, mask_size = 0;
6343 gboolean low = FALSE;
6345 switch (ins->opcode) {
6346 case OP_UNPACK_LOWB:
6350 case OP_UNPACK_LOWW:
6354 case OP_UNPACK_LOWD:
6355 case OP_UNPACK_LOWPS:
6359 case OP_UNPACK_LOWQ:
6360 case OP_UNPACK_LOWPD:
6364 case OP_UNPACK_HIGHB:
6367 case OP_UNPACK_HIGHW:
6370 case OP_UNPACK_HIGHD:
6371 case OP_UNPACK_HIGHPS:
6374 case OP_UNPACK_HIGHQ:
6375 case OP_UNPACK_HIGHPD:
6379 g_assert_not_reached ();
6383 for (i = 0; i < (mask_size / 2); ++i) {
6385 mask [(i * 2) + 1] = mask_size + i;
6388 for (i = 0; i < (mask_size / 2); ++i) {
6389 mask [(i * 2)] = (mask_size / 2) + i;
6390 mask [(i * 2) + 1] = mask_size + (mask_size / 2) + i;
6394 for (i = 0; i < mask_size; ++i)
6395 mask_values [i] = LLVMConstInt (LLVMInt32Type (), mask [i], FALSE);
6397 values [ins->dreg] =
6398 LLVMBuildShuffleVector (builder, values [ins->sreg1], values [ins->sreg2],
6399 LLVMConstVector (mask_values, mask_size), dname);
6404 LLVMTypeRef t = simd_op_to_llvm_type (ins->opcode);
6405 LLVMValueRef v, val;
6407 v = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
6408 val = LLVMConstNull (t);
6409 val = LLVMBuildInsertElement (builder, val, v, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
6410 val = LLVMBuildInsertElement (builder, val, v, LLVMConstInt (LLVMInt32Type (), 1, FALSE), dname);
6412 values [ins->dreg] = val;
6416 case OP_DUPPS_HIGH: {
6417 LLVMTypeRef t = simd_op_to_llvm_type (ins->opcode);
6418 LLVMValueRef v1, v2, val;
6421 if (ins->opcode == OP_DUPPS_LOW) {
6422 v1 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
6423 v2 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 2, FALSE), "");
6425 v1 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 1, FALSE), "");
6426 v2 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 3, FALSE), "");
6428 val = LLVMConstNull (t);
6429 val = LLVMBuildInsertElement (builder, val, v1, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
6430 val = LLVMBuildInsertElement (builder, val, v1, LLVMConstInt (LLVMInt32Type (), 1, FALSE), "");
6431 val = LLVMBuildInsertElement (builder, val, v2, LLVMConstInt (LLVMInt32Type (), 2, FALSE), "");
6432 val = LLVMBuildInsertElement (builder, val, v2, LLVMConstInt (LLVMInt32Type (), 3, FALSE), "");
6434 values [ins->dreg] = val;
6444 * EXCEPTION HANDLING
6446 case OP_IMPLICIT_EXCEPTION:
6447 /* This marks a place where an implicit exception can happen */
6448 if (bb->region != -1)
6449 set_failure (ctx, "implicit-exception");
6453 gboolean rethrow = (ins->opcode == OP_RETHROW);
6454 if (ctx->llvm_only) {
6455 emit_llvmonly_throw (ctx, bb, rethrow, lhs);
6456 has_terminator = TRUE;
6457 ctx->unreachable [bb->block_num] = TRUE;
6459 emit_throw (ctx, bb, rethrow, lhs);
6460 builder = ctx->builder;
6464 case OP_CALL_HANDLER: {
6466 * We don't 'call' handlers, but instead simply branch to them.
6467 * The code generated by ENDFINALLY will branch back to us.
6469 LLVMBasicBlockRef noex_bb;
6471 BBInfo *info = &bblocks [ins->inst_target_bb->block_num];
6473 bb_list = info->call_handler_return_bbs;
6476 * Set the indicator variable for the finally clause.
6478 lhs = info->finally_ind;
6480 LLVMBuildStore (builder, LLVMConstInt (LLVMInt32Type (), g_slist_length (bb_list) + 1, FALSE), lhs);
6482 /* Branch to the finally clause */
6483 LLVMBuildBr (builder, info->call_handler_target_bb);
6485 noex_bb = gen_bb (ctx, "CALL_HANDLER_CONT_BB");
6486 info->call_handler_return_bbs = g_slist_append_mempool (cfg->mempool, info->call_handler_return_bbs, noex_bb);
6488 builder = ctx->builder = create_builder (ctx);
6489 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
6491 bblocks [bb->block_num].end_bblock = noex_bb;
6494 case OP_START_HANDLER: {
6497 case OP_ENDFINALLY: {
6498 LLVMBasicBlockRef resume_bb;
6499 MonoBasicBlock *handler_bb;
6500 LLVMValueRef val, switch_ins, callee;
6504 handler_bb = (MonoBasicBlock*)g_hash_table_lookup (ctx->region_to_handler, GUINT_TO_POINTER (mono_get_block_region_notry (cfg, bb->region)));
6505 g_assert (handler_bb);
6506 info = &bblocks [handler_bb->block_num];
6507 lhs = info->finally_ind;
6510 bb_list = info->call_handler_return_bbs;
6512 resume_bb = gen_bb (ctx, "ENDFINALLY_RESUME_BB");
6514 /* Load the finally variable */
6515 val = LLVMBuildLoad (builder, lhs, "");
6517 /* Reset the variable */
6518 LLVMBuildStore (builder, LLVMConstInt (LLVMInt32Type (), 0, FALSE), lhs);
6520 /* Branch to either resume_bb, or to the bblocks in bb_list */
6521 switch_ins = LLVMBuildSwitch (builder, val, resume_bb, g_slist_length (bb_list));
6523 * The other targets are added at the end to handle OP_CALL_HANDLER
6524 * opcodes processed later.
6526 info->endfinally_switch_ins_list = g_slist_append_mempool (cfg->mempool, info->endfinally_switch_ins_list, switch_ins);
6528 builder = ctx->builder = create_builder (ctx);
6529 LLVMPositionBuilderAtEnd (ctx->builder, resume_bb);
6531 if (ctx->llvm_only) {
6532 emit_resume_eh (ctx, bb);
6534 if (ctx->cfg->compile_aot) {
6535 callee = get_callee (ctx, LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE), MONO_PATCH_INFO_INTERNAL_METHOD, "llvm_resume_unwind_trampoline");
6537 #if LLVM_API_VERSION > 100
6538 MonoJitICallInfo *info;
6540 info = mono_find_jit_icall_by_name ("llvm_resume_unwind_trampoline");
6542 gpointer target = (void*)info->func;
6543 LLVMTypeRef icall_sig = LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE);
6544 callee = emit_jit_callee (ctx, "llvm_resume_unwind_trampoline", icall_sig, target);
6546 callee = LLVMGetNamedFunction (ctx->lmodule, "llvm_resume_unwind_trampoline");
6549 LLVMBuildCall (builder, callee, NULL, 0, "");
6550 LLVMBuildUnreachable (builder);
6553 has_terminator = TRUE;
6556 case OP_IL_SEQ_POINT:
6561 sprintf (reason, "opcode %s", mono_inst_name (ins->opcode));
6562 set_failure (ctx, reason);
6570 /* Convert the value to the type required by phi nodes */
6571 if (spec [MONO_INST_DEST] != ' ' && !MONO_IS_STORE_MEMBASE (ins) && ctx->vreg_types [ins->dreg]) {
6572 if (ctx->is_vphi [ins->dreg])
6574 values [ins->dreg] = addresses [ins->dreg];
6576 values [ins->dreg] = convert (ctx, values [ins->dreg], ctx->vreg_types [ins->dreg]);
6579 /* Add stores for volatile variables */
6580 if (spec [MONO_INST_DEST] != ' ' && spec [MONO_INST_DEST] != 'v' && !MONO_IS_STORE_MEMBASE (ins))
6581 emit_volatile_store (ctx, ins->dreg);
6587 if (!has_terminator && bb->next_bb && (bb == cfg->bb_entry || bb->in_count > 0)) {
6588 LLVMBuildBr (builder, get_bb (ctx, bb->next_bb));
6591 if (bb == cfg->bb_exit && sig->ret->type == MONO_TYPE_VOID) {
6592 emit_dbg_loc (ctx, builder, cfg->header->code + cfg->header->code_size - 1);
6593 LLVMBuildRetVoid (builder);
6596 if (bb == cfg->bb_entry)
6597 ctx->last_alloca = LLVMGetLastInstruction (get_bb (ctx, cfg->bb_entry));
6601 * mono_llvm_check_method_supported:
6603 * Do some quick checks to decide whenever cfg->method can be compiled by LLVM, to avoid
6604 * compiling a method twice.
6607 mono_llvm_check_method_supported (MonoCompile *cfg)
6614 if (cfg->method->save_lmf) {
6615 cfg->exception_message = g_strdup ("lmf");
6616 cfg->disable_llvm = TRUE;
6618 if (cfg->disable_llvm)
6622 * Nested clauses where one of the clauses is a finally clause is
6623 * not supported, because LLVM can't figure out the control flow,
6624 * probably because we resume exception handling by calling our
6625 * own function instead of using the 'resume' llvm instruction.
6627 for (i = 0; i < cfg->header->num_clauses; ++i) {
6628 for (j = 0; j < cfg->header->num_clauses; ++j) {
6629 MonoExceptionClause *clause1 = &cfg->header->clauses [i];
6630 MonoExceptionClause *clause2 = &cfg->header->clauses [j];
6632 // FIXME: Nested try clauses fail in some cases too, i.e. #37273
6633 if (i != j && clause1->try_offset >= clause2->try_offset && clause1->handler_offset <= clause2->handler_offset) {
6634 //(clause1->flags == MONO_EXCEPTION_CLAUSE_FINALLY || clause2->flags == MONO_EXCEPTION_CLAUSE_FINALLY)) {
6635 cfg->exception_message = g_strdup ("nested clauses");
6636 cfg->disable_llvm = TRUE;
6641 if (cfg->disable_llvm)
6645 if (cfg->method->dynamic) {
6646 cfg->exception_message = g_strdup ("dynamic.");
6647 cfg->disable_llvm = TRUE;
6649 if (cfg->disable_llvm)
6653 static LLVMCallInfo*
6654 get_llvm_call_info (MonoCompile *cfg, MonoMethodSignature *sig)
6656 LLVMCallInfo *linfo;
6659 if (cfg->gsharedvt && cfg->llvm_only && mini_is_gsharedvt_variable_signature (sig)) {
6663 * Gsharedvt methods have the following calling convention:
6664 * - all arguments are passed by ref, even non generic ones
6665 * - the return value is returned by ref too, using a vret
6666 * argument passed after 'this'.
6668 n = sig->param_count + sig->hasthis;
6669 linfo = (LLVMCallInfo*)mono_mempool_alloc0 (cfg->mempool, sizeof (LLVMCallInfo) + (sizeof (LLVMArgInfo) * n));
6673 linfo->args [pindex ++].storage = LLVMArgNormal;
6675 if (sig->ret->type != MONO_TYPE_VOID) {
6676 if (mini_is_gsharedvt_variable_type (sig->ret))
6677 linfo->ret.storage = LLVMArgGsharedvtVariable;
6678 else if (mini_type_is_vtype (sig->ret))
6679 linfo->ret.storage = LLVMArgGsharedvtFixedVtype;
6681 linfo->ret.storage = LLVMArgGsharedvtFixed;
6682 linfo->vret_arg_index = pindex;
6684 linfo->ret.storage = LLVMArgNone;
6687 for (i = 0; i < sig->param_count; ++i) {
6688 if (sig->params [i]->byref)
6689 linfo->args [pindex].storage = LLVMArgNormal;
6690 else if (mini_is_gsharedvt_variable_type (sig->params [i]))
6691 linfo->args [pindex].storage = LLVMArgGsharedvtVariable;
6692 else if (mini_type_is_vtype (sig->params [i]))
6693 linfo->args [pindex].storage = LLVMArgGsharedvtFixedVtype;
6695 linfo->args [pindex].storage = LLVMArgGsharedvtFixed;
6696 linfo->args [pindex].type = sig->params [i];
6703 linfo = mono_arch_get_llvm_call_info (cfg, sig);
6704 for (i = 0; i < sig->param_count; ++i)
6705 linfo->args [i + sig->hasthis].type = sig->params [i];
6711 emit_method_inner (EmitContext *ctx);
6714 free_ctx (EmitContext *ctx)
6718 g_free (ctx->values);
6719 g_free (ctx->addresses);
6720 g_free (ctx->vreg_types);
6721 g_free (ctx->is_vphi);
6722 g_free (ctx->vreg_cli_types);
6723 g_free (ctx->is_dead);
6724 g_free (ctx->unreachable);
6725 g_ptr_array_free (ctx->phi_values, TRUE);
6726 g_free (ctx->bblocks);
6727 g_hash_table_destroy (ctx->region_to_handler);
6728 g_hash_table_destroy (ctx->clause_to_handler);
6729 g_hash_table_destroy (ctx->jit_callees);
6731 GHashTableIter iter;
6732 g_hash_table_iter_init (&iter, ctx->method_to_callers);
6733 while (g_hash_table_iter_next (&iter, NULL, (gpointer)&l))
6736 g_hash_table_destroy (ctx->method_to_callers);
6738 g_free (ctx->method_name);
6739 g_ptr_array_free (ctx->bblock_list, TRUE);
6741 for (l = ctx->builders; l; l = l->next) {
6742 LLVMBuilderRef builder = (LLVMBuilderRef)l->data;
6743 LLVMDisposeBuilder (builder);
6750 * mono_llvm_emit_method:
6752 * Emit LLVM IL from the mono IL, and compile it to native code using LLVM.
6755 mono_llvm_emit_method (MonoCompile *cfg)
6759 gboolean is_linkonce = FALSE;
6762 /* The code below might acquire the loader lock, so use it for global locking */
6763 mono_loader_lock ();
6765 /* Used to communicate with the callbacks */
6766 mono_native_tls_set_value (current_cfg_tls_id, cfg);
6768 ctx = g_new0 (EmitContext, 1);
6770 ctx->mempool = cfg->mempool;
6773 * This maps vregs to the LLVM instruction defining them
6775 ctx->values = g_new0 (LLVMValueRef, cfg->next_vreg);
6777 * This maps vregs for volatile variables to the LLVM instruction defining their
6780 ctx->addresses = g_new0 (LLVMValueRef, cfg->next_vreg);
6781 ctx->vreg_types = g_new0 (LLVMTypeRef, cfg->next_vreg);
6782 ctx->is_vphi = g_new0 (gboolean, cfg->next_vreg);
6783 ctx->vreg_cli_types = g_new0 (MonoType*, cfg->next_vreg);
6784 ctx->phi_values = g_ptr_array_sized_new (256);
6786 * This signals whenever the vreg was defined by a phi node with no input vars
6787 * (i.e. all its input bblocks end with NOT_REACHABLE).
6789 ctx->is_dead = g_new0 (gboolean, cfg->next_vreg);
6790 /* Whenever the bblock is unreachable */
6791 ctx->unreachable = g_new0 (gboolean, cfg->max_block_num);
6792 ctx->bblock_list = g_ptr_array_sized_new (256);
6794 ctx->region_to_handler = g_hash_table_new (NULL, NULL);
6795 ctx->clause_to_handler = g_hash_table_new (NULL, NULL);
6796 ctx->method_to_callers = g_hash_table_new (NULL, NULL);
6797 ctx->jit_callees = g_hash_table_new (NULL, NULL);
6798 if (cfg->compile_aot) {
6799 ctx->module = &aot_module;
6803 * Allow the linker to discard duplicate copies of wrappers, generic instances etc. by using the 'linkonce'
6804 * linkage for them. This requires the following:
6805 * - the method needs to have a unique mangled name
6806 * - llvmonly mode, since the code in aot-runtime.c would initialize got slots in the wrong aot image etc.
6808 is_linkonce = ctx->module->llvm_only && ctx->module->static_link && mono_aot_is_linkonce_method (cfg->method);
6810 method_name = mono_aot_get_mangled_method_name (cfg->method);
6812 is_linkonce = FALSE;
6815 printf ("%s %s\n", mono_method_full_name (cfg->method, 1), method_name);
6817 printf ("%s\n", mono_method_full_name (cfg->method, 1));
6821 method_name = mono_aot_get_method_name (cfg);
6822 cfg->llvm_method_name = g_strdup (method_name);
6824 init_jit_module (cfg->domain);
6825 ctx->module = (MonoLLVMModule*)domain_jit_info (cfg->domain)->llvm_module;
6826 method_name = mono_method_full_name (cfg->method, TRUE);
6828 ctx->method_name = method_name;
6829 ctx->is_linkonce = is_linkonce;
6831 #if LLVM_API_VERSION > 100
6832 if (cfg->compile_aot)
6833 ctx->lmodule = ctx->module->lmodule;
6835 ctx->lmodule = LLVMModuleCreateWithName ("jit-module");
6837 ctx->lmodule = ctx->module->lmodule;
6839 ctx->llvm_only = ctx->module->llvm_only;
6841 emit_method_inner (ctx);
6843 if (!ctx_ok (ctx)) {
6845 /* Need to add unused phi nodes as they can be referenced by other values */
6846 LLVMBasicBlockRef phi_bb = LLVMAppendBasicBlock (ctx->lmethod, "PHI_BB");
6847 LLVMBuilderRef builder;
6849 builder = create_builder (ctx);
6850 LLVMPositionBuilderAtEnd (builder, phi_bb);
6852 for (i = 0; i < ctx->phi_values->len; ++i) {
6853 LLVMValueRef v = (LLVMValueRef)g_ptr_array_index (ctx->phi_values, i);
6854 if (LLVMGetInstructionParent (v) == NULL)
6855 LLVMInsertIntoBuilder (builder, v);
6858 LLVMDeleteFunction (ctx->lmethod);
6864 mono_native_tls_set_value (current_cfg_tls_id, NULL);
6866 mono_loader_unlock ();
6870 emit_method_inner (EmitContext *ctx)
6872 MonoCompile *cfg = ctx->cfg;
6873 MonoMethodSignature *sig;
6875 LLVMTypeRef method_type;
6876 LLVMValueRef method = NULL;
6877 LLVMValueRef *values = ctx->values;
6878 int i, max_block_num, bb_index;
6879 gboolean last = FALSE;
6880 LLVMCallInfo *linfo;
6881 LLVMModuleRef lmodule = ctx->lmodule;
6883 GPtrArray *bblock_list = ctx->bblock_list;
6884 MonoMethodHeader *header;
6885 MonoExceptionClause *clause;
6888 if (cfg->gsharedvt && !cfg->llvm_only) {
6889 set_failure (ctx, "gsharedvt");
6895 static int count = 0;
6898 if (g_getenv ("LLVM_COUNT")) {
6899 if (count == atoi (g_getenv ("LLVM_COUNT"))) {
6900 printf ("LAST: %s\n", mono_method_full_name (cfg->method, TRUE));
6904 if (count > atoi (g_getenv ("LLVM_COUNT"))) {
6905 set_failure (ctx, "count");
6912 sig = mono_method_signature (cfg->method);
6915 linfo = get_llvm_call_info (cfg, sig);
6921 linfo->rgctx_arg = TRUE;
6922 ctx->method_type = method_type = sig_to_llvm_sig_full (ctx, sig, linfo);
6926 method = LLVMAddFunction (lmodule, ctx->method_name, method_type);
6927 ctx->lmethod = method;
6929 if (!cfg->llvm_only)
6930 LLVMSetFunctionCallConv (method, LLVMMono1CallConv);
6931 LLVMSetLinkage (method, LLVMPrivateLinkage);
6933 LLVMAddFunctionAttr (method, LLVMUWTable);
6935 if (cfg->compile_aot) {
6936 LLVMSetLinkage (method, LLVMInternalLinkage);
6937 if (ctx->module->external_symbols) {
6938 LLVMSetLinkage (method, LLVMExternalLinkage);
6939 LLVMSetVisibility (method, LLVMHiddenVisibility);
6941 if (ctx->is_linkonce) {
6942 LLVMSetLinkage (method, LLVMLinkOnceAnyLinkage);
6943 LLVMSetVisibility (method, LLVMDefaultVisibility);
6946 #if LLVM_API_VERSION > 100
6947 LLVMSetLinkage (method, LLVMExternalLinkage);
6949 LLVMSetLinkage (method, LLVMPrivateLinkage);
6953 if (cfg->method->save_lmf && !cfg->llvm_only) {
6954 set_failure (ctx, "lmf");
6958 if (sig->pinvoke && cfg->method->wrapper_type != MONO_WRAPPER_RUNTIME_INVOKE && !cfg->llvm_only) {
6959 set_failure (ctx, "pinvoke signature");
6963 header = cfg->header;
6964 for (i = 0; i < header->num_clauses; ++i) {
6965 clause = &header->clauses [i];
6966 if (clause->flags != MONO_EXCEPTION_CLAUSE_FINALLY && clause->flags != MONO_EXCEPTION_CLAUSE_NONE) {
6967 set_failure (ctx, "non-finally/catch clause.");
6971 if (header->num_clauses || (cfg->method->iflags & METHOD_IMPL_ATTRIBUTE_NOINLINING) || cfg->no_inline)
6972 /* We can't handle inlined methods with clauses */
6973 LLVMAddFunctionAttr (method, LLVMNoInlineAttribute);
6975 if (linfo->rgctx_arg) {
6976 ctx->rgctx_arg = LLVMGetParam (method, linfo->rgctx_arg_pindex);
6977 ctx->rgctx_arg_pindex = linfo->rgctx_arg_pindex;
6979 * We mark the rgctx parameter with the inreg attribute, which is mapped to
6980 * MONO_ARCH_RGCTX_REG in the Mono calling convention in llvm, i.e.
6981 * CC_X86_64_Mono in X86CallingConv.td.
6983 if (!ctx->llvm_only)
6984 LLVMAddAttribute (ctx->rgctx_arg, LLVMInRegAttribute);
6985 LLVMSetValueName (ctx->rgctx_arg, "rgctx");
6987 ctx->rgctx_arg_pindex = -1;
6989 if (cfg->vret_addr) {
6990 values [cfg->vret_addr->dreg] = LLVMGetParam (method, linfo->vret_arg_pindex);
6991 LLVMSetValueName (values [cfg->vret_addr->dreg], "vret");
6992 if (linfo->ret.storage == LLVMArgVtypeByRef) {
6993 LLVMAddAttribute (LLVMGetParam (method, linfo->vret_arg_pindex), LLVMStructRetAttribute);
6994 LLVMAddAttribute (LLVMGetParam (method, linfo->vret_arg_pindex), LLVMNoAliasAttribute);
6999 ctx->this_arg_pindex = linfo->this_arg_pindex;
7000 ctx->this_arg = LLVMGetParam (method, linfo->this_arg_pindex);
7001 values [cfg->args [0]->dreg] = ctx->this_arg;
7002 LLVMSetValueName (values [cfg->args [0]->dreg], "this");
7005 names = g_new (char *, sig->param_count);
7006 mono_method_get_param_names (cfg->method, (const char **) names);
7008 /* Set parameter names/attributes */
7009 for (i = 0; i < sig->param_count; ++i) {
7010 LLVMArgInfo *ainfo = &linfo->args [i + sig->hasthis];
7012 int pindex = ainfo->pindex + ainfo->ndummy_fpargs;
7015 for (j = 0; j < ainfo->ndummy_fpargs; ++j) {
7016 name = g_strdup_printf ("dummy_%d_%d", i, j);
7017 LLVMSetValueName (LLVMGetParam (method, ainfo->pindex + j), name);
7021 if (ainfo->storage == LLVMArgVtypeInReg && ainfo->pair_storage [0] == LLVMArgNone && ainfo->pair_storage [1] == LLVMArgNone)
7024 values [cfg->args [i + sig->hasthis]->dreg] = LLVMGetParam (method, pindex);
7025 if (ainfo->storage == LLVMArgGsharedvtFixed || ainfo->storage == LLVMArgGsharedvtFixedVtype) {
7026 if (names [i] && names [i][0] != '\0')
7027 name = g_strdup_printf ("p_arg_%s", names [i]);
7029 name = g_strdup_printf ("p_arg_%d", i);
7031 if (names [i] && names [i][0] != '\0')
7032 name = g_strdup_printf ("arg_%s", names [i]);
7034 name = g_strdup_printf ("arg_%d", i);
7036 LLVMSetValueName (values [cfg->args [i + sig->hasthis]->dreg], name);
7038 if (ainfo->storage == LLVMArgVtypeByVal)
7039 LLVMAddAttribute (LLVMGetParam (method, pindex), LLVMByValAttribute);
7041 if (ainfo->storage == LLVMArgVtypeByRef) {
7043 cfg->args [i + sig->hasthis]->opcode = OP_VTARG_ADDR;
7048 if (ctx->module->emit_dwarf && cfg->compile_aot && mono_debug_enabled ()) {
7049 ctx->minfo = mono_debug_lookup_method (cfg->method);
7050 ctx->dbg_md = emit_dbg_subprogram (ctx, cfg, method, ctx->method_name);
7054 for (bb = cfg->bb_entry; bb; bb = bb->next_bb)
7055 max_block_num = MAX (max_block_num, bb->block_num);
7056 ctx->bblocks = bblocks = g_new0 (BBInfo, max_block_num + 1);
7058 /* Add branches between non-consecutive bblocks */
7059 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
7060 if (bb->last_ins && MONO_IS_COND_BRANCH_OP (bb->last_ins) &&
7061 bb->next_bb != bb->last_ins->inst_false_bb) {
7063 MonoInst *inst = (MonoInst*)mono_mempool_alloc0 (cfg->mempool, sizeof (MonoInst));
7064 inst->opcode = OP_BR;
7065 inst->inst_target_bb = bb->last_ins->inst_false_bb;
7066 mono_bblock_add_inst (bb, inst);
7071 * The INDIRECT flag added by OP_LDADDR inhibits optimizations, even if the LDADDR
7072 * was later optimized away, so clear these flags, and add them back for the still
7073 * present OP_LDADDR instructions.
7075 for (i = 0; i < cfg->next_vreg; ++i) {
7078 ins = get_vreg_to_inst (cfg, i);
7079 if (ins && ins != cfg->rgctx_var)
7080 ins->flags &= ~MONO_INST_INDIRECT;
7084 * Make a first pass over the code to precreate PHI nodes/set INDIRECT flags.
7086 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
7088 LLVMBuilderRef builder;
7090 char dname_buf[128];
7092 builder = create_builder (ctx);
7094 for (ins = bb->code; ins; ins = ins->next) {
7095 switch (ins->opcode) {
7100 LLVMTypeRef phi_type = llvm_type_to_stack_type (cfg, type_to_llvm_type (ctx, &ins->klass->byval_arg));
7105 if (ins->opcode == OP_VPHI) {
7106 /* Treat valuetype PHI nodes as operating on the address itself */
7107 g_assert (ins->klass);
7108 phi_type = LLVMPointerType (type_to_llvm_type (ctx, &ins->klass->byval_arg), 0);
7112 * Have to precreate these, as they can be referenced by
7113 * earlier instructions.
7115 sprintf (dname_buf, "t%d", ins->dreg);
7117 values [ins->dreg] = LLVMBuildPhi (builder, phi_type, dname);
7119 if (ins->opcode == OP_VPHI)
7120 ctx->addresses [ins->dreg] = values [ins->dreg];
7122 g_ptr_array_add (ctx->phi_values, values [ins->dreg]);
7125 * Set the expected type of the incoming arguments since these have
7126 * to have the same type.
7128 for (i = 0; i < ins->inst_phi_args [0]; i++) {
7129 int sreg1 = ins->inst_phi_args [i + 1];
7132 if (ins->opcode == OP_VPHI)
7133 ctx->is_vphi [sreg1] = TRUE;
7134 ctx->vreg_types [sreg1] = phi_type;
7140 ((MonoInst*)ins->inst_p0)->flags |= MONO_INST_INDIRECT;
7149 * Create an ordering for bblocks, use the depth first order first, then
7150 * put the exception handling bblocks last.
7152 for (bb_index = 0; bb_index < cfg->num_bblocks; ++bb_index) {
7153 bb = cfg->bblocks [bb_index];
7154 if (!(bb->region != -1 && !MONO_BBLOCK_IS_IN_REGION (bb, MONO_REGION_TRY))) {
7155 g_ptr_array_add (bblock_list, bb);
7156 bblocks [bb->block_num].added = TRUE;
7160 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
7161 if (!bblocks [bb->block_num].added)
7162 g_ptr_array_add (bblock_list, bb);
7166 * Second pass: generate code.
7169 LLVMBuilderRef entry_builder = create_builder (ctx);
7170 LLVMBasicBlockRef entry_bb = get_bb (ctx, cfg->bb_entry);
7171 LLVMPositionBuilderAtEnd (entry_builder, entry_bb);
7172 emit_entry_bb (ctx, entry_builder);
7174 // Make landing pads first
7175 ctx->exc_meta = g_hash_table_new_full (NULL, NULL, NULL, NULL);
7177 if (ctx->llvm_only) {
7178 size_t group_index = 0;
7179 while (group_index < cfg->header->num_clauses) {
7181 size_t cursor = group_index;
7182 while (cursor < cfg->header->num_clauses &&
7183 CLAUSE_START (&cfg->header->clauses [cursor]) == CLAUSE_START (&cfg->header->clauses [group_index]) &&
7184 CLAUSE_END (&cfg->header->clauses [cursor]) == CLAUSE_END (&cfg->header->clauses [group_index])) {
7189 LLVMBasicBlockRef lpad_bb = emit_landing_pad (ctx, group_index, count);
7190 intptr_t key = CLAUSE_END (&cfg->header->clauses [group_index]);
7191 g_hash_table_insert (ctx->exc_meta, (gpointer)key, lpad_bb);
7193 group_index = cursor;
7197 for (bb_index = 0; bb_index < bblock_list->len; ++bb_index) {
7198 bb = (MonoBasicBlock*)g_ptr_array_index (bblock_list, bb_index);
7200 // Prune unreachable mono BBs.
7201 if (!(bb == cfg->bb_entry || bb->in_count > 0))
7204 process_bb (ctx, bb);
7208 g_hash_table_destroy (ctx->exc_meta);
7210 mono_memory_barrier ();
7212 /* Add incoming phi values */
7213 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
7214 GSList *l, *ins_list;
7216 ins_list = bblocks [bb->block_num].phi_nodes;
7218 for (l = ins_list; l; l = l->next) {
7219 PhiNode *node = (PhiNode*)l->data;
7220 MonoInst *phi = node->phi;
7221 int sreg1 = node->sreg;
7222 LLVMBasicBlockRef in_bb;
7227 in_bb = get_end_bb (ctx, node->in_bb);
7229 if (ctx->unreachable [node->in_bb->block_num])
7232 if (!values [sreg1]) {
7233 /* Can happen with values in EH clauses */
7234 set_failure (ctx, "incoming phi sreg1");
7238 if (phi->opcode == OP_VPHI) {
7239 g_assert (LLVMTypeOf (ctx->addresses [sreg1]) == LLVMTypeOf (values [phi->dreg]));
7240 LLVMAddIncoming (values [phi->dreg], &ctx->addresses [sreg1], &in_bb, 1);
7242 if (LLVMTypeOf (values [sreg1]) != LLVMTypeOf (values [phi->dreg])) {
7243 set_failure (ctx, "incoming phi arg type mismatch");
7246 g_assert (LLVMTypeOf (values [sreg1]) == LLVMTypeOf (values [phi->dreg]));
7247 LLVMAddIncoming (values [phi->dreg], &values [sreg1], &in_bb, 1);
7252 /* Nullify empty phi instructions */
7253 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
7254 GSList *l, *ins_list;
7256 ins_list = bblocks [bb->block_num].phi_nodes;
7258 for (l = ins_list; l; l = l->next) {
7259 PhiNode *node = (PhiNode*)l->data;
7260 MonoInst *phi = node->phi;
7261 LLVMValueRef phi_ins = values [phi->dreg];
7264 /* Already removed */
7267 if (LLVMCountIncoming (phi_ins) == 0) {
7268 mono_llvm_replace_uses_of (phi_ins, LLVMConstNull (LLVMTypeOf (phi_ins)));
7269 LLVMInstructionEraseFromParent (phi_ins);
7270 values [phi->dreg] = NULL;
7275 /* Create the SWITCH statements for ENDFINALLY instructions */
7276 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
7277 BBInfo *info = &bblocks [bb->block_num];
7279 for (l = info->endfinally_switch_ins_list; l; l = l->next) {
7280 LLVMValueRef switch_ins = (LLVMValueRef)l->data;
7281 GSList *bb_list = info->call_handler_return_bbs;
7283 for (i = 0; i < g_slist_length (bb_list); ++i)
7284 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), i + 1, FALSE), (LLVMBasicBlockRef)(g_slist_nth (bb_list, i)->data));
7288 /* Initialize the method if needed */
7289 if (cfg->compile_aot && ctx->llvm_only) {
7290 // FIXME: Add more shared got entries
7291 ctx->builder = create_builder (ctx);
7292 LLVMPositionBuilderAtEnd (ctx->builder, ctx->init_bb);
7294 ctx->module->max_method_idx = MAX (ctx->module->max_method_idx, cfg->method_index);
7296 // FIXME: beforefieldinit
7298 * NATIVE_TO_MANAGED methods might be called on a thread not attached to the runtime, so they are initialized when loaded
7299 * in load_method ().
7301 if ((ctx->has_got_access || mono_class_get_cctor (cfg->method->klass)) && !(cfg->method->wrapper_type == MONO_WRAPPER_NATIVE_TO_MANAGED)) {
7303 * linkonce methods shouldn't have initialization,
7304 * because they might belong to assemblies which
7305 * haven't been loaded yet.
7307 g_assert (!ctx->is_linkonce);
7308 emit_init_method (ctx);
7310 LLVMBuildBr (ctx->builder, ctx->inited_bb);
7314 if (cfg->llvm_only) {
7315 GHashTableIter iter;
7317 GSList *callers, *l, *l2;
7320 * Add the contents of ctx->method_to_callers to module->method_to_callers.
7321 * We can't do this earlier, as it contains llvm instructions which can be
7322 * freed if compilation fails.
7323 * FIXME: Get rid of this when all methods can be llvm compiled.
7325 g_hash_table_iter_init (&iter, ctx->method_to_callers);
7326 while (g_hash_table_iter_next (&iter, (void**)&method, (void**)&callers)) {
7327 for (l = callers; l; l = l->next) {
7328 l2 = (GSList*)g_hash_table_lookup (ctx->module->method_to_callers, method);
7329 l2 = g_slist_prepend (l2, l->data);
7330 g_hash_table_insert (ctx->module->method_to_callers, method, l2);
7335 if (cfg->verbose_level > 1)
7336 mono_llvm_dump_value (method);
7338 if (cfg->compile_aot && !cfg->llvm_only)
7339 mark_as_used (ctx->module, method);
7341 if (!cfg->llvm_only) {
7342 LLVMValueRef md_args [16];
7343 LLVMValueRef md_node;
7346 if (cfg->compile_aot)
7347 method_index = mono_aot_get_method_index (cfg->orig_method);
7350 md_args [0] = LLVMMDString (ctx->method_name, strlen (ctx->method_name));
7351 md_args [1] = LLVMConstInt (LLVMInt32Type (), method_index, FALSE);
7352 md_node = LLVMMDNode (md_args, 2);
7353 LLVMAddNamedMetadataOperand (lmodule, "mono.function_indexes", md_node);
7354 //LLVMSetMetadata (method, md_kind, LLVMMDNode (&md_arg, 1));
7357 if (cfg->compile_aot) {
7358 /* Don't generate native code, keep the LLVM IR */
7359 if (cfg->verbose_level)
7360 printf ("%s emitted as %s\n", mono_method_full_name (cfg->method, TRUE), ctx->method_name);
7362 #if LLVM_API_VERSION < 100
7363 /* VerifyFunction can't handle some of the debug info created by DIBuilder in llvm 3.9 */
7364 int err = LLVMVerifyFunction(ctx->lmethod, LLVMPrintMessageAction);
7365 g_assert (err == 0);
7368 //LLVMVerifyFunction(method, 0);
7369 #if LLVM_API_VERSION > 100
7370 MonoDomain *domain = mono_domain_get ();
7371 MonoJitDomainInfo *domain_info;
7372 int nvars = g_hash_table_size (ctx->jit_callees);
7373 LLVMValueRef *callee_vars = g_new0 (LLVMValueRef, nvars);
7374 gpointer *callee_addrs = g_new0 (gpointer, nvars);
7375 GHashTableIter iter;
7381 * Compute the addresses of the LLVM globals pointing to the
7382 * methods called by the current method. Pass it to the trampoline
7383 * code so it can update them after their corresponding method was
7386 g_hash_table_iter_init (&iter, ctx->jit_callees);
7388 while (g_hash_table_iter_next (&iter, NULL, (void**)&var))
7389 callee_vars [i ++] = var;
7391 cfg->native_code = mono_llvm_compile_method (ctx->module->mono_ee, ctx->lmethod, nvars, callee_vars, callee_addrs, &eh_frame);
7393 decode_llvm_eh_info (ctx, eh_frame);
7395 mono_domain_lock (domain);
7396 domain_info = domain_jit_info (domain);
7397 if (!domain_info->llvm_jit_callees)
7398 domain_info->llvm_jit_callees = g_hash_table_new (NULL, NULL);
7399 g_hash_table_iter_init (&iter, ctx->jit_callees);
7401 while (g_hash_table_iter_next (&iter, (void**)&callee, (void**)&var)) {
7402 GSList *addrs = g_hash_table_lookup (domain_info->llvm_jit_callees, callee);
7403 addrs = g_slist_prepend (addrs, callee_addrs [i]);
7404 g_hash_table_insert (domain_info->llvm_jit_callees, callee, addrs);
7407 mono_domain_unlock (domain);
7409 mono_llvm_optimize_method (ctx->module->mono_ee, ctx->lmethod);
7411 if (cfg->verbose_level > 1)
7412 mono_llvm_dump_value (ctx->lmethod);
7414 cfg->native_code = (unsigned char*)LLVMGetPointerToGlobal (ctx->module->ee, ctx->lmethod);
7416 /* Set by emit_cb */
7417 g_assert (cfg->code_len);
7421 if (ctx->module->method_to_lmethod)
7422 g_hash_table_insert (ctx->module->method_to_lmethod, cfg->method, ctx->lmethod);
7423 if (ctx->module->idx_to_lmethod)
7424 g_hash_table_insert (ctx->module->idx_to_lmethod, GINT_TO_POINTER (cfg->method_index), ctx->lmethod);
7426 if (ctx->llvm_only && cfg->orig_method->klass->valuetype && !(cfg->orig_method->flags & METHOD_ATTRIBUTE_STATIC))
7427 emit_unbox_tramp (ctx, ctx->method_name, ctx->method_type, ctx->lmethod, cfg->method_index);
7431 * mono_llvm_create_vars:
7433 * Same as mono_arch_create_vars () for LLVM.
7436 mono_llvm_create_vars (MonoCompile *cfg)
7438 MonoMethodSignature *sig;
7440 sig = mono_method_signature (cfg->method);
7441 if (cfg->gsharedvt && cfg->llvm_only) {
7442 if (mini_is_gsharedvt_variable_signature (sig) && sig->ret->type != MONO_TYPE_VOID) {
7443 cfg->vret_addr = mono_compile_create_var (cfg, &mono_get_intptr_class ()->byval_arg, OP_ARG);
7444 if (G_UNLIKELY (cfg->verbose_level > 1)) {
7445 printf ("vret_addr = ");
7446 mono_print_ins (cfg->vret_addr);
7450 mono_arch_create_vars (cfg);
7455 * mono_llvm_emit_call:
7457 * Same as mono_arch_emit_call () for LLVM.
7460 mono_llvm_emit_call (MonoCompile *cfg, MonoCallInst *call)
7463 MonoMethodSignature *sig;
7464 int i, n, stack_size;
7469 sig = call->signature;
7470 n = sig->param_count + sig->hasthis;
7472 call->cinfo = get_llvm_call_info (cfg, sig);
7474 if (cfg->disable_llvm)
7477 if (sig->call_convention == MONO_CALL_VARARG) {
7478 cfg->exception_message = g_strdup ("varargs");
7479 cfg->disable_llvm = TRUE;
7482 for (i = 0; i < n; ++i) {
7485 ainfo = call->cinfo->args + i;
7487 in = call->args [i];
7489 /* Simply remember the arguments */
7490 switch (ainfo->storage) {
7491 case LLVMArgNormal: {
7492 MonoType *t = (sig->hasthis && i == 0) ? &mono_get_intptr_class ()->byval_arg : ainfo->type;
7495 opcode = mono_type_to_regmove (cfg, t);
7496 if (opcode == OP_FMOVE) {
7497 MONO_INST_NEW (cfg, ins, OP_FMOVE);
7498 ins->dreg = mono_alloc_freg (cfg);
7499 } else if (opcode == OP_LMOVE) {
7500 MONO_INST_NEW (cfg, ins, OP_LMOVE);
7501 ins->dreg = mono_alloc_lreg (cfg);
7502 } else if (opcode == OP_RMOVE) {
7503 MONO_INST_NEW (cfg, ins, OP_RMOVE);
7504 ins->dreg = mono_alloc_freg (cfg);
7506 MONO_INST_NEW (cfg, ins, OP_MOVE);
7507 ins->dreg = mono_alloc_ireg (cfg);
7509 ins->sreg1 = in->dreg;
7512 case LLVMArgVtypeByVal:
7513 case LLVMArgVtypeByRef:
7514 case LLVMArgVtypeInReg:
7515 case LLVMArgVtypeAsScalar:
7516 case LLVMArgAsIArgs:
7517 case LLVMArgAsFpArgs:
7518 case LLVMArgGsharedvtVariable:
7519 case LLVMArgGsharedvtFixed:
7520 case LLVMArgGsharedvtFixedVtype:
7521 MONO_INST_NEW (cfg, ins, OP_LLVM_OUTARG_VT);
7522 ins->dreg = mono_alloc_ireg (cfg);
7523 ins->sreg1 = in->dreg;
7524 ins->inst_p0 = mono_mempool_alloc0 (cfg->mempool, sizeof (LLVMArgInfo));
7525 memcpy (ins->inst_p0, ainfo, sizeof (LLVMArgInfo));
7526 ins->inst_vtype = ainfo->type;
7527 ins->klass = mono_class_from_mono_type (ainfo->type);
7530 cfg->exception_message = g_strdup ("ainfo->storage");
7531 cfg->disable_llvm = TRUE;
7535 if (!cfg->disable_llvm) {
7536 MONO_ADD_INS (cfg->cbb, ins);
7537 mono_call_inst_add_outarg_reg (cfg, call, ins->dreg, 0, FALSE);
7542 static unsigned char*
7543 alloc_cb (LLVMValueRef function, int size)
7547 cfg = (MonoCompile*)mono_native_tls_get_value (current_cfg_tls_id);
7551 return (unsigned char*)mono_domain_code_reserve (cfg->domain, size);
7553 return (unsigned char*)mono_domain_code_reserve (mono_domain_get (), size);
7558 emitted_cb (LLVMValueRef function, void *start, void *end)
7562 cfg = (MonoCompile*)mono_native_tls_get_value (current_cfg_tls_id);
7564 cfg->code_len = (guint8*)end - (guint8*)start;
7568 exception_cb (void *data)
7571 MonoJitExceptionInfo *ei;
7572 guint32 ei_len, i, j, nested_len, nindex;
7573 gpointer *type_info;
7574 int this_reg, this_offset;
7576 cfg = (MonoCompile*)mono_native_tls_get_value (current_cfg_tls_id);
7580 * data points to a DWARF FDE structure, convert it to our unwind format and
7582 * An alternative would be to save it directly, and modify our unwinder to work
7585 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);
7586 if (cfg->verbose_level > 1)
7587 mono_print_unwind_info (cfg->encoded_unwind_ops, cfg->encoded_unwind_ops_len);
7589 /* Count nested clauses */
7591 for (i = 0; i < ei_len; ++i) {
7592 gint32 cindex1 = *(gint32*)type_info [i];
7593 MonoExceptionClause *clause1 = &cfg->header->clauses [cindex1];
7595 for (j = 0; j < cfg->header->num_clauses; ++j) {
7597 MonoExceptionClause *clause2 = &cfg->header->clauses [cindex2];
7599 if (cindex1 != cindex2 && clause1->try_offset >= clause2->try_offset && clause1->handler_offset <= clause2->handler_offset) {
7605 cfg->llvm_ex_info = (MonoJitExceptionInfo*)mono_mempool_alloc0 (cfg->mempool, (ei_len + nested_len) * sizeof (MonoJitExceptionInfo));
7606 cfg->llvm_ex_info_len = ei_len + nested_len;
7607 memcpy (cfg->llvm_ex_info, ei, ei_len * sizeof (MonoJitExceptionInfo));
7608 /* Fill the rest of the information from the type info */
7609 for (i = 0; i < ei_len; ++i) {
7610 gint32 clause_index = *(gint32*)type_info [i];
7611 MonoExceptionClause *clause = &cfg->header->clauses [clause_index];
7613 cfg->llvm_ex_info [i].flags = clause->flags;
7614 cfg->llvm_ex_info [i].data.catch_class = clause->data.catch_class;
7615 cfg->llvm_ex_info [i].clause_index = clause_index;
7619 * For nested clauses, the LLVM produced exception info associates the try interval with
7620 * the innermost handler, while mono expects it to be associated with all nesting clauses.
7621 * So add new clauses which use the IL info (catch class etc.) from the nesting clause,
7622 * and everything else from the nested clause.
7625 for (i = 0; i < ei_len; ++i) {
7626 gint32 cindex1 = *(gint32*)type_info [i];
7627 MonoExceptionClause *clause1 = &cfg->header->clauses [cindex1];
7629 for (j = 0; j < cfg->header->num_clauses; ++j) {
7631 MonoExceptionClause *clause2 = &cfg->header->clauses [cindex2];
7632 MonoJitExceptionInfo *nesting_ei, *nested_ei;
7634 if (cindex1 != cindex2 && clause1->try_offset >= clause2->try_offset && clause1->handler_offset <= clause2->handler_offset) {
7635 /* clause1 is the nested clause */
7636 nested_ei = &cfg->llvm_ex_info [i];
7637 nesting_ei = &cfg->llvm_ex_info [nindex];
7640 memcpy (nesting_ei, nested_ei, sizeof (MonoJitExceptionInfo));
7642 nesting_ei->flags = clause2->flags;
7643 nesting_ei->data.catch_class = clause2->data.catch_class;
7644 nesting_ei->clause_index = cindex2;
7648 g_assert (nindex == ei_len + nested_len);
7649 cfg->llvm_this_reg = this_reg;
7650 cfg->llvm_this_offset = this_offset;
7652 /* type_info [i] is cfg mempool allocated, no need to free it */
7658 #if LLVM_API_VERSION > 100
7660 * decode_llvm_eh_info:
7662 * Decode the EH table emitted by llvm in jit mode, and store
7663 * the result into cfg.
7666 decode_llvm_eh_info (EmitContext *ctx, gpointer eh_frame)
7668 MonoCompile *cfg = ctx->cfg;
7671 MonoLLVMFDEInfo info;
7672 MonoJitExceptionInfo *ei;
7673 guint8 *p = eh_frame;
7674 int version, fde_count, fde_offset;
7675 guint32 ei_len, i, nested_len;
7676 gpointer *type_info;
7680 * Decode the one element EH table emitted by the MonoException class
7684 /* Similar to decode_llvm_mono_eh_frame () in aot-runtime.c */
7687 g_assert (version == 3);
7690 p = (guint8 *)ALIGN_PTR_TO (p, 4);
7692 fde_count = *(guint32*)p;
7696 g_assert (fde_count <= 2);
7698 /* The first entry is the real method */
7699 g_assert (table [0] == 1);
7700 fde_offset = table [1];
7701 table += fde_count * 2;
7703 cfg->code_len = table [0];
7704 fde_len = table [1] - fde_offset;
7707 fde = (guint8*)eh_frame + fde_offset;
7708 cie = (guint8*)table;
7710 mono_unwind_decode_llvm_mono_fde (fde, fde_len, cie, cfg->native_code, &info);
7712 cfg->encoded_unwind_ops = info.unw_info;
7713 cfg->encoded_unwind_ops_len = info.unw_info_len;
7714 if (cfg->verbose_level > 1)
7715 mono_print_unwind_info (cfg->encoded_unwind_ops, cfg->encoded_unwind_ops_len);
7716 if (info.this_reg != -1) {
7717 cfg->llvm_this_reg = info.this_reg;
7718 cfg->llvm_this_offset = info.this_offset;
7722 ei_len = info.ex_info_len;
7723 type_info = info.type_info;
7725 // Nested clauses are currently disabled
7728 cfg->llvm_ex_info = (MonoJitExceptionInfo*)mono_mempool_alloc0 (cfg->mempool, (ei_len + nested_len) * sizeof (MonoJitExceptionInfo));
7729 cfg->llvm_ex_info_len = ei_len + nested_len;
7730 memcpy (cfg->llvm_ex_info, ei, ei_len * sizeof (MonoJitExceptionInfo));
7731 /* Fill the rest of the information from the type info */
7732 for (i = 0; i < ei_len; ++i) {
7733 gint32 clause_index = *(gint32*)type_info [i];
7734 MonoExceptionClause *clause = &cfg->header->clauses [clause_index];
7736 cfg->llvm_ex_info [i].flags = clause->flags;
7737 cfg->llvm_ex_info [i].data.catch_class = clause->data.catch_class;
7738 cfg->llvm_ex_info [i].clause_index = clause_index;
7744 dlsym_cb (const char *name, void **symbol)
7750 if (!strcmp (name, "__bzero")) {
7751 *symbol = (void*)bzero;
7753 current = mono_dl_open (NULL, 0, NULL);
7756 err = mono_dl_symbol (current, name, symbol);
7758 mono_dl_close (current);
7760 #ifdef MONO_ARCH_HAVE_CREATE_LLVM_NATIVE_THUNK
7761 *symbol = (char*)mono_arch_create_llvm_native_thunk (mono_domain_get (), (guint8*)(*symbol));
7767 AddFunc (LLVMModuleRef module, const char *name, LLVMTypeRef ret_type, LLVMTypeRef *param_types, int nparams)
7769 LLVMAddFunction (module, name, LLVMFunctionType (ret_type, param_types, nparams, FALSE));
7773 AddFunc2 (LLVMModuleRef module, const char *name, LLVMTypeRef ret_type, LLVMTypeRef param_type1, LLVMTypeRef param_type2)
7775 LLVMTypeRef param_types [4];
7777 param_types [0] = param_type1;
7778 param_types [1] = param_type2;
7780 AddFunc (module, name, ret_type, param_types, 2);
7786 INTRINS_SADD_OVF_I32,
7787 INTRINS_UADD_OVF_I32,
7788 INTRINS_SSUB_OVF_I32,
7789 INTRINS_USUB_OVF_I32,
7790 INTRINS_SMUL_OVF_I32,
7791 INTRINS_UMUL_OVF_I32,
7792 INTRINS_SADD_OVF_I64,
7793 INTRINS_UADD_OVF_I64,
7794 INTRINS_SSUB_OVF_I64,
7795 INTRINS_USUB_OVF_I64,
7796 INTRINS_SMUL_OVF_I64,
7797 INTRINS_UMUL_OVF_I64,
7804 #if defined(TARGET_AMD64) || defined(TARGET_X86)
7805 INTRINS_SSE_PMOVMSKB,
7806 INTRINS_SSE_PSRLI_W,
7807 INTRINS_SSE_PSRAI_W,
7808 INTRINS_SSE_PSLLI_W,
7809 INTRINS_SSE_PSRLI_D,
7810 INTRINS_SSE_PSRAI_D,
7811 INTRINS_SSE_PSLLI_D,
7812 INTRINS_SSE_PSRLI_Q,
7813 INTRINS_SSE_PSLLI_Q,
7814 INTRINS_SSE_SQRT_PD,
7815 INTRINS_SSE_SQRT_PS,
7816 INTRINS_SSE_RSQRT_PS,
7818 INTRINS_SSE_CVTTPD2DQ,
7819 INTRINS_SSE_CVTTPS2DQ,
7820 INTRINS_SSE_CVTDQ2PD,
7821 INTRINS_SSE_CVTDQ2PS,
7822 INTRINS_SSE_CVTPD2DQ,
7823 INTRINS_SSE_CVTPS2DQ,
7824 INTRINS_SSE_CVTPD2PS,
7825 INTRINS_SSE_CVTPS2PD,
7828 INTRINS_SSE_PACKSSWB,
7829 INTRINS_SSE_PACKUSWB,
7830 INTRINS_SSE_PACKSSDW,
7831 INTRINS_SSE_PACKUSDW,
7836 INTRINS_SSE_ADDSUBPS,
7841 INTRINS_SSE_ADDSUBPD,
7844 INTRINS_SSE_PADDUSW,
7845 INTRINS_SSE_PSUBUSW,
7851 INTRINS_SSE_PADDUSB,
7852 INTRINS_SSE_PSUBUSB,
7864 static IntrinsicDesc intrinsics[] = {
7865 {INTRINS_MEMSET, "llvm.memset.p0i8.i32"},
7866 {INTRINS_MEMCPY, "llvm.memcpy.p0i8.p0i8.i32"},
7867 {INTRINS_SADD_OVF_I32, "llvm.sadd.with.overflow.i32"},
7868 {INTRINS_UADD_OVF_I32, "llvm.uadd.with.overflow.i32"},
7869 {INTRINS_SSUB_OVF_I32, "llvm.ssub.with.overflow.i32"},
7870 {INTRINS_USUB_OVF_I32, "llvm.usub.with.overflow.i32"},
7871 {INTRINS_SMUL_OVF_I32, "llvm.smul.with.overflow.i32"},
7872 {INTRINS_UMUL_OVF_I32, "llvm.umul.with.overflow.i32"},
7873 {INTRINS_SADD_OVF_I64, "llvm.sadd.with.overflow.i64"},
7874 {INTRINS_UADD_OVF_I64, "llvm.uadd.with.overflow.i64"},
7875 {INTRINS_SSUB_OVF_I64, "llvm.ssub.with.overflow.i64"},
7876 {INTRINS_USUB_OVF_I64, "llvm.usub.with.overflow.i64"},
7877 {INTRINS_SMUL_OVF_I64, "llvm.smul.with.overflow.i64"},
7878 {INTRINS_UMUL_OVF_I64, "llvm.umul.with.overflow.i64"},
7879 {INTRINS_SIN, "llvm.sin.f64"},
7880 {INTRINS_COS, "llvm.cos.f64"},
7881 {INTRINS_SQRT, "llvm.sqrt.f64"},
7882 /* This isn't an intrinsic, instead llvm seems to special case it by name */
7883 {INTRINS_FABS, "fabs"},
7884 {INTRINS_EXPECT_I8, "llvm.expect.i8"},
7885 {INTRINS_EXPECT_I1, "llvm.expect.i1"},
7886 #if defined(TARGET_AMD64) || defined(TARGET_X86)
7887 {INTRINS_SSE_PMOVMSKB, "llvm.x86.sse2.pmovmskb.128"},
7888 {INTRINS_SSE_PSRLI_W, "llvm.x86.sse2.psrli.w"},
7889 {INTRINS_SSE_PSRAI_W, "llvm.x86.sse2.psrai.w"},
7890 {INTRINS_SSE_PSLLI_W, "llvm.x86.sse2.pslli.w"},
7891 {INTRINS_SSE_PSRLI_D, "llvm.x86.sse2.psrli.d"},
7892 {INTRINS_SSE_PSRAI_D, "llvm.x86.sse2.psrai.d"},
7893 {INTRINS_SSE_PSLLI_D, "llvm.x86.sse2.pslli.d"},
7894 {INTRINS_SSE_PSRLI_Q, "llvm.x86.sse2.psrli.q"},
7895 {INTRINS_SSE_PSLLI_Q, "llvm.x86.sse2.pslli.q"},
7896 {INTRINS_SSE_SQRT_PD, "llvm.x86.sse2.sqrt.pd"},
7897 {INTRINS_SSE_SQRT_PS, "llvm.x86.sse.sqrt.ps"},
7898 {INTRINS_SSE_RSQRT_PS, "llvm.x86.sse.rsqrt.ps"},
7899 {INTRINS_SSE_RCP_PS, "llvm.x86.sse.rcp.ps"},
7900 {INTRINS_SSE_CVTTPD2DQ, "llvm.x86.sse2.cvttpd2dq"},
7901 {INTRINS_SSE_CVTTPS2DQ, "llvm.x86.sse2.cvttps2dq"},
7902 {INTRINS_SSE_CVTDQ2PD, "llvm.x86.sse2.cvtdq2pd"},
7903 {INTRINS_SSE_CVTDQ2PS, "llvm.x86.sse2.cvtdq2ps"},
7904 {INTRINS_SSE_CVTPD2DQ, "llvm.x86.sse2.cvtpd2dq"},
7905 {INTRINS_SSE_CVTPS2DQ, "llvm.x86.sse2.cvtps2dq"},
7906 {INTRINS_SSE_CVTPD2PS, "llvm.x86.sse2.cvtpd2ps"},
7907 {INTRINS_SSE_CVTPS2PD, "llvm.x86.sse2.cvtps2pd"},
7908 {INTRINS_SSE_CMPPD, "llvm.x86.sse2.cmp.pd"},
7909 {INTRINS_SSE_CMPPS, "llvm.x86.sse.cmp.ps"},
7910 {INTRINS_SSE_PACKSSWB, "llvm.x86.sse2.packsswb.128"},
7911 {INTRINS_SSE_PACKUSWB, "llvm.x86.sse2.packuswb.128"},
7912 {INTRINS_SSE_PACKSSDW, "llvm.x86.sse2.packssdw.128"},
7913 {INTRINS_SSE_PACKUSDW, "llvm.x86.sse41.packusdw"},
7914 {INTRINS_SSE_MINPS, "llvm.x86.sse.min.ps"},
7915 {INTRINS_SSE_MAXPS, "llvm.x86.sse.max.ps"},
7916 {INTRINS_SSE_HADDPS, "llvm.x86.sse3.hadd.ps"},
7917 {INTRINS_SSE_HSUBPS, "llvm.x86.sse3.hsub.ps"},
7918 {INTRINS_SSE_ADDSUBPS, "llvm.x86.sse3.addsub.ps"},
7919 {INTRINS_SSE_MINPD, "llvm.x86.sse2.min.pd"},
7920 {INTRINS_SSE_MAXPD, "llvm.x86.sse2.max.pd"},
7921 {INTRINS_SSE_HADDPD, "llvm.x86.sse3.hadd.pd"},
7922 {INTRINS_SSE_HSUBPD, "llvm.x86.sse3.hsub.pd"},
7923 {INTRINS_SSE_ADDSUBPD, "llvm.x86.sse3.addsub.pd"},
7924 {INTRINS_SSE_PADDSW, "llvm.x86.sse2.padds.w"},
7925 {INTRINS_SSE_PSUBSW, "llvm.x86.sse2.psubs.w"},
7926 {INTRINS_SSE_PADDUSW, "llvm.x86.sse2.paddus.w"},
7927 {INTRINS_SSE_PSUBUSW, "llvm.x86.sse2.psubus.w"},
7928 {INTRINS_SSE_PAVGW, "llvm.x86.sse2.pavg.w"},
7929 {INTRINS_SSE_PMULHW, "llvm.x86.sse2.pmulh.w"},
7930 {INTRINS_SSE_PMULHU, "llvm.x86.sse2.pmulhu.w"},
7931 {INTRINS_SE_PADDSB, "llvm.x86.sse2.padds.b"},
7932 {INTRINS_SSE_PSUBSB, "llvm.x86.sse2.psubs.b"},
7933 {INTRINS_SSE_PADDUSB, "llvm.x86.sse2.paddus.b"},
7934 {INTRINS_SSE_PSUBUSB, "llvm.x86.sse2.psubus.b"},
7935 {INTRINS_SSE_PAVGB, "llvm.x86.sse2.pavg.b"},
7936 {INTRINS_SSE_PAUSE, "llvm.x86.sse2.pause"}
7941 add_sse_binary (LLVMModuleRef module, const char *name, int type)
7943 LLVMTypeRef ret_type = type_to_simd_type (type);
7944 AddFunc2 (module, name, ret_type, ret_type, ret_type);
7948 add_intrinsic (LLVMModuleRef module, int id)
7951 #if defined(TARGET_AMD64) || defined(TARGET_X86)
7952 LLVMTypeRef ret_type, arg_types [16];
7955 name = g_hash_table_lookup (intrins_id_to_name, GINT_TO_POINTER (id));
7959 case INTRINS_MEMSET: {
7960 LLVMTypeRef params [] = { LLVMPointerType (LLVMInt8Type (), 0), LLVMInt8Type (), LLVMInt32Type (), LLVMInt32Type (), LLVMInt1Type () };
7962 AddFunc (module, name, LLVMVoidType (), params, 5);
7965 case INTRINS_MEMCPY: {
7966 LLVMTypeRef params [] = { LLVMPointerType (LLVMInt8Type (), 0), LLVMPointerType (LLVMInt8Type (), 0), LLVMInt32Type (), LLVMInt32Type (), LLVMInt1Type () };
7968 AddFunc (module, name, LLVMVoidType (), params, 5);
7971 case INTRINS_SADD_OVF_I32:
7972 case INTRINS_UADD_OVF_I32:
7973 case INTRINS_SSUB_OVF_I32:
7974 case INTRINS_USUB_OVF_I32:
7975 case INTRINS_SMUL_OVF_I32:
7976 case INTRINS_UMUL_OVF_I32: {
7977 LLVMTypeRef ovf_res_i32 [] = { LLVMInt32Type (), LLVMInt1Type () };
7978 LLVMTypeRef params [] = { LLVMInt32Type (), LLVMInt32Type () };
7979 LLVMTypeRef ret_type = LLVMStructType (ovf_res_i32, 2, FALSE);
7981 AddFunc (module, name, ret_type, params, 2);
7984 case INTRINS_SADD_OVF_I64:
7985 case INTRINS_UADD_OVF_I64:
7986 case INTRINS_SSUB_OVF_I64:
7987 case INTRINS_USUB_OVF_I64:
7988 case INTRINS_SMUL_OVF_I64:
7989 case INTRINS_UMUL_OVF_I64: {
7990 LLVMTypeRef ovf_res_i64 [] = { LLVMInt64Type (), LLVMInt1Type () };
7991 LLVMTypeRef params [] = { LLVMInt64Type (), LLVMInt64Type () };
7992 LLVMTypeRef ret_type = LLVMStructType (ovf_res_i64, 2, FALSE);
7994 AddFunc (module, name, ret_type, params, 2);
8000 case INTRINS_FABS: {
8001 LLVMTypeRef params [] = { LLVMDoubleType () };
8003 AddFunc (module, name, LLVMDoubleType (), params, 1);
8006 case INTRINS_EXPECT_I8:
8007 AddFunc2 (module, name, LLVMInt8Type (), LLVMInt8Type (), LLVMInt8Type ());
8009 case INTRINS_EXPECT_I1:
8010 AddFunc2 (module, name, LLVMInt1Type (), LLVMInt1Type (), LLVMInt1Type ());
8012 #if defined(TARGET_AMD64) || defined(TARGET_X86)
8013 case INTRINS_SSE_PMOVMSKB:
8015 ret_type = LLVMInt32Type ();
8016 arg_types [0] = type_to_simd_type (MONO_TYPE_I1);
8017 AddFunc (module, name, ret_type, arg_types, 1);
8019 case INTRINS_SSE_PSRLI_W:
8020 case INTRINS_SSE_PSRAI_W:
8021 case INTRINS_SSE_PSLLI_W:
8023 ret_type = type_to_simd_type (MONO_TYPE_I2);
8024 arg_types [0] = ret_type;
8025 arg_types [1] = LLVMInt32Type ();
8026 AddFunc (module, name, ret_type, arg_types, 2);
8028 case INTRINS_SSE_PSRLI_D:
8029 case INTRINS_SSE_PSRAI_D:
8030 case INTRINS_SSE_PSLLI_D:
8031 ret_type = type_to_simd_type (MONO_TYPE_I4);
8032 arg_types [0] = ret_type;
8033 arg_types [1] = LLVMInt32Type ();
8034 AddFunc (module, name, ret_type, arg_types, 2);
8036 case INTRINS_SSE_PSRLI_Q:
8037 case INTRINS_SSE_PSLLI_Q:
8038 ret_type = type_to_simd_type (MONO_TYPE_I8);
8039 arg_types [0] = ret_type;
8040 arg_types [1] = LLVMInt32Type ();
8041 AddFunc (module, name, ret_type, arg_types, 2);
8043 case INTRINS_SSE_SQRT_PD:
8045 ret_type = type_to_simd_type (MONO_TYPE_R8);
8046 arg_types [0] = ret_type;
8047 AddFunc (module, name, ret_type, arg_types, 1);
8049 case INTRINS_SSE_SQRT_PS:
8050 ret_type = type_to_simd_type (MONO_TYPE_R4);
8051 arg_types [0] = ret_type;
8052 AddFunc (module, name, ret_type, arg_types, 1);
8054 case INTRINS_SSE_RSQRT_PS:
8055 ret_type = type_to_simd_type (MONO_TYPE_R4);
8056 arg_types [0] = ret_type;
8057 AddFunc (module, name, ret_type, arg_types, 1);
8059 case INTRINS_SSE_RCP_PS:
8060 ret_type = type_to_simd_type (MONO_TYPE_R4);
8061 arg_types [0] = ret_type;
8062 AddFunc (module, name, ret_type, arg_types, 1);
8064 case INTRINS_SSE_CVTTPD2DQ:
8065 ret_type = type_to_simd_type (MONO_TYPE_I4);
8066 arg_types [0] = type_to_simd_type (MONO_TYPE_R8);
8067 AddFunc (module, name, ret_type, arg_types, 1);
8069 case INTRINS_SSE_CVTTPS2DQ:
8070 ret_type = type_to_simd_type (MONO_TYPE_I4);
8071 arg_types [0] = type_to_simd_type (MONO_TYPE_R4);
8072 AddFunc (module, name, ret_type, arg_types, 1);
8074 case INTRINS_SSE_CVTDQ2PD:
8075 /* Conversion ops */
8076 ret_type = type_to_simd_type (MONO_TYPE_R8);
8077 arg_types [0] = type_to_simd_type (MONO_TYPE_I4);
8078 AddFunc (module, name, ret_type, arg_types, 1);
8080 case INTRINS_SSE_CVTDQ2PS:
8081 ret_type = type_to_simd_type (MONO_TYPE_R4);
8082 arg_types [0] = type_to_simd_type (MONO_TYPE_I4);
8083 AddFunc (module, name, ret_type, arg_types, 1);
8085 case INTRINS_SSE_CVTPD2DQ:
8086 ret_type = type_to_simd_type (MONO_TYPE_I4);
8087 arg_types [0] = type_to_simd_type (MONO_TYPE_R8);
8088 AddFunc (module, name, ret_type, arg_types, 1);
8090 case INTRINS_SSE_CVTPS2DQ:
8091 ret_type = type_to_simd_type (MONO_TYPE_I4);
8092 arg_types [0] = type_to_simd_type (MONO_TYPE_R4);
8093 AddFunc (module, name, ret_type, arg_types, 1);
8095 case INTRINS_SSE_CVTPD2PS:
8096 ret_type = type_to_simd_type (MONO_TYPE_R4);
8097 arg_types [0] = type_to_simd_type (MONO_TYPE_R8);
8098 AddFunc (module, name, ret_type, arg_types, 1);
8100 case INTRINS_SSE_CVTPS2PD:
8101 ret_type = type_to_simd_type (MONO_TYPE_R8);
8102 arg_types [0] = type_to_simd_type (MONO_TYPE_R4);
8103 AddFunc (module, name, ret_type, arg_types, 1);
8105 case INTRINS_SSE_CMPPD:
8107 ret_type = type_to_simd_type (MONO_TYPE_R8);
8108 arg_types [0] = ret_type;
8109 arg_types [1] = ret_type;
8110 arg_types [2] = LLVMInt8Type ();
8111 AddFunc (module, name, ret_type, arg_types, 3);
8113 case INTRINS_SSE_CMPPS:
8114 ret_type = type_to_simd_type (MONO_TYPE_R4);
8115 arg_types [0] = ret_type;
8116 arg_types [1] = ret_type;
8117 arg_types [2] = LLVMInt8Type ();
8118 AddFunc (module, name, ret_type, arg_types, 3);
8120 case INTRINS_SSE_PACKSSWB:
8121 case INTRINS_SSE_PACKUSWB:
8122 case INTRINS_SSE_PACKSSDW:
8124 ret_type = type_to_simd_type (MONO_TYPE_I1);
8125 arg_types [0] = type_to_simd_type (MONO_TYPE_I2);
8126 arg_types [1] = type_to_simd_type (MONO_TYPE_I2);
8127 AddFunc (module, name, ret_type, arg_types, 2);
8129 case INTRINS_SSE_PACKUSDW:
8130 ret_type = type_to_simd_type (MONO_TYPE_I2);
8131 arg_types [0] = type_to_simd_type (MONO_TYPE_I4);
8132 arg_types [1] = type_to_simd_type (MONO_TYPE_I4);
8133 AddFunc (module, name, ret_type, arg_types, 2);
8135 /* SSE Binary ops */
8136 case INTRINS_SSE_PADDSW:
8137 case INTRINS_SSE_PSUBSW:
8138 case INTRINS_SSE_PADDUSW:
8139 case INTRINS_SSE_PSUBUSW:
8140 case INTRINS_SSE_PAVGW:
8141 case INTRINS_SSE_PMULHW:
8142 case INTRINS_SSE_PMULHU:
8143 add_sse_binary (module, name, MONO_TYPE_I2);
8145 case INTRINS_SSE_MINPS:
8146 case INTRINS_SSE_MAXPS:
8147 case INTRINS_SSE_HADDPS:
8148 case INTRINS_SSE_HSUBPS:
8149 case INTRINS_SSE_ADDSUBPS:
8150 add_sse_binary (module, name, MONO_TYPE_R4);
8152 case INTRINS_SSE_MINPD:
8153 case INTRINS_SSE_MAXPD:
8154 case INTRINS_SSE_HADDPD:
8155 case INTRINS_SSE_HSUBPD:
8156 case INTRINS_SSE_ADDSUBPD:
8157 add_sse_binary (module, name, MONO_TYPE_R8);
8159 case INTRINS_SE_PADDSB:
8160 case INTRINS_SSE_PSUBSB:
8161 case INTRINS_SSE_PADDUSB:
8162 case INTRINS_SSE_PSUBUSB:
8163 case INTRINS_SSE_PAVGB:
8164 add_sse_binary (module, name, MONO_TYPE_I1);
8166 case INTRINS_SSE_PAUSE:
8167 AddFunc (module, "llvm.x86.sse2.pause", LLVMVoidType (), NULL, 0);
8171 g_assert_not_reached ();
8177 get_intrinsic (EmitContext *ctx, const char *name)
8179 #if LLVM_API_VERSION > 100
8183 * Every method is emitted into its own module so
8184 * we can add intrinsics on demand.
8186 res = LLVMGetNamedFunction (ctx->lmodule, name);
8190 /* No locking needed */
8191 id = GPOINTER_TO_INT (g_hash_table_lookup (intrins_name_to_id, name));
8194 printf ("%s\n", name);
8195 g_assert (id != -1);
8196 add_intrinsic (ctx->lmodule, id);
8197 res = LLVMGetNamedFunction (ctx->lmodule, name);
8205 res = LLVMGetNamedFunction (ctx->lmodule, name);
8212 add_intrinsics (LLVMModuleRef module)
8216 /* Emit declarations of instrinsics */
8218 * It would be nicer to emit only the intrinsics actually used, but LLVM's Module
8219 * type doesn't seem to do any locking.
8221 for (i = 0; i < INTRINS_NUM; ++i)
8222 add_intrinsic (module, i);
8226 AddFunc (module, "mono_personality", LLVMVoidType (), NULL, 0);
8228 AddFunc (module, "llvm_resume_unwind_trampoline", LLVMVoidType (), NULL, 0);
8231 /* Load/Store intrinsics */
8233 LLVMTypeRef arg_types [5];
8237 for (i = 1; i <= 8; i *= 2) {
8238 arg_types [0] = LLVMPointerType (LLVMIntType (i * 8), 0);
8239 arg_types [1] = LLVMInt32Type ();
8240 arg_types [2] = LLVMInt1Type ();
8241 arg_types [3] = LLVMInt32Type ();
8242 sprintf (name, "llvm.mono.load.i%d.p0i%d", i * 8, i * 8);
8243 AddFunc (module, name, LLVMIntType (i * 8), arg_types, 4);
8245 arg_types [0] = LLVMIntType (i * 8);
8246 arg_types [1] = LLVMPointerType (LLVMIntType (i * 8), 0);
8247 arg_types [2] = LLVMInt32Type ();
8248 arg_types [3] = LLVMInt1Type ();
8249 arg_types [4] = LLVMInt32Type ();
8250 sprintf (name, "llvm.mono.store.i%d.p0i%d", i * 8, i * 8);
8251 AddFunc (module, name, LLVMVoidType (), arg_types, 5);
8257 add_types (MonoLLVMModule *module)
8259 module->ptr_type = LLVMPointerType (sizeof (gpointer) == 8 ? LLVMInt64Type () : LLVMInt32Type (), 0);
8263 mono_llvm_init (void)
8268 mono_native_tls_alloc (¤t_cfg_tls_id, NULL);
8270 h = g_hash_table_new (NULL, NULL);
8271 for (i = 0; i < INTRINS_NUM; ++i)
8272 g_hash_table_insert (h, GINT_TO_POINTER (intrinsics [i].id), (gpointer)intrinsics [i].name);
8273 intrins_id_to_name = h;
8275 h = g_hash_table_new (g_str_hash, g_str_equal);
8276 for (i = 0; i < INTRINS_NUM; ++i)
8277 g_hash_table_insert (h, (gpointer)intrinsics [i].name, GINT_TO_POINTER (intrinsics [i].id + 1));
8278 intrins_name_to_id = h;
8282 init_jit_module (MonoDomain *domain)
8284 MonoJitDomainInfo *dinfo;
8285 MonoLLVMModule *module;
8288 dinfo = domain_jit_info (domain);
8289 if (dinfo->llvm_module)
8292 mono_loader_lock ();
8294 if (dinfo->llvm_module) {
8295 mono_loader_unlock ();
8299 module = g_new0 (MonoLLVMModule, 1);
8301 name = g_strdup_printf ("mono-%s", domain->friendly_name);
8302 module->lmodule = LLVMModuleCreateWithName (name);
8303 module->context = LLVMGetGlobalContext ();
8305 module->mono_ee = (MonoEERef*)mono_llvm_create_ee (LLVMCreateModuleProviderForExistingModule (module->lmodule), alloc_cb, emitted_cb, exception_cb, dlsym_cb, &module->ee);
8307 add_intrinsics (module->lmodule);
8310 module->llvm_types = g_hash_table_new (NULL, NULL);
8312 #if LLVM_API_VERSION < 100
8313 MonoJitICallInfo *info;
8315 info = mono_find_jit_icall_by_name ("llvm_resume_unwind_trampoline");
8317 LLVMAddGlobalMapping (module->ee, LLVMGetNamedFunction (module->lmodule, "llvm_resume_unwind_trampoline"), (void*)info->func);
8320 mono_memory_barrier ();
8322 dinfo->llvm_module = module;
8324 mono_loader_unlock ();
8328 mono_llvm_cleanup (void)
8330 MonoLLVMModule *module = &aot_module;
8332 if (module->lmodule)
8333 LLVMDisposeModule (module->lmodule);
8335 if (module->context)
8336 LLVMContextDispose (module->context);
8340 mono_llvm_free_domain_info (MonoDomain *domain)
8342 MonoJitDomainInfo *info = domain_jit_info (domain);
8343 MonoLLVMModule *module = (MonoLLVMModule*)info->llvm_module;
8349 if (module->llvm_types)
8350 g_hash_table_destroy (module->llvm_types);
8352 mono_llvm_dispose_ee (module->mono_ee);
8354 if (module->bb_names) {
8355 for (i = 0; i < module->bb_names_len; ++i)
8356 g_free (module->bb_names [i]);
8357 g_free (module->bb_names);
8359 //LLVMDisposeModule (module->module);
8363 info->llvm_module = NULL;
8367 mono_llvm_create_aot_module (MonoAssembly *assembly, const char *global_prefix, gboolean emit_dwarf, gboolean static_link, gboolean llvm_only)
8369 MonoLLVMModule *module = &aot_module;
8371 /* Delete previous module */
8372 if (module->plt_entries)
8373 g_hash_table_destroy (module->plt_entries);
8374 if (module->lmodule)
8375 LLVMDisposeModule (module->lmodule);
8377 memset (module, 0, sizeof (aot_module));
8379 module->lmodule = LLVMModuleCreateWithName ("aot");
8380 module->assembly = assembly;
8381 module->global_prefix = g_strdup (global_prefix);
8382 module->got_symbol = g_strdup_printf ("%s_llvm_got", global_prefix);
8383 module->eh_frame_symbol = g_strdup_printf ("%s_eh_frame", global_prefix);
8384 module->get_method_symbol = g_strdup_printf ("%s_get_method", global_prefix);
8385 module->get_unbox_tramp_symbol = g_strdup_printf ("%s_get_unbox_tramp", global_prefix);
8386 module->external_symbols = TRUE;
8387 module->emit_dwarf = emit_dwarf;
8388 module->static_link = static_link;
8389 module->llvm_only = llvm_only;
8390 /* The first few entries are reserved */
8391 module->max_got_offset = 16;
8392 module->context = LLVMGetGlobalContext ();
8395 /* clang ignores our debug info because it has an invalid version */
8396 module->emit_dwarf = FALSE;
8398 add_intrinsics (module->lmodule);
8401 #if LLVM_API_VERSION > 100
8402 if (module->emit_dwarf) {
8403 char *dir, *build_info, *s, *cu_name;
8405 module->di_builder = mono_llvm_create_di_builder (module->lmodule);
8408 dir = g_strdup (".");
8409 build_info = mono_get_runtime_build_info ();
8410 s = g_strdup_printf ("Mono AOT Compiler %s (LLVM)", build_info);
8411 cu_name = g_path_get_basename (assembly->image->name);
8412 module->cu = mono_llvm_di_create_compile_unit (module->di_builder, cu_name, dir, s);
8414 g_free (build_info);
8421 * We couldn't compute the type of the LLVM global representing the got because
8422 * its size is only known after all the methods have been emitted. So create
8423 * a dummy variable, and replace all uses it with the real got variable when
8424 * its size is known in mono_llvm_emit_aot_module ().
8427 LLVMTypeRef got_type = LLVMArrayType (module->ptr_type, 0);
8429 module->got_var = LLVMAddGlobal (module->lmodule, got_type, "mono_dummy_got");
8430 LLVMSetInitializer (module->got_var, LLVMConstNull (got_type));
8433 /* Add initialization array */
8435 LLVMTypeRef inited_type = LLVMArrayType (LLVMInt8Type (), 0);
8437 module->inited_var = LLVMAddGlobal (aot_module.lmodule, inited_type, "mono_inited_tmp");
8438 LLVMSetInitializer (module->inited_var, LLVMConstNull (inited_type));
8442 emit_init_icall_wrappers (module);
8444 emit_llvm_code_start (module);
8446 /* Add a dummy personality function */
8447 if (!use_debug_personality) {
8448 LLVMValueRef personality = LLVMAddFunction (module->lmodule, default_personality_name, LLVMFunctionType (LLVMInt32Type (), NULL, 0, TRUE));
8449 LLVMSetLinkage (personality, LLVMExternalLinkage);
8450 mark_as_used (module, personality);
8453 /* Add a reference to the c++ exception we throw/catch */
8455 LLVMTypeRef exc = LLVMPointerType (LLVMInt8Type (), 0);
8456 module->sentinel_exception = LLVMAddGlobal (module->lmodule, exc, "_ZTIPi");
8457 LLVMSetLinkage (module->sentinel_exception, LLVMExternalLinkage);
8458 mono_llvm_set_is_constant (module->sentinel_exception);
8461 module->llvm_types = g_hash_table_new (NULL, NULL);
8462 module->plt_entries = g_hash_table_new (g_str_hash, g_str_equal);
8463 module->plt_entries_ji = g_hash_table_new (NULL, NULL);
8464 module->direct_callables = g_hash_table_new (g_str_hash, g_str_equal);
8465 module->method_to_lmethod = g_hash_table_new (NULL, NULL);
8466 module->idx_to_lmethod = g_hash_table_new (NULL, NULL);
8467 module->idx_to_unbox_tramp = g_hash_table_new (NULL, NULL);
8468 module->method_to_callers = g_hash_table_new (NULL, NULL);
8472 llvm_array_from_uints (LLVMTypeRef el_type, guint32 *values, int nvalues)
8475 LLVMValueRef res, *vals;
8477 vals = g_new0 (LLVMValueRef, nvalues);
8478 for (i = 0; i < nvalues; ++i)
8479 vals [i] = LLVMConstInt (LLVMInt32Type (), values [i], FALSE);
8480 res = LLVMConstArray (LLVMInt32Type (), vals, nvalues);
8486 llvm_array_from_bytes (guint8 *values, int nvalues)
8489 LLVMValueRef res, *vals;
8491 vals = g_new0 (LLVMValueRef, nvalues);
8492 for (i = 0; i < nvalues; ++i)
8493 vals [i] = LLVMConstInt (LLVMInt8Type (), values [i], FALSE);
8494 res = LLVMConstArray (LLVMInt8Type (), vals, nvalues);
8499 * mono_llvm_emit_aot_file_info:
8501 * Emit the MonoAotFileInfo structure.
8502 * Same as emit_aot_file_info () in aot-compiler.c.
8505 mono_llvm_emit_aot_file_info (MonoAotFileInfo *info, gboolean has_jitted_code)
8507 MonoLLVMModule *module = &aot_module;
8509 /* Save these for later */
8510 memcpy (&module->aot_info, info, sizeof (MonoAotFileInfo));
8511 module->has_jitted_code = has_jitted_code;
8515 * mono_llvm_emit_aot_data:
8517 * Emit the binary data DATA pointed to by symbol SYMBOL.
8520 mono_llvm_emit_aot_data (const char *symbol, guint8 *data, int data_len)
8522 MonoLLVMModule *module = &aot_module;
8526 type = LLVMArrayType (LLVMInt8Type (), data_len);
8527 d = LLVMAddGlobal (module->lmodule, type, symbol);
8528 LLVMSetVisibility (d, LLVMHiddenVisibility);
8529 LLVMSetLinkage (d, LLVMInternalLinkage);
8530 LLVMSetInitializer (d, mono_llvm_create_constant_data_array (data, data_len));
8531 mono_llvm_set_is_constant (d);
8534 /* Add a reference to a global defined in JITted code */
8536 AddJitGlobal (MonoLLVMModule *module, LLVMTypeRef type, const char *name)
8541 s = g_strdup_printf ("%s%s", module->global_prefix, name);
8542 v = LLVMAddGlobal (module->lmodule, LLVMInt8Type (), s);
8548 emit_aot_file_info (MonoLLVMModule *module)
8550 LLVMTypeRef file_info_type;
8551 LLVMTypeRef *eltypes, eltype;
8552 LLVMValueRef info_var;
8553 LLVMValueRef *fields;
8554 int i, nfields, tindex;
8555 MonoAotFileInfo *info;
8556 LLVMModuleRef lmodule = module->lmodule;
8558 info = &module->aot_info;
8560 /* Create an LLVM type to represent MonoAotFileInfo */
8561 nfields = 2 + MONO_AOT_FILE_INFO_NUM_SYMBOLS + 16 + 5;
8562 eltypes = g_new (LLVMTypeRef, nfields);
8564 eltypes [tindex ++] = LLVMInt32Type ();
8565 eltypes [tindex ++] = LLVMInt32Type ();
8567 for (i = 0; i < MONO_AOT_FILE_INFO_NUM_SYMBOLS; ++i)
8568 eltypes [tindex ++] = LLVMPointerType (LLVMInt8Type (), 0);
8570 for (i = 0; i < 15; ++i)
8571 eltypes [tindex ++] = LLVMInt32Type ();
8573 eltypes [tindex ++] = LLVMArrayType (LLVMInt32Type (), MONO_AOT_TABLE_NUM);
8574 for (i = 0; i < 4; ++i)
8575 eltypes [tindex ++] = LLVMArrayType (LLVMInt32Type (), MONO_AOT_TRAMP_NUM);
8576 eltypes [tindex ++] = LLVMArrayType (LLVMInt8Type (), 16);
8577 g_assert (tindex == nfields);
8578 file_info_type = LLVMStructCreateNamed (module->context, "MonoAotFileInfo");
8579 LLVMStructSetBody (file_info_type, eltypes, nfields, FALSE);
8581 info_var = LLVMAddGlobal (lmodule, file_info_type, "mono_aot_file_info");
8582 if (module->static_link) {
8583 LLVMSetVisibility (info_var, LLVMHiddenVisibility);
8584 LLVMSetLinkage (info_var, LLVMInternalLinkage);
8586 fields = g_new (LLVMValueRef, nfields);
8588 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->version, FALSE);
8589 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->dummy, FALSE);
8593 * We use LLVMGetNamedGlobal () for symbol which are defined in LLVM code, and LLVMAddGlobal ()
8594 * for symbols defined in the .s file emitted by the aot compiler.
8596 eltype = eltypes [tindex];
8597 if (module->llvm_only)
8598 fields [tindex ++] = LLVMConstNull (eltype);
8600 fields [tindex ++] = AddJitGlobal (module, eltype, "jit_got");
8601 fields [tindex ++] = module->got_var;
8602 /* llc defines this directly */
8603 if (!module->llvm_only) {
8604 fields [tindex ++] = LLVMAddGlobal (lmodule, eltype, module->eh_frame_symbol);
8605 fields [tindex ++] = LLVMConstNull (eltype);
8606 fields [tindex ++] = LLVMConstNull (eltype);
8608 fields [tindex ++] = LLVMConstNull (eltype);
8609 fields [tindex ++] = module->get_method;
8610 fields [tindex ++] = module->get_unbox_tramp;
8612 if (module->has_jitted_code) {
8613 fields [tindex ++] = AddJitGlobal (module, eltype, "jit_code_start");
8614 fields [tindex ++] = AddJitGlobal (module, eltype, "jit_code_end");
8616 fields [tindex ++] = LLVMConstNull (eltype);
8617 fields [tindex ++] = LLVMConstNull (eltype);
8619 if (!module->llvm_only)
8620 fields [tindex ++] = AddJitGlobal (module, eltype, "method_addresses");
8622 fields [tindex ++] = LLVMConstNull (eltype);
8623 if (info->flags & MONO_AOT_FILE_FLAG_SEPARATE_DATA) {
8624 for (i = 0; i < MONO_AOT_TABLE_NUM; ++i)
8625 fields [tindex ++] = LLVMConstNull (eltype);
8627 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "blob");
8628 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "class_name_table");
8629 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "class_info_offsets");
8630 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "method_info_offsets");
8631 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "ex_info_offsets");
8632 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "extra_method_info_offsets");
8633 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "extra_method_table");
8634 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "got_info_offsets");
8635 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "llvm_got_info_offsets");
8636 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "image_table");
8638 /* Not needed (mem_end) */
8639 fields [tindex ++] = LLVMConstNull (eltype);
8640 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "assembly_guid");
8641 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "runtime_version");
8642 if (info->trampoline_size [0]) {
8643 fields [tindex ++] = AddJitGlobal (module, eltype, "specific_trampolines");
8644 fields [tindex ++] = AddJitGlobal (module, eltype, "static_rgctx_trampolines");
8645 fields [tindex ++] = AddJitGlobal (module, eltype, "imt_trampolines");
8646 fields [tindex ++] = AddJitGlobal (module, eltype, "gsharedvt_arg_trampolines");
8648 fields [tindex ++] = LLVMConstNull (eltype);
8649 fields [tindex ++] = LLVMConstNull (eltype);
8650 fields [tindex ++] = LLVMConstNull (eltype);
8651 fields [tindex ++] = LLVMConstNull (eltype);
8653 if (module->static_link && !module->llvm_only)
8654 fields [tindex ++] = AddJitGlobal (module, eltype, "globals");
8656 fields [tindex ++] = LLVMConstNull (eltype);
8657 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "assembly_name");
8658 if (!module->llvm_only) {
8659 fields [tindex ++] = AddJitGlobal (module, eltype, "plt");
8660 fields [tindex ++] = AddJitGlobal (module, eltype, "plt_end");
8661 fields [tindex ++] = AddJitGlobal (module, eltype, "unwind_info");
8662 fields [tindex ++] = AddJitGlobal (module, eltype, "unbox_trampolines");
8663 fields [tindex ++] = AddJitGlobal (module, eltype, "unbox_trampolines_end");
8664 fields [tindex ++] = AddJitGlobal (module, eltype, "unbox_trampoline_addresses");
8666 fields [tindex ++] = LLVMConstNull (eltype);
8667 fields [tindex ++] = LLVMConstNull (eltype);
8668 fields [tindex ++] = LLVMConstNull (eltype);
8669 fields [tindex ++] = LLVMConstNull (eltype);
8670 fields [tindex ++] = LLVMConstNull (eltype);
8671 fields [tindex ++] = LLVMConstNull (eltype);
8674 for (i = 0; i < MONO_AOT_FILE_INFO_NUM_SYMBOLS; ++i)
8675 fields [2 + i] = LLVMConstBitCast (fields [2 + i], eltype);
8678 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->plt_got_offset_base, FALSE);
8679 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->got_size, FALSE);
8680 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->plt_size, FALSE);
8681 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->nmethods, FALSE);
8682 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->flags, FALSE);
8683 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->opts, FALSE);
8684 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->simd_opts, FALSE);
8685 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->gc_name_index, FALSE);
8686 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->num_rgctx_fetch_trampolines, FALSE);
8687 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->double_align, FALSE);
8688 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->long_align, FALSE);
8689 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->generic_tramp_num, FALSE);
8690 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->tramp_page_size, FALSE);
8691 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->nshared_got_entries, FALSE);
8692 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->datafile_size, FALSE);
8694 fields [tindex ++] = llvm_array_from_uints (LLVMInt32Type (), info->table_offsets, MONO_AOT_TABLE_NUM);
8695 fields [tindex ++] = llvm_array_from_uints (LLVMInt32Type (), info->num_trampolines, MONO_AOT_TRAMP_NUM);
8696 fields [tindex ++] = llvm_array_from_uints (LLVMInt32Type (), info->trampoline_got_offset_base, MONO_AOT_TRAMP_NUM);
8697 fields [tindex ++] = llvm_array_from_uints (LLVMInt32Type (), info->trampoline_size, MONO_AOT_TRAMP_NUM);
8698 fields [tindex ++] = llvm_array_from_uints (LLVMInt32Type (), info->tramp_page_code_offsets, MONO_AOT_TRAMP_NUM);
8700 fields [tindex ++] = llvm_array_from_bytes (info->aotid, 16);
8701 g_assert (tindex == nfields);
8703 LLVMSetInitializer (info_var, LLVMConstNamedStruct (file_info_type, fields, nfields));
8705 if (module->static_link) {
8709 s = g_strdup_printf ("mono_aot_module_%s_info", module->assembly->aname.name);
8710 /* Get rid of characters which cannot occur in symbols */
8712 for (p = s; *p; ++p) {
8713 if (!(isalnum (*p) || *p == '_'))
8716 var = LLVMAddGlobal (module->lmodule, LLVMPointerType (LLVMInt8Type (), 0), s);
8718 LLVMSetInitializer (var, LLVMConstBitCast (LLVMGetNamedGlobal (module->lmodule, "mono_aot_file_info"), LLVMPointerType (LLVMInt8Type (), 0)));
8719 LLVMSetLinkage (var, LLVMExternalLinkage);
8724 * Emit the aot module into the LLVM bitcode file FILENAME.
8727 mono_llvm_emit_aot_module (const char *filename, const char *cu_name)
8729 LLVMTypeRef got_type, inited_type;
8730 LLVMValueRef real_got, real_inited;
8731 MonoLLVMModule *module = &aot_module;
8733 emit_llvm_code_end (module);
8736 * Create the real got variable and replace all uses of the dummy variable with
8739 got_type = LLVMArrayType (module->ptr_type, module->max_got_offset + 1);
8740 real_got = LLVMAddGlobal (module->lmodule, got_type, module->got_symbol);
8741 LLVMSetInitializer (real_got, LLVMConstNull (got_type));
8742 if (module->external_symbols) {
8743 LLVMSetLinkage (real_got, LLVMExternalLinkage);
8744 LLVMSetVisibility (real_got, LLVMHiddenVisibility);
8746 LLVMSetLinkage (real_got, LLVMInternalLinkage);
8748 mono_llvm_replace_uses_of (module->got_var, real_got);
8750 mark_as_used (&aot_module, real_got);
8752 /* Delete the dummy got so it doesn't become a global */
8753 LLVMDeleteGlobal (module->got_var);
8754 module->got_var = real_got;
8757 * Same for the init_var
8759 if (module->llvm_only) {
8760 inited_type = LLVMArrayType (LLVMInt8Type (), module->max_inited_idx + 1);
8761 real_inited = LLVMAddGlobal (module->lmodule, inited_type, "mono_inited");
8762 LLVMSetInitializer (real_inited, LLVMConstNull (inited_type));
8763 LLVMSetLinkage (real_inited, LLVMInternalLinkage);
8764 mono_llvm_replace_uses_of (module->inited_var, real_inited);
8765 LLVMDeleteGlobal (module->inited_var);
8768 if (module->llvm_only) {
8769 emit_get_method (&aot_module);
8770 emit_get_unbox_tramp (&aot_module);
8773 emit_llvm_used (&aot_module);
8774 emit_dbg_info (&aot_module, filename, cu_name);
8775 emit_aot_file_info (&aot_module);
8778 * Replace GOT entries for directly callable methods with the methods themselves.
8779 * It would be easier to implement this by predefining all methods before compiling
8780 * their bodies, but that couldn't handle the case when a method fails to compile
8783 if (module->llvm_only) {
8784 GHashTableIter iter;
8786 GSList *callers, *l;
8788 g_hash_table_iter_init (&iter, module->method_to_callers);
8789 while (g_hash_table_iter_next (&iter, (void**)&method, (void**)&callers)) {
8790 LLVMValueRef lmethod;
8792 if (method->iflags & METHOD_IMPL_ATTRIBUTE_SYNCHRONIZED)
8795 lmethod = (LLVMValueRef)g_hash_table_lookup (module->method_to_lmethod, method);
8797 for (l = callers; l; l = l->next) {
8798 LLVMValueRef caller = (LLVMValueRef)l->data;
8800 mono_llvm_replace_uses_of (caller, lmethod);
8806 /* Replace PLT entries for directly callable methods with the methods themselves */
8808 GHashTableIter iter;
8810 LLVMValueRef callee;
8812 g_hash_table_iter_init (&iter, module->plt_entries_ji);
8813 while (g_hash_table_iter_next (&iter, (void**)&ji, (void**)&callee)) {
8814 if (mono_aot_is_direct_callable (ji)) {
8815 LLVMValueRef lmethod;
8817 lmethod = (LLVMValueRef)g_hash_table_lookup (module->method_to_lmethod, ji->data.method);
8818 /* The types might not match because the caller might pass an rgctx */
8819 if (lmethod && LLVMTypeOf (callee) == LLVMTypeOf (lmethod)) {
8820 mono_llvm_replace_uses_of (callee, lmethod);
8821 mono_aot_mark_unused_llvm_plt_entry (ji);
8831 if (LLVMVerifyModule (module->lmodule, LLVMReturnStatusAction, &verifier_err)) {
8832 printf ("%s\n", verifier_err);
8833 g_assert_not_reached ();
8838 LLVMWriteBitcodeToFile (module->lmodule, filename);
8843 md_string (const char *s)
8845 return LLVMMDString (s, strlen (s));
8848 /* Debugging support */
8851 emit_dbg_info (MonoLLVMModule *module, const char *filename, const char *cu_name)
8853 LLVMModuleRef lmodule = module->lmodule;
8854 LLVMValueRef args [16], ver;
8857 * This can only be enabled when LLVM code is emitted into a separate object
8858 * file, since the AOT compiler also emits dwarf info,
8859 * and the abbrev indexes will not be correct since llvm has added its own
8862 if (!module->emit_dwarf)
8865 #if LLVM_API_VERSION > 100
8866 mono_llvm_di_builder_finalize (module->di_builder);
8868 LLVMValueRef cu_args [16], cu;
8870 char *build_info, *s, *dir;
8873 * Emit dwarf info in the form of LLVM metadata. There is some
8874 * out-of-date documentation at:
8875 * http://llvm.org/docs/SourceLevelDebugging.html
8876 * but most of this was gathered from the llvm and
8881 cu_args [n_cuargs ++] = LLVMConstInt (LLVMInt32Type (), DW_TAG_compile_unit, FALSE);
8882 /* CU name/compilation dir */
8883 dir = g_path_get_dirname (filename);
8884 args [0] = LLVMMDString (cu_name, strlen (cu_name));
8885 args [1] = LLVMMDString (dir, strlen (dir));
8886 cu_args [n_cuargs ++] = LLVMMDNode (args, 2);
8889 cu_args [n_cuargs ++] = LLVMConstInt (LLVMInt32Type (), DW_LANG_C99, FALSE);
8891 build_info = mono_get_runtime_build_info ();
8892 s = g_strdup_printf ("Mono AOT Compiler %s (LLVM)", build_info);
8893 cu_args [n_cuargs ++] = LLVMMDString (s, strlen (s));
8894 g_free (build_info);
8896 cu_args [n_cuargs ++] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
8898 cu_args [n_cuargs ++] = LLVMMDString ("", strlen (""));
8899 /* Runtime version */
8900 cu_args [n_cuargs ++] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
8902 cu_args [n_cuargs ++] = LLVMMDNode (args, 0);
8903 cu_args [n_cuargs ++] = LLVMMDNode (args, 0);
8905 if (module->subprogram_mds) {
8909 mds = g_new0 (LLVMValueRef, module->subprogram_mds->len);
8910 for (i = 0; i < module->subprogram_mds->len; ++i)
8911 mds [i] = (LLVMValueRef)g_ptr_array_index (module->subprogram_mds, i);
8912 cu_args [n_cuargs ++] = LLVMMDNode (mds, module->subprogram_mds->len);
8914 cu_args [n_cuargs ++] = LLVMMDNode (args, 0);
8917 cu_args [n_cuargs ++] = LLVMMDNode (args, 0);
8918 /* Imported modules */
8919 cu_args [n_cuargs ++] = LLVMMDNode (args, 0);
8921 cu_args [n_cuargs ++] = LLVMMDString ("", strlen (""));
8922 /* DebugEmissionKind = FullDebug */
8923 cu_args [n_cuargs ++] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
8924 cu = LLVMMDNode (cu_args, n_cuargs);
8925 LLVMAddNamedMetadataOperand (lmodule, "llvm.dbg.cu", cu);
8928 #if LLVM_API_VERSION > 100
8929 args [0] = LLVMConstInt (LLVMInt32Type (), 2, FALSE);
8930 args [1] = LLVMMDString ("Dwarf Version", strlen ("Dwarf Version"));
8931 args [2] = LLVMConstInt (LLVMInt32Type (), 2, FALSE);
8932 ver = LLVMMDNode (args, 3);
8933 LLVMAddNamedMetadataOperand (lmodule, "llvm.module.flags", ver);
8935 args [0] = LLVMConstInt (LLVMInt32Type (), 2, FALSE);
8936 args [1] = LLVMMDString ("Debug Info Version", strlen ("Debug Info Version"));
8937 args [2] = LLVMConstInt (LLVMInt64Type (), 3, FALSE);
8938 ver = LLVMMDNode (args, 3);
8939 LLVMAddNamedMetadataOperand (lmodule, "llvm.module.flags", ver);
8941 args [0] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
8942 args [1] = LLVMMDString ("Dwarf Version", strlen ("Dwarf Version"));
8943 args [2] = LLVMConstInt (LLVMInt32Type (), 2, FALSE);
8944 ver = LLVMMDNode (args, 3);
8945 LLVMAddNamedMetadataOperand (lmodule, "llvm.module.flags", ver);
8947 args [0] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
8948 args [1] = LLVMMDString ("Debug Info Version", strlen ("Debug Info Version"));
8949 args [2] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
8950 ver = LLVMMDNode (args, 3);
8951 LLVMAddNamedMetadataOperand (lmodule, "llvm.module.flags", ver);
8956 emit_dbg_subprogram (EmitContext *ctx, MonoCompile *cfg, LLVMValueRef method, const char *name)
8958 MonoLLVMModule *module = ctx->module;
8959 MonoDebugMethodInfo *minfo = ctx->minfo;
8960 char *source_file, *dir, *filename;
8961 LLVMValueRef md, args [16], ctx_args [16], md_args [64], type_args [16], ctx_md, type_md;
8962 MonoSymSeqPoint *sym_seq_points;
8968 mono_debug_symfile_get_seq_points (minfo, &source_file, NULL, NULL, &sym_seq_points, &n_seq_points);
8970 source_file = g_strdup ("<unknown>");
8971 dir = g_path_get_dirname (source_file);
8972 filename = g_path_get_basename (source_file);
8974 #if LLVM_API_VERSION > 100
8975 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);
8978 ctx_args [0] = LLVMConstInt (LLVMInt32Type (), 0x29, FALSE);
8979 args [0] = md_string (filename);
8980 args [1] = md_string (dir);
8981 ctx_args [1] = LLVMMDNode (args, 2);
8982 ctx_md = LLVMMDNode (ctx_args, 2);
8984 type_args [0] = LLVMConstInt (LLVMInt32Type (), DW_TAG_subroutine_type, FALSE);
8985 type_args [1] = NULL;
8986 type_args [2] = NULL;
8987 type_args [3] = LLVMMDString ("", 0);
8988 type_args [4] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
8989 type_args [5] = LLVMConstInt (LLVMInt64Type (), 0, FALSE);
8990 type_args [6] = LLVMConstInt (LLVMInt64Type (), 0, FALSE);
8991 type_args [7] = LLVMConstInt (LLVMInt64Type (), 0, FALSE);
8992 type_args [8] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
8993 type_args [9] = NULL;
8994 type_args [10] = NULL;
8995 type_args [11] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
8996 type_args [12] = NULL;
8997 type_args [13] = NULL;
8998 type_args [14] = NULL;
8999 type_md = LLVMMDNode (type_args, 14);
9001 /* http://llvm.org/docs/SourceLevelDebugging.html#subprogram-descriptors */
9002 md_args [0] = LLVMConstInt (LLVMInt32Type (), DW_TAG_subprogram, FALSE);
9003 /* Source directory + file pair */
9004 args [0] = md_string (filename);
9005 args [1] = md_string (dir);
9006 md_args [1] = LLVMMDNode (args ,2);
9007 md_args [2] = ctx_md;
9008 md_args [3] = md_string (cfg->method->name);
9009 md_args [4] = md_string (name);
9010 md_args [5] = md_string (name);
9013 md_args [6] = LLVMConstInt (LLVMInt32Type (), sym_seq_points [0].line, FALSE);
9015 md_args [6] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
9017 md_args [7] = type_md;
9019 md_args [8] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
9021 md_args [9] = LLVMConstInt (LLVMInt1Type (), 1, FALSE);
9023 md_args [10] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
9024 /* Index into a virtual function */
9025 md_args [11] = NULL;
9026 md_args [12] = NULL;
9028 md_args [13] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
9030 md_args [14] = LLVMConstInt (LLVMInt1Type (), 1, FALSE);
9031 /* Pointer to LLVM function */
9032 md_args [15] = method;
9033 /* Function template parameter */
9034 md_args [16] = NULL;
9035 /* Function declaration descriptor */
9036 md_args [17] = NULL;
9037 /* List of function variables */
9038 md_args [18] = LLVMMDNode (args, 0);
9040 md_args [19] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
9041 md = LLVMMDNode (md_args, 20);
9043 if (!module->subprogram_mds)
9044 module->subprogram_mds = g_ptr_array_new ();
9045 g_ptr_array_add (module->subprogram_mds, md);
9049 g_free (source_file);
9050 g_free (sym_seq_points);
9056 emit_dbg_loc (EmitContext *ctx, LLVMBuilderRef builder, const unsigned char *cil_code)
9058 MonoCompile *cfg = ctx->cfg;
9060 if (ctx->minfo && cil_code && cil_code >= cfg->header->code && cil_code < cfg->header->code + cfg->header->code_size) {
9061 MonoDebugSourceLocation *loc;
9062 LLVMValueRef loc_md;
9064 loc = mono_debug_symfile_lookup_location (ctx->minfo, cil_code - cfg->header->code);
9067 #if LLVM_API_VERSION > 100
9068 loc_md = mono_llvm_di_create_location (ctx->module->di_builder, ctx->dbg_md, loc->row, loc->column);
9069 mono_llvm_di_set_location (builder, loc_md);
9071 LLVMValueRef md_args [16];
9075 md_args [nmd_args ++] = LLVMConstInt (LLVMInt32Type (), loc->row, FALSE);
9076 md_args [nmd_args ++] = LLVMConstInt (LLVMInt32Type (), loc->column, FALSE);
9077 md_args [nmd_args ++] = ctx->dbg_md;
9078 md_args [nmd_args ++] = NULL;
9079 loc_md = LLVMMDNode (md_args, nmd_args);
9080 LLVMSetCurrentDebugLocation (builder, loc_md);
9082 mono_debug_symfile_free_location (loc);
9088 default_mono_llvm_unhandled_exception (void)
9090 MonoJitTlsData *jit_tls = mono_get_jit_tls ();
9091 MonoObject *target = mono_gchandle_get_target (jit_tls->thrown_exc);
9093 mono_unhandled_exception (target);
9094 mono_invoke_unhandled_exception_hook (target);
9095 g_assert_not_reached ();
9100 - Emit LLVM IR from the mono IR using the LLVM C API.
9101 - The original arch specific code remains, so we can fall back to it if we run
9102 into something we can't handle.
9106 A partial list of issues:
9107 - Handling of opcodes which can throw exceptions.
9109 In the mono JIT, these are implemented using code like this:
9116 push throw_pos - method
9117 call <exception trampoline>
9119 The problematic part is push throw_pos - method, which cannot be represented
9120 in the LLVM IR, since it does not support label values.
9121 -> this can be implemented in AOT mode using inline asm + labels, but cannot
9122 be implemented in JIT mode ?
9123 -> a possible but slower implementation would use the normal exception
9124 throwing code but it would need to control the placement of the throw code
9125 (it needs to be exactly after the compare+branch).
9126 -> perhaps add a PC offset intrinsics ?
9128 - efficient implementation of .ovf opcodes.
9130 These are currently implemented as:
9131 <ins which sets the condition codes>
9134 Some overflow opcodes are now supported by LLVM SVN.
9136 - exception handling, unwinding.
9137 - SSA is disabled for methods with exception handlers
9138 - How to obtain unwind info for LLVM compiled methods ?
9139 -> this is now solved by converting the unwind info generated by LLVM
9141 - LLVM uses the c++ exception handling framework, while we use our home grown
9142 code, and couldn't use the c++ one:
9143 - its not supported under VC++, other exotic platforms.
9144 - it might be impossible to support filter clauses with it.
9148 The trampolines need a predictable call sequence, since they need to disasm
9149 the calling code to obtain register numbers / offsets.
9151 LLVM currently generates this code in non-JIT mode:
9152 mov -0x98(%rax),%eax
9154 Here, the vtable pointer is lost.
9155 -> solution: use one vtable trampoline per class.
9157 - passing/receiving the IMT pointer/RGCTX.
9158 -> solution: pass them as normal arguments ?
9162 LLVM does not allow the specification of argument registers etc. This means
9163 that all calls are made according to the platform ABI.
9165 - passing/receiving vtypes.
9167 Vtypes passed/received in registers are handled by the front end by using
9168 a signature with scalar arguments, and loading the parts of the vtype into those
9171 Vtypes passed on the stack are handled using the 'byval' attribute.
9175 Supported though alloca, we need to emit the load/store code.
9179 The mono JIT uses pointer sized iregs/double fregs, while LLVM uses precisely
9180 typed registers, so we have to keep track of the precise LLVM type of each vreg.
9181 This is made easier because the IR is already in SSA form.
9182 An additional problem is that our IR is not consistent with types, i.e. i32/ia64
9183 types are frequently used incorrectly.
9188 Emit LLVM bytecode into a .bc file, compile it using llc into a .s file, then link
9189 it with the file containing the methods emitted by the JIT and the AOT data
9193 /* FIXME: Normalize some aspects of the mono IR to allow easier translation, like:
9194 * - each bblock should end with a branch
9195 * - setting the return value, making cfg->ret non-volatile
9196 * - avoid some transformations in the JIT which make it harder for us to generate
9198 * - use pointer types to help optimizations.