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)
9 #include <mono/metadata/debug-helpers.h>
10 #include <mono/metadata/debug-mono-symfile.h>
11 #include <mono/metadata/mempool-internals.h>
12 #include <mono/metadata/environment.h>
13 #include <mono/metadata/object-internals.h>
14 #include <mono/metadata/abi-details.h>
15 #include <mono/utils/mono-tls.h>
16 #include <mono/utils/mono-dl.h>
17 #include <mono/utils/mono-time.h>
18 #include <mono/utils/freebsd-dwarf.h>
20 #ifndef __STDC_LIMIT_MACROS
21 #define __STDC_LIMIT_MACROS
23 #ifndef __STDC_CONSTANT_MACROS
24 #define __STDC_CONSTANT_MACROS
27 #include "llvm-c/Core.h"
28 #include "llvm-c/ExecutionEngine.h"
29 #include "llvm-c/BitWriter.h"
30 #include "llvm-c/Analysis.h"
32 #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."
49 * Information associated by mono with LLVM modules.
52 LLVMModuleRef lmodule;
53 LLVMValueRef throw_icall, rethrow, match_exc, throw_corlib_exception, resume_eh;
54 GHashTable *llvm_types;
56 const char *got_symbol;
57 const char *get_method_symbol;
58 const char *get_unbox_tramp_symbol;
59 GHashTable *plt_entries;
60 GHashTable *plt_entries_ji;
61 GHashTable *method_to_lmethod;
62 GHashTable *direct_callables;
67 GPtrArray *subprogram_mds;
69 LLVMExecutionEngineRef ee;
70 gboolean external_symbols;
75 MonoAssembly *assembly;
77 MonoAotFileInfo aot_info;
78 const char *jit_got_symbol;
79 const char *eh_frame_symbol;
80 LLVMValueRef get_method, get_unbox_tramp;
81 LLVMValueRef init_method, init_method_gshared_mrgctx, init_method_gshared_this, init_method_gshared_vtable;
82 LLVMValueRef code_start, code_end;
83 LLVMValueRef inited_var;
84 int max_inited_idx, max_method_idx;
85 gboolean has_jitted_code;
88 GHashTable *idx_to_lmethod;
89 GHashTable *idx_to_unbox_tramp;
90 /* Maps a MonoMethod to LLVM instructions representing it */
91 GHashTable *method_to_callers;
92 LLVMContextRef context;
93 LLVMValueRef sentinel_exception;
94 void *di_builder, *cu;
98 * Information associated by the backend with mono basic blocks.
101 LLVMBasicBlockRef bblock, end_bblock;
102 LLVMValueRef finally_ind;
103 gboolean added, invoke_target;
105 * If this bblock is the start of a finally clause, this is a list of bblocks it
106 * needs to branch to in ENDFINALLY.
108 GSList *call_handler_return_bbs;
110 * If this bblock is the start of a finally clause, this is the bblock that
111 * CALL_HANDLER needs to branch to.
113 LLVMBasicBlockRef call_handler_target_bb;
114 /* The list of switch statements generated by ENDFINALLY instructions */
115 GSList *endfinally_switch_ins_list;
120 * Structure containing emit state
123 MonoMemPool *mempool;
125 /* Maps method names to the corresponding LLVMValueRef */
126 GHashTable *emitted_method_decls;
129 LLVMValueRef lmethod;
130 MonoLLVMModule *module;
131 LLVMModuleRef lmodule;
133 int sindex, default_index, ex_index;
134 LLVMBuilderRef builder;
135 LLVMValueRef *values, *addresses;
136 MonoType **vreg_cli_types;
138 MonoMethodSignature *sig;
140 GHashTable *region_to_handler;
141 GHashTable *clause_to_handler;
142 LLVMBuilderRef alloca_builder;
143 LLVMValueRef last_alloca;
144 LLVMValueRef rgctx_arg;
145 LLVMValueRef this_arg;
146 LLVMTypeRef *vreg_types;
147 LLVMTypeRef method_type;
148 LLVMBasicBlockRef init_bb, inited_bb;
150 gboolean *unreachable;
152 gboolean has_got_access;
153 gboolean is_linkonce;
154 int this_arg_pindex, rgctx_arg_pindex;
155 LLVMValueRef imt_rgctx_loc;
156 GHashTable *llvm_types;
158 MonoDebugMethodInfo *minfo;
160 /* For every clause, the clauses it is nested in */
163 GHashTable *exc_meta;
164 GHashTable *method_to_callers;
165 GPtrArray *phi_values;
166 GPtrArray *bblock_list;
173 MonoBasicBlock *in_bb;
178 * Instruction metadata
179 * This is the same as ins_info, but LREG != IREG.
187 #define MINI_OP(a,b,dest,src1,src2) dest, src1, src2, ' ',
188 #define MINI_OP3(a,b,dest,src1,src2,src3) dest, src1, src2, src3,
195 /* keep in sync with the enum in mini.h */
198 #include "mini-ops.h"
203 #if SIZEOF_VOID_P == 4
204 #define GET_LONG_IMM(ins) (((guint64)(ins)->inst_ms_word << 32) | (guint64)(guint32)(ins)->inst_ls_word)
206 #define GET_LONG_IMM(ins) ((ins)->inst_imm)
209 #define LLVM_INS_INFO(opcode) (&llvm_ins_info [((opcode) - OP_START - 1) * 4])
212 #define TRACE_FAILURE(msg) do { printf ("%s\n", msg); } while (0)
214 #define TRACE_FAILURE(msg)
218 #define IS_TARGET_X86 1
220 #define IS_TARGET_X86 0
224 #define IS_TARGET_AMD64 1
226 #define IS_TARGET_AMD64 0
229 #define ctx_ok(ctx) (!(ctx)->cfg->disable_llvm)
231 static LLVMIntPredicate cond_to_llvm_cond [] = {
244 static LLVMRealPredicate fpcond_to_llvm_cond [] = {
257 static MonoNativeTlsKey current_cfg_tls_id;
259 static MonoLLVMModule aot_module;
260 static int memset_param_count, memcpy_param_count;
261 static const char *memset_func_name;
262 static const char *memcpy_func_name;
264 static void init_jit_module (MonoDomain *domain);
266 static void emit_dbg_loc (EmitContext *ctx, LLVMBuilderRef builder, const unsigned char *cil_code);
267 static LLVMValueRef emit_dbg_subprogram (EmitContext *ctx, MonoCompile *cfg, LLVMValueRef method, const char *name);
268 static void emit_dbg_info (MonoLLVMModule *module, const char *filename, const char *cu_name);
269 static void emit_cond_system_exception (EmitContext *ctx, MonoBasicBlock *bb, const char *exc_type, LLVMValueRef cmp);
272 set_failure (EmitContext *ctx, const char *message)
274 TRACE_FAILURE (reason);
275 ctx->cfg->exception_message = g_strdup (message);
276 ctx->cfg->disable_llvm = TRUE;
282 * The LLVM type with width == sizeof (gpointer)
287 return sizeof (gpointer) == 8 ? LLVMInt64Type () : LLVMInt32Type ();
293 return sizeof (gpointer) == 8 ? LLVMPointerType (LLVMInt64Type (), 0) : LLVMPointerType (LLVMInt32Type (), 0);
299 return sizeof (gpointer) == 8 ? LLVMPointerType (LLVMInt64Type (), 0) : LLVMPointerType (LLVMInt32Type (), 0);
305 * Return the size of the LLVM representation of the vtype T.
308 get_vtype_size (MonoType *t)
312 size = mono_class_value_size (mono_class_from_mono_type (t), NULL);
314 /* LLVMArgAsIArgs depends on this since it stores whole words */
315 while (size < 2 * sizeof (gpointer) && mono_is_power_of_two (size) == -1)
322 * simd_class_to_llvm_type:
324 * Return the LLVM type corresponding to the Mono.SIMD class KLASS
327 simd_class_to_llvm_type (EmitContext *ctx, MonoClass *klass)
329 if (!strcmp (klass->name, "Vector2d")) {
330 return LLVMVectorType (LLVMDoubleType (), 2);
331 } else if (!strcmp (klass->name, "Vector2l")) {
332 return LLVMVectorType (LLVMInt64Type (), 2);
333 } else if (!strcmp (klass->name, "Vector2ul")) {
334 return LLVMVectorType (LLVMInt64Type (), 2);
335 } else if (!strcmp (klass->name, "Vector4i")) {
336 return LLVMVectorType (LLVMInt32Type (), 4);
337 } else if (!strcmp (klass->name, "Vector4ui")) {
338 return LLVMVectorType (LLVMInt32Type (), 4);
339 } else if (!strcmp (klass->name, "Vector4f")) {
340 return LLVMVectorType (LLVMFloatType (), 4);
341 } else if (!strcmp (klass->name, "Vector8s")) {
342 return LLVMVectorType (LLVMInt16Type (), 8);
343 } else if (!strcmp (klass->name, "Vector8us")) {
344 return LLVMVectorType (LLVMInt16Type (), 8);
345 } else if (!strcmp (klass->name, "Vector16sb")) {
346 return LLVMVectorType (LLVMInt8Type (), 16);
347 } else if (!strcmp (klass->name, "Vector16b")) {
348 return LLVMVectorType (LLVMInt8Type (), 16);
350 printf ("%s\n", klass->name);
356 /* Return the 128 bit SIMD type corresponding to the mono type TYPE */
357 static inline G_GNUC_UNUSED LLVMTypeRef
358 type_to_simd_type (int type)
362 return LLVMVectorType (LLVMInt8Type (), 16);
364 return LLVMVectorType (LLVMInt16Type (), 8);
366 return LLVMVectorType (LLVMInt32Type (), 4);
368 return LLVMVectorType (LLVMInt64Type (), 2);
370 return LLVMVectorType (LLVMDoubleType (), 2);
372 return LLVMVectorType (LLVMFloatType (), 4);
374 g_assert_not_reached ();
380 create_llvm_type_for_type (MonoLLVMModule *module, MonoClass *klass)
382 int i, size, nfields, esize;
383 LLVMTypeRef *eltypes;
388 t = &klass->byval_arg;
390 if (mini_type_is_hfa (t, &nfields, &esize)) {
392 * This is needed on arm64 where HFAs are returned in
396 eltypes = g_new (LLVMTypeRef, size);
397 for (i = 0; i < size; ++i)
398 eltypes [i] = esize == 4 ? LLVMFloatType () : LLVMDoubleType ();
400 size = get_vtype_size (t);
402 eltypes = g_new (LLVMTypeRef, size);
403 for (i = 0; i < size; ++i)
404 eltypes [i] = LLVMInt8Type ();
407 name = mono_type_full_name (&klass->byval_arg);
408 ltype = LLVMStructCreateNamed (module->context, name);
409 LLVMStructSetBody (ltype, eltypes, size, FALSE);
419 * Return the LLVM type corresponding to T.
422 type_to_llvm_type (EmitContext *ctx, MonoType *t)
424 t = mini_get_underlying_type (t);
428 return LLVMVoidType ();
430 return LLVMInt8Type ();
432 return LLVMInt16Type ();
434 return LLVMInt32Type ();
436 return LLVMInt8Type ();
438 return LLVMInt16Type ();
440 return LLVMInt32Type ();
441 case MONO_TYPE_BOOLEAN:
442 return LLVMInt8Type ();
445 return LLVMInt64Type ();
447 return LLVMInt16Type ();
449 return LLVMFloatType ();
451 return LLVMDoubleType ();
454 return IntPtrType ();
455 case MONO_TYPE_OBJECT:
456 case MONO_TYPE_CLASS:
457 case MONO_TYPE_ARRAY:
458 case MONO_TYPE_SZARRAY:
459 case MONO_TYPE_STRING:
461 return ObjRefType ();
464 /* Because of generic sharing */
465 return ObjRefType ();
466 case MONO_TYPE_GENERICINST:
467 if (!mono_type_generic_inst_is_valuetype (t))
468 return ObjRefType ();
470 case MONO_TYPE_VALUETYPE:
471 case MONO_TYPE_TYPEDBYREF: {
475 klass = mono_class_from_mono_type (t);
477 if (MONO_CLASS_IS_SIMD (ctx->cfg, klass))
478 return simd_class_to_llvm_type (ctx, klass);
481 return type_to_llvm_type (ctx, mono_class_enum_basetype (klass));
483 ltype = (LLVMTypeRef)g_hash_table_lookup (ctx->module->llvm_types, klass);
485 ltype = create_llvm_type_for_type (ctx->module, klass);
486 g_hash_table_insert (ctx->module->llvm_types, klass, ltype);
492 printf ("X: %d\n", t->type);
493 ctx->cfg->exception_message = g_strdup_printf ("type %s", mono_type_full_name (t));
494 ctx->cfg->disable_llvm = TRUE;
502 * Return whenever T is an unsigned int type.
505 type_is_unsigned (EmitContext *ctx, MonoType *t)
507 t = mini_get_underlying_type (t);
523 * type_to_llvm_arg_type:
525 * Same as type_to_llvm_type, but treat i8/i16 as i32.
528 type_to_llvm_arg_type (EmitContext *ctx, MonoType *t)
530 LLVMTypeRef ptype = type_to_llvm_type (ctx, t);
532 if (ctx->cfg->llvm_only)
536 * This works on all abis except arm64/ios which passes multiple
537 * arguments in one stack slot.
540 if (ptype == LLVMInt8Type () || ptype == LLVMInt16Type ()) {
542 * LLVM generates code which only sets the lower bits, while JITted
543 * code expects all the bits to be set.
545 ptype = LLVMInt32Type ();
553 * llvm_type_to_stack_type:
555 * Return the LLVM type which needs to be used when a value of type TYPE is pushed
558 static G_GNUC_UNUSED LLVMTypeRef
559 llvm_type_to_stack_type (MonoCompile *cfg, LLVMTypeRef type)
563 if (type == LLVMInt8Type ())
564 return LLVMInt32Type ();
565 else if (type == LLVMInt16Type ())
566 return LLVMInt32Type ();
567 else if (!cfg->r4fp && type == LLVMFloatType ())
568 return LLVMDoubleType ();
574 * regtype_to_llvm_type:
576 * Return the LLVM type corresponding to the regtype C used in instruction
580 regtype_to_llvm_type (char c)
584 return LLVMInt32Type ();
586 return LLVMInt64Type ();
588 return LLVMDoubleType ();
597 * Return the LLVM type corresponding to the unary/binary opcode OPCODE.
600 op_to_llvm_type (int opcode)
605 return LLVMInt8Type ();
608 return LLVMInt8Type ();
611 return LLVMInt16Type ();
614 return LLVMInt16Type ();
617 return LLVMInt32Type ();
620 return LLVMInt32Type ();
622 return LLVMInt64Type ();
624 return LLVMFloatType ();
626 return LLVMDoubleType ();
628 return LLVMInt64Type ();
630 return LLVMInt32Type ();
632 return LLVMInt64Type ();
637 return LLVMInt8Type ();
642 return LLVMInt16Type ();
644 return LLVMInt32Type ();
647 return sizeof (gpointer) == 8 ? LLVMInt64Type () : LLVMInt32Type ();
654 return LLVMInt32Type ();
661 return LLVMInt64Type ();
663 printf ("%s\n", mono_inst_name (opcode));
664 g_assert_not_reached ();
669 #define CLAUSE_START(clause) ((clause)->try_offset)
670 #define CLAUSE_END(clause) (((clause))->try_offset + ((clause))->try_len)
673 * load_store_to_llvm_type:
675 * Return the size/sign/zero extension corresponding to the load/store opcode
679 load_store_to_llvm_type (int opcode, int *size, gboolean *sext, gboolean *zext)
685 case OP_LOADI1_MEMBASE:
686 case OP_STOREI1_MEMBASE_REG:
687 case OP_STOREI1_MEMBASE_IMM:
688 case OP_ATOMIC_LOAD_I1:
689 case OP_ATOMIC_STORE_I1:
692 return LLVMInt8Type ();
693 case OP_LOADU1_MEMBASE:
695 case OP_ATOMIC_LOAD_U1:
696 case OP_ATOMIC_STORE_U1:
699 return LLVMInt8Type ();
700 case OP_LOADI2_MEMBASE:
701 case OP_STOREI2_MEMBASE_REG:
702 case OP_STOREI2_MEMBASE_IMM:
703 case OP_ATOMIC_LOAD_I2:
704 case OP_ATOMIC_STORE_I2:
707 return LLVMInt16Type ();
708 case OP_LOADU2_MEMBASE:
710 case OP_ATOMIC_LOAD_U2:
711 case OP_ATOMIC_STORE_U2:
714 return LLVMInt16Type ();
715 case OP_LOADI4_MEMBASE:
716 case OP_LOADU4_MEMBASE:
719 case OP_STOREI4_MEMBASE_REG:
720 case OP_STOREI4_MEMBASE_IMM:
721 case OP_ATOMIC_LOAD_I4:
722 case OP_ATOMIC_STORE_I4:
723 case OP_ATOMIC_LOAD_U4:
724 case OP_ATOMIC_STORE_U4:
726 return LLVMInt32Type ();
727 case OP_LOADI8_MEMBASE:
729 case OP_STOREI8_MEMBASE_REG:
730 case OP_STOREI8_MEMBASE_IMM:
731 case OP_ATOMIC_LOAD_I8:
732 case OP_ATOMIC_STORE_I8:
733 case OP_ATOMIC_LOAD_U8:
734 case OP_ATOMIC_STORE_U8:
736 return LLVMInt64Type ();
737 case OP_LOADR4_MEMBASE:
738 case OP_STORER4_MEMBASE_REG:
739 case OP_ATOMIC_LOAD_R4:
740 case OP_ATOMIC_STORE_R4:
742 return LLVMFloatType ();
743 case OP_LOADR8_MEMBASE:
744 case OP_STORER8_MEMBASE_REG:
745 case OP_ATOMIC_LOAD_R8:
746 case OP_ATOMIC_STORE_R8:
748 return LLVMDoubleType ();
749 case OP_LOAD_MEMBASE:
751 case OP_STORE_MEMBASE_REG:
752 case OP_STORE_MEMBASE_IMM:
753 *size = sizeof (gpointer);
754 return IntPtrType ();
756 g_assert_not_reached ();
764 * Return the LLVM intrinsics corresponding to the overflow opcode OPCODE.
767 ovf_op_to_intrins (int opcode)
771 return "llvm.sadd.with.overflow.i32";
773 return "llvm.uadd.with.overflow.i32";
775 return "llvm.ssub.with.overflow.i32";
777 return "llvm.usub.with.overflow.i32";
779 return "llvm.smul.with.overflow.i32";
781 return "llvm.umul.with.overflow.i32";
783 return "llvm.sadd.with.overflow.i64";
785 return "llvm.uadd.with.overflow.i64";
787 return "llvm.ssub.with.overflow.i64";
789 return "llvm.usub.with.overflow.i64";
791 return "llvm.smul.with.overflow.i64";
793 return "llvm.umul.with.overflow.i64";
795 g_assert_not_reached ();
801 simd_op_to_intrins (int opcode)
804 #if defined(TARGET_X86) || defined(TARGET_AMD64)
806 return "llvm.x86.sse2.min.pd";
808 return "llvm.x86.sse.min.ps";
810 return "llvm.x86.sse41.pminud";
812 return "llvm.x86.sse41.pminuw";
814 return "llvm.x86.sse2.pminu.b";
816 return "llvm.x86.sse2.pmins.w";
818 return "llvm.x86.sse2.max.pd";
820 return "llvm.x86.sse.max.ps";
822 return "llvm.x86.sse3.hadd.pd";
824 return "llvm.x86.sse3.hadd.ps";
826 return "llvm.x86.sse3.hsub.pd";
828 return "llvm.x86.sse3.hsub.ps";
830 return "llvm.x86.sse41.pmaxud";
832 return "llvm.x86.sse41.pmaxuw";
834 return "llvm.x86.sse2.pmaxu.b";
836 return "llvm.x86.sse3.addsub.ps";
838 return "llvm.x86.sse3.addsub.pd";
839 case OP_EXTRACT_MASK:
840 return "llvm.x86.sse2.pmovmskb.128";
843 return "llvm.x86.sse2.psrli.w";
846 return "llvm.x86.sse2.psrli.d";
849 return "llvm.x86.sse2.psrli.q";
852 return "llvm.x86.sse2.pslli.w";
855 return "llvm.x86.sse2.pslli.d";
858 return "llvm.x86.sse2.pslli.q";
861 return "llvm.x86.sse2.psrai.w";
864 return "llvm.x86.sse2.psrai.d";
866 return "llvm.x86.sse2.padds.b";
868 return "llvm.x86.sse2.padds.w";
870 return "llvm.x86.sse2.psubs.b";
872 return "llvm.x86.sse2.psubs.w";
873 case OP_PADDB_SAT_UN:
874 return "llvm.x86.sse2.paddus.b";
875 case OP_PADDW_SAT_UN:
876 return "llvm.x86.sse2.paddus.w";
877 case OP_PSUBB_SAT_UN:
878 return "llvm.x86.sse2.psubus.b";
879 case OP_PSUBW_SAT_UN:
880 return "llvm.x86.sse2.psubus.w";
882 return "llvm.x86.sse2.pavg.b";
884 return "llvm.x86.sse2.pavg.w";
886 return "llvm.x86.sse.sqrt.ps";
888 return "llvm.x86.sse2.sqrt.pd";
890 return "llvm.x86.sse.rsqrt.ps";
892 return "llvm.x86.sse.rcp.ps";
894 return "llvm.x86.sse2.cvtdq2pd";
896 return "llvm.x86.sse2.cvtdq2ps";
898 return "llvm.x86.sse2.cvtpd2dq";
900 return "llvm.x86.sse2.cvtps2dq";
902 return "llvm.x86.sse2.cvtpd2ps";
904 return "llvm.x86.sse2.cvtps2pd";
906 return "llvm.x86.sse2.cvttpd2dq";
908 return "llvm.x86.sse2.cvttps2dq";
910 return "llvm.x86.sse.cmp.ps";
912 return "llvm.x86.sse2.cmp.pd";
914 return "llvm.x86.sse2.packsswb.128";
916 return "llvm.x86.sse2.packssdw.128";
918 return "llvm.x86.sse2.packuswb.128";
920 return "llvm.x86.sse41.packusdw";
922 return "llvm.x86.sse2.pmulh.w";
923 case OP_PMULW_HIGH_UN:
924 return "llvm.x86.sse2.pmulhu.w";
927 g_assert_not_reached ();
933 simd_op_to_llvm_type (int opcode)
935 #if defined(TARGET_X86) || defined(TARGET_AMD64)
939 return type_to_simd_type (MONO_TYPE_R8);
942 return type_to_simd_type (MONO_TYPE_I8);
945 return type_to_simd_type (MONO_TYPE_I4);
950 return type_to_simd_type (MONO_TYPE_I2);
954 return type_to_simd_type (MONO_TYPE_I1);
956 return type_to_simd_type (MONO_TYPE_R4);
959 return type_to_simd_type (MONO_TYPE_I4);
963 return type_to_simd_type (MONO_TYPE_R8);
967 return type_to_simd_type (MONO_TYPE_R4);
968 case OP_EXTRACT_MASK:
969 return type_to_simd_type (MONO_TYPE_I1);
975 return type_to_simd_type (MONO_TYPE_R4);
978 return type_to_simd_type (MONO_TYPE_R8);
980 g_assert_not_reached ();
991 * Return the LLVM basic block corresponding to BB.
993 static LLVMBasicBlockRef
994 get_bb (EmitContext *ctx, MonoBasicBlock *bb)
996 char bb_name_buf [128];
999 if (ctx->bblocks [bb->block_num].bblock == NULL) {
1000 if (bb->flags & BB_EXCEPTION_HANDLER) {
1001 int clause_index = (mono_get_block_region_notry (ctx->cfg, bb->region) >> 8) - 1;
1002 sprintf (bb_name_buf, "EH_CLAUSE%d_BB%d", clause_index, bb->block_num);
1003 bb_name = bb_name_buf;
1004 } else if (bb->block_num < 256) {
1005 if (!ctx->module->bb_names) {
1006 ctx->module->bb_names_len = 256;
1007 ctx->module->bb_names = g_new0 (char*, ctx->module->bb_names_len);
1009 if (!ctx->module->bb_names [bb->block_num]) {
1012 n = g_strdup_printf ("BB%d", bb->block_num);
1013 mono_memory_barrier ();
1014 ctx->module->bb_names [bb->block_num] = n;
1016 bb_name = ctx->module->bb_names [bb->block_num];
1018 sprintf (bb_name_buf, "BB%d", bb->block_num);
1019 bb_name = bb_name_buf;
1022 ctx->bblocks [bb->block_num].bblock = LLVMAppendBasicBlock (ctx->lmethod, bb_name);
1023 ctx->bblocks [bb->block_num].end_bblock = ctx->bblocks [bb->block_num].bblock;
1026 return ctx->bblocks [bb->block_num].bblock;
1032 * Return the last LLVM bblock corresponding to BB.
1033 * This might not be equal to the bb returned by get_bb () since we need to generate
1034 * multiple LLVM bblocks for a mono bblock to handle throwing exceptions.
1036 static LLVMBasicBlockRef
1037 get_end_bb (EmitContext *ctx, MonoBasicBlock *bb)
1040 return ctx->bblocks [bb->block_num].end_bblock;
1043 static LLVMBasicBlockRef
1044 gen_bb (EmitContext *ctx, const char *prefix)
1048 sprintf (bb_name, "%s%d", prefix, ++ ctx->ex_index);
1049 return LLVMAppendBasicBlock (ctx->lmethod, bb_name);
1055 * Return the target of the patch identified by TYPE and TARGET.
1058 resolve_patch (MonoCompile *cfg, MonoJumpInfoType type, gconstpointer target)
1064 memset (&ji, 0, sizeof (ji));
1066 ji.data.target = target;
1068 res = mono_resolve_patch_target (cfg->method, cfg->domain, NULL, &ji, FALSE, &error);
1069 mono_error_assert_ok (&error);
1077 * Emit code to convert the LLVM value V to DTYPE.
1080 convert_full (EmitContext *ctx, LLVMValueRef v, LLVMTypeRef dtype, gboolean is_unsigned)
1082 LLVMTypeRef stype = LLVMTypeOf (v);
1084 if (stype != dtype) {
1085 gboolean ext = FALSE;
1088 if (dtype == LLVMInt64Type () && (stype == LLVMInt32Type () || stype == LLVMInt16Type () || stype == LLVMInt8Type ()))
1090 else if (dtype == LLVMInt32Type () && (stype == LLVMInt16Type () || stype == LLVMInt8Type ()))
1092 else if (dtype == LLVMInt16Type () && (stype == LLVMInt8Type ()))
1096 return is_unsigned ? LLVMBuildZExt (ctx->builder, v, dtype, "") : LLVMBuildSExt (ctx->builder, v, dtype, "");
1098 if (dtype == LLVMDoubleType () && stype == LLVMFloatType ())
1099 return LLVMBuildFPExt (ctx->builder, v, dtype, "");
1102 if (stype == LLVMInt64Type () && (dtype == LLVMInt32Type () || dtype == LLVMInt16Type () || dtype == LLVMInt8Type ()))
1103 return LLVMBuildTrunc (ctx->builder, v, dtype, "");
1104 if (stype == LLVMInt32Type () && (dtype == LLVMInt16Type () || dtype == LLVMInt8Type ()))
1105 return LLVMBuildTrunc (ctx->builder, v, dtype, "");
1106 if (stype == LLVMInt16Type () && dtype == LLVMInt8Type ())
1107 return LLVMBuildTrunc (ctx->builder, v, dtype, "");
1108 if (stype == LLVMDoubleType () && dtype == LLVMFloatType ())
1109 return LLVMBuildFPTrunc (ctx->builder, v, dtype, "");
1111 if (LLVMGetTypeKind (stype) == LLVMPointerTypeKind && LLVMGetTypeKind (dtype) == LLVMPointerTypeKind)
1112 return LLVMBuildBitCast (ctx->builder, v, dtype, "");
1113 if (LLVMGetTypeKind (dtype) == LLVMPointerTypeKind)
1114 return LLVMBuildIntToPtr (ctx->builder, v, dtype, "");
1115 if (LLVMGetTypeKind (stype) == LLVMPointerTypeKind)
1116 return LLVMBuildPtrToInt (ctx->builder, v, dtype, "");
1118 if (mono_arch_is_soft_float ()) {
1119 if (stype == LLVMInt32Type () && dtype == LLVMFloatType ())
1120 return LLVMBuildBitCast (ctx->builder, v, dtype, "");
1121 if (stype == LLVMInt32Type () && dtype == LLVMDoubleType ())
1122 return LLVMBuildBitCast (ctx->builder, LLVMBuildZExt (ctx->builder, v, LLVMInt64Type (), ""), dtype, "");
1125 if (LLVMGetTypeKind (stype) == LLVMVectorTypeKind && LLVMGetTypeKind (dtype) == LLVMVectorTypeKind)
1126 return LLVMBuildBitCast (ctx->builder, v, dtype, "");
1129 LLVMDumpValue (LLVMConstNull (dtype));
1130 g_assert_not_reached ();
1138 convert (EmitContext *ctx, LLVMValueRef v, LLVMTypeRef dtype)
1140 return convert_full (ctx, v, dtype, FALSE);
1144 * emit_volatile_load:
1146 * If vreg is volatile, emit a load from its address.
1149 emit_volatile_load (EmitContext *ctx, int vreg)
1153 LLVMValueRef v = LLVMBuildLoad (ctx->builder, ctx->addresses [vreg], "");
1154 t = ctx->vreg_cli_types [vreg];
1155 if (t && !t->byref) {
1157 * Might have to zero extend since llvm doesn't have
1160 if (t->type == MONO_TYPE_U1 || t->type == MONO_TYPE_U2 || t->type == MONO_TYPE_CHAR || t->type == MONO_TYPE_BOOLEAN)
1161 v = LLVMBuildZExt (ctx->builder, v, LLVMInt32Type (), "");
1162 else if (t->type == MONO_TYPE_I1 || t->type == MONO_TYPE_I2)
1163 v = LLVMBuildSExt (ctx->builder, v, LLVMInt32Type (), "");
1164 else if (t->type == MONO_TYPE_U8)
1165 v = LLVMBuildZExt (ctx->builder, v, LLVMInt64Type (), "");
1172 * emit_volatile_store:
1174 * If VREG is volatile, emit a store from its value to its address.
1177 emit_volatile_store (EmitContext *ctx, int vreg)
1179 MonoInst *var = get_vreg_to_inst (ctx->cfg, vreg);
1181 if (var && var->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT)) {
1182 g_assert (ctx->addresses [vreg]);
1183 LLVMBuildStore (ctx->builder, convert (ctx, ctx->values [vreg], type_to_llvm_type (ctx, var->inst_vtype)), ctx->addresses [vreg]);
1188 sig_to_llvm_sig_no_cinfo (EmitContext *ctx, MonoMethodSignature *sig)
1190 LLVMTypeRef ret_type;
1191 LLVMTypeRef *param_types = NULL;
1196 rtype = mini_get_underlying_type (sig->ret);
1197 ret_type = type_to_llvm_type (ctx, rtype);
1201 param_types = g_new0 (LLVMTypeRef, (sig->param_count * 8) + 3);
1205 param_types [pindex ++] = ThisType ();
1206 for (i = 0; i < sig->param_count; ++i)
1207 param_types [pindex ++] = type_to_llvm_arg_type (ctx, sig->params [i]);
1209 if (!ctx_ok (ctx)) {
1210 g_free (param_types);
1214 res = LLVMFunctionType (ret_type, param_types, pindex, FALSE);
1215 g_free (param_types);
1221 * sig_to_llvm_sig_full:
1223 * Return the LLVM signature corresponding to the mono signature SIG using the
1224 * calling convention information in CINFO. Fill out the parameter mapping information in CINFO.
1227 sig_to_llvm_sig_full (EmitContext *ctx, MonoMethodSignature *sig, LLVMCallInfo *cinfo)
1229 LLVMTypeRef ret_type;
1230 LLVMTypeRef *param_types = NULL;
1232 int i, j, pindex, vret_arg_pindex = 0;
1233 gboolean vretaddr = FALSE;
1237 return sig_to_llvm_sig_no_cinfo (ctx, sig);
1239 rtype = mini_get_underlying_type (sig->ret);
1240 ret_type = type_to_llvm_type (ctx, rtype);
1244 switch (cinfo->ret.storage) {
1245 case LLVMArgVtypeInReg:
1246 /* LLVM models this by returning an aggregate value */
1247 if (cinfo->ret.pair_storage [0] == LLVMArgInIReg && cinfo->ret.pair_storage [1] == LLVMArgNone) {
1248 LLVMTypeRef members [2];
1250 members [0] = IntPtrType ();
1251 ret_type = LLVMStructType (members, 1, FALSE);
1252 } else if (cinfo->ret.pair_storage [0] == LLVMArgNone && cinfo->ret.pair_storage [1] == LLVMArgNone) {
1254 ret_type = LLVMVoidType ();
1255 } else if (cinfo->ret.pair_storage [0] == LLVMArgInIReg && cinfo->ret.pair_storage [1] == LLVMArgInIReg) {
1256 LLVMTypeRef members [2];
1258 members [0] = IntPtrType ();
1259 members [1] = IntPtrType ();
1260 ret_type = LLVMStructType (members, 2, FALSE);
1262 g_assert_not_reached ();
1265 case LLVMArgVtypeByVal:
1266 /* Vtype returned normally by val */
1268 case LLVMArgVtypeAsScalar: {
1269 int size = mono_class_value_size (mono_class_from_mono_type (rtype), NULL);
1270 /* LLVM models this by returning an int */
1271 if (size < SIZEOF_VOID_P) {
1272 g_assert (cinfo->ret.nslots == 1);
1273 ret_type = LLVMIntType (size * 8);
1275 g_assert (cinfo->ret.nslots == 1 || cinfo->ret.nslots == 2);
1276 ret_type = LLVMIntType (cinfo->ret.nslots * sizeof (mgreg_t) * 8);
1280 case LLVMArgFpStruct: {
1281 /* Vtype returned as a fp struct */
1282 LLVMTypeRef members [16];
1284 /* Have to create our own structure since we don't map fp structures to LLVM fp structures yet */
1285 for (i = 0; i < cinfo->ret.nslots; ++i)
1286 members [i] = cinfo->ret.esize == 8 ? LLVMDoubleType () : LLVMFloatType ();
1287 ret_type = LLVMStructType (members, cinfo->ret.nslots, FALSE);
1290 case LLVMArgVtypeByRef:
1291 /* Vtype returned using a hidden argument */
1292 ret_type = LLVMVoidType ();
1294 case LLVMArgVtypeRetAddr:
1295 case LLVMArgGsharedvtFixed:
1296 case LLVMArgGsharedvtFixedVtype:
1297 case LLVMArgGsharedvtVariable:
1299 ret_type = LLVMVoidType ();
1305 param_types = g_new0 (LLVMTypeRef, (sig->param_count * 8) + 3);
1307 if (cinfo->ret.storage == LLVMArgVtypeByRef) {
1309 * Has to be the first argument because of the sret argument attribute
1310 * FIXME: This might conflict with passing 'this' as the first argument, but
1311 * this is only used on arm64 which has a dedicated struct return register.
1313 cinfo->vret_arg_pindex = pindex;
1314 param_types [pindex] = type_to_llvm_arg_type (ctx, sig->ret);
1315 if (!ctx_ok (ctx)) {
1316 g_free (param_types);
1319 param_types [pindex] = LLVMPointerType (param_types [pindex], 0);
1322 if (!ctx->llvm_only && cinfo->rgctx_arg) {
1323 cinfo->rgctx_arg_pindex = pindex;
1324 param_types [pindex] = ctx->module->ptr_type;
1327 if (cinfo->imt_arg) {
1328 cinfo->imt_arg_pindex = pindex;
1329 param_types [pindex] = ctx->module->ptr_type;
1333 /* Compute the index in the LLVM signature where the vret arg needs to be passed */
1334 vret_arg_pindex = pindex;
1335 if (cinfo->vret_arg_index == 1) {
1336 /* Add the slots consumed by the first argument */
1337 LLVMArgInfo *ainfo = &cinfo->args [0];
1338 switch (ainfo->storage) {
1339 case LLVMArgVtypeInReg:
1340 for (j = 0; j < 2; ++j) {
1341 if (ainfo->pair_storage [j] == LLVMArgInIReg)
1350 cinfo->vret_arg_pindex = vret_arg_pindex;
1353 if (vretaddr && vret_arg_pindex == pindex)
1354 param_types [pindex ++] = IntPtrType ();
1356 cinfo->this_arg_pindex = pindex;
1357 param_types [pindex ++] = ThisType ();
1358 cinfo->args [0].pindex = cinfo->this_arg_pindex;
1360 if (vretaddr && vret_arg_pindex == pindex)
1361 param_types [pindex ++] = IntPtrType ();
1362 for (i = 0; i < sig->param_count; ++i) {
1363 LLVMArgInfo *ainfo = &cinfo->args [i + sig->hasthis];
1365 if (vretaddr && vret_arg_pindex == pindex)
1366 param_types [pindex ++] = IntPtrType ();
1367 ainfo->pindex = pindex;
1369 switch (ainfo->storage) {
1370 case LLVMArgVtypeInReg:
1371 for (j = 0; j < 2; ++j) {
1372 switch (ainfo->pair_storage [j]) {
1374 param_types [pindex ++] = LLVMIntType (sizeof (gpointer) * 8);
1379 g_assert_not_reached ();
1383 case LLVMArgVtypeByVal:
1384 param_types [pindex] = type_to_llvm_arg_type (ctx, ainfo->type);
1387 param_types [pindex] = LLVMPointerType (param_types [pindex], 0);
1390 case LLVMArgAsIArgs:
1391 param_types [pindex] = LLVMArrayType (IntPtrType (), ainfo->nslots);
1394 case LLVMArgVtypeByRef:
1395 param_types [pindex] = type_to_llvm_arg_type (ctx, ainfo->type);
1398 param_types [pindex] = LLVMPointerType (param_types [pindex], 0);
1401 case LLVMArgAsFpArgs: {
1404 /* Emit dummy fp arguments if needed so the rest is passed on the stack */
1405 for (j = 0; j < ainfo->ndummy_fpargs; ++j)
1406 param_types [pindex ++] = LLVMDoubleType ();
1407 for (j = 0; j < ainfo->nslots; ++j)
1408 param_types [pindex ++] = ainfo->esize == 8 ? LLVMDoubleType () : LLVMFloatType ();
1411 case LLVMArgVtypeAsScalar:
1412 g_assert_not_reached ();
1414 case LLVMArgGsharedvtFixed:
1415 case LLVMArgGsharedvtFixedVtype:
1416 param_types [pindex ++] = LLVMPointerType (type_to_llvm_arg_type (ctx, ainfo->type), 0);
1418 case LLVMArgGsharedvtVariable:
1419 param_types [pindex ++] = LLVMPointerType (IntPtrType (), 0);
1422 param_types [pindex ++] = type_to_llvm_arg_type (ctx, ainfo->type);
1426 if (!ctx_ok (ctx)) {
1427 g_free (param_types);
1430 if (vretaddr && vret_arg_pindex == pindex)
1431 param_types [pindex ++] = IntPtrType ();
1432 if (ctx->llvm_only && cinfo->rgctx_arg) {
1433 /* Pass the rgctx as the last argument */
1434 cinfo->rgctx_arg_pindex = pindex;
1435 param_types [pindex] = ctx->module->ptr_type;
1439 res = LLVMFunctionType (ret_type, param_types, pindex, FALSE);
1440 g_free (param_types);
1446 sig_to_llvm_sig (EmitContext *ctx, MonoMethodSignature *sig)
1448 return sig_to_llvm_sig_full (ctx, sig, NULL);
1452 * LLVMFunctionType1:
1454 * Create an LLVM function type from the arguments.
1456 static G_GNUC_UNUSED LLVMTypeRef
1457 LLVMFunctionType0 (LLVMTypeRef ReturnType,
1460 return LLVMFunctionType (ReturnType, NULL, 0, IsVarArg);
1464 * LLVMFunctionType1:
1466 * Create an LLVM function type from the arguments.
1468 static G_GNUC_UNUSED LLVMTypeRef
1469 LLVMFunctionType1 (LLVMTypeRef ReturnType,
1470 LLVMTypeRef ParamType1,
1473 LLVMTypeRef param_types [1];
1475 param_types [0] = ParamType1;
1477 return LLVMFunctionType (ReturnType, param_types, 1, IsVarArg);
1481 * LLVMFunctionType2:
1483 * Create an LLVM function type from the arguments.
1485 static G_GNUC_UNUSED LLVMTypeRef
1486 LLVMFunctionType2 (LLVMTypeRef ReturnType,
1487 LLVMTypeRef ParamType1,
1488 LLVMTypeRef ParamType2,
1491 LLVMTypeRef param_types [2];
1493 param_types [0] = ParamType1;
1494 param_types [1] = ParamType2;
1496 return LLVMFunctionType (ReturnType, param_types, 2, IsVarArg);
1500 * LLVMFunctionType3:
1502 * Create an LLVM function type from the arguments.
1504 static G_GNUC_UNUSED LLVMTypeRef
1505 LLVMFunctionType3 (LLVMTypeRef ReturnType,
1506 LLVMTypeRef ParamType1,
1507 LLVMTypeRef ParamType2,
1508 LLVMTypeRef ParamType3,
1511 LLVMTypeRef param_types [3];
1513 param_types [0] = ParamType1;
1514 param_types [1] = ParamType2;
1515 param_types [2] = ParamType3;
1517 return LLVMFunctionType (ReturnType, param_types, 3, IsVarArg);
1520 static G_GNUC_UNUSED LLVMTypeRef
1521 LLVMFunctionType5 (LLVMTypeRef ReturnType,
1522 LLVMTypeRef ParamType1,
1523 LLVMTypeRef ParamType2,
1524 LLVMTypeRef ParamType3,
1525 LLVMTypeRef ParamType4,
1526 LLVMTypeRef ParamType5,
1529 LLVMTypeRef param_types [5];
1531 param_types [0] = ParamType1;
1532 param_types [1] = ParamType2;
1533 param_types [2] = ParamType3;
1534 param_types [3] = ParamType4;
1535 param_types [4] = ParamType5;
1537 return LLVMFunctionType (ReturnType, param_types, 5, IsVarArg);
1543 * Create an LLVM builder and remember it so it can be freed later.
1545 static LLVMBuilderRef
1546 create_builder (EmitContext *ctx)
1548 LLVMBuilderRef builder = LLVMCreateBuilder ();
1550 ctx->builders = g_slist_prepend_mempool (ctx->cfg->mempool, ctx->builders, builder);
1556 get_aotconst_name (MonoJumpInfoType type, gconstpointer data, int got_offset)
1561 case MONO_PATCH_INFO_INTERNAL_METHOD:
1562 name = g_strdup_printf ("jit_icall_%s", data);
1564 case MONO_PATCH_INFO_RGCTX_SLOT_INDEX: {
1565 MonoJumpInfoRgctxEntry *entry = (MonoJumpInfoRgctxEntry*)data;
1566 name = g_strdup_printf ("RGCTX_SLOT_INDEX_%s", mono_rgctx_info_type_to_str (entry->info_type));
1570 name = g_strdup_printf ("%s_%d", mono_ji_type_to_string (type), got_offset);
1578 get_aotconst_typed (EmitContext *ctx, MonoJumpInfoType type, gconstpointer data, LLVMTypeRef llvm_type)
1582 LLVMValueRef indexes [2];
1584 LLVMValueRef got_entry_addr, load;
1585 LLVMBuilderRef builder = ctx->builder;
1590 ji = g_new0 (MonoJumpInfo, 1);
1592 ji->data.target = data;
1594 ji = mono_aot_patch_info_dup (ji);
1596 ji->next = cfg->patch_info;
1597 cfg->patch_info = ji;
1599 got_offset = mono_aot_get_got_offset (cfg->patch_info);
1600 ctx->module->max_got_offset = MAX (ctx->module->max_got_offset, got_offset);
1602 * If the got slot is shared, it means its initialized when the aot image is loaded, so we don't need to
1603 * explicitly initialize it.
1605 if (!mono_aot_is_shared_got_offset (got_offset)) {
1606 //mono_print_ji (ji);
1608 ctx->has_got_access = TRUE;
1611 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
1612 indexes [1] = LLVMConstInt (LLVMInt32Type (), (gssize)got_offset, FALSE);
1613 got_entry_addr = LLVMBuildGEP (builder, ctx->module->got_var, indexes, 2, "");
1615 name = get_aotconst_name (type, data, got_offset);
1617 load = LLVMBuildLoad (builder, got_entry_addr, "");
1618 load = convert (ctx, load, llvm_type);
1619 LLVMSetValueName (load, name ? name : "");
1621 load = LLVMBuildLoad (builder, got_entry_addr, name ? name : "");
1624 //set_invariant_load_flag (load);
1630 get_aotconst (EmitContext *ctx, MonoJumpInfoType type, gconstpointer data)
1632 return get_aotconst_typed (ctx, type, data, NULL);
1636 get_callee (EmitContext *ctx, LLVMTypeRef llvm_sig, MonoJumpInfoType type, gconstpointer data)
1638 LLVMValueRef callee;
1640 if (ctx->llvm_only) {
1641 callee_name = mono_aot_get_direct_call_symbol (type, data);
1643 /* Directly callable */
1645 callee = (LLVMValueRef)g_hash_table_lookup (ctx->module->direct_callables, callee_name);
1647 callee = LLVMAddFunction (ctx->lmodule, callee_name, llvm_sig);
1649 LLVMSetVisibility (callee, LLVMHiddenVisibility);
1651 g_hash_table_insert (ctx->module->direct_callables, (char*)callee_name, callee);
1653 /* LLVMTypeRef's are uniqued */
1654 if (LLVMGetElementType (LLVMTypeOf (callee)) != llvm_sig)
1655 return LLVMConstBitCast (callee, LLVMPointerType (llvm_sig, 0));
1657 g_free (callee_name);
1663 * Calls are made through the GOT.
1665 return get_aotconst_typed (ctx, type, data, LLVMPointerType (llvm_sig, 0));
1667 MonoJumpInfo *ji = NULL;
1669 callee_name = mono_aot_get_plt_symbol (type, data);
1673 if (ctx->cfg->compile_aot)
1674 /* Add a patch so referenced wrappers can be compiled in full aot mode */
1675 mono_add_patch_info (ctx->cfg, 0, type, data);
1678 callee = (LLVMValueRef)g_hash_table_lookup (ctx->module->plt_entries, callee_name);
1680 callee = LLVMAddFunction (ctx->lmodule, callee_name, llvm_sig);
1682 LLVMSetVisibility (callee, LLVMHiddenVisibility);
1684 g_hash_table_insert (ctx->module->plt_entries, (char*)callee_name, callee);
1687 if (ctx->cfg->compile_aot) {
1688 ji = g_new0 (MonoJumpInfo, 1);
1690 ji->data.target = data;
1692 g_hash_table_insert (ctx->module->plt_entries_ji, ji, callee);
1700 get_handler_clause (MonoCompile *cfg, MonoBasicBlock *bb)
1702 MonoMethodHeader *header = cfg->header;
1703 MonoExceptionClause *clause;
1707 if (bb->region != -1 && MONO_BBLOCK_IS_IN_REGION (bb, MONO_REGION_TRY))
1708 return (bb->region >> 8) - 1;
1711 for (i = 0; i < header->num_clauses; ++i) {
1712 clause = &header->clauses [i];
1714 if (MONO_OFFSET_IN_CLAUSE (clause, bb->real_offset) && clause->flags == MONO_EXCEPTION_CLAUSE_NONE)
1721 static MonoExceptionClause *
1722 get_most_deep_clause (MonoCompile *cfg, EmitContext *ctx, MonoBasicBlock *bb)
1724 // Since they're sorted by nesting we just need
1725 // the first one that the bb is a member of
1726 MonoExceptionClause *last = NULL;
1728 for (int i = 0; i < cfg->header->num_clauses; i++) {
1729 MonoExceptionClause *curr = &cfg->header->clauses [i];
1731 if (MONO_OFFSET_IN_CLAUSE (curr, bb->real_offset))
1734 if (MONO_OFFSET_IN_CLAUSE (curr, bb->real_offset)) {
1735 if (last && CLAUSE_END(last) > CLAUSE_END(curr))
1749 set_metadata_flag (LLVMValueRef v, const char *flag_name)
1751 LLVMValueRef md_arg;
1754 md_kind = LLVMGetMDKindID (flag_name, strlen (flag_name));
1755 md_arg = LLVMMDString ("mono", 4);
1756 LLVMSetMetadata (v, md_kind, LLVMMDNode (&md_arg, 1));
1760 set_invariant_load_flag (LLVMValueRef v)
1762 LLVMValueRef md_arg;
1764 const char *flag_name;
1766 // FIXME: Cache this
1767 flag_name = "invariant.load";
1768 md_kind = LLVMGetMDKindID (flag_name, strlen (flag_name));
1769 md_arg = LLVMMDString ("<index>", strlen ("<index>"));
1770 LLVMSetMetadata (v, md_kind, LLVMMDNode (&md_arg, 1));
1776 * Emit an LLVM call or invoke instruction depending on whenever the call is inside
1780 emit_call (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, LLVMValueRef callee, LLVMValueRef *args, int pindex)
1782 MonoCompile *cfg = ctx->cfg;
1783 LLVMValueRef lcall = NULL;
1784 LLVMBuilderRef builder = *builder_ref;
1785 MonoExceptionClause *clause;
1787 if (ctx->llvm_only) {
1788 clause = get_most_deep_clause (cfg, ctx, bb);
1791 g_assert (clause->flags == MONO_EXCEPTION_CLAUSE_NONE || clause->flags == MONO_EXCEPTION_CLAUSE_FINALLY);
1794 * Have to use an invoke instead of a call, branching to the
1795 * handler bblock of the clause containing this bblock.
1797 intptr_t key = CLAUSE_END(clause);
1799 LLVMBasicBlockRef lpad_bb = (LLVMBasicBlockRef)g_hash_table_lookup (ctx->exc_meta, (gconstpointer)key);
1801 // FIXME: Find the one that has the lowest end bound for the right start address
1802 // FIXME: Finally + nesting
1805 LLVMBasicBlockRef noex_bb = gen_bb (ctx, "CALL_NOEX_BB");
1808 lcall = LLVMBuildInvoke (builder, callee, args, pindex, noex_bb, lpad_bb, "");
1810 builder = ctx->builder = create_builder (ctx);
1811 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
1813 ctx->bblocks [bb->block_num].end_bblock = noex_bb;
1817 int clause_index = get_handler_clause (cfg, bb);
1819 if (clause_index != -1) {
1820 MonoMethodHeader *header = cfg->header;
1821 MonoExceptionClause *ec = &header->clauses [clause_index];
1822 MonoBasicBlock *tblock;
1823 LLVMBasicBlockRef ex_bb, noex_bb;
1826 * Have to use an invoke instead of a call, branching to the
1827 * handler bblock of the clause containing this bblock.
1830 g_assert (ec->flags == MONO_EXCEPTION_CLAUSE_NONE || ec->flags == MONO_EXCEPTION_CLAUSE_FINALLY);
1832 tblock = cfg->cil_offset_to_bb [ec->handler_offset];
1835 ctx->bblocks [tblock->block_num].invoke_target = TRUE;
1837 ex_bb = get_bb (ctx, tblock);
1839 noex_bb = gen_bb (ctx, "NOEX_BB");
1842 lcall = LLVMBuildInvoke (builder, callee, args, pindex, noex_bb, ex_bb, "");
1844 builder = ctx->builder = create_builder (ctx);
1845 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
1847 ctx->bblocks [bb->block_num].end_bblock = noex_bb;
1852 lcall = LLVMBuildCall (builder, callee, args, pindex, "");
1853 ctx->builder = builder;
1857 *builder_ref = ctx->builder;
1863 emit_load_general (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, int size, LLVMValueRef addr, const char *name, gboolean is_faulting, BarrierKind barrier)
1865 const char *intrins_name;
1866 LLVMValueRef args [16], res;
1867 LLVMTypeRef addr_type;
1868 gboolean use_intrinsics = TRUE;
1870 #if LLVM_API_VERSION > 100
1871 if (is_faulting && bb->region != -1 && !ctx->cfg->llvm_only) {
1872 /* The llvm.mono.load/store intrinsics are not supported by this llvm version, emit an explicit null check instead */
1873 LLVMValueRef cmp = LLVMBuildICmp (*builder_ref, LLVMIntEQ, addr, LLVMConstNull (LLVMTypeOf (addr)), "");
1874 emit_cond_system_exception (ctx, bb, "NullReferenceException", cmp);
1875 *builder_ref = ctx->builder;
1876 use_intrinsics = FALSE;
1880 if (is_faulting && bb->region != -1 && !ctx->cfg->llvm_only && use_intrinsics) {
1881 LLVMAtomicOrdering ordering;
1884 case LLVM_BARRIER_NONE:
1885 ordering = LLVMAtomicOrderingNotAtomic;
1887 case LLVM_BARRIER_ACQ:
1888 ordering = LLVMAtomicOrderingAcquire;
1890 case LLVM_BARRIER_SEQ:
1891 ordering = LLVMAtomicOrderingSequentiallyConsistent;
1894 g_assert_not_reached ();
1899 * We handle loads which can fault by calling a mono specific intrinsic
1900 * using an invoke, so they are handled properly inside try blocks.
1901 * We can't use this outside clauses, since LLVM optimizes intrinsics which
1902 * are marked with IntrReadArgMem.
1906 intrins_name = "llvm.mono.load.i8.p0i8";
1909 intrins_name = "llvm.mono.load.i16.p0i16";
1912 intrins_name = "llvm.mono.load.i32.p0i32";
1915 intrins_name = "llvm.mono.load.i64.p0i64";
1918 g_assert_not_reached ();
1921 addr_type = LLVMTypeOf (addr);
1922 if (addr_type == LLVMPointerType (LLVMDoubleType (), 0) || addr_type == LLVMPointerType (LLVMFloatType (), 0))
1923 addr = LLVMBuildBitCast (*builder_ref, addr, LLVMPointerType (LLVMIntType (size * 8), 0), "");
1926 args [1] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
1927 args [2] = LLVMConstInt (LLVMInt1Type (), TRUE, FALSE);
1928 args [3] = LLVMConstInt (LLVMInt32Type (), ordering, FALSE);
1929 res = emit_call (ctx, bb, builder_ref, LLVMGetNamedFunction (ctx->lmodule, intrins_name), args, 4);
1931 if (addr_type == LLVMPointerType (LLVMDoubleType (), 0))
1932 res = LLVMBuildBitCast (*builder_ref, res, LLVMDoubleType (), "");
1933 else if (addr_type == LLVMPointerType (LLVMFloatType (), 0))
1934 res = LLVMBuildBitCast (*builder_ref, res, LLVMFloatType (), "");
1941 * We emit volatile loads for loads which can fault, because otherwise
1942 * LLVM will generate invalid code when encountering a load from a
1945 res = mono_llvm_build_load (*builder_ref, addr, name, is_faulting, barrier);
1947 /* Mark it with a custom metadata */
1950 set_metadata_flag (res, "mono.faulting.load");
1958 emit_load (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, int size, LLVMValueRef addr, const char *name, gboolean is_faulting)
1960 return emit_load_general (ctx, bb, builder_ref, size, addr, name, is_faulting, LLVM_BARRIER_NONE);
1964 emit_store_general (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, int size, LLVMValueRef value, LLVMValueRef addr, gboolean is_faulting, BarrierKind barrier)
1966 const char *intrins_name;
1967 LLVMValueRef args [16];
1968 gboolean use_intrinsics = TRUE;
1970 #if LLVM_API_VERSION > 100
1971 if (is_faulting && bb->region != -1 && !ctx->cfg->llvm_only) {
1972 /* The llvm.mono.load/store intrinsics are not supported by this llvm version, emit an explicit null check instead */
1973 LLVMValueRef cmp = LLVMBuildICmp (*builder_ref, LLVMIntEQ, addr, LLVMConstNull (LLVMTypeOf (addr)), "");
1974 emit_cond_system_exception (ctx, bb, "NullReferenceException", cmp);
1975 *builder_ref = ctx->builder;
1976 use_intrinsics = FALSE;
1980 if (is_faulting && bb->region != -1 && !ctx->cfg->llvm_only && use_intrinsics) {
1981 LLVMAtomicOrdering ordering;
1984 case LLVM_BARRIER_NONE:
1985 ordering = LLVMAtomicOrderingNotAtomic;
1987 case LLVM_BARRIER_REL:
1988 ordering = LLVMAtomicOrderingRelease;
1990 case LLVM_BARRIER_SEQ:
1991 ordering = LLVMAtomicOrderingSequentiallyConsistent;
1994 g_assert_not_reached ();
2000 intrins_name = "llvm.mono.store.i8.p0i8";
2003 intrins_name = "llvm.mono.store.i16.p0i16";
2006 intrins_name = "llvm.mono.store.i32.p0i32";
2009 intrins_name = "llvm.mono.store.i64.p0i64";
2012 g_assert_not_reached ();
2015 if (LLVMTypeOf (value) == LLVMDoubleType () || LLVMTypeOf (value) == LLVMFloatType ()) {
2016 value = LLVMBuildBitCast (*builder_ref, value, LLVMIntType (size * 8), "");
2017 addr = LLVMBuildBitCast (*builder_ref, addr, LLVMPointerType (LLVMIntType (size * 8), 0), "");
2022 args [2] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
2023 args [3] = LLVMConstInt (LLVMInt1Type (), TRUE, FALSE);
2024 args [4] = LLVMConstInt (LLVMInt32Type (), ordering, FALSE);
2025 emit_call (ctx, bb, builder_ref, LLVMGetNamedFunction (ctx->lmodule, intrins_name), args, 5);
2027 mono_llvm_build_store (*builder_ref, value, addr, is_faulting, barrier);
2032 emit_store (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, int size, LLVMValueRef value, LLVMValueRef addr, gboolean is_faulting)
2034 emit_store_general (ctx, bb, builder_ref, size, value, addr, is_faulting, LLVM_BARRIER_NONE);
2038 * emit_cond_system_exception:
2040 * Emit code to throw the exception EXC_TYPE if the condition CMP is false.
2041 * Might set the ctx exception.
2044 emit_cond_system_exception (EmitContext *ctx, MonoBasicBlock *bb, const char *exc_type, LLVMValueRef cmp)
2046 LLVMBasicBlockRef ex_bb, ex2_bb = NULL, noex_bb;
2047 LLVMBuilderRef builder;
2048 MonoClass *exc_class;
2049 LLVMValueRef args [2];
2050 LLVMValueRef callee;
2052 ex_bb = gen_bb (ctx, "EX_BB");
2054 ex2_bb = gen_bb (ctx, "EX2_BB");
2055 noex_bb = gen_bb (ctx, "NOEX_BB");
2057 LLVMBuildCondBr (ctx->builder, cmp, ex_bb, noex_bb);
2059 exc_class = mono_class_load_from_name (mono_get_corlib (), "System", exc_type);
2061 /* Emit exception throwing code */
2062 ctx->builder = builder = create_builder (ctx);
2063 LLVMPositionBuilderAtEnd (builder, ex_bb);
2065 if (ctx->cfg->llvm_only) {
2066 static LLVMTypeRef sig;
2069 sig = LLVMFunctionType1 (LLVMVoidType (), LLVMInt32Type (), FALSE);
2070 callee = get_callee (ctx, sig, MONO_PATCH_INFO_JIT_ICALL_ADDR, "mono_llvm_throw_corlib_exception");
2072 LLVMBuildBr (builder, ex2_bb);
2074 ctx->builder = builder = create_builder (ctx);
2075 LLVMPositionBuilderAtEnd (ctx->builder, ex2_bb);
2077 args [0] = LLVMConstInt (LLVMInt32Type (), exc_class->type_token - MONO_TOKEN_TYPE_DEF, FALSE);
2078 emit_call (ctx, bb, &builder, callee, args, 1);
2079 LLVMBuildUnreachable (builder);
2081 ctx->builder = builder = create_builder (ctx);
2082 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
2084 ctx->bblocks [bb->block_num].end_bblock = noex_bb;
2090 callee = ctx->module->throw_corlib_exception;
2093 const char *icall_name;
2095 sig = LLVMFunctionType2 (LLVMVoidType (), LLVMInt32Type (), LLVMPointerType (LLVMInt8Type (), 0), FALSE);
2096 icall_name = "llvm_throw_corlib_exception_abs_trampoline";
2098 if (ctx->cfg->compile_aot) {
2099 callee = get_callee (ctx, sig, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
2101 callee = LLVMAddFunction (ctx->lmodule, "llvm_throw_corlib_exception_trampoline", sig);
2104 * Differences between the LLVM/non-LLVM throw corlib exception trampoline:
2105 * - On x86, LLVM generated code doesn't push the arguments
2106 * - The trampoline takes the throw address as an arguments, not a pc offset.
2108 LLVMAddGlobalMapping (ctx->module->ee, callee, resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name));
2110 mono_memory_barrier ();
2111 ctx->module->throw_corlib_exception = callee;
2115 if (IS_TARGET_X86 || IS_TARGET_AMD64)
2116 args [0] = LLVMConstInt (LLVMInt32Type (), exc_class->type_token - MONO_TOKEN_TYPE_DEF, FALSE);
2118 args [0] = LLVMConstInt (LLVMInt32Type (), exc_class->type_token, FALSE);
2121 * The LLVM mono branch contains changes so a block address can be passed as an
2122 * argument to a call.
2124 args [1] = LLVMBlockAddress (ctx->lmethod, ex_bb);
2125 emit_call (ctx, bb, &builder, callee, args, 2);
2127 LLVMBuildUnreachable (builder);
2129 ctx->builder = builder = create_builder (ctx);
2130 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
2132 ctx->bblocks [bb->block_num].end_bblock = noex_bb;
2139 * emit_args_to_vtype:
2141 * Emit code to store the vtype in the arguments args to the address ADDRESS.
2144 emit_args_to_vtype (EmitContext *ctx, LLVMBuilderRef builder, MonoType *t, LLVMValueRef address, LLVMArgInfo *ainfo, LLVMValueRef *args)
2146 int j, size, nslots;
2148 size = mono_class_value_size (mono_class_from_mono_type (t), NULL);
2150 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (t))) {
2151 address = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (LLVMInt8Type (), 0), "");
2154 if (ainfo->storage == LLVMArgAsFpArgs)
2155 nslots = ainfo->nslots;
2159 for (j = 0; j < nslots; ++j) {
2160 LLVMValueRef index [2], addr, daddr;
2161 int part_size = size > sizeof (gpointer) ? sizeof (gpointer) : size;
2162 LLVMTypeRef part_type;
2164 while (part_size != 1 && part_size != 2 && part_size != 4 && part_size < 8)
2167 if (ainfo->pair_storage [j] == LLVMArgNone)
2170 switch (ainfo->pair_storage [j]) {
2171 case LLVMArgInIReg: {
2172 part_type = LLVMIntType (part_size * 8);
2173 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (t))) {
2174 index [0] = LLVMConstInt (LLVMInt32Type (), j * sizeof (gpointer), FALSE);
2175 addr = LLVMBuildGEP (builder, address, index, 1, "");
2177 daddr = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (IntPtrType (), 0), "");
2178 index [0] = LLVMConstInt (LLVMInt32Type (), j, FALSE);
2179 addr = LLVMBuildGEP (builder, daddr, index, 1, "");
2181 LLVMBuildStore (builder, convert (ctx, args [j], part_type), LLVMBuildBitCast (ctx->builder, addr, LLVMPointerType (part_type, 0), ""));
2184 case LLVMArgInFPReg: {
2185 LLVMTypeRef arg_type;
2187 if (ainfo->esize == 8)
2188 arg_type = LLVMDoubleType ();
2190 arg_type = LLVMFloatType ();
2192 index [0] = LLVMConstInt (LLVMInt32Type (), j, FALSE);
2193 daddr = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (arg_type, 0), "");
2194 addr = LLVMBuildGEP (builder, daddr, index, 1, "");
2195 LLVMBuildStore (builder, args [j], addr);
2201 g_assert_not_reached ();
2204 size -= sizeof (gpointer);
2209 * emit_vtype_to_args:
2211 * Emit code to load a vtype at address ADDRESS into scalar arguments. Store the arguments
2212 * into ARGS, and the number of arguments into NARGS.
2215 emit_vtype_to_args (EmitContext *ctx, LLVMBuilderRef builder, MonoType *t, LLVMValueRef address, LLVMArgInfo *ainfo, LLVMValueRef *args, guint32 *nargs)
2218 int j, size, nslots;
2219 LLVMTypeRef arg_type;
2221 size = get_vtype_size (t);
2223 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (t)))
2224 address = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (LLVMInt8Type (), 0), "");
2226 if (ainfo->storage == LLVMArgAsFpArgs)
2227 nslots = ainfo->nslots;
2230 for (j = 0; j < nslots; ++j) {
2231 LLVMValueRef index [2], addr, daddr;
2232 int partsize = size > sizeof (gpointer) ? sizeof (gpointer) : size;
2234 if (ainfo->pair_storage [j] == LLVMArgNone)
2237 switch (ainfo->pair_storage [j]) {
2239 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (t))) {
2240 index [0] = LLVMConstInt (LLVMInt32Type (), j * sizeof (gpointer), FALSE);
2241 addr = LLVMBuildGEP (builder, address, index, 1, "");
2243 daddr = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (IntPtrType (), 0), "");
2244 index [0] = LLVMConstInt (LLVMInt32Type (), j, FALSE);
2245 addr = LLVMBuildGEP (builder, daddr, index, 1, "");
2247 args [pindex ++] = convert (ctx, LLVMBuildLoad (builder, LLVMBuildBitCast (ctx->builder, addr, LLVMPointerType (LLVMIntType (partsize * 8), 0), ""), ""), IntPtrType ());
2249 case LLVMArgInFPReg:
2250 if (ainfo->esize == 8)
2251 arg_type = LLVMDoubleType ();
2253 arg_type = LLVMFloatType ();
2254 daddr = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (arg_type, 0), "");
2255 index [0] = LLVMConstInt (LLVMInt32Type (), j, FALSE);
2256 addr = LLVMBuildGEP (builder, daddr, index, 1, "");
2257 args [pindex ++] = LLVMBuildLoad (builder, addr, "");
2262 g_assert_not_reached ();
2264 size -= sizeof (gpointer);
2271 build_alloca_llvm_type_name (EmitContext *ctx, LLVMTypeRef t, int align, const char *name)
2274 * Have to place all alloca's at the end of the entry bb, since otherwise they would
2275 * get executed every time control reaches them.
2277 LLVMPositionBuilder (ctx->alloca_builder, get_bb (ctx, ctx->cfg->bb_entry), ctx->last_alloca);
2279 ctx->last_alloca = mono_llvm_build_alloca (ctx->alloca_builder, t, NULL, align, name);
2280 return ctx->last_alloca;
2284 build_alloca_llvm_type (EmitContext *ctx, LLVMTypeRef t, int align)
2286 return build_alloca_llvm_type_name (ctx, t, align, "");
2290 build_alloca (EmitContext *ctx, MonoType *t)
2292 MonoClass *k = mono_class_from_mono_type (t);
2295 g_assert (!mini_is_gsharedvt_variable_type (t));
2297 if (MONO_CLASS_IS_SIMD (ctx->cfg, k))
2300 align = mono_class_min_align (k);
2302 /* Sometimes align is not a power of 2 */
2303 while (mono_is_power_of_two (align) == -1)
2306 return build_alloca_llvm_type (ctx, type_to_llvm_type (ctx, t), align);
2310 emit_gsharedvt_ldaddr (EmitContext *ctx, int vreg)
2314 * Compute the address of the local as gsharedvt_locals_var + gsharedvt_info_var->locals_offsets [idx].
2316 MonoCompile *cfg = ctx->cfg;
2317 LLVMBuilderRef builder = ctx->builder;
2318 LLVMValueRef offset, offset_var;
2319 LLVMValueRef info_var = ctx->values [cfg->gsharedvt_info_var->dreg];
2320 LLVMValueRef locals_var = ctx->values [cfg->gsharedvt_locals_var->dreg];
2324 g_assert (info_var);
2325 g_assert (locals_var);
2327 int idx = cfg->gsharedvt_vreg_to_idx [vreg] - 1;
2329 offset = LLVMConstInt (LLVMInt32Type (), MONO_STRUCT_OFFSET (MonoGSharedVtMethodRuntimeInfo, entries) + (idx * sizeof (gpointer)), FALSE);
2330 ptr = LLVMBuildAdd (builder, convert (ctx, info_var, IntPtrType ()), convert (ctx, offset, IntPtrType ()), "");
2332 name = g_strdup_printf ("gsharedvt_local_%d_offset", vreg);
2333 offset_var = LLVMBuildLoad (builder, convert (ctx, ptr, LLVMPointerType (LLVMInt32Type (), 0)), name);
2335 return LLVMBuildAdd (builder, convert (ctx, locals_var, IntPtrType ()), convert (ctx, offset_var, IntPtrType ()), "");
2339 * Put the global into the 'llvm.used' array to prevent it from being optimized away.
2342 mark_as_used (MonoLLVMModule *module, LLVMValueRef global)
2345 module->used = g_ptr_array_sized_new (16);
2346 g_ptr_array_add (module->used, global);
2350 emit_llvm_used (MonoLLVMModule *module)
2352 LLVMModuleRef lmodule = module->lmodule;
2353 LLVMTypeRef used_type;
2354 LLVMValueRef used, *used_elem;
2360 used_type = LLVMArrayType (LLVMPointerType (LLVMInt8Type (), 0), module->used->len);
2361 used = LLVMAddGlobal (lmodule, used_type, "llvm.used");
2362 used_elem = g_new0 (LLVMValueRef, module->used->len);
2363 for (i = 0; i < module->used->len; ++i)
2364 used_elem [i] = LLVMConstBitCast ((LLVMValueRef)g_ptr_array_index (module->used, i), LLVMPointerType (LLVMInt8Type (), 0));
2365 LLVMSetInitializer (used, LLVMConstArray (LLVMPointerType (LLVMInt8Type (), 0), used_elem, module->used->len));
2366 LLVMSetLinkage (used, LLVMAppendingLinkage);
2367 LLVMSetSection (used, "llvm.metadata");
2373 * Emit a function mapping method indexes to their code
2376 emit_get_method (MonoLLVMModule *module)
2378 LLVMModuleRef lmodule = module->lmodule;
2379 LLVMValueRef func, switch_ins, m;
2380 LLVMBasicBlockRef entry_bb, fail_bb, bb, code_start_bb, code_end_bb;
2381 LLVMBasicBlockRef *bbs;
2383 LLVMBuilderRef builder;
2388 * Emit a switch statement. Emitting a table of function addresses is smaller/faster,
2389 * but generating code seems safer.
2391 rtype = LLVMPointerType (LLVMInt8Type (), 0);
2392 func = LLVMAddFunction (lmodule, module->get_method_symbol, LLVMFunctionType1 (rtype, LLVMInt32Type (), FALSE));
2393 LLVMSetLinkage (func, LLVMExternalLinkage);
2394 LLVMSetVisibility (func, LLVMHiddenVisibility);
2395 LLVMAddFunctionAttr (func, LLVMNoUnwindAttribute);
2396 module->get_method = func;
2398 entry_bb = LLVMAppendBasicBlock (func, "ENTRY");
2401 * Return llvm_code_start/llvm_code_end when called with -1/-2.
2402 * Hopefully, the toolchain doesn't reorder these functions. If it does,
2403 * then we will have to find another solution.
2406 name = g_strdup_printf ("BB_CODE_START");
2407 code_start_bb = LLVMAppendBasicBlock (func, name);
2409 builder = LLVMCreateBuilder ();
2410 LLVMPositionBuilderAtEnd (builder, code_start_bb);
2411 LLVMBuildRet (builder, LLVMBuildBitCast (builder, module->code_start, rtype, ""));
2413 name = g_strdup_printf ("BB_CODE_END");
2414 code_end_bb = LLVMAppendBasicBlock (func, name);
2416 builder = LLVMCreateBuilder ();
2417 LLVMPositionBuilderAtEnd (builder, code_end_bb);
2418 LLVMBuildRet (builder, LLVMBuildBitCast (builder, module->code_end, rtype, ""));
2420 bbs = g_new0 (LLVMBasicBlockRef, module->max_method_idx + 1);
2421 for (i = 0; i < module->max_method_idx + 1; ++i) {
2422 name = g_strdup_printf ("BB_%d", i);
2423 bb = LLVMAppendBasicBlock (func, name);
2427 builder = LLVMCreateBuilder ();
2428 LLVMPositionBuilderAtEnd (builder, bb);
2430 m = (LLVMValueRef)g_hash_table_lookup (module->idx_to_lmethod, GINT_TO_POINTER (i));
2432 LLVMBuildRet (builder, LLVMBuildBitCast (builder, m, rtype, ""));
2434 LLVMBuildRet (builder, LLVMConstNull (rtype));
2437 fail_bb = LLVMAppendBasicBlock (func, "FAIL");
2438 builder = LLVMCreateBuilder ();
2439 LLVMPositionBuilderAtEnd (builder, fail_bb);
2440 LLVMBuildRet (builder, LLVMConstNull (rtype));
2442 builder = LLVMCreateBuilder ();
2443 LLVMPositionBuilderAtEnd (builder, entry_bb);
2445 switch_ins = LLVMBuildSwitch (builder, LLVMGetParam (func, 0), fail_bb, 0);
2446 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), -1, FALSE), code_start_bb);
2447 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), -2, FALSE), code_end_bb);
2448 for (i = 0; i < module->max_method_idx + 1; ++i) {
2449 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), i, FALSE), bbs [i]);
2452 mark_as_used (module, func);
2456 * emit_get_unbox_tramp:
2458 * Emit a function mapping method indexes to their unbox trampoline
2461 emit_get_unbox_tramp (MonoLLVMModule *module)
2463 LLVMModuleRef lmodule = module->lmodule;
2464 LLVMValueRef func, switch_ins, m;
2465 LLVMBasicBlockRef entry_bb, fail_bb, bb;
2466 LLVMBasicBlockRef *bbs;
2468 LLVMBuilderRef builder;
2472 /* Similar to emit_get_method () */
2474 rtype = LLVMPointerType (LLVMInt8Type (), 0);
2475 func = LLVMAddFunction (lmodule, module->get_unbox_tramp_symbol, LLVMFunctionType1 (rtype, LLVMInt32Type (), FALSE));
2476 LLVMSetLinkage (func, LLVMExternalLinkage);
2477 LLVMSetVisibility (func, LLVMHiddenVisibility);
2478 LLVMAddFunctionAttr (func, LLVMNoUnwindAttribute);
2479 module->get_unbox_tramp = func;
2481 entry_bb = LLVMAppendBasicBlock (func, "ENTRY");
2483 bbs = g_new0 (LLVMBasicBlockRef, module->max_method_idx + 1);
2484 for (i = 0; i < module->max_method_idx + 1; ++i) {
2485 m = (LLVMValueRef)g_hash_table_lookup (module->idx_to_unbox_tramp, GINT_TO_POINTER (i));
2489 name = g_strdup_printf ("BB_%d", i);
2490 bb = LLVMAppendBasicBlock (func, name);
2494 builder = LLVMCreateBuilder ();
2495 LLVMPositionBuilderAtEnd (builder, bb);
2497 LLVMBuildRet (builder, LLVMBuildBitCast (builder, m, rtype, ""));
2500 fail_bb = LLVMAppendBasicBlock (func, "FAIL");
2501 builder = LLVMCreateBuilder ();
2502 LLVMPositionBuilderAtEnd (builder, fail_bb);
2503 LLVMBuildRet (builder, LLVMConstNull (rtype));
2505 builder = LLVMCreateBuilder ();
2506 LLVMPositionBuilderAtEnd (builder, entry_bb);
2508 switch_ins = LLVMBuildSwitch (builder, LLVMGetParam (func, 0), fail_bb, 0);
2509 for (i = 0; i < module->max_method_idx + 1; ++i) {
2510 m = (LLVMValueRef)g_hash_table_lookup (module->idx_to_unbox_tramp, GINT_TO_POINTER (i));
2514 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), i, FALSE), bbs [i]);
2517 mark_as_used (module, func);
2520 /* Add a function to mark the beginning of LLVM code */
2522 emit_llvm_code_start (MonoLLVMModule *module)
2524 LLVMModuleRef lmodule = module->lmodule;
2526 LLVMBasicBlockRef entry_bb;
2527 LLVMBuilderRef builder;
2529 func = LLVMAddFunction (lmodule, "llvm_code_start", LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE));
2530 LLVMSetLinkage (func, LLVMInternalLinkage);
2531 LLVMAddFunctionAttr (func, LLVMNoUnwindAttribute);
2532 module->code_start = func;
2533 entry_bb = LLVMAppendBasicBlock (func, "ENTRY");
2534 builder = LLVMCreateBuilder ();
2535 LLVMPositionBuilderAtEnd (builder, entry_bb);
2536 LLVMBuildRetVoid (builder);
2540 emit_init_icall_wrapper (MonoLLVMModule *module, const char *name, const char *icall_name, int subtype)
2542 LLVMModuleRef lmodule = module->lmodule;
2543 LLVMValueRef func, indexes [2], got_entry_addr, args [16], callee;
2544 LLVMBasicBlockRef entry_bb;
2545 LLVMBuilderRef builder;
2552 func = LLVMAddFunction (lmodule, name, LLVMFunctionType1 (LLVMVoidType (), LLVMInt32Type (), FALSE));
2553 sig = LLVMFunctionType2 (LLVMVoidType (), IntPtrType (), LLVMInt32Type (), FALSE);
2558 func = LLVMAddFunction (lmodule, name, LLVMFunctionType2 (LLVMVoidType (), LLVMInt32Type (), IntPtrType (), FALSE));
2559 sig = LLVMFunctionType3 (LLVMVoidType (), IntPtrType (), LLVMInt32Type (), IntPtrType (), FALSE);
2562 func = LLVMAddFunction (lmodule, name, LLVMFunctionType2 (LLVMVoidType (), LLVMInt32Type (), ObjRefType (), FALSE));
2563 sig = LLVMFunctionType3 (LLVMVoidType (), IntPtrType (), LLVMInt32Type (), ObjRefType (), FALSE);
2566 g_assert_not_reached ();
2568 LLVMSetLinkage (func, LLVMInternalLinkage);
2569 LLVMAddFunctionAttr (func, LLVMNoInlineAttribute);
2570 mono_llvm_set_preserveall_cc (func);
2571 entry_bb = LLVMAppendBasicBlock (func, "ENTRY");
2572 builder = LLVMCreateBuilder ();
2573 LLVMPositionBuilderAtEnd (builder, entry_bb);
2576 ji = g_new0 (MonoJumpInfo, 1);
2577 ji->type = MONO_PATCH_INFO_AOT_MODULE;
2578 ji = mono_aot_patch_info_dup (ji);
2579 got_offset = mono_aot_get_got_offset (ji);
2580 module->max_got_offset = MAX (module->max_got_offset, got_offset);
2581 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
2582 indexes [1] = LLVMConstInt (LLVMInt32Type (), got_offset, FALSE);
2583 got_entry_addr = LLVMBuildGEP (builder, module->got_var, indexes, 2, "");
2584 args [0] = LLVMBuildPtrToInt (builder, LLVMBuildLoad (builder, got_entry_addr, ""), IntPtrType (), "");
2585 args [1] = LLVMGetParam (func, 0);
2587 args [2] = LLVMGetParam (func, 1);
2589 ji = g_new0 (MonoJumpInfo, 1);
2590 ji->type = MONO_PATCH_INFO_INTERNAL_METHOD;
2591 ji->data.name = icall_name;
2592 ji = mono_aot_patch_info_dup (ji);
2593 got_offset = mono_aot_get_got_offset (ji);
2594 module->max_got_offset = MAX (module->max_got_offset, got_offset);
2595 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
2596 indexes [1] = LLVMConstInt (LLVMInt32Type (), got_offset, FALSE);
2597 got_entry_addr = LLVMBuildGEP (builder, module->got_var, indexes, 2, "");
2598 callee = LLVMBuildLoad (builder, got_entry_addr, "");
2599 callee = LLVMBuildBitCast (builder, callee, LLVMPointerType (sig, 0), "");
2600 LLVMBuildCall (builder, callee, args, LLVMCountParamTypes (sig), "");
2602 // Set the inited flag
2603 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
2604 indexes [1] = LLVMGetParam (func, 0);
2605 LLVMBuildStore (builder, LLVMConstInt (LLVMInt8Type (), 1, FALSE), LLVMBuildGEP (builder, module->inited_var, indexes, 2, ""));
2607 LLVMBuildRetVoid (builder);
2609 LLVMVerifyFunction(func, LLVMAbortProcessAction);
2614 * Emit wrappers around the C icalls used to initialize llvm methods, to
2615 * make the calling code smaller and to enable usage of the llvm
2616 * PreserveAll calling convention.
2619 emit_init_icall_wrappers (MonoLLVMModule *module)
2621 module->init_method = emit_init_icall_wrapper (module, "init_method", "mono_aot_init_llvm_method", 0);
2622 module->init_method_gshared_mrgctx = emit_init_icall_wrapper (module, "init_method_gshared_mrgctx", "mono_aot_init_gshared_method_mrgctx", 1);
2623 module->init_method_gshared_this = emit_init_icall_wrapper (module, "init_method_gshared_this", "mono_aot_init_gshared_method_this", 2);
2624 module->init_method_gshared_vtable = emit_init_icall_wrapper (module, "init_method_gshared_vtable", "mono_aot_init_gshared_method_vtable", 3);
2628 emit_llvm_code_end (MonoLLVMModule *module)
2630 LLVMModuleRef lmodule = module->lmodule;
2632 LLVMBasicBlockRef entry_bb;
2633 LLVMBuilderRef builder;
2635 func = LLVMAddFunction (lmodule, "llvm_code_end", LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE));
2636 LLVMSetLinkage (func, LLVMInternalLinkage);
2637 LLVMAddFunctionAttr (func, LLVMNoUnwindAttribute);
2638 module->code_end = func;
2639 entry_bb = LLVMAppendBasicBlock (func, "ENTRY");
2640 builder = LLVMCreateBuilder ();
2641 LLVMPositionBuilderAtEnd (builder, entry_bb);
2642 LLVMBuildRetVoid (builder);
2646 emit_div_check (EmitContext *ctx, LLVMBuilderRef builder, MonoBasicBlock *bb, MonoInst *ins, LLVMValueRef lhs, LLVMValueRef rhs)
2648 gboolean need_div_check = ctx->cfg->backend->need_div_check;
2651 /* LLVM doesn't know that these can throw an exception since they are not called through an intrinsic */
2652 need_div_check = TRUE;
2654 if (!need_div_check)
2657 switch (ins->opcode) {
2670 case OP_IDIV_UN_IMM:
2671 case OP_LDIV_UN_IMM:
2672 case OP_IREM_UN_IMM:
2673 case OP_LREM_UN_IMM: {
2675 gboolean is_signed = (ins->opcode == OP_IDIV || ins->opcode == OP_LDIV || ins->opcode == OP_IREM || ins->opcode == OP_LREM ||
2676 ins->opcode == OP_IDIV_IMM || ins->opcode == OP_LDIV_IMM || ins->opcode == OP_IREM_IMM || ins->opcode == OP_LREM_IMM);
2678 cmp = LLVMBuildICmp (builder, LLVMIntEQ, rhs, LLVMConstInt (LLVMTypeOf (rhs), 0, FALSE), "");
2679 emit_cond_system_exception (ctx, bb, "DivideByZeroException", cmp);
2682 builder = ctx->builder;
2684 /* b == -1 && a == 0x80000000 */
2686 LLVMValueRef c = (LLVMTypeOf (lhs) == LLVMInt32Type ()) ? LLVMConstInt (LLVMTypeOf (lhs), 0x80000000, FALSE) : LLVMConstInt (LLVMTypeOf (lhs), 0x8000000000000000LL, FALSE);
2687 LLVMValueRef cond1 = LLVMBuildICmp (builder, LLVMIntEQ, rhs, LLVMConstInt (LLVMTypeOf (rhs), -1, FALSE), "");
2688 LLVMValueRef cond2 = LLVMBuildICmp (builder, LLVMIntEQ, lhs, c, "");
2690 cmp = LLVMBuildICmp (builder, LLVMIntEQ, LLVMBuildAnd (builder, cond1, cond2, ""), LLVMConstInt (LLVMInt1Type (), 1, FALSE), "");
2691 emit_cond_system_exception (ctx, bb, "OverflowException", cmp);
2694 builder = ctx->builder;
2706 * Emit code to initialize the GOT slots used by the method.
2709 emit_init_method (EmitContext *ctx)
2711 LLVMValueRef indexes [16], args [16], callee;
2712 LLVMValueRef inited_var, cmp, call;
2713 LLVMBasicBlockRef inited_bb, notinited_bb;
2714 LLVMBuilderRef builder = ctx->builder;
2715 MonoCompile *cfg = ctx->cfg;
2717 ctx->module->max_inited_idx = MAX (ctx->module->max_inited_idx, cfg->method_index);
2719 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
2720 indexes [1] = LLVMConstInt (LLVMInt32Type (), cfg->method_index, FALSE);
2721 inited_var = LLVMBuildLoad (builder, LLVMBuildGEP (builder, ctx->module->inited_var, indexes, 2, ""), "is_inited");
2723 args [0] = inited_var;
2724 args [1] = LLVMConstInt (LLVMInt8Type (), 1, FALSE);
2725 inited_var = LLVMBuildCall (ctx->builder, LLVMGetNamedFunction (ctx->lmodule, "llvm.expect.i8"), args, 2, "");
2727 cmp = LLVMBuildICmp (builder, LLVMIntEQ, inited_var, LLVMConstInt (LLVMTypeOf (inited_var), 0, FALSE), "");
2729 inited_bb = ctx->inited_bb;
2730 notinited_bb = gen_bb (ctx, "NOTINITED_BB");
2732 LLVMBuildCondBr (ctx->builder, cmp, notinited_bb, inited_bb);
2734 builder = ctx->builder = create_builder (ctx);
2735 LLVMPositionBuilderAtEnd (ctx->builder, notinited_bb);
2738 if (ctx->rgctx_arg && cfg->method->is_inflated && mono_method_get_context (cfg->method)->method_inst) {
2739 args [0] = LLVMConstInt (LLVMInt32Type (), cfg->method_index, 0);
2740 args [1] = convert (ctx, ctx->rgctx_arg, IntPtrType ());
2741 callee = ctx->module->init_method_gshared_mrgctx;
2742 call = LLVMBuildCall (builder, callee, args, 2, "");
2743 } else if (ctx->rgctx_arg) {
2744 /* A vtable is passed as the rgctx argument */
2745 args [0] = LLVMConstInt (LLVMInt32Type (), cfg->method_index, 0);
2746 args [1] = convert (ctx, ctx->rgctx_arg, IntPtrType ());
2747 callee = ctx->module->init_method_gshared_vtable;
2748 call = LLVMBuildCall (builder, callee, args, 2, "");
2749 } else if (cfg->gshared) {
2750 args [0] = LLVMConstInt (LLVMInt32Type (), cfg->method_index, 0);
2751 args [1] = convert (ctx, ctx->this_arg, ObjRefType ());
2752 callee = ctx->module->init_method_gshared_this;
2753 call = LLVMBuildCall (builder, callee, args, 2, "");
2755 args [0] = LLVMConstInt (LLVMInt32Type (), cfg->method_index, 0);
2756 callee = ctx->module->init_method;
2757 call = LLVMBuildCall (builder, callee, args, 1, "");
2761 * This enables llvm to keep arguments in their original registers/
2762 * scratch registers, since the call will not clobber them.
2764 mono_llvm_set_call_preserveall_cc (call);
2766 LLVMBuildBr (builder, inited_bb);
2767 ctx->bblocks [cfg->bb_entry->block_num].end_bblock = inited_bb;
2769 builder = ctx->builder = create_builder (ctx);
2770 LLVMPositionBuilderAtEnd (ctx->builder, inited_bb);
2774 emit_unbox_tramp (EmitContext *ctx, const char *method_name, LLVMTypeRef method_type, LLVMValueRef method, int method_index)
2777 * Emit unbox trampoline using a tail call
2779 LLVMValueRef tramp, call, *args;
2780 LLVMBuilderRef builder;
2781 LLVMBasicBlockRef lbb;
2782 LLVMCallInfo *linfo;
2786 tramp_name = g_strdup_printf ("ut_%s", method_name);
2787 tramp = LLVMAddFunction (ctx->module->lmodule, tramp_name, method_type);
2788 LLVMSetLinkage (tramp, LLVMInternalLinkage);
2789 LLVMAddFunctionAttr (tramp, LLVMOptimizeForSizeAttribute);
2790 //LLVMAddFunctionAttr (tramp, LLVMNoUnwindAttribute);
2792 // FIXME: Reduce code duplication with mono_llvm_compile_method () etc.
2793 if (!ctx->llvm_only && ctx->rgctx_arg_pindex != -1)
2794 LLVMAddAttribute (LLVMGetParam (tramp, ctx->rgctx_arg_pindex), LLVMInRegAttribute);
2795 if (ctx->cfg->vret_addr) {
2796 LLVMSetValueName (LLVMGetParam (tramp, linfo->vret_arg_pindex), "vret");
2797 if (linfo->ret.storage == LLVMArgVtypeByRef) {
2798 LLVMAddAttribute (LLVMGetParam (tramp, linfo->vret_arg_pindex), LLVMStructRetAttribute);
2799 LLVMAddAttribute (LLVMGetParam (tramp, linfo->vret_arg_pindex), LLVMNoAliasAttribute);
2803 lbb = LLVMAppendBasicBlock (tramp, "");
2804 builder = LLVMCreateBuilder ();
2805 LLVMPositionBuilderAtEnd (builder, lbb);
2807 nargs = LLVMCountParamTypes (method_type);
2808 args = g_new0 (LLVMValueRef, nargs);
2809 for (i = 0; i < nargs; ++i) {
2810 args [i] = LLVMGetParam (tramp, i);
2811 if (i == ctx->this_arg_pindex) {
2812 LLVMTypeRef arg_type = LLVMTypeOf (args [i]);
2814 args [i] = LLVMBuildPtrToInt (builder, args [i], IntPtrType (), "");
2815 args [i] = LLVMBuildAdd (builder, args [i], LLVMConstInt (IntPtrType (), sizeof (MonoObject), FALSE), "");
2816 args [i] = LLVMBuildIntToPtr (builder, args [i], arg_type, "");
2819 call = LLVMBuildCall (builder, method, args, nargs, "");
2820 if (!ctx->llvm_only && ctx->rgctx_arg_pindex != -1)
2821 LLVMAddInstrAttribute (call, 1 + ctx->rgctx_arg_pindex, LLVMInRegAttribute);
2822 if (linfo->ret.storage == LLVMArgVtypeByRef)
2823 LLVMAddInstrAttribute (call, 1 + linfo->vret_arg_pindex, LLVMStructRetAttribute);
2825 // FIXME: This causes assertions in clang
2826 //mono_llvm_set_must_tail (call);
2827 if (LLVMGetReturnType (method_type) == LLVMVoidType ())
2828 LLVMBuildRetVoid (builder);
2830 LLVMBuildRet (builder, call);
2832 g_hash_table_insert (ctx->module->idx_to_unbox_tramp, GINT_TO_POINTER (method_index), tramp);
2838 * Emit code to load/convert arguments.
2841 emit_entry_bb (EmitContext *ctx, LLVMBuilderRef builder)
2844 MonoCompile *cfg = ctx->cfg;
2845 MonoMethodSignature *sig = ctx->sig;
2846 LLVMCallInfo *linfo = ctx->linfo;
2850 LLVMBuilderRef old_builder = ctx->builder;
2851 ctx->builder = builder;
2853 ctx->alloca_builder = create_builder (ctx);
2856 * Handle indirect/volatile variables by allocating memory for them
2857 * using 'alloca', and storing their address in a temporary.
2859 for (i = 0; i < cfg->num_varinfo; ++i) {
2860 MonoInst *var = cfg->varinfo [i];
2863 if (var->opcode == OP_GSHAREDVT_LOCAL || var->opcode == OP_GSHAREDVT_ARG_REGOFFSET) {
2864 } 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))) {
2865 vtype = type_to_llvm_type (ctx, var->inst_vtype);
2868 /* Could be already created by an OP_VPHI */
2869 if (!ctx->addresses [var->dreg]) {
2870 ctx->addresses [var->dreg] = build_alloca (ctx, var->inst_vtype);
2871 //LLVMSetValueName (ctx->addresses [var->dreg], g_strdup_printf ("vreg_loc_%d", var->dreg));
2873 ctx->vreg_cli_types [var->dreg] = var->inst_vtype;
2877 names = g_new (char *, sig->param_count);
2878 mono_method_get_param_names (cfg->method, (const char **) names);
2880 for (i = 0; i < sig->param_count; ++i) {
2881 LLVMArgInfo *ainfo = &linfo->args [i + sig->hasthis];
2882 int reg = cfg->args [i + sig->hasthis]->dreg;
2885 pindex = ainfo->pindex;
2887 switch (ainfo->storage) {
2888 case LLVMArgVtypeInReg:
2889 case LLVMArgAsFpArgs: {
2890 LLVMValueRef args [8];
2893 pindex += ainfo->ndummy_fpargs;
2895 /* The argument is received as a set of int/fp arguments, store them into the real argument */
2896 memset (args, 0, sizeof (args));
2897 if (ainfo->storage == LLVMArgVtypeInReg) {
2898 args [0] = LLVMGetParam (ctx->lmethod, pindex);
2899 if (ainfo->pair_storage [1] != LLVMArgNone)
2900 args [1] = LLVMGetParam (ctx->lmethod, pindex + 1);
2902 g_assert (ainfo->nslots <= 8);
2903 for (j = 0; j < ainfo->nslots; ++j)
2904 args [j] = LLVMGetParam (ctx->lmethod, pindex + j);
2906 ctx->addresses [reg] = build_alloca (ctx, ainfo->type);
2908 emit_args_to_vtype (ctx, builder, ainfo->type, ctx->addresses [reg], ainfo, args);
2910 if (ainfo->storage == LLVMArgVtypeInReg && MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (ainfo->type))) {
2911 /* Treat these as normal values */
2912 ctx->values [reg] = LLVMBuildLoad (builder, ctx->addresses [reg], "");
2916 case LLVMArgVtypeByVal: {
2917 ctx->addresses [reg] = LLVMGetParam (ctx->lmethod, pindex);
2919 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (ainfo->type))) {
2920 /* Treat these as normal values */
2921 ctx->values [reg] = LLVMBuildLoad (builder, ctx->addresses [reg], "");
2925 case LLVMArgVtypeByRef: {
2926 /* The argument is passed by ref */
2927 ctx->addresses [reg] = LLVMGetParam (ctx->lmethod, pindex);
2930 case LLVMArgAsIArgs: {
2931 LLVMValueRef arg = LLVMGetParam (ctx->lmethod, pindex);
2934 /* The argument is received as an array of ints, store it into the real argument */
2935 ctx->addresses [reg] = build_alloca (ctx, ainfo->type);
2937 size = mono_class_value_size (mono_class_from_mono_type (ainfo->type), NULL);
2938 if (size < SIZEOF_VOID_P) {
2939 /* The upper bits of the registers might not be valid */
2940 LLVMValueRef val = LLVMBuildExtractValue (builder, arg, 0, "");
2941 LLVMValueRef dest = convert (ctx, ctx->addresses [reg], LLVMPointerType (LLVMIntType (size * 8), 0));
2942 LLVMBuildStore (ctx->builder, LLVMBuildTrunc (builder, val, LLVMIntType (size * 8), ""), dest);
2944 LLVMBuildStore (ctx->builder, arg, convert (ctx, ctx->addresses [reg], LLVMPointerType (LLVMTypeOf (arg), 0)));
2948 case LLVMArgVtypeAsScalar:
2949 g_assert_not_reached ();
2951 case LLVMArgGsharedvtFixed: {
2952 /* These are non-gsharedvt arguments passed by ref, the rest of the IR treats them as scalars */
2953 LLVMValueRef arg = LLVMGetParam (ctx->lmethod, pindex);
2956 name = g_strdup_printf ("arg_%s", names [i]);
2958 name = g_strdup_printf ("arg_%d", i);
2960 ctx->values [reg] = LLVMBuildLoad (builder, convert (ctx, arg, LLVMPointerType (type_to_llvm_type (ctx, ainfo->type), 0)), name);
2963 case LLVMArgGsharedvtFixedVtype: {
2964 LLVMValueRef arg = LLVMGetParam (ctx->lmethod, pindex);
2967 name = g_strdup_printf ("vtype_arg_%s", names [i]);
2969 name = g_strdup_printf ("vtype_arg_%d", i);
2971 /* Non-gsharedvt vtype argument passed by ref, the rest of the IR treats it as a vtype */
2972 g_assert (ctx->addresses [reg]);
2973 LLVMSetValueName (ctx->addresses [reg], name);
2974 LLVMBuildStore (builder, LLVMBuildLoad (builder, convert (ctx, arg, LLVMPointerType (type_to_llvm_type (ctx, ainfo->type), 0)), ""), ctx->addresses [reg]);
2977 case LLVMArgGsharedvtVariable:
2978 /* The IR treats these as variables with addresses */
2979 ctx->addresses [reg] = LLVMGetParam (ctx->lmethod, pindex);
2982 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));
2989 emit_volatile_store (ctx, cfg->vret_addr->dreg);
2991 emit_volatile_store (ctx, cfg->args [0]->dreg);
2992 for (i = 0; i < sig->param_count; ++i)
2993 if (!mini_type_is_vtype (sig->params [i]))
2994 emit_volatile_store (ctx, cfg->args [i + sig->hasthis]->dreg);
2996 if (sig->hasthis && !cfg->rgctx_var && cfg->gshared) {
2997 LLVMValueRef this_alloc;
3000 * The exception handling code needs the location where the this argument was
3001 * stored for gshared methods. We create a separate alloca to hold it, and mark it
3002 * with the "mono.this" custom metadata to tell llvm that it needs to save its
3003 * location into the LSDA.
3005 this_alloc = mono_llvm_build_alloca (builder, ThisType (), LLVMConstInt (LLVMInt32Type (), 1, FALSE), 0, "");
3006 /* This volatile store will keep the alloca alive */
3007 mono_llvm_build_store (builder, ctx->values [cfg->args [0]->dreg], this_alloc, TRUE, LLVM_BARRIER_NONE);
3009 set_metadata_flag (this_alloc, "mono.this");
3012 if (cfg->rgctx_var) {
3013 LLVMValueRef rgctx_alloc, store;
3016 * We handle the rgctx arg similarly to the this pointer.
3018 g_assert (ctx->addresses [cfg->rgctx_var->dreg]);
3019 rgctx_alloc = ctx->addresses [cfg->rgctx_var->dreg];
3020 /* This volatile store will keep the alloca alive */
3021 store = mono_llvm_build_store (builder, convert (ctx, ctx->rgctx_arg, IntPtrType ()), rgctx_alloc, TRUE, LLVM_BARRIER_NONE);
3023 set_metadata_flag (rgctx_alloc, "mono.this");
3026 /* Initialize the method if needed */
3027 if (cfg->compile_aot && ctx->llvm_only) {
3028 /* Emit a location for the initialization code */
3029 ctx->init_bb = gen_bb (ctx, "INIT_BB");
3030 ctx->inited_bb = gen_bb (ctx, "INITED_BB");
3032 LLVMBuildBr (ctx->builder, ctx->init_bb);
3033 builder = ctx->builder = create_builder (ctx);
3034 LLVMPositionBuilderAtEnd (ctx->builder, ctx->inited_bb);
3035 ctx->bblocks [cfg->bb_entry->block_num].end_bblock = ctx->inited_bb;
3038 /* Compute nesting between clauses */
3039 ctx->nested_in = (GSList**)mono_mempool_alloc0 (cfg->mempool, sizeof (GSList*) * cfg->header->num_clauses);
3040 for (i = 0; i < cfg->header->num_clauses; ++i) {
3041 for (j = 0; j < cfg->header->num_clauses; ++j) {
3042 MonoExceptionClause *clause1 = &cfg->header->clauses [i];
3043 MonoExceptionClause *clause2 = &cfg->header->clauses [j];
3045 if (i != j && clause1->try_offset >= clause2->try_offset && clause1->handler_offset <= clause2->handler_offset)
3046 ctx->nested_in [i] = g_slist_prepend_mempool (cfg->mempool, ctx->nested_in [i], GINT_TO_POINTER (j));
3051 * For finally clauses, create an indicator variable telling OP_ENDFINALLY whenever
3052 * it needs to continue normally, or return back to the exception handling system.
3054 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
3058 if (!(bb->region != -1 && (bb->flags & BB_EXCEPTION_HANDLER)))
3061 clause_index = MONO_REGION_CLAUSE_INDEX (bb->region);
3062 g_hash_table_insert (ctx->region_to_handler, GUINT_TO_POINTER (mono_get_block_region_notry (cfg, bb->region)), bb);
3063 g_hash_table_insert (ctx->clause_to_handler, GINT_TO_POINTER (clause_index), bb);
3065 if (bb->in_scount == 0) {
3068 sprintf (name, "finally_ind_bb%d", bb->block_num);
3069 val = LLVMBuildAlloca (builder, LLVMInt32Type (), name);
3070 LLVMBuildStore (builder, LLVMConstInt (LLVMInt32Type (), 0, FALSE), val);
3072 ctx->bblocks [bb->block_num].finally_ind = val;
3074 /* Create a variable to hold the exception var */
3076 ctx->ex_var = LLVMBuildAlloca (builder, ObjRefType (), "exvar");
3080 * Create a new bblock which CALL_HANDLER/landing pads can branch to, because branching to the
3081 * LLVM bblock containing a landing pad causes problems for the
3082 * LLVM optimizer passes.
3084 sprintf (name, "BB%d_CALL_HANDLER_TARGET", bb->block_num);
3085 ctx->bblocks [bb->block_num].call_handler_target_bb = LLVMAppendBasicBlock (ctx->lmethod, name);
3087 ctx->builder = old_builder;
3091 process_call (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, MonoInst *ins)
3093 MonoCompile *cfg = ctx->cfg;
3094 LLVMModuleRef lmodule = ctx->lmodule;
3095 LLVMValueRef *values = ctx->values;
3096 LLVMValueRef *addresses = ctx->addresses;
3097 MonoCallInst *call = (MonoCallInst*)ins;
3098 MonoMethodSignature *sig = call->signature;
3099 LLVMValueRef callee = NULL, lcall;
3101 LLVMCallInfo *cinfo;
3105 LLVMTypeRef llvm_sig;
3107 gboolean is_virtual, calli, preserveall;
3108 LLVMBuilderRef builder = *builder_ref;
3110 if (call->signature->call_convention != MONO_CALL_DEFAULT) {
3111 set_failure (ctx, "non-default callconv");
3115 cinfo = call->cinfo;
3117 if (call->rgctx_arg_reg)
3118 cinfo->rgctx_arg = TRUE;
3119 if (call->imt_arg_reg)
3120 cinfo->imt_arg = TRUE;
3122 vretaddr = (cinfo->ret.storage == LLVMArgVtypeRetAddr || cinfo->ret.storage == LLVMArgVtypeByRef || cinfo->ret.storage == LLVMArgGsharedvtFixed || cinfo->ret.storage == LLVMArgGsharedvtVariable || cinfo->ret.storage == LLVMArgGsharedvtFixedVtype);
3124 llvm_sig = sig_to_llvm_sig_full (ctx, sig, cinfo);
3128 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);
3129 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);
3131 preserveall = FALSE;
3133 /* FIXME: Avoid creating duplicate methods */
3135 if (ins->flags & MONO_INST_HAS_METHOD) {
3139 if (cfg->compile_aot) {
3140 callee = get_callee (ctx, llvm_sig, MONO_PATCH_INFO_METHOD, call->method);
3142 set_failure (ctx, "can't encode patch");
3145 if (cfg->llvm_only && call->method->klass->image->assembly == ctx->module->assembly) {
3147 * Collect instructions representing the callee into a hash so they can be replaced
3148 * by the llvm method for the callee if the callee turns out to be direct
3149 * callable. Currently this only requires it to not fail llvm compilation.
3151 GSList *l = (GSList*)g_hash_table_lookup (ctx->method_to_callers, call->method);
3152 l = g_slist_prepend (l, callee);
3153 g_hash_table_insert (ctx->method_to_callers, call->method, l);
3158 callee = LLVMAddFunction (lmodule, "", llvm_sig);
3161 mono_create_jit_trampoline (mono_domain_get (),
3162 call->method, &error);
3163 if (!mono_error_ok (&error))
3164 mono_error_raise_exception (&error); /* FIXME: Don't raise here */
3165 LLVMAddGlobalMapping (ctx->module->ee, callee, target);
3169 if (!cfg->llvm_only && call->method && strstr (call->method->klass->name, "AsyncVoidMethodBuilder")) {
3170 /* LLVM miscompiles async methods */
3171 set_failure (ctx, "#13734");
3176 MonoJitICallInfo *info = mono_find_jit_icall_by_addr (call->fptr);
3182 memset (&ji, 0, sizeof (ji));
3183 ji.type = MONO_PATCH_INFO_JIT_ICALL_ADDR;
3184 ji.data.target = info->name;
3186 target = mono_resolve_patch_target (cfg->method, cfg->domain, NULL, &ji, FALSE);
3188 if (cfg->compile_aot) {
3189 callee = get_callee (ctx, llvm_sig, MONO_PATCH_INFO_INTERNAL_METHOD, (char*)info->name);
3191 set_failure (ctx, "can't encode patch");
3195 callee = LLVMAddFunction (lmodule, "", llvm_sig);
3196 target = (gpointer)mono_icall_get_wrapper (info);
3197 LLVMAddGlobalMapping (ctx->module->ee, callee, target);
3200 if (cfg->compile_aot) {
3202 if (cfg->abs_patches) {
3203 MonoJumpInfo *abs_ji = (MonoJumpInfo*)g_hash_table_lookup (cfg->abs_patches, call->fptr);
3205 callee = get_callee (ctx, llvm_sig, abs_ji->type, abs_ji->data.target);
3207 set_failure (ctx, "can't encode patch");
3213 set_failure (ctx, "aot");
3217 callee = LLVMAddFunction (lmodule, "", llvm_sig);
3219 if (cfg->abs_patches) {
3220 MonoJumpInfo *abs_ji = (MonoJumpInfo*)g_hash_table_lookup (cfg->abs_patches, call->fptr);
3225 * FIXME: Some trampolines might have
3226 * their own calling convention on some platforms.
3228 target = mono_resolve_patch_target (cfg->method, cfg->domain, NULL, abs_ji, FALSE, &error);
3229 mono_error_assert_ok (&error);
3230 LLVMAddGlobalMapping (ctx->module->ee, callee, target);
3234 LLVMAddGlobalMapping (ctx->module->ee, callee, (gpointer)call->fptr);
3240 int size = sizeof (gpointer);
3243 g_assert (ins->inst_offset % size == 0);
3244 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
3246 callee = convert (ctx, LLVMBuildLoad (builder, LLVMBuildGEP (builder, convert (ctx, values [ins->inst_basereg], LLVMPointerType (LLVMPointerType (IntPtrType (), 0), 0)), &index, 1, ""), ""), LLVMPointerType (llvm_sig, 0));
3248 callee = convert (ctx, values [ins->sreg1], LLVMPointerType (llvm_sig, 0));
3250 if (ins->flags & MONO_INST_HAS_METHOD) {
3255 * Collect and convert arguments
3257 nargs = (sig->param_count * 16) + sig->hasthis + vretaddr + call->rgctx_reg + call->imt_arg_reg;
3258 len = sizeof (LLVMValueRef) * nargs;
3259 args = (LLVMValueRef*)alloca (len);
3260 memset (args, 0, len);
3261 l = call->out_ireg_args;
3263 if (call->rgctx_arg_reg) {
3264 g_assert (values [call->rgctx_arg_reg]);
3265 g_assert (cinfo->rgctx_arg_pindex < nargs);
3267 * On ARM, the imt/rgctx argument is passed in a caller save register, but some of our trampolines etc. clobber it, leading to
3268 * problems is LLVM moves the arg assignment earlier. To work around this, save the argument into a stack slot and load
3269 * it using a volatile load.
3272 if (!ctx->imt_rgctx_loc)
3273 ctx->imt_rgctx_loc = build_alloca_llvm_type (ctx, ctx->module->ptr_type, sizeof (gpointer));
3274 LLVMBuildStore (builder, convert (ctx, ctx->values [call->rgctx_arg_reg], ctx->module->ptr_type), ctx->imt_rgctx_loc);
3275 args [cinfo->rgctx_arg_pindex] = mono_llvm_build_load (builder, ctx->imt_rgctx_loc, "", TRUE, LLVM_BARRIER_NONE);
3277 args [cinfo->rgctx_arg_pindex] = convert (ctx, values [call->rgctx_arg_reg], ctx->module->ptr_type);
3280 if (call->imt_arg_reg) {
3281 g_assert (!ctx->llvm_only);
3282 g_assert (values [call->imt_arg_reg]);
3283 g_assert (cinfo->imt_arg_pindex < nargs);
3285 if (!ctx->imt_rgctx_loc)
3286 ctx->imt_rgctx_loc = build_alloca_llvm_type (ctx, ctx->module->ptr_type, sizeof (gpointer));
3287 LLVMBuildStore (builder, convert (ctx, ctx->values [call->imt_arg_reg], ctx->module->ptr_type), ctx->imt_rgctx_loc);
3288 args [cinfo->imt_arg_pindex] = mono_llvm_build_load (builder, ctx->imt_rgctx_loc, "", TRUE, LLVM_BARRIER_NONE);
3290 args [cinfo->imt_arg_pindex] = convert (ctx, values [call->imt_arg_reg], ctx->module->ptr_type);
3293 switch (cinfo->ret.storage) {
3294 case LLVMArgGsharedvtVariable: {
3295 MonoInst *var = get_vreg_to_inst (cfg, call->inst.dreg);
3297 if (var && var->opcode == OP_GSHAREDVT_LOCAL) {
3298 args [cinfo->vret_arg_pindex] = convert (ctx, emit_gsharedvt_ldaddr (ctx, var->dreg), IntPtrType ());
3300 g_assert (addresses [call->inst.dreg]);
3301 args [cinfo->vret_arg_pindex] = addresses [call->inst.dreg];
3307 if (!addresses [call->inst.dreg])
3308 addresses [call->inst.dreg] = build_alloca (ctx, sig->ret);
3309 g_assert (cinfo->vret_arg_pindex < nargs);
3310 if (cinfo->ret.storage == LLVMArgVtypeByRef)
3311 args [cinfo->vret_arg_pindex] = addresses [call->inst.dreg];
3313 args [cinfo->vret_arg_pindex] = LLVMBuildPtrToInt (builder, addresses [call->inst.dreg], IntPtrType (), "");
3319 * Sometimes the same method is called with two different signatures (i.e. with and without 'this'), so
3320 * use the real callee for argument type conversion.
3322 LLVMTypeRef callee_type = LLVMGetElementType (LLVMTypeOf (callee));
3323 LLVMTypeRef *param_types = (LLVMTypeRef*)g_alloca (sizeof (LLVMTypeRef) * LLVMCountParamTypes (callee_type));
3324 LLVMGetParamTypes (callee_type, param_types);
3326 for (i = 0; i < sig->param_count + sig->hasthis; ++i) {
3329 LLVMArgInfo *ainfo = &call->cinfo->args [i];
3331 pindex = ainfo->pindex;
3333 regpair = (guint32)(gssize)(l->data);
3334 reg = regpair & 0xffffff;
3335 args [pindex] = values [reg];
3336 switch (ainfo->storage) {
3337 case LLVMArgVtypeInReg:
3338 case LLVMArgAsFpArgs: {
3342 for (j = 0; j < ainfo->ndummy_fpargs; ++j)
3343 args [pindex + j] = LLVMConstNull (LLVMDoubleType ());
3344 pindex += ainfo->ndummy_fpargs;
3346 g_assert (addresses [reg]);
3347 emit_vtype_to_args (ctx, builder, ainfo->type, addresses [reg], ainfo, args + pindex, &nargs);
3351 // FIXME: Get rid of the VMOVE
3354 case LLVMArgVtypeByVal:
3355 g_assert (addresses [reg]);
3356 args [pindex] = addresses [reg];
3358 case LLVMArgVtypeByRef: {
3359 g_assert (addresses [reg]);
3360 args [pindex] = convert (ctx, addresses [reg], LLVMPointerType (type_to_llvm_arg_type (ctx, ainfo->type), 0));
3363 case LLVMArgAsIArgs:
3364 g_assert (addresses [reg]);
3365 args [pindex] = LLVMBuildLoad (ctx->builder, convert (ctx, addresses [reg], LLVMPointerType (LLVMArrayType (IntPtrType (), ainfo->nslots), 0)), "");
3367 case LLVMArgVtypeAsScalar:
3368 g_assert_not_reached ();
3370 case LLVMArgGsharedvtFixed:
3371 case LLVMArgGsharedvtFixedVtype:
3372 g_assert (addresses [reg]);
3373 args [pindex] = convert (ctx, addresses [reg], LLVMPointerType (type_to_llvm_arg_type (ctx, ainfo->type), 0));
3375 case LLVMArgGsharedvtVariable:
3376 g_assert (addresses [reg]);
3377 args [pindex] = convert (ctx, addresses [reg], LLVMPointerType (IntPtrType (), 0));
3380 g_assert (args [pindex]);
3381 if (i == 0 && sig->hasthis)
3382 args [pindex] = convert (ctx, args [pindex], param_types [pindex]);
3384 args [pindex] = convert (ctx, args [pindex], type_to_llvm_arg_type (ctx, ainfo->type));
3387 g_assert (pindex <= nargs);
3392 // FIXME: Align call sites
3398 lcall = emit_call (ctx, bb, &builder, callee, args, LLVMCountParamTypes (llvm_sig));
3401 * Modify cconv and parameter attributes to pass rgctx/imt correctly.
3403 #if defined(MONO_ARCH_IMT_REG) && defined(MONO_ARCH_RGCTX_REG)
3404 g_assert (MONO_ARCH_IMT_REG == MONO_ARCH_RGCTX_REG);
3406 /* The two can't be used together, so use only one LLVM calling conv to pass them */
3407 g_assert (!(call->rgctx_arg_reg && call->imt_arg_reg));
3408 if (!sig->pinvoke && !cfg->llvm_only)
3409 LLVMSetInstructionCallConv (lcall, LLVMMono1CallConv);
3411 mono_llvm_set_call_preserveall_cc (lcall);
3413 if (cinfo->ret.storage == LLVMArgVtypeByRef)
3414 LLVMAddInstrAttribute (lcall, 1 + cinfo->vret_arg_pindex, LLVMStructRetAttribute);
3415 if (!ctx->llvm_only && call->rgctx_arg_reg)
3416 LLVMAddInstrAttribute (lcall, 1 + cinfo->rgctx_arg_pindex, LLVMInRegAttribute);
3417 if (call->imt_arg_reg)
3418 LLVMAddInstrAttribute (lcall, 1 + cinfo->imt_arg_pindex, LLVMInRegAttribute);
3420 /* Add byval attributes if needed */
3421 for (i = 0; i < sig->param_count; ++i) {
3422 LLVMArgInfo *ainfo = &call->cinfo->args [i + sig->hasthis];
3424 if (ainfo && ainfo->storage == LLVMArgVtypeByVal)
3425 LLVMAddInstrAttribute (lcall, 1 + ainfo->pindex, LLVMByValAttribute);
3429 * Convert the result
3431 switch (cinfo->ret.storage) {
3432 case LLVMArgVtypeInReg: {
3433 LLVMValueRef regs [2];
3435 if (LLVMTypeOf (lcall) == LLVMVoidType ())
3439 if (!addresses [ins->dreg])
3440 addresses [ins->dreg] = build_alloca (ctx, sig->ret);
3442 regs [0] = LLVMBuildExtractValue (builder, lcall, 0, "");
3443 if (cinfo->ret.pair_storage [1] != LLVMArgNone)
3444 regs [1] = LLVMBuildExtractValue (builder, lcall, 1, "");
3445 emit_args_to_vtype (ctx, builder, sig->ret, addresses [ins->dreg], &cinfo->ret, regs);
3448 case LLVMArgVtypeByVal:
3449 if (!addresses [call->inst.dreg])
3450 addresses [call->inst.dreg] = build_alloca (ctx, sig->ret);
3451 LLVMBuildStore (builder, lcall, addresses [call->inst.dreg]);
3453 case LLVMArgFpStruct:
3454 if (!addresses [call->inst.dreg])
3455 addresses [call->inst.dreg] = build_alloca (ctx, sig->ret);
3456 LLVMBuildStore (builder, lcall, convert_full (ctx, addresses [call->inst.dreg], LLVMPointerType (LLVMTypeOf (lcall), 0), FALSE));
3458 case LLVMArgVtypeAsScalar:
3459 if (!addresses [call->inst.dreg])
3460 addresses [call->inst.dreg] = build_alloca (ctx, sig->ret);
3461 LLVMBuildStore (builder, lcall, convert_full (ctx, addresses [call->inst.dreg], LLVMPointerType (LLVMTypeOf (lcall), 0), FALSE));
3463 case LLVMArgVtypeRetAddr:
3464 case LLVMArgVtypeByRef:
3465 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (sig->ret))) {
3466 /* Some opcodes like STOREX_MEMBASE access these by value */
3467 g_assert (addresses [call->inst.dreg]);
3468 values [ins->dreg] = LLVMBuildLoad (builder, convert_full (ctx, addresses [call->inst.dreg], LLVMPointerType (type_to_llvm_type (ctx, sig->ret), 0), FALSE), "");
3471 case LLVMArgGsharedvtVariable:
3473 case LLVMArgGsharedvtFixed:
3474 case LLVMArgGsharedvtFixedVtype:
3475 values [ins->dreg] = LLVMBuildLoad (builder, convert_full (ctx, addresses [call->inst.dreg], LLVMPointerType (type_to_llvm_type (ctx, sig->ret), 0), FALSE), "");
3478 if (sig->ret->type != MONO_TYPE_VOID)
3479 /* If the method returns an unsigned value, need to zext it */
3480 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));
3484 *builder_ref = ctx->builder;
3488 emit_llvmonly_throw (EmitContext *ctx, MonoBasicBlock *bb, gboolean rethrow, LLVMValueRef exc)
3490 const char *icall_name = rethrow ? "mono_llvm_rethrow_exception" : "mono_llvm_throw_exception";
3491 LLVMValueRef callee = rethrow ? ctx->module->rethrow : ctx->module->throw_icall;
3493 LLVMTypeRef exc_type = type_to_llvm_type (ctx, &mono_get_exception_class ()->byval_arg);
3496 LLVMTypeRef fun_sig = LLVMFunctionType1 (LLVMVoidType (), exc_type, FALSE);
3498 if (ctx->cfg->compile_aot) {
3499 callee = get_callee (ctx, fun_sig, MONO_PATCH_INFO_JIT_ICALL_ADDR, icall_name);
3501 callee = LLVMAddFunction (ctx->lmodule, icall_name, fun_sig);
3502 LLVMAddGlobalMapping (ctx->module->ee, callee, resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name));
3503 mono_memory_barrier ();
3506 ctx->module->rethrow = callee;
3508 ctx->module->throw_icall = callee;
3512 LLVMValueRef args [2];
3514 args [0] = convert (ctx, exc, exc_type);
3515 emit_call (ctx, bb, &ctx->builder, callee, args, 1);
3517 LLVMBuildUnreachable (ctx->builder);
3519 ctx->builder = create_builder (ctx);
3523 emit_throw (EmitContext *ctx, MonoBasicBlock *bb, gboolean rethrow, LLVMValueRef exc)
3525 MonoMethodSignature *throw_sig;
3526 LLVMValueRef callee, arg;
3527 const char *icall_name;
3529 callee = rethrow ? ctx->module->rethrow : ctx->module->throw_icall;
3530 icall_name = rethrow ? "mono_arch_rethrow_exception" : "mono_arch_throw_exception";
3533 throw_sig = mono_metadata_signature_alloc (mono_get_corlib (), 1);
3534 throw_sig->ret = &mono_get_void_class ()->byval_arg;
3535 throw_sig->params [0] = &mono_get_object_class ()->byval_arg;
3536 if (ctx->cfg->compile_aot) {
3537 callee = get_callee (ctx, sig_to_llvm_sig (ctx, throw_sig), MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
3539 callee = LLVMAddFunction (ctx->lmodule, icall_name, sig_to_llvm_sig (ctx, throw_sig));
3543 * LLVM doesn't push the exception argument, so we need a different
3546 LLVMAddGlobalMapping (ctx->module->ee, callee, resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, rethrow ? "llvm_rethrow_exception_trampoline" : "llvm_throw_exception_trampoline"));
3548 LLVMAddGlobalMapping (ctx->module->ee, callee, resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name));
3552 mono_memory_barrier ();
3554 ctx->module->rethrow = callee;
3556 ctx->module->throw_icall = callee;
3558 arg = convert (ctx, exc, type_to_llvm_type (ctx, &mono_get_object_class ()->byval_arg));
3559 emit_call (ctx, bb, &ctx->builder, callee, &arg, 1);
3563 emit_resume_eh (EmitContext *ctx, MonoBasicBlock *bb)
3565 const char *icall_name = "mono_llvm_resume_exception";
3566 LLVMValueRef callee = ctx->module->resume_eh;
3568 LLVMTypeRef fun_sig = LLVMFunctionType0 (LLVMVoidType (), FALSE);
3571 if (ctx->cfg->compile_aot) {
3572 callee = get_callee (ctx, fun_sig, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
3574 callee = LLVMAddFunction (ctx->lmodule, icall_name, fun_sig);
3575 LLVMAddGlobalMapping (ctx->module->ee, callee, resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name));
3576 mono_memory_barrier ();
3578 ctx->module->resume_eh = callee;
3582 emit_call (ctx, bb, &ctx->builder, callee, NULL, 0);
3584 LLVMBuildUnreachable (ctx->builder);
3586 ctx->builder = create_builder (ctx);
3590 mono_llvm_emit_clear_exception_call (EmitContext *ctx, LLVMBuilderRef builder)
3592 const char *icall_name = "mono_llvm_clear_exception";
3594 LLVMTypeRef call_sig = LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE);
3595 LLVMValueRef callee = NULL;
3598 if (ctx->cfg->compile_aot) {
3599 callee = get_callee (ctx, call_sig, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
3601 // FIXME: This is broken.
3602 callee = LLVMAddFunction (ctx->lmodule, icall_name, call_sig);
3606 g_assert (builder && callee);
3608 return LLVMBuildCall (builder, callee, NULL, 0, "");
3612 mono_llvm_emit_load_exception_call (EmitContext *ctx, LLVMBuilderRef builder)
3614 const char *icall_name = "mono_llvm_load_exception";
3616 LLVMTypeRef call_sig = LLVMFunctionType (ObjRefType (), NULL, 0, FALSE);
3617 LLVMValueRef callee = NULL;
3620 if (ctx->cfg->compile_aot) {
3621 callee = get_callee (ctx, call_sig, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
3623 // FIXME: This is broken.
3624 callee = LLVMAddFunction (ctx->lmodule, icall_name, call_sig);
3628 g_assert (builder && callee);
3630 return LLVMBuildCall (builder, callee, NULL, 0, icall_name);
3635 mono_llvm_emit_match_exception_call (EmitContext *ctx, LLVMBuilderRef builder, gint32 region_start, gint32 region_end)
3637 const char *icall_name = "mono_llvm_match_exception";
3639 ctx->builder = builder;
3641 const int num_args = 5;
3642 LLVMValueRef args [num_args];
3643 args [0] = convert (ctx, get_aotconst (ctx, MONO_PATCH_INFO_AOT_JIT_INFO, GINT_TO_POINTER (ctx->cfg->method_index)), IntPtrType ());
3644 args [1] = LLVMConstInt (LLVMInt32Type (), region_start, 0);
3645 args [2] = LLVMConstInt (LLVMInt32Type (), region_end, 0);
3646 if (ctx->cfg->rgctx_var) {
3647 LLVMValueRef rgctx_alloc = ctx->addresses [ctx->cfg->rgctx_var->dreg];
3648 g_assert (rgctx_alloc);
3649 args [3] = LLVMBuildLoad (builder, convert (ctx, rgctx_alloc, LLVMPointerType (IntPtrType (), 0)), "");
3651 args [3] = LLVMConstInt (IntPtrType (), 0, 0);
3654 args [4] = convert (ctx, ctx->this_arg, IntPtrType ());
3656 args [4] = LLVMConstInt (IntPtrType (), 0, 0);
3658 LLVMTypeRef match_sig = LLVMFunctionType5 (LLVMInt32Type (), IntPtrType (), LLVMInt32Type (), LLVMInt32Type (), IntPtrType (), IntPtrType (), FALSE);
3659 LLVMValueRef callee = ctx->module->match_exc;
3662 if (ctx->cfg->compile_aot) {
3663 ctx->builder = builder;
3664 // get_callee expects ctx->builder to be the emitting builder
3665 callee = get_callee (ctx, match_sig, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
3667 callee = ctx->module->match_exc = LLVMAddFunction (ctx->lmodule, icall_name, match_sig);
3668 LLVMAddGlobalMapping (ctx->module->ee, ctx->module->match_exc, resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name));
3669 ctx->module->match_exc = callee;
3670 mono_memory_barrier ();
3674 g_assert (builder && callee);
3676 g_assert (ctx->ex_var);
3678 return LLVMBuildCall (builder, callee, args, num_args, icall_name);
3681 // FIXME: This won't work because the code-finding makes this
3683 /*#define MONO_PERSONALITY_DEBUG*/
3685 #ifdef MONO_PERSONALITY_DEBUG
3686 static const gboolean use_debug_personality = TRUE;
3687 static const char *default_personality_name = "mono_debug_personality";
3689 static const gboolean use_debug_personality = FALSE;
3690 static const char *default_personality_name = "__gxx_personality_v0";
3694 default_cpp_lpad_exc_signature (void)
3696 static gboolean inited = FALSE;
3697 static LLVMTypeRef sig;
3700 LLVMTypeRef signature [2];
3701 signature [0] = LLVMPointerType (LLVMInt8Type (), 0);
3702 signature [1] = LLVMInt32Type ();
3703 sig = LLVMStructType (signature, 2, FALSE);
3711 get_mono_personality (EmitContext *ctx)
3713 LLVMValueRef personality = NULL;
3714 static gint32 mapping_inited = FALSE;
3715 LLVMTypeRef personality_type = LLVMFunctionType (LLVMInt32Type (), NULL, 0, TRUE);
3717 if (!use_debug_personality) {
3718 if (ctx->cfg->compile_aot) {
3719 personality = LLVMGetNamedFunction (ctx->lmodule, default_personality_name);
3720 } else if (InterlockedCompareExchange (&mapping_inited, 1, 0) == 0) {
3721 personality = LLVMAddFunction (ctx->lmodule, default_personality_name, personality_type);
3722 LLVMAddGlobalMapping (ctx->module->ee, personality, personality);
3725 if (ctx->cfg->compile_aot) {
3726 personality = get_callee (ctx, personality_type, MONO_PATCH_INFO_INTERNAL_METHOD, default_personality_name);
3728 personality = LLVMAddFunction (ctx->lmodule, default_personality_name, personality_type);
3729 LLVMAddGlobalMapping (ctx->module->ee, personality, resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, default_personality_name));
3730 mono_memory_barrier ();
3734 g_assert (personality);
3738 static LLVMBasicBlockRef
3739 emit_landing_pad (EmitContext *ctx, int group_index, int group_size)
3741 MonoCompile *cfg = ctx->cfg;
3742 LLVMBuilderRef old_builder = ctx->builder;
3743 MonoExceptionClause *group_start = cfg->header->clauses + group_index;
3745 LLVMBuilderRef lpadBuilder = create_builder (ctx);
3746 ctx->builder = lpadBuilder;
3748 MonoBasicBlock *handler_bb = cfg->cil_offset_to_bb [CLAUSE_START (group_start)];
3749 g_assert (handler_bb);
3751 // <resultval> = landingpad <somety> personality <type> <pers_fn> <clause>+
3752 LLVMValueRef personality = get_mono_personality (ctx);
3753 g_assert (personality);
3755 char *bb_name = g_strdup_printf ("LPAD%d_BB", group_index);
3756 LLVMBasicBlockRef lpad_bb = gen_bb (ctx, bb_name);
3758 LLVMPositionBuilderAtEnd (lpadBuilder, lpad_bb);
3759 LLVMValueRef landing_pad = LLVMBuildLandingPad (lpadBuilder, default_cpp_lpad_exc_signature (), personality, 0, "");
3760 g_assert (landing_pad);
3762 LLVMValueRef cast = LLVMBuildBitCast (lpadBuilder, ctx->module->sentinel_exception, LLVMPointerType (LLVMInt8Type (), 0), "int8TypeInfo");
3763 LLVMAddClause (landing_pad, cast);
3765 LLVMBasicBlockRef resume_bb = gen_bb (ctx, "RESUME_BB");
3766 LLVMBuilderRef resume_builder = create_builder (ctx);
3767 ctx->builder = resume_builder;
3768 LLVMPositionBuilderAtEnd (resume_builder, resume_bb);
3770 emit_resume_eh (ctx, handler_bb);
3773 ctx->builder = lpadBuilder;
3774 LLVMPositionBuilderAtEnd (lpadBuilder, lpad_bb);
3776 gboolean finally_only = TRUE;
3778 MonoExceptionClause *group_cursor = group_start;
3780 for (int i = 0; i < group_size; i ++) {
3781 if (!(group_cursor->flags & MONO_EXCEPTION_CLAUSE_FINALLY))
3782 finally_only = FALSE;
3788 // Handle landing pad inlining
3790 if (!finally_only) {
3791 // So at each level of the exception stack we will match the exception again.
3792 // During that match, we need to compare against the handler types for the current
3793 // protected region. We send the try start and end so that we can only check against
3794 // handlers for this lexical protected region.
3795 LLVMValueRef match = mono_llvm_emit_match_exception_call (ctx, lpadBuilder, group_start->try_offset, group_start->try_offset + group_start->try_len);
3797 // if returns -1, resume
3798 LLVMValueRef switch_ins = LLVMBuildSwitch (lpadBuilder, match, resume_bb, group_size);
3800 // else move to that target bb
3801 for (int i=0; i < group_size; i++) {
3802 MonoExceptionClause *clause = group_start + i;
3803 int clause_index = clause - cfg->header->clauses;
3804 MonoBasicBlock *handler_bb = (MonoBasicBlock*)g_hash_table_lookup (ctx->clause_to_handler, GINT_TO_POINTER (clause_index));
3805 g_assert (handler_bb);
3806 g_assert (ctx->bblocks [handler_bb->block_num].call_handler_target_bb);
3807 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), clause_index, FALSE), ctx->bblocks [handler_bb->block_num].call_handler_target_bb);
3810 int clause_index = group_start - cfg->header->clauses;
3811 MonoBasicBlock *finally_bb = (MonoBasicBlock*)g_hash_table_lookup (ctx->clause_to_handler, GINT_TO_POINTER (clause_index));
3812 g_assert (finally_bb);
3814 LLVMBuildBr (ctx->builder, ctx->bblocks [finally_bb->block_num].call_handler_target_bb);
3817 ctx->builder = old_builder;
3824 emit_llvmonly_handler_start (EmitContext *ctx, MonoBasicBlock *bb, LLVMBasicBlockRef cbb)
3826 int clause_index = MONO_REGION_CLAUSE_INDEX (bb->region);
3827 MonoExceptionClause *clause = &ctx->cfg->header->clauses [clause_index];
3829 // Make exception available to catch blocks
3830 if (!(clause->flags & MONO_EXCEPTION_CLAUSE_FINALLY)) {
3831 LLVMValueRef mono_exc = mono_llvm_emit_load_exception_call (ctx, ctx->builder);
3833 g_assert (ctx->ex_var);
3834 LLVMBuildStore (ctx->builder, LLVMBuildBitCast (ctx->builder, mono_exc, ObjRefType (), ""), ctx->ex_var);
3836 if (bb->in_scount == 1) {
3837 MonoInst *exvar = bb->in_stack [0];
3838 g_assert (!ctx->values [exvar->dreg]);
3839 g_assert (ctx->ex_var);
3840 ctx->values [exvar->dreg] = LLVMBuildLoad (ctx->builder, ctx->ex_var, "save_exception");
3841 emit_volatile_store (ctx, exvar->dreg);
3844 mono_llvm_emit_clear_exception_call (ctx, ctx->builder);
3847 LLVMBuilderRef handler_builder = create_builder (ctx);
3848 LLVMBasicBlockRef target_bb = ctx->bblocks [bb->block_num].call_handler_target_bb;
3849 LLVMPositionBuilderAtEnd (handler_builder, target_bb);
3851 // Make the handler code end with a jump to cbb
3852 LLVMBuildBr (handler_builder, cbb);
3856 emit_handler_start (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef builder)
3858 MonoCompile *cfg = ctx->cfg;
3859 LLVMValueRef *values = ctx->values;
3860 LLVMModuleRef lmodule = ctx->lmodule;
3861 BBInfo *bblocks = ctx->bblocks;
3863 LLVMValueRef personality;
3864 LLVMValueRef landing_pad;
3865 LLVMBasicBlockRef target_bb;
3867 static gint32 mapping_inited;
3868 static int ti_generator;
3871 LLVMValueRef type_info;
3875 // <resultval> = landingpad <somety> personality <type> <pers_fn> <clause>+
3877 if (cfg->compile_aot) {
3878 /* Use a dummy personality function */
3879 personality = LLVMGetNamedFunction (lmodule, "mono_personality");
3880 g_assert (personality);
3882 personality = LLVMGetNamedFunction (lmodule, "mono_personality");
3883 if (InterlockedCompareExchange (&mapping_inited, 1, 0) == 0)
3884 LLVMAddGlobalMapping (ctx->module->ee, personality, (gpointer)mono_personality);
3887 i8ptr = LLVMPointerType (LLVMInt8Type (), 0);
3889 clause_index = (mono_get_block_region_notry (cfg, bb->region) >> 8) - 1;
3892 * Create the type info
3894 sprintf (ti_name, "type_info_%d", ti_generator);
3897 if (cfg->compile_aot) {
3898 /* decode_eh_frame () in aot-runtime.c will decode this */
3899 type_info = LLVMAddGlobal (lmodule, LLVMInt32Type (), ti_name);
3900 LLVMSetInitializer (type_info, LLVMConstInt (LLVMInt32Type (), clause_index, FALSE));
3903 * These symbols are not really used, the clause_index is embedded into the EH tables generated by DwarfMonoException in LLVM.
3905 LLVMSetLinkage (type_info, LLVMInternalLinkage);
3908 * After the cfg mempool is freed, the type info will point to stale memory,
3909 * but this is not a problem, since we decode it once in exception_cb during
3912 ti = (gint32*)mono_mempool_alloc (cfg->mempool, sizeof (gint32));
3913 *(gint32*)ti = clause_index;
3915 type_info = LLVMAddGlobal (lmodule, i8ptr, ti_name);
3917 LLVMAddGlobalMapping (ctx->module->ee, type_info, ti);
3921 LLVMTypeRef members [2], ret_type;
3923 members [0] = i8ptr;
3924 members [1] = LLVMInt32Type ();
3925 ret_type = LLVMStructType (members, 2, FALSE);
3927 landing_pad = LLVMBuildLandingPad (builder, ret_type, personality, 1, "");
3928 LLVMAddClause (landing_pad, type_info);
3930 /* Store the exception into the exvar */
3932 LLVMBuildStore (builder, convert (ctx, LLVMBuildExtractValue (builder, landing_pad, 0, "ex_obj"), ObjRefType ()), ctx->ex_var);
3936 * LLVM throw sites are associated with a one landing pad, and LLVM generated
3937 * code expects control to be transferred to this landing pad even in the
3938 * presence of nested clauses. The landing pad needs to branch to the landing
3939 * pads belonging to nested clauses based on the selector value returned by
3940 * the landing pad instruction, which is passed to the landing pad in a
3941 * register by the EH code.
3943 target_bb = bblocks [bb->block_num].call_handler_target_bb;
3944 g_assert (target_bb);
3947 * Branch to the correct landing pad
3949 LLVMValueRef ex_selector = LLVMBuildExtractValue (builder, landing_pad, 1, "ex_selector");
3950 LLVMValueRef switch_ins = LLVMBuildSwitch (builder, ex_selector, target_bb, 0);
3952 for (l = ctx->nested_in [clause_index]; l; l = l->next) {
3953 int nesting_clause_index = GPOINTER_TO_INT (l->data);
3954 MonoBasicBlock *handler_bb;
3956 handler_bb = (MonoBasicBlock*)g_hash_table_lookup (ctx->clause_to_handler, GINT_TO_POINTER (nesting_clause_index));
3957 g_assert (handler_bb);
3959 g_assert (ctx->bblocks [handler_bb->block_num].call_handler_target_bb);
3960 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), nesting_clause_index, FALSE), ctx->bblocks [handler_bb->block_num].call_handler_target_bb);
3963 /* Start a new bblock which CALL_HANDLER can branch to */
3964 target_bb = bblocks [bb->block_num].call_handler_target_bb;
3966 ctx->builder = builder = create_builder (ctx);
3967 LLVMPositionBuilderAtEnd (ctx->builder, target_bb);
3969 ctx->bblocks [bb->block_num].end_bblock = target_bb;
3971 /* Store the exception into the IL level exvar */
3972 if (bb->in_scount == 1) {
3973 g_assert (bb->in_scount == 1);
3974 exvar = bb->in_stack [0];
3976 // FIXME: This is shared with filter clauses ?
3977 g_assert (!values [exvar->dreg]);
3979 g_assert (ctx->ex_var);
3980 values [exvar->dreg] = LLVMBuildLoad (builder, ctx->ex_var, "");
3981 emit_volatile_store (ctx, exvar->dreg);
3987 process_bb (EmitContext *ctx, MonoBasicBlock *bb)
3989 MonoCompile *cfg = ctx->cfg;
3990 MonoMethodSignature *sig = ctx->sig;
3991 LLVMValueRef method = ctx->lmethod;
3992 LLVMValueRef *values = ctx->values;
3993 LLVMValueRef *addresses = ctx->addresses;
3994 LLVMCallInfo *linfo = ctx->linfo;
3995 LLVMModuleRef lmodule = ctx->lmodule;
3996 BBInfo *bblocks = ctx->bblocks;
3998 LLVMBasicBlockRef cbb;
3999 LLVMBuilderRef builder, starting_builder;
4000 gboolean has_terminator;
4002 LLVMValueRef lhs, rhs;
4005 cbb = get_end_bb (ctx, bb);
4007 builder = create_builder (ctx);
4008 ctx->builder = builder;
4009 LLVMPositionBuilderAtEnd (builder, cbb);
4014 if (bb->flags & BB_EXCEPTION_HANDLER) {
4015 if (!ctx->llvm_only && !bblocks [bb->block_num].invoke_target) {
4016 set_failure (ctx, "handler without invokes");
4021 emit_llvmonly_handler_start (ctx, bb, cbb);
4023 emit_handler_start (ctx, bb, builder);
4026 builder = ctx->builder;
4029 has_terminator = FALSE;
4030 starting_builder = builder;
4031 for (ins = bb->code; ins; ins = ins->next) {
4032 const char *spec = LLVM_INS_INFO (ins->opcode);
4034 char dname_buf [128];
4036 emit_dbg_loc (ctx, builder, ins->cil_code);
4041 * Some steps in llc are non-linear in the size of basic blocks, see #5714.
4042 * Start a new bblock. If the llvm optimization passes merge these, we
4043 * can work around that by doing a volatile load + cond branch from
4044 * localloc-ed memory.
4046 //set_failure (ctx, "basic block too long");
4047 cbb = gen_bb (ctx, "CONT_LONG_BB");
4048 LLVMBuildBr (ctx->builder, cbb);
4049 ctx->builder = builder = create_builder (ctx);
4050 LLVMPositionBuilderAtEnd (builder, cbb);
4051 ctx->bblocks [bb->block_num].end_bblock = cbb;
4056 /* There could be instructions after a terminator, skip them */
4059 if (spec [MONO_INST_DEST] != ' ' && !MONO_IS_STORE_MEMBASE (ins)) {
4060 sprintf (dname_buf, "t%d", ins->dreg);
4064 if (spec [MONO_INST_SRC1] != ' ' && spec [MONO_INST_SRC1] != 'v') {
4065 MonoInst *var = get_vreg_to_inst (cfg, ins->sreg1);
4067 if (var && var->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT) && var->opcode != OP_GSHAREDVT_ARG_REGOFFSET) {
4068 lhs = emit_volatile_load (ctx, ins->sreg1);
4070 /* It is ok for SETRET to have an uninitialized argument */
4071 if (!values [ins->sreg1] && ins->opcode != OP_SETRET) {
4072 set_failure (ctx, "sreg1");
4075 lhs = values [ins->sreg1];
4081 if (spec [MONO_INST_SRC2] != ' ' && spec [MONO_INST_SRC2] != ' ') {
4082 MonoInst *var = get_vreg_to_inst (cfg, ins->sreg2);
4083 if (var && var->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT)) {
4084 rhs = emit_volatile_load (ctx, ins->sreg2);
4086 if (!values [ins->sreg2]) {
4087 set_failure (ctx, "sreg2");
4090 rhs = values [ins->sreg2];
4096 //mono_print_ins (ins);
4097 switch (ins->opcode) {
4100 case OP_LIVERANGE_START:
4101 case OP_LIVERANGE_END:
4104 values [ins->dreg] = LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE);
4107 #if SIZEOF_VOID_P == 4
4108 values [ins->dreg] = LLVMConstInt (LLVMInt64Type (), GET_LONG_IMM (ins), FALSE);
4110 values [ins->dreg] = LLVMConstInt (LLVMInt64Type (), (gint64)ins->inst_c0, FALSE);
4114 values [ins->dreg] = LLVMConstReal (LLVMDoubleType (), *(double*)ins->inst_p0);
4118 values [ins->dreg] = LLVMConstReal (LLVMFloatType (), *(float*)ins->inst_p0);
4120 values [ins->dreg] = LLVMConstFPExt (LLVMConstReal (LLVMFloatType (), *(float*)ins->inst_p0), LLVMDoubleType ());
4122 case OP_DUMMY_ICONST:
4123 values [ins->dreg] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
4125 case OP_DUMMY_I8CONST:
4126 values [ins->dreg] = LLVMConstInt (LLVMInt64Type (), 0, FALSE);
4128 case OP_DUMMY_R8CONST:
4129 values [ins->dreg] = LLVMConstReal (LLVMDoubleType (), 0.0f);
4132 LLVMBasicBlockRef target_bb = get_bb (ctx, ins->inst_target_bb);
4133 LLVMBuildBr (builder, target_bb);
4134 has_terminator = TRUE;
4141 LLVMBasicBlockRef new_bb;
4142 LLVMBuilderRef new_builder;
4144 // The default branch is already handled
4145 // FIXME: Handle it here
4147 /* Start new bblock */
4148 sprintf (bb_name, "SWITCH_DEFAULT_BB%d", ctx->default_index ++);
4149 new_bb = LLVMAppendBasicBlock (ctx->lmethod, bb_name);
4151 lhs = convert (ctx, lhs, LLVMInt32Type ());
4152 v = LLVMBuildSwitch (builder, lhs, new_bb, GPOINTER_TO_UINT (ins->klass));
4153 for (i = 0; i < GPOINTER_TO_UINT (ins->klass); ++i) {
4154 MonoBasicBlock *target_bb = ins->inst_many_bb [i];
4156 LLVMAddCase (v, LLVMConstInt (LLVMInt32Type (), i, FALSE), get_bb (ctx, target_bb));
4159 new_builder = create_builder (ctx);
4160 LLVMPositionBuilderAtEnd (new_builder, new_bb);
4161 LLVMBuildUnreachable (new_builder);
4163 has_terminator = TRUE;
4164 g_assert (!ins->next);
4170 switch (linfo->ret.storage) {
4171 case LLVMArgVtypeInReg: {
4172 LLVMTypeRef ret_type = LLVMGetReturnType (LLVMGetElementType (LLVMTypeOf (method)));
4173 LLVMValueRef val, addr, retval;
4176 retval = LLVMGetUndef (ret_type);
4178 if (!addresses [ins->sreg1]) {
4180 * The return type is an LLVM vector type, have to convert between it and the
4181 * real return type which is a struct type.
4183 g_assert (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (sig->ret)));
4184 /* Convert to 2xi64 first */
4185 val = LLVMBuildBitCast (builder, values [ins->sreg1], LLVMVectorType (IntPtrType (), 2), "");
4187 for (i = 0; i < 2; ++i) {
4188 if (linfo->ret.pair_storage [i] == LLVMArgInIReg) {
4189 retval = LLVMBuildInsertValue (builder, retval, LLVMBuildExtractElement (builder, val, LLVMConstInt (LLVMInt32Type (), i, FALSE), ""), i, "");
4191 g_assert (linfo->ret.pair_storage [i] == LLVMArgNone);
4195 addr = LLVMBuildBitCast (builder, addresses [ins->sreg1], LLVMPointerType (ret_type, 0), "");
4196 for (i = 0; i < 2; ++i) {
4197 if (linfo->ret.pair_storage [i] == LLVMArgInIReg) {
4198 LLVMValueRef indexes [2], part_addr;
4200 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
4201 indexes [1] = LLVMConstInt (LLVMInt32Type (), i, FALSE);
4202 part_addr = LLVMBuildGEP (builder, addr, indexes, 2, "");
4204 retval = LLVMBuildInsertValue (builder, retval, LLVMBuildLoad (builder, part_addr, ""), i, "");
4206 g_assert (linfo->ret.pair_storage [i] == LLVMArgNone);
4210 LLVMBuildRet (builder, retval);
4213 case LLVMArgVtypeAsScalar: {
4214 LLVMTypeRef ret_type = LLVMGetReturnType (LLVMGetElementType (LLVMTypeOf (method)));
4215 LLVMValueRef retval;
4217 g_assert (addresses [ins->sreg1]);
4219 retval = LLVMBuildLoad (builder, LLVMBuildBitCast (builder, addresses [ins->sreg1], LLVMPointerType (ret_type, 0), ""), "");
4220 LLVMBuildRet (builder, retval);
4223 case LLVMArgVtypeByVal: {
4224 LLVMValueRef retval;
4226 g_assert (addresses [ins->sreg1]);
4227 retval = LLVMBuildLoad (builder, addresses [ins->sreg1], "");
4228 LLVMBuildRet (builder, retval);
4231 case LLVMArgVtypeByRef: {
4232 LLVMBuildRetVoid (builder);
4235 case LLVMArgGsharedvtFixed: {
4236 LLVMTypeRef ret_type = type_to_llvm_type (ctx, sig->ret);
4237 /* The return value is in lhs, need to store to the vret argument */
4238 /* sreg1 might not be set */
4240 g_assert (cfg->vret_addr);
4241 g_assert (values [cfg->vret_addr->dreg]);
4242 LLVMBuildStore (builder, convert (ctx, lhs, ret_type), convert (ctx, values [cfg->vret_addr->dreg], LLVMPointerType (ret_type, 0)));
4244 LLVMBuildRetVoid (builder);
4247 case LLVMArgGsharedvtFixedVtype: {
4249 LLVMBuildRetVoid (builder);
4252 case LLVMArgGsharedvtVariable: {
4254 LLVMBuildRetVoid (builder);
4257 case LLVMArgVtypeRetAddr: {
4258 LLVMBuildRetVoid (builder);
4261 case LLVMArgFpStruct: {
4262 LLVMTypeRef ret_type = LLVMGetReturnType (LLVMGetElementType (LLVMTypeOf (method)));
4263 LLVMValueRef retval;
4265 g_assert (addresses [ins->sreg1]);
4266 retval = LLVMBuildLoad (builder, convert (ctx, addresses [ins->sreg1], LLVMPointerType (ret_type, 0)), "");
4267 LLVMBuildRet (builder, retval);
4271 case LLVMArgNormal: {
4272 if (!lhs || ctx->is_dead [ins->sreg1]) {
4274 * The method did not set its return value, probably because it
4275 * ends with a throw.
4278 LLVMBuildRetVoid (builder);
4280 LLVMBuildRet (builder, LLVMConstNull (type_to_llvm_type (ctx, sig->ret)));
4282 LLVMBuildRet (builder, convert (ctx, lhs, type_to_llvm_type (ctx, sig->ret)));
4284 has_terminator = TRUE;
4288 g_assert_not_reached ();
4297 case OP_ICOMPARE_IMM:
4298 case OP_LCOMPARE_IMM:
4299 case OP_COMPARE_IMM: {
4301 LLVMValueRef cmp, args [16];
4302 gboolean likely = (ins->flags & MONO_INST_LIKELY) != 0;
4304 if (ins->next->opcode == OP_NOP)
4307 if (ins->next->opcode == OP_BR)
4308 /* The comparison result is not needed */
4311 rel = mono_opcode_to_cond (ins->next->opcode);
4313 if (ins->opcode == OP_ICOMPARE_IMM) {
4314 lhs = convert (ctx, lhs, LLVMInt32Type ());
4315 rhs = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
4317 if (ins->opcode == OP_LCOMPARE_IMM) {
4318 lhs = convert (ctx, lhs, LLVMInt64Type ());
4319 rhs = LLVMConstInt (LLVMInt64Type (), GET_LONG_IMM (ins), FALSE);
4321 if (ins->opcode == OP_LCOMPARE) {
4322 lhs = convert (ctx, lhs, LLVMInt64Type ());
4323 rhs = convert (ctx, rhs, LLVMInt64Type ());
4325 if (ins->opcode == OP_ICOMPARE) {
4326 lhs = convert (ctx, lhs, LLVMInt32Type ());
4327 rhs = convert (ctx, rhs, LLVMInt32Type ());
4331 if (LLVMGetTypeKind (LLVMTypeOf (lhs)) == LLVMPointerTypeKind)
4332 rhs = convert (ctx, rhs, LLVMTypeOf (lhs));
4333 else if (LLVMGetTypeKind (LLVMTypeOf (rhs)) == LLVMPointerTypeKind)
4334 lhs = convert (ctx, lhs, LLVMTypeOf (rhs));
4337 /* We use COMPARE+SETcc/Bcc, llvm uses SETcc+br cond */
4338 if (ins->opcode == OP_FCOMPARE) {
4339 cmp = LLVMBuildFCmp (builder, fpcond_to_llvm_cond [rel], convert (ctx, lhs, LLVMDoubleType ()), convert (ctx, rhs, LLVMDoubleType ()), "");
4340 } else if (ins->opcode == OP_RCOMPARE) {
4341 cmp = LLVMBuildFCmp (builder, fpcond_to_llvm_cond [rel], convert (ctx, lhs, LLVMFloatType ()), convert (ctx, rhs, LLVMFloatType ()), "");
4342 } else if (ins->opcode == OP_COMPARE_IMM) {
4343 if (LLVMGetTypeKind (LLVMTypeOf (lhs)) == LLVMPointerTypeKind && ins->inst_imm == 0)
4344 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], lhs, LLVMConstNull (LLVMTypeOf (lhs)), "");
4346 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE), "");
4347 } else if (ins->opcode == OP_LCOMPARE_IMM) {
4348 if (SIZEOF_REGISTER == 4 && COMPILE_LLVM (cfg)) {
4349 /* The immediate is encoded in two fields */
4350 guint64 l = ((guint64)(guint32)ins->inst_offset << 32) | ((guint32)ins->inst_imm);
4351 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, LLVMInt64Type ()), LLVMConstInt (LLVMInt64Type (), l, FALSE), "");
4353 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, LLVMInt64Type ()), LLVMConstInt (LLVMInt64Type (), ins->inst_imm, FALSE), "");
4356 else if (ins->opcode == OP_COMPARE) {
4357 if (LLVMGetTypeKind (LLVMTypeOf (lhs)) == LLVMPointerTypeKind && LLVMTypeOf (lhs) == LLVMTypeOf (rhs))
4358 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], lhs, rhs, "");
4360 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, IntPtrType ()), convert (ctx, rhs, IntPtrType ()), "");
4362 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], lhs, rhs, "");
4366 args [1] = LLVMConstInt (LLVMInt1Type (), 1, FALSE);
4367 cmp = LLVMBuildCall (ctx->builder, LLVMGetNamedFunction (ctx->lmodule, "llvm.expect.i1"), args, 2, "");
4370 if (MONO_IS_COND_BRANCH_OP (ins->next)) {
4371 if (ins->next->inst_true_bb == ins->next->inst_false_bb) {
4373 * If the target bb contains PHI instructions, LLVM requires
4374 * two PHI entries for this bblock, while we only generate one.
4375 * So convert this to an unconditional bblock. (bxc #171).
4377 LLVMBuildBr (builder, get_bb (ctx, ins->next->inst_true_bb));
4379 LLVMBuildCondBr (builder, cmp, get_bb (ctx, ins->next->inst_true_bb), get_bb (ctx, ins->next->inst_false_bb));
4381 has_terminator = TRUE;
4382 } else if (MONO_IS_SETCC (ins->next)) {
4383 sprintf (dname_buf, "t%d", ins->next->dreg);
4385 values [ins->next->dreg] = LLVMBuildZExt (builder, cmp, LLVMInt32Type (), dname);
4387 /* Add stores for volatile variables */
4388 emit_volatile_store (ctx, ins->next->dreg);
4389 } else if (MONO_IS_COND_EXC (ins->next)) {
4390 emit_cond_system_exception (ctx, bb, (const char*)ins->next->inst_p1, cmp);
4393 builder = ctx->builder;
4395 set_failure (ctx, "next");
4413 rel = mono_opcode_to_cond (ins->opcode);
4415 cmp = LLVMBuildFCmp (builder, fpcond_to_llvm_cond [rel], convert (ctx, lhs, LLVMDoubleType ()), convert (ctx, rhs, LLVMDoubleType ()), "");
4416 values [ins->dreg] = LLVMBuildZExt (builder, cmp, LLVMInt32Type (), dname);
4427 rel = mono_opcode_to_cond (ins->opcode);
4429 cmp = LLVMBuildFCmp (builder, fpcond_to_llvm_cond [rel], convert (ctx, lhs, LLVMFloatType ()), convert (ctx, rhs, LLVMFloatType ()), "");
4430 values [ins->dreg] = LLVMBuildZExt (builder, cmp, LLVMInt32Type (), dname);
4438 gboolean empty = TRUE;
4440 /* Check that all input bblocks really branch to us */
4441 for (i = 0; i < bb->in_count; ++i) {
4442 if (bb->in_bb [i]->last_ins && bb->in_bb [i]->last_ins->opcode == OP_NOT_REACHED)
4443 ins->inst_phi_args [i + 1] = -1;
4449 /* LLVM doesn't like phi instructions with zero operands */
4450 ctx->is_dead [ins->dreg] = TRUE;
4454 /* Created earlier, insert it now */
4455 LLVMInsertIntoBuilder (builder, values [ins->dreg]);
4457 for (i = 0; i < ins->inst_phi_args [0]; i++) {
4458 int sreg1 = ins->inst_phi_args [i + 1];
4462 * Count the number of times the incoming bblock branches to us,
4463 * since llvm requires a separate entry for each.
4465 if (bb->in_bb [i]->last_ins && bb->in_bb [i]->last_ins->opcode == OP_SWITCH) {
4466 MonoInst *switch_ins = bb->in_bb [i]->last_ins;
4469 for (j = 0; j < GPOINTER_TO_UINT (switch_ins->klass); ++j) {
4470 if (switch_ins->inst_many_bb [j] == bb)
4477 /* Remember for later */
4478 for (j = 0; j < count; ++j) {
4479 PhiNode *node = (PhiNode*)mono_mempool_alloc0 (ctx->mempool, sizeof (PhiNode));
4482 node->in_bb = bb->in_bb [i];
4484 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);
4494 values [ins->dreg] = lhs;
4498 MonoInst *var = get_vreg_to_inst (cfg, ins->dreg);
4501 values [ins->dreg] = lhs;
4503 if (var && var->klass->byval_arg.type == MONO_TYPE_R4) {
4505 * This is added by the spilling pass in case of the JIT,
4506 * but we have to do it ourselves.
4508 values [ins->dreg] = convert (ctx, values [ins->dreg], LLVMFloatType ());
4512 case OP_MOVE_F_TO_I4: {
4513 values [ins->dreg] = LLVMBuildBitCast (builder, LLVMBuildFPTrunc (builder, lhs, LLVMFloatType (), ""), LLVMInt32Type (), "");
4516 case OP_MOVE_I4_TO_F: {
4517 values [ins->dreg] = LLVMBuildFPExt (builder, LLVMBuildBitCast (builder, lhs, LLVMFloatType (), ""), LLVMDoubleType (), "");
4520 case OP_MOVE_F_TO_I8: {
4521 values [ins->dreg] = LLVMBuildBitCast (builder, lhs, LLVMInt64Type (), "");
4524 case OP_MOVE_I8_TO_F: {
4525 values [ins->dreg] = LLVMBuildBitCast (builder, lhs, LLVMDoubleType (), "");
4558 lhs = convert (ctx, lhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
4559 rhs = convert (ctx, rhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
4561 emit_div_check (ctx, builder, bb, ins, lhs, rhs);
4564 builder = ctx->builder;
4566 switch (ins->opcode) {
4569 values [ins->dreg] = LLVMBuildAdd (builder, lhs, rhs, dname);
4573 values [ins->dreg] = LLVMBuildSub (builder, lhs, rhs, dname);
4577 values [ins->dreg] = LLVMBuildMul (builder, lhs, rhs, dname);
4581 values [ins->dreg] = LLVMBuildSRem (builder, lhs, rhs, dname);
4585 values [ins->dreg] = LLVMBuildURem (builder, lhs, rhs, dname);
4589 values [ins->dreg] = LLVMBuildSDiv (builder, lhs, rhs, dname);
4593 values [ins->dreg] = LLVMBuildUDiv (builder, lhs, rhs, dname);
4597 values [ins->dreg] = LLVMBuildFDiv (builder, lhs, rhs, dname);
4601 values [ins->dreg] = LLVMBuildAnd (builder, lhs, rhs, dname);
4605 values [ins->dreg] = LLVMBuildOr (builder, lhs, rhs, dname);
4609 values [ins->dreg] = LLVMBuildXor (builder, lhs, rhs, dname);
4613 values [ins->dreg] = LLVMBuildShl (builder, lhs, rhs, dname);
4617 values [ins->dreg] = LLVMBuildAShr (builder, lhs, rhs, dname);
4621 values [ins->dreg] = LLVMBuildLShr (builder, lhs, rhs, dname);
4625 values [ins->dreg] = LLVMBuildFAdd (builder, lhs, rhs, dname);
4628 values [ins->dreg] = LLVMBuildFSub (builder, lhs, rhs, dname);
4631 values [ins->dreg] = LLVMBuildFMul (builder, lhs, rhs, dname);
4635 g_assert_not_reached ();
4642 lhs = convert (ctx, lhs, LLVMFloatType ());
4643 rhs = convert (ctx, rhs, LLVMFloatType ());
4644 switch (ins->opcode) {
4646 values [ins->dreg] = LLVMBuildFAdd (builder, lhs, rhs, dname);
4649 values [ins->dreg] = LLVMBuildFSub (builder, lhs, rhs, dname);
4652 values [ins->dreg] = LLVMBuildFMul (builder, lhs, rhs, dname);
4655 values [ins->dreg] = LLVMBuildFDiv (builder, lhs, rhs, dname);
4658 g_assert_not_reached ();
4667 case OP_IREM_UN_IMM:
4669 case OP_IDIV_UN_IMM:
4675 case OP_ISHR_UN_IMM:
4685 case OP_LSHR_UN_IMM:
4691 case OP_SHR_UN_IMM: {
4694 if (spec [MONO_INST_SRC1] == 'l') {
4695 imm = LLVMConstInt (LLVMInt64Type (), GET_LONG_IMM (ins), FALSE);
4697 imm = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
4700 emit_div_check (ctx, builder, bb, ins, lhs, imm);
4703 builder = ctx->builder;
4705 #if SIZEOF_VOID_P == 4
4706 if (ins->opcode == OP_LSHL_IMM || ins->opcode == OP_LSHR_IMM || ins->opcode == OP_LSHR_UN_IMM)
4707 imm = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
4710 if (LLVMGetTypeKind (LLVMTypeOf (lhs)) == LLVMPointerTypeKind)
4711 lhs = convert (ctx, lhs, IntPtrType ());
4712 imm = convert (ctx, imm, LLVMTypeOf (lhs));
4713 switch (ins->opcode) {
4717 values [ins->dreg] = LLVMBuildAdd (builder, lhs, imm, dname);
4721 values [ins->dreg] = LLVMBuildSub (builder, lhs, imm, dname);
4726 values [ins->dreg] = LLVMBuildMul (builder, lhs, imm, dname);
4730 values [ins->dreg] = LLVMBuildSDiv (builder, lhs, imm, dname);
4732 case OP_IDIV_UN_IMM:
4733 case OP_LDIV_UN_IMM:
4734 values [ins->dreg] = LLVMBuildUDiv (builder, lhs, imm, dname);
4738 values [ins->dreg] = LLVMBuildSRem (builder, lhs, imm, dname);
4740 case OP_IREM_UN_IMM:
4741 values [ins->dreg] = LLVMBuildURem (builder, lhs, imm, dname);
4746 values [ins->dreg] = LLVMBuildAnd (builder, lhs, imm, dname);
4750 values [ins->dreg] = LLVMBuildOr (builder, lhs, imm, dname);
4754 values [ins->dreg] = LLVMBuildXor (builder, lhs, imm, dname);
4759 values [ins->dreg] = LLVMBuildShl (builder, lhs, imm, dname);
4764 values [ins->dreg] = LLVMBuildAShr (builder, lhs, imm, dname);
4766 case OP_ISHR_UN_IMM:
4767 /* This is used to implement conv.u4, so the lhs could be an i8 */
4768 lhs = convert (ctx, lhs, LLVMInt32Type ());
4769 imm = convert (ctx, imm, LLVMInt32Type ());
4770 values [ins->dreg] = LLVMBuildLShr (builder, lhs, imm, dname);
4772 case OP_LSHR_UN_IMM:
4774 values [ins->dreg] = LLVMBuildLShr (builder, lhs, imm, dname);
4777 g_assert_not_reached ();
4782 values [ins->dreg] = LLVMBuildSub (builder, LLVMConstInt (LLVMInt32Type (), 0, FALSE), convert (ctx, lhs, LLVMInt32Type ()), dname);
4785 values [ins->dreg] = LLVMBuildSub (builder, LLVMConstInt (LLVMInt64Type (), 0, FALSE), lhs, dname);
4788 lhs = convert (ctx, lhs, LLVMDoubleType ());
4789 values [ins->dreg] = LLVMBuildFSub (builder, LLVMConstReal (LLVMDoubleType (), 0.0), lhs, dname);
4792 lhs = convert (ctx, lhs, LLVMFloatType ());
4793 values [ins->dreg] = LLVMBuildFSub (builder, LLVMConstReal (LLVMFloatType (), 0.0), lhs, dname);
4796 guint32 v = 0xffffffff;
4797 values [ins->dreg] = LLVMBuildXor (builder, LLVMConstInt (LLVMInt32Type (), v, FALSE), convert (ctx, lhs, LLVMInt32Type ()), dname);
4801 guint64 v = 0xffffffffffffffffLL;
4802 values [ins->dreg] = LLVMBuildXor (builder, LLVMConstInt (LLVMInt64Type (), v, FALSE), lhs, dname);
4805 #if defined(TARGET_X86) || defined(TARGET_AMD64)
4807 LLVMValueRef v1, v2;
4809 v1 = LLVMBuildMul (builder, convert (ctx, rhs, IntPtrType ()), LLVMConstInt (IntPtrType (), (1 << ins->backend.shift_amount), FALSE), "");
4810 v2 = LLVMBuildAdd (builder, convert (ctx, lhs, IntPtrType ()), v1, "");
4811 values [ins->dreg] = LLVMBuildAdd (builder, v2, LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE), dname);
4816 case OP_ICONV_TO_I1:
4817 case OP_ICONV_TO_I2:
4818 case OP_ICONV_TO_I4:
4819 case OP_ICONV_TO_U1:
4820 case OP_ICONV_TO_U2:
4821 case OP_ICONV_TO_U4:
4822 case OP_LCONV_TO_I1:
4823 case OP_LCONV_TO_I2:
4824 case OP_LCONV_TO_U1:
4825 case OP_LCONV_TO_U2:
4826 case OP_LCONV_TO_U4: {
4829 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);
4831 /* Have to do two casts since our vregs have type int */
4832 v = LLVMBuildTrunc (builder, lhs, op_to_llvm_type (ins->opcode), "");
4834 values [ins->dreg] = LLVMBuildSExt (builder, v, LLVMInt32Type (), dname);
4836 values [ins->dreg] = LLVMBuildZExt (builder, v, LLVMInt32Type (), dname);
4839 case OP_ICONV_TO_I8:
4840 values [ins->dreg] = LLVMBuildSExt (builder, lhs, LLVMInt64Type (), dname);
4842 case OP_ICONV_TO_U8:
4843 values [ins->dreg] = LLVMBuildZExt (builder, lhs, LLVMInt64Type (), dname);
4845 case OP_FCONV_TO_I4:
4846 case OP_RCONV_TO_I4:
4847 values [ins->dreg] = LLVMBuildFPToSI (builder, lhs, LLVMInt32Type (), dname);
4849 case OP_FCONV_TO_I1:
4850 case OP_RCONV_TO_I1:
4851 values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildFPToSI (builder, lhs, LLVMInt8Type (), dname), LLVMInt32Type (), "");
4853 case OP_FCONV_TO_U1:
4854 case OP_RCONV_TO_U1:
4855 values [ins->dreg] = LLVMBuildZExt (builder, LLVMBuildTrunc (builder, LLVMBuildFPToUI (builder, lhs, IntPtrType (), dname), LLVMInt8Type (), ""), LLVMInt32Type (), "");
4857 case OP_FCONV_TO_I2:
4858 case OP_RCONV_TO_I2:
4859 values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildFPToSI (builder, lhs, LLVMInt16Type (), dname), LLVMInt32Type (), "");
4861 case OP_FCONV_TO_U2:
4862 case OP_RCONV_TO_U2:
4863 values [ins->dreg] = LLVMBuildZExt (builder, LLVMBuildFPToUI (builder, lhs, LLVMInt16Type (), dname), LLVMInt32Type (), "");
4865 case OP_RCONV_TO_U4:
4866 values [ins->dreg] = LLVMBuildFPToUI (builder, lhs, LLVMInt32Type (), dname);
4868 case OP_FCONV_TO_I8:
4869 case OP_RCONV_TO_I8:
4870 values [ins->dreg] = LLVMBuildFPToSI (builder, lhs, LLVMInt64Type (), dname);
4873 values [ins->dreg] = LLVMBuildFPToSI (builder, lhs, IntPtrType (), dname);
4875 case OP_ICONV_TO_R8:
4876 case OP_LCONV_TO_R8:
4877 values [ins->dreg] = LLVMBuildSIToFP (builder, lhs, LLVMDoubleType (), dname);
4879 case OP_ICONV_TO_R_UN:
4880 case OP_LCONV_TO_R_UN:
4881 values [ins->dreg] = LLVMBuildUIToFP (builder, lhs, LLVMDoubleType (), dname);
4883 #if SIZEOF_VOID_P == 4
4886 case OP_LCONV_TO_I4:
4887 values [ins->dreg] = LLVMBuildTrunc (builder, lhs, LLVMInt32Type (), dname);
4889 case OP_ICONV_TO_R4:
4890 case OP_LCONV_TO_R4:
4891 v = LLVMBuildSIToFP (builder, lhs, LLVMFloatType (), "");
4893 values [ins->dreg] = v;
4895 values [ins->dreg] = LLVMBuildFPExt (builder, v, LLVMDoubleType (), dname);
4897 case OP_FCONV_TO_R4:
4898 v = LLVMBuildFPTrunc (builder, lhs, LLVMFloatType (), "");
4900 values [ins->dreg] = v;
4902 values [ins->dreg] = LLVMBuildFPExt (builder, v, LLVMDoubleType (), dname);
4904 case OP_RCONV_TO_R8:
4905 values [ins->dreg] = LLVMBuildFPExt (builder, lhs, LLVMDoubleType (), dname);
4907 case OP_RCONV_TO_R4:
4908 values [ins->dreg] = lhs;
4911 values [ins->dreg] = LLVMBuildSExt (builder, convert (ctx, lhs, LLVMInt32Type ()), LLVMInt64Type (), dname);
4914 values [ins->dreg] = LLVMBuildZExt (builder, convert (ctx, lhs, LLVMInt32Type ()), LLVMInt64Type (), dname);
4917 values [ins->dreg] = LLVMBuildTrunc (builder, lhs, LLVMInt32Type (), dname);
4919 case OP_LOCALLOC_IMM: {
4922 guint32 size = ins->inst_imm;
4923 size = (size + (MONO_ARCH_FRAME_ALIGNMENT - 1)) & ~ (MONO_ARCH_FRAME_ALIGNMENT - 1);
4925 v = mono_llvm_build_alloca (builder, LLVMInt8Type (), LLVMConstInt (LLVMInt32Type (), size, FALSE), MONO_ARCH_FRAME_ALIGNMENT, "");
4927 if (ins->flags & MONO_INST_INIT) {
4928 LLVMValueRef args [5];
4931 args [1] = LLVMConstInt (LLVMInt8Type (), 0, FALSE);
4932 args [2] = LLVMConstInt (LLVMInt32Type (), size, FALSE);
4933 args [3] = LLVMConstInt (LLVMInt32Type (), MONO_ARCH_FRAME_ALIGNMENT, FALSE);
4934 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
4935 LLVMBuildCall (builder, LLVMGetNamedFunction (lmodule, memset_func_name), args, memset_param_count, "");
4938 values [ins->dreg] = v;
4942 LLVMValueRef v, size;
4944 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), "");
4946 v = mono_llvm_build_alloca (builder, LLVMInt8Type (), size, MONO_ARCH_FRAME_ALIGNMENT, "");
4948 if (ins->flags & MONO_INST_INIT) {
4949 LLVMValueRef args [5];
4952 args [1] = LLVMConstInt (LLVMInt8Type (), 0, FALSE);
4954 args [3] = LLVMConstInt (LLVMInt32Type (), MONO_ARCH_FRAME_ALIGNMENT, FALSE);
4955 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
4956 LLVMBuildCall (builder, LLVMGetNamedFunction (lmodule, memset_func_name), args, memset_param_count, "");
4958 values [ins->dreg] = v;
4962 case OP_LOADI1_MEMBASE:
4963 case OP_LOADU1_MEMBASE:
4964 case OP_LOADI2_MEMBASE:
4965 case OP_LOADU2_MEMBASE:
4966 case OP_LOADI4_MEMBASE:
4967 case OP_LOADU4_MEMBASE:
4968 case OP_LOADI8_MEMBASE:
4969 case OP_LOADR4_MEMBASE:
4970 case OP_LOADR8_MEMBASE:
4971 case OP_LOAD_MEMBASE:
4979 LLVMValueRef base, index, addr;
4981 gboolean sext = FALSE, zext = FALSE;
4982 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
4984 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
4989 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)) {
4990 addr = LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE);
4995 if (ins->inst_offset == 0) {
4997 } else if (ins->inst_offset % size != 0) {
4998 /* Unaligned load */
4999 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset, FALSE);
5000 addr = LLVMBuildGEP (builder, convert (ctx, base, LLVMPointerType (LLVMInt8Type (), 0)), &index, 1, "");
5002 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
5003 addr = LLVMBuildGEP (builder, convert (ctx, base, LLVMPointerType (t, 0)), &index, 1, "");
5007 addr = convert (ctx, addr, LLVMPointerType (t, 0));
5009 values [ins->dreg] = emit_load (ctx, bb, &builder, size, addr, dname, is_volatile);
5011 if (!is_volatile && (ins->flags & MONO_INST_INVARIANT_LOAD)) {
5013 * These will signal LLVM that these loads do not alias any stores, and
5014 * they can't fail, allowing them to be hoisted out of loops.
5016 set_invariant_load_flag (values [ins->dreg]);
5017 #if LLVM_API_VERSION < 100
5018 set_metadata_flag (values [ins->dreg], "mono.nofail.load");
5023 values [ins->dreg] = LLVMBuildSExt (builder, values [ins->dreg], LLVMInt32Type (), dname);
5025 values [ins->dreg] = LLVMBuildZExt (builder, values [ins->dreg], LLVMInt32Type (), dname);
5026 else if (!cfg->r4fp && ins->opcode == OP_LOADR4_MEMBASE)
5027 values [ins->dreg] = LLVMBuildFPExt (builder, values [ins->dreg], LLVMDoubleType (), dname);
5031 case OP_STOREI1_MEMBASE_REG:
5032 case OP_STOREI2_MEMBASE_REG:
5033 case OP_STOREI4_MEMBASE_REG:
5034 case OP_STOREI8_MEMBASE_REG:
5035 case OP_STORER4_MEMBASE_REG:
5036 case OP_STORER8_MEMBASE_REG:
5037 case OP_STORE_MEMBASE_REG: {
5039 LLVMValueRef index, addr;
5041 gboolean sext = FALSE, zext = FALSE;
5042 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
5044 if (!values [ins->inst_destbasereg]) {
5045 set_failure (ctx, "inst_destbasereg");
5049 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
5051 if (ins->inst_offset % size != 0) {
5052 /* Unaligned store */
5053 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset, FALSE);
5054 addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (LLVMInt8Type (), 0)), &index, 1, "");
5056 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
5057 addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (t, 0)), &index, 1, "");
5059 emit_store (ctx, bb, &builder, size, convert (ctx, values [ins->sreg1], t), convert (ctx, addr, LLVMPointerType (t, 0)), is_volatile);
5063 case OP_STOREI1_MEMBASE_IMM:
5064 case OP_STOREI2_MEMBASE_IMM:
5065 case OP_STOREI4_MEMBASE_IMM:
5066 case OP_STOREI8_MEMBASE_IMM:
5067 case OP_STORE_MEMBASE_IMM: {
5069 LLVMValueRef index, addr;
5071 gboolean sext = FALSE, zext = FALSE;
5072 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
5074 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
5076 if (ins->inst_offset % size != 0) {
5077 /* Unaligned store */
5078 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset, FALSE);
5079 addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (LLVMInt8Type (), 0)), &index, 1, "");
5081 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
5082 addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (t, 0)), &index, 1, "");
5084 emit_store (ctx, bb, &builder, size, convert (ctx, LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE), t), convert (ctx, addr, LLVMPointerType (t, 0)), is_volatile);
5089 emit_load (ctx, bb, &builder, sizeof (gpointer), convert (ctx, lhs, LLVMPointerType (IntPtrType (), 0)), "", TRUE);
5091 case OP_OUTARG_VTRETADDR:
5099 case OP_VOIDCALL_MEMBASE:
5100 case OP_CALL_MEMBASE:
5101 case OP_LCALL_MEMBASE:
5102 case OP_FCALL_MEMBASE:
5103 case OP_RCALL_MEMBASE:
5104 case OP_VCALL_MEMBASE:
5105 case OP_VOIDCALL_REG:
5110 case OP_VCALL_REG: {
5111 process_call (ctx, bb, &builder, ins);
5116 LLVMValueRef indexes [2];
5117 MonoJumpInfo *tmp_ji, *ji;
5118 LLVMValueRef got_entry_addr;
5122 * FIXME: Can't allocate from the cfg mempool since that is freed if
5123 * the LLVM compile fails.
5125 tmp_ji = g_new0 (MonoJumpInfo, 1);
5126 tmp_ji->type = (MonoJumpInfoType)ins->inst_c1;
5127 tmp_ji->data.target = ins->inst_p0;
5129 ji = mono_aot_patch_info_dup (tmp_ji);
5132 ji->next = cfg->patch_info;
5133 cfg->patch_info = ji;
5135 //mono_add_patch_info (cfg, 0, (MonoJumpInfoType)ins->inst_i1, ins->inst_p0);
5136 got_offset = mono_aot_get_got_offset (cfg->patch_info);
5137 ctx->module->max_got_offset = MAX (ctx->module->max_got_offset, got_offset);
5138 if (!mono_aot_is_shared_got_offset (got_offset)) {
5139 //mono_print_ji (ji);
5141 ctx->has_got_access = TRUE;
5144 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
5145 indexes [1] = LLVMConstInt (LLVMInt32Type (), (gssize)got_offset, FALSE);
5146 got_entry_addr = LLVMBuildGEP (builder, ctx->module->got_var, indexes, 2, "");
5148 name = get_aotconst_name (ji->type, ji->data.target, got_offset);
5149 values [ins->dreg] = LLVMBuildLoad (builder, got_entry_addr, name);
5151 /* Can't use this in llvmonly mode since the got slots are initialized by the methods themselves */
5152 if (!cfg->llvm_only)
5153 set_invariant_load_flag (values [ins->dreg]);
5156 case OP_NOT_REACHED:
5157 LLVMBuildUnreachable (builder);
5158 has_terminator = TRUE;
5159 g_assert (bb->block_num < cfg->max_block_num);
5160 ctx->unreachable [bb->block_num] = TRUE;
5161 /* Might have instructions after this */
5163 MonoInst *next = ins->next;
5165 * FIXME: If later code uses the regs defined by these instructions,
5166 * compilation will fail.
5168 MONO_DELETE_INS (bb, next);
5172 MonoInst *var = ins->inst_i0;
5174 if (var->opcode == OP_VTARG_ADDR) {
5175 /* The variable contains the vtype address */
5176 values [ins->dreg] = values [var->dreg];
5177 } else if (var->opcode == OP_GSHAREDVT_LOCAL) {
5178 values [ins->dreg] = emit_gsharedvt_ldaddr (ctx, var->dreg);
5180 values [ins->dreg] = addresses [var->dreg];
5185 LLVMValueRef args [1];
5187 args [0] = convert (ctx, lhs, LLVMDoubleType ());
5188 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (lmodule, "llvm.sin.f64"), args, 1, dname);
5192 LLVMValueRef args [1];
5194 args [0] = convert (ctx, lhs, LLVMDoubleType ());
5195 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (lmodule, "llvm.cos.f64"), args, 1, dname);
5199 LLVMValueRef args [1];
5201 args [0] = convert (ctx, lhs, LLVMDoubleType ());
5202 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (lmodule, "llvm.sqrt.f64"), args, 1, dname);
5206 LLVMValueRef args [1];
5208 args [0] = convert (ctx, lhs, LLVMDoubleType ());
5209 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (lmodule, "fabs"), args, 1, dname);
5223 lhs = convert (ctx, lhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
5224 rhs = convert (ctx, rhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
5226 switch (ins->opcode) {
5229 v = LLVMBuildICmp (builder, LLVMIntSLE, lhs, rhs, "");
5233 v = LLVMBuildICmp (builder, LLVMIntSGE, lhs, rhs, "");
5237 v = LLVMBuildICmp (builder, LLVMIntULE, lhs, rhs, "");
5241 v = LLVMBuildICmp (builder, LLVMIntUGE, lhs, rhs, "");
5244 g_assert_not_reached ();
5247 values [ins->dreg] = LLVMBuildSelect (builder, v, lhs, rhs, dname);
5250 case OP_ATOMIC_EXCHANGE_I4:
5251 case OP_ATOMIC_EXCHANGE_I8: {
5252 LLVMValueRef args [2];
5255 if (ins->opcode == OP_ATOMIC_EXCHANGE_I4)
5256 t = LLVMInt32Type ();
5258 t = LLVMInt64Type ();
5260 g_assert (ins->inst_offset == 0);
5262 args [0] = convert (ctx, lhs, LLVMPointerType (t, 0));
5263 args [1] = convert (ctx, rhs, t);
5265 values [ins->dreg] = mono_llvm_build_atomic_rmw (builder, LLVM_ATOMICRMW_OP_XCHG, args [0], args [1]);
5268 case OP_ATOMIC_ADD_I4:
5269 case OP_ATOMIC_ADD_I8: {
5270 LLVMValueRef args [2];
5273 if (ins->opcode == OP_ATOMIC_ADD_I4)
5274 t = LLVMInt32Type ();
5276 t = LLVMInt64Type ();
5278 g_assert (ins->inst_offset == 0);
5280 args [0] = convert (ctx, lhs, LLVMPointerType (t, 0));
5281 args [1] = convert (ctx, rhs, t);
5282 values [ins->dreg] = LLVMBuildAdd (builder, mono_llvm_build_atomic_rmw (builder, LLVM_ATOMICRMW_OP_ADD, args [0], args [1]), args [1], dname);
5285 case OP_ATOMIC_CAS_I4:
5286 case OP_ATOMIC_CAS_I8: {
5287 LLVMValueRef args [3], val;
5290 if (ins->opcode == OP_ATOMIC_CAS_I4)
5291 t = LLVMInt32Type ();
5293 t = LLVMInt64Type ();
5295 args [0] = convert (ctx, lhs, LLVMPointerType (t, 0));
5297 args [1] = convert (ctx, values [ins->sreg3], t);
5299 args [2] = convert (ctx, values [ins->sreg2], t);
5300 val = mono_llvm_build_cmpxchg (builder, args [0], args [1], args [2]);
5301 /* cmpxchg returns a pair */
5302 values [ins->dreg] = LLVMBuildExtractValue (builder, val, 0, "");
5305 case OP_MEMORY_BARRIER: {
5306 mono_llvm_build_fence (builder, (BarrierKind) ins->backend.memory_barrier_kind);
5309 case OP_ATOMIC_LOAD_I1:
5310 case OP_ATOMIC_LOAD_I2:
5311 case OP_ATOMIC_LOAD_I4:
5312 case OP_ATOMIC_LOAD_I8:
5313 case OP_ATOMIC_LOAD_U1:
5314 case OP_ATOMIC_LOAD_U2:
5315 case OP_ATOMIC_LOAD_U4:
5316 case OP_ATOMIC_LOAD_U8:
5317 case OP_ATOMIC_LOAD_R4:
5318 case OP_ATOMIC_LOAD_R8: {
5319 set_failure (ctx, "atomic mono.load intrinsic");
5323 gboolean sext, zext;
5325 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
5326 BarrierKind barrier = (BarrierKind) ins->backend.memory_barrier_kind;
5327 LLVMValueRef index, addr;
5329 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
5334 if (ins->inst_offset != 0) {
5335 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
5336 addr = LLVMBuildGEP (builder, convert (ctx, lhs, LLVMPointerType (t, 0)), &index, 1, "");
5341 addr = convert (ctx, addr, LLVMPointerType (t, 0));
5343 values [ins->dreg] = emit_load_general (ctx, bb, &builder, size, addr, dname, is_volatile, barrier);
5346 values [ins->dreg] = LLVMBuildSExt (builder, values [ins->dreg], LLVMInt32Type (), dname);
5348 values [ins->dreg] = LLVMBuildZExt (builder, values [ins->dreg], LLVMInt32Type (), dname);
5352 case OP_ATOMIC_STORE_I1:
5353 case OP_ATOMIC_STORE_I2:
5354 case OP_ATOMIC_STORE_I4:
5355 case OP_ATOMIC_STORE_I8:
5356 case OP_ATOMIC_STORE_U1:
5357 case OP_ATOMIC_STORE_U2:
5358 case OP_ATOMIC_STORE_U4:
5359 case OP_ATOMIC_STORE_U8:
5360 case OP_ATOMIC_STORE_R4:
5361 case OP_ATOMIC_STORE_R8: {
5362 set_failure (ctx, "atomic mono.store intrinsic");
5366 gboolean sext, zext;
5368 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
5369 BarrierKind barrier = (BarrierKind) ins->backend.memory_barrier_kind;
5370 LLVMValueRef index, addr, value;
5372 if (!values [ins->inst_destbasereg]) {
5373 set_failure (ctx, "inst_destbasereg");
5377 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
5379 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
5380 addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (t, 0)), &index, 1, "");
5381 value = convert (ctx, values [ins->sreg1], t);
5383 emit_store_general (ctx, bb, &builder, size, value, addr, is_volatile, barrier);
5387 case OP_RELAXED_NOP: {
5388 #if defined(TARGET_AMD64) || defined(TARGET_X86)
5389 emit_call (ctx, bb, &builder, LLVMGetNamedFunction (ctx->lmodule, "llvm.x86.sse2.pause"), NULL, 0);
5396 #if (defined(TARGET_AMD64) || defined(TARGET_X86)) && defined(__linux__)
5398 // 257 == FS segment register
5399 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 257);
5401 // 256 == GS segment register
5402 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 256);
5405 values [ins->dreg] = LLVMBuildLoad (builder, LLVMBuildIntToPtr (builder, LLVMConstInt (IntPtrType (), ins->inst_offset, TRUE), ptrtype, ""), "");
5406 #elif defined(TARGET_AMD64) && defined(TARGET_OSX)
5407 /* See mono_amd64_emit_tls_get () */
5408 int offset = mono_amd64_get_tls_gs_offset () + (ins->inst_offset * 8);
5410 // 256 == GS segment register
5411 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 256);
5412 values [ins->dreg] = LLVMBuildLoad (builder, LLVMBuildIntToPtr (builder, LLVMConstInt (IntPtrType (), offset, TRUE), ptrtype, ""), "");
5414 set_failure (ctx, "opcode tls-get");
5420 case OP_TLS_GET_REG: {
5421 #if defined(TARGET_AMD64) && defined(TARGET_OSX)
5422 /* See emit_tls_get_reg () */
5423 // 256 == GS segment register
5424 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 256);
5425 values [ins->dreg] = LLVMBuildLoad (builder, LLVMBuildIntToPtr (builder, convert (ctx, lhs, LLVMInt32Type ()), ptrtype, ""), "");
5427 set_failure (ctx, "opcode tls-get");
5433 case OP_TLS_SET_REG: {
5434 #if defined(TARGET_AMD64) && defined(TARGET_OSX)
5435 /* See emit_tls_get_reg () */
5436 // 256 == GS segment register
5437 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 256);
5438 LLVMBuildStore (builder, convert (ctx, lhs, IntPtrType ()), LLVMBuildIntToPtr (builder, convert (ctx, rhs, LLVMInt32Type ()), ptrtype, ""));
5440 set_failure (ctx, "opcode tls-set-reg");
5450 case OP_IADD_OVF_UN:
5452 case OP_ISUB_OVF_UN:
5454 case OP_IMUL_OVF_UN:
5455 #if SIZEOF_VOID_P == 8
5457 case OP_LADD_OVF_UN:
5459 case OP_LSUB_OVF_UN:
5461 case OP_LMUL_OVF_UN:
5464 LLVMValueRef args [2], val, ovf, func;
5466 args [0] = convert (ctx, lhs, op_to_llvm_type (ins->opcode));
5467 args [1] = convert (ctx, rhs, op_to_llvm_type (ins->opcode));
5468 func = LLVMGetNamedFunction (lmodule, ovf_op_to_intrins (ins->opcode));
5470 val = LLVMBuildCall (builder, func, args, 2, "");
5471 values [ins->dreg] = LLVMBuildExtractValue (builder, val, 0, dname);
5472 ovf = LLVMBuildExtractValue (builder, val, 1, "");
5473 emit_cond_system_exception (ctx, bb, "OverflowException", ovf);
5476 builder = ctx->builder;
5482 * We currently model them using arrays. Promotion to local vregs is
5483 * disabled for them in mono_handle_global_vregs () in the LLVM case,
5484 * so we always have an entry in cfg->varinfo for them.
5485 * FIXME: Is this needed ?
5488 MonoClass *klass = ins->klass;
5489 LLVMValueRef args [5];
5493 set_failure (ctx, "!klass");
5497 if (!addresses [ins->dreg])
5498 addresses [ins->dreg] = build_alloca (ctx, &klass->byval_arg);
5499 args [0] = LLVMBuildBitCast (builder, addresses [ins->dreg], LLVMPointerType (LLVMInt8Type (), 0), "");
5500 args [1] = LLVMConstInt (LLVMInt8Type (), 0, FALSE);
5501 args [2] = LLVMConstInt (LLVMInt32Type (), mono_class_value_size (klass, NULL), FALSE);
5503 args [3] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
5504 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
5505 LLVMBuildCall (builder, LLVMGetNamedFunction (lmodule, memset_func_name), args, memset_param_count, "");
5508 case OP_DUMMY_VZERO:
5511 case OP_STOREV_MEMBASE:
5512 case OP_LOADV_MEMBASE:
5514 MonoClass *klass = ins->klass;
5515 LLVMValueRef src = NULL, dst, args [5];
5516 gboolean done = FALSE;
5520 set_failure (ctx, "!klass");
5524 if (mini_is_gsharedvt_klass (klass)) {
5526 set_failure (ctx, "gsharedvt");
5530 switch (ins->opcode) {
5531 case OP_STOREV_MEMBASE:
5532 if (cfg->gen_write_barriers && klass->has_references && ins->inst_destbasereg != cfg->frame_reg &&
5533 LLVMGetInstructionOpcode (values [ins->inst_destbasereg]) != LLVMAlloca) {
5534 /* Decomposed earlier */
5535 g_assert_not_reached ();
5538 if (!addresses [ins->sreg1]) {
5540 g_assert (values [ins->sreg1]);
5541 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));
5542 LLVMBuildStore (builder, values [ins->sreg1], dst);
5545 src = LLVMBuildBitCast (builder, addresses [ins->sreg1], LLVMPointerType (LLVMInt8Type (), 0), "");
5546 dst = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_destbasereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (LLVMInt8Type (), 0));
5549 case OP_LOADV_MEMBASE:
5550 if (!addresses [ins->dreg])
5551 addresses [ins->dreg] = build_alloca (ctx, &klass->byval_arg);
5552 src = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_basereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (LLVMInt8Type (), 0));
5553 dst = LLVMBuildBitCast (builder, addresses [ins->dreg], LLVMPointerType (LLVMInt8Type (), 0), "");
5556 if (!addresses [ins->sreg1])
5557 addresses [ins->sreg1] = build_alloca (ctx, &klass->byval_arg);
5558 if (!addresses [ins->dreg])
5559 addresses [ins->dreg] = build_alloca (ctx, &klass->byval_arg);
5560 src = LLVMBuildBitCast (builder, addresses [ins->sreg1], LLVMPointerType (LLVMInt8Type (), 0), "");
5561 dst = LLVMBuildBitCast (builder, addresses [ins->dreg], LLVMPointerType (LLVMInt8Type (), 0), "");
5564 g_assert_not_reached ();
5574 args [2] = LLVMConstInt (LLVMInt32Type (), mono_class_value_size (klass, NULL), FALSE);
5575 args [3] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
5577 args [3] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
5578 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
5579 LLVMBuildCall (builder, LLVMGetNamedFunction (lmodule, memcpy_func_name), args, memcpy_param_count, "");
5582 case OP_LLVM_OUTARG_VT: {
5583 LLVMArgInfo *ainfo = (LLVMArgInfo*)ins->inst_p0;
5584 MonoType *t = mini_get_underlying_type (ins->inst_vtype);
5586 if (ainfo->storage == LLVMArgGsharedvtVariable) {
5587 MonoInst *var = get_vreg_to_inst (cfg, ins->sreg1);
5589 if (var && var->opcode == OP_GSHAREDVT_LOCAL) {
5590 addresses [ins->dreg] = convert (ctx, emit_gsharedvt_ldaddr (ctx, var->dreg), LLVMPointerType (IntPtrType (), 0));
5592 g_assert (addresses [ins->sreg1]);
5593 addresses [ins->dreg] = addresses [ins->sreg1];
5595 } else if (ainfo->storage == LLVMArgGsharedvtFixed) {
5596 if (!addresses [ins->sreg1]) {
5597 addresses [ins->sreg1] = build_alloca (ctx, t);
5598 g_assert (values [ins->sreg1]);
5600 LLVMBuildStore (builder, convert (ctx, values [ins->sreg1], LLVMGetElementType (LLVMTypeOf (addresses [ins->sreg1]))), addresses [ins->sreg1]);
5601 addresses [ins->dreg] = addresses [ins->sreg1];
5603 if (!addresses [ins->sreg1]) {
5604 addresses [ins->sreg1] = build_alloca (ctx, t);
5605 g_assert (values [ins->sreg1]);
5606 LLVMBuildStore (builder, convert (ctx, values [ins->sreg1], type_to_llvm_type (ctx, t)), addresses [ins->sreg1]);
5608 addresses [ins->dreg] = addresses [ins->sreg1];
5616 #if defined(TARGET_X86) || defined(TARGET_AMD64)
5618 values [ins->dreg] = LLVMConstNull (type_to_llvm_type (ctx, &ins->klass->byval_arg));
5621 case OP_LOADX_MEMBASE: {
5622 LLVMTypeRef t = type_to_llvm_type (ctx, &ins->klass->byval_arg);
5625 src = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_basereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (t, 0));
5626 values [ins->dreg] = mono_llvm_build_aligned_load (builder, src, "", FALSE, 1);
5629 case OP_STOREX_MEMBASE: {
5630 LLVMTypeRef t = LLVMTypeOf (values [ins->sreg1]);
5633 dest = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_destbasereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (t, 0));
5634 mono_llvm_build_aligned_store (builder, values [ins->sreg1], dest, FALSE, 1);
5641 values [ins->dreg] = LLVMBuildAdd (builder, lhs, rhs, "");
5645 values [ins->dreg] = LLVMBuildFAdd (builder, lhs, rhs, "");
5651 values [ins->dreg] = LLVMBuildSub (builder, lhs, rhs, "");
5655 values [ins->dreg] = LLVMBuildFSub (builder, lhs, rhs, "");
5659 values [ins->dreg] = LLVMBuildFMul (builder, lhs, rhs, "");
5663 values [ins->dreg] = LLVMBuildFDiv (builder, lhs, rhs, "");
5666 values [ins->dreg] = LLVMBuildAnd (builder, lhs, rhs, "");
5669 values [ins->dreg] = LLVMBuildOr (builder, lhs, rhs, "");
5672 values [ins->dreg] = LLVMBuildXor (builder, lhs, rhs, "");
5676 values [ins->dreg] = LLVMBuildMul (builder, lhs, rhs, "");
5687 LLVMValueRef v = NULL;
5689 switch (ins->opcode) {
5694 t = LLVMVectorType (LLVMInt32Type (), 4);
5695 rt = LLVMVectorType (LLVMFloatType (), 4);
5701 t = LLVMVectorType (LLVMInt64Type (), 2);
5702 rt = LLVMVectorType (LLVMDoubleType (), 2);
5705 t = LLVMInt32Type ();
5706 rt = LLVMInt32Type ();
5707 g_assert_not_reached ();
5710 lhs = LLVMBuildBitCast (builder, lhs, t, "");
5711 rhs = LLVMBuildBitCast (builder, rhs, t, "");
5712 switch (ins->opcode) {
5715 v = LLVMBuildAnd (builder, lhs, rhs, "");
5719 v = LLVMBuildOr (builder, lhs, rhs, "");
5723 v = LLVMBuildXor (builder, lhs, rhs, "");
5727 v = LLVMBuildAnd (builder, rhs, LLVMBuildNot (builder, lhs, ""), "");
5730 values [ins->dreg] = LLVMBuildBitCast (builder, v, rt, "");
5754 case OP_PADDB_SAT_UN:
5755 case OP_PADDW_SAT_UN:
5756 case OP_PSUBB_SAT_UN:
5757 case OP_PSUBW_SAT_UN:
5765 case OP_PMULW_HIGH_UN: {
5766 LLVMValueRef args [2];
5771 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (lmodule, simd_op_to_intrins (ins->opcode)), args, 2, dname);
5778 values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildICmp (builder, LLVMIntEQ, lhs, rhs, ""), LLVMTypeOf (lhs), "");
5782 values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildICmp (builder, LLVMIntSGT, lhs, rhs, ""), LLVMTypeOf (lhs), "");
5790 case OP_EXTRACTX_U2:
5792 case OP_EXTRACT_U1: {
5794 gboolean zext = FALSE;
5796 t = simd_op_to_llvm_type (ins->opcode);
5798 switch (ins->opcode) {
5806 case OP_EXTRACTX_U2:
5811 t = LLVMInt32Type ();
5812 g_assert_not_reached ();
5815 lhs = LLVMBuildBitCast (builder, lhs, t, "");
5816 values [ins->dreg] = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), "");
5818 values [ins->dreg] = LLVMBuildZExt (builder, values [ins->dreg], LLVMInt32Type (), "");
5827 case OP_EXPAND_R8: {
5828 LLVMTypeRef t = simd_op_to_llvm_type (ins->opcode);
5829 LLVMValueRef mask [16], v;
5832 for (i = 0; i < 16; ++i)
5833 mask [i] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
5835 v = convert (ctx, values [ins->sreg1], LLVMGetElementType (t));
5837 values [ins->dreg] = LLVMBuildInsertElement (builder, LLVMConstNull (t), v, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
5838 values [ins->dreg] = LLVMBuildShuffleVector (builder, values [ins->dreg], LLVMGetUndef (t), LLVMConstVector (mask, LLVMGetVectorSize (t)), "");
5843 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt8Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
5846 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt16Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
5849 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt32Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
5852 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt64Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
5855 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMFloatType ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
5858 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMDoubleType ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
5869 case OP_EXTRACT_MASK:
5876 v = convert (ctx, values [ins->sreg1], simd_op_to_llvm_type (ins->opcode));
5878 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (lmodule, simd_op_to_intrins (ins->opcode)), &v, 1, dname);
5884 LLVMValueRef args [3];
5888 args [2] = LLVMConstInt (LLVMInt8Type (), ins->inst_c0, FALSE);
5890 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (lmodule, simd_op_to_intrins (ins->opcode)), args, 3, dname);
5895 /* This is only used for implementing shifts by non-immediate */
5896 values [ins->dreg] = lhs;
5907 LLVMValueRef args [3];
5910 args [1] = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
5912 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (lmodule, simd_op_to_intrins (ins->opcode)), args, 2, dname);
5923 case OP_PSHLQ_REG: {
5924 LLVMValueRef args [3];
5927 args [1] = values [ins->sreg2];
5929 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (lmodule, simd_op_to_intrins (ins->opcode)), args, 2, dname);
5936 case OP_PSHUFLEW_LOW:
5937 case OP_PSHUFLEW_HIGH: {
5939 LLVMValueRef v1 = NULL, v2 = NULL, mask_values [16];
5940 int i, mask_size = 0;
5941 int imask = ins->inst_c0;
5943 /* Convert the x86 shuffle mask to LLVM's */
5944 switch (ins->opcode) {
5947 mask [0] = ((imask >> 0) & 3);
5948 mask [1] = ((imask >> 2) & 3);
5949 mask [2] = ((imask >> 4) & 3) + 4;
5950 mask [3] = ((imask >> 6) & 3) + 4;
5951 v1 = values [ins->sreg1];
5952 v2 = values [ins->sreg2];
5956 mask [0] = ((imask >> 0) & 1);
5957 mask [1] = ((imask >> 1) & 1) + 2;
5958 v1 = values [ins->sreg1];
5959 v2 = values [ins->sreg2];
5961 case OP_PSHUFLEW_LOW:
5963 mask [0] = ((imask >> 0) & 3);
5964 mask [1] = ((imask >> 2) & 3);
5965 mask [2] = ((imask >> 4) & 3);
5966 mask [3] = ((imask >> 6) & 3);
5971 v1 = values [ins->sreg1];
5972 v2 = LLVMGetUndef (LLVMTypeOf (v1));
5974 case OP_PSHUFLEW_HIGH:
5980 mask [4] = 4 + ((imask >> 0) & 3);
5981 mask [5] = 4 + ((imask >> 2) & 3);
5982 mask [6] = 4 + ((imask >> 4) & 3);
5983 mask [7] = 4 + ((imask >> 6) & 3);
5984 v1 = values [ins->sreg1];
5985 v2 = LLVMGetUndef (LLVMTypeOf (v1));
5989 mask [0] = ((imask >> 0) & 3);
5990 mask [1] = ((imask >> 2) & 3);
5991 mask [2] = ((imask >> 4) & 3);
5992 mask [3] = ((imask >> 6) & 3);
5993 v1 = values [ins->sreg1];
5994 v2 = LLVMGetUndef (LLVMTypeOf (v1));
5997 g_assert_not_reached ();
5999 for (i = 0; i < mask_size; ++i)
6000 mask_values [i] = LLVMConstInt (LLVMInt32Type (), mask [i], FALSE);
6002 values [ins->dreg] =
6003 LLVMBuildShuffleVector (builder, v1, v2,
6004 LLVMConstVector (mask_values, mask_size), dname);
6008 case OP_UNPACK_LOWB:
6009 case OP_UNPACK_LOWW:
6010 case OP_UNPACK_LOWD:
6011 case OP_UNPACK_LOWQ:
6012 case OP_UNPACK_LOWPS:
6013 case OP_UNPACK_LOWPD:
6014 case OP_UNPACK_HIGHB:
6015 case OP_UNPACK_HIGHW:
6016 case OP_UNPACK_HIGHD:
6017 case OP_UNPACK_HIGHQ:
6018 case OP_UNPACK_HIGHPS:
6019 case OP_UNPACK_HIGHPD: {
6021 LLVMValueRef mask_values [16];
6022 int i, mask_size = 0;
6023 gboolean low = FALSE;
6025 switch (ins->opcode) {
6026 case OP_UNPACK_LOWB:
6030 case OP_UNPACK_LOWW:
6034 case OP_UNPACK_LOWD:
6035 case OP_UNPACK_LOWPS:
6039 case OP_UNPACK_LOWQ:
6040 case OP_UNPACK_LOWPD:
6044 case OP_UNPACK_HIGHB:
6047 case OP_UNPACK_HIGHW:
6050 case OP_UNPACK_HIGHD:
6051 case OP_UNPACK_HIGHPS:
6054 case OP_UNPACK_HIGHQ:
6055 case OP_UNPACK_HIGHPD:
6059 g_assert_not_reached ();
6063 for (i = 0; i < (mask_size / 2); ++i) {
6065 mask [(i * 2) + 1] = mask_size + i;
6068 for (i = 0; i < (mask_size / 2); ++i) {
6069 mask [(i * 2)] = (mask_size / 2) + i;
6070 mask [(i * 2) + 1] = mask_size + (mask_size / 2) + i;
6074 for (i = 0; i < mask_size; ++i)
6075 mask_values [i] = LLVMConstInt (LLVMInt32Type (), mask [i], FALSE);
6077 values [ins->dreg] =
6078 LLVMBuildShuffleVector (builder, values [ins->sreg1], values [ins->sreg2],
6079 LLVMConstVector (mask_values, mask_size), dname);
6084 LLVMTypeRef t = simd_op_to_llvm_type (ins->opcode);
6085 LLVMValueRef v, val;
6087 v = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
6088 val = LLVMConstNull (t);
6089 val = LLVMBuildInsertElement (builder, val, v, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
6090 val = LLVMBuildInsertElement (builder, val, v, LLVMConstInt (LLVMInt32Type (), 1, FALSE), dname);
6092 values [ins->dreg] = val;
6096 case OP_DUPPS_HIGH: {
6097 LLVMTypeRef t = simd_op_to_llvm_type (ins->opcode);
6098 LLVMValueRef v1, v2, val;
6101 if (ins->opcode == OP_DUPPS_LOW) {
6102 v1 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
6103 v2 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 2, FALSE), "");
6105 v1 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 1, FALSE), "");
6106 v2 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 3, FALSE), "");
6108 val = LLVMConstNull (t);
6109 val = LLVMBuildInsertElement (builder, val, v1, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
6110 val = LLVMBuildInsertElement (builder, val, v1, LLVMConstInt (LLVMInt32Type (), 1, FALSE), "");
6111 val = LLVMBuildInsertElement (builder, val, v2, LLVMConstInt (LLVMInt32Type (), 2, FALSE), "");
6112 val = LLVMBuildInsertElement (builder, val, v2, LLVMConstInt (LLVMInt32Type (), 3, FALSE), "");
6114 values [ins->dreg] = val;
6124 * EXCEPTION HANDLING
6126 case OP_IMPLICIT_EXCEPTION:
6127 /* This marks a place where an implicit exception can happen */
6128 if (bb->region != -1)
6129 set_failure (ctx, "implicit-exception");
6133 gboolean rethrow = (ins->opcode == OP_RETHROW);
6134 if (ctx->llvm_only) {
6135 emit_llvmonly_throw (ctx, bb, rethrow, lhs);
6136 has_terminator = TRUE;
6137 ctx->unreachable [bb->block_num] = TRUE;
6139 emit_throw (ctx, bb, rethrow, lhs);
6140 builder = ctx->builder;
6144 case OP_CALL_HANDLER: {
6146 * We don't 'call' handlers, but instead simply branch to them.
6147 * The code generated by ENDFINALLY will branch back to us.
6149 LLVMBasicBlockRef noex_bb;
6151 BBInfo *info = &bblocks [ins->inst_target_bb->block_num];
6153 bb_list = info->call_handler_return_bbs;
6156 * Set the indicator variable for the finally clause.
6158 lhs = info->finally_ind;
6160 LLVMBuildStore (builder, LLVMConstInt (LLVMInt32Type (), g_slist_length (bb_list) + 1, FALSE), lhs);
6162 /* Branch to the finally clause */
6163 LLVMBuildBr (builder, info->call_handler_target_bb);
6165 noex_bb = gen_bb (ctx, "CALL_HANDLER_CONT_BB");
6166 info->call_handler_return_bbs = g_slist_append_mempool (cfg->mempool, info->call_handler_return_bbs, noex_bb);
6168 builder = ctx->builder = create_builder (ctx);
6169 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
6171 bblocks [bb->block_num].end_bblock = noex_bb;
6174 case OP_START_HANDLER: {
6177 case OP_ENDFINALLY: {
6178 LLVMBasicBlockRef resume_bb;
6179 MonoBasicBlock *handler_bb;
6180 LLVMValueRef val, switch_ins, callee;
6184 handler_bb = (MonoBasicBlock*)g_hash_table_lookup (ctx->region_to_handler, GUINT_TO_POINTER (mono_get_block_region_notry (cfg, bb->region)));
6185 g_assert (handler_bb);
6186 info = &bblocks [handler_bb->block_num];
6187 lhs = info->finally_ind;
6190 bb_list = info->call_handler_return_bbs;
6192 resume_bb = gen_bb (ctx, "ENDFINALLY_RESUME_BB");
6194 /* Load the finally variable */
6195 val = LLVMBuildLoad (builder, lhs, "");
6197 /* Reset the variable */
6198 LLVMBuildStore (builder, LLVMConstInt (LLVMInt32Type (), 0, FALSE), lhs);
6200 /* Branch to either resume_bb, or to the bblocks in bb_list */
6201 switch_ins = LLVMBuildSwitch (builder, val, resume_bb, g_slist_length (bb_list));
6203 * The other targets are added at the end to handle OP_CALL_HANDLER
6204 * opcodes processed later.
6206 info->endfinally_switch_ins_list = g_slist_append_mempool (cfg->mempool, info->endfinally_switch_ins_list, switch_ins);
6208 builder = ctx->builder = create_builder (ctx);
6209 LLVMPositionBuilderAtEnd (ctx->builder, resume_bb);
6211 if (ctx->llvm_only) {
6212 emit_resume_eh (ctx, bb);
6214 if (ctx->cfg->compile_aot) {
6215 callee = get_callee (ctx, LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE), MONO_PATCH_INFO_INTERNAL_METHOD, "llvm_resume_unwind_trampoline");
6217 callee = LLVMGetNamedFunction (lmodule, "llvm_resume_unwind_trampoline");
6219 LLVMBuildCall (builder, callee, NULL, 0, "");
6220 LLVMBuildUnreachable (builder);
6223 has_terminator = TRUE;
6226 case OP_IL_SEQ_POINT:
6231 sprintf (reason, "opcode %s", mono_inst_name (ins->opcode));
6232 set_failure (ctx, reason);
6240 /* Convert the value to the type required by phi nodes */
6241 if (spec [MONO_INST_DEST] != ' ' && !MONO_IS_STORE_MEMBASE (ins) && ctx->vreg_types [ins->dreg]) {
6242 if (!values [ins->dreg])
6244 values [ins->dreg] = addresses [ins->dreg];
6246 values [ins->dreg] = convert (ctx, values [ins->dreg], ctx->vreg_types [ins->dreg]);
6249 /* Add stores for volatile variables */
6250 if (spec [MONO_INST_DEST] != ' ' && spec [MONO_INST_DEST] != 'v' && !MONO_IS_STORE_MEMBASE (ins))
6251 emit_volatile_store (ctx, ins->dreg);
6257 if (!has_terminator && bb->next_bb && (bb == cfg->bb_entry || bb->in_count > 0)) {
6258 LLVMBuildBr (builder, get_bb (ctx, bb->next_bb));
6261 if (bb == cfg->bb_exit && sig->ret->type == MONO_TYPE_VOID) {
6262 emit_dbg_loc (ctx, builder, cfg->header->code + cfg->header->code_size - 1);
6263 LLVMBuildRetVoid (builder);
6266 if (bb == cfg->bb_entry)
6267 ctx->last_alloca = LLVMGetLastInstruction (get_bb (ctx, cfg->bb_entry));
6271 * mono_llvm_check_method_supported:
6273 * Do some quick checks to decide whenever cfg->method can be compiled by LLVM, to avoid
6274 * compiling a method twice.
6277 mono_llvm_check_method_supported (MonoCompile *cfg)
6284 if (cfg->method->save_lmf) {
6285 cfg->exception_message = g_strdup ("lmf");
6286 cfg->disable_llvm = TRUE;
6288 if (cfg->disable_llvm)
6292 * Nested clauses where one of the clauses is a finally clause is
6293 * not supported, because LLVM can't figure out the control flow,
6294 * probably because we resume exception handling by calling our
6295 * own function instead of using the 'resume' llvm instruction.
6297 for (i = 0; i < cfg->header->num_clauses; ++i) {
6298 for (j = 0; j < cfg->header->num_clauses; ++j) {
6299 MonoExceptionClause *clause1 = &cfg->header->clauses [i];
6300 MonoExceptionClause *clause2 = &cfg->header->clauses [j];
6302 // FIXME: Nested try clauses fail in some cases too, i.e. #37273
6303 if (i != j && clause1->try_offset >= clause2->try_offset && clause1->handler_offset <= clause2->handler_offset) {
6304 //(clause1->flags == MONO_EXCEPTION_CLAUSE_FINALLY || clause2->flags == MONO_EXCEPTION_CLAUSE_FINALLY)) {
6305 cfg->exception_message = g_strdup ("nested clauses");
6306 cfg->disable_llvm = TRUE;
6311 if (cfg->disable_llvm)
6315 if (cfg->method->dynamic) {
6316 cfg->exception_message = g_strdup ("dynamic.");
6317 cfg->disable_llvm = TRUE;
6319 if (cfg->disable_llvm)
6323 static LLVMCallInfo*
6324 get_llvm_call_info (MonoCompile *cfg, MonoMethodSignature *sig)
6326 LLVMCallInfo *linfo;
6329 if (cfg->gsharedvt && cfg->llvm_only && mini_is_gsharedvt_variable_signature (sig)) {
6333 * Gsharedvt methods have the following calling convention:
6334 * - all arguments are passed by ref, even non generic ones
6335 * - the return value is returned by ref too, using a vret
6336 * argument passed after 'this'.
6338 n = sig->param_count + sig->hasthis;
6339 linfo = (LLVMCallInfo*)mono_mempool_alloc0 (cfg->mempool, sizeof (LLVMCallInfo) + (sizeof (LLVMArgInfo) * n));
6343 linfo->args [pindex ++].storage = LLVMArgNormal;
6345 if (sig->ret->type != MONO_TYPE_VOID) {
6346 if (mini_is_gsharedvt_variable_type (sig->ret))
6347 linfo->ret.storage = LLVMArgGsharedvtVariable;
6348 else if (mini_type_is_vtype (sig->ret))
6349 linfo->ret.storage = LLVMArgGsharedvtFixedVtype;
6351 linfo->ret.storage = LLVMArgGsharedvtFixed;
6352 linfo->vret_arg_index = pindex;
6354 linfo->ret.storage = LLVMArgNone;
6357 for (i = 0; i < sig->param_count; ++i) {
6358 if (sig->params [i]->byref)
6359 linfo->args [pindex].storage = LLVMArgNormal;
6360 else if (mini_is_gsharedvt_variable_type (sig->params [i]))
6361 linfo->args [pindex].storage = LLVMArgGsharedvtVariable;
6362 else if (mini_type_is_vtype (sig->params [i]))
6363 linfo->args [pindex].storage = LLVMArgGsharedvtFixedVtype;
6365 linfo->args [pindex].storage = LLVMArgGsharedvtFixed;
6366 linfo->args [pindex].type = sig->params [i];
6373 linfo = mono_arch_get_llvm_call_info (cfg, sig);
6374 for (i = 0; i < sig->param_count; ++i)
6375 linfo->args [i + sig->hasthis].type = sig->params [i];
6381 emit_method_inner (EmitContext *ctx);
6384 free_ctx (EmitContext *ctx)
6388 g_free (ctx->values);
6389 g_free (ctx->addresses);
6390 g_free (ctx->vreg_types);
6391 g_free (ctx->vreg_cli_types);
6392 g_free (ctx->is_dead);
6393 g_free (ctx->unreachable);
6394 g_ptr_array_free (ctx->phi_values, TRUE);
6395 g_free (ctx->bblocks);
6396 g_hash_table_destroy (ctx->region_to_handler);
6397 g_hash_table_destroy (ctx->clause_to_handler);
6398 g_free (ctx->method_name);
6399 g_ptr_array_free (ctx->bblock_list, TRUE);
6401 for (l = ctx->builders; l; l = l->next) {
6402 LLVMBuilderRef builder = (LLVMBuilderRef)l->data;
6403 LLVMDisposeBuilder (builder);
6410 * mono_llvm_emit_method:
6412 * Emit LLVM IL from the mono IL, and compile it to native code using LLVM.
6415 mono_llvm_emit_method (MonoCompile *cfg)
6419 gboolean is_linkonce = FALSE;
6422 /* The code below might acquire the loader lock, so use it for global locking */
6423 mono_loader_lock ();
6425 /* Used to communicate with the callbacks */
6426 mono_native_tls_set_value (current_cfg_tls_id, cfg);
6428 ctx = g_new0 (EmitContext, 1);
6430 ctx->mempool = cfg->mempool;
6433 * This maps vregs to the LLVM instruction defining them
6435 ctx->values = g_new0 (LLVMValueRef, cfg->next_vreg);
6437 * This maps vregs for volatile variables to the LLVM instruction defining their
6440 ctx->addresses = g_new0 (LLVMValueRef, cfg->next_vreg);
6441 ctx->vreg_types = g_new0 (LLVMTypeRef, cfg->next_vreg);
6442 ctx->vreg_cli_types = g_new0 (MonoType*, cfg->next_vreg);
6443 ctx->phi_values = g_ptr_array_sized_new (256);
6445 * This signals whenever the vreg was defined by a phi node with no input vars
6446 * (i.e. all its input bblocks end with NOT_REACHABLE).
6448 ctx->is_dead = g_new0 (gboolean, cfg->next_vreg);
6449 /* Whenever the bblock is unreachable */
6450 ctx->unreachable = g_new0 (gboolean, cfg->max_block_num);
6451 ctx->bblock_list = g_ptr_array_sized_new (256);
6453 ctx->region_to_handler = g_hash_table_new (NULL, NULL);
6454 ctx->clause_to_handler = g_hash_table_new (NULL, NULL);
6455 ctx->method_to_callers = g_hash_table_new (NULL, NULL);
6456 if (cfg->compile_aot) {
6457 ctx->module = &aot_module;
6461 * Allow the linker to discard duplicate copies of wrappers, generic instances etc. by using the 'linkonce'
6462 * linkage for them. This requires the following:
6463 * - the method needs to have a unique mangled name
6464 * - llvmonly mode, since the code in aot-runtime.c would initialize got slots in the wrong aot image etc.
6466 is_linkonce = ctx->module->llvm_only && ctx->module->static_link && mono_aot_is_linkonce_method (cfg->method);
6468 method_name = mono_aot_get_mangled_method_name (cfg->method);
6470 is_linkonce = FALSE;
6473 printf ("%s %s\n", mono_method_full_name (cfg->method, 1), method_name);
6475 printf ("%s\n", mono_method_full_name (cfg->method, 1));
6479 method_name = mono_aot_get_method_name (cfg);
6480 cfg->llvm_method_name = g_strdup (method_name);
6482 init_jit_module (cfg->domain);
6483 ctx->module = (MonoLLVMModule*)domain_jit_info (cfg->domain)->llvm_module;
6484 method_name = mono_method_full_name (cfg->method, TRUE);
6486 ctx->method_name = method_name;
6487 ctx->is_linkonce = is_linkonce;
6489 ctx->lmodule = ctx->module->lmodule;
6490 ctx->llvm_only = ctx->module->llvm_only;
6492 emit_method_inner (ctx);
6494 if (!ctx_ok (ctx)) {
6496 /* Need to add unused phi nodes as they can be referenced by other values */
6497 LLVMBasicBlockRef phi_bb = LLVMAppendBasicBlock (ctx->lmethod, "PHI_BB");
6498 LLVMBuilderRef builder;
6500 builder = create_builder (ctx);
6501 LLVMPositionBuilderAtEnd (builder, phi_bb);
6503 for (i = 0; i < ctx->phi_values->len; ++i) {
6504 LLVMValueRef v = (LLVMValueRef)g_ptr_array_index (ctx->phi_values, i);
6505 if (LLVMGetInstructionParent (v) == NULL)
6506 LLVMInsertIntoBuilder (builder, v);
6509 LLVMDeleteFunction (ctx->lmethod);
6515 mono_native_tls_set_value (current_cfg_tls_id, NULL);
6517 mono_loader_unlock ();
6521 emit_method_inner (EmitContext *ctx)
6523 MonoCompile *cfg = ctx->cfg;
6524 MonoMethodSignature *sig;
6526 LLVMTypeRef method_type;
6527 LLVMValueRef method = NULL;
6528 LLVMValueRef *values = ctx->values;
6529 int i, max_block_num, bb_index;
6530 gboolean last = FALSE;
6531 LLVMCallInfo *linfo;
6532 LLVMModuleRef lmodule = ctx->lmodule;
6534 GPtrArray *bblock_list = ctx->bblock_list;
6535 MonoMethodHeader *header;
6536 MonoExceptionClause *clause;
6539 if (cfg->gsharedvt && !cfg->llvm_only) {
6540 set_failure (ctx, "gsharedvt");
6546 static int count = 0;
6549 if (g_getenv ("LLVM_COUNT")) {
6550 if (count == atoi (g_getenv ("LLVM_COUNT"))) {
6551 printf ("LAST: %s\n", mono_method_full_name (cfg->method, TRUE));
6555 if (count > atoi (g_getenv ("LLVM_COUNT"))) {
6556 set_failure (ctx, "count");
6563 sig = mono_method_signature (cfg->method);
6566 linfo = get_llvm_call_info (cfg, sig);
6572 linfo->rgctx_arg = TRUE;
6573 ctx->method_type = method_type = sig_to_llvm_sig_full (ctx, sig, linfo);
6577 method = LLVMAddFunction (lmodule, ctx->method_name, method_type);
6578 ctx->lmethod = method;
6580 if (!cfg->llvm_only)
6581 LLVMSetFunctionCallConv (method, LLVMMono1CallConv);
6582 LLVMSetLinkage (method, LLVMPrivateLinkage);
6584 LLVMAddFunctionAttr (method, LLVMUWTable);
6586 if (cfg->compile_aot) {
6587 LLVMSetLinkage (method, LLVMInternalLinkage);
6588 if (ctx->module->external_symbols) {
6589 LLVMSetLinkage (method, LLVMExternalLinkage);
6590 LLVMSetVisibility (method, LLVMHiddenVisibility);
6592 if (ctx->is_linkonce) {
6593 LLVMSetLinkage (method, LLVMLinkOnceAnyLinkage);
6594 LLVMSetVisibility (method, LLVMDefaultVisibility);
6597 LLVMSetLinkage (method, LLVMPrivateLinkage);
6600 if (cfg->method->save_lmf && !cfg->llvm_only) {
6601 set_failure (ctx, "lmf");
6605 if (sig->pinvoke && cfg->method->wrapper_type != MONO_WRAPPER_RUNTIME_INVOKE && !cfg->llvm_only) {
6606 set_failure (ctx, "pinvoke signature");
6610 header = cfg->header;
6611 for (i = 0; i < header->num_clauses; ++i) {
6612 clause = &header->clauses [i];
6613 if (clause->flags != MONO_EXCEPTION_CLAUSE_FINALLY && clause->flags != MONO_EXCEPTION_CLAUSE_NONE) {
6614 set_failure (ctx, "non-finally/catch clause.");
6618 if (header->num_clauses || (cfg->method->iflags & METHOD_IMPL_ATTRIBUTE_NOINLINING) || cfg->no_inline)
6619 /* We can't handle inlined methods with clauses */
6620 LLVMAddFunctionAttr (method, LLVMNoInlineAttribute);
6622 if (linfo->rgctx_arg) {
6623 ctx->rgctx_arg = LLVMGetParam (method, linfo->rgctx_arg_pindex);
6624 ctx->rgctx_arg_pindex = linfo->rgctx_arg_pindex;
6626 * We mark the rgctx parameter with the inreg attribute, which is mapped to
6627 * MONO_ARCH_RGCTX_REG in the Mono calling convention in llvm, i.e.
6628 * CC_X86_64_Mono in X86CallingConv.td.
6630 if (!ctx->llvm_only)
6631 LLVMAddAttribute (ctx->rgctx_arg, LLVMInRegAttribute);
6632 LLVMSetValueName (ctx->rgctx_arg, "rgctx");
6634 ctx->rgctx_arg_pindex = -1;
6636 if (cfg->vret_addr) {
6637 values [cfg->vret_addr->dreg] = LLVMGetParam (method, linfo->vret_arg_pindex);
6638 LLVMSetValueName (values [cfg->vret_addr->dreg], "vret");
6639 if (linfo->ret.storage == LLVMArgVtypeByRef) {
6640 LLVMAddAttribute (LLVMGetParam (method, linfo->vret_arg_pindex), LLVMStructRetAttribute);
6641 LLVMAddAttribute (LLVMGetParam (method, linfo->vret_arg_pindex), LLVMNoAliasAttribute);
6646 ctx->this_arg_pindex = linfo->this_arg_pindex;
6647 ctx->this_arg = LLVMGetParam (method, linfo->this_arg_pindex);
6648 values [cfg->args [0]->dreg] = ctx->this_arg;
6649 LLVMSetValueName (values [cfg->args [0]->dreg], "this");
6652 names = g_new (char *, sig->param_count);
6653 mono_method_get_param_names (cfg->method, (const char **) names);
6655 for (i = 0; i < sig->param_count; ++i) {
6656 LLVMArgInfo *ainfo = &linfo->args [i + sig->hasthis];
6658 int pindex = ainfo->pindex + ainfo->ndummy_fpargs;
6661 for (j = 0; j < ainfo->ndummy_fpargs; ++j) {
6662 name = g_strdup_printf ("dummy_%d_%d", i, j);
6663 LLVMSetValueName (LLVMGetParam (method, ainfo->pindex + j), name);
6667 values [cfg->args [i + sig->hasthis]->dreg] = LLVMGetParam (method, pindex);
6668 if (ainfo->storage == LLVMArgGsharedvtFixed || ainfo->storage == LLVMArgGsharedvtFixedVtype) {
6669 if (names [i] && names [i][0] != '\0')
6670 name = g_strdup_printf ("p_arg_%s", names [i]);
6672 name = g_strdup_printf ("p_arg_%d", i);
6674 if (names [i] && names [i][0] != '\0')
6675 name = g_strdup_printf ("arg_%s", names [i]);
6677 name = g_strdup_printf ("arg_%d", i);
6679 LLVMSetValueName (values [cfg->args [i + sig->hasthis]->dreg], name);
6681 if (ainfo->storage == LLVMArgVtypeByVal)
6682 LLVMAddAttribute (LLVMGetParam (method, pindex), LLVMByValAttribute);
6684 if (ainfo->storage == LLVMArgVtypeByRef) {
6686 cfg->args [i + sig->hasthis]->opcode = OP_VTARG_ADDR;
6691 if (ctx->module->emit_dwarf && cfg->compile_aot && mono_debug_enabled ()) {
6692 ctx->minfo = mono_debug_lookup_method (cfg->method);
6693 ctx->dbg_md = emit_dbg_subprogram (ctx, cfg, method, ctx->method_name);
6697 for (bb = cfg->bb_entry; bb; bb = bb->next_bb)
6698 max_block_num = MAX (max_block_num, bb->block_num);
6699 ctx->bblocks = bblocks = g_new0 (BBInfo, max_block_num + 1);
6701 /* Add branches between non-consecutive bblocks */
6702 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
6703 if (bb->last_ins && MONO_IS_COND_BRANCH_OP (bb->last_ins) &&
6704 bb->next_bb != bb->last_ins->inst_false_bb) {
6706 MonoInst *inst = (MonoInst*)mono_mempool_alloc0 (cfg->mempool, sizeof (MonoInst));
6707 inst->opcode = OP_BR;
6708 inst->inst_target_bb = bb->last_ins->inst_false_bb;
6709 mono_bblock_add_inst (bb, inst);
6714 * The INDIRECT flag added by OP_LDADDR inhibits optimizations, even if the LDADDR
6715 * was later optimized away, so clear these flags, and add them back for the still
6716 * present OP_LDADDR instructions.
6718 for (i = 0; i < cfg->next_vreg; ++i) {
6721 ins = get_vreg_to_inst (cfg, i);
6722 if (ins && ins != cfg->rgctx_var)
6723 ins->flags &= ~MONO_INST_INDIRECT;
6727 * Make a first pass over the code to precreate PHI nodes/set INDIRECT flags.
6729 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
6731 LLVMBuilderRef builder;
6733 char dname_buf[128];
6735 builder = create_builder (ctx);
6737 for (ins = bb->code; ins; ins = ins->next) {
6738 switch (ins->opcode) {
6743 LLVMTypeRef phi_type = llvm_type_to_stack_type (cfg, type_to_llvm_type (ctx, &ins->klass->byval_arg));
6748 if (ins->opcode == OP_VPHI) {
6749 /* Treat valuetype PHI nodes as operating on the address itself */
6750 g_assert (ins->klass);
6751 phi_type = LLVMPointerType (type_to_llvm_type (ctx, &ins->klass->byval_arg), 0);
6755 * Have to precreate these, as they can be referenced by
6756 * earlier instructions.
6758 sprintf (dname_buf, "t%d", ins->dreg);
6760 values [ins->dreg] = LLVMBuildPhi (builder, phi_type, dname);
6762 if (ins->opcode == OP_VPHI)
6763 ctx->addresses [ins->dreg] = values [ins->dreg];
6765 g_ptr_array_add (ctx->phi_values, values [ins->dreg]);
6768 * Set the expected type of the incoming arguments since these have
6769 * to have the same type.
6771 for (i = 0; i < ins->inst_phi_args [0]; i++) {
6772 int sreg1 = ins->inst_phi_args [i + 1];
6775 ctx->vreg_types [sreg1] = phi_type;
6780 ((MonoInst*)ins->inst_p0)->flags |= MONO_INST_INDIRECT;
6789 * Create an ordering for bblocks, use the depth first order first, then
6790 * put the exception handling bblocks last.
6792 for (bb_index = 0; bb_index < cfg->num_bblocks; ++bb_index) {
6793 bb = cfg->bblocks [bb_index];
6794 if (!(bb->region != -1 && !MONO_BBLOCK_IS_IN_REGION (bb, MONO_REGION_TRY))) {
6795 g_ptr_array_add (bblock_list, bb);
6796 bblocks [bb->block_num].added = TRUE;
6800 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
6801 if (!bblocks [bb->block_num].added)
6802 g_ptr_array_add (bblock_list, bb);
6806 * Second pass: generate code.
6809 LLVMBuilderRef entry_builder = create_builder (ctx);
6810 LLVMBasicBlockRef entry_bb = get_bb (ctx, cfg->bb_entry);
6811 LLVMPositionBuilderAtEnd (entry_builder, entry_bb);
6812 emit_entry_bb (ctx, entry_builder);
6814 // Make landing pads first
6815 ctx->exc_meta = g_hash_table_new_full (NULL, NULL, NULL, NULL);
6817 if (ctx->llvm_only) {
6818 size_t group_index = 0;
6819 while (group_index < cfg->header->num_clauses) {
6821 size_t cursor = group_index;
6822 while (cursor < cfg->header->num_clauses &&
6823 CLAUSE_START (&cfg->header->clauses [cursor]) == CLAUSE_START (&cfg->header->clauses [group_index]) &&
6824 CLAUSE_END (&cfg->header->clauses [cursor]) == CLAUSE_END (&cfg->header->clauses [group_index])) {
6829 LLVMBasicBlockRef lpad_bb = emit_landing_pad (ctx, group_index, count);
6830 intptr_t key = CLAUSE_END (&cfg->header->clauses [group_index]);
6831 g_hash_table_insert (ctx->exc_meta, (gpointer)key, lpad_bb);
6833 group_index = cursor;
6837 for (bb_index = 0; bb_index < bblock_list->len; ++bb_index) {
6838 bb = (MonoBasicBlock*)g_ptr_array_index (bblock_list, bb_index);
6840 // Prune unreachable mono BBs.
6841 if (!(bb == cfg->bb_entry || bb->in_count > 0))
6844 process_bb (ctx, bb);
6848 g_hash_table_destroy (ctx->exc_meta);
6850 mono_memory_barrier ();
6852 /* Add incoming phi values */
6853 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
6854 GSList *l, *ins_list;
6856 ins_list = bblocks [bb->block_num].phi_nodes;
6858 for (l = ins_list; l; l = l->next) {
6859 PhiNode *node = (PhiNode*)l->data;
6860 MonoInst *phi = node->phi;
6861 int sreg1 = node->sreg;
6862 LLVMBasicBlockRef in_bb;
6867 in_bb = get_end_bb (ctx, node->in_bb);
6869 if (ctx->unreachable [node->in_bb->block_num])
6872 if (!values [sreg1]) {
6873 /* Can happen with values in EH clauses */
6874 set_failure (ctx, "incoming phi sreg1");
6878 if (phi->opcode == OP_VPHI) {
6879 g_assert (LLVMTypeOf (ctx->addresses [sreg1]) == LLVMTypeOf (values [phi->dreg]));
6880 LLVMAddIncoming (values [phi->dreg], &ctx->addresses [sreg1], &in_bb, 1);
6882 if (LLVMTypeOf (values [sreg1]) != LLVMTypeOf (values [phi->dreg])) {
6883 set_failure (ctx, "incoming phi arg type mismatch");
6886 g_assert (LLVMTypeOf (values [sreg1]) == LLVMTypeOf (values [phi->dreg]));
6887 LLVMAddIncoming (values [phi->dreg], &values [sreg1], &in_bb, 1);
6892 /* Nullify empty phi instructions */
6893 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
6894 GSList *l, *ins_list;
6896 ins_list = bblocks [bb->block_num].phi_nodes;
6898 for (l = ins_list; l; l = l->next) {
6899 PhiNode *node = (PhiNode*)l->data;
6900 MonoInst *phi = node->phi;
6901 LLVMValueRef phi_ins = values [phi->dreg];
6904 /* Already removed */
6907 if (LLVMCountIncoming (phi_ins) == 0) {
6908 mono_llvm_replace_uses_of (phi_ins, LLVMConstNull (LLVMTypeOf (phi_ins)));
6909 LLVMInstructionEraseFromParent (phi_ins);
6910 values [phi->dreg] = NULL;
6915 /* Create the SWITCH statements for ENDFINALLY instructions */
6916 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
6917 BBInfo *info = &bblocks [bb->block_num];
6919 for (l = info->endfinally_switch_ins_list; l; l = l->next) {
6920 LLVMValueRef switch_ins = (LLVMValueRef)l->data;
6921 GSList *bb_list = info->call_handler_return_bbs;
6923 for (i = 0; i < g_slist_length (bb_list); ++i)
6924 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), i + 1, FALSE), (LLVMBasicBlockRef)(g_slist_nth (bb_list, i)->data));
6928 /* Initialize the method if needed */
6929 if (cfg->compile_aot && ctx->llvm_only) {
6930 // FIXME: Add more shared got entries
6931 ctx->builder = create_builder (ctx);
6932 LLVMPositionBuilderAtEnd (ctx->builder, ctx->init_bb);
6934 ctx->module->max_method_idx = MAX (ctx->module->max_method_idx, cfg->method_index);
6936 // FIXME: beforefieldinit
6937 if (ctx->has_got_access || mono_class_get_cctor (cfg->method->klass)) {
6938 emit_init_method (ctx);
6940 LLVMBuildBr (ctx->builder, ctx->inited_bb);
6944 if (cfg->llvm_only) {
6945 GHashTableIter iter;
6947 GSList *callers, *l, *l2;
6950 * Add the contents of ctx->method_to_callers to module->method_to_callers.
6951 * We can't do this earlier, as it contains llvm instructions which can be
6952 * freed if compilation fails.
6953 * FIXME: Get rid of this when all methods can be llvm compiled.
6955 g_hash_table_iter_init (&iter, ctx->method_to_callers);
6956 while (g_hash_table_iter_next (&iter, (void**)&method, (void**)&callers)) {
6957 for (l = callers; l; l = l->next) {
6958 l2 = (GSList*)g_hash_table_lookup (ctx->module->method_to_callers, method);
6959 l2 = g_slist_prepend (l2, l->data);
6960 g_hash_table_insert (ctx->module->method_to_callers, method, l2);
6965 if (cfg->verbose_level > 1)
6966 mono_llvm_dump_value (method);
6968 if (cfg->compile_aot && !cfg->llvm_only)
6969 mark_as_used (ctx->module, method);
6971 if (cfg->compile_aot && !cfg->llvm_only) {
6972 LLVMValueRef md_args [16];
6973 LLVMValueRef md_node;
6976 method_index = mono_aot_get_method_index (cfg->orig_method);
6977 md_args [0] = LLVMMDString (ctx->method_name, strlen (ctx->method_name));
6978 md_args [1] = LLVMConstInt (LLVMInt32Type (), method_index, FALSE);
6979 md_node = LLVMMDNode (md_args, 2);
6980 LLVMAddNamedMetadataOperand (lmodule, "mono.function_indexes", md_node);
6981 //LLVMSetMetadata (method, md_kind, LLVMMDNode (&md_arg, 1));
6984 if (cfg->compile_aot) {
6985 /* Don't generate native code, keep the LLVM IR */
6986 if (cfg->verbose_level)
6987 printf ("%s emitted as %s\n", mono_method_full_name (cfg->method, TRUE), ctx->method_name);
6989 #if LLVM_API_VERSION < 100
6990 /* VerifyFunction can't handle some of the debug info created by DIBuilder in llvm 3.9 */
6991 int err = LLVMVerifyFunction(ctx->lmethod, LLVMPrintMessageAction);
6992 g_assert (err == 0);
6995 //LLVMVerifyFunction(method, 0);
6996 mono_llvm_optimize_method (ctx->module->mono_ee, ctx->lmethod);
6998 if (cfg->verbose_level > 1)
6999 mono_llvm_dump_value (ctx->lmethod);
7001 cfg->native_code = (unsigned char*)LLVMGetPointerToGlobal (ctx->module->ee, ctx->lmethod);
7003 /* Set by emit_cb */
7004 g_assert (cfg->code_len);
7007 if (ctx->module->method_to_lmethod)
7008 g_hash_table_insert (ctx->module->method_to_lmethod, cfg->method, ctx->lmethod);
7009 if (ctx->module->idx_to_lmethod)
7010 g_hash_table_insert (ctx->module->idx_to_lmethod, GINT_TO_POINTER (cfg->method_index), ctx->lmethod);
7012 if (ctx->llvm_only && cfg->orig_method->klass->valuetype && !(cfg->orig_method->flags & METHOD_ATTRIBUTE_STATIC))
7013 emit_unbox_tramp (ctx, ctx->method_name, ctx->method_type, ctx->lmethod, cfg->method_index);
7017 * mono_llvm_create_vars:
7019 * Same as mono_arch_create_vars () for LLVM.
7022 mono_llvm_create_vars (MonoCompile *cfg)
7024 MonoMethodSignature *sig;
7026 sig = mono_method_signature (cfg->method);
7027 if (cfg->gsharedvt && cfg->llvm_only) {
7028 if (mini_is_gsharedvt_variable_signature (sig) && sig->ret->type != MONO_TYPE_VOID) {
7029 cfg->vret_addr = mono_compile_create_var (cfg, &mono_get_intptr_class ()->byval_arg, OP_ARG);
7030 if (G_UNLIKELY (cfg->verbose_level > 1)) {
7031 printf ("vret_addr = ");
7032 mono_print_ins (cfg->vret_addr);
7036 mono_arch_create_vars (cfg);
7041 * mono_llvm_emit_call:
7043 * Same as mono_arch_emit_call () for LLVM.
7046 mono_llvm_emit_call (MonoCompile *cfg, MonoCallInst *call)
7049 MonoMethodSignature *sig;
7050 int i, n, stack_size;
7055 sig = call->signature;
7056 n = sig->param_count + sig->hasthis;
7058 call->cinfo = get_llvm_call_info (cfg, sig);
7060 if (cfg->disable_llvm)
7063 if (sig->call_convention == MONO_CALL_VARARG) {
7064 cfg->exception_message = g_strdup ("varargs");
7065 cfg->disable_llvm = TRUE;
7068 for (i = 0; i < n; ++i) {
7071 ainfo = call->cinfo->args + i;
7073 in = call->args [i];
7075 /* Simply remember the arguments */
7076 switch (ainfo->storage) {
7077 case LLVMArgNormal: {
7078 MonoType *t = (sig->hasthis && i == 0) ? &mono_get_intptr_class ()->byval_arg : ainfo->type;
7081 opcode = mono_type_to_regmove (cfg, t);
7082 if (opcode == OP_FMOVE) {
7083 MONO_INST_NEW (cfg, ins, OP_FMOVE);
7084 ins->dreg = mono_alloc_freg (cfg);
7085 } else if (opcode == OP_LMOVE) {
7086 MONO_INST_NEW (cfg, ins, OP_LMOVE);
7087 ins->dreg = mono_alloc_lreg (cfg);
7088 } else if (opcode == OP_RMOVE) {
7089 MONO_INST_NEW (cfg, ins, OP_RMOVE);
7090 ins->dreg = mono_alloc_freg (cfg);
7092 MONO_INST_NEW (cfg, ins, OP_MOVE);
7093 ins->dreg = mono_alloc_ireg (cfg);
7095 ins->sreg1 = in->dreg;
7098 case LLVMArgVtypeByVal:
7099 case LLVMArgVtypeByRef:
7100 case LLVMArgVtypeInReg:
7101 case LLVMArgVtypeAsScalar:
7102 case LLVMArgAsIArgs:
7103 case LLVMArgAsFpArgs:
7104 case LLVMArgGsharedvtVariable:
7105 case LLVMArgGsharedvtFixed:
7106 case LLVMArgGsharedvtFixedVtype:
7107 MONO_INST_NEW (cfg, ins, OP_LLVM_OUTARG_VT);
7108 ins->dreg = mono_alloc_ireg (cfg);
7109 ins->sreg1 = in->dreg;
7110 ins->inst_p0 = mono_mempool_alloc0 (cfg->mempool, sizeof (LLVMArgInfo));
7111 memcpy (ins->inst_p0, ainfo, sizeof (LLVMArgInfo));
7112 ins->inst_vtype = ainfo->type;
7113 ins->klass = mono_class_from_mono_type (ainfo->type);
7116 cfg->exception_message = g_strdup ("ainfo->storage");
7117 cfg->disable_llvm = TRUE;
7121 if (!cfg->disable_llvm) {
7122 MONO_ADD_INS (cfg->cbb, ins);
7123 mono_call_inst_add_outarg_reg (cfg, call, ins->dreg, 0, FALSE);
7128 static unsigned char*
7129 alloc_cb (LLVMValueRef function, int size)
7133 cfg = (MonoCompile*)mono_native_tls_get_value (current_cfg_tls_id);
7137 return (unsigned char*)mono_domain_code_reserve (cfg->domain, size);
7139 return (unsigned char*)mono_domain_code_reserve (mono_domain_get (), size);
7144 emitted_cb (LLVMValueRef function, void *start, void *end)
7148 cfg = (MonoCompile*)mono_native_tls_get_value (current_cfg_tls_id);
7150 cfg->code_len = (guint8*)end - (guint8*)start;
7154 exception_cb (void *data)
7157 MonoJitExceptionInfo *ei;
7158 guint32 ei_len, i, j, nested_len, nindex;
7159 gpointer *type_info;
7160 int this_reg, this_offset;
7162 cfg = (MonoCompile*)mono_native_tls_get_value (current_cfg_tls_id);
7166 * data points to a DWARF FDE structure, convert it to our unwind format and
7168 * An alternative would be to save it directly, and modify our unwinder to work
7171 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);
7172 if (cfg->verbose_level > 1)
7173 mono_print_unwind_info (cfg->encoded_unwind_ops, cfg->encoded_unwind_ops_len);
7175 /* Count nested clauses */
7177 for (i = 0; i < ei_len; ++i) {
7178 gint32 cindex1 = *(gint32*)type_info [i];
7179 MonoExceptionClause *clause1 = &cfg->header->clauses [cindex1];
7181 for (j = 0; j < cfg->header->num_clauses; ++j) {
7183 MonoExceptionClause *clause2 = &cfg->header->clauses [cindex2];
7185 if (cindex1 != cindex2 && clause1->try_offset >= clause2->try_offset && clause1->handler_offset <= clause2->handler_offset) {
7191 cfg->llvm_ex_info = (MonoJitExceptionInfo*)mono_mempool_alloc0 (cfg->mempool, (ei_len + nested_len) * sizeof (MonoJitExceptionInfo));
7192 cfg->llvm_ex_info_len = ei_len + nested_len;
7193 memcpy (cfg->llvm_ex_info, ei, ei_len * sizeof (MonoJitExceptionInfo));
7194 /* Fill the rest of the information from the type info */
7195 for (i = 0; i < ei_len; ++i) {
7196 gint32 clause_index = *(gint32*)type_info [i];
7197 MonoExceptionClause *clause = &cfg->header->clauses [clause_index];
7199 cfg->llvm_ex_info [i].flags = clause->flags;
7200 cfg->llvm_ex_info [i].data.catch_class = clause->data.catch_class;
7201 cfg->llvm_ex_info [i].clause_index = clause_index;
7205 * For nested clauses, the LLVM produced exception info associates the try interval with
7206 * the innermost handler, while mono expects it to be associated with all nesting clauses.
7207 * So add new clauses which use the IL info (catch class etc.) from the nesting clause,
7208 * and everything else from the nested clause.
7211 for (i = 0; i < ei_len; ++i) {
7212 gint32 cindex1 = *(gint32*)type_info [i];
7213 MonoExceptionClause *clause1 = &cfg->header->clauses [cindex1];
7215 for (j = 0; j < cfg->header->num_clauses; ++j) {
7217 MonoExceptionClause *clause2 = &cfg->header->clauses [cindex2];
7218 MonoJitExceptionInfo *nesting_ei, *nested_ei;
7220 if (cindex1 != cindex2 && clause1->try_offset >= clause2->try_offset && clause1->handler_offset <= clause2->handler_offset) {
7221 /* clause1 is the nested clause */
7222 nested_ei = &cfg->llvm_ex_info [i];
7223 nesting_ei = &cfg->llvm_ex_info [nindex];
7226 memcpy (nesting_ei, nested_ei, sizeof (MonoJitExceptionInfo));
7228 nesting_ei->flags = clause2->flags;
7229 nesting_ei->data.catch_class = clause2->data.catch_class;
7230 nesting_ei->clause_index = cindex2;
7234 g_assert (nindex == ei_len + nested_len);
7235 cfg->llvm_this_reg = this_reg;
7236 cfg->llvm_this_offset = this_offset;
7238 /* type_info [i] is cfg mempool allocated, no need to free it */
7245 dlsym_cb (const char *name, void **symbol)
7251 if (!strcmp (name, "__bzero")) {
7252 *symbol = (void*)bzero;
7254 current = mono_dl_open (NULL, 0, NULL);
7257 err = mono_dl_symbol (current, name, symbol);
7259 mono_dl_close (current);
7261 #ifdef MONO_ARCH_HAVE_CREATE_LLVM_NATIVE_THUNK
7262 *symbol = (char*)mono_arch_create_llvm_native_thunk (mono_domain_get (), (guint8*)(*symbol));
7268 AddFunc (LLVMModuleRef module, const char *name, LLVMTypeRef ret_type, LLVMTypeRef *param_types, int nparams)
7270 LLVMAddFunction (module, name, LLVMFunctionType (ret_type, param_types, nparams, FALSE));
7274 AddFunc2 (LLVMModuleRef module, const char *name, LLVMTypeRef ret_type, LLVMTypeRef param_type1, LLVMTypeRef param_type2)
7276 LLVMTypeRef param_types [4];
7278 param_types [0] = param_type1;
7279 param_types [1] = param_type2;
7281 AddFunc (module, name, ret_type, param_types, 2);
7285 add_intrinsics (LLVMModuleRef module)
7287 /* Emit declarations of instrinsics */
7289 * It would be nicer to emit only the intrinsics actually used, but LLVM's Module
7290 * type doesn't seem to do any locking.
7293 LLVMTypeRef params [] = { LLVMPointerType (LLVMInt8Type (), 0), LLVMInt8Type (), LLVMInt32Type (), LLVMInt32Type (), LLVMInt1Type () };
7295 memset_param_count = 5;
7296 memset_func_name = "llvm.memset.p0i8.i32";
7298 AddFunc (module, memset_func_name, LLVMVoidType (), params, memset_param_count);
7302 LLVMTypeRef params [] = { LLVMPointerType (LLVMInt8Type (), 0), LLVMPointerType (LLVMInt8Type (), 0), LLVMInt32Type (), LLVMInt32Type (), LLVMInt1Type () };
7304 memcpy_param_count = 5;
7305 memcpy_func_name = "llvm.memcpy.p0i8.p0i8.i32";
7307 AddFunc (module, memcpy_func_name, LLVMVoidType (), params, memcpy_param_count);
7311 LLVMTypeRef params [] = { LLVMDoubleType () };
7313 AddFunc (module, "llvm.sin.f64", LLVMDoubleType (), params, 1);
7314 AddFunc (module, "llvm.cos.f64", LLVMDoubleType (), params, 1);
7315 AddFunc (module, "llvm.sqrt.f64", LLVMDoubleType (), params, 1);
7317 /* This isn't an intrinsic, instead llvm seems to special case it by name */
7318 AddFunc (module, "fabs", LLVMDoubleType (), params, 1);
7322 LLVMTypeRef ovf_res_i32 [] = { LLVMInt32Type (), LLVMInt1Type () };
7323 LLVMTypeRef params [] = { LLVMInt32Type (), LLVMInt32Type () };
7324 LLVMTypeRef ret_type = LLVMStructType (ovf_res_i32, 2, FALSE);
7326 AddFunc (module, "llvm.sadd.with.overflow.i32", ret_type, params, 2);
7327 AddFunc (module, "llvm.sadd.with.overflow.i32", ret_type, params, 2);
7328 AddFunc (module, "llvm.uadd.with.overflow.i32", ret_type, params, 2);
7329 AddFunc (module, "llvm.ssub.with.overflow.i32", ret_type, params, 2);
7330 AddFunc (module, "llvm.usub.with.overflow.i32", ret_type, params, 2);
7331 AddFunc (module, "llvm.smul.with.overflow.i32", ret_type, params, 2);
7332 AddFunc (module, "llvm.umul.with.overflow.i32", ret_type, params, 2);
7336 LLVMTypeRef ovf_res_i64 [] = { LLVMInt64Type (), LLVMInt1Type () };
7337 LLVMTypeRef params [] = { LLVMInt64Type (), LLVMInt64Type () };
7338 LLVMTypeRef ret_type = LLVMStructType (ovf_res_i64, 2, FALSE);
7340 AddFunc (module, "llvm.sadd.with.overflow.i64", ret_type, params, 2);
7341 AddFunc (module, "llvm.uadd.with.overflow.i64", ret_type, params, 2);
7342 AddFunc (module, "llvm.ssub.with.overflow.i64", ret_type, params, 2);
7343 AddFunc (module, "llvm.usub.with.overflow.i64", ret_type, params, 2);
7344 AddFunc (module, "llvm.smul.with.overflow.i64", ret_type, params, 2);
7345 AddFunc (module, "llvm.umul.with.overflow.i64", ret_type, params, 2);
7348 AddFunc2 (module, "llvm.expect.i8", LLVMInt8Type (), LLVMInt8Type (), LLVMInt8Type ());
7349 AddFunc2 (module, "llvm.expect.i1", LLVMInt1Type (), LLVMInt1Type (), LLVMInt1Type ());
7353 AddFunc (module, "mono_personality", LLVMVoidType (), NULL, 0);
7355 AddFunc (module, "llvm_resume_unwind_trampoline", LLVMVoidType (), NULL, 0);
7358 /* SSE intrinsics */
7359 #if defined(TARGET_X86) || defined(TARGET_AMD64)
7361 LLVMTypeRef ret_type, arg_types [16];
7364 ret_type = type_to_simd_type (MONO_TYPE_I4);
7365 arg_types [0] = ret_type;
7366 arg_types [1] = ret_type;
7367 AddFunc (module, "llvm.x86.sse41.pminud", ret_type, arg_types, 2);
7368 AddFunc (module, "llvm.x86.sse41.pmaxud", ret_type, arg_types, 2);
7370 ret_type = type_to_simd_type (MONO_TYPE_I2);
7371 arg_types [0] = ret_type;
7372 arg_types [1] = ret_type;
7373 AddFunc (module, "llvm.x86.sse41.pminuw", ret_type, arg_types, 2);
7374 AddFunc (module, "llvm.x86.sse2.pmins.w", ret_type, arg_types, 2);
7375 AddFunc (module, "llvm.x86.sse41.pmaxuw", ret_type, arg_types, 2);
7376 AddFunc (module, "llvm.x86.sse2.padds.w", ret_type, arg_types, 2);
7377 AddFunc (module, "llvm.x86.sse2.psubs.w", ret_type, arg_types, 2);
7378 AddFunc (module, "llvm.x86.sse2.paddus.w", ret_type, arg_types, 2);
7379 AddFunc (module, "llvm.x86.sse2.psubus.w", ret_type, arg_types, 2);
7380 AddFunc (module, "llvm.x86.sse2.pavg.w", ret_type, arg_types, 2);
7381 AddFunc (module, "llvm.x86.sse2.pmulh.w", ret_type, arg_types, 2);
7382 AddFunc (module, "llvm.x86.sse2.pmulhu.w", ret_type, arg_types, 2);
7384 ret_type = type_to_simd_type (MONO_TYPE_I1);
7385 arg_types [0] = ret_type;
7386 arg_types [1] = ret_type;
7387 AddFunc (module, "llvm.x86.sse2.pminu.b", ret_type, arg_types, 2);
7388 AddFunc (module, "llvm.x86.sse2.pmaxu.b", ret_type, arg_types, 2);
7389 AddFunc (module, "llvm.x86.sse2.padds.b", ret_type, arg_types, 2);
7390 AddFunc (module, "llvm.x86.sse2.psubs.b", ret_type, arg_types, 2);
7391 AddFunc (module, "llvm.x86.sse2.paddus.b", ret_type, arg_types, 2);
7392 AddFunc (module, "llvm.x86.sse2.psubus.b", ret_type, arg_types, 2);
7393 AddFunc (module, "llvm.x86.sse2.pavg.b", ret_type, arg_types, 2);
7395 ret_type = type_to_simd_type (MONO_TYPE_R8);
7396 arg_types [0] = ret_type;
7397 arg_types [1] = ret_type;
7398 AddFunc (module, "llvm.x86.sse2.min.pd", ret_type, arg_types, 2);
7399 AddFunc (module, "llvm.x86.sse2.max.pd", ret_type, arg_types, 2);
7400 AddFunc (module, "llvm.x86.sse3.hadd.pd", ret_type, arg_types, 2);
7401 AddFunc (module, "llvm.x86.sse3.hsub.pd", ret_type, arg_types, 2);
7402 AddFunc (module, "llvm.x86.sse3.addsub.pd", ret_type, arg_types, 2);
7404 ret_type = type_to_simd_type (MONO_TYPE_R4);
7405 arg_types [0] = ret_type;
7406 arg_types [1] = ret_type;
7407 AddFunc (module, "llvm.x86.sse.min.ps", ret_type, arg_types, 2);
7408 AddFunc (module, "llvm.x86.sse.max.ps", ret_type, arg_types, 2);
7409 AddFunc (module, "llvm.x86.sse3.hadd.ps", ret_type, arg_types, 2);
7410 AddFunc (module, "llvm.x86.sse3.hsub.ps", ret_type, arg_types, 2);
7411 AddFunc (module, "llvm.x86.sse3.addsub.ps", ret_type, arg_types, 2);
7414 ret_type = type_to_simd_type (MONO_TYPE_I1);
7415 arg_types [0] = type_to_simd_type (MONO_TYPE_I2);
7416 arg_types [1] = type_to_simd_type (MONO_TYPE_I2);
7417 AddFunc (module, "llvm.x86.sse2.packsswb.128", ret_type, arg_types, 2);
7418 AddFunc (module, "llvm.x86.sse2.packuswb.128", ret_type, arg_types, 2);
7419 ret_type = type_to_simd_type (MONO_TYPE_I2);
7420 arg_types [0] = type_to_simd_type (MONO_TYPE_I4);
7421 arg_types [1] = type_to_simd_type (MONO_TYPE_I4);
7422 AddFunc (module, "llvm.x86.sse2.packssdw.128", ret_type, arg_types, 2);
7423 AddFunc (module, "llvm.x86.sse41.packusdw", ret_type, arg_types, 2);
7426 ret_type = type_to_simd_type (MONO_TYPE_R8);
7427 arg_types [0] = ret_type;
7428 arg_types [1] = ret_type;
7429 arg_types [2] = LLVMInt8Type ();
7430 AddFunc (module, "llvm.x86.sse2.cmp.pd", ret_type, arg_types, 3);
7431 ret_type = type_to_simd_type (MONO_TYPE_R4);
7432 arg_types [0] = ret_type;
7433 arg_types [1] = ret_type;
7434 arg_types [2] = LLVMInt8Type ();
7435 AddFunc (module, "llvm.x86.sse.cmp.ps", ret_type, arg_types, 3);
7437 /* Conversion ops */
7438 ret_type = type_to_simd_type (MONO_TYPE_R8);
7439 arg_types [0] = type_to_simd_type (MONO_TYPE_I4);
7440 AddFunc (module, "llvm.x86.sse2.cvtdq2pd", ret_type, arg_types, 1);
7441 ret_type = type_to_simd_type (MONO_TYPE_R4);
7442 arg_types [0] = type_to_simd_type (MONO_TYPE_I4);
7443 AddFunc (module, "llvm.x86.sse2.cvtdq2ps", ret_type, arg_types, 1);
7444 ret_type = type_to_simd_type (MONO_TYPE_I4);
7445 arg_types [0] = type_to_simd_type (MONO_TYPE_R8);
7446 AddFunc (module, "llvm.x86.sse2.cvtpd2dq", ret_type, arg_types, 1);
7447 ret_type = type_to_simd_type (MONO_TYPE_I4);
7448 arg_types [0] = type_to_simd_type (MONO_TYPE_R4);
7449 AddFunc (module, "llvm.x86.sse2.cvtps2dq", ret_type, arg_types, 1);
7450 ret_type = type_to_simd_type (MONO_TYPE_R4);
7451 arg_types [0] = type_to_simd_type (MONO_TYPE_R8);
7452 AddFunc (module, "llvm.x86.sse2.cvtpd2ps", ret_type, arg_types, 1);
7453 ret_type = type_to_simd_type (MONO_TYPE_R8);
7454 arg_types [0] = type_to_simd_type (MONO_TYPE_R4);
7455 AddFunc (module, "llvm.x86.sse2.cvtps2pd", ret_type, arg_types, 1);
7457 ret_type = type_to_simd_type (MONO_TYPE_I4);
7458 arg_types [0] = type_to_simd_type (MONO_TYPE_R8);
7459 AddFunc (module, "llvm.x86.sse2.cvttpd2dq", ret_type, arg_types, 1);
7460 ret_type = type_to_simd_type (MONO_TYPE_I4);
7461 arg_types [0] = type_to_simd_type (MONO_TYPE_R4);
7462 AddFunc (module, "llvm.x86.sse2.cvttps2dq", ret_type, arg_types, 1);
7465 ret_type = type_to_simd_type (MONO_TYPE_R8);
7466 arg_types [0] = ret_type;
7467 AddFunc (module, "llvm.x86.sse2.sqrt.pd", ret_type, arg_types, 1);
7468 ret_type = type_to_simd_type (MONO_TYPE_R4);
7469 arg_types [0] = ret_type;
7470 AddFunc (module, "llvm.x86.sse.sqrt.ps", ret_type, arg_types, 1);
7471 ret_type = type_to_simd_type (MONO_TYPE_R4);
7472 arg_types [0] = ret_type;
7473 AddFunc (module, "llvm.x86.sse.rsqrt.ps", ret_type, arg_types, 1);
7474 ret_type = type_to_simd_type (MONO_TYPE_R4);
7475 arg_types [0] = ret_type;
7476 AddFunc (module, "llvm.x86.sse.rcp.ps", ret_type, arg_types, 1);
7479 ret_type = type_to_simd_type (MONO_TYPE_I2);
7480 arg_types [0] = ret_type;
7481 arg_types [1] = LLVMInt32Type ();
7482 AddFunc (module, "llvm.x86.sse2.psrli.w", ret_type, arg_types, 2);
7483 AddFunc (module, "llvm.x86.sse2.psrai.w", ret_type, arg_types, 2);
7484 AddFunc (module, "llvm.x86.sse2.pslli.w", ret_type, arg_types, 2);
7485 ret_type = type_to_simd_type (MONO_TYPE_I4);
7486 arg_types [0] = ret_type;
7487 arg_types [1] = LLVMInt32Type ();
7488 AddFunc (module, "llvm.x86.sse2.psrli.d", ret_type, arg_types, 2);
7489 AddFunc (module, "llvm.x86.sse2.psrai.d", ret_type, arg_types, 2);
7490 AddFunc (module, "llvm.x86.sse2.pslli.d", ret_type, arg_types, 2);
7491 ret_type = type_to_simd_type (MONO_TYPE_I8);
7492 arg_types [0] = ret_type;
7493 arg_types [1] = LLVMInt32Type ();
7494 AddFunc (module, "llvm.x86.sse2.psrli.q", ret_type, arg_types, 2);
7495 AddFunc (module, "llvm.x86.sse2.pslli.q", ret_type, arg_types, 2);
7498 ret_type = LLVMInt32Type ();
7499 arg_types [0] = type_to_simd_type (MONO_TYPE_I1);
7500 AddFunc (module, "llvm.x86.sse2.pmovmskb.128", ret_type, arg_types, 1);
7503 AddFunc (module, "llvm.x86.sse2.pause", LLVMVoidType (), NULL, 0);
7506 /* Load/Store intrinsics */
7508 LLVMTypeRef arg_types [5];
7512 for (i = 1; i <= 8; i *= 2) {
7513 arg_types [0] = LLVMPointerType (LLVMIntType (i * 8), 0);
7514 arg_types [1] = LLVMInt32Type ();
7515 arg_types [2] = LLVMInt1Type ();
7516 arg_types [3] = LLVMInt32Type ();
7517 sprintf (name, "llvm.mono.load.i%d.p0i%d", i * 8, i * 8);
7518 AddFunc (module, name, LLVMIntType (i * 8), arg_types, 4);
7520 arg_types [0] = LLVMIntType (i * 8);
7521 arg_types [1] = LLVMPointerType (LLVMIntType (i * 8), 0);
7522 arg_types [2] = LLVMInt32Type ();
7523 arg_types [3] = LLVMInt1Type ();
7524 arg_types [4] = LLVMInt32Type ();
7525 sprintf (name, "llvm.mono.store.i%d.p0i%d", i * 8, i * 8);
7526 AddFunc (module, name, LLVMVoidType (), arg_types, 5);
7532 add_types (MonoLLVMModule *module)
7534 module->ptr_type = LLVMPointerType (sizeof (gpointer) == 8 ? LLVMInt64Type () : LLVMInt32Type (), 0);
7538 mono_llvm_init (void)
7540 mono_native_tls_alloc (¤t_cfg_tls_id, NULL);
7544 init_jit_module (MonoDomain *domain)
7546 MonoJitICallInfo *info;
7547 MonoJitDomainInfo *dinfo;
7548 MonoLLVMModule *module;
7551 dinfo = domain_jit_info (domain);
7552 if (dinfo->llvm_module)
7555 mono_loader_lock ();
7557 if (dinfo->llvm_module) {
7558 mono_loader_unlock ();
7562 module = g_new0 (MonoLLVMModule, 1);
7564 name = g_strdup_printf ("mono-%s", domain->friendly_name);
7565 module->lmodule = LLVMModuleCreateWithName (name);
7566 module->context = LLVMGetGlobalContext ();
7568 module->mono_ee = (MonoEERef*)mono_llvm_create_ee (LLVMCreateModuleProviderForExistingModule (module->lmodule), alloc_cb, emitted_cb, exception_cb, dlsym_cb, &module->ee);
7570 add_intrinsics (module->lmodule);
7573 module->llvm_types = g_hash_table_new (NULL, NULL);
7575 info = mono_find_jit_icall_by_name ("llvm_resume_unwind_trampoline");
7577 LLVMAddGlobalMapping (module->ee, LLVMGetNamedFunction (module->lmodule, "llvm_resume_unwind_trampoline"), (void*)info->func);
7579 mono_memory_barrier ();
7581 dinfo->llvm_module = module;
7583 mono_loader_unlock ();
7587 mono_llvm_cleanup (void)
7589 MonoLLVMModule *module = &aot_module;
7591 if (module->lmodule)
7592 LLVMDisposeModule (module->lmodule);
7594 if (module->context)
7595 LLVMContextDispose (module->context);
7599 mono_llvm_free_domain_info (MonoDomain *domain)
7601 MonoJitDomainInfo *info = domain_jit_info (domain);
7602 MonoLLVMModule *module = (MonoLLVMModule*)info->llvm_module;
7608 if (module->llvm_types)
7609 g_hash_table_destroy (module->llvm_types);
7611 mono_llvm_dispose_ee (module->mono_ee);
7613 if (module->bb_names) {
7614 for (i = 0; i < module->bb_names_len; ++i)
7615 g_free (module->bb_names [i]);
7616 g_free (module->bb_names);
7618 //LLVMDisposeModule (module->module);
7622 info->llvm_module = NULL;
7626 mono_llvm_create_aot_module (MonoAssembly *assembly, const char *global_prefix, gboolean emit_dwarf, gboolean static_link, gboolean llvm_only)
7628 MonoLLVMModule *module = &aot_module;
7630 /* Delete previous module */
7631 if (module->plt_entries)
7632 g_hash_table_destroy (module->plt_entries);
7633 if (module->lmodule)
7634 LLVMDisposeModule (module->lmodule);
7636 memset (module, 0, sizeof (aot_module));
7638 module->lmodule = LLVMModuleCreateWithName ("aot");
7639 module->assembly = assembly;
7640 module->global_prefix = g_strdup (global_prefix);
7641 module->got_symbol = g_strdup_printf ("%s_llvm_got", global_prefix);
7642 module->eh_frame_symbol = g_strdup_printf ("%s_eh_frame", global_prefix);
7643 module->get_method_symbol = g_strdup_printf ("%s_get_method", global_prefix);
7644 module->get_unbox_tramp_symbol = g_strdup_printf ("%s_get_unbox_tramp", global_prefix);
7645 module->external_symbols = TRUE;
7646 module->emit_dwarf = emit_dwarf;
7647 module->static_link = static_link;
7648 module->llvm_only = llvm_only;
7649 /* The first few entries are reserved */
7650 module->max_got_offset = 16;
7651 module->context = LLVMContextCreate ();
7654 /* clang ignores our debug info because it has an invalid version */
7655 module->emit_dwarf = FALSE;
7657 #if LLVM_API_VERSION > 100
7658 module->emit_dwarf = FALSE;
7661 add_intrinsics (module->lmodule);
7664 #if LLVM_API_VERSION > 100
7665 if (module->emit_dwarf) {
7666 char *dir, *build_info, *s, *cu_name;
7668 module->di_builder = mono_llvm_create_di_builder (module->lmodule);
7671 dir = g_strdup (".");
7672 build_info = mono_get_runtime_build_info ();
7673 s = g_strdup_printf ("Mono AOT Compiler %s (LLVM)", build_info);
7674 cu_name = g_path_get_basename (assembly->image->name);
7675 module->cu = mono_llvm_di_create_compile_unit (module->di_builder, cu_name, dir, s);
7677 g_free (build_info);
7684 * We couldn't compute the type of the LLVM global representing the got because
7685 * its size is only known after all the methods have been emitted. So create
7686 * a dummy variable, and replace all uses it with the real got variable when
7687 * its size is known in mono_llvm_emit_aot_module ().
7690 LLVMTypeRef got_type = LLVMArrayType (module->ptr_type, 0);
7692 module->got_var = LLVMAddGlobal (module->lmodule, got_type, "mono_dummy_got");
7693 LLVMSetInitializer (module->got_var, LLVMConstNull (got_type));
7696 /* Add initialization array */
7698 LLVMTypeRef inited_type = LLVMArrayType (LLVMInt8Type (), 0);
7700 module->inited_var = LLVMAddGlobal (aot_module.lmodule, inited_type, "mono_inited_tmp");
7701 LLVMSetInitializer (module->inited_var, LLVMConstNull (inited_type));
7705 emit_init_icall_wrappers (module);
7707 emit_llvm_code_start (module);
7709 /* Add a dummy personality function */
7710 if (!use_debug_personality) {
7711 LLVMValueRef personality = LLVMAddFunction (module->lmodule, default_personality_name, LLVMFunctionType (LLVMInt32Type (), NULL, 0, TRUE));
7712 LLVMSetLinkage (personality, LLVMExternalLinkage);
7713 mark_as_used (module, personality);
7716 /* Add a reference to the c++ exception we throw/catch */
7718 LLVMTypeRef exc = LLVMPointerType (LLVMInt8Type (), 0);
7719 module->sentinel_exception = LLVMAddGlobal (module->lmodule, exc, "_ZTIPi");
7720 LLVMSetLinkage (module->sentinel_exception, LLVMExternalLinkage);
7721 mono_llvm_set_is_constant (module->sentinel_exception);
7724 module->llvm_types = g_hash_table_new (NULL, NULL);
7725 module->plt_entries = g_hash_table_new (g_str_hash, g_str_equal);
7726 module->plt_entries_ji = g_hash_table_new (NULL, NULL);
7727 module->direct_callables = g_hash_table_new (g_str_hash, g_str_equal);
7728 module->method_to_lmethod = g_hash_table_new (NULL, NULL);
7729 module->idx_to_lmethod = g_hash_table_new (NULL, NULL);
7730 module->idx_to_unbox_tramp = g_hash_table_new (NULL, NULL);
7731 module->method_to_callers = g_hash_table_new (NULL, NULL);
7735 llvm_array_from_uints (LLVMTypeRef el_type, guint32 *values, int nvalues)
7738 LLVMValueRef res, *vals;
7740 vals = g_new0 (LLVMValueRef, nvalues);
7741 for (i = 0; i < nvalues; ++i)
7742 vals [i] = LLVMConstInt (LLVMInt32Type (), values [i], FALSE);
7743 res = LLVMConstArray (LLVMInt32Type (), vals, nvalues);
7749 * mono_llvm_emit_aot_file_info:
7751 * Emit the MonoAotFileInfo structure.
7752 * Same as emit_aot_file_info () in aot-compiler.c.
7755 mono_llvm_emit_aot_file_info (MonoAotFileInfo *info, gboolean has_jitted_code)
7757 MonoLLVMModule *module = &aot_module;
7759 /* Save these for later */
7760 memcpy (&module->aot_info, info, sizeof (MonoAotFileInfo));
7761 module->has_jitted_code = has_jitted_code;
7765 * mono_llvm_emit_aot_data:
7767 * Emit the binary data DATA pointed to by symbol SYMBOL.
7770 mono_llvm_emit_aot_data (const char *symbol, guint8 *data, int data_len)
7772 MonoLLVMModule *module = &aot_module;
7776 type = LLVMArrayType (LLVMInt8Type (), data_len);
7777 d = LLVMAddGlobal (module->lmodule, type, symbol);
7778 LLVMSetVisibility (d, LLVMHiddenVisibility);
7779 LLVMSetLinkage (d, LLVMInternalLinkage);
7780 LLVMSetInitializer (d, mono_llvm_create_constant_data_array (data, data_len));
7781 mono_llvm_set_is_constant (d);
7784 /* Add a reference to a global defined in JITted code */
7786 AddJitGlobal (MonoLLVMModule *module, LLVMTypeRef type, const char *name)
7791 s = g_strdup_printf ("%s%s", module->global_prefix, name);
7792 v = LLVMAddGlobal (module->lmodule, LLVMInt8Type (), s);
7798 emit_aot_file_info (MonoLLVMModule *module)
7800 LLVMTypeRef file_info_type;
7801 LLVMTypeRef *eltypes, eltype;
7802 LLVMValueRef info_var;
7803 LLVMValueRef *fields;
7804 int i, nfields, tindex;
7805 MonoAotFileInfo *info;
7806 LLVMModuleRef lmodule = module->lmodule;
7808 info = &module->aot_info;
7810 /* Create an LLVM type to represent MonoAotFileInfo */
7811 nfields = 2 + MONO_AOT_FILE_INFO_NUM_SYMBOLS + 15 + 5;
7812 eltypes = g_new (LLVMTypeRef, nfields);
7814 eltypes [tindex ++] = LLVMInt32Type ();
7815 eltypes [tindex ++] = LLVMInt32Type ();
7817 for (i = 0; i < MONO_AOT_FILE_INFO_NUM_SYMBOLS; ++i)
7818 eltypes [tindex ++] = LLVMPointerType (LLVMInt8Type (), 0);
7820 for (i = 0; i < 15; ++i)
7821 eltypes [tindex ++] = LLVMInt32Type ();
7823 eltypes [tindex ++] = LLVMArrayType (LLVMInt32Type (), MONO_AOT_TABLE_NUM);
7824 for (i = 0; i < 4; ++i)
7825 eltypes [tindex ++] = LLVMArrayType (LLVMInt32Type (), MONO_AOT_TRAMP_NUM);
7826 g_assert (tindex == nfields);
7827 file_info_type = LLVMStructCreateNamed (module->context, "MonoAotFileInfo");
7828 LLVMStructSetBody (file_info_type, eltypes, nfields, FALSE);
7830 info_var = LLVMAddGlobal (lmodule, file_info_type, "mono_aot_file_info");
7831 if (module->static_link) {
7832 LLVMSetVisibility (info_var, LLVMHiddenVisibility);
7833 LLVMSetLinkage (info_var, LLVMInternalLinkage);
7835 fields = g_new (LLVMValueRef, nfields);
7837 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->version, FALSE);
7838 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->dummy, FALSE);
7842 * We use LLVMGetNamedGlobal () for symbol which are defined in LLVM code, and LLVMAddGlobal ()
7843 * for symbols defined in the .s file emitted by the aot compiler.
7845 eltype = eltypes [tindex];
7846 if (module->llvm_only)
7847 fields [tindex ++] = LLVMConstNull (eltype);
7849 fields [tindex ++] = AddJitGlobal (module, eltype, "jit_got");
7850 fields [tindex ++] = module->got_var;
7851 /* llc defines this directly */
7852 if (!module->llvm_only) {
7853 fields [tindex ++] = LLVMAddGlobal (lmodule, eltype, module->eh_frame_symbol);
7854 fields [tindex ++] = LLVMConstNull (eltype);
7855 fields [tindex ++] = LLVMConstNull (eltype);
7857 fields [tindex ++] = LLVMConstNull (eltype);
7858 fields [tindex ++] = module->get_method;
7859 fields [tindex ++] = module->get_unbox_tramp;
7861 if (module->has_jitted_code) {
7862 fields [tindex ++] = AddJitGlobal (module, eltype, "jit_code_start");
7863 fields [tindex ++] = AddJitGlobal (module, eltype, "jit_code_end");
7865 fields [tindex ++] = LLVMConstNull (eltype);
7866 fields [tindex ++] = LLVMConstNull (eltype);
7868 if (!module->llvm_only)
7869 fields [tindex ++] = AddJitGlobal (module, eltype, "method_addresses");
7871 fields [tindex ++] = LLVMConstNull (eltype);
7872 if (info->flags & MONO_AOT_FILE_FLAG_SEPARATE_DATA) {
7873 for (i = 0; i < MONO_AOT_TABLE_NUM; ++i)
7874 fields [tindex ++] = LLVMConstNull (eltype);
7876 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "blob");
7877 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "class_name_table");
7878 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "class_info_offsets");
7879 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "method_info_offsets");
7880 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "ex_info_offsets");
7881 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "extra_method_info_offsets");
7882 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "extra_method_table");
7883 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "got_info_offsets");
7884 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "llvm_got_info_offsets");
7885 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "image_table");
7887 /* Not needed (mem_end) */
7888 fields [tindex ++] = LLVMConstNull (eltype);
7889 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "assembly_guid");
7890 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "runtime_version");
7891 if (info->trampoline_size [0]) {
7892 fields [tindex ++] = AddJitGlobal (module, eltype, "specific_trampolines");
7893 fields [tindex ++] = AddJitGlobal (module, eltype, "static_rgctx_trampolines");
7894 fields [tindex ++] = AddJitGlobal (module, eltype, "imt_thunks");
7895 fields [tindex ++] = AddJitGlobal (module, eltype, "gsharedvt_arg_trampolines");
7897 fields [tindex ++] = LLVMConstNull (eltype);
7898 fields [tindex ++] = LLVMConstNull (eltype);
7899 fields [tindex ++] = LLVMConstNull (eltype);
7900 fields [tindex ++] = LLVMConstNull (eltype);
7902 if (module->static_link && !module->llvm_only)
7903 fields [tindex ++] = AddJitGlobal (module, eltype, "globals");
7905 fields [tindex ++] = LLVMConstNull (eltype);
7906 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "assembly_name");
7907 if (!module->llvm_only) {
7908 fields [tindex ++] = AddJitGlobal (module, eltype, "plt");
7909 fields [tindex ++] = AddJitGlobal (module, eltype, "plt_end");
7910 fields [tindex ++] = AddJitGlobal (module, eltype, "unwind_info");
7911 fields [tindex ++] = AddJitGlobal (module, eltype, "unbox_trampolines");
7912 fields [tindex ++] = AddJitGlobal (module, eltype, "unbox_trampolines_end");
7913 fields [tindex ++] = AddJitGlobal (module, eltype, "unbox_trampoline_addresses");
7915 fields [tindex ++] = LLVMConstNull (eltype);
7916 fields [tindex ++] = LLVMConstNull (eltype);
7917 fields [tindex ++] = LLVMConstNull (eltype);
7918 fields [tindex ++] = LLVMConstNull (eltype);
7919 fields [tindex ++] = LLVMConstNull (eltype);
7920 fields [tindex ++] = LLVMConstNull (eltype);
7923 for (i = 0; i < MONO_AOT_FILE_INFO_NUM_SYMBOLS; ++i)
7924 fields [2 + i] = LLVMConstBitCast (fields [2 + i], eltype);
7927 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->plt_got_offset_base, FALSE);
7928 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->got_size, FALSE);
7929 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->plt_size, FALSE);
7930 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->nmethods, FALSE);
7931 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->flags, FALSE);
7932 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->opts, FALSE);
7933 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->simd_opts, FALSE);
7934 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->gc_name_index, FALSE);
7935 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->num_rgctx_fetch_trampolines, FALSE);
7936 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->double_align, FALSE);
7937 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->long_align, FALSE);
7938 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->generic_tramp_num, FALSE);
7939 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->tramp_page_size, FALSE);
7940 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->nshared_got_entries, FALSE);
7941 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->datafile_size, FALSE);
7943 fields [tindex ++] = llvm_array_from_uints (LLVMInt32Type (), info->table_offsets, MONO_AOT_TABLE_NUM);
7944 fields [tindex ++] = llvm_array_from_uints (LLVMInt32Type (), info->num_trampolines, MONO_AOT_TRAMP_NUM);
7945 fields [tindex ++] = llvm_array_from_uints (LLVMInt32Type (), info->trampoline_got_offset_base, MONO_AOT_TRAMP_NUM);
7946 fields [tindex ++] = llvm_array_from_uints (LLVMInt32Type (), info->trampoline_size, MONO_AOT_TRAMP_NUM);
7947 fields [tindex ++] = llvm_array_from_uints (LLVMInt32Type (), info->tramp_page_code_offsets, MONO_AOT_TRAMP_NUM);
7948 g_assert (tindex == nfields);
7950 LLVMSetInitializer (info_var, LLVMConstNamedStruct (file_info_type, fields, nfields));
7952 if (module->static_link) {
7956 s = g_strdup_printf ("mono_aot_module_%s_info", module->assembly->aname.name);
7957 /* Get rid of characters which cannot occur in symbols */
7959 for (p = s; *p; ++p) {
7960 if (!(isalnum (*p) || *p == '_'))
7963 var = LLVMAddGlobal (module->lmodule, LLVMPointerType (LLVMInt8Type (), 0), s);
7965 LLVMSetInitializer (var, LLVMConstBitCast (LLVMGetNamedGlobal (module->lmodule, "mono_aot_file_info"), LLVMPointerType (LLVMInt8Type (), 0)));
7966 LLVMSetLinkage (var, LLVMExternalLinkage);
7971 * Emit the aot module into the LLVM bitcode file FILENAME.
7974 mono_llvm_emit_aot_module (const char *filename, const char *cu_name)
7976 LLVMTypeRef got_type, inited_type;
7977 LLVMValueRef real_got, real_inited;
7978 MonoLLVMModule *module = &aot_module;
7980 emit_llvm_code_end (module);
7983 * Create the real got variable and replace all uses of the dummy variable with
7986 got_type = LLVMArrayType (module->ptr_type, module->max_got_offset + 1);
7987 real_got = LLVMAddGlobal (module->lmodule, got_type, module->got_symbol);
7988 LLVMSetInitializer (real_got, LLVMConstNull (got_type));
7989 if (module->external_symbols) {
7990 LLVMSetLinkage (real_got, LLVMExternalLinkage);
7991 LLVMSetVisibility (real_got, LLVMHiddenVisibility);
7993 LLVMSetLinkage (real_got, LLVMInternalLinkage);
7995 mono_llvm_replace_uses_of (module->got_var, real_got);
7997 mark_as_used (&aot_module, real_got);
7999 /* Delete the dummy got so it doesn't become a global */
8000 LLVMDeleteGlobal (module->got_var);
8001 module->got_var = real_got;
8004 * Same for the init_var
8006 if (module->llvm_only) {
8007 inited_type = LLVMArrayType (LLVMInt8Type (), module->max_inited_idx + 1);
8008 real_inited = LLVMAddGlobal (module->lmodule, inited_type, "mono_inited");
8009 LLVMSetInitializer (real_inited, LLVMConstNull (inited_type));
8010 LLVMSetLinkage (real_inited, LLVMInternalLinkage);
8011 mono_llvm_replace_uses_of (module->inited_var, real_inited);
8012 LLVMDeleteGlobal (module->inited_var);
8015 if (module->llvm_only) {
8016 emit_get_method (&aot_module);
8017 emit_get_unbox_tramp (&aot_module);
8020 emit_llvm_used (&aot_module);
8021 emit_dbg_info (&aot_module, filename, cu_name);
8022 emit_aot_file_info (&aot_module);
8025 * Replace GOT entries for directly callable methods with the methods themselves.
8026 * It would be easier to implement this by predefining all methods before compiling
8027 * their bodies, but that couldn't handle the case when a method fails to compile
8030 if (module->llvm_only) {
8031 GHashTableIter iter;
8033 GSList *callers, *l;
8035 g_hash_table_iter_init (&iter, module->method_to_callers);
8036 while (g_hash_table_iter_next (&iter, (void**)&method, (void**)&callers)) {
8037 LLVMValueRef lmethod;
8039 lmethod = (LLVMValueRef)g_hash_table_lookup (module->method_to_lmethod, method);
8041 for (l = callers; l; l = l->next) {
8042 LLVMValueRef caller = (LLVMValueRef)l->data;
8044 mono_llvm_replace_uses_of (caller, lmethod);
8050 /* Replace PLT entries for directly callable methods with the methods themselves */
8052 GHashTableIter iter;
8054 LLVMValueRef callee;
8056 g_hash_table_iter_init (&iter, module->plt_entries_ji);
8057 while (g_hash_table_iter_next (&iter, (void**)&ji, (void**)&callee)) {
8058 if (mono_aot_is_direct_callable (ji)) {
8059 LLVMValueRef lmethod;
8061 lmethod = (LLVMValueRef)g_hash_table_lookup (module->method_to_lmethod, ji->data.method);
8062 /* The types might not match because the caller might pass an rgctx */
8063 if (lmethod && LLVMTypeOf (callee) == LLVMTypeOf (lmethod)) {
8064 mono_llvm_replace_uses_of (callee, lmethod);
8065 mono_aot_mark_unused_llvm_plt_entry (ji);
8075 if (LLVMVerifyModule (module->lmodule, LLVMReturnStatusAction, &verifier_err)) {
8076 g_assert_not_reached ();
8081 LLVMWriteBitcodeToFile (module->lmodule, filename);
8086 md_string (const char *s)
8088 return LLVMMDString (s, strlen (s));
8091 /* Debugging support */
8094 emit_dbg_info (MonoLLVMModule *module, const char *filename, const char *cu_name)
8096 LLVMModuleRef lmodule = module->lmodule;
8097 LLVMValueRef args [16], ver;
8100 * This can only be enabled when LLVM code is emitted into a separate object
8101 * file, since the AOT compiler also emits dwarf info,
8102 * and the abbrev indexes will not be correct since llvm has added its own
8105 if (!module->emit_dwarf)
8108 #if LLVM_API_VERSION > 100
8109 mono_llvm_di_builder_finalize (module->di_builder);
8111 LLVMValueRef cu_args [16], cu;
8113 char *build_info, *s, *dir;
8116 * Emit dwarf info in the form of LLVM metadata. There is some
8117 * out-of-date documentation at:
8118 * http://llvm.org/docs/SourceLevelDebugging.html
8119 * but most of this was gathered from the llvm and
8124 cu_args [n_cuargs ++] = LLVMConstInt (LLVMInt32Type (), DW_TAG_compile_unit, FALSE);
8125 /* CU name/compilation dir */
8126 dir = g_path_get_dirname (filename);
8127 args [0] = LLVMMDString (cu_name, strlen (cu_name));
8128 args [1] = LLVMMDString (dir, strlen (dir));
8129 cu_args [n_cuargs ++] = LLVMMDNode (args, 2);
8132 cu_args [n_cuargs ++] = LLVMConstInt (LLVMInt32Type (), DW_LANG_C99, FALSE);
8134 build_info = mono_get_runtime_build_info ();
8135 s = g_strdup_printf ("Mono AOT Compiler %s (LLVM)", build_info);
8136 cu_args [n_cuargs ++] = LLVMMDString (s, strlen (s));
8137 g_free (build_info);
8139 cu_args [n_cuargs ++] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
8141 cu_args [n_cuargs ++] = LLVMMDString ("", strlen (""));
8142 /* Runtime version */
8143 cu_args [n_cuargs ++] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
8145 cu_args [n_cuargs ++] = LLVMMDNode (args, 0);
8146 cu_args [n_cuargs ++] = LLVMMDNode (args, 0);
8148 if (module->subprogram_mds) {
8152 mds = g_new0 (LLVMValueRef, module->subprogram_mds->len);
8153 for (i = 0; i < module->subprogram_mds->len; ++i)
8154 mds [i] = (LLVMValueRef)g_ptr_array_index (module->subprogram_mds, i);
8155 cu_args [n_cuargs ++] = LLVMMDNode (mds, module->subprogram_mds->len);
8157 cu_args [n_cuargs ++] = LLVMMDNode (args, 0);
8160 cu_args [n_cuargs ++] = LLVMMDNode (args, 0);
8161 /* Imported modules */
8162 cu_args [n_cuargs ++] = LLVMMDNode (args, 0);
8164 cu_args [n_cuargs ++] = LLVMMDString ("", strlen (""));
8165 /* DebugEmissionKind = FullDebug */
8166 cu_args [n_cuargs ++] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
8167 cu = LLVMMDNode (cu_args, n_cuargs);
8168 LLVMAddNamedMetadataOperand (lmodule, "llvm.dbg.cu", cu);
8171 #if LLVM_API_VERSION > 100
8172 args [0] = LLVMConstInt (LLVMInt32Type (), 2, FALSE);
8173 args [1] = LLVMMDString ("Dwarf Version", strlen ("Dwarf Version"));
8174 args [2] = LLVMConstInt (LLVMInt32Type (), 2, FALSE);
8175 ver = LLVMMDNode (args, 3);
8176 LLVMAddNamedMetadataOperand (lmodule, "llvm.module.flags", ver);
8178 args [0] = LLVMConstInt (LLVMInt32Type (), 2, FALSE);
8179 args [1] = LLVMMDString ("Debug Info Version", strlen ("Debug Info Version"));
8180 args [2] = LLVMConstInt (LLVMInt64Type (), 3, FALSE);
8181 ver = LLVMMDNode (args, 3);
8182 LLVMAddNamedMetadataOperand (lmodule, "llvm.module.flags", ver);
8184 args [0] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
8185 args [1] = LLVMMDString ("Dwarf Version", strlen ("Dwarf Version"));
8186 args [2] = LLVMConstInt (LLVMInt32Type (), 2, FALSE);
8187 ver = LLVMMDNode (args, 3);
8188 LLVMAddNamedMetadataOperand (lmodule, "llvm.module.flags", ver);
8190 args [0] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
8191 args [1] = LLVMMDString ("Debug Info Version", strlen ("Debug Info Version"));
8192 args [2] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
8193 ver = LLVMMDNode (args, 3);
8194 LLVMAddNamedMetadataOperand (lmodule, "llvm.module.flags", ver);
8199 emit_dbg_subprogram (EmitContext *ctx, MonoCompile *cfg, LLVMValueRef method, const char *name)
8201 MonoLLVMModule *module = ctx->module;
8202 MonoDebugMethodInfo *minfo = ctx->minfo;
8203 char *source_file, *dir, *filename;
8204 LLVMValueRef md, args [16], ctx_args [16], md_args [64], type_args [16], ctx_md, type_md;
8205 MonoSymSeqPoint *sym_seq_points;
8211 mono_debug_symfile_get_seq_points (minfo, &source_file, NULL, NULL, &sym_seq_points, &n_seq_points);
8213 source_file = g_strdup ("<unknown>");
8214 dir = g_path_get_dirname (source_file);
8215 filename = g_path_get_basename (source_file);
8217 #if LLVM_API_VERSION > 100
8218 return mono_llvm_di_create_function (module->di_builder, module->cu, cfg->method->name, name, dir, filename, n_seq_points ? sym_seq_points [0].line : 1);
8221 ctx_args [0] = LLVMConstInt (LLVMInt32Type (), 0x29, FALSE);
8222 args [0] = md_string (filename);
8223 args [1] = md_string (dir);
8224 ctx_args [1] = LLVMMDNode (args, 2);
8225 ctx_md = LLVMMDNode (ctx_args, 2);
8227 type_args [0] = LLVMConstInt (LLVMInt32Type (), DW_TAG_subroutine_type, FALSE);
8228 type_args [1] = NULL;
8229 type_args [2] = NULL;
8230 type_args [3] = LLVMMDString ("", 0);
8231 type_args [4] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
8232 type_args [5] = LLVMConstInt (LLVMInt64Type (), 0, FALSE);
8233 type_args [6] = LLVMConstInt (LLVMInt64Type (), 0, FALSE);
8234 type_args [7] = LLVMConstInt (LLVMInt64Type (), 0, FALSE);
8235 type_args [8] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
8236 type_args [9] = NULL;
8237 type_args [10] = NULL;
8238 type_args [11] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
8239 type_args [12] = NULL;
8240 type_args [13] = NULL;
8241 type_args [14] = NULL;
8242 type_md = LLVMMDNode (type_args, 14);
8244 /* http://llvm.org/docs/SourceLevelDebugging.html#subprogram-descriptors */
8245 md_args [0] = LLVMConstInt (LLVMInt32Type (), DW_TAG_subprogram, FALSE);
8246 /* Source directory + file pair */
8247 args [0] = md_string (filename);
8248 args [1] = md_string (dir);
8249 md_args [1] = LLVMMDNode (args ,2);
8250 md_args [2] = ctx_md;
8251 md_args [3] = md_string (cfg->method->name);
8252 md_args [4] = md_string (name);
8253 md_args [5] = md_string (name);
8256 md_args [6] = LLVMConstInt (LLVMInt32Type (), sym_seq_points [0].line, FALSE);
8258 md_args [6] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
8260 md_args [7] = type_md;
8262 md_args [8] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
8264 md_args [9] = LLVMConstInt (LLVMInt1Type (), 1, FALSE);
8266 md_args [10] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
8267 /* Index into a virtual function */
8268 md_args [11] = NULL;
8269 md_args [12] = NULL;
8271 md_args [13] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
8273 md_args [14] = LLVMConstInt (LLVMInt1Type (), 1, FALSE);
8274 /* Pointer to LLVM function */
8275 md_args [15] = method;
8276 /* Function template parameter */
8277 md_args [16] = NULL;
8278 /* Function declaration descriptor */
8279 md_args [17] = NULL;
8280 /* List of function variables */
8281 md_args [18] = LLVMMDNode (args, 0);
8283 md_args [19] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
8284 md = LLVMMDNode (md_args, 20);
8286 if (!module->subprogram_mds)
8287 module->subprogram_mds = g_ptr_array_new ();
8288 g_ptr_array_add (module->subprogram_mds, md);
8292 g_free (source_file);
8293 g_free (sym_seq_points);
8299 emit_dbg_loc (EmitContext *ctx, LLVMBuilderRef builder, const unsigned char *cil_code)
8301 MonoCompile *cfg = ctx->cfg;
8303 if (ctx->minfo && cil_code && cil_code >= cfg->header->code && cil_code < cfg->header->code + cfg->header->code_size) {
8304 MonoDebugSourceLocation *loc;
8305 LLVMValueRef loc_md;
8307 loc = mono_debug_symfile_lookup_location (ctx->minfo, cil_code - cfg->header->code);
8310 #if LLVM_API_VERSION > 100
8311 loc_md = mono_llvm_di_create_location (ctx->module->di_builder, ctx->dbg_md, loc->row, loc->column);
8312 mono_llvm_di_set_location (builder, loc_md);
8314 LLVMValueRef md_args [16];
8318 md_args [nmd_args ++] = LLVMConstInt (LLVMInt32Type (), loc->row, FALSE);
8319 md_args [nmd_args ++] = LLVMConstInt (LLVMInt32Type (), loc->column, FALSE);
8320 md_args [nmd_args ++] = ctx->dbg_md;
8321 md_args [nmd_args ++] = NULL;
8322 loc_md = LLVMMDNode (md_args, nmd_args);
8323 LLVMSetCurrentDebugLocation (builder, loc_md);
8325 mono_debug_symfile_free_location (loc);
8331 default_mono_llvm_unhandled_exception (void)
8333 MonoJitTlsData *jit_tls = mono_get_jit_tls ();
8334 MonoObject *target = mono_gchandle_get_target (jit_tls->thrown_exc);
8336 mono_unhandled_exception (target);
8337 exit (mono_environment_exitcode_get ());
8342 - Emit LLVM IR from the mono IR using the LLVM C API.
8343 - The original arch specific code remains, so we can fall back to it if we run
8344 into something we can't handle.
8348 A partial list of issues:
8349 - Handling of opcodes which can throw exceptions.
8351 In the mono JIT, these are implemented using code like this:
8358 push throw_pos - method
8359 call <exception trampoline>
8361 The problematic part is push throw_pos - method, which cannot be represented
8362 in the LLVM IR, since it does not support label values.
8363 -> this can be implemented in AOT mode using inline asm + labels, but cannot
8364 be implemented in JIT mode ?
8365 -> a possible but slower implementation would use the normal exception
8366 throwing code but it would need to control the placement of the throw code
8367 (it needs to be exactly after the compare+branch).
8368 -> perhaps add a PC offset intrinsics ?
8370 - efficient implementation of .ovf opcodes.
8372 These are currently implemented as:
8373 <ins which sets the condition codes>
8376 Some overflow opcodes are now supported by LLVM SVN.
8378 - exception handling, unwinding.
8379 - SSA is disabled for methods with exception handlers
8380 - How to obtain unwind info for LLVM compiled methods ?
8381 -> this is now solved by converting the unwind info generated by LLVM
8383 - LLVM uses the c++ exception handling framework, while we use our home grown
8384 code, and couldn't use the c++ one:
8385 - its not supported under VC++, other exotic platforms.
8386 - it might be impossible to support filter clauses with it.
8390 The trampolines need a predictable call sequence, since they need to disasm
8391 the calling code to obtain register numbers / offsets.
8393 LLVM currently generates this code in non-JIT mode:
8394 mov -0x98(%rax),%eax
8396 Here, the vtable pointer is lost.
8397 -> solution: use one vtable trampoline per class.
8399 - passing/receiving the IMT pointer/RGCTX.
8400 -> solution: pass them as normal arguments ?
8404 LLVM does not allow the specification of argument registers etc. This means
8405 that all calls are made according to the platform ABI.
8407 - passing/receiving vtypes.
8409 Vtypes passed/received in registers are handled by the front end by using
8410 a signature with scalar arguments, and loading the parts of the vtype into those
8413 Vtypes passed on the stack are handled using the 'byval' attribute.
8417 Supported though alloca, we need to emit the load/store code.
8421 The mono JIT uses pointer sized iregs/double fregs, while LLVM uses precisely
8422 typed registers, so we have to keep track of the precise LLVM type of each vreg.
8423 This is made easier because the IR is already in SSA form.
8424 An additional problem is that our IR is not consistent with types, i.e. i32/ia64
8425 types are frequently used incorrectly.
8430 Emit LLVM bytecode into a .bc file, compile it using llc into a .s file, then link
8431 it with the file containing the methods emitted by the JIT and the AOT data
8435 /* FIXME: Normalize some aspects of the mono IR to allow easier translation, like:
8436 * - each bblock should end with a branch
8437 * - setting the return value, making cfg->ret non-volatile
8438 * - avoid some transformations in the JIT which make it harder for us to generate
8440 * - use pointer types to help optimizations.