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 LLVMArgScalarRetAddr:
1296 case LLVMArgGsharedvtFixed:
1297 case LLVMArgGsharedvtFixedVtype:
1298 case LLVMArgGsharedvtVariable:
1300 ret_type = LLVMVoidType ();
1306 param_types = g_new0 (LLVMTypeRef, (sig->param_count * 8) + 3);
1308 if (cinfo->ret.storage == LLVMArgVtypeByRef) {
1310 * Has to be the first argument because of the sret argument attribute
1311 * FIXME: This might conflict with passing 'this' as the first argument, but
1312 * this is only used on arm64 which has a dedicated struct return register.
1314 cinfo->vret_arg_pindex = pindex;
1315 param_types [pindex] = type_to_llvm_arg_type (ctx, sig->ret);
1316 if (!ctx_ok (ctx)) {
1317 g_free (param_types);
1320 param_types [pindex] = LLVMPointerType (param_types [pindex], 0);
1323 if (!ctx->llvm_only && cinfo->rgctx_arg) {
1324 cinfo->rgctx_arg_pindex = pindex;
1325 param_types [pindex] = ctx->module->ptr_type;
1328 if (cinfo->imt_arg) {
1329 cinfo->imt_arg_pindex = pindex;
1330 param_types [pindex] = ctx->module->ptr_type;
1334 /* Compute the index in the LLVM signature where the vret arg needs to be passed */
1335 vret_arg_pindex = pindex;
1336 if (cinfo->vret_arg_index == 1) {
1337 /* Add the slots consumed by the first argument */
1338 LLVMArgInfo *ainfo = &cinfo->args [0];
1339 switch (ainfo->storage) {
1340 case LLVMArgVtypeInReg:
1341 for (j = 0; j < 2; ++j) {
1342 if (ainfo->pair_storage [j] == LLVMArgInIReg)
1351 cinfo->vret_arg_pindex = vret_arg_pindex;
1354 if (vretaddr && vret_arg_pindex == pindex)
1355 param_types [pindex ++] = IntPtrType ();
1357 cinfo->this_arg_pindex = pindex;
1358 param_types [pindex ++] = ThisType ();
1359 cinfo->args [0].pindex = cinfo->this_arg_pindex;
1361 if (vretaddr && vret_arg_pindex == pindex)
1362 param_types [pindex ++] = IntPtrType ();
1363 for (i = 0; i < sig->param_count; ++i) {
1364 LLVMArgInfo *ainfo = &cinfo->args [i + sig->hasthis];
1366 if (vretaddr && vret_arg_pindex == pindex)
1367 param_types [pindex ++] = IntPtrType ();
1368 ainfo->pindex = pindex;
1370 switch (ainfo->storage) {
1371 case LLVMArgVtypeInReg:
1372 for (j = 0; j < 2; ++j) {
1373 switch (ainfo->pair_storage [j]) {
1375 param_types [pindex ++] = LLVMIntType (sizeof (gpointer) * 8);
1380 g_assert_not_reached ();
1384 case LLVMArgVtypeByVal:
1385 param_types [pindex] = type_to_llvm_arg_type (ctx, ainfo->type);
1388 param_types [pindex] = LLVMPointerType (param_types [pindex], 0);
1391 case LLVMArgAsIArgs:
1392 param_types [pindex] = LLVMArrayType (IntPtrType (), ainfo->nslots);
1395 case LLVMArgVtypeByRef:
1396 case LLVMArgScalarByRef:
1397 param_types [pindex] = type_to_llvm_arg_type (ctx, ainfo->type);
1400 param_types [pindex] = LLVMPointerType (param_types [pindex], 0);
1403 case LLVMArgAsFpArgs: {
1406 /* Emit dummy fp arguments if needed so the rest is passed on the stack */
1407 for (j = 0; j < ainfo->ndummy_fpargs; ++j)
1408 param_types [pindex ++] = LLVMDoubleType ();
1409 for (j = 0; j < ainfo->nslots; ++j)
1410 param_types [pindex ++] = ainfo->esize == 8 ? LLVMDoubleType () : LLVMFloatType ();
1413 case LLVMArgVtypeAsScalar:
1414 g_assert_not_reached ();
1416 case LLVMArgGsharedvtFixed:
1417 case LLVMArgGsharedvtFixedVtype:
1418 param_types [pindex ++] = LLVMPointerType (type_to_llvm_arg_type (ctx, ainfo->type), 0);
1420 case LLVMArgGsharedvtVariable:
1421 param_types [pindex ++] = LLVMPointerType (IntPtrType (), 0);
1424 param_types [pindex ++] = type_to_llvm_arg_type (ctx, ainfo->type);
1428 if (!ctx_ok (ctx)) {
1429 g_free (param_types);
1432 if (vretaddr && vret_arg_pindex == pindex)
1433 param_types [pindex ++] = IntPtrType ();
1434 if (ctx->llvm_only && cinfo->rgctx_arg) {
1435 /* Pass the rgctx as the last argument */
1436 cinfo->rgctx_arg_pindex = pindex;
1437 param_types [pindex] = ctx->module->ptr_type;
1441 res = LLVMFunctionType (ret_type, param_types, pindex, FALSE);
1442 g_free (param_types);
1448 sig_to_llvm_sig (EmitContext *ctx, MonoMethodSignature *sig)
1450 return sig_to_llvm_sig_full (ctx, sig, NULL);
1454 * LLVMFunctionType1:
1456 * Create an LLVM function type from the arguments.
1458 static G_GNUC_UNUSED LLVMTypeRef
1459 LLVMFunctionType0 (LLVMTypeRef ReturnType,
1462 return LLVMFunctionType (ReturnType, NULL, 0, IsVarArg);
1466 * LLVMFunctionType1:
1468 * Create an LLVM function type from the arguments.
1470 static G_GNUC_UNUSED LLVMTypeRef
1471 LLVMFunctionType1 (LLVMTypeRef ReturnType,
1472 LLVMTypeRef ParamType1,
1475 LLVMTypeRef param_types [1];
1477 param_types [0] = ParamType1;
1479 return LLVMFunctionType (ReturnType, param_types, 1, IsVarArg);
1483 * LLVMFunctionType2:
1485 * Create an LLVM function type from the arguments.
1487 static G_GNUC_UNUSED LLVMTypeRef
1488 LLVMFunctionType2 (LLVMTypeRef ReturnType,
1489 LLVMTypeRef ParamType1,
1490 LLVMTypeRef ParamType2,
1493 LLVMTypeRef param_types [2];
1495 param_types [0] = ParamType1;
1496 param_types [1] = ParamType2;
1498 return LLVMFunctionType (ReturnType, param_types, 2, IsVarArg);
1502 * LLVMFunctionType3:
1504 * Create an LLVM function type from the arguments.
1506 static G_GNUC_UNUSED LLVMTypeRef
1507 LLVMFunctionType3 (LLVMTypeRef ReturnType,
1508 LLVMTypeRef ParamType1,
1509 LLVMTypeRef ParamType2,
1510 LLVMTypeRef ParamType3,
1513 LLVMTypeRef param_types [3];
1515 param_types [0] = ParamType1;
1516 param_types [1] = ParamType2;
1517 param_types [2] = ParamType3;
1519 return LLVMFunctionType (ReturnType, param_types, 3, IsVarArg);
1522 static G_GNUC_UNUSED LLVMTypeRef
1523 LLVMFunctionType5 (LLVMTypeRef ReturnType,
1524 LLVMTypeRef ParamType1,
1525 LLVMTypeRef ParamType2,
1526 LLVMTypeRef ParamType3,
1527 LLVMTypeRef ParamType4,
1528 LLVMTypeRef ParamType5,
1531 LLVMTypeRef param_types [5];
1533 param_types [0] = ParamType1;
1534 param_types [1] = ParamType2;
1535 param_types [2] = ParamType3;
1536 param_types [3] = ParamType4;
1537 param_types [4] = ParamType5;
1539 return LLVMFunctionType (ReturnType, param_types, 5, IsVarArg);
1545 * Create an LLVM builder and remember it so it can be freed later.
1547 static LLVMBuilderRef
1548 create_builder (EmitContext *ctx)
1550 LLVMBuilderRef builder = LLVMCreateBuilder ();
1552 ctx->builders = g_slist_prepend_mempool (ctx->cfg->mempool, ctx->builders, builder);
1558 get_aotconst_name (MonoJumpInfoType type, gconstpointer data, int got_offset)
1563 case MONO_PATCH_INFO_INTERNAL_METHOD:
1564 name = g_strdup_printf ("jit_icall_%s", data);
1566 case MONO_PATCH_INFO_RGCTX_SLOT_INDEX: {
1567 MonoJumpInfoRgctxEntry *entry = (MonoJumpInfoRgctxEntry*)data;
1568 name = g_strdup_printf ("RGCTX_SLOT_INDEX_%s", mono_rgctx_info_type_to_str (entry->info_type));
1572 name = g_strdup_printf ("%s_%d", mono_ji_type_to_string (type), got_offset);
1580 get_aotconst_typed (EmitContext *ctx, MonoJumpInfoType type, gconstpointer data, LLVMTypeRef llvm_type)
1584 LLVMValueRef indexes [2];
1586 LLVMValueRef got_entry_addr, load;
1587 LLVMBuilderRef builder = ctx->builder;
1592 ji = g_new0 (MonoJumpInfo, 1);
1594 ji->data.target = data;
1596 ji = mono_aot_patch_info_dup (ji);
1598 ji->next = cfg->patch_info;
1599 cfg->patch_info = ji;
1601 got_offset = mono_aot_get_got_offset (cfg->patch_info);
1602 ctx->module->max_got_offset = MAX (ctx->module->max_got_offset, got_offset);
1604 * If the got slot is shared, it means its initialized when the aot image is loaded, so we don't need to
1605 * explicitly initialize it.
1607 if (!mono_aot_is_shared_got_offset (got_offset)) {
1608 //mono_print_ji (ji);
1610 ctx->has_got_access = TRUE;
1613 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
1614 indexes [1] = LLVMConstInt (LLVMInt32Type (), (gssize)got_offset, FALSE);
1615 got_entry_addr = LLVMBuildGEP (builder, ctx->module->got_var, indexes, 2, "");
1617 name = get_aotconst_name (type, data, got_offset);
1619 load = LLVMBuildLoad (builder, got_entry_addr, "");
1620 load = convert (ctx, load, llvm_type);
1621 LLVMSetValueName (load, name ? name : "");
1623 load = LLVMBuildLoad (builder, got_entry_addr, name ? name : "");
1626 //set_invariant_load_flag (load);
1632 get_aotconst (EmitContext *ctx, MonoJumpInfoType type, gconstpointer data)
1634 return get_aotconst_typed (ctx, type, data, NULL);
1638 get_callee (EmitContext *ctx, LLVMTypeRef llvm_sig, MonoJumpInfoType type, gconstpointer data)
1640 LLVMValueRef callee;
1642 if (ctx->llvm_only) {
1643 callee_name = mono_aot_get_direct_call_symbol (type, data);
1645 /* Directly callable */
1647 callee = (LLVMValueRef)g_hash_table_lookup (ctx->module->direct_callables, callee_name);
1649 callee = LLVMAddFunction (ctx->lmodule, callee_name, llvm_sig);
1651 LLVMSetVisibility (callee, LLVMHiddenVisibility);
1653 g_hash_table_insert (ctx->module->direct_callables, (char*)callee_name, callee);
1655 /* LLVMTypeRef's are uniqued */
1656 if (LLVMGetElementType (LLVMTypeOf (callee)) != llvm_sig)
1657 return LLVMConstBitCast (callee, LLVMPointerType (llvm_sig, 0));
1659 g_free (callee_name);
1665 * Calls are made through the GOT.
1667 return get_aotconst_typed (ctx, type, data, LLVMPointerType (llvm_sig, 0));
1669 MonoJumpInfo *ji = NULL;
1671 callee_name = mono_aot_get_plt_symbol (type, data);
1675 if (ctx->cfg->compile_aot)
1676 /* Add a patch so referenced wrappers can be compiled in full aot mode */
1677 mono_add_patch_info (ctx->cfg, 0, type, data);
1680 callee = (LLVMValueRef)g_hash_table_lookup (ctx->module->plt_entries, callee_name);
1682 callee = LLVMAddFunction (ctx->lmodule, callee_name, llvm_sig);
1684 LLVMSetVisibility (callee, LLVMHiddenVisibility);
1686 g_hash_table_insert (ctx->module->plt_entries, (char*)callee_name, callee);
1689 if (ctx->cfg->compile_aot) {
1690 ji = g_new0 (MonoJumpInfo, 1);
1692 ji->data.target = data;
1694 g_hash_table_insert (ctx->module->plt_entries_ji, ji, callee);
1702 get_handler_clause (MonoCompile *cfg, MonoBasicBlock *bb)
1704 MonoMethodHeader *header = cfg->header;
1705 MonoExceptionClause *clause;
1709 if (bb->region != -1 && MONO_BBLOCK_IS_IN_REGION (bb, MONO_REGION_TRY))
1710 return (bb->region >> 8) - 1;
1713 for (i = 0; i < header->num_clauses; ++i) {
1714 clause = &header->clauses [i];
1716 if (MONO_OFFSET_IN_CLAUSE (clause, bb->real_offset) && clause->flags == MONO_EXCEPTION_CLAUSE_NONE)
1723 static MonoExceptionClause *
1724 get_most_deep_clause (MonoCompile *cfg, EmitContext *ctx, MonoBasicBlock *bb)
1726 // Since they're sorted by nesting we just need
1727 // the first one that the bb is a member of
1728 MonoExceptionClause *last = NULL;
1730 for (int i = 0; i < cfg->header->num_clauses; i++) {
1731 MonoExceptionClause *curr = &cfg->header->clauses [i];
1733 if (MONO_OFFSET_IN_CLAUSE (curr, bb->real_offset))
1736 if (MONO_OFFSET_IN_CLAUSE (curr, bb->real_offset)) {
1737 if (last && CLAUSE_END(last) > CLAUSE_END(curr))
1751 set_metadata_flag (LLVMValueRef v, const char *flag_name)
1753 LLVMValueRef md_arg;
1756 md_kind = LLVMGetMDKindID (flag_name, strlen (flag_name));
1757 md_arg = LLVMMDString ("mono", 4);
1758 LLVMSetMetadata (v, md_kind, LLVMMDNode (&md_arg, 1));
1762 set_invariant_load_flag (LLVMValueRef v)
1764 LLVMValueRef md_arg;
1766 const char *flag_name;
1768 // FIXME: Cache this
1769 flag_name = "invariant.load";
1770 md_kind = LLVMGetMDKindID (flag_name, strlen (flag_name));
1771 md_arg = LLVMMDString ("<index>", strlen ("<index>"));
1772 LLVMSetMetadata (v, md_kind, LLVMMDNode (&md_arg, 1));
1778 * Emit an LLVM call or invoke instruction depending on whenever the call is inside
1782 emit_call (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, LLVMValueRef callee, LLVMValueRef *args, int pindex)
1784 MonoCompile *cfg = ctx->cfg;
1785 LLVMValueRef lcall = NULL;
1786 LLVMBuilderRef builder = *builder_ref;
1787 MonoExceptionClause *clause;
1789 if (ctx->llvm_only) {
1790 clause = get_most_deep_clause (cfg, ctx, bb);
1793 g_assert (clause->flags == MONO_EXCEPTION_CLAUSE_NONE || clause->flags == MONO_EXCEPTION_CLAUSE_FINALLY);
1796 * Have to use an invoke instead of a call, branching to the
1797 * handler bblock of the clause containing this bblock.
1799 intptr_t key = CLAUSE_END(clause);
1801 LLVMBasicBlockRef lpad_bb = (LLVMBasicBlockRef)g_hash_table_lookup (ctx->exc_meta, (gconstpointer)key);
1803 // FIXME: Find the one that has the lowest end bound for the right start address
1804 // FIXME: Finally + nesting
1807 LLVMBasicBlockRef noex_bb = gen_bb (ctx, "CALL_NOEX_BB");
1810 lcall = LLVMBuildInvoke (builder, callee, args, pindex, noex_bb, lpad_bb, "");
1812 builder = ctx->builder = create_builder (ctx);
1813 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
1815 ctx->bblocks [bb->block_num].end_bblock = noex_bb;
1819 int clause_index = get_handler_clause (cfg, bb);
1821 if (clause_index != -1) {
1822 MonoMethodHeader *header = cfg->header;
1823 MonoExceptionClause *ec = &header->clauses [clause_index];
1824 MonoBasicBlock *tblock;
1825 LLVMBasicBlockRef ex_bb, noex_bb;
1828 * Have to use an invoke instead of a call, branching to the
1829 * handler bblock of the clause containing this bblock.
1832 g_assert (ec->flags == MONO_EXCEPTION_CLAUSE_NONE || ec->flags == MONO_EXCEPTION_CLAUSE_FINALLY);
1834 tblock = cfg->cil_offset_to_bb [ec->handler_offset];
1837 ctx->bblocks [tblock->block_num].invoke_target = TRUE;
1839 ex_bb = get_bb (ctx, tblock);
1841 noex_bb = gen_bb (ctx, "NOEX_BB");
1844 lcall = LLVMBuildInvoke (builder, callee, args, pindex, noex_bb, ex_bb, "");
1846 builder = ctx->builder = create_builder (ctx);
1847 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
1849 ctx->bblocks [bb->block_num].end_bblock = noex_bb;
1854 lcall = LLVMBuildCall (builder, callee, args, pindex, "");
1855 ctx->builder = builder;
1859 *builder_ref = ctx->builder;
1865 emit_load_general (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, int size, LLVMValueRef addr, const char *name, gboolean is_faulting, BarrierKind barrier)
1867 const char *intrins_name;
1868 LLVMValueRef args [16], res;
1869 LLVMTypeRef addr_type;
1870 gboolean use_intrinsics = TRUE;
1872 #if LLVM_API_VERSION > 100
1873 if (is_faulting && bb->region != -1 && !ctx->cfg->llvm_only) {
1874 /* The llvm.mono.load/store intrinsics are not supported by this llvm version, emit an explicit null check instead */
1875 LLVMValueRef cmp = LLVMBuildICmp (*builder_ref, LLVMIntEQ, addr, LLVMConstNull (LLVMTypeOf (addr)), "");
1876 emit_cond_system_exception (ctx, bb, "NullReferenceException", cmp);
1877 *builder_ref = ctx->builder;
1878 use_intrinsics = FALSE;
1882 if (is_faulting && bb->region != -1 && !ctx->cfg->llvm_only && use_intrinsics) {
1883 LLVMAtomicOrdering ordering;
1886 case LLVM_BARRIER_NONE:
1887 ordering = LLVMAtomicOrderingNotAtomic;
1889 case LLVM_BARRIER_ACQ:
1890 ordering = LLVMAtomicOrderingAcquire;
1892 case LLVM_BARRIER_SEQ:
1893 ordering = LLVMAtomicOrderingSequentiallyConsistent;
1896 g_assert_not_reached ();
1901 * We handle loads which can fault by calling a mono specific intrinsic
1902 * using an invoke, so they are handled properly inside try blocks.
1903 * We can't use this outside clauses, since LLVM optimizes intrinsics which
1904 * are marked with IntrReadArgMem.
1908 intrins_name = "llvm.mono.load.i8.p0i8";
1911 intrins_name = "llvm.mono.load.i16.p0i16";
1914 intrins_name = "llvm.mono.load.i32.p0i32";
1917 intrins_name = "llvm.mono.load.i64.p0i64";
1920 g_assert_not_reached ();
1923 addr_type = LLVMTypeOf (addr);
1924 if (addr_type == LLVMPointerType (LLVMDoubleType (), 0) || addr_type == LLVMPointerType (LLVMFloatType (), 0))
1925 addr = LLVMBuildBitCast (*builder_ref, addr, LLVMPointerType (LLVMIntType (size * 8), 0), "");
1928 args [1] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
1929 args [2] = LLVMConstInt (LLVMInt1Type (), TRUE, FALSE);
1930 args [3] = LLVMConstInt (LLVMInt32Type (), ordering, FALSE);
1931 res = emit_call (ctx, bb, builder_ref, LLVMGetNamedFunction (ctx->lmodule, intrins_name), args, 4);
1933 if (addr_type == LLVMPointerType (LLVMDoubleType (), 0))
1934 res = LLVMBuildBitCast (*builder_ref, res, LLVMDoubleType (), "");
1935 else if (addr_type == LLVMPointerType (LLVMFloatType (), 0))
1936 res = LLVMBuildBitCast (*builder_ref, res, LLVMFloatType (), "");
1943 * We emit volatile loads for loads which can fault, because otherwise
1944 * LLVM will generate invalid code when encountering a load from a
1947 res = mono_llvm_build_load (*builder_ref, addr, name, is_faulting, barrier);
1949 /* Mark it with a custom metadata */
1952 set_metadata_flag (res, "mono.faulting.load");
1960 emit_load (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, int size, LLVMValueRef addr, const char *name, gboolean is_faulting)
1962 return emit_load_general (ctx, bb, builder_ref, size, addr, name, is_faulting, LLVM_BARRIER_NONE);
1966 emit_store_general (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, int size, LLVMValueRef value, LLVMValueRef addr, gboolean is_faulting, BarrierKind barrier)
1968 const char *intrins_name;
1969 LLVMValueRef args [16];
1970 gboolean use_intrinsics = TRUE;
1972 #if LLVM_API_VERSION > 100
1973 if (is_faulting && bb->region != -1 && !ctx->cfg->llvm_only) {
1974 /* The llvm.mono.load/store intrinsics are not supported by this llvm version, emit an explicit null check instead */
1975 LLVMValueRef cmp = LLVMBuildICmp (*builder_ref, LLVMIntEQ, addr, LLVMConstNull (LLVMTypeOf (addr)), "");
1976 emit_cond_system_exception (ctx, bb, "NullReferenceException", cmp);
1977 *builder_ref = ctx->builder;
1978 use_intrinsics = FALSE;
1982 if (is_faulting && bb->region != -1 && !ctx->cfg->llvm_only && use_intrinsics) {
1983 LLVMAtomicOrdering ordering;
1986 case LLVM_BARRIER_NONE:
1987 ordering = LLVMAtomicOrderingNotAtomic;
1989 case LLVM_BARRIER_REL:
1990 ordering = LLVMAtomicOrderingRelease;
1992 case LLVM_BARRIER_SEQ:
1993 ordering = LLVMAtomicOrderingSequentiallyConsistent;
1996 g_assert_not_reached ();
2002 intrins_name = "llvm.mono.store.i8.p0i8";
2005 intrins_name = "llvm.mono.store.i16.p0i16";
2008 intrins_name = "llvm.mono.store.i32.p0i32";
2011 intrins_name = "llvm.mono.store.i64.p0i64";
2014 g_assert_not_reached ();
2017 if (LLVMTypeOf (value) == LLVMDoubleType () || LLVMTypeOf (value) == LLVMFloatType ()) {
2018 value = LLVMBuildBitCast (*builder_ref, value, LLVMIntType (size * 8), "");
2019 addr = LLVMBuildBitCast (*builder_ref, addr, LLVMPointerType (LLVMIntType (size * 8), 0), "");
2024 args [2] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
2025 args [3] = LLVMConstInt (LLVMInt1Type (), TRUE, FALSE);
2026 args [4] = LLVMConstInt (LLVMInt32Type (), ordering, FALSE);
2027 emit_call (ctx, bb, builder_ref, LLVMGetNamedFunction (ctx->lmodule, intrins_name), args, 5);
2029 mono_llvm_build_store (*builder_ref, value, addr, is_faulting, barrier);
2034 emit_store (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, int size, LLVMValueRef value, LLVMValueRef addr, gboolean is_faulting)
2036 emit_store_general (ctx, bb, builder_ref, size, value, addr, is_faulting, LLVM_BARRIER_NONE);
2040 * emit_cond_system_exception:
2042 * Emit code to throw the exception EXC_TYPE if the condition CMP is false.
2043 * Might set the ctx exception.
2046 emit_cond_system_exception (EmitContext *ctx, MonoBasicBlock *bb, const char *exc_type, LLVMValueRef cmp)
2048 LLVMBasicBlockRef ex_bb, ex2_bb = NULL, noex_bb;
2049 LLVMBuilderRef builder;
2050 MonoClass *exc_class;
2051 LLVMValueRef args [2];
2052 LLVMValueRef callee;
2054 ex_bb = gen_bb (ctx, "EX_BB");
2056 ex2_bb = gen_bb (ctx, "EX2_BB");
2057 noex_bb = gen_bb (ctx, "NOEX_BB");
2059 LLVMBuildCondBr (ctx->builder, cmp, ex_bb, noex_bb);
2061 exc_class = mono_class_load_from_name (mono_get_corlib (), "System", exc_type);
2063 /* Emit exception throwing code */
2064 ctx->builder = builder = create_builder (ctx);
2065 LLVMPositionBuilderAtEnd (builder, ex_bb);
2067 if (ctx->cfg->llvm_only) {
2068 static LLVMTypeRef sig;
2071 sig = LLVMFunctionType1 (LLVMVoidType (), LLVMInt32Type (), FALSE);
2072 callee = get_callee (ctx, sig, MONO_PATCH_INFO_JIT_ICALL_ADDR, "mono_llvm_throw_corlib_exception");
2074 LLVMBuildBr (builder, ex2_bb);
2076 ctx->builder = builder = create_builder (ctx);
2077 LLVMPositionBuilderAtEnd (ctx->builder, ex2_bb);
2079 args [0] = LLVMConstInt (LLVMInt32Type (), exc_class->type_token - MONO_TOKEN_TYPE_DEF, FALSE);
2080 emit_call (ctx, bb, &builder, callee, args, 1);
2081 LLVMBuildUnreachable (builder);
2083 ctx->builder = builder = create_builder (ctx);
2084 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
2086 ctx->bblocks [bb->block_num].end_bblock = noex_bb;
2092 callee = ctx->module->throw_corlib_exception;
2095 const char *icall_name;
2097 sig = LLVMFunctionType2 (LLVMVoidType (), LLVMInt32Type (), LLVMPointerType (LLVMInt8Type (), 0), FALSE);
2098 icall_name = "llvm_throw_corlib_exception_abs_trampoline";
2100 if (ctx->cfg->compile_aot) {
2101 callee = get_callee (ctx, sig, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
2103 callee = LLVMAddFunction (ctx->lmodule, "llvm_throw_corlib_exception_trampoline", sig);
2106 * Differences between the LLVM/non-LLVM throw corlib exception trampoline:
2107 * - On x86, LLVM generated code doesn't push the arguments
2108 * - The trampoline takes the throw address as an arguments, not a pc offset.
2110 LLVMAddGlobalMapping (ctx->module->ee, callee, resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name));
2112 mono_memory_barrier ();
2113 ctx->module->throw_corlib_exception = callee;
2117 if (IS_TARGET_X86 || IS_TARGET_AMD64)
2118 args [0] = LLVMConstInt (LLVMInt32Type (), exc_class->type_token - MONO_TOKEN_TYPE_DEF, FALSE);
2120 args [0] = LLVMConstInt (LLVMInt32Type (), exc_class->type_token, FALSE);
2123 * The LLVM mono branch contains changes so a block address can be passed as an
2124 * argument to a call.
2126 args [1] = LLVMBlockAddress (ctx->lmethod, ex_bb);
2127 emit_call (ctx, bb, &builder, callee, args, 2);
2129 LLVMBuildUnreachable (builder);
2131 ctx->builder = builder = create_builder (ctx);
2132 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
2134 ctx->bblocks [bb->block_num].end_bblock = noex_bb;
2141 * emit_args_to_vtype:
2143 * Emit code to store the vtype in the arguments args to the address ADDRESS.
2146 emit_args_to_vtype (EmitContext *ctx, LLVMBuilderRef builder, MonoType *t, LLVMValueRef address, LLVMArgInfo *ainfo, LLVMValueRef *args)
2148 int j, size, nslots;
2150 size = mono_class_value_size (mono_class_from_mono_type (t), NULL);
2152 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (t))) {
2153 address = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (LLVMInt8Type (), 0), "");
2156 if (ainfo->storage == LLVMArgAsFpArgs)
2157 nslots = ainfo->nslots;
2161 for (j = 0; j < nslots; ++j) {
2162 LLVMValueRef index [2], addr, daddr;
2163 int part_size = size > sizeof (gpointer) ? sizeof (gpointer) : size;
2164 LLVMTypeRef part_type;
2166 while (part_size != 1 && part_size != 2 && part_size != 4 && part_size < 8)
2169 if (ainfo->pair_storage [j] == LLVMArgNone)
2172 switch (ainfo->pair_storage [j]) {
2173 case LLVMArgInIReg: {
2174 part_type = LLVMIntType (part_size * 8);
2175 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (t))) {
2176 index [0] = LLVMConstInt (LLVMInt32Type (), j * sizeof (gpointer), FALSE);
2177 addr = LLVMBuildGEP (builder, address, index, 1, "");
2179 daddr = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (IntPtrType (), 0), "");
2180 index [0] = LLVMConstInt (LLVMInt32Type (), j, FALSE);
2181 addr = LLVMBuildGEP (builder, daddr, index, 1, "");
2183 LLVMBuildStore (builder, convert (ctx, args [j], part_type), LLVMBuildBitCast (ctx->builder, addr, LLVMPointerType (part_type, 0), ""));
2186 case LLVMArgInFPReg: {
2187 LLVMTypeRef arg_type;
2189 if (ainfo->esize == 8)
2190 arg_type = LLVMDoubleType ();
2192 arg_type = LLVMFloatType ();
2194 index [0] = LLVMConstInt (LLVMInt32Type (), j, FALSE);
2195 daddr = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (arg_type, 0), "");
2196 addr = LLVMBuildGEP (builder, daddr, index, 1, "");
2197 LLVMBuildStore (builder, args [j], addr);
2203 g_assert_not_reached ();
2206 size -= sizeof (gpointer);
2211 * emit_vtype_to_args:
2213 * Emit code to load a vtype at address ADDRESS into scalar arguments. Store the arguments
2214 * into ARGS, and the number of arguments into NARGS.
2217 emit_vtype_to_args (EmitContext *ctx, LLVMBuilderRef builder, MonoType *t, LLVMValueRef address, LLVMArgInfo *ainfo, LLVMValueRef *args, guint32 *nargs)
2220 int j, size, nslots;
2221 LLVMTypeRef arg_type;
2223 size = get_vtype_size (t);
2225 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (t)))
2226 address = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (LLVMInt8Type (), 0), "");
2228 if (ainfo->storage == LLVMArgAsFpArgs)
2229 nslots = ainfo->nslots;
2232 for (j = 0; j < nslots; ++j) {
2233 LLVMValueRef index [2], addr, daddr;
2234 int partsize = size > sizeof (gpointer) ? sizeof (gpointer) : size;
2236 if (ainfo->pair_storage [j] == LLVMArgNone)
2239 switch (ainfo->pair_storage [j]) {
2241 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (t))) {
2242 index [0] = LLVMConstInt (LLVMInt32Type (), j * sizeof (gpointer), FALSE);
2243 addr = LLVMBuildGEP (builder, address, index, 1, "");
2245 daddr = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (IntPtrType (), 0), "");
2246 index [0] = LLVMConstInt (LLVMInt32Type (), j, FALSE);
2247 addr = LLVMBuildGEP (builder, daddr, index, 1, "");
2249 args [pindex ++] = convert (ctx, LLVMBuildLoad (builder, LLVMBuildBitCast (ctx->builder, addr, LLVMPointerType (LLVMIntType (partsize * 8), 0), ""), ""), IntPtrType ());
2251 case LLVMArgInFPReg:
2252 if (ainfo->esize == 8)
2253 arg_type = LLVMDoubleType ();
2255 arg_type = LLVMFloatType ();
2256 daddr = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (arg_type, 0), "");
2257 index [0] = LLVMConstInt (LLVMInt32Type (), j, FALSE);
2258 addr = LLVMBuildGEP (builder, daddr, index, 1, "");
2259 args [pindex ++] = LLVMBuildLoad (builder, addr, "");
2264 g_assert_not_reached ();
2266 size -= sizeof (gpointer);
2273 build_alloca_llvm_type_name (EmitContext *ctx, LLVMTypeRef t, int align, const char *name)
2276 * Have to place all alloca's at the end of the entry bb, since otherwise they would
2277 * get executed every time control reaches them.
2279 LLVMPositionBuilder (ctx->alloca_builder, get_bb (ctx, ctx->cfg->bb_entry), ctx->last_alloca);
2281 ctx->last_alloca = mono_llvm_build_alloca (ctx->alloca_builder, t, NULL, align, name);
2282 return ctx->last_alloca;
2286 build_alloca_llvm_type (EmitContext *ctx, LLVMTypeRef t, int align)
2288 return build_alloca_llvm_type_name (ctx, t, align, "");
2292 build_alloca (EmitContext *ctx, MonoType *t)
2294 MonoClass *k = mono_class_from_mono_type (t);
2297 g_assert (!mini_is_gsharedvt_variable_type (t));
2299 if (MONO_CLASS_IS_SIMD (ctx->cfg, k))
2302 align = mono_class_min_align (k);
2304 /* Sometimes align is not a power of 2 */
2305 while (mono_is_power_of_two (align) == -1)
2308 return build_alloca_llvm_type (ctx, type_to_llvm_type (ctx, t), align);
2312 emit_gsharedvt_ldaddr (EmitContext *ctx, int vreg)
2316 * Compute the address of the local as gsharedvt_locals_var + gsharedvt_info_var->locals_offsets [idx].
2318 MonoCompile *cfg = ctx->cfg;
2319 LLVMBuilderRef builder = ctx->builder;
2320 LLVMValueRef offset, offset_var;
2321 LLVMValueRef info_var = ctx->values [cfg->gsharedvt_info_var->dreg];
2322 LLVMValueRef locals_var = ctx->values [cfg->gsharedvt_locals_var->dreg];
2326 g_assert (info_var);
2327 g_assert (locals_var);
2329 int idx = cfg->gsharedvt_vreg_to_idx [vreg] - 1;
2331 offset = LLVMConstInt (LLVMInt32Type (), MONO_STRUCT_OFFSET (MonoGSharedVtMethodRuntimeInfo, entries) + (idx * sizeof (gpointer)), FALSE);
2332 ptr = LLVMBuildAdd (builder, convert (ctx, info_var, IntPtrType ()), convert (ctx, offset, IntPtrType ()), "");
2334 name = g_strdup_printf ("gsharedvt_local_%d_offset", vreg);
2335 offset_var = LLVMBuildLoad (builder, convert (ctx, ptr, LLVMPointerType (LLVMInt32Type (), 0)), name);
2337 return LLVMBuildAdd (builder, convert (ctx, locals_var, IntPtrType ()), convert (ctx, offset_var, IntPtrType ()), "");
2341 * Put the global into the 'llvm.used' array to prevent it from being optimized away.
2344 mark_as_used (MonoLLVMModule *module, LLVMValueRef global)
2347 module->used = g_ptr_array_sized_new (16);
2348 g_ptr_array_add (module->used, global);
2352 emit_llvm_used (MonoLLVMModule *module)
2354 LLVMModuleRef lmodule = module->lmodule;
2355 LLVMTypeRef used_type;
2356 LLVMValueRef used, *used_elem;
2362 used_type = LLVMArrayType (LLVMPointerType (LLVMInt8Type (), 0), module->used->len);
2363 used = LLVMAddGlobal (lmodule, used_type, "llvm.used");
2364 used_elem = g_new0 (LLVMValueRef, module->used->len);
2365 for (i = 0; i < module->used->len; ++i)
2366 used_elem [i] = LLVMConstBitCast ((LLVMValueRef)g_ptr_array_index (module->used, i), LLVMPointerType (LLVMInt8Type (), 0));
2367 LLVMSetInitializer (used, LLVMConstArray (LLVMPointerType (LLVMInt8Type (), 0), used_elem, module->used->len));
2368 LLVMSetLinkage (used, LLVMAppendingLinkage);
2369 LLVMSetSection (used, "llvm.metadata");
2375 * Emit a function mapping method indexes to their code
2378 emit_get_method (MonoLLVMModule *module)
2380 LLVMModuleRef lmodule = module->lmodule;
2381 LLVMValueRef func, switch_ins, m;
2382 LLVMBasicBlockRef entry_bb, fail_bb, bb, code_start_bb, code_end_bb;
2383 LLVMBasicBlockRef *bbs;
2385 LLVMBuilderRef builder;
2390 * Emit a switch statement. Emitting a table of function addresses is smaller/faster,
2391 * but generating code seems safer.
2393 rtype = LLVMPointerType (LLVMInt8Type (), 0);
2394 func = LLVMAddFunction (lmodule, module->get_method_symbol, LLVMFunctionType1 (rtype, LLVMInt32Type (), FALSE));
2395 LLVMSetLinkage (func, LLVMExternalLinkage);
2396 LLVMSetVisibility (func, LLVMHiddenVisibility);
2397 LLVMAddFunctionAttr (func, LLVMNoUnwindAttribute);
2398 module->get_method = func;
2400 entry_bb = LLVMAppendBasicBlock (func, "ENTRY");
2403 * Return llvm_code_start/llvm_code_end when called with -1/-2.
2404 * Hopefully, the toolchain doesn't reorder these functions. If it does,
2405 * then we will have to find another solution.
2408 name = g_strdup_printf ("BB_CODE_START");
2409 code_start_bb = LLVMAppendBasicBlock (func, name);
2411 builder = LLVMCreateBuilder ();
2412 LLVMPositionBuilderAtEnd (builder, code_start_bb);
2413 LLVMBuildRet (builder, LLVMBuildBitCast (builder, module->code_start, rtype, ""));
2415 name = g_strdup_printf ("BB_CODE_END");
2416 code_end_bb = LLVMAppendBasicBlock (func, name);
2418 builder = LLVMCreateBuilder ();
2419 LLVMPositionBuilderAtEnd (builder, code_end_bb);
2420 LLVMBuildRet (builder, LLVMBuildBitCast (builder, module->code_end, rtype, ""));
2422 bbs = g_new0 (LLVMBasicBlockRef, module->max_method_idx + 1);
2423 for (i = 0; i < module->max_method_idx + 1; ++i) {
2424 name = g_strdup_printf ("BB_%d", i);
2425 bb = LLVMAppendBasicBlock (func, name);
2429 builder = LLVMCreateBuilder ();
2430 LLVMPositionBuilderAtEnd (builder, bb);
2432 m = (LLVMValueRef)g_hash_table_lookup (module->idx_to_lmethod, GINT_TO_POINTER (i));
2434 LLVMBuildRet (builder, LLVMBuildBitCast (builder, m, rtype, ""));
2436 LLVMBuildRet (builder, LLVMConstNull (rtype));
2439 fail_bb = LLVMAppendBasicBlock (func, "FAIL");
2440 builder = LLVMCreateBuilder ();
2441 LLVMPositionBuilderAtEnd (builder, fail_bb);
2442 LLVMBuildRet (builder, LLVMConstNull (rtype));
2444 builder = LLVMCreateBuilder ();
2445 LLVMPositionBuilderAtEnd (builder, entry_bb);
2447 switch_ins = LLVMBuildSwitch (builder, LLVMGetParam (func, 0), fail_bb, 0);
2448 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), -1, FALSE), code_start_bb);
2449 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), -2, FALSE), code_end_bb);
2450 for (i = 0; i < module->max_method_idx + 1; ++i) {
2451 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), i, FALSE), bbs [i]);
2454 mark_as_used (module, func);
2458 * emit_get_unbox_tramp:
2460 * Emit a function mapping method indexes to their unbox trampoline
2463 emit_get_unbox_tramp (MonoLLVMModule *module)
2465 LLVMModuleRef lmodule = module->lmodule;
2466 LLVMValueRef func, switch_ins, m;
2467 LLVMBasicBlockRef entry_bb, fail_bb, bb;
2468 LLVMBasicBlockRef *bbs;
2470 LLVMBuilderRef builder;
2474 /* Similar to emit_get_method () */
2476 rtype = LLVMPointerType (LLVMInt8Type (), 0);
2477 func = LLVMAddFunction (lmodule, module->get_unbox_tramp_symbol, LLVMFunctionType1 (rtype, LLVMInt32Type (), FALSE));
2478 LLVMSetLinkage (func, LLVMExternalLinkage);
2479 LLVMSetVisibility (func, LLVMHiddenVisibility);
2480 LLVMAddFunctionAttr (func, LLVMNoUnwindAttribute);
2481 module->get_unbox_tramp = func;
2483 entry_bb = LLVMAppendBasicBlock (func, "ENTRY");
2485 bbs = g_new0 (LLVMBasicBlockRef, module->max_method_idx + 1);
2486 for (i = 0; i < module->max_method_idx + 1; ++i) {
2487 m = (LLVMValueRef)g_hash_table_lookup (module->idx_to_unbox_tramp, GINT_TO_POINTER (i));
2491 name = g_strdup_printf ("BB_%d", i);
2492 bb = LLVMAppendBasicBlock (func, name);
2496 builder = LLVMCreateBuilder ();
2497 LLVMPositionBuilderAtEnd (builder, bb);
2499 LLVMBuildRet (builder, LLVMBuildBitCast (builder, m, rtype, ""));
2502 fail_bb = LLVMAppendBasicBlock (func, "FAIL");
2503 builder = LLVMCreateBuilder ();
2504 LLVMPositionBuilderAtEnd (builder, fail_bb);
2505 LLVMBuildRet (builder, LLVMConstNull (rtype));
2507 builder = LLVMCreateBuilder ();
2508 LLVMPositionBuilderAtEnd (builder, entry_bb);
2510 switch_ins = LLVMBuildSwitch (builder, LLVMGetParam (func, 0), fail_bb, 0);
2511 for (i = 0; i < module->max_method_idx + 1; ++i) {
2512 m = (LLVMValueRef)g_hash_table_lookup (module->idx_to_unbox_tramp, GINT_TO_POINTER (i));
2516 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), i, FALSE), bbs [i]);
2519 mark_as_used (module, func);
2522 /* Add a function to mark the beginning of LLVM code */
2524 emit_llvm_code_start (MonoLLVMModule *module)
2526 LLVMModuleRef lmodule = module->lmodule;
2528 LLVMBasicBlockRef entry_bb;
2529 LLVMBuilderRef builder;
2531 func = LLVMAddFunction (lmodule, "llvm_code_start", LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE));
2532 LLVMSetLinkage (func, LLVMInternalLinkage);
2533 LLVMAddFunctionAttr (func, LLVMNoUnwindAttribute);
2534 module->code_start = func;
2535 entry_bb = LLVMAppendBasicBlock (func, "ENTRY");
2536 builder = LLVMCreateBuilder ();
2537 LLVMPositionBuilderAtEnd (builder, entry_bb);
2538 LLVMBuildRetVoid (builder);
2542 emit_init_icall_wrapper (MonoLLVMModule *module, const char *name, const char *icall_name, int subtype)
2544 LLVMModuleRef lmodule = module->lmodule;
2545 LLVMValueRef func, indexes [2], got_entry_addr, args [16], callee;
2546 LLVMBasicBlockRef entry_bb;
2547 LLVMBuilderRef builder;
2554 func = LLVMAddFunction (lmodule, name, LLVMFunctionType1 (LLVMVoidType (), LLVMInt32Type (), FALSE));
2555 sig = LLVMFunctionType2 (LLVMVoidType (), IntPtrType (), LLVMInt32Type (), FALSE);
2560 func = LLVMAddFunction (lmodule, name, LLVMFunctionType2 (LLVMVoidType (), LLVMInt32Type (), IntPtrType (), FALSE));
2561 sig = LLVMFunctionType3 (LLVMVoidType (), IntPtrType (), LLVMInt32Type (), IntPtrType (), FALSE);
2564 func = LLVMAddFunction (lmodule, name, LLVMFunctionType2 (LLVMVoidType (), LLVMInt32Type (), ObjRefType (), FALSE));
2565 sig = LLVMFunctionType3 (LLVMVoidType (), IntPtrType (), LLVMInt32Type (), ObjRefType (), FALSE);
2568 g_assert_not_reached ();
2570 LLVMSetLinkage (func, LLVMInternalLinkage);
2571 LLVMAddFunctionAttr (func, LLVMNoInlineAttribute);
2572 mono_llvm_set_preserveall_cc (func);
2573 entry_bb = LLVMAppendBasicBlock (func, "ENTRY");
2574 builder = LLVMCreateBuilder ();
2575 LLVMPositionBuilderAtEnd (builder, entry_bb);
2578 ji = g_new0 (MonoJumpInfo, 1);
2579 ji->type = MONO_PATCH_INFO_AOT_MODULE;
2580 ji = mono_aot_patch_info_dup (ji);
2581 got_offset = mono_aot_get_got_offset (ji);
2582 module->max_got_offset = MAX (module->max_got_offset, got_offset);
2583 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
2584 indexes [1] = LLVMConstInt (LLVMInt32Type (), got_offset, FALSE);
2585 got_entry_addr = LLVMBuildGEP (builder, module->got_var, indexes, 2, "");
2586 args [0] = LLVMBuildPtrToInt (builder, LLVMBuildLoad (builder, got_entry_addr, ""), IntPtrType (), "");
2587 args [1] = LLVMGetParam (func, 0);
2589 args [2] = LLVMGetParam (func, 1);
2591 ji = g_new0 (MonoJumpInfo, 1);
2592 ji->type = MONO_PATCH_INFO_INTERNAL_METHOD;
2593 ji->data.name = icall_name;
2594 ji = mono_aot_patch_info_dup (ji);
2595 got_offset = mono_aot_get_got_offset (ji);
2596 module->max_got_offset = MAX (module->max_got_offset, got_offset);
2597 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
2598 indexes [1] = LLVMConstInt (LLVMInt32Type (), got_offset, FALSE);
2599 got_entry_addr = LLVMBuildGEP (builder, module->got_var, indexes, 2, "");
2600 callee = LLVMBuildLoad (builder, got_entry_addr, "");
2601 callee = LLVMBuildBitCast (builder, callee, LLVMPointerType (sig, 0), "");
2602 LLVMBuildCall (builder, callee, args, LLVMCountParamTypes (sig), "");
2604 // Set the inited flag
2605 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
2606 indexes [1] = LLVMGetParam (func, 0);
2607 LLVMBuildStore (builder, LLVMConstInt (LLVMInt8Type (), 1, FALSE), LLVMBuildGEP (builder, module->inited_var, indexes, 2, ""));
2609 LLVMBuildRetVoid (builder);
2611 LLVMVerifyFunction(func, LLVMAbortProcessAction);
2616 * Emit wrappers around the C icalls used to initialize llvm methods, to
2617 * make the calling code smaller and to enable usage of the llvm
2618 * PreserveAll calling convention.
2621 emit_init_icall_wrappers (MonoLLVMModule *module)
2623 module->init_method = emit_init_icall_wrapper (module, "init_method", "mono_aot_init_llvm_method", 0);
2624 module->init_method_gshared_mrgctx = emit_init_icall_wrapper (module, "init_method_gshared_mrgctx", "mono_aot_init_gshared_method_mrgctx", 1);
2625 module->init_method_gshared_this = emit_init_icall_wrapper (module, "init_method_gshared_this", "mono_aot_init_gshared_method_this", 2);
2626 module->init_method_gshared_vtable = emit_init_icall_wrapper (module, "init_method_gshared_vtable", "mono_aot_init_gshared_method_vtable", 3);
2630 emit_llvm_code_end (MonoLLVMModule *module)
2632 LLVMModuleRef lmodule = module->lmodule;
2634 LLVMBasicBlockRef entry_bb;
2635 LLVMBuilderRef builder;
2637 func = LLVMAddFunction (lmodule, "llvm_code_end", LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE));
2638 LLVMSetLinkage (func, LLVMInternalLinkage);
2639 LLVMAddFunctionAttr (func, LLVMNoUnwindAttribute);
2640 module->code_end = func;
2641 entry_bb = LLVMAppendBasicBlock (func, "ENTRY");
2642 builder = LLVMCreateBuilder ();
2643 LLVMPositionBuilderAtEnd (builder, entry_bb);
2644 LLVMBuildRetVoid (builder);
2648 emit_div_check (EmitContext *ctx, LLVMBuilderRef builder, MonoBasicBlock *bb, MonoInst *ins, LLVMValueRef lhs, LLVMValueRef rhs)
2650 gboolean need_div_check = ctx->cfg->backend->need_div_check;
2653 /* LLVM doesn't know that these can throw an exception since they are not called through an intrinsic */
2654 need_div_check = TRUE;
2656 if (!need_div_check)
2659 switch (ins->opcode) {
2672 case OP_IDIV_UN_IMM:
2673 case OP_LDIV_UN_IMM:
2674 case OP_IREM_UN_IMM:
2675 case OP_LREM_UN_IMM: {
2677 gboolean is_signed = (ins->opcode == OP_IDIV || ins->opcode == OP_LDIV || ins->opcode == OP_IREM || ins->opcode == OP_LREM ||
2678 ins->opcode == OP_IDIV_IMM || ins->opcode == OP_LDIV_IMM || ins->opcode == OP_IREM_IMM || ins->opcode == OP_LREM_IMM);
2680 cmp = LLVMBuildICmp (builder, LLVMIntEQ, rhs, LLVMConstInt (LLVMTypeOf (rhs), 0, FALSE), "");
2681 emit_cond_system_exception (ctx, bb, "DivideByZeroException", cmp);
2684 builder = ctx->builder;
2686 /* b == -1 && a == 0x80000000 */
2688 LLVMValueRef c = (LLVMTypeOf (lhs) == LLVMInt32Type ()) ? LLVMConstInt (LLVMTypeOf (lhs), 0x80000000, FALSE) : LLVMConstInt (LLVMTypeOf (lhs), 0x8000000000000000LL, FALSE);
2689 LLVMValueRef cond1 = LLVMBuildICmp (builder, LLVMIntEQ, rhs, LLVMConstInt (LLVMTypeOf (rhs), -1, FALSE), "");
2690 LLVMValueRef cond2 = LLVMBuildICmp (builder, LLVMIntEQ, lhs, c, "");
2692 cmp = LLVMBuildICmp (builder, LLVMIntEQ, LLVMBuildAnd (builder, cond1, cond2, ""), LLVMConstInt (LLVMInt1Type (), 1, FALSE), "");
2693 emit_cond_system_exception (ctx, bb, "OverflowException", cmp);
2696 builder = ctx->builder;
2708 * Emit code to initialize the GOT slots used by the method.
2711 emit_init_method (EmitContext *ctx)
2713 LLVMValueRef indexes [16], args [16], callee;
2714 LLVMValueRef inited_var, cmp, call;
2715 LLVMBasicBlockRef inited_bb, notinited_bb;
2716 LLVMBuilderRef builder = ctx->builder;
2717 MonoCompile *cfg = ctx->cfg;
2719 ctx->module->max_inited_idx = MAX (ctx->module->max_inited_idx, cfg->method_index);
2721 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
2722 indexes [1] = LLVMConstInt (LLVMInt32Type (), cfg->method_index, FALSE);
2723 inited_var = LLVMBuildLoad (builder, LLVMBuildGEP (builder, ctx->module->inited_var, indexes, 2, ""), "is_inited");
2725 args [0] = inited_var;
2726 args [1] = LLVMConstInt (LLVMInt8Type (), 1, FALSE);
2727 inited_var = LLVMBuildCall (ctx->builder, LLVMGetNamedFunction (ctx->lmodule, "llvm.expect.i8"), args, 2, "");
2729 cmp = LLVMBuildICmp (builder, LLVMIntEQ, inited_var, LLVMConstInt (LLVMTypeOf (inited_var), 0, FALSE), "");
2731 inited_bb = ctx->inited_bb;
2732 notinited_bb = gen_bb (ctx, "NOTINITED_BB");
2734 LLVMBuildCondBr (ctx->builder, cmp, notinited_bb, inited_bb);
2736 builder = ctx->builder = create_builder (ctx);
2737 LLVMPositionBuilderAtEnd (ctx->builder, notinited_bb);
2740 if (ctx->rgctx_arg && cfg->method->is_inflated && mono_method_get_context (cfg->method)->method_inst) {
2741 args [0] = LLVMConstInt (LLVMInt32Type (), cfg->method_index, 0);
2742 args [1] = convert (ctx, ctx->rgctx_arg, IntPtrType ());
2743 callee = ctx->module->init_method_gshared_mrgctx;
2744 call = LLVMBuildCall (builder, callee, args, 2, "");
2745 } else if (ctx->rgctx_arg) {
2746 /* A vtable is passed as the rgctx argument */
2747 args [0] = LLVMConstInt (LLVMInt32Type (), cfg->method_index, 0);
2748 args [1] = convert (ctx, ctx->rgctx_arg, IntPtrType ());
2749 callee = ctx->module->init_method_gshared_vtable;
2750 call = LLVMBuildCall (builder, callee, args, 2, "");
2751 } else if (cfg->gshared) {
2752 args [0] = LLVMConstInt (LLVMInt32Type (), cfg->method_index, 0);
2753 args [1] = convert (ctx, ctx->this_arg, ObjRefType ());
2754 callee = ctx->module->init_method_gshared_this;
2755 call = LLVMBuildCall (builder, callee, args, 2, "");
2757 args [0] = LLVMConstInt (LLVMInt32Type (), cfg->method_index, 0);
2758 callee = ctx->module->init_method;
2759 call = LLVMBuildCall (builder, callee, args, 1, "");
2763 * This enables llvm to keep arguments in their original registers/
2764 * scratch registers, since the call will not clobber them.
2766 mono_llvm_set_call_preserveall_cc (call);
2768 LLVMBuildBr (builder, inited_bb);
2769 ctx->bblocks [cfg->bb_entry->block_num].end_bblock = inited_bb;
2771 builder = ctx->builder = create_builder (ctx);
2772 LLVMPositionBuilderAtEnd (ctx->builder, inited_bb);
2776 emit_unbox_tramp (EmitContext *ctx, const char *method_name, LLVMTypeRef method_type, LLVMValueRef method, int method_index)
2779 * Emit unbox trampoline using a tail call
2781 LLVMValueRef tramp, call, *args;
2782 LLVMBuilderRef builder;
2783 LLVMBasicBlockRef lbb;
2784 LLVMCallInfo *linfo;
2788 tramp_name = g_strdup_printf ("ut_%s", method_name);
2789 tramp = LLVMAddFunction (ctx->module->lmodule, tramp_name, method_type);
2790 LLVMSetLinkage (tramp, LLVMInternalLinkage);
2791 LLVMAddFunctionAttr (tramp, LLVMOptimizeForSizeAttribute);
2792 //LLVMAddFunctionAttr (tramp, LLVMNoUnwindAttribute);
2794 // FIXME: Reduce code duplication with mono_llvm_compile_method () etc.
2795 if (!ctx->llvm_only && ctx->rgctx_arg_pindex != -1)
2796 LLVMAddAttribute (LLVMGetParam (tramp, ctx->rgctx_arg_pindex), LLVMInRegAttribute);
2797 if (ctx->cfg->vret_addr) {
2798 LLVMSetValueName (LLVMGetParam (tramp, linfo->vret_arg_pindex), "vret");
2799 if (linfo->ret.storage == LLVMArgVtypeByRef) {
2800 LLVMAddAttribute (LLVMGetParam (tramp, linfo->vret_arg_pindex), LLVMStructRetAttribute);
2801 LLVMAddAttribute (LLVMGetParam (tramp, linfo->vret_arg_pindex), LLVMNoAliasAttribute);
2805 lbb = LLVMAppendBasicBlock (tramp, "");
2806 builder = LLVMCreateBuilder ();
2807 LLVMPositionBuilderAtEnd (builder, lbb);
2809 nargs = LLVMCountParamTypes (method_type);
2810 args = g_new0 (LLVMValueRef, nargs);
2811 for (i = 0; i < nargs; ++i) {
2812 args [i] = LLVMGetParam (tramp, i);
2813 if (i == ctx->this_arg_pindex) {
2814 LLVMTypeRef arg_type = LLVMTypeOf (args [i]);
2816 args [i] = LLVMBuildPtrToInt (builder, args [i], IntPtrType (), "");
2817 args [i] = LLVMBuildAdd (builder, args [i], LLVMConstInt (IntPtrType (), sizeof (MonoObject), FALSE), "");
2818 args [i] = LLVMBuildIntToPtr (builder, args [i], arg_type, "");
2821 call = LLVMBuildCall (builder, method, args, nargs, "");
2822 if (!ctx->llvm_only && ctx->rgctx_arg_pindex != -1)
2823 LLVMAddInstrAttribute (call, 1 + ctx->rgctx_arg_pindex, LLVMInRegAttribute);
2824 if (linfo->ret.storage == LLVMArgVtypeByRef)
2825 LLVMAddInstrAttribute (call, 1 + linfo->vret_arg_pindex, LLVMStructRetAttribute);
2827 // FIXME: This causes assertions in clang
2828 //mono_llvm_set_must_tail (call);
2829 if (LLVMGetReturnType (method_type) == LLVMVoidType ())
2830 LLVMBuildRetVoid (builder);
2832 LLVMBuildRet (builder, call);
2834 g_hash_table_insert (ctx->module->idx_to_unbox_tramp, GINT_TO_POINTER (method_index), tramp);
2840 * Emit code to load/convert arguments.
2843 emit_entry_bb (EmitContext *ctx, LLVMBuilderRef builder)
2846 MonoCompile *cfg = ctx->cfg;
2847 MonoMethodSignature *sig = ctx->sig;
2848 LLVMCallInfo *linfo = ctx->linfo;
2852 LLVMBuilderRef old_builder = ctx->builder;
2853 ctx->builder = builder;
2855 ctx->alloca_builder = create_builder (ctx);
2858 * Handle indirect/volatile variables by allocating memory for them
2859 * using 'alloca', and storing their address in a temporary.
2861 for (i = 0; i < cfg->num_varinfo; ++i) {
2862 MonoInst *var = cfg->varinfo [i];
2865 if (var->opcode == OP_GSHAREDVT_LOCAL || var->opcode == OP_GSHAREDVT_ARG_REGOFFSET) {
2866 } 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))) {
2867 vtype = type_to_llvm_type (ctx, var->inst_vtype);
2870 /* Could be already created by an OP_VPHI */
2871 if (!ctx->addresses [var->dreg]) {
2872 ctx->addresses [var->dreg] = build_alloca (ctx, var->inst_vtype);
2873 //LLVMSetValueName (ctx->addresses [var->dreg], g_strdup_printf ("vreg_loc_%d", var->dreg));
2875 ctx->vreg_cli_types [var->dreg] = var->inst_vtype;
2879 names = g_new (char *, sig->param_count);
2880 mono_method_get_param_names (cfg->method, (const char **) names);
2882 for (i = 0; i < sig->param_count; ++i) {
2883 LLVMArgInfo *ainfo = &linfo->args [i + sig->hasthis];
2884 int reg = cfg->args [i + sig->hasthis]->dreg;
2887 pindex = ainfo->pindex;
2889 switch (ainfo->storage) {
2890 case LLVMArgVtypeInReg:
2891 case LLVMArgAsFpArgs: {
2892 LLVMValueRef args [8];
2895 pindex += ainfo->ndummy_fpargs;
2897 /* The argument is received as a set of int/fp arguments, store them into the real argument */
2898 memset (args, 0, sizeof (args));
2899 if (ainfo->storage == LLVMArgVtypeInReg) {
2900 args [0] = LLVMGetParam (ctx->lmethod, pindex);
2901 if (ainfo->pair_storage [1] != LLVMArgNone)
2902 args [1] = LLVMGetParam (ctx->lmethod, pindex + 1);
2904 g_assert (ainfo->nslots <= 8);
2905 for (j = 0; j < ainfo->nslots; ++j)
2906 args [j] = LLVMGetParam (ctx->lmethod, pindex + j);
2908 ctx->addresses [reg] = build_alloca (ctx, ainfo->type);
2910 emit_args_to_vtype (ctx, builder, ainfo->type, ctx->addresses [reg], ainfo, args);
2912 if (ainfo->storage == LLVMArgVtypeInReg && MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (ainfo->type))) {
2913 /* Treat these as normal values */
2914 ctx->values [reg] = LLVMBuildLoad (builder, ctx->addresses [reg], "");
2918 case LLVMArgVtypeByVal: {
2919 ctx->addresses [reg] = LLVMGetParam (ctx->lmethod, pindex);
2921 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (ainfo->type))) {
2922 /* Treat these as normal values */
2923 ctx->values [reg] = LLVMBuildLoad (builder, ctx->addresses [reg], "");
2927 case LLVMArgVtypeByRef: {
2928 /* The argument is passed by ref */
2929 ctx->addresses [reg] = LLVMGetParam (ctx->lmethod, pindex);
2932 case LLVMArgScalarByRef: {
2934 name = g_strdup_printf ("arg_%s", names [i]);
2936 name = g_strdup_printf ("arg_%d", i);
2937 ctx->values [reg] = LLVMBuildLoad (builder, LLVMGetParam (ctx->lmethod, pindex), name);
2941 case LLVMArgAsIArgs: {
2942 LLVMValueRef arg = LLVMGetParam (ctx->lmethod, pindex);
2945 /* The argument is received as an array of ints, store it into the real argument */
2946 ctx->addresses [reg] = build_alloca (ctx, ainfo->type);
2948 size = mono_class_value_size (mono_class_from_mono_type (ainfo->type), NULL);
2949 if (size < SIZEOF_VOID_P) {
2950 /* The upper bits of the registers might not be valid */
2951 LLVMValueRef val = LLVMBuildExtractValue (builder, arg, 0, "");
2952 LLVMValueRef dest = convert (ctx, ctx->addresses [reg], LLVMPointerType (LLVMIntType (size * 8), 0));
2953 LLVMBuildStore (ctx->builder, LLVMBuildTrunc (builder, val, LLVMIntType (size * 8), ""), dest);
2955 LLVMBuildStore (ctx->builder, arg, convert (ctx, ctx->addresses [reg], LLVMPointerType (LLVMTypeOf (arg), 0)));
2959 case LLVMArgVtypeAsScalar:
2960 g_assert_not_reached ();
2962 case LLVMArgGsharedvtFixed: {
2963 /* These are non-gsharedvt arguments passed by ref, the rest of the IR treats them as scalars */
2964 LLVMValueRef arg = LLVMGetParam (ctx->lmethod, pindex);
2967 name = g_strdup_printf ("arg_%s", names [i]);
2969 name = g_strdup_printf ("arg_%d", i);
2971 ctx->values [reg] = LLVMBuildLoad (builder, convert (ctx, arg, LLVMPointerType (type_to_llvm_type (ctx, ainfo->type), 0)), name);
2974 case LLVMArgGsharedvtFixedVtype: {
2975 LLVMValueRef arg = LLVMGetParam (ctx->lmethod, pindex);
2978 name = g_strdup_printf ("vtype_arg_%s", names [i]);
2980 name = g_strdup_printf ("vtype_arg_%d", i);
2982 /* Non-gsharedvt vtype argument passed by ref, the rest of the IR treats it as a vtype */
2983 g_assert (ctx->addresses [reg]);
2984 LLVMSetValueName (ctx->addresses [reg], name);
2985 LLVMBuildStore (builder, LLVMBuildLoad (builder, convert (ctx, arg, LLVMPointerType (type_to_llvm_type (ctx, ainfo->type), 0)), ""), ctx->addresses [reg]);
2988 case LLVMArgGsharedvtVariable:
2989 /* The IR treats these as variables with addresses */
2990 ctx->addresses [reg] = LLVMGetParam (ctx->lmethod, pindex);
2993 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));
3000 emit_volatile_store (ctx, cfg->vret_addr->dreg);
3002 emit_volatile_store (ctx, cfg->args [0]->dreg);
3003 for (i = 0; i < sig->param_count; ++i)
3004 if (!mini_type_is_vtype (sig->params [i]))
3005 emit_volatile_store (ctx, cfg->args [i + sig->hasthis]->dreg);
3007 if (sig->hasthis && !cfg->rgctx_var && cfg->gshared) {
3008 LLVMValueRef this_alloc;
3011 * The exception handling code needs the location where the this argument was
3012 * stored for gshared methods. We create a separate alloca to hold it, and mark it
3013 * with the "mono.this" custom metadata to tell llvm that it needs to save its
3014 * location into the LSDA.
3016 this_alloc = mono_llvm_build_alloca (builder, ThisType (), LLVMConstInt (LLVMInt32Type (), 1, FALSE), 0, "");
3017 /* This volatile store will keep the alloca alive */
3018 mono_llvm_build_store (builder, ctx->values [cfg->args [0]->dreg], this_alloc, TRUE, LLVM_BARRIER_NONE);
3020 set_metadata_flag (this_alloc, "mono.this");
3023 if (cfg->rgctx_var) {
3024 LLVMValueRef rgctx_alloc, store;
3027 * We handle the rgctx arg similarly to the this pointer.
3029 g_assert (ctx->addresses [cfg->rgctx_var->dreg]);
3030 rgctx_alloc = ctx->addresses [cfg->rgctx_var->dreg];
3031 /* This volatile store will keep the alloca alive */
3032 store = mono_llvm_build_store (builder, convert (ctx, ctx->rgctx_arg, IntPtrType ()), rgctx_alloc, TRUE, LLVM_BARRIER_NONE);
3034 set_metadata_flag (rgctx_alloc, "mono.this");
3037 /* Initialize the method if needed */
3038 if (cfg->compile_aot && ctx->llvm_only) {
3039 /* Emit a location for the initialization code */
3040 ctx->init_bb = gen_bb (ctx, "INIT_BB");
3041 ctx->inited_bb = gen_bb (ctx, "INITED_BB");
3043 LLVMBuildBr (ctx->builder, ctx->init_bb);
3044 builder = ctx->builder = create_builder (ctx);
3045 LLVMPositionBuilderAtEnd (ctx->builder, ctx->inited_bb);
3046 ctx->bblocks [cfg->bb_entry->block_num].end_bblock = ctx->inited_bb;
3049 /* Compute nesting between clauses */
3050 ctx->nested_in = (GSList**)mono_mempool_alloc0 (cfg->mempool, sizeof (GSList*) * cfg->header->num_clauses);
3051 for (i = 0; i < cfg->header->num_clauses; ++i) {
3052 for (j = 0; j < cfg->header->num_clauses; ++j) {
3053 MonoExceptionClause *clause1 = &cfg->header->clauses [i];
3054 MonoExceptionClause *clause2 = &cfg->header->clauses [j];
3056 if (i != j && clause1->try_offset >= clause2->try_offset && clause1->handler_offset <= clause2->handler_offset)
3057 ctx->nested_in [i] = g_slist_prepend_mempool (cfg->mempool, ctx->nested_in [i], GINT_TO_POINTER (j));
3062 * For finally clauses, create an indicator variable telling OP_ENDFINALLY whenever
3063 * it needs to continue normally, or return back to the exception handling system.
3065 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
3069 if (!(bb->region != -1 && (bb->flags & BB_EXCEPTION_HANDLER)))
3072 clause_index = MONO_REGION_CLAUSE_INDEX (bb->region);
3073 g_hash_table_insert (ctx->region_to_handler, GUINT_TO_POINTER (mono_get_block_region_notry (cfg, bb->region)), bb);
3074 g_hash_table_insert (ctx->clause_to_handler, GINT_TO_POINTER (clause_index), bb);
3076 if (bb->in_scount == 0) {
3079 sprintf (name, "finally_ind_bb%d", bb->block_num);
3080 val = LLVMBuildAlloca (builder, LLVMInt32Type (), name);
3081 LLVMBuildStore (builder, LLVMConstInt (LLVMInt32Type (), 0, FALSE), val);
3083 ctx->bblocks [bb->block_num].finally_ind = val;
3085 /* Create a variable to hold the exception var */
3087 ctx->ex_var = LLVMBuildAlloca (builder, ObjRefType (), "exvar");
3091 * Create a new bblock which CALL_HANDLER/landing pads can branch to, because branching to the
3092 * LLVM bblock containing a landing pad causes problems for the
3093 * LLVM optimizer passes.
3095 sprintf (name, "BB%d_CALL_HANDLER_TARGET", bb->block_num);
3096 ctx->bblocks [bb->block_num].call_handler_target_bb = LLVMAppendBasicBlock (ctx->lmethod, name);
3098 ctx->builder = old_builder;
3102 process_call (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, MonoInst *ins)
3104 MonoCompile *cfg = ctx->cfg;
3105 LLVMModuleRef lmodule = ctx->lmodule;
3106 LLVMValueRef *values = ctx->values;
3107 LLVMValueRef *addresses = ctx->addresses;
3108 MonoCallInst *call = (MonoCallInst*)ins;
3109 MonoMethodSignature *sig = call->signature;
3110 LLVMValueRef callee = NULL, lcall;
3112 LLVMCallInfo *cinfo;
3116 LLVMTypeRef llvm_sig;
3118 gboolean is_virtual, calli, preserveall;
3119 LLVMBuilderRef builder = *builder_ref;
3121 if (call->signature->call_convention != MONO_CALL_DEFAULT) {
3122 set_failure (ctx, "non-default callconv");
3126 cinfo = call->cinfo;
3128 if (call->rgctx_arg_reg)
3129 cinfo->rgctx_arg = TRUE;
3130 if (call->imt_arg_reg)
3131 cinfo->imt_arg = TRUE;
3133 vretaddr = (cinfo->ret.storage == LLVMArgVtypeRetAddr || cinfo->ret.storage == LLVMArgVtypeByRef || cinfo->ret.storage == LLVMArgScalarRetAddr || cinfo->ret.storage == LLVMArgGsharedvtFixed || cinfo->ret.storage == LLVMArgGsharedvtVariable || cinfo->ret.storage == LLVMArgGsharedvtFixedVtype);
3135 llvm_sig = sig_to_llvm_sig_full (ctx, sig, cinfo);
3139 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);
3140 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);
3142 preserveall = FALSE;
3144 /* FIXME: Avoid creating duplicate methods */
3146 if (ins->flags & MONO_INST_HAS_METHOD) {
3150 if (cfg->compile_aot) {
3151 callee = get_callee (ctx, llvm_sig, MONO_PATCH_INFO_METHOD, call->method);
3153 set_failure (ctx, "can't encode patch");
3156 if (cfg->llvm_only && call->method->klass->image->assembly == ctx->module->assembly) {
3158 * Collect instructions representing the callee into a hash so they can be replaced
3159 * by the llvm method for the callee if the callee turns out to be direct
3160 * callable. Currently this only requires it to not fail llvm compilation.
3162 GSList *l = (GSList*)g_hash_table_lookup (ctx->method_to_callers, call->method);
3163 l = g_slist_prepend (l, callee);
3164 g_hash_table_insert (ctx->method_to_callers, call->method, l);
3167 callee = LLVMAddFunction (lmodule, "", llvm_sig);
3170 mono_create_jit_trampoline_in_domain (mono_domain_get (),
3172 LLVMAddGlobalMapping (ctx->module->ee, callee, target);
3176 if (!cfg->llvm_only && call->method && strstr (call->method->klass->name, "AsyncVoidMethodBuilder")) {
3177 /* LLVM miscompiles async methods */
3178 set_failure (ctx, "#13734");
3183 MonoJitICallInfo *info = mono_find_jit_icall_by_addr (call->fptr);
3189 memset (&ji, 0, sizeof (ji));
3190 ji.type = MONO_PATCH_INFO_JIT_ICALL_ADDR;
3191 ji.data.target = info->name;
3193 target = mono_resolve_patch_target (cfg->method, cfg->domain, NULL, &ji, FALSE);
3195 if (cfg->compile_aot) {
3196 callee = get_callee (ctx, llvm_sig, MONO_PATCH_INFO_INTERNAL_METHOD, (char*)info->name);
3198 set_failure (ctx, "can't encode patch");
3202 callee = LLVMAddFunction (lmodule, "", llvm_sig);
3203 target = (gpointer)mono_icall_get_wrapper (info);
3204 LLVMAddGlobalMapping (ctx->module->ee, callee, target);
3207 if (cfg->compile_aot) {
3209 if (cfg->abs_patches) {
3210 MonoJumpInfo *abs_ji = (MonoJumpInfo*)g_hash_table_lookup (cfg->abs_patches, call->fptr);
3212 callee = get_callee (ctx, llvm_sig, abs_ji->type, abs_ji->data.target);
3214 set_failure (ctx, "can't encode patch");
3220 set_failure (ctx, "aot");
3224 callee = LLVMAddFunction (lmodule, "", llvm_sig);
3226 if (cfg->abs_patches) {
3227 MonoJumpInfo *abs_ji = (MonoJumpInfo*)g_hash_table_lookup (cfg->abs_patches, call->fptr);
3232 * FIXME: Some trampolines might have
3233 * their own calling convention on some platforms.
3235 target = mono_resolve_patch_target (cfg->method, cfg->domain, NULL, abs_ji, FALSE, &error);
3236 mono_error_assert_ok (&error);
3237 LLVMAddGlobalMapping (ctx->module->ee, callee, target);
3241 LLVMAddGlobalMapping (ctx->module->ee, callee, (gpointer)call->fptr);
3247 int size = sizeof (gpointer);
3250 g_assert (ins->inst_offset % size == 0);
3251 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
3253 callee = convert (ctx, LLVMBuildLoad (builder, LLVMBuildGEP (builder, convert (ctx, values [ins->inst_basereg], LLVMPointerType (LLVMPointerType (IntPtrType (), 0), 0)), &index, 1, ""), ""), LLVMPointerType (llvm_sig, 0));
3255 callee = convert (ctx, values [ins->sreg1], LLVMPointerType (llvm_sig, 0));
3257 if (ins->flags & MONO_INST_HAS_METHOD) {
3262 * Collect and convert arguments
3264 nargs = (sig->param_count * 16) + sig->hasthis + vretaddr + call->rgctx_reg + call->imt_arg_reg;
3265 len = sizeof (LLVMValueRef) * nargs;
3266 args = (LLVMValueRef*)alloca (len);
3267 memset (args, 0, len);
3268 l = call->out_ireg_args;
3270 if (call->rgctx_arg_reg) {
3271 g_assert (values [call->rgctx_arg_reg]);
3272 g_assert (cinfo->rgctx_arg_pindex < nargs);
3274 * On ARM, the imt/rgctx argument is passed in a caller save register, but some of our trampolines etc. clobber it, leading to
3275 * problems is LLVM moves the arg assignment earlier. To work around this, save the argument into a stack slot and load
3276 * it using a volatile load.
3279 if (!ctx->imt_rgctx_loc)
3280 ctx->imt_rgctx_loc = build_alloca_llvm_type (ctx, ctx->module->ptr_type, sizeof (gpointer));
3281 LLVMBuildStore (builder, convert (ctx, ctx->values [call->rgctx_arg_reg], ctx->module->ptr_type), ctx->imt_rgctx_loc);
3282 args [cinfo->rgctx_arg_pindex] = mono_llvm_build_load (builder, ctx->imt_rgctx_loc, "", TRUE, LLVM_BARRIER_NONE);
3284 args [cinfo->rgctx_arg_pindex] = convert (ctx, values [call->rgctx_arg_reg], ctx->module->ptr_type);
3287 if (call->imt_arg_reg) {
3288 g_assert (!ctx->llvm_only);
3289 g_assert (values [call->imt_arg_reg]);
3290 g_assert (cinfo->imt_arg_pindex < nargs);
3292 if (!ctx->imt_rgctx_loc)
3293 ctx->imt_rgctx_loc = build_alloca_llvm_type (ctx, ctx->module->ptr_type, sizeof (gpointer));
3294 LLVMBuildStore (builder, convert (ctx, ctx->values [call->imt_arg_reg], ctx->module->ptr_type), ctx->imt_rgctx_loc);
3295 args [cinfo->imt_arg_pindex] = mono_llvm_build_load (builder, ctx->imt_rgctx_loc, "", TRUE, LLVM_BARRIER_NONE);
3297 args [cinfo->imt_arg_pindex] = convert (ctx, values [call->imt_arg_reg], ctx->module->ptr_type);
3300 switch (cinfo->ret.storage) {
3301 case LLVMArgGsharedvtVariable: {
3302 MonoInst *var = get_vreg_to_inst (cfg, call->inst.dreg);
3304 if (var && var->opcode == OP_GSHAREDVT_LOCAL) {
3305 args [cinfo->vret_arg_pindex] = convert (ctx, emit_gsharedvt_ldaddr (ctx, var->dreg), IntPtrType ());
3307 g_assert (addresses [call->inst.dreg]);
3308 args [cinfo->vret_arg_pindex] = addresses [call->inst.dreg];
3314 if (!addresses [call->inst.dreg])
3315 addresses [call->inst.dreg] = build_alloca (ctx, sig->ret);
3316 g_assert (cinfo->vret_arg_pindex < nargs);
3317 if (cinfo->ret.storage == LLVMArgVtypeByRef)
3318 args [cinfo->vret_arg_pindex] = addresses [call->inst.dreg];
3320 args [cinfo->vret_arg_pindex] = LLVMBuildPtrToInt (builder, addresses [call->inst.dreg], IntPtrType (), "");
3326 * Sometimes the same method is called with two different signatures (i.e. with and without 'this'), so
3327 * use the real callee for argument type conversion.
3329 LLVMTypeRef callee_type = LLVMGetElementType (LLVMTypeOf (callee));
3330 LLVMTypeRef *param_types = (LLVMTypeRef*)g_alloca (sizeof (LLVMTypeRef) * LLVMCountParamTypes (callee_type));
3331 LLVMGetParamTypes (callee_type, param_types);
3333 for (i = 0; i < sig->param_count + sig->hasthis; ++i) {
3336 LLVMArgInfo *ainfo = &call->cinfo->args [i];
3338 pindex = ainfo->pindex;
3340 regpair = (guint32)(gssize)(l->data);
3341 reg = regpair & 0xffffff;
3342 args [pindex] = values [reg];
3343 switch (ainfo->storage) {
3344 case LLVMArgVtypeInReg:
3345 case LLVMArgAsFpArgs: {
3349 for (j = 0; j < ainfo->ndummy_fpargs; ++j)
3350 args [pindex + j] = LLVMConstNull (LLVMDoubleType ());
3351 pindex += ainfo->ndummy_fpargs;
3353 g_assert (addresses [reg]);
3354 emit_vtype_to_args (ctx, builder, ainfo->type, addresses [reg], ainfo, args + pindex, &nargs);
3358 // FIXME: Get rid of the VMOVE
3361 case LLVMArgVtypeByVal:
3362 g_assert (addresses [reg]);
3363 args [pindex] = addresses [reg];
3365 case LLVMArgVtypeByRef:
3366 case LLVMArgScalarByRef: {
3367 g_assert (addresses [reg]);
3368 args [pindex] = convert (ctx, addresses [reg], LLVMPointerType (type_to_llvm_arg_type (ctx, ainfo->type), 0));
3371 case LLVMArgAsIArgs:
3372 g_assert (addresses [reg]);
3373 args [pindex] = LLVMBuildLoad (ctx->builder, convert (ctx, addresses [reg], LLVMPointerType (LLVMArrayType (IntPtrType (), ainfo->nslots), 0)), "");
3375 case LLVMArgVtypeAsScalar:
3376 g_assert_not_reached ();
3378 case LLVMArgGsharedvtFixed:
3379 case LLVMArgGsharedvtFixedVtype:
3380 g_assert (addresses [reg]);
3381 args [pindex] = convert (ctx, addresses [reg], LLVMPointerType (type_to_llvm_arg_type (ctx, ainfo->type), 0));
3383 case LLVMArgGsharedvtVariable:
3384 g_assert (addresses [reg]);
3385 args [pindex] = convert (ctx, addresses [reg], LLVMPointerType (IntPtrType (), 0));
3388 g_assert (args [pindex]);
3389 if (i == 0 && sig->hasthis)
3390 args [pindex] = convert (ctx, args [pindex], param_types [pindex]);
3392 args [pindex] = convert (ctx, args [pindex], type_to_llvm_arg_type (ctx, ainfo->type));
3395 g_assert (pindex <= nargs);
3400 // FIXME: Align call sites
3406 lcall = emit_call (ctx, bb, &builder, callee, args, LLVMCountParamTypes (llvm_sig));
3409 * Modify cconv and parameter attributes to pass rgctx/imt correctly.
3411 #if defined(MONO_ARCH_IMT_REG) && defined(MONO_ARCH_RGCTX_REG)
3412 g_assert (MONO_ARCH_IMT_REG == MONO_ARCH_RGCTX_REG);
3414 /* The two can't be used together, so use only one LLVM calling conv to pass them */
3415 g_assert (!(call->rgctx_arg_reg && call->imt_arg_reg));
3416 if (!sig->pinvoke && !cfg->llvm_only)
3417 LLVMSetInstructionCallConv (lcall, LLVMMono1CallConv);
3419 mono_llvm_set_call_preserveall_cc (lcall);
3421 if (cinfo->ret.storage == LLVMArgVtypeByRef)
3422 LLVMAddInstrAttribute (lcall, 1 + cinfo->vret_arg_pindex, LLVMStructRetAttribute);
3423 if (!ctx->llvm_only && call->rgctx_arg_reg)
3424 LLVMAddInstrAttribute (lcall, 1 + cinfo->rgctx_arg_pindex, LLVMInRegAttribute);
3425 if (call->imt_arg_reg)
3426 LLVMAddInstrAttribute (lcall, 1 + cinfo->imt_arg_pindex, LLVMInRegAttribute);
3428 /* Add byval attributes if needed */
3429 for (i = 0; i < sig->param_count; ++i) {
3430 LLVMArgInfo *ainfo = &call->cinfo->args [i + sig->hasthis];
3432 if (ainfo && ainfo->storage == LLVMArgVtypeByVal)
3433 LLVMAddInstrAttribute (lcall, 1 + ainfo->pindex, LLVMByValAttribute);
3437 * Convert the result
3439 switch (cinfo->ret.storage) {
3440 case LLVMArgVtypeInReg: {
3441 LLVMValueRef regs [2];
3443 if (LLVMTypeOf (lcall) == LLVMVoidType ())
3447 if (!addresses [ins->dreg])
3448 addresses [ins->dreg] = build_alloca (ctx, sig->ret);
3450 regs [0] = LLVMBuildExtractValue (builder, lcall, 0, "");
3451 if (cinfo->ret.pair_storage [1] != LLVMArgNone)
3452 regs [1] = LLVMBuildExtractValue (builder, lcall, 1, "");
3453 emit_args_to_vtype (ctx, builder, sig->ret, addresses [ins->dreg], &cinfo->ret, regs);
3456 case LLVMArgVtypeByVal:
3457 if (!addresses [call->inst.dreg])
3458 addresses [call->inst.dreg] = build_alloca (ctx, sig->ret);
3459 LLVMBuildStore (builder, lcall, addresses [call->inst.dreg]);
3461 case LLVMArgFpStruct:
3462 if (!addresses [call->inst.dreg])
3463 addresses [call->inst.dreg] = build_alloca (ctx, sig->ret);
3464 LLVMBuildStore (builder, lcall, convert_full (ctx, addresses [call->inst.dreg], LLVMPointerType (LLVMTypeOf (lcall), 0), FALSE));
3466 case LLVMArgVtypeAsScalar:
3467 if (!addresses [call->inst.dreg])
3468 addresses [call->inst.dreg] = build_alloca (ctx, sig->ret);
3469 LLVMBuildStore (builder, lcall, convert_full (ctx, addresses [call->inst.dreg], LLVMPointerType (LLVMTypeOf (lcall), 0), FALSE));
3471 case LLVMArgVtypeRetAddr:
3472 case LLVMArgVtypeByRef:
3473 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (sig->ret))) {
3474 /* Some opcodes like STOREX_MEMBASE access these by value */
3475 g_assert (addresses [call->inst.dreg]);
3476 values [ins->dreg] = LLVMBuildLoad (builder, convert_full (ctx, addresses [call->inst.dreg], LLVMPointerType (type_to_llvm_type (ctx, sig->ret), 0), FALSE), "");
3479 case LLVMArgScalarRetAddr:
3480 /* Normal scalar returned using a vtype return argument */
3481 values [ins->dreg] = LLVMBuildLoad (builder, convert_full (ctx, addresses [call->inst.dreg], LLVMPointerType (type_to_llvm_type (ctx, sig->ret), 0), FALSE), "");
3483 case LLVMArgGsharedvtVariable:
3485 case LLVMArgGsharedvtFixed:
3486 case LLVMArgGsharedvtFixedVtype:
3487 values [ins->dreg] = LLVMBuildLoad (builder, convert_full (ctx, addresses [call->inst.dreg], LLVMPointerType (type_to_llvm_type (ctx, sig->ret), 0), FALSE), "");
3490 if (sig->ret->type != MONO_TYPE_VOID)
3491 /* If the method returns an unsigned value, need to zext it */
3492 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));
3496 *builder_ref = ctx->builder;
3500 emit_llvmonly_throw (EmitContext *ctx, MonoBasicBlock *bb, gboolean rethrow, LLVMValueRef exc)
3502 const char *icall_name = rethrow ? "mono_llvm_rethrow_exception" : "mono_llvm_throw_exception";
3503 LLVMValueRef callee = rethrow ? ctx->module->rethrow : ctx->module->throw_icall;
3505 LLVMTypeRef exc_type = type_to_llvm_type (ctx, &mono_get_exception_class ()->byval_arg);
3508 LLVMTypeRef fun_sig = LLVMFunctionType1 (LLVMVoidType (), exc_type, FALSE);
3510 if (ctx->cfg->compile_aot) {
3511 callee = get_callee (ctx, fun_sig, MONO_PATCH_INFO_JIT_ICALL_ADDR, icall_name);
3513 callee = LLVMAddFunction (ctx->lmodule, icall_name, fun_sig);
3514 LLVMAddGlobalMapping (ctx->module->ee, callee, resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name));
3515 mono_memory_barrier ();
3518 ctx->module->rethrow = callee;
3520 ctx->module->throw_icall = callee;
3524 LLVMValueRef args [2];
3526 args [0] = convert (ctx, exc, exc_type);
3527 emit_call (ctx, bb, &ctx->builder, callee, args, 1);
3529 LLVMBuildUnreachable (ctx->builder);
3531 ctx->builder = create_builder (ctx);
3535 emit_throw (EmitContext *ctx, MonoBasicBlock *bb, gboolean rethrow, LLVMValueRef exc)
3537 MonoMethodSignature *throw_sig;
3538 LLVMValueRef callee, arg;
3539 const char *icall_name;
3541 callee = rethrow ? ctx->module->rethrow : ctx->module->throw_icall;
3542 icall_name = rethrow ? "mono_arch_rethrow_exception" : "mono_arch_throw_exception";
3545 throw_sig = mono_metadata_signature_alloc (mono_get_corlib (), 1);
3546 throw_sig->ret = &mono_get_void_class ()->byval_arg;
3547 throw_sig->params [0] = &mono_get_object_class ()->byval_arg;
3548 if (ctx->cfg->compile_aot) {
3549 callee = get_callee (ctx, sig_to_llvm_sig (ctx, throw_sig), MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
3551 callee = LLVMAddFunction (ctx->lmodule, icall_name, sig_to_llvm_sig (ctx, throw_sig));
3555 * LLVM doesn't push the exception argument, so we need a different
3558 LLVMAddGlobalMapping (ctx->module->ee, callee, resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, rethrow ? "llvm_rethrow_exception_trampoline" : "llvm_throw_exception_trampoline"));
3560 LLVMAddGlobalMapping (ctx->module->ee, callee, resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name));
3564 mono_memory_barrier ();
3566 ctx->module->rethrow = callee;
3568 ctx->module->throw_icall = callee;
3570 arg = convert (ctx, exc, type_to_llvm_type (ctx, &mono_get_object_class ()->byval_arg));
3571 emit_call (ctx, bb, &ctx->builder, callee, &arg, 1);
3575 emit_resume_eh (EmitContext *ctx, MonoBasicBlock *bb)
3577 const char *icall_name = "mono_llvm_resume_exception";
3578 LLVMValueRef callee = ctx->module->resume_eh;
3580 LLVMTypeRef fun_sig = LLVMFunctionType0 (LLVMVoidType (), FALSE);
3583 if (ctx->cfg->compile_aot) {
3584 callee = get_callee (ctx, fun_sig, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
3586 callee = LLVMAddFunction (ctx->lmodule, icall_name, fun_sig);
3587 LLVMAddGlobalMapping (ctx->module->ee, callee, resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name));
3588 mono_memory_barrier ();
3590 ctx->module->resume_eh = callee;
3594 emit_call (ctx, bb, &ctx->builder, callee, NULL, 0);
3596 LLVMBuildUnreachable (ctx->builder);
3598 ctx->builder = create_builder (ctx);
3602 mono_llvm_emit_clear_exception_call (EmitContext *ctx, LLVMBuilderRef builder)
3604 const char *icall_name = "mono_llvm_clear_exception";
3606 LLVMTypeRef call_sig = LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE);
3607 LLVMValueRef callee = NULL;
3610 if (ctx->cfg->compile_aot) {
3611 callee = get_callee (ctx, call_sig, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
3613 // FIXME: This is broken.
3614 callee = LLVMAddFunction (ctx->lmodule, icall_name, call_sig);
3618 g_assert (builder && callee);
3620 return LLVMBuildCall (builder, callee, NULL, 0, "");
3624 mono_llvm_emit_load_exception_call (EmitContext *ctx, LLVMBuilderRef builder)
3626 const char *icall_name = "mono_llvm_load_exception";
3628 LLVMTypeRef call_sig = LLVMFunctionType (ObjRefType (), NULL, 0, FALSE);
3629 LLVMValueRef callee = NULL;
3632 if (ctx->cfg->compile_aot) {
3633 callee = get_callee (ctx, call_sig, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
3635 // FIXME: This is broken.
3636 callee = LLVMAddFunction (ctx->lmodule, icall_name, call_sig);
3640 g_assert (builder && callee);
3642 return LLVMBuildCall (builder, callee, NULL, 0, icall_name);
3647 mono_llvm_emit_match_exception_call (EmitContext *ctx, LLVMBuilderRef builder, gint32 region_start, gint32 region_end)
3649 const char *icall_name = "mono_llvm_match_exception";
3651 ctx->builder = builder;
3653 const int num_args = 5;
3654 LLVMValueRef args [num_args];
3655 args [0] = convert (ctx, get_aotconst (ctx, MONO_PATCH_INFO_AOT_JIT_INFO, GINT_TO_POINTER (ctx->cfg->method_index)), IntPtrType ());
3656 args [1] = LLVMConstInt (LLVMInt32Type (), region_start, 0);
3657 args [2] = LLVMConstInt (LLVMInt32Type (), region_end, 0);
3658 if (ctx->cfg->rgctx_var) {
3659 LLVMValueRef rgctx_alloc = ctx->addresses [ctx->cfg->rgctx_var->dreg];
3660 g_assert (rgctx_alloc);
3661 args [3] = LLVMBuildLoad (builder, convert (ctx, rgctx_alloc, LLVMPointerType (IntPtrType (), 0)), "");
3663 args [3] = LLVMConstInt (IntPtrType (), 0, 0);
3666 args [4] = convert (ctx, ctx->this_arg, IntPtrType ());
3668 args [4] = LLVMConstInt (IntPtrType (), 0, 0);
3670 LLVMTypeRef match_sig = LLVMFunctionType5 (LLVMInt32Type (), IntPtrType (), LLVMInt32Type (), LLVMInt32Type (), IntPtrType (), IntPtrType (), FALSE);
3671 LLVMValueRef callee = ctx->module->match_exc;
3674 if (ctx->cfg->compile_aot) {
3675 ctx->builder = builder;
3676 // get_callee expects ctx->builder to be the emitting builder
3677 callee = get_callee (ctx, match_sig, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
3679 callee = ctx->module->match_exc = LLVMAddFunction (ctx->lmodule, icall_name, match_sig);
3680 LLVMAddGlobalMapping (ctx->module->ee, ctx->module->match_exc, resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name));
3681 ctx->module->match_exc = callee;
3682 mono_memory_barrier ();
3686 g_assert (builder && callee);
3688 g_assert (ctx->ex_var);
3690 return LLVMBuildCall (builder, callee, args, num_args, icall_name);
3693 // FIXME: This won't work because the code-finding makes this
3695 /*#define MONO_PERSONALITY_DEBUG*/
3697 #ifdef MONO_PERSONALITY_DEBUG
3698 static const gboolean use_debug_personality = TRUE;
3699 static const char *default_personality_name = "mono_debug_personality";
3701 static const gboolean use_debug_personality = FALSE;
3702 static const char *default_personality_name = "__gxx_personality_v0";
3706 default_cpp_lpad_exc_signature (void)
3708 static gboolean inited = FALSE;
3709 static LLVMTypeRef sig;
3712 LLVMTypeRef signature [2];
3713 signature [0] = LLVMPointerType (LLVMInt8Type (), 0);
3714 signature [1] = LLVMInt32Type ();
3715 sig = LLVMStructType (signature, 2, FALSE);
3723 get_mono_personality (EmitContext *ctx)
3725 LLVMValueRef personality = NULL;
3726 static gint32 mapping_inited = FALSE;
3727 LLVMTypeRef personality_type = LLVMFunctionType (LLVMInt32Type (), NULL, 0, TRUE);
3729 if (!use_debug_personality) {
3730 if (ctx->cfg->compile_aot) {
3731 personality = LLVMGetNamedFunction (ctx->lmodule, default_personality_name);
3732 } else if (InterlockedCompareExchange (&mapping_inited, 1, 0) == 0) {
3733 personality = LLVMAddFunction (ctx->lmodule, default_personality_name, personality_type);
3734 LLVMAddGlobalMapping (ctx->module->ee, personality, personality);
3737 if (ctx->cfg->compile_aot) {
3738 personality = get_callee (ctx, personality_type, MONO_PATCH_INFO_INTERNAL_METHOD, default_personality_name);
3740 personality = LLVMAddFunction (ctx->lmodule, default_personality_name, personality_type);
3741 LLVMAddGlobalMapping (ctx->module->ee, personality, resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, default_personality_name));
3742 mono_memory_barrier ();
3746 g_assert (personality);
3750 static LLVMBasicBlockRef
3751 emit_landing_pad (EmitContext *ctx, int group_index, int group_size)
3753 MonoCompile *cfg = ctx->cfg;
3754 LLVMBuilderRef old_builder = ctx->builder;
3755 MonoExceptionClause *group_start = cfg->header->clauses + group_index;
3757 LLVMBuilderRef lpadBuilder = create_builder (ctx);
3758 ctx->builder = lpadBuilder;
3760 MonoBasicBlock *handler_bb = cfg->cil_offset_to_bb [CLAUSE_START (group_start)];
3761 g_assert (handler_bb);
3763 // <resultval> = landingpad <somety> personality <type> <pers_fn> <clause>+
3764 LLVMValueRef personality = get_mono_personality (ctx);
3765 g_assert (personality);
3767 char *bb_name = g_strdup_printf ("LPAD%d_BB", group_index);
3768 LLVMBasicBlockRef lpad_bb = gen_bb (ctx, bb_name);
3770 LLVMPositionBuilderAtEnd (lpadBuilder, lpad_bb);
3771 LLVMValueRef landing_pad = LLVMBuildLandingPad (lpadBuilder, default_cpp_lpad_exc_signature (), personality, 0, "");
3772 g_assert (landing_pad);
3774 LLVMValueRef cast = LLVMBuildBitCast (lpadBuilder, ctx->module->sentinel_exception, LLVMPointerType (LLVMInt8Type (), 0), "int8TypeInfo");
3775 LLVMAddClause (landing_pad, cast);
3777 LLVMBasicBlockRef resume_bb = gen_bb (ctx, "RESUME_BB");
3778 LLVMBuilderRef resume_builder = create_builder (ctx);
3779 ctx->builder = resume_builder;
3780 LLVMPositionBuilderAtEnd (resume_builder, resume_bb);
3782 emit_resume_eh (ctx, handler_bb);
3785 ctx->builder = lpadBuilder;
3786 LLVMPositionBuilderAtEnd (lpadBuilder, lpad_bb);
3788 gboolean finally_only = TRUE;
3790 MonoExceptionClause *group_cursor = group_start;
3792 for (int i = 0; i < group_size; i ++) {
3793 if (!(group_cursor->flags & MONO_EXCEPTION_CLAUSE_FINALLY))
3794 finally_only = FALSE;
3800 // Handle landing pad inlining
3802 if (!finally_only) {
3803 // So at each level of the exception stack we will match the exception again.
3804 // During that match, we need to compare against the handler types for the current
3805 // protected region. We send the try start and end so that we can only check against
3806 // handlers for this lexical protected region.
3807 LLVMValueRef match = mono_llvm_emit_match_exception_call (ctx, lpadBuilder, group_start->try_offset, group_start->try_offset + group_start->try_len);
3809 // if returns -1, resume
3810 LLVMValueRef switch_ins = LLVMBuildSwitch (lpadBuilder, match, resume_bb, group_size);
3812 // else move to that target bb
3813 for (int i=0; i < group_size; i++) {
3814 MonoExceptionClause *clause = group_start + i;
3815 int clause_index = clause - cfg->header->clauses;
3816 MonoBasicBlock *handler_bb = (MonoBasicBlock*)g_hash_table_lookup (ctx->clause_to_handler, GINT_TO_POINTER (clause_index));
3817 g_assert (handler_bb);
3818 g_assert (ctx->bblocks [handler_bb->block_num].call_handler_target_bb);
3819 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), clause_index, FALSE), ctx->bblocks [handler_bb->block_num].call_handler_target_bb);
3822 int clause_index = group_start - cfg->header->clauses;
3823 MonoBasicBlock *finally_bb = (MonoBasicBlock*)g_hash_table_lookup (ctx->clause_to_handler, GINT_TO_POINTER (clause_index));
3824 g_assert (finally_bb);
3826 LLVMBuildBr (ctx->builder, ctx->bblocks [finally_bb->block_num].call_handler_target_bb);
3829 ctx->builder = old_builder;
3836 emit_llvmonly_handler_start (EmitContext *ctx, MonoBasicBlock *bb, LLVMBasicBlockRef cbb)
3838 int clause_index = MONO_REGION_CLAUSE_INDEX (bb->region);
3839 MonoExceptionClause *clause = &ctx->cfg->header->clauses [clause_index];
3841 // Make exception available to catch blocks
3842 if (!(clause->flags & MONO_EXCEPTION_CLAUSE_FINALLY)) {
3843 LLVMValueRef mono_exc = mono_llvm_emit_load_exception_call (ctx, ctx->builder);
3845 g_assert (ctx->ex_var);
3846 LLVMBuildStore (ctx->builder, LLVMBuildBitCast (ctx->builder, mono_exc, ObjRefType (), ""), ctx->ex_var);
3848 if (bb->in_scount == 1) {
3849 MonoInst *exvar = bb->in_stack [0];
3850 g_assert (!ctx->values [exvar->dreg]);
3851 g_assert (ctx->ex_var);
3852 ctx->values [exvar->dreg] = LLVMBuildLoad (ctx->builder, ctx->ex_var, "save_exception");
3853 emit_volatile_store (ctx, exvar->dreg);
3856 mono_llvm_emit_clear_exception_call (ctx, ctx->builder);
3859 LLVMBuilderRef handler_builder = create_builder (ctx);
3860 LLVMBasicBlockRef target_bb = ctx->bblocks [bb->block_num].call_handler_target_bb;
3861 LLVMPositionBuilderAtEnd (handler_builder, target_bb);
3863 // Make the handler code end with a jump to cbb
3864 LLVMBuildBr (handler_builder, cbb);
3868 emit_handler_start (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef builder)
3870 MonoCompile *cfg = ctx->cfg;
3871 LLVMValueRef *values = ctx->values;
3872 LLVMModuleRef lmodule = ctx->lmodule;
3873 BBInfo *bblocks = ctx->bblocks;
3875 LLVMValueRef personality;
3876 LLVMValueRef landing_pad;
3877 LLVMBasicBlockRef target_bb;
3879 static gint32 mapping_inited;
3880 static int ti_generator;
3883 LLVMValueRef type_info;
3887 // <resultval> = landingpad <somety> personality <type> <pers_fn> <clause>+
3889 if (cfg->compile_aot) {
3890 /* Use a dummy personality function */
3891 personality = LLVMGetNamedFunction (lmodule, "mono_personality");
3892 g_assert (personality);
3894 personality = LLVMGetNamedFunction (lmodule, "mono_personality");
3895 if (InterlockedCompareExchange (&mapping_inited, 1, 0) == 0)
3896 LLVMAddGlobalMapping (ctx->module->ee, personality, (gpointer)mono_personality);
3899 i8ptr = LLVMPointerType (LLVMInt8Type (), 0);
3901 clause_index = (mono_get_block_region_notry (cfg, bb->region) >> 8) - 1;
3904 * Create the type info
3906 sprintf (ti_name, "type_info_%d", ti_generator);
3909 if (cfg->compile_aot) {
3910 /* decode_eh_frame () in aot-runtime.c will decode this */
3911 type_info = LLVMAddGlobal (lmodule, LLVMInt32Type (), ti_name);
3912 LLVMSetInitializer (type_info, LLVMConstInt (LLVMInt32Type (), clause_index, FALSE));
3915 * These symbols are not really used, the clause_index is embedded into the EH tables generated by DwarfMonoException in LLVM.
3917 LLVMSetLinkage (type_info, LLVMInternalLinkage);
3920 * After the cfg mempool is freed, the type info will point to stale memory,
3921 * but this is not a problem, since we decode it once in exception_cb during
3924 ti = (gint32*)mono_mempool_alloc (cfg->mempool, sizeof (gint32));
3925 *(gint32*)ti = clause_index;
3927 type_info = LLVMAddGlobal (lmodule, i8ptr, ti_name);
3929 LLVMAddGlobalMapping (ctx->module->ee, type_info, ti);
3933 LLVMTypeRef members [2], ret_type;
3935 members [0] = i8ptr;
3936 members [1] = LLVMInt32Type ();
3937 ret_type = LLVMStructType (members, 2, FALSE);
3939 landing_pad = LLVMBuildLandingPad (builder, ret_type, personality, 1, "");
3940 LLVMAddClause (landing_pad, type_info);
3942 /* Store the exception into the exvar */
3944 LLVMBuildStore (builder, convert (ctx, LLVMBuildExtractValue (builder, landing_pad, 0, "ex_obj"), ObjRefType ()), ctx->ex_var);
3948 * LLVM throw sites are associated with a one landing pad, and LLVM generated
3949 * code expects control to be transferred to this landing pad even in the
3950 * presence of nested clauses. The landing pad needs to branch to the landing
3951 * pads belonging to nested clauses based on the selector value returned by
3952 * the landing pad instruction, which is passed to the landing pad in a
3953 * register by the EH code.
3955 target_bb = bblocks [bb->block_num].call_handler_target_bb;
3956 g_assert (target_bb);
3959 * Branch to the correct landing pad
3961 LLVMValueRef ex_selector = LLVMBuildExtractValue (builder, landing_pad, 1, "ex_selector");
3962 LLVMValueRef switch_ins = LLVMBuildSwitch (builder, ex_selector, target_bb, 0);
3964 for (l = ctx->nested_in [clause_index]; l; l = l->next) {
3965 int nesting_clause_index = GPOINTER_TO_INT (l->data);
3966 MonoBasicBlock *handler_bb;
3968 handler_bb = (MonoBasicBlock*)g_hash_table_lookup (ctx->clause_to_handler, GINT_TO_POINTER (nesting_clause_index));
3969 g_assert (handler_bb);
3971 g_assert (ctx->bblocks [handler_bb->block_num].call_handler_target_bb);
3972 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), nesting_clause_index, FALSE), ctx->bblocks [handler_bb->block_num].call_handler_target_bb);
3975 /* Start a new bblock which CALL_HANDLER can branch to */
3976 target_bb = bblocks [bb->block_num].call_handler_target_bb;
3978 ctx->builder = builder = create_builder (ctx);
3979 LLVMPositionBuilderAtEnd (ctx->builder, target_bb);
3981 ctx->bblocks [bb->block_num].end_bblock = target_bb;
3983 /* Store the exception into the IL level exvar */
3984 if (bb->in_scount == 1) {
3985 g_assert (bb->in_scount == 1);
3986 exvar = bb->in_stack [0];
3988 // FIXME: This is shared with filter clauses ?
3989 g_assert (!values [exvar->dreg]);
3991 g_assert (ctx->ex_var);
3992 values [exvar->dreg] = LLVMBuildLoad (builder, ctx->ex_var, "");
3993 emit_volatile_store (ctx, exvar->dreg);
3999 process_bb (EmitContext *ctx, MonoBasicBlock *bb)
4001 MonoCompile *cfg = ctx->cfg;
4002 MonoMethodSignature *sig = ctx->sig;
4003 LLVMValueRef method = ctx->lmethod;
4004 LLVMValueRef *values = ctx->values;
4005 LLVMValueRef *addresses = ctx->addresses;
4006 LLVMCallInfo *linfo = ctx->linfo;
4007 LLVMModuleRef lmodule = ctx->lmodule;
4008 BBInfo *bblocks = ctx->bblocks;
4010 LLVMBasicBlockRef cbb;
4011 LLVMBuilderRef builder, starting_builder;
4012 gboolean has_terminator;
4014 LLVMValueRef lhs, rhs;
4017 cbb = get_end_bb (ctx, bb);
4019 builder = create_builder (ctx);
4020 ctx->builder = builder;
4021 LLVMPositionBuilderAtEnd (builder, cbb);
4026 if (bb->flags & BB_EXCEPTION_HANDLER) {
4027 if (!ctx->llvm_only && !bblocks [bb->block_num].invoke_target) {
4028 set_failure (ctx, "handler without invokes");
4033 emit_llvmonly_handler_start (ctx, bb, cbb);
4035 emit_handler_start (ctx, bb, builder);
4038 builder = ctx->builder;
4041 has_terminator = FALSE;
4042 starting_builder = builder;
4043 for (ins = bb->code; ins; ins = ins->next) {
4044 const char *spec = LLVM_INS_INFO (ins->opcode);
4046 char dname_buf [128];
4048 emit_dbg_loc (ctx, builder, ins->cil_code);
4053 * Some steps in llc are non-linear in the size of basic blocks, see #5714.
4054 * Start a new bblock. If the llvm optimization passes merge these, we
4055 * can work around that by doing a volatile load + cond branch from
4056 * localloc-ed memory.
4058 //set_failure (ctx, "basic block too long");
4059 cbb = gen_bb (ctx, "CONT_LONG_BB");
4060 LLVMBuildBr (ctx->builder, cbb);
4061 ctx->builder = builder = create_builder (ctx);
4062 LLVMPositionBuilderAtEnd (builder, cbb);
4063 ctx->bblocks [bb->block_num].end_bblock = cbb;
4068 /* There could be instructions after a terminator, skip them */
4071 if (spec [MONO_INST_DEST] != ' ' && !MONO_IS_STORE_MEMBASE (ins)) {
4072 sprintf (dname_buf, "t%d", ins->dreg);
4076 if (spec [MONO_INST_SRC1] != ' ' && spec [MONO_INST_SRC1] != 'v') {
4077 MonoInst *var = get_vreg_to_inst (cfg, ins->sreg1);
4079 if (var && var->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT) && var->opcode != OP_GSHAREDVT_ARG_REGOFFSET) {
4080 lhs = emit_volatile_load (ctx, ins->sreg1);
4082 /* It is ok for SETRET to have an uninitialized argument */
4083 if (!values [ins->sreg1] && ins->opcode != OP_SETRET) {
4084 set_failure (ctx, "sreg1");
4087 lhs = values [ins->sreg1];
4093 if (spec [MONO_INST_SRC2] != ' ' && spec [MONO_INST_SRC2] != ' ') {
4094 MonoInst *var = get_vreg_to_inst (cfg, ins->sreg2);
4095 if (var && var->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT)) {
4096 rhs = emit_volatile_load (ctx, ins->sreg2);
4098 if (!values [ins->sreg2]) {
4099 set_failure (ctx, "sreg2");
4102 rhs = values [ins->sreg2];
4108 //mono_print_ins (ins);
4109 switch (ins->opcode) {
4112 case OP_LIVERANGE_START:
4113 case OP_LIVERANGE_END:
4116 values [ins->dreg] = LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE);
4119 #if SIZEOF_VOID_P == 4
4120 values [ins->dreg] = LLVMConstInt (LLVMInt64Type (), GET_LONG_IMM (ins), FALSE);
4122 values [ins->dreg] = LLVMConstInt (LLVMInt64Type (), (gint64)ins->inst_c0, FALSE);
4126 values [ins->dreg] = LLVMConstReal (LLVMDoubleType (), *(double*)ins->inst_p0);
4130 values [ins->dreg] = LLVMConstReal (LLVMFloatType (), *(float*)ins->inst_p0);
4132 values [ins->dreg] = LLVMConstFPExt (LLVMConstReal (LLVMFloatType (), *(float*)ins->inst_p0), LLVMDoubleType ());
4134 case OP_DUMMY_ICONST:
4135 values [ins->dreg] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
4137 case OP_DUMMY_I8CONST:
4138 values [ins->dreg] = LLVMConstInt (LLVMInt64Type (), 0, FALSE);
4140 case OP_DUMMY_R8CONST:
4141 values [ins->dreg] = LLVMConstReal (LLVMDoubleType (), 0.0f);
4144 LLVMBasicBlockRef target_bb = get_bb (ctx, ins->inst_target_bb);
4145 LLVMBuildBr (builder, target_bb);
4146 has_terminator = TRUE;
4153 LLVMBasicBlockRef new_bb;
4154 LLVMBuilderRef new_builder;
4156 // The default branch is already handled
4157 // FIXME: Handle it here
4159 /* Start new bblock */
4160 sprintf (bb_name, "SWITCH_DEFAULT_BB%d", ctx->default_index ++);
4161 new_bb = LLVMAppendBasicBlock (ctx->lmethod, bb_name);
4163 lhs = convert (ctx, lhs, LLVMInt32Type ());
4164 v = LLVMBuildSwitch (builder, lhs, new_bb, GPOINTER_TO_UINT (ins->klass));
4165 for (i = 0; i < GPOINTER_TO_UINT (ins->klass); ++i) {
4166 MonoBasicBlock *target_bb = ins->inst_many_bb [i];
4168 LLVMAddCase (v, LLVMConstInt (LLVMInt32Type (), i, FALSE), get_bb (ctx, target_bb));
4171 new_builder = create_builder (ctx);
4172 LLVMPositionBuilderAtEnd (new_builder, new_bb);
4173 LLVMBuildUnreachable (new_builder);
4175 has_terminator = TRUE;
4176 g_assert (!ins->next);
4182 switch (linfo->ret.storage) {
4183 case LLVMArgVtypeInReg: {
4184 LLVMTypeRef ret_type = LLVMGetReturnType (LLVMGetElementType (LLVMTypeOf (method)));
4185 LLVMValueRef val, addr, retval;
4188 retval = LLVMGetUndef (ret_type);
4190 if (!addresses [ins->sreg1]) {
4192 * The return type is an LLVM vector type, have to convert between it and the
4193 * real return type which is a struct type.
4195 g_assert (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (sig->ret)));
4196 /* Convert to 2xi64 first */
4197 val = LLVMBuildBitCast (builder, values [ins->sreg1], LLVMVectorType (IntPtrType (), 2), "");
4199 for (i = 0; i < 2; ++i) {
4200 if (linfo->ret.pair_storage [i] == LLVMArgInIReg) {
4201 retval = LLVMBuildInsertValue (builder, retval, LLVMBuildExtractElement (builder, val, LLVMConstInt (LLVMInt32Type (), i, FALSE), ""), i, "");
4203 g_assert (linfo->ret.pair_storage [i] == LLVMArgNone);
4207 addr = LLVMBuildBitCast (builder, addresses [ins->sreg1], LLVMPointerType (ret_type, 0), "");
4208 for (i = 0; i < 2; ++i) {
4209 if (linfo->ret.pair_storage [i] == LLVMArgInIReg) {
4210 LLVMValueRef indexes [2], part_addr;
4212 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
4213 indexes [1] = LLVMConstInt (LLVMInt32Type (), i, FALSE);
4214 part_addr = LLVMBuildGEP (builder, addr, indexes, 2, "");
4216 retval = LLVMBuildInsertValue (builder, retval, LLVMBuildLoad (builder, part_addr, ""), i, "");
4218 g_assert (linfo->ret.pair_storage [i] == LLVMArgNone);
4222 LLVMBuildRet (builder, retval);
4225 case LLVMArgVtypeAsScalar: {
4226 LLVMTypeRef ret_type = LLVMGetReturnType (LLVMGetElementType (LLVMTypeOf (method)));
4227 LLVMValueRef retval;
4229 g_assert (addresses [ins->sreg1]);
4231 retval = LLVMBuildLoad (builder, LLVMBuildBitCast (builder, addresses [ins->sreg1], LLVMPointerType (ret_type, 0), ""), "");
4232 LLVMBuildRet (builder, retval);
4235 case LLVMArgVtypeByVal: {
4236 LLVMValueRef retval;
4238 g_assert (addresses [ins->sreg1]);
4239 retval = LLVMBuildLoad (builder, addresses [ins->sreg1], "");
4240 LLVMBuildRet (builder, retval);
4243 case LLVMArgVtypeByRef: {
4244 LLVMBuildRetVoid (builder);
4247 case LLVMArgGsharedvtFixed: {
4248 LLVMTypeRef ret_type = type_to_llvm_type (ctx, sig->ret);
4249 /* The return value is in lhs, need to store to the vret argument */
4250 /* sreg1 might not be set */
4252 g_assert (cfg->vret_addr);
4253 g_assert (values [cfg->vret_addr->dreg]);
4254 LLVMBuildStore (builder, convert (ctx, lhs, ret_type), convert (ctx, values [cfg->vret_addr->dreg], LLVMPointerType (ret_type, 0)));
4256 LLVMBuildRetVoid (builder);
4259 case LLVMArgGsharedvtFixedVtype: {
4261 LLVMBuildRetVoid (builder);
4264 case LLVMArgGsharedvtVariable: {
4266 LLVMBuildRetVoid (builder);
4269 case LLVMArgVtypeRetAddr: {
4270 LLVMBuildRetVoid (builder);
4273 case LLVMArgScalarRetAddr: {
4274 LLVMTypeRef ret_type = type_to_llvm_type (ctx, sig->ret);
4275 LLVMValueRef param = LLVMGetParam (method, linfo->vret_arg_pindex);
4277 /* sreg1 might not be set */
4279 LLVMBuildStore (builder, convert (ctx, lhs, ret_type), convert (ctx, param, LLVMPointerType (ret_type, 0)));
4280 LLVMBuildRetVoid (builder);
4283 case LLVMArgFpStruct: {
4284 LLVMTypeRef ret_type = LLVMGetReturnType (LLVMGetElementType (LLVMTypeOf (method)));
4285 LLVMValueRef retval;
4287 g_assert (addresses [ins->sreg1]);
4288 retval = LLVMBuildLoad (builder, convert (ctx, addresses [ins->sreg1], LLVMPointerType (ret_type, 0)), "");
4289 LLVMBuildRet (builder, retval);
4293 case LLVMArgNormal: {
4294 if (!lhs || ctx->is_dead [ins->sreg1]) {
4296 * The method did not set its return value, probably because it
4297 * ends with a throw.
4300 LLVMBuildRetVoid (builder);
4302 LLVMBuildRet (builder, LLVMConstNull (type_to_llvm_type (ctx, sig->ret)));
4304 LLVMBuildRet (builder, convert (ctx, lhs, type_to_llvm_type (ctx, sig->ret)));
4306 has_terminator = TRUE;
4310 g_assert_not_reached ();
4319 case OP_ICOMPARE_IMM:
4320 case OP_LCOMPARE_IMM:
4321 case OP_COMPARE_IMM: {
4323 LLVMValueRef cmp, args [16];
4324 gboolean likely = (ins->flags & MONO_INST_LIKELY) != 0;
4326 if (ins->next->opcode == OP_NOP)
4329 if (ins->next->opcode == OP_BR)
4330 /* The comparison result is not needed */
4333 rel = mono_opcode_to_cond (ins->next->opcode);
4335 if (ins->opcode == OP_ICOMPARE_IMM) {
4336 lhs = convert (ctx, lhs, LLVMInt32Type ());
4337 rhs = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
4339 if (ins->opcode == OP_LCOMPARE_IMM) {
4340 lhs = convert (ctx, lhs, LLVMInt64Type ());
4341 rhs = LLVMConstInt (LLVMInt64Type (), GET_LONG_IMM (ins), FALSE);
4343 if (ins->opcode == OP_LCOMPARE) {
4344 lhs = convert (ctx, lhs, LLVMInt64Type ());
4345 rhs = convert (ctx, rhs, LLVMInt64Type ());
4347 if (ins->opcode == OP_ICOMPARE) {
4348 lhs = convert (ctx, lhs, LLVMInt32Type ());
4349 rhs = convert (ctx, rhs, LLVMInt32Type ());
4353 if (LLVMGetTypeKind (LLVMTypeOf (lhs)) == LLVMPointerTypeKind)
4354 rhs = convert (ctx, rhs, LLVMTypeOf (lhs));
4355 else if (LLVMGetTypeKind (LLVMTypeOf (rhs)) == LLVMPointerTypeKind)
4356 lhs = convert (ctx, lhs, LLVMTypeOf (rhs));
4359 /* We use COMPARE+SETcc/Bcc, llvm uses SETcc+br cond */
4360 if (ins->opcode == OP_FCOMPARE) {
4361 cmp = LLVMBuildFCmp (builder, fpcond_to_llvm_cond [rel], convert (ctx, lhs, LLVMDoubleType ()), convert (ctx, rhs, LLVMDoubleType ()), "");
4362 } else if (ins->opcode == OP_RCOMPARE) {
4363 cmp = LLVMBuildFCmp (builder, fpcond_to_llvm_cond [rel], convert (ctx, lhs, LLVMFloatType ()), convert (ctx, rhs, LLVMFloatType ()), "");
4364 } else if (ins->opcode == OP_COMPARE_IMM) {
4365 if (LLVMGetTypeKind (LLVMTypeOf (lhs)) == LLVMPointerTypeKind && ins->inst_imm == 0)
4366 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], lhs, LLVMConstNull (LLVMTypeOf (lhs)), "");
4368 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE), "");
4369 } else if (ins->opcode == OP_LCOMPARE_IMM) {
4370 if (SIZEOF_REGISTER == 4 && COMPILE_LLVM (cfg)) {
4371 /* The immediate is encoded in two fields */
4372 guint64 l = ((guint64)(guint32)ins->inst_offset << 32) | ((guint32)ins->inst_imm);
4373 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, LLVMInt64Type ()), LLVMConstInt (LLVMInt64Type (), l, FALSE), "");
4375 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, LLVMInt64Type ()), LLVMConstInt (LLVMInt64Type (), ins->inst_imm, FALSE), "");
4378 else if (ins->opcode == OP_COMPARE) {
4379 if (LLVMGetTypeKind (LLVMTypeOf (lhs)) == LLVMPointerTypeKind && LLVMTypeOf (lhs) == LLVMTypeOf (rhs))
4380 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], lhs, rhs, "");
4382 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, IntPtrType ()), convert (ctx, rhs, IntPtrType ()), "");
4384 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], lhs, rhs, "");
4388 args [1] = LLVMConstInt (LLVMInt1Type (), 1, FALSE);
4389 cmp = LLVMBuildCall (ctx->builder, LLVMGetNamedFunction (ctx->lmodule, "llvm.expect.i1"), args, 2, "");
4392 if (MONO_IS_COND_BRANCH_OP (ins->next)) {
4393 if (ins->next->inst_true_bb == ins->next->inst_false_bb) {
4395 * If the target bb contains PHI instructions, LLVM requires
4396 * two PHI entries for this bblock, while we only generate one.
4397 * So convert this to an unconditional bblock. (bxc #171).
4399 LLVMBuildBr (builder, get_bb (ctx, ins->next->inst_true_bb));
4401 LLVMBuildCondBr (builder, cmp, get_bb (ctx, ins->next->inst_true_bb), get_bb (ctx, ins->next->inst_false_bb));
4403 has_terminator = TRUE;
4404 } else if (MONO_IS_SETCC (ins->next)) {
4405 sprintf (dname_buf, "t%d", ins->next->dreg);
4407 values [ins->next->dreg] = LLVMBuildZExt (builder, cmp, LLVMInt32Type (), dname);
4409 /* Add stores for volatile variables */
4410 emit_volatile_store (ctx, ins->next->dreg);
4411 } else if (MONO_IS_COND_EXC (ins->next)) {
4412 emit_cond_system_exception (ctx, bb, (const char*)ins->next->inst_p1, cmp);
4415 builder = ctx->builder;
4417 set_failure (ctx, "next");
4435 rel = mono_opcode_to_cond (ins->opcode);
4437 cmp = LLVMBuildFCmp (builder, fpcond_to_llvm_cond [rel], convert (ctx, lhs, LLVMDoubleType ()), convert (ctx, rhs, LLVMDoubleType ()), "");
4438 values [ins->dreg] = LLVMBuildZExt (builder, cmp, LLVMInt32Type (), dname);
4449 rel = mono_opcode_to_cond (ins->opcode);
4451 cmp = LLVMBuildFCmp (builder, fpcond_to_llvm_cond [rel], convert (ctx, lhs, LLVMFloatType ()), convert (ctx, rhs, LLVMFloatType ()), "");
4452 values [ins->dreg] = LLVMBuildZExt (builder, cmp, LLVMInt32Type (), dname);
4460 gboolean empty = TRUE;
4462 /* Check that all input bblocks really branch to us */
4463 for (i = 0; i < bb->in_count; ++i) {
4464 if (bb->in_bb [i]->last_ins && bb->in_bb [i]->last_ins->opcode == OP_NOT_REACHED)
4465 ins->inst_phi_args [i + 1] = -1;
4471 /* LLVM doesn't like phi instructions with zero operands */
4472 ctx->is_dead [ins->dreg] = TRUE;
4476 /* Created earlier, insert it now */
4477 LLVMInsertIntoBuilder (builder, values [ins->dreg]);
4479 for (i = 0; i < ins->inst_phi_args [0]; i++) {
4480 int sreg1 = ins->inst_phi_args [i + 1];
4484 * Count the number of times the incoming bblock branches to us,
4485 * since llvm requires a separate entry for each.
4487 if (bb->in_bb [i]->last_ins && bb->in_bb [i]->last_ins->opcode == OP_SWITCH) {
4488 MonoInst *switch_ins = bb->in_bb [i]->last_ins;
4491 for (j = 0; j < GPOINTER_TO_UINT (switch_ins->klass); ++j) {
4492 if (switch_ins->inst_many_bb [j] == bb)
4499 /* Remember for later */
4500 for (j = 0; j < count; ++j) {
4501 PhiNode *node = (PhiNode*)mono_mempool_alloc0 (ctx->mempool, sizeof (PhiNode));
4504 node->in_bb = bb->in_bb [i];
4506 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);
4516 values [ins->dreg] = lhs;
4520 MonoInst *var = get_vreg_to_inst (cfg, ins->dreg);
4523 values [ins->dreg] = lhs;
4525 if (var && var->klass->byval_arg.type == MONO_TYPE_R4) {
4527 * This is added by the spilling pass in case of the JIT,
4528 * but we have to do it ourselves.
4530 values [ins->dreg] = convert (ctx, values [ins->dreg], LLVMFloatType ());
4534 case OP_MOVE_F_TO_I4: {
4535 values [ins->dreg] = LLVMBuildBitCast (builder, LLVMBuildFPTrunc (builder, lhs, LLVMFloatType (), ""), LLVMInt32Type (), "");
4538 case OP_MOVE_I4_TO_F: {
4539 values [ins->dreg] = LLVMBuildFPExt (builder, LLVMBuildBitCast (builder, lhs, LLVMFloatType (), ""), LLVMDoubleType (), "");
4542 case OP_MOVE_F_TO_I8: {
4543 values [ins->dreg] = LLVMBuildBitCast (builder, lhs, LLVMInt64Type (), "");
4546 case OP_MOVE_I8_TO_F: {
4547 values [ins->dreg] = LLVMBuildBitCast (builder, lhs, LLVMDoubleType (), "");
4580 lhs = convert (ctx, lhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
4581 rhs = convert (ctx, rhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
4583 emit_div_check (ctx, builder, bb, ins, lhs, rhs);
4586 builder = ctx->builder;
4588 switch (ins->opcode) {
4591 values [ins->dreg] = LLVMBuildAdd (builder, lhs, rhs, dname);
4595 values [ins->dreg] = LLVMBuildSub (builder, lhs, rhs, dname);
4599 values [ins->dreg] = LLVMBuildMul (builder, lhs, rhs, dname);
4603 values [ins->dreg] = LLVMBuildSRem (builder, lhs, rhs, dname);
4607 values [ins->dreg] = LLVMBuildURem (builder, lhs, rhs, dname);
4611 values [ins->dreg] = LLVMBuildSDiv (builder, lhs, rhs, dname);
4615 values [ins->dreg] = LLVMBuildUDiv (builder, lhs, rhs, dname);
4619 values [ins->dreg] = LLVMBuildFDiv (builder, lhs, rhs, dname);
4623 values [ins->dreg] = LLVMBuildAnd (builder, lhs, rhs, dname);
4627 values [ins->dreg] = LLVMBuildOr (builder, lhs, rhs, dname);
4631 values [ins->dreg] = LLVMBuildXor (builder, lhs, rhs, dname);
4635 values [ins->dreg] = LLVMBuildShl (builder, lhs, rhs, dname);
4639 values [ins->dreg] = LLVMBuildAShr (builder, lhs, rhs, dname);
4643 values [ins->dreg] = LLVMBuildLShr (builder, lhs, rhs, dname);
4647 values [ins->dreg] = LLVMBuildFAdd (builder, lhs, rhs, dname);
4650 values [ins->dreg] = LLVMBuildFSub (builder, lhs, rhs, dname);
4653 values [ins->dreg] = LLVMBuildFMul (builder, lhs, rhs, dname);
4657 g_assert_not_reached ();
4664 lhs = convert (ctx, lhs, LLVMFloatType ());
4665 rhs = convert (ctx, rhs, LLVMFloatType ());
4666 switch (ins->opcode) {
4668 values [ins->dreg] = LLVMBuildFAdd (builder, lhs, rhs, dname);
4671 values [ins->dreg] = LLVMBuildFSub (builder, lhs, rhs, dname);
4674 values [ins->dreg] = LLVMBuildFMul (builder, lhs, rhs, dname);
4677 values [ins->dreg] = LLVMBuildFDiv (builder, lhs, rhs, dname);
4680 g_assert_not_reached ();
4689 case OP_IREM_UN_IMM:
4691 case OP_IDIV_UN_IMM:
4697 case OP_ISHR_UN_IMM:
4707 case OP_LSHR_UN_IMM:
4713 case OP_SHR_UN_IMM: {
4716 if (spec [MONO_INST_SRC1] == 'l') {
4717 imm = LLVMConstInt (LLVMInt64Type (), GET_LONG_IMM (ins), FALSE);
4719 imm = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
4722 emit_div_check (ctx, builder, bb, ins, lhs, imm);
4725 builder = ctx->builder;
4727 #if SIZEOF_VOID_P == 4
4728 if (ins->opcode == OP_LSHL_IMM || ins->opcode == OP_LSHR_IMM || ins->opcode == OP_LSHR_UN_IMM)
4729 imm = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
4732 if (LLVMGetTypeKind (LLVMTypeOf (lhs)) == LLVMPointerTypeKind)
4733 lhs = convert (ctx, lhs, IntPtrType ());
4734 imm = convert (ctx, imm, LLVMTypeOf (lhs));
4735 switch (ins->opcode) {
4739 values [ins->dreg] = LLVMBuildAdd (builder, lhs, imm, dname);
4743 values [ins->dreg] = LLVMBuildSub (builder, lhs, imm, dname);
4748 values [ins->dreg] = LLVMBuildMul (builder, lhs, imm, dname);
4752 values [ins->dreg] = LLVMBuildSDiv (builder, lhs, imm, dname);
4754 case OP_IDIV_UN_IMM:
4755 case OP_LDIV_UN_IMM:
4756 values [ins->dreg] = LLVMBuildUDiv (builder, lhs, imm, dname);
4760 values [ins->dreg] = LLVMBuildSRem (builder, lhs, imm, dname);
4762 case OP_IREM_UN_IMM:
4763 values [ins->dreg] = LLVMBuildURem (builder, lhs, imm, dname);
4768 values [ins->dreg] = LLVMBuildAnd (builder, lhs, imm, dname);
4772 values [ins->dreg] = LLVMBuildOr (builder, lhs, imm, dname);
4776 values [ins->dreg] = LLVMBuildXor (builder, lhs, imm, dname);
4781 values [ins->dreg] = LLVMBuildShl (builder, lhs, imm, dname);
4786 values [ins->dreg] = LLVMBuildAShr (builder, lhs, imm, dname);
4788 case OP_ISHR_UN_IMM:
4789 /* This is used to implement conv.u4, so the lhs could be an i8 */
4790 lhs = convert (ctx, lhs, LLVMInt32Type ());
4791 imm = convert (ctx, imm, LLVMInt32Type ());
4792 values [ins->dreg] = LLVMBuildLShr (builder, lhs, imm, dname);
4794 case OP_LSHR_UN_IMM:
4796 values [ins->dreg] = LLVMBuildLShr (builder, lhs, imm, dname);
4799 g_assert_not_reached ();
4804 values [ins->dreg] = LLVMBuildSub (builder, LLVMConstInt (LLVMInt32Type (), 0, FALSE), convert (ctx, lhs, LLVMInt32Type ()), dname);
4807 values [ins->dreg] = LLVMBuildSub (builder, LLVMConstInt (LLVMInt64Type (), 0, FALSE), lhs, dname);
4810 lhs = convert (ctx, lhs, LLVMDoubleType ());
4811 values [ins->dreg] = LLVMBuildFSub (builder, LLVMConstReal (LLVMDoubleType (), 0.0), lhs, dname);
4814 lhs = convert (ctx, lhs, LLVMFloatType ());
4815 values [ins->dreg] = LLVMBuildFSub (builder, LLVMConstReal (LLVMFloatType (), 0.0), lhs, dname);
4818 guint32 v = 0xffffffff;
4819 values [ins->dreg] = LLVMBuildXor (builder, LLVMConstInt (LLVMInt32Type (), v, FALSE), convert (ctx, lhs, LLVMInt32Type ()), dname);
4823 guint64 v = 0xffffffffffffffffLL;
4824 values [ins->dreg] = LLVMBuildXor (builder, LLVMConstInt (LLVMInt64Type (), v, FALSE), lhs, dname);
4827 #if defined(TARGET_X86) || defined(TARGET_AMD64)
4829 LLVMValueRef v1, v2;
4831 v1 = LLVMBuildMul (builder, convert (ctx, rhs, IntPtrType ()), LLVMConstInt (IntPtrType (), (1 << ins->backend.shift_amount), FALSE), "");
4832 v2 = LLVMBuildAdd (builder, convert (ctx, lhs, IntPtrType ()), v1, "");
4833 values [ins->dreg] = LLVMBuildAdd (builder, v2, LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE), dname);
4838 case OP_ICONV_TO_I1:
4839 case OP_ICONV_TO_I2:
4840 case OP_ICONV_TO_I4:
4841 case OP_ICONV_TO_U1:
4842 case OP_ICONV_TO_U2:
4843 case OP_ICONV_TO_U4:
4844 case OP_LCONV_TO_I1:
4845 case OP_LCONV_TO_I2:
4846 case OP_LCONV_TO_U1:
4847 case OP_LCONV_TO_U2:
4848 case OP_LCONV_TO_U4: {
4851 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);
4853 /* Have to do two casts since our vregs have type int */
4854 v = LLVMBuildTrunc (builder, lhs, op_to_llvm_type (ins->opcode), "");
4856 values [ins->dreg] = LLVMBuildSExt (builder, v, LLVMInt32Type (), dname);
4858 values [ins->dreg] = LLVMBuildZExt (builder, v, LLVMInt32Type (), dname);
4861 case OP_ICONV_TO_I8:
4862 values [ins->dreg] = LLVMBuildSExt (builder, lhs, LLVMInt64Type (), dname);
4864 case OP_ICONV_TO_U8:
4865 values [ins->dreg] = LLVMBuildZExt (builder, lhs, LLVMInt64Type (), dname);
4867 case OP_FCONV_TO_I4:
4868 case OP_RCONV_TO_I4:
4869 values [ins->dreg] = LLVMBuildFPToSI (builder, lhs, LLVMInt32Type (), dname);
4871 case OP_FCONV_TO_I1:
4872 case OP_RCONV_TO_I1:
4873 values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildFPToSI (builder, lhs, LLVMInt8Type (), dname), LLVMInt32Type (), "");
4875 case OP_FCONV_TO_U1:
4876 case OP_RCONV_TO_U1:
4877 values [ins->dreg] = LLVMBuildZExt (builder, LLVMBuildTrunc (builder, LLVMBuildFPToUI (builder, lhs, IntPtrType (), dname), LLVMInt8Type (), ""), LLVMInt32Type (), "");
4879 case OP_FCONV_TO_I2:
4880 case OP_RCONV_TO_I2:
4881 values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildFPToSI (builder, lhs, LLVMInt16Type (), dname), LLVMInt32Type (), "");
4883 case OP_FCONV_TO_U2:
4884 case OP_RCONV_TO_U2:
4885 values [ins->dreg] = LLVMBuildZExt (builder, LLVMBuildFPToUI (builder, lhs, LLVMInt16Type (), dname), LLVMInt32Type (), "");
4887 case OP_RCONV_TO_U4:
4888 values [ins->dreg] = LLVMBuildFPToUI (builder, lhs, LLVMInt32Type (), dname);
4890 case OP_FCONV_TO_I8:
4891 case OP_RCONV_TO_I8:
4892 values [ins->dreg] = LLVMBuildFPToSI (builder, lhs, LLVMInt64Type (), dname);
4895 values [ins->dreg] = LLVMBuildFPToSI (builder, lhs, IntPtrType (), dname);
4897 case OP_ICONV_TO_R8:
4898 case OP_LCONV_TO_R8:
4899 values [ins->dreg] = LLVMBuildSIToFP (builder, lhs, LLVMDoubleType (), dname);
4901 case OP_ICONV_TO_R_UN:
4902 case OP_LCONV_TO_R_UN:
4903 values [ins->dreg] = LLVMBuildUIToFP (builder, lhs, LLVMDoubleType (), dname);
4905 #if SIZEOF_VOID_P == 4
4908 case OP_LCONV_TO_I4:
4909 values [ins->dreg] = LLVMBuildTrunc (builder, lhs, LLVMInt32Type (), dname);
4911 case OP_ICONV_TO_R4:
4912 case OP_LCONV_TO_R4:
4913 v = LLVMBuildSIToFP (builder, lhs, LLVMFloatType (), "");
4915 values [ins->dreg] = v;
4917 values [ins->dreg] = LLVMBuildFPExt (builder, v, LLVMDoubleType (), dname);
4919 case OP_FCONV_TO_R4:
4920 v = LLVMBuildFPTrunc (builder, lhs, LLVMFloatType (), "");
4922 values [ins->dreg] = v;
4924 values [ins->dreg] = LLVMBuildFPExt (builder, v, LLVMDoubleType (), dname);
4926 case OP_RCONV_TO_R8:
4927 values [ins->dreg] = LLVMBuildFPExt (builder, lhs, LLVMDoubleType (), dname);
4929 case OP_RCONV_TO_R4:
4930 values [ins->dreg] = lhs;
4933 values [ins->dreg] = LLVMBuildSExt (builder, convert (ctx, lhs, LLVMInt32Type ()), LLVMInt64Type (), dname);
4936 values [ins->dreg] = LLVMBuildZExt (builder, convert (ctx, lhs, LLVMInt32Type ()), LLVMInt64Type (), dname);
4939 values [ins->dreg] = LLVMBuildTrunc (builder, lhs, LLVMInt32Type (), dname);
4941 case OP_LOCALLOC_IMM: {
4944 guint32 size = ins->inst_imm;
4945 size = (size + (MONO_ARCH_FRAME_ALIGNMENT - 1)) & ~ (MONO_ARCH_FRAME_ALIGNMENT - 1);
4947 v = mono_llvm_build_alloca (builder, LLVMInt8Type (), LLVMConstInt (LLVMInt32Type (), size, FALSE), MONO_ARCH_FRAME_ALIGNMENT, "");
4949 if (ins->flags & MONO_INST_INIT) {
4950 LLVMValueRef args [5];
4953 args [1] = LLVMConstInt (LLVMInt8Type (), 0, FALSE);
4954 args [2] = LLVMConstInt (LLVMInt32Type (), size, FALSE);
4955 args [3] = LLVMConstInt (LLVMInt32Type (), MONO_ARCH_FRAME_ALIGNMENT, FALSE);
4956 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
4957 LLVMBuildCall (builder, LLVMGetNamedFunction (lmodule, memset_func_name), args, memset_param_count, "");
4960 values [ins->dreg] = v;
4964 LLVMValueRef v, size;
4966 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), "");
4968 v = mono_llvm_build_alloca (builder, LLVMInt8Type (), size, MONO_ARCH_FRAME_ALIGNMENT, "");
4970 if (ins->flags & MONO_INST_INIT) {
4971 LLVMValueRef args [5];
4974 args [1] = LLVMConstInt (LLVMInt8Type (), 0, FALSE);
4976 args [3] = LLVMConstInt (LLVMInt32Type (), MONO_ARCH_FRAME_ALIGNMENT, FALSE);
4977 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
4978 LLVMBuildCall (builder, LLVMGetNamedFunction (lmodule, memset_func_name), args, memset_param_count, "");
4980 values [ins->dreg] = v;
4984 case OP_LOADI1_MEMBASE:
4985 case OP_LOADU1_MEMBASE:
4986 case OP_LOADI2_MEMBASE:
4987 case OP_LOADU2_MEMBASE:
4988 case OP_LOADI4_MEMBASE:
4989 case OP_LOADU4_MEMBASE:
4990 case OP_LOADI8_MEMBASE:
4991 case OP_LOADR4_MEMBASE:
4992 case OP_LOADR8_MEMBASE:
4993 case OP_LOAD_MEMBASE:
5001 LLVMValueRef base, index, addr;
5003 gboolean sext = FALSE, zext = FALSE;
5004 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
5006 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
5011 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)) {
5012 addr = LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE);
5017 if (ins->inst_offset == 0) {
5019 } else if (ins->inst_offset % size != 0) {
5020 /* Unaligned load */
5021 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset, FALSE);
5022 addr = LLVMBuildGEP (builder, convert (ctx, base, LLVMPointerType (LLVMInt8Type (), 0)), &index, 1, "");
5024 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
5025 addr = LLVMBuildGEP (builder, convert (ctx, base, LLVMPointerType (t, 0)), &index, 1, "");
5029 addr = convert (ctx, addr, LLVMPointerType (t, 0));
5031 values [ins->dreg] = emit_load (ctx, bb, &builder, size, addr, dname, is_volatile);
5033 if (!is_volatile && (ins->flags & MONO_INST_INVARIANT_LOAD)) {
5035 * These will signal LLVM that these loads do not alias any stores, and
5036 * they can't fail, allowing them to be hoisted out of loops.
5038 set_invariant_load_flag (values [ins->dreg]);
5039 #if LLVM_API_VERSION < 100
5040 set_metadata_flag (values [ins->dreg], "mono.nofail.load");
5045 values [ins->dreg] = LLVMBuildSExt (builder, values [ins->dreg], LLVMInt32Type (), dname);
5047 values [ins->dreg] = LLVMBuildZExt (builder, values [ins->dreg], LLVMInt32Type (), dname);
5048 else if (!cfg->r4fp && ins->opcode == OP_LOADR4_MEMBASE)
5049 values [ins->dreg] = LLVMBuildFPExt (builder, values [ins->dreg], LLVMDoubleType (), dname);
5053 case OP_STOREI1_MEMBASE_REG:
5054 case OP_STOREI2_MEMBASE_REG:
5055 case OP_STOREI4_MEMBASE_REG:
5056 case OP_STOREI8_MEMBASE_REG:
5057 case OP_STORER4_MEMBASE_REG:
5058 case OP_STORER8_MEMBASE_REG:
5059 case OP_STORE_MEMBASE_REG: {
5061 LLVMValueRef index, addr;
5063 gboolean sext = FALSE, zext = FALSE;
5064 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
5066 if (!values [ins->inst_destbasereg]) {
5067 set_failure (ctx, "inst_destbasereg");
5071 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
5073 if (ins->inst_offset % size != 0) {
5074 /* Unaligned store */
5075 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset, FALSE);
5076 addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (LLVMInt8Type (), 0)), &index, 1, "");
5078 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
5079 addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (t, 0)), &index, 1, "");
5081 emit_store (ctx, bb, &builder, size, convert (ctx, values [ins->sreg1], t), convert (ctx, addr, LLVMPointerType (t, 0)), is_volatile);
5085 case OP_STOREI1_MEMBASE_IMM:
5086 case OP_STOREI2_MEMBASE_IMM:
5087 case OP_STOREI4_MEMBASE_IMM:
5088 case OP_STOREI8_MEMBASE_IMM:
5089 case OP_STORE_MEMBASE_IMM: {
5091 LLVMValueRef index, addr;
5093 gboolean sext = FALSE, zext = FALSE;
5094 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
5096 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
5098 if (ins->inst_offset % size != 0) {
5099 /* Unaligned store */
5100 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset, FALSE);
5101 addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (LLVMInt8Type (), 0)), &index, 1, "");
5103 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
5104 addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (t, 0)), &index, 1, "");
5106 emit_store (ctx, bb, &builder, size, convert (ctx, LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE), t), convert (ctx, addr, LLVMPointerType (t, 0)), is_volatile);
5111 emit_load (ctx, bb, &builder, sizeof (gpointer), convert (ctx, lhs, LLVMPointerType (IntPtrType (), 0)), "", TRUE);
5113 case OP_OUTARG_VTRETADDR:
5121 case OP_VOIDCALL_MEMBASE:
5122 case OP_CALL_MEMBASE:
5123 case OP_LCALL_MEMBASE:
5124 case OP_FCALL_MEMBASE:
5125 case OP_RCALL_MEMBASE:
5126 case OP_VCALL_MEMBASE:
5127 case OP_VOIDCALL_REG:
5132 case OP_VCALL_REG: {
5133 process_call (ctx, bb, &builder, ins);
5138 LLVMValueRef indexes [2];
5139 MonoJumpInfo *tmp_ji, *ji;
5140 LLVMValueRef got_entry_addr;
5144 * FIXME: Can't allocate from the cfg mempool since that is freed if
5145 * the LLVM compile fails.
5147 tmp_ji = g_new0 (MonoJumpInfo, 1);
5148 tmp_ji->type = (MonoJumpInfoType)ins->inst_c1;
5149 tmp_ji->data.target = ins->inst_p0;
5151 ji = mono_aot_patch_info_dup (tmp_ji);
5154 ji->next = cfg->patch_info;
5155 cfg->patch_info = ji;
5157 //mono_add_patch_info (cfg, 0, (MonoJumpInfoType)ins->inst_i1, ins->inst_p0);
5158 got_offset = mono_aot_get_got_offset (cfg->patch_info);
5159 ctx->module->max_got_offset = MAX (ctx->module->max_got_offset, got_offset);
5160 if (!mono_aot_is_shared_got_offset (got_offset)) {
5161 //mono_print_ji (ji);
5163 ctx->has_got_access = TRUE;
5166 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
5167 indexes [1] = LLVMConstInt (LLVMInt32Type (), (gssize)got_offset, FALSE);
5168 got_entry_addr = LLVMBuildGEP (builder, ctx->module->got_var, indexes, 2, "");
5170 name = get_aotconst_name (ji->type, ji->data.target, got_offset);
5171 values [ins->dreg] = LLVMBuildLoad (builder, got_entry_addr, name);
5173 /* Can't use this in llvmonly mode since the got slots are initialized by the methods themselves */
5174 if (!cfg->llvm_only)
5175 set_invariant_load_flag (values [ins->dreg]);
5178 case OP_NOT_REACHED:
5179 LLVMBuildUnreachable (builder);
5180 has_terminator = TRUE;
5181 g_assert (bb->block_num < cfg->max_block_num);
5182 ctx->unreachable [bb->block_num] = TRUE;
5183 /* Might have instructions after this */
5185 MonoInst *next = ins->next;
5187 * FIXME: If later code uses the regs defined by these instructions,
5188 * compilation will fail.
5190 MONO_DELETE_INS (bb, next);
5194 MonoInst *var = ins->inst_i0;
5196 if (var->opcode == OP_VTARG_ADDR) {
5197 /* The variable contains the vtype address */
5198 values [ins->dreg] = values [var->dreg];
5199 } else if (var->opcode == OP_GSHAREDVT_LOCAL) {
5200 values [ins->dreg] = emit_gsharedvt_ldaddr (ctx, var->dreg);
5202 values [ins->dreg] = addresses [var->dreg];
5207 LLVMValueRef args [1];
5209 args [0] = convert (ctx, lhs, LLVMDoubleType ());
5210 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (lmodule, "llvm.sin.f64"), args, 1, dname);
5214 LLVMValueRef args [1];
5216 args [0] = convert (ctx, lhs, LLVMDoubleType ());
5217 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (lmodule, "llvm.cos.f64"), args, 1, dname);
5221 LLVMValueRef args [1];
5223 args [0] = convert (ctx, lhs, LLVMDoubleType ());
5224 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (lmodule, "llvm.sqrt.f64"), args, 1, dname);
5228 LLVMValueRef args [1];
5230 args [0] = convert (ctx, lhs, LLVMDoubleType ());
5231 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (lmodule, "fabs"), args, 1, dname);
5245 lhs = convert (ctx, lhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
5246 rhs = convert (ctx, rhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
5248 switch (ins->opcode) {
5251 v = LLVMBuildICmp (builder, LLVMIntSLE, lhs, rhs, "");
5255 v = LLVMBuildICmp (builder, LLVMIntSGE, lhs, rhs, "");
5259 v = LLVMBuildICmp (builder, LLVMIntULE, lhs, rhs, "");
5263 v = LLVMBuildICmp (builder, LLVMIntUGE, lhs, rhs, "");
5266 g_assert_not_reached ();
5269 values [ins->dreg] = LLVMBuildSelect (builder, v, lhs, rhs, dname);
5272 case OP_ATOMIC_EXCHANGE_I4:
5273 case OP_ATOMIC_EXCHANGE_I8: {
5274 LLVMValueRef args [2];
5277 if (ins->opcode == OP_ATOMIC_EXCHANGE_I4)
5278 t = LLVMInt32Type ();
5280 t = LLVMInt64Type ();
5282 g_assert (ins->inst_offset == 0);
5284 args [0] = convert (ctx, lhs, LLVMPointerType (t, 0));
5285 args [1] = convert (ctx, rhs, t);
5287 values [ins->dreg] = mono_llvm_build_atomic_rmw (builder, LLVM_ATOMICRMW_OP_XCHG, args [0], args [1]);
5290 case OP_ATOMIC_ADD_I4:
5291 case OP_ATOMIC_ADD_I8: {
5292 LLVMValueRef args [2];
5295 if (ins->opcode == OP_ATOMIC_ADD_I4)
5296 t = LLVMInt32Type ();
5298 t = LLVMInt64Type ();
5300 g_assert (ins->inst_offset == 0);
5302 args [0] = convert (ctx, lhs, LLVMPointerType (t, 0));
5303 args [1] = convert (ctx, rhs, t);
5304 values [ins->dreg] = LLVMBuildAdd (builder, mono_llvm_build_atomic_rmw (builder, LLVM_ATOMICRMW_OP_ADD, args [0], args [1]), args [1], dname);
5307 case OP_ATOMIC_CAS_I4:
5308 case OP_ATOMIC_CAS_I8: {
5309 LLVMValueRef args [3], val;
5312 if (ins->opcode == OP_ATOMIC_CAS_I4)
5313 t = LLVMInt32Type ();
5315 t = LLVMInt64Type ();
5317 args [0] = convert (ctx, lhs, LLVMPointerType (t, 0));
5319 args [1] = convert (ctx, values [ins->sreg3], t);
5321 args [2] = convert (ctx, values [ins->sreg2], t);
5322 val = mono_llvm_build_cmpxchg (builder, args [0], args [1], args [2]);
5323 /* cmpxchg returns a pair */
5324 values [ins->dreg] = LLVMBuildExtractValue (builder, val, 0, "");
5327 case OP_MEMORY_BARRIER: {
5328 mono_llvm_build_fence (builder, (BarrierKind) ins->backend.memory_barrier_kind);
5331 case OP_ATOMIC_LOAD_I1:
5332 case OP_ATOMIC_LOAD_I2:
5333 case OP_ATOMIC_LOAD_I4:
5334 case OP_ATOMIC_LOAD_I8:
5335 case OP_ATOMIC_LOAD_U1:
5336 case OP_ATOMIC_LOAD_U2:
5337 case OP_ATOMIC_LOAD_U4:
5338 case OP_ATOMIC_LOAD_U8:
5339 case OP_ATOMIC_LOAD_R4:
5340 case OP_ATOMIC_LOAD_R8: {
5341 set_failure (ctx, "atomic mono.load intrinsic");
5345 gboolean sext, zext;
5347 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
5348 BarrierKind barrier = (BarrierKind) ins->backend.memory_barrier_kind;
5349 LLVMValueRef index, addr;
5351 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
5356 if (ins->inst_offset != 0) {
5357 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
5358 addr = LLVMBuildGEP (builder, convert (ctx, lhs, LLVMPointerType (t, 0)), &index, 1, "");
5363 addr = convert (ctx, addr, LLVMPointerType (t, 0));
5365 values [ins->dreg] = emit_load_general (ctx, bb, &builder, size, addr, dname, is_volatile, barrier);
5368 values [ins->dreg] = LLVMBuildSExt (builder, values [ins->dreg], LLVMInt32Type (), dname);
5370 values [ins->dreg] = LLVMBuildZExt (builder, values [ins->dreg], LLVMInt32Type (), dname);
5374 case OP_ATOMIC_STORE_I1:
5375 case OP_ATOMIC_STORE_I2:
5376 case OP_ATOMIC_STORE_I4:
5377 case OP_ATOMIC_STORE_I8:
5378 case OP_ATOMIC_STORE_U1:
5379 case OP_ATOMIC_STORE_U2:
5380 case OP_ATOMIC_STORE_U4:
5381 case OP_ATOMIC_STORE_U8:
5382 case OP_ATOMIC_STORE_R4:
5383 case OP_ATOMIC_STORE_R8: {
5384 set_failure (ctx, "atomic mono.store intrinsic");
5388 gboolean sext, zext;
5390 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
5391 BarrierKind barrier = (BarrierKind) ins->backend.memory_barrier_kind;
5392 LLVMValueRef index, addr, value;
5394 if (!values [ins->inst_destbasereg]) {
5395 set_failure (ctx, "inst_destbasereg");
5399 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
5401 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
5402 addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (t, 0)), &index, 1, "");
5403 value = convert (ctx, values [ins->sreg1], t);
5405 emit_store_general (ctx, bb, &builder, size, value, addr, is_volatile, barrier);
5409 case OP_RELAXED_NOP: {
5410 #if defined(TARGET_AMD64) || defined(TARGET_X86)
5411 emit_call (ctx, bb, &builder, LLVMGetNamedFunction (ctx->lmodule, "llvm.x86.sse2.pause"), NULL, 0);
5418 #if (defined(TARGET_AMD64) || defined(TARGET_X86)) && defined(__linux__)
5420 // 257 == FS segment register
5421 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 257);
5423 // 256 == GS segment register
5424 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 256);
5427 values [ins->dreg] = LLVMBuildLoad (builder, LLVMBuildIntToPtr (builder, LLVMConstInt (IntPtrType (), ins->inst_offset, TRUE), ptrtype, ""), "");
5428 #elif defined(TARGET_AMD64) && defined(TARGET_OSX)
5429 /* See mono_amd64_emit_tls_get () */
5430 int offset = mono_amd64_get_tls_gs_offset () + (ins->inst_offset * 8);
5432 // 256 == GS segment register
5433 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 256);
5434 values [ins->dreg] = LLVMBuildLoad (builder, LLVMBuildIntToPtr (builder, LLVMConstInt (IntPtrType (), offset, TRUE), ptrtype, ""), "");
5436 set_failure (ctx, "opcode tls-get");
5442 case OP_TLS_GET_REG: {
5443 #if defined(TARGET_AMD64) && defined(TARGET_OSX)
5444 /* See emit_tls_get_reg () */
5445 // 256 == GS segment register
5446 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 256);
5447 values [ins->dreg] = LLVMBuildLoad (builder, LLVMBuildIntToPtr (builder, convert (ctx, lhs, LLVMInt32Type ()), ptrtype, ""), "");
5449 set_failure (ctx, "opcode tls-get");
5455 case OP_TLS_SET_REG: {
5456 #if defined(TARGET_AMD64) && defined(TARGET_OSX)
5457 /* See emit_tls_get_reg () */
5458 // 256 == GS segment register
5459 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 256);
5460 LLVMBuildStore (builder, convert (ctx, lhs, IntPtrType ()), LLVMBuildIntToPtr (builder, convert (ctx, rhs, LLVMInt32Type ()), ptrtype, ""));
5462 set_failure (ctx, "opcode tls-set-reg");
5472 case OP_IADD_OVF_UN:
5474 case OP_ISUB_OVF_UN:
5476 case OP_IMUL_OVF_UN:
5477 #if SIZEOF_VOID_P == 8
5479 case OP_LADD_OVF_UN:
5481 case OP_LSUB_OVF_UN:
5483 case OP_LMUL_OVF_UN:
5486 LLVMValueRef args [2], val, ovf, func;
5488 args [0] = convert (ctx, lhs, op_to_llvm_type (ins->opcode));
5489 args [1] = convert (ctx, rhs, op_to_llvm_type (ins->opcode));
5490 func = LLVMGetNamedFunction (lmodule, ovf_op_to_intrins (ins->opcode));
5492 val = LLVMBuildCall (builder, func, args, 2, "");
5493 values [ins->dreg] = LLVMBuildExtractValue (builder, val, 0, dname);
5494 ovf = LLVMBuildExtractValue (builder, val, 1, "");
5495 emit_cond_system_exception (ctx, bb, "OverflowException", ovf);
5498 builder = ctx->builder;
5504 * We currently model them using arrays. Promotion to local vregs is
5505 * disabled for them in mono_handle_global_vregs () in the LLVM case,
5506 * so we always have an entry in cfg->varinfo for them.
5507 * FIXME: Is this needed ?
5510 MonoClass *klass = ins->klass;
5511 LLVMValueRef args [5];
5515 set_failure (ctx, "!klass");
5519 if (!addresses [ins->dreg])
5520 addresses [ins->dreg] = build_alloca (ctx, &klass->byval_arg);
5521 args [0] = LLVMBuildBitCast (builder, addresses [ins->dreg], LLVMPointerType (LLVMInt8Type (), 0), "");
5522 args [1] = LLVMConstInt (LLVMInt8Type (), 0, FALSE);
5523 args [2] = LLVMConstInt (LLVMInt32Type (), mono_class_value_size (klass, NULL), FALSE);
5525 args [3] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
5526 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
5527 LLVMBuildCall (builder, LLVMGetNamedFunction (lmodule, memset_func_name), args, memset_param_count, "");
5530 case OP_DUMMY_VZERO:
5533 case OP_STOREV_MEMBASE:
5534 case OP_LOADV_MEMBASE:
5536 MonoClass *klass = ins->klass;
5537 LLVMValueRef src = NULL, dst, args [5];
5538 gboolean done = FALSE;
5542 set_failure (ctx, "!klass");
5546 if (mini_is_gsharedvt_klass (klass)) {
5548 set_failure (ctx, "gsharedvt");
5552 switch (ins->opcode) {
5553 case OP_STOREV_MEMBASE:
5554 if (cfg->gen_write_barriers && klass->has_references && ins->inst_destbasereg != cfg->frame_reg &&
5555 LLVMGetInstructionOpcode (values [ins->inst_destbasereg]) != LLVMAlloca) {
5556 /* Decomposed earlier */
5557 g_assert_not_reached ();
5560 if (!addresses [ins->sreg1]) {
5562 g_assert (values [ins->sreg1]);
5563 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));
5564 LLVMBuildStore (builder, values [ins->sreg1], dst);
5567 src = LLVMBuildBitCast (builder, addresses [ins->sreg1], LLVMPointerType (LLVMInt8Type (), 0), "");
5568 dst = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_destbasereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (LLVMInt8Type (), 0));
5571 case OP_LOADV_MEMBASE:
5572 if (!addresses [ins->dreg])
5573 addresses [ins->dreg] = build_alloca (ctx, &klass->byval_arg);
5574 src = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_basereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (LLVMInt8Type (), 0));
5575 dst = LLVMBuildBitCast (builder, addresses [ins->dreg], LLVMPointerType (LLVMInt8Type (), 0), "");
5578 if (!addresses [ins->sreg1])
5579 addresses [ins->sreg1] = build_alloca (ctx, &klass->byval_arg);
5580 if (!addresses [ins->dreg])
5581 addresses [ins->dreg] = build_alloca (ctx, &klass->byval_arg);
5582 src = LLVMBuildBitCast (builder, addresses [ins->sreg1], LLVMPointerType (LLVMInt8Type (), 0), "");
5583 dst = LLVMBuildBitCast (builder, addresses [ins->dreg], LLVMPointerType (LLVMInt8Type (), 0), "");
5586 g_assert_not_reached ();
5596 args [2] = LLVMConstInt (LLVMInt32Type (), mono_class_value_size (klass, NULL), FALSE);
5597 args [3] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
5599 args [3] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
5600 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
5601 LLVMBuildCall (builder, LLVMGetNamedFunction (lmodule, memcpy_func_name), args, memcpy_param_count, "");
5604 case OP_LLVM_OUTARG_VT: {
5605 LLVMArgInfo *ainfo = (LLVMArgInfo*)ins->inst_p0;
5606 MonoType *t = mini_get_underlying_type (ins->inst_vtype);
5608 if (ainfo->storage == LLVMArgScalarByRef) {
5609 LLVMTypeRef argtype;
5610 LLVMValueRef loc, v;
5612 argtype = type_to_llvm_arg_type (ctx, t);
5613 loc = build_alloca_llvm_type (ctx, argtype, 0);
5614 v = convert (ctx, values [ins->sreg1], argtype);
5615 LLVMBuildStore (ctx->builder, v, loc);
5616 addresses [ins->dreg] = loc;
5617 } else if (ainfo->storage == LLVMArgGsharedvtVariable) {
5618 MonoInst *var = get_vreg_to_inst (cfg, ins->sreg1);
5620 if (var && var->opcode == OP_GSHAREDVT_LOCAL) {
5621 addresses [ins->dreg] = convert (ctx, emit_gsharedvt_ldaddr (ctx, var->dreg), LLVMPointerType (IntPtrType (), 0));
5623 g_assert (addresses [ins->sreg1]);
5624 addresses [ins->dreg] = addresses [ins->sreg1];
5626 } else if (ainfo->storage == LLVMArgGsharedvtFixed) {
5627 if (!addresses [ins->sreg1]) {
5628 addresses [ins->sreg1] = build_alloca (ctx, t);
5629 g_assert (values [ins->sreg1]);
5631 LLVMBuildStore (builder, convert (ctx, values [ins->sreg1], LLVMGetElementType (LLVMTypeOf (addresses [ins->sreg1]))), addresses [ins->sreg1]);
5632 addresses [ins->dreg] = addresses [ins->sreg1];
5634 if (!addresses [ins->sreg1]) {
5635 addresses [ins->sreg1] = build_alloca (ctx, t);
5636 g_assert (values [ins->sreg1]);
5637 LLVMBuildStore (builder, convert (ctx, values [ins->sreg1], type_to_llvm_type (ctx, t)), addresses [ins->sreg1]);
5639 addresses [ins->dreg] = addresses [ins->sreg1];
5647 #if defined(TARGET_X86) || defined(TARGET_AMD64)
5649 values [ins->dreg] = LLVMConstNull (type_to_llvm_type (ctx, &ins->klass->byval_arg));
5652 case OP_LOADX_MEMBASE: {
5653 LLVMTypeRef t = type_to_llvm_type (ctx, &ins->klass->byval_arg);
5656 src = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_basereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (t, 0));
5657 values [ins->dreg] = mono_llvm_build_aligned_load (builder, src, "", FALSE, 1);
5660 case OP_STOREX_MEMBASE: {
5661 LLVMTypeRef t = LLVMTypeOf (values [ins->sreg1]);
5664 dest = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_destbasereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (t, 0));
5665 mono_llvm_build_aligned_store (builder, values [ins->sreg1], dest, FALSE, 1);
5672 values [ins->dreg] = LLVMBuildAdd (builder, lhs, rhs, "");
5676 values [ins->dreg] = LLVMBuildFAdd (builder, lhs, rhs, "");
5682 values [ins->dreg] = LLVMBuildSub (builder, lhs, rhs, "");
5686 values [ins->dreg] = LLVMBuildFSub (builder, lhs, rhs, "");
5690 values [ins->dreg] = LLVMBuildFMul (builder, lhs, rhs, "");
5694 values [ins->dreg] = LLVMBuildFDiv (builder, lhs, rhs, "");
5697 values [ins->dreg] = LLVMBuildAnd (builder, lhs, rhs, "");
5700 values [ins->dreg] = LLVMBuildOr (builder, lhs, rhs, "");
5703 values [ins->dreg] = LLVMBuildXor (builder, lhs, rhs, "");
5707 values [ins->dreg] = LLVMBuildMul (builder, lhs, rhs, "");
5718 LLVMValueRef v = NULL;
5720 switch (ins->opcode) {
5725 t = LLVMVectorType (LLVMInt32Type (), 4);
5726 rt = LLVMVectorType (LLVMFloatType (), 4);
5732 t = LLVMVectorType (LLVMInt64Type (), 2);
5733 rt = LLVMVectorType (LLVMDoubleType (), 2);
5736 t = LLVMInt32Type ();
5737 rt = LLVMInt32Type ();
5738 g_assert_not_reached ();
5741 lhs = LLVMBuildBitCast (builder, lhs, t, "");
5742 rhs = LLVMBuildBitCast (builder, rhs, t, "");
5743 switch (ins->opcode) {
5746 v = LLVMBuildAnd (builder, lhs, rhs, "");
5750 v = LLVMBuildOr (builder, lhs, rhs, "");
5754 v = LLVMBuildXor (builder, lhs, rhs, "");
5758 v = LLVMBuildAnd (builder, rhs, LLVMBuildNot (builder, lhs, ""), "");
5761 values [ins->dreg] = LLVMBuildBitCast (builder, v, rt, "");
5785 case OP_PADDB_SAT_UN:
5786 case OP_PADDW_SAT_UN:
5787 case OP_PSUBB_SAT_UN:
5788 case OP_PSUBW_SAT_UN:
5796 case OP_PMULW_HIGH_UN: {
5797 LLVMValueRef args [2];
5802 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (lmodule, simd_op_to_intrins (ins->opcode)), args, 2, dname);
5809 values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildICmp (builder, LLVMIntEQ, lhs, rhs, ""), LLVMTypeOf (lhs), "");
5813 values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildICmp (builder, LLVMIntSGT, lhs, rhs, ""), LLVMTypeOf (lhs), "");
5821 case OP_EXTRACTX_U2:
5823 case OP_EXTRACT_U1: {
5825 gboolean zext = FALSE;
5827 t = simd_op_to_llvm_type (ins->opcode);
5829 switch (ins->opcode) {
5837 case OP_EXTRACTX_U2:
5842 t = LLVMInt32Type ();
5843 g_assert_not_reached ();
5846 lhs = LLVMBuildBitCast (builder, lhs, t, "");
5847 values [ins->dreg] = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), "");
5849 values [ins->dreg] = LLVMBuildZExt (builder, values [ins->dreg], LLVMInt32Type (), "");
5858 case OP_EXPAND_R8: {
5859 LLVMTypeRef t = simd_op_to_llvm_type (ins->opcode);
5860 LLVMValueRef mask [16], v;
5863 for (i = 0; i < 16; ++i)
5864 mask [i] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
5866 v = convert (ctx, values [ins->sreg1], LLVMGetElementType (t));
5868 values [ins->dreg] = LLVMBuildInsertElement (builder, LLVMConstNull (t), v, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
5869 values [ins->dreg] = LLVMBuildShuffleVector (builder, values [ins->dreg], LLVMGetUndef (t), LLVMConstVector (mask, LLVMGetVectorSize (t)), "");
5874 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt8Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
5877 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt16Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
5880 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt32Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
5883 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt64Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
5886 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMFloatType ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
5889 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMDoubleType ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
5900 case OP_EXTRACT_MASK:
5907 v = convert (ctx, values [ins->sreg1], simd_op_to_llvm_type (ins->opcode));
5909 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (lmodule, simd_op_to_intrins (ins->opcode)), &v, 1, dname);
5915 LLVMValueRef args [3];
5919 args [2] = LLVMConstInt (LLVMInt8Type (), ins->inst_c0, FALSE);
5921 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (lmodule, simd_op_to_intrins (ins->opcode)), args, 3, dname);
5926 /* This is only used for implementing shifts by non-immediate */
5927 values [ins->dreg] = lhs;
5938 LLVMValueRef args [3];
5941 args [1] = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
5943 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (lmodule, simd_op_to_intrins (ins->opcode)), args, 2, dname);
5954 case OP_PSHLQ_REG: {
5955 LLVMValueRef args [3];
5958 args [1] = values [ins->sreg2];
5960 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (lmodule, simd_op_to_intrins (ins->opcode)), args, 2, dname);
5967 case OP_PSHUFLEW_LOW:
5968 case OP_PSHUFLEW_HIGH: {
5970 LLVMValueRef v1 = NULL, v2 = NULL, mask_values [16];
5971 int i, mask_size = 0;
5972 int imask = ins->inst_c0;
5974 /* Convert the x86 shuffle mask to LLVM's */
5975 switch (ins->opcode) {
5978 mask [0] = ((imask >> 0) & 3);
5979 mask [1] = ((imask >> 2) & 3);
5980 mask [2] = ((imask >> 4) & 3) + 4;
5981 mask [3] = ((imask >> 6) & 3) + 4;
5982 v1 = values [ins->sreg1];
5983 v2 = values [ins->sreg2];
5987 mask [0] = ((imask >> 0) & 1);
5988 mask [1] = ((imask >> 1) & 1) + 2;
5989 v1 = values [ins->sreg1];
5990 v2 = values [ins->sreg2];
5992 case OP_PSHUFLEW_LOW:
5994 mask [0] = ((imask >> 0) & 3);
5995 mask [1] = ((imask >> 2) & 3);
5996 mask [2] = ((imask >> 4) & 3);
5997 mask [3] = ((imask >> 6) & 3);
6002 v1 = values [ins->sreg1];
6003 v2 = LLVMGetUndef (LLVMTypeOf (v1));
6005 case OP_PSHUFLEW_HIGH:
6011 mask [4] = 4 + ((imask >> 0) & 3);
6012 mask [5] = 4 + ((imask >> 2) & 3);
6013 mask [6] = 4 + ((imask >> 4) & 3);
6014 mask [7] = 4 + ((imask >> 6) & 3);
6015 v1 = values [ins->sreg1];
6016 v2 = LLVMGetUndef (LLVMTypeOf (v1));
6020 mask [0] = ((imask >> 0) & 3);
6021 mask [1] = ((imask >> 2) & 3);
6022 mask [2] = ((imask >> 4) & 3);
6023 mask [3] = ((imask >> 6) & 3);
6024 v1 = values [ins->sreg1];
6025 v2 = LLVMGetUndef (LLVMTypeOf (v1));
6028 g_assert_not_reached ();
6030 for (i = 0; i < mask_size; ++i)
6031 mask_values [i] = LLVMConstInt (LLVMInt32Type (), mask [i], FALSE);
6033 values [ins->dreg] =
6034 LLVMBuildShuffleVector (builder, v1, v2,
6035 LLVMConstVector (mask_values, mask_size), dname);
6039 case OP_UNPACK_LOWB:
6040 case OP_UNPACK_LOWW:
6041 case OP_UNPACK_LOWD:
6042 case OP_UNPACK_LOWQ:
6043 case OP_UNPACK_LOWPS:
6044 case OP_UNPACK_LOWPD:
6045 case OP_UNPACK_HIGHB:
6046 case OP_UNPACK_HIGHW:
6047 case OP_UNPACK_HIGHD:
6048 case OP_UNPACK_HIGHQ:
6049 case OP_UNPACK_HIGHPS:
6050 case OP_UNPACK_HIGHPD: {
6052 LLVMValueRef mask_values [16];
6053 int i, mask_size = 0;
6054 gboolean low = FALSE;
6056 switch (ins->opcode) {
6057 case OP_UNPACK_LOWB:
6061 case OP_UNPACK_LOWW:
6065 case OP_UNPACK_LOWD:
6066 case OP_UNPACK_LOWPS:
6070 case OP_UNPACK_LOWQ:
6071 case OP_UNPACK_LOWPD:
6075 case OP_UNPACK_HIGHB:
6078 case OP_UNPACK_HIGHW:
6081 case OP_UNPACK_HIGHD:
6082 case OP_UNPACK_HIGHPS:
6085 case OP_UNPACK_HIGHQ:
6086 case OP_UNPACK_HIGHPD:
6090 g_assert_not_reached ();
6094 for (i = 0; i < (mask_size / 2); ++i) {
6096 mask [(i * 2) + 1] = mask_size + i;
6099 for (i = 0; i < (mask_size / 2); ++i) {
6100 mask [(i * 2)] = (mask_size / 2) + i;
6101 mask [(i * 2) + 1] = mask_size + (mask_size / 2) + i;
6105 for (i = 0; i < mask_size; ++i)
6106 mask_values [i] = LLVMConstInt (LLVMInt32Type (), mask [i], FALSE);
6108 values [ins->dreg] =
6109 LLVMBuildShuffleVector (builder, values [ins->sreg1], values [ins->sreg2],
6110 LLVMConstVector (mask_values, mask_size), dname);
6115 LLVMTypeRef t = simd_op_to_llvm_type (ins->opcode);
6116 LLVMValueRef v, val;
6118 v = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
6119 val = LLVMConstNull (t);
6120 val = LLVMBuildInsertElement (builder, val, v, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
6121 val = LLVMBuildInsertElement (builder, val, v, LLVMConstInt (LLVMInt32Type (), 1, FALSE), dname);
6123 values [ins->dreg] = val;
6127 case OP_DUPPS_HIGH: {
6128 LLVMTypeRef t = simd_op_to_llvm_type (ins->opcode);
6129 LLVMValueRef v1, v2, val;
6132 if (ins->opcode == OP_DUPPS_LOW) {
6133 v1 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
6134 v2 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 2, FALSE), "");
6136 v1 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 1, FALSE), "");
6137 v2 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 3, FALSE), "");
6139 val = LLVMConstNull (t);
6140 val = LLVMBuildInsertElement (builder, val, v1, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
6141 val = LLVMBuildInsertElement (builder, val, v1, LLVMConstInt (LLVMInt32Type (), 1, FALSE), "");
6142 val = LLVMBuildInsertElement (builder, val, v2, LLVMConstInt (LLVMInt32Type (), 2, FALSE), "");
6143 val = LLVMBuildInsertElement (builder, val, v2, LLVMConstInt (LLVMInt32Type (), 3, FALSE), "");
6145 values [ins->dreg] = val;
6155 * EXCEPTION HANDLING
6157 case OP_IMPLICIT_EXCEPTION:
6158 /* This marks a place where an implicit exception can happen */
6159 if (bb->region != -1)
6160 set_failure (ctx, "implicit-exception");
6164 gboolean rethrow = (ins->opcode == OP_RETHROW);
6165 if (ctx->llvm_only) {
6166 emit_llvmonly_throw (ctx, bb, rethrow, lhs);
6167 has_terminator = TRUE;
6168 ctx->unreachable [bb->block_num] = TRUE;
6170 emit_throw (ctx, bb, rethrow, lhs);
6171 builder = ctx->builder;
6175 case OP_CALL_HANDLER: {
6177 * We don't 'call' handlers, but instead simply branch to them.
6178 * The code generated by ENDFINALLY will branch back to us.
6180 LLVMBasicBlockRef noex_bb;
6182 BBInfo *info = &bblocks [ins->inst_target_bb->block_num];
6184 bb_list = info->call_handler_return_bbs;
6187 * Set the indicator variable for the finally clause.
6189 lhs = info->finally_ind;
6191 LLVMBuildStore (builder, LLVMConstInt (LLVMInt32Type (), g_slist_length (bb_list) + 1, FALSE), lhs);
6193 /* Branch to the finally clause */
6194 LLVMBuildBr (builder, info->call_handler_target_bb);
6196 noex_bb = gen_bb (ctx, "CALL_HANDLER_CONT_BB");
6197 info->call_handler_return_bbs = g_slist_append_mempool (cfg->mempool, info->call_handler_return_bbs, noex_bb);
6199 builder = ctx->builder = create_builder (ctx);
6200 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
6202 bblocks [bb->block_num].end_bblock = noex_bb;
6205 case OP_START_HANDLER: {
6208 case OP_ENDFINALLY: {
6209 LLVMBasicBlockRef resume_bb;
6210 MonoBasicBlock *handler_bb;
6211 LLVMValueRef val, switch_ins, callee;
6215 handler_bb = (MonoBasicBlock*)g_hash_table_lookup (ctx->region_to_handler, GUINT_TO_POINTER (mono_get_block_region_notry (cfg, bb->region)));
6216 g_assert (handler_bb);
6217 info = &bblocks [handler_bb->block_num];
6218 lhs = info->finally_ind;
6221 bb_list = info->call_handler_return_bbs;
6223 resume_bb = gen_bb (ctx, "ENDFINALLY_RESUME_BB");
6225 /* Load the finally variable */
6226 val = LLVMBuildLoad (builder, lhs, "");
6228 /* Reset the variable */
6229 LLVMBuildStore (builder, LLVMConstInt (LLVMInt32Type (), 0, FALSE), lhs);
6231 /* Branch to either resume_bb, or to the bblocks in bb_list */
6232 switch_ins = LLVMBuildSwitch (builder, val, resume_bb, g_slist_length (bb_list));
6234 * The other targets are added at the end to handle OP_CALL_HANDLER
6235 * opcodes processed later.
6237 info->endfinally_switch_ins_list = g_slist_append_mempool (cfg->mempool, info->endfinally_switch_ins_list, switch_ins);
6239 builder = ctx->builder = create_builder (ctx);
6240 LLVMPositionBuilderAtEnd (ctx->builder, resume_bb);
6242 if (ctx->llvm_only) {
6243 emit_resume_eh (ctx, bb);
6245 if (ctx->cfg->compile_aot) {
6246 callee = get_callee (ctx, LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE), MONO_PATCH_INFO_INTERNAL_METHOD, "llvm_resume_unwind_trampoline");
6248 callee = LLVMGetNamedFunction (lmodule, "llvm_resume_unwind_trampoline");
6250 LLVMBuildCall (builder, callee, NULL, 0, "");
6251 LLVMBuildUnreachable (builder);
6254 has_terminator = TRUE;
6257 case OP_IL_SEQ_POINT:
6262 sprintf (reason, "opcode %s", mono_inst_name (ins->opcode));
6263 set_failure (ctx, reason);
6271 /* Convert the value to the type required by phi nodes */
6272 if (spec [MONO_INST_DEST] != ' ' && !MONO_IS_STORE_MEMBASE (ins) && ctx->vreg_types [ins->dreg]) {
6273 if (!values [ins->dreg])
6275 values [ins->dreg] = addresses [ins->dreg];
6277 values [ins->dreg] = convert (ctx, values [ins->dreg], ctx->vreg_types [ins->dreg]);
6280 /* Add stores for volatile variables */
6281 if (spec [MONO_INST_DEST] != ' ' && spec [MONO_INST_DEST] != 'v' && !MONO_IS_STORE_MEMBASE (ins))
6282 emit_volatile_store (ctx, ins->dreg);
6288 if (!has_terminator && bb->next_bb && (bb == cfg->bb_entry || bb->in_count > 0)) {
6289 LLVMBuildBr (builder, get_bb (ctx, bb->next_bb));
6292 if (bb == cfg->bb_exit && sig->ret->type == MONO_TYPE_VOID) {
6293 emit_dbg_loc (ctx, builder, cfg->header->code + cfg->header->code_size - 1);
6294 LLVMBuildRetVoid (builder);
6297 if (bb == cfg->bb_entry)
6298 ctx->last_alloca = LLVMGetLastInstruction (get_bb (ctx, cfg->bb_entry));
6302 * mono_llvm_check_method_supported:
6304 * Do some quick checks to decide whenever cfg->method can be compiled by LLVM, to avoid
6305 * compiling a method twice.
6308 mono_llvm_check_method_supported (MonoCompile *cfg)
6315 if (cfg->method->save_lmf) {
6316 cfg->exception_message = g_strdup ("lmf");
6317 cfg->disable_llvm = TRUE;
6319 if (cfg->disable_llvm)
6323 * Nested clauses where one of the clauses is a finally clause is
6324 * not supported, because LLVM can't figure out the control flow,
6325 * probably because we resume exception handling by calling our
6326 * own function instead of using the 'resume' llvm instruction.
6328 for (i = 0; i < cfg->header->num_clauses; ++i) {
6329 for (j = 0; j < cfg->header->num_clauses; ++j) {
6330 MonoExceptionClause *clause1 = &cfg->header->clauses [i];
6331 MonoExceptionClause *clause2 = &cfg->header->clauses [j];
6333 // FIXME: Nested try clauses fail in some cases too, i.e. #37273
6334 if (i != j && clause1->try_offset >= clause2->try_offset && clause1->handler_offset <= clause2->handler_offset) {
6335 //(clause1->flags == MONO_EXCEPTION_CLAUSE_FINALLY || clause2->flags == MONO_EXCEPTION_CLAUSE_FINALLY)) {
6336 cfg->exception_message = g_strdup ("nested clauses");
6337 cfg->disable_llvm = TRUE;
6342 if (cfg->disable_llvm)
6346 if (cfg->method->dynamic) {
6347 cfg->exception_message = g_strdup ("dynamic.");
6348 cfg->disable_llvm = TRUE;
6350 if (cfg->disable_llvm)
6354 static LLVMCallInfo*
6355 get_llvm_call_info (MonoCompile *cfg, MonoMethodSignature *sig)
6357 LLVMCallInfo *linfo;
6360 if (cfg->gsharedvt && cfg->llvm_only && mini_is_gsharedvt_variable_signature (sig)) {
6364 * Gsharedvt methods have the following calling convention:
6365 * - all arguments are passed by ref, even non generic ones
6366 * - the return value is returned by ref too, using a vret
6367 * argument passed after 'this'.
6369 n = sig->param_count + sig->hasthis;
6370 linfo = (LLVMCallInfo*)mono_mempool_alloc0 (cfg->mempool, sizeof (LLVMCallInfo) + (sizeof (LLVMArgInfo) * n));
6374 linfo->args [pindex ++].storage = LLVMArgNormal;
6376 if (sig->ret->type != MONO_TYPE_VOID) {
6377 if (mini_is_gsharedvt_variable_type (sig->ret))
6378 linfo->ret.storage = LLVMArgGsharedvtVariable;
6379 else if (mini_type_is_vtype (sig->ret))
6380 linfo->ret.storage = LLVMArgGsharedvtFixedVtype;
6382 linfo->ret.storage = LLVMArgGsharedvtFixed;
6383 linfo->vret_arg_index = pindex;
6385 linfo->ret.storage = LLVMArgNone;
6388 for (i = 0; i < sig->param_count; ++i) {
6389 if (sig->params [i]->byref)
6390 linfo->args [pindex].storage = LLVMArgNormal;
6391 else if (mini_is_gsharedvt_variable_type (sig->params [i]))
6392 linfo->args [pindex].storage = LLVMArgGsharedvtVariable;
6393 else if (mini_type_is_vtype (sig->params [i]))
6394 linfo->args [pindex].storage = LLVMArgGsharedvtFixedVtype;
6396 linfo->args [pindex].storage = LLVMArgGsharedvtFixed;
6397 linfo->args [pindex].type = sig->params [i];
6404 linfo = mono_arch_get_llvm_call_info (cfg, sig);
6405 for (i = 0; i < sig->param_count; ++i)
6406 linfo->args [i + sig->hasthis].type = sig->params [i];
6412 emit_method_inner (EmitContext *ctx);
6415 free_ctx (EmitContext *ctx)
6419 g_free (ctx->values);
6420 g_free (ctx->addresses);
6421 g_free (ctx->vreg_types);
6422 g_free (ctx->vreg_cli_types);
6423 g_free (ctx->is_dead);
6424 g_free (ctx->unreachable);
6425 g_ptr_array_free (ctx->phi_values, TRUE);
6426 g_free (ctx->bblocks);
6427 g_hash_table_destroy (ctx->region_to_handler);
6428 g_hash_table_destroy (ctx->clause_to_handler);
6429 g_free (ctx->method_name);
6430 g_ptr_array_free (ctx->bblock_list, TRUE);
6432 for (l = ctx->builders; l; l = l->next) {
6433 LLVMBuilderRef builder = (LLVMBuilderRef)l->data;
6434 LLVMDisposeBuilder (builder);
6441 * mono_llvm_emit_method:
6443 * Emit LLVM IL from the mono IL, and compile it to native code using LLVM.
6446 mono_llvm_emit_method (MonoCompile *cfg)
6450 gboolean is_linkonce = FALSE;
6453 /* The code below might acquire the loader lock, so use it for global locking */
6454 mono_loader_lock ();
6456 /* Used to communicate with the callbacks */
6457 mono_native_tls_set_value (current_cfg_tls_id, cfg);
6459 ctx = g_new0 (EmitContext, 1);
6461 ctx->mempool = cfg->mempool;
6464 * This maps vregs to the LLVM instruction defining them
6466 ctx->values = g_new0 (LLVMValueRef, cfg->next_vreg);
6468 * This maps vregs for volatile variables to the LLVM instruction defining their
6471 ctx->addresses = g_new0 (LLVMValueRef, cfg->next_vreg);
6472 ctx->vreg_types = g_new0 (LLVMTypeRef, cfg->next_vreg);
6473 ctx->vreg_cli_types = g_new0 (MonoType*, cfg->next_vreg);
6474 ctx->phi_values = g_ptr_array_sized_new (256);
6476 * This signals whenever the vreg was defined by a phi node with no input vars
6477 * (i.e. all its input bblocks end with NOT_REACHABLE).
6479 ctx->is_dead = g_new0 (gboolean, cfg->next_vreg);
6480 /* Whenever the bblock is unreachable */
6481 ctx->unreachable = g_new0 (gboolean, cfg->max_block_num);
6482 ctx->bblock_list = g_ptr_array_sized_new (256);
6484 ctx->region_to_handler = g_hash_table_new (NULL, NULL);
6485 ctx->clause_to_handler = g_hash_table_new (NULL, NULL);
6486 ctx->method_to_callers = g_hash_table_new (NULL, NULL);
6487 if (cfg->compile_aot) {
6488 ctx->module = &aot_module;
6492 * Allow the linker to discard duplicate copies of wrappers, generic instances etc. by using the 'linkonce'
6493 * linkage for them. This requires the following:
6494 * - the method needs to have a unique mangled name
6495 * - llvmonly mode, since the code in aot-runtime.c would initialize got slots in the wrong aot image etc.
6497 is_linkonce = ctx->module->llvm_only && ctx->module->static_link && mono_aot_is_linkonce_method (cfg->method);
6499 method_name = mono_aot_get_mangled_method_name (cfg->method);
6501 is_linkonce = FALSE;
6504 printf ("%s %s\n", mono_method_full_name (cfg->method, 1), method_name);
6506 printf ("%s\n", mono_method_full_name (cfg->method, 1));
6510 method_name = mono_aot_get_method_name (cfg);
6511 cfg->llvm_method_name = g_strdup (method_name);
6513 init_jit_module (cfg->domain);
6514 ctx->module = (MonoLLVMModule*)domain_jit_info (cfg->domain)->llvm_module;
6515 method_name = mono_method_full_name (cfg->method, TRUE);
6517 ctx->method_name = method_name;
6518 ctx->is_linkonce = is_linkonce;
6520 ctx->lmodule = ctx->module->lmodule;
6521 ctx->llvm_only = ctx->module->llvm_only;
6523 emit_method_inner (ctx);
6525 if (!ctx_ok (ctx)) {
6527 /* Need to add unused phi nodes as they can be referenced by other values */
6528 LLVMBasicBlockRef phi_bb = LLVMAppendBasicBlock (ctx->lmethod, "PHI_BB");
6529 LLVMBuilderRef builder;
6531 builder = create_builder (ctx);
6532 LLVMPositionBuilderAtEnd (builder, phi_bb);
6534 for (i = 0; i < ctx->phi_values->len; ++i) {
6535 LLVMValueRef v = (LLVMValueRef)g_ptr_array_index (ctx->phi_values, i);
6536 if (LLVMGetInstructionParent (v) == NULL)
6537 LLVMInsertIntoBuilder (builder, v);
6540 LLVMDeleteFunction (ctx->lmethod);
6546 mono_native_tls_set_value (current_cfg_tls_id, NULL);
6548 mono_loader_unlock ();
6552 emit_method_inner (EmitContext *ctx)
6554 MonoCompile *cfg = ctx->cfg;
6555 MonoMethodSignature *sig;
6557 LLVMTypeRef method_type;
6558 LLVMValueRef method = NULL;
6559 LLVMValueRef *values = ctx->values;
6560 int i, max_block_num, bb_index;
6561 gboolean last = FALSE;
6562 LLVMCallInfo *linfo;
6563 LLVMModuleRef lmodule = ctx->lmodule;
6565 GPtrArray *bblock_list = ctx->bblock_list;
6566 MonoMethodHeader *header;
6567 MonoExceptionClause *clause;
6570 if (cfg->gsharedvt && !cfg->llvm_only) {
6571 set_failure (ctx, "gsharedvt");
6577 static int count = 0;
6580 if (g_getenv ("LLVM_COUNT")) {
6581 if (count == atoi (g_getenv ("LLVM_COUNT"))) {
6582 printf ("LAST: %s\n", mono_method_full_name (cfg->method, TRUE));
6586 if (count > atoi (g_getenv ("LLVM_COUNT"))) {
6587 set_failure (ctx, "count");
6594 sig = mono_method_signature (cfg->method);
6597 linfo = get_llvm_call_info (cfg, sig);
6603 linfo->rgctx_arg = TRUE;
6604 ctx->method_type = method_type = sig_to_llvm_sig_full (ctx, sig, linfo);
6608 method = LLVMAddFunction (lmodule, ctx->method_name, method_type);
6609 ctx->lmethod = method;
6611 if (!cfg->llvm_only)
6612 LLVMSetFunctionCallConv (method, LLVMMono1CallConv);
6613 LLVMSetLinkage (method, LLVMPrivateLinkage);
6615 LLVMAddFunctionAttr (method, LLVMUWTable);
6617 if (cfg->compile_aot) {
6618 LLVMSetLinkage (method, LLVMInternalLinkage);
6619 if (ctx->module->external_symbols) {
6620 LLVMSetLinkage (method, LLVMExternalLinkage);
6621 LLVMSetVisibility (method, LLVMHiddenVisibility);
6623 if (ctx->is_linkonce) {
6624 LLVMSetLinkage (method, LLVMLinkOnceAnyLinkage);
6625 LLVMSetVisibility (method, LLVMDefaultVisibility);
6628 LLVMSetLinkage (method, LLVMPrivateLinkage);
6631 if (cfg->method->save_lmf && !cfg->llvm_only) {
6632 set_failure (ctx, "lmf");
6636 if (sig->pinvoke && cfg->method->wrapper_type != MONO_WRAPPER_RUNTIME_INVOKE && !cfg->llvm_only) {
6637 set_failure (ctx, "pinvoke signature");
6641 header = cfg->header;
6642 for (i = 0; i < header->num_clauses; ++i) {
6643 clause = &header->clauses [i];
6644 if (clause->flags != MONO_EXCEPTION_CLAUSE_FINALLY && clause->flags != MONO_EXCEPTION_CLAUSE_NONE) {
6645 set_failure (ctx, "non-finally/catch clause.");
6649 if (header->num_clauses || (cfg->method->iflags & METHOD_IMPL_ATTRIBUTE_NOINLINING) || cfg->no_inline)
6650 /* We can't handle inlined methods with clauses */
6651 LLVMAddFunctionAttr (method, LLVMNoInlineAttribute);
6653 if (linfo->rgctx_arg) {
6654 ctx->rgctx_arg = LLVMGetParam (method, linfo->rgctx_arg_pindex);
6655 ctx->rgctx_arg_pindex = linfo->rgctx_arg_pindex;
6657 * We mark the rgctx parameter with the inreg attribute, which is mapped to
6658 * MONO_ARCH_RGCTX_REG in the Mono calling convention in llvm, i.e.
6659 * CC_X86_64_Mono in X86CallingConv.td.
6661 if (!ctx->llvm_only)
6662 LLVMAddAttribute (ctx->rgctx_arg, LLVMInRegAttribute);
6663 LLVMSetValueName (ctx->rgctx_arg, "rgctx");
6665 ctx->rgctx_arg_pindex = -1;
6667 if (cfg->vret_addr) {
6668 values [cfg->vret_addr->dreg] = LLVMGetParam (method, linfo->vret_arg_pindex);
6669 LLVMSetValueName (values [cfg->vret_addr->dreg], "vret");
6670 if (linfo->ret.storage == LLVMArgVtypeByRef) {
6671 LLVMAddAttribute (LLVMGetParam (method, linfo->vret_arg_pindex), LLVMStructRetAttribute);
6672 LLVMAddAttribute (LLVMGetParam (method, linfo->vret_arg_pindex), LLVMNoAliasAttribute);
6674 } else if (linfo->ret.storage == LLVMArgScalarRetAddr) {
6675 LLVMValueRef param = LLVMGetParam (method, linfo->vret_arg_pindex);
6676 LLVMSetValueName (param, "vret");
6680 ctx->this_arg_pindex = linfo->this_arg_pindex;
6681 ctx->this_arg = LLVMGetParam (method, linfo->this_arg_pindex);
6682 values [cfg->args [0]->dreg] = ctx->this_arg;
6683 LLVMSetValueName (values [cfg->args [0]->dreg], "this");
6686 names = g_new (char *, sig->param_count);
6687 mono_method_get_param_names (cfg->method, (const char **) names);
6689 for (i = 0; i < sig->param_count; ++i) {
6690 LLVMArgInfo *ainfo = &linfo->args [i + sig->hasthis];
6692 int pindex = ainfo->pindex + ainfo->ndummy_fpargs;
6695 for (j = 0; j < ainfo->ndummy_fpargs; ++j) {
6696 name = g_strdup_printf ("dummy_%d_%d", i, j);
6697 LLVMSetValueName (LLVMGetParam (method, ainfo->pindex + j), name);
6701 values [cfg->args [i + sig->hasthis]->dreg] = LLVMGetParam (method, pindex);
6702 if (ainfo->storage == LLVMArgScalarByRef) {
6703 if (names [i] && names [i][0] != '\0')
6704 name = g_strdup_printf ("p_arg_%s", names [i]);
6706 name = g_strdup_printf ("p_arg_%d", i);
6707 } else if (ainfo->storage == LLVMArgGsharedvtFixed || ainfo->storage == LLVMArgGsharedvtFixedVtype) {
6708 if (names [i] && names [i][0] != '\0')
6709 name = g_strdup_printf ("p_arg_%s", names [i]);
6711 name = g_strdup_printf ("p_arg_%d", i);
6713 if (names [i] && names [i][0] != '\0')
6714 name = g_strdup_printf ("arg_%s", names [i]);
6716 name = g_strdup_printf ("arg_%d", i);
6718 LLVMSetValueName (values [cfg->args [i + sig->hasthis]->dreg], name);
6720 if (ainfo->storage == LLVMArgVtypeByVal)
6721 LLVMAddAttribute (LLVMGetParam (method, pindex), LLVMByValAttribute);
6723 if (ainfo->storage == LLVMArgVtypeByRef) {
6725 cfg->args [i + sig->hasthis]->opcode = OP_VTARG_ADDR;
6730 if (ctx->module->emit_dwarf && cfg->compile_aot && mono_debug_enabled ()) {
6731 ctx->minfo = mono_debug_lookup_method (cfg->method);
6732 ctx->dbg_md = emit_dbg_subprogram (ctx, cfg, method, ctx->method_name);
6736 for (bb = cfg->bb_entry; bb; bb = bb->next_bb)
6737 max_block_num = MAX (max_block_num, bb->block_num);
6738 ctx->bblocks = bblocks = g_new0 (BBInfo, max_block_num + 1);
6740 /* Add branches between non-consecutive bblocks */
6741 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
6742 if (bb->last_ins && MONO_IS_COND_BRANCH_OP (bb->last_ins) &&
6743 bb->next_bb != bb->last_ins->inst_false_bb) {
6745 MonoInst *inst = (MonoInst*)mono_mempool_alloc0 (cfg->mempool, sizeof (MonoInst));
6746 inst->opcode = OP_BR;
6747 inst->inst_target_bb = bb->last_ins->inst_false_bb;
6748 mono_bblock_add_inst (bb, inst);
6753 * The INDIRECT flag added by OP_LDADDR inhibits optimizations, even if the LDADDR
6754 * was later optimized away, so clear these flags, and add them back for the still
6755 * present OP_LDADDR instructions.
6757 for (i = 0; i < cfg->next_vreg; ++i) {
6760 ins = get_vreg_to_inst (cfg, i);
6761 if (ins && ins != cfg->rgctx_var)
6762 ins->flags &= ~MONO_INST_INDIRECT;
6766 * Make a first pass over the code to precreate PHI nodes/set INDIRECT flags.
6768 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
6770 LLVMBuilderRef builder;
6772 char dname_buf[128];
6774 builder = create_builder (ctx);
6776 for (ins = bb->code; ins; ins = ins->next) {
6777 switch (ins->opcode) {
6782 LLVMTypeRef phi_type = llvm_type_to_stack_type (cfg, type_to_llvm_type (ctx, &ins->klass->byval_arg));
6787 if (ins->opcode == OP_VPHI) {
6788 /* Treat valuetype PHI nodes as operating on the address itself */
6789 g_assert (ins->klass);
6790 phi_type = LLVMPointerType (type_to_llvm_type (ctx, &ins->klass->byval_arg), 0);
6794 * Have to precreate these, as they can be referenced by
6795 * earlier instructions.
6797 sprintf (dname_buf, "t%d", ins->dreg);
6799 values [ins->dreg] = LLVMBuildPhi (builder, phi_type, dname);
6801 if (ins->opcode == OP_VPHI)
6802 ctx->addresses [ins->dreg] = values [ins->dreg];
6804 g_ptr_array_add (ctx->phi_values, values [ins->dreg]);
6807 * Set the expected type of the incoming arguments since these have
6808 * to have the same type.
6810 for (i = 0; i < ins->inst_phi_args [0]; i++) {
6811 int sreg1 = ins->inst_phi_args [i + 1];
6814 ctx->vreg_types [sreg1] = phi_type;
6819 ((MonoInst*)ins->inst_p0)->flags |= MONO_INST_INDIRECT;
6828 * Create an ordering for bblocks, use the depth first order first, then
6829 * put the exception handling bblocks last.
6831 for (bb_index = 0; bb_index < cfg->num_bblocks; ++bb_index) {
6832 bb = cfg->bblocks [bb_index];
6833 if (!(bb->region != -1 && !MONO_BBLOCK_IS_IN_REGION (bb, MONO_REGION_TRY))) {
6834 g_ptr_array_add (bblock_list, bb);
6835 bblocks [bb->block_num].added = TRUE;
6839 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
6840 if (!bblocks [bb->block_num].added)
6841 g_ptr_array_add (bblock_list, bb);
6845 * Second pass: generate code.
6848 LLVMBuilderRef entry_builder = create_builder (ctx);
6849 LLVMBasicBlockRef entry_bb = get_bb (ctx, cfg->bb_entry);
6850 LLVMPositionBuilderAtEnd (entry_builder, entry_bb);
6851 emit_entry_bb (ctx, entry_builder);
6853 // Make landing pads first
6854 ctx->exc_meta = g_hash_table_new_full (NULL, NULL, NULL, NULL);
6856 if (ctx->llvm_only) {
6857 size_t group_index = 0;
6858 while (group_index < cfg->header->num_clauses) {
6860 size_t cursor = group_index;
6861 while (cursor < cfg->header->num_clauses &&
6862 CLAUSE_START (&cfg->header->clauses [cursor]) == CLAUSE_START (&cfg->header->clauses [group_index]) &&
6863 CLAUSE_END (&cfg->header->clauses [cursor]) == CLAUSE_END (&cfg->header->clauses [group_index])) {
6868 LLVMBasicBlockRef lpad_bb = emit_landing_pad (ctx, group_index, count);
6869 intptr_t key = CLAUSE_END (&cfg->header->clauses [group_index]);
6870 g_hash_table_insert (ctx->exc_meta, (gpointer)key, lpad_bb);
6872 group_index = cursor;
6876 for (bb_index = 0; bb_index < bblock_list->len; ++bb_index) {
6877 bb = (MonoBasicBlock*)g_ptr_array_index (bblock_list, bb_index);
6879 // Prune unreachable mono BBs.
6880 if (!(bb == cfg->bb_entry || bb->in_count > 0))
6883 process_bb (ctx, bb);
6887 g_hash_table_destroy (ctx->exc_meta);
6889 mono_memory_barrier ();
6891 /* Add incoming phi values */
6892 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
6893 GSList *l, *ins_list;
6895 ins_list = bblocks [bb->block_num].phi_nodes;
6897 for (l = ins_list; l; l = l->next) {
6898 PhiNode *node = (PhiNode*)l->data;
6899 MonoInst *phi = node->phi;
6900 int sreg1 = node->sreg;
6901 LLVMBasicBlockRef in_bb;
6906 in_bb = get_end_bb (ctx, node->in_bb);
6908 if (ctx->unreachable [node->in_bb->block_num])
6911 if (!values [sreg1]) {
6912 /* Can happen with values in EH clauses */
6913 set_failure (ctx, "incoming phi sreg1");
6917 if (phi->opcode == OP_VPHI) {
6918 g_assert (LLVMTypeOf (ctx->addresses [sreg1]) == LLVMTypeOf (values [phi->dreg]));
6919 LLVMAddIncoming (values [phi->dreg], &ctx->addresses [sreg1], &in_bb, 1);
6921 if (LLVMTypeOf (values [sreg1]) != LLVMTypeOf (values [phi->dreg])) {
6922 set_failure (ctx, "incoming phi arg type mismatch");
6925 g_assert (LLVMTypeOf (values [sreg1]) == LLVMTypeOf (values [phi->dreg]));
6926 LLVMAddIncoming (values [phi->dreg], &values [sreg1], &in_bb, 1);
6931 /* Nullify empty phi instructions */
6932 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
6933 GSList *l, *ins_list;
6935 ins_list = bblocks [bb->block_num].phi_nodes;
6937 for (l = ins_list; l; l = l->next) {
6938 PhiNode *node = (PhiNode*)l->data;
6939 MonoInst *phi = node->phi;
6940 LLVMValueRef phi_ins = values [phi->dreg];
6943 /* Already removed */
6946 if (LLVMCountIncoming (phi_ins) == 0) {
6947 mono_llvm_replace_uses_of (phi_ins, LLVMConstNull (LLVMTypeOf (phi_ins)));
6948 LLVMInstructionEraseFromParent (phi_ins);
6949 values [phi->dreg] = NULL;
6954 /* Create the SWITCH statements for ENDFINALLY instructions */
6955 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
6956 BBInfo *info = &bblocks [bb->block_num];
6958 for (l = info->endfinally_switch_ins_list; l; l = l->next) {
6959 LLVMValueRef switch_ins = (LLVMValueRef)l->data;
6960 GSList *bb_list = info->call_handler_return_bbs;
6962 for (i = 0; i < g_slist_length (bb_list); ++i)
6963 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), i + 1, FALSE), (LLVMBasicBlockRef)(g_slist_nth (bb_list, i)->data));
6967 /* Initialize the method if needed */
6968 if (cfg->compile_aot && ctx->llvm_only) {
6969 // FIXME: Add more shared got entries
6970 ctx->builder = create_builder (ctx);
6971 LLVMPositionBuilderAtEnd (ctx->builder, ctx->init_bb);
6973 ctx->module->max_method_idx = MAX (ctx->module->max_method_idx, cfg->method_index);
6975 // FIXME: beforefieldinit
6976 if (ctx->has_got_access || mono_class_get_cctor (cfg->method->klass)) {
6977 emit_init_method (ctx);
6979 LLVMBuildBr (ctx->builder, ctx->inited_bb);
6983 if (cfg->llvm_only) {
6984 GHashTableIter iter;
6986 GSList *callers, *l, *l2;
6989 * Add the contents of ctx->method_to_callers to module->method_to_callers.
6990 * We can't do this earlier, as it contains llvm instructions which can be
6991 * freed if compilation fails.
6992 * FIXME: Get rid of this when all methods can be llvm compiled.
6994 g_hash_table_iter_init (&iter, ctx->method_to_callers);
6995 while (g_hash_table_iter_next (&iter, (void**)&method, (void**)&callers)) {
6996 for (l = callers; l; l = l->next) {
6997 l2 = (GSList*)g_hash_table_lookup (ctx->module->method_to_callers, method);
6998 l2 = g_slist_prepend (l2, l->data);
6999 g_hash_table_insert (ctx->module->method_to_callers, method, l2);
7004 if (cfg->verbose_level > 1)
7005 mono_llvm_dump_value (method);
7007 if (cfg->compile_aot && !cfg->llvm_only)
7008 mark_as_used (ctx->module, method);
7010 if (cfg->compile_aot && !cfg->llvm_only) {
7011 LLVMValueRef md_args [16];
7012 LLVMValueRef md_node;
7015 method_index = mono_aot_get_method_index (cfg->orig_method);
7016 md_args [0] = LLVMMDString (ctx->method_name, strlen (ctx->method_name));
7017 md_args [1] = LLVMConstInt (LLVMInt32Type (), method_index, FALSE);
7018 md_node = LLVMMDNode (md_args, 2);
7019 LLVMAddNamedMetadataOperand (lmodule, "mono.function_indexes", md_node);
7020 //LLVMSetMetadata (method, md_kind, LLVMMDNode (&md_arg, 1));
7023 if (cfg->compile_aot) {
7024 /* Don't generate native code, keep the LLVM IR */
7025 if (cfg->verbose_level)
7026 printf ("%s emitted as %s\n", mono_method_full_name (cfg->method, TRUE), ctx->method_name);
7028 #if LLVM_API_VERSION < 100
7029 /* VerifyFunction can't handle some of the debug info created by DIBuilder in llvm 3.9 */
7030 int err = LLVMVerifyFunction(ctx->lmethod, LLVMPrintMessageAction);
7031 g_assert (err == 0);
7034 //LLVMVerifyFunction(method, 0);
7035 mono_llvm_optimize_method (ctx->module->mono_ee, ctx->lmethod);
7037 if (cfg->verbose_level > 1)
7038 mono_llvm_dump_value (ctx->lmethod);
7040 cfg->native_code = (unsigned char*)LLVMGetPointerToGlobal (ctx->module->ee, ctx->lmethod);
7042 /* Set by emit_cb */
7043 g_assert (cfg->code_len);
7046 if (ctx->module->method_to_lmethod)
7047 g_hash_table_insert (ctx->module->method_to_lmethod, cfg->method, ctx->lmethod);
7048 if (ctx->module->idx_to_lmethod)
7049 g_hash_table_insert (ctx->module->idx_to_lmethod, GINT_TO_POINTER (cfg->method_index), ctx->lmethod);
7051 if (ctx->llvm_only && cfg->orig_method->klass->valuetype && !(cfg->orig_method->flags & METHOD_ATTRIBUTE_STATIC))
7052 emit_unbox_tramp (ctx, ctx->method_name, ctx->method_type, ctx->lmethod, cfg->method_index);
7056 * mono_llvm_create_vars:
7058 * Same as mono_arch_create_vars () for LLVM.
7061 mono_llvm_create_vars (MonoCompile *cfg)
7063 MonoMethodSignature *sig;
7065 sig = mono_method_signature (cfg->method);
7066 if (cfg->gsharedvt && cfg->llvm_only) {
7067 if (mini_is_gsharedvt_variable_signature (sig) && sig->ret->type != MONO_TYPE_VOID) {
7068 cfg->vret_addr = mono_compile_create_var (cfg, &mono_get_intptr_class ()->byval_arg, OP_ARG);
7069 if (G_UNLIKELY (cfg->verbose_level > 1)) {
7070 printf ("vret_addr = ");
7071 mono_print_ins (cfg->vret_addr);
7075 mono_arch_create_vars (cfg);
7080 * mono_llvm_emit_call:
7082 * Same as mono_arch_emit_call () for LLVM.
7085 mono_llvm_emit_call (MonoCompile *cfg, MonoCallInst *call)
7088 MonoMethodSignature *sig;
7089 int i, n, stack_size;
7094 sig = call->signature;
7095 n = sig->param_count + sig->hasthis;
7097 call->cinfo = get_llvm_call_info (cfg, sig);
7099 if (cfg->disable_llvm)
7102 if (sig->call_convention == MONO_CALL_VARARG) {
7103 cfg->exception_message = g_strdup ("varargs");
7104 cfg->disable_llvm = TRUE;
7107 for (i = 0; i < n; ++i) {
7110 ainfo = call->cinfo->args + i;
7112 in = call->args [i];
7114 /* Simply remember the arguments */
7115 switch (ainfo->storage) {
7116 case LLVMArgNormal: {
7117 MonoType *t = (sig->hasthis && i == 0) ? &mono_get_intptr_class ()->byval_arg : ainfo->type;
7120 opcode = mono_type_to_regmove (cfg, t);
7121 if (opcode == OP_FMOVE) {
7122 MONO_INST_NEW (cfg, ins, OP_FMOVE);
7123 ins->dreg = mono_alloc_freg (cfg);
7124 } else if (opcode == OP_LMOVE) {
7125 MONO_INST_NEW (cfg, ins, OP_LMOVE);
7126 ins->dreg = mono_alloc_lreg (cfg);
7127 } else if (opcode == OP_RMOVE) {
7128 MONO_INST_NEW (cfg, ins, OP_RMOVE);
7129 ins->dreg = mono_alloc_freg (cfg);
7131 MONO_INST_NEW (cfg, ins, OP_MOVE);
7132 ins->dreg = mono_alloc_ireg (cfg);
7134 ins->sreg1 = in->dreg;
7137 case LLVMArgVtypeByVal:
7138 case LLVMArgVtypeByRef:
7139 case LLVMArgVtypeInReg:
7140 case LLVMArgVtypeAsScalar:
7141 case LLVMArgScalarByRef:
7142 case LLVMArgAsIArgs:
7143 case LLVMArgAsFpArgs:
7144 case LLVMArgGsharedvtVariable:
7145 case LLVMArgGsharedvtFixed:
7146 case LLVMArgGsharedvtFixedVtype:
7147 MONO_INST_NEW (cfg, ins, OP_LLVM_OUTARG_VT);
7148 ins->dreg = mono_alloc_ireg (cfg);
7149 ins->sreg1 = in->dreg;
7150 ins->inst_p0 = mono_mempool_alloc0 (cfg->mempool, sizeof (LLVMArgInfo));
7151 memcpy (ins->inst_p0, ainfo, sizeof (LLVMArgInfo));
7152 ins->inst_vtype = ainfo->type;
7153 ins->klass = mono_class_from_mono_type (ainfo->type);
7156 cfg->exception_message = g_strdup ("ainfo->storage");
7157 cfg->disable_llvm = TRUE;
7161 if (!cfg->disable_llvm) {
7162 MONO_ADD_INS (cfg->cbb, ins);
7163 mono_call_inst_add_outarg_reg (cfg, call, ins->dreg, 0, FALSE);
7168 static unsigned char*
7169 alloc_cb (LLVMValueRef function, int size)
7173 cfg = (MonoCompile*)mono_native_tls_get_value (current_cfg_tls_id);
7177 return (unsigned char*)mono_domain_code_reserve (cfg->domain, size);
7179 return (unsigned char*)mono_domain_code_reserve (mono_domain_get (), size);
7184 emitted_cb (LLVMValueRef function, void *start, void *end)
7188 cfg = (MonoCompile*)mono_native_tls_get_value (current_cfg_tls_id);
7190 cfg->code_len = (guint8*)end - (guint8*)start;
7194 exception_cb (void *data)
7197 MonoJitExceptionInfo *ei;
7198 guint32 ei_len, i, j, nested_len, nindex;
7199 gpointer *type_info;
7200 int this_reg, this_offset;
7202 cfg = (MonoCompile*)mono_native_tls_get_value (current_cfg_tls_id);
7206 * data points to a DWARF FDE structure, convert it to our unwind format and
7208 * An alternative would be to save it directly, and modify our unwinder to work
7211 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);
7212 if (cfg->verbose_level > 1)
7213 mono_print_unwind_info (cfg->encoded_unwind_ops, cfg->encoded_unwind_ops_len);
7215 /* Count nested clauses */
7217 for (i = 0; i < ei_len; ++i) {
7218 gint32 cindex1 = *(gint32*)type_info [i];
7219 MonoExceptionClause *clause1 = &cfg->header->clauses [cindex1];
7221 for (j = 0; j < cfg->header->num_clauses; ++j) {
7223 MonoExceptionClause *clause2 = &cfg->header->clauses [cindex2];
7225 if (cindex1 != cindex2 && clause1->try_offset >= clause2->try_offset && clause1->handler_offset <= clause2->handler_offset) {
7231 cfg->llvm_ex_info = (MonoJitExceptionInfo*)mono_mempool_alloc0 (cfg->mempool, (ei_len + nested_len) * sizeof (MonoJitExceptionInfo));
7232 cfg->llvm_ex_info_len = ei_len + nested_len;
7233 memcpy (cfg->llvm_ex_info, ei, ei_len * sizeof (MonoJitExceptionInfo));
7234 /* Fill the rest of the information from the type info */
7235 for (i = 0; i < ei_len; ++i) {
7236 gint32 clause_index = *(gint32*)type_info [i];
7237 MonoExceptionClause *clause = &cfg->header->clauses [clause_index];
7239 cfg->llvm_ex_info [i].flags = clause->flags;
7240 cfg->llvm_ex_info [i].data.catch_class = clause->data.catch_class;
7241 cfg->llvm_ex_info [i].clause_index = clause_index;
7245 * For nested clauses, the LLVM produced exception info associates the try interval with
7246 * the innermost handler, while mono expects it to be associated with all nesting clauses.
7247 * So add new clauses which use the IL info (catch class etc.) from the nesting clause,
7248 * and everything else from the nested clause.
7251 for (i = 0; i < ei_len; ++i) {
7252 gint32 cindex1 = *(gint32*)type_info [i];
7253 MonoExceptionClause *clause1 = &cfg->header->clauses [cindex1];
7255 for (j = 0; j < cfg->header->num_clauses; ++j) {
7257 MonoExceptionClause *clause2 = &cfg->header->clauses [cindex2];
7258 MonoJitExceptionInfo *nesting_ei, *nested_ei;
7260 if (cindex1 != cindex2 && clause1->try_offset >= clause2->try_offset && clause1->handler_offset <= clause2->handler_offset) {
7261 /* clause1 is the nested clause */
7262 nested_ei = &cfg->llvm_ex_info [i];
7263 nesting_ei = &cfg->llvm_ex_info [nindex];
7266 memcpy (nesting_ei, nested_ei, sizeof (MonoJitExceptionInfo));
7268 nesting_ei->flags = clause2->flags;
7269 nesting_ei->data.catch_class = clause2->data.catch_class;
7270 nesting_ei->clause_index = cindex2;
7274 g_assert (nindex == ei_len + nested_len);
7275 cfg->llvm_this_reg = this_reg;
7276 cfg->llvm_this_offset = this_offset;
7278 /* type_info [i] is cfg mempool allocated, no need to free it */
7285 dlsym_cb (const char *name, void **symbol)
7291 if (!strcmp (name, "__bzero")) {
7292 *symbol = (void*)bzero;
7294 current = mono_dl_open (NULL, 0, NULL);
7297 err = mono_dl_symbol (current, name, symbol);
7299 mono_dl_close (current);
7301 #ifdef MONO_ARCH_HAVE_CREATE_LLVM_NATIVE_THUNK
7302 *symbol = (char*)mono_arch_create_llvm_native_thunk (mono_domain_get (), (guint8*)(*symbol));
7308 AddFunc (LLVMModuleRef module, const char *name, LLVMTypeRef ret_type, LLVMTypeRef *param_types, int nparams)
7310 LLVMAddFunction (module, name, LLVMFunctionType (ret_type, param_types, nparams, FALSE));
7314 AddFunc2 (LLVMModuleRef module, const char *name, LLVMTypeRef ret_type, LLVMTypeRef param_type1, LLVMTypeRef param_type2)
7316 LLVMTypeRef param_types [4];
7318 param_types [0] = param_type1;
7319 param_types [1] = param_type2;
7321 AddFunc (module, name, ret_type, param_types, 2);
7325 add_intrinsics (LLVMModuleRef module)
7327 /* Emit declarations of instrinsics */
7329 * It would be nicer to emit only the intrinsics actually used, but LLVM's Module
7330 * type doesn't seem to do any locking.
7333 LLVMTypeRef params [] = { LLVMPointerType (LLVMInt8Type (), 0), LLVMInt8Type (), LLVMInt32Type (), LLVMInt32Type (), LLVMInt1Type () };
7335 memset_param_count = 5;
7336 memset_func_name = "llvm.memset.p0i8.i32";
7338 AddFunc (module, memset_func_name, LLVMVoidType (), params, memset_param_count);
7342 LLVMTypeRef params [] = { LLVMPointerType (LLVMInt8Type (), 0), LLVMPointerType (LLVMInt8Type (), 0), LLVMInt32Type (), LLVMInt32Type (), LLVMInt1Type () };
7344 memcpy_param_count = 5;
7345 memcpy_func_name = "llvm.memcpy.p0i8.p0i8.i32";
7347 AddFunc (module, memcpy_func_name, LLVMVoidType (), params, memcpy_param_count);
7351 LLVMTypeRef params [] = { LLVMDoubleType () };
7353 AddFunc (module, "llvm.sin.f64", LLVMDoubleType (), params, 1);
7354 AddFunc (module, "llvm.cos.f64", LLVMDoubleType (), params, 1);
7355 AddFunc (module, "llvm.sqrt.f64", LLVMDoubleType (), params, 1);
7357 /* This isn't an intrinsic, instead llvm seems to special case it by name */
7358 AddFunc (module, "fabs", LLVMDoubleType (), params, 1);
7362 LLVMTypeRef ovf_res_i32 [] = { LLVMInt32Type (), LLVMInt1Type () };
7363 LLVMTypeRef params [] = { LLVMInt32Type (), LLVMInt32Type () };
7364 LLVMTypeRef ret_type = LLVMStructType (ovf_res_i32, 2, FALSE);
7366 AddFunc (module, "llvm.sadd.with.overflow.i32", ret_type, params, 2);
7367 AddFunc (module, "llvm.sadd.with.overflow.i32", ret_type, params, 2);
7368 AddFunc (module, "llvm.uadd.with.overflow.i32", ret_type, params, 2);
7369 AddFunc (module, "llvm.ssub.with.overflow.i32", ret_type, params, 2);
7370 AddFunc (module, "llvm.usub.with.overflow.i32", ret_type, params, 2);
7371 AddFunc (module, "llvm.smul.with.overflow.i32", ret_type, params, 2);
7372 AddFunc (module, "llvm.umul.with.overflow.i32", ret_type, params, 2);
7376 LLVMTypeRef ovf_res_i64 [] = { LLVMInt64Type (), LLVMInt1Type () };
7377 LLVMTypeRef params [] = { LLVMInt64Type (), LLVMInt64Type () };
7378 LLVMTypeRef ret_type = LLVMStructType (ovf_res_i64, 2, FALSE);
7380 AddFunc (module, "llvm.sadd.with.overflow.i64", ret_type, params, 2);
7381 AddFunc (module, "llvm.uadd.with.overflow.i64", ret_type, params, 2);
7382 AddFunc (module, "llvm.ssub.with.overflow.i64", ret_type, params, 2);
7383 AddFunc (module, "llvm.usub.with.overflow.i64", ret_type, params, 2);
7384 AddFunc (module, "llvm.smul.with.overflow.i64", ret_type, params, 2);
7385 AddFunc (module, "llvm.umul.with.overflow.i64", ret_type, params, 2);
7388 AddFunc2 (module, "llvm.expect.i8", LLVMInt8Type (), LLVMInt8Type (), LLVMInt8Type ());
7389 AddFunc2 (module, "llvm.expect.i1", LLVMInt1Type (), LLVMInt1Type (), LLVMInt1Type ());
7393 AddFunc (module, "mono_personality", LLVMVoidType (), NULL, 0);
7395 AddFunc (module, "llvm_resume_unwind_trampoline", LLVMVoidType (), NULL, 0);
7398 /* SSE intrinsics */
7399 #if defined(TARGET_X86) || defined(TARGET_AMD64)
7401 LLVMTypeRef ret_type, arg_types [16];
7404 ret_type = type_to_simd_type (MONO_TYPE_I4);
7405 arg_types [0] = ret_type;
7406 arg_types [1] = ret_type;
7407 AddFunc (module, "llvm.x86.sse41.pminud", ret_type, arg_types, 2);
7408 AddFunc (module, "llvm.x86.sse41.pmaxud", ret_type, arg_types, 2);
7410 ret_type = type_to_simd_type (MONO_TYPE_I2);
7411 arg_types [0] = ret_type;
7412 arg_types [1] = ret_type;
7413 AddFunc (module, "llvm.x86.sse41.pminuw", ret_type, arg_types, 2);
7414 AddFunc (module, "llvm.x86.sse2.pmins.w", ret_type, arg_types, 2);
7415 AddFunc (module, "llvm.x86.sse41.pmaxuw", ret_type, arg_types, 2);
7416 AddFunc (module, "llvm.x86.sse2.padds.w", ret_type, arg_types, 2);
7417 AddFunc (module, "llvm.x86.sse2.psubs.w", ret_type, arg_types, 2);
7418 AddFunc (module, "llvm.x86.sse2.paddus.w", ret_type, arg_types, 2);
7419 AddFunc (module, "llvm.x86.sse2.psubus.w", ret_type, arg_types, 2);
7420 AddFunc (module, "llvm.x86.sse2.pavg.w", ret_type, arg_types, 2);
7421 AddFunc (module, "llvm.x86.sse2.pmulh.w", ret_type, arg_types, 2);
7422 AddFunc (module, "llvm.x86.sse2.pmulhu.w", ret_type, arg_types, 2);
7424 ret_type = type_to_simd_type (MONO_TYPE_I1);
7425 arg_types [0] = ret_type;
7426 arg_types [1] = ret_type;
7427 AddFunc (module, "llvm.x86.sse2.pminu.b", ret_type, arg_types, 2);
7428 AddFunc (module, "llvm.x86.sse2.pmaxu.b", ret_type, arg_types, 2);
7429 AddFunc (module, "llvm.x86.sse2.padds.b", ret_type, arg_types, 2);
7430 AddFunc (module, "llvm.x86.sse2.psubs.b", ret_type, arg_types, 2);
7431 AddFunc (module, "llvm.x86.sse2.paddus.b", ret_type, arg_types, 2);
7432 AddFunc (module, "llvm.x86.sse2.psubus.b", ret_type, arg_types, 2);
7433 AddFunc (module, "llvm.x86.sse2.pavg.b", ret_type, arg_types, 2);
7435 ret_type = type_to_simd_type (MONO_TYPE_R8);
7436 arg_types [0] = ret_type;
7437 arg_types [1] = ret_type;
7438 AddFunc (module, "llvm.x86.sse2.min.pd", ret_type, arg_types, 2);
7439 AddFunc (module, "llvm.x86.sse2.max.pd", ret_type, arg_types, 2);
7440 AddFunc (module, "llvm.x86.sse3.hadd.pd", ret_type, arg_types, 2);
7441 AddFunc (module, "llvm.x86.sse3.hsub.pd", ret_type, arg_types, 2);
7442 AddFunc (module, "llvm.x86.sse3.addsub.pd", ret_type, arg_types, 2);
7444 ret_type = type_to_simd_type (MONO_TYPE_R4);
7445 arg_types [0] = ret_type;
7446 arg_types [1] = ret_type;
7447 AddFunc (module, "llvm.x86.sse.min.ps", ret_type, arg_types, 2);
7448 AddFunc (module, "llvm.x86.sse.max.ps", ret_type, arg_types, 2);
7449 AddFunc (module, "llvm.x86.sse3.hadd.ps", ret_type, arg_types, 2);
7450 AddFunc (module, "llvm.x86.sse3.hsub.ps", ret_type, arg_types, 2);
7451 AddFunc (module, "llvm.x86.sse3.addsub.ps", ret_type, arg_types, 2);
7454 ret_type = type_to_simd_type (MONO_TYPE_I1);
7455 arg_types [0] = type_to_simd_type (MONO_TYPE_I2);
7456 arg_types [1] = type_to_simd_type (MONO_TYPE_I2);
7457 AddFunc (module, "llvm.x86.sse2.packsswb.128", ret_type, arg_types, 2);
7458 AddFunc (module, "llvm.x86.sse2.packuswb.128", ret_type, arg_types, 2);
7459 ret_type = type_to_simd_type (MONO_TYPE_I2);
7460 arg_types [0] = type_to_simd_type (MONO_TYPE_I4);
7461 arg_types [1] = type_to_simd_type (MONO_TYPE_I4);
7462 AddFunc (module, "llvm.x86.sse2.packssdw.128", ret_type, arg_types, 2);
7463 AddFunc (module, "llvm.x86.sse41.packusdw", ret_type, arg_types, 2);
7466 ret_type = type_to_simd_type (MONO_TYPE_R8);
7467 arg_types [0] = ret_type;
7468 arg_types [1] = ret_type;
7469 arg_types [2] = LLVMInt8Type ();
7470 AddFunc (module, "llvm.x86.sse2.cmp.pd", ret_type, arg_types, 3);
7471 ret_type = type_to_simd_type (MONO_TYPE_R4);
7472 arg_types [0] = ret_type;
7473 arg_types [1] = ret_type;
7474 arg_types [2] = LLVMInt8Type ();
7475 AddFunc (module, "llvm.x86.sse.cmp.ps", ret_type, arg_types, 3);
7477 /* Conversion ops */
7478 ret_type = type_to_simd_type (MONO_TYPE_R8);
7479 arg_types [0] = type_to_simd_type (MONO_TYPE_I4);
7480 AddFunc (module, "llvm.x86.sse2.cvtdq2pd", ret_type, arg_types, 1);
7481 ret_type = type_to_simd_type (MONO_TYPE_R4);
7482 arg_types [0] = type_to_simd_type (MONO_TYPE_I4);
7483 AddFunc (module, "llvm.x86.sse2.cvtdq2ps", ret_type, arg_types, 1);
7484 ret_type = type_to_simd_type (MONO_TYPE_I4);
7485 arg_types [0] = type_to_simd_type (MONO_TYPE_R8);
7486 AddFunc (module, "llvm.x86.sse2.cvtpd2dq", ret_type, arg_types, 1);
7487 ret_type = type_to_simd_type (MONO_TYPE_I4);
7488 arg_types [0] = type_to_simd_type (MONO_TYPE_R4);
7489 AddFunc (module, "llvm.x86.sse2.cvtps2dq", ret_type, arg_types, 1);
7490 ret_type = type_to_simd_type (MONO_TYPE_R4);
7491 arg_types [0] = type_to_simd_type (MONO_TYPE_R8);
7492 AddFunc (module, "llvm.x86.sse2.cvtpd2ps", ret_type, arg_types, 1);
7493 ret_type = type_to_simd_type (MONO_TYPE_R8);
7494 arg_types [0] = type_to_simd_type (MONO_TYPE_R4);
7495 AddFunc (module, "llvm.x86.sse2.cvtps2pd", ret_type, arg_types, 1);
7497 ret_type = type_to_simd_type (MONO_TYPE_I4);
7498 arg_types [0] = type_to_simd_type (MONO_TYPE_R8);
7499 AddFunc (module, "llvm.x86.sse2.cvttpd2dq", ret_type, arg_types, 1);
7500 ret_type = type_to_simd_type (MONO_TYPE_I4);
7501 arg_types [0] = type_to_simd_type (MONO_TYPE_R4);
7502 AddFunc (module, "llvm.x86.sse2.cvttps2dq", ret_type, arg_types, 1);
7505 ret_type = type_to_simd_type (MONO_TYPE_R8);
7506 arg_types [0] = ret_type;
7507 AddFunc (module, "llvm.x86.sse2.sqrt.pd", ret_type, arg_types, 1);
7508 ret_type = type_to_simd_type (MONO_TYPE_R4);
7509 arg_types [0] = ret_type;
7510 AddFunc (module, "llvm.x86.sse.sqrt.ps", ret_type, arg_types, 1);
7511 ret_type = type_to_simd_type (MONO_TYPE_R4);
7512 arg_types [0] = ret_type;
7513 AddFunc (module, "llvm.x86.sse.rsqrt.ps", ret_type, arg_types, 1);
7514 ret_type = type_to_simd_type (MONO_TYPE_R4);
7515 arg_types [0] = ret_type;
7516 AddFunc (module, "llvm.x86.sse.rcp.ps", ret_type, arg_types, 1);
7519 ret_type = type_to_simd_type (MONO_TYPE_I2);
7520 arg_types [0] = ret_type;
7521 arg_types [1] = LLVMInt32Type ();
7522 AddFunc (module, "llvm.x86.sse2.psrli.w", ret_type, arg_types, 2);
7523 AddFunc (module, "llvm.x86.sse2.psrai.w", ret_type, arg_types, 2);
7524 AddFunc (module, "llvm.x86.sse2.pslli.w", ret_type, arg_types, 2);
7525 ret_type = type_to_simd_type (MONO_TYPE_I4);
7526 arg_types [0] = ret_type;
7527 arg_types [1] = LLVMInt32Type ();
7528 AddFunc (module, "llvm.x86.sse2.psrli.d", ret_type, arg_types, 2);
7529 AddFunc (module, "llvm.x86.sse2.psrai.d", ret_type, arg_types, 2);
7530 AddFunc (module, "llvm.x86.sse2.pslli.d", ret_type, arg_types, 2);
7531 ret_type = type_to_simd_type (MONO_TYPE_I8);
7532 arg_types [0] = ret_type;
7533 arg_types [1] = LLVMInt32Type ();
7534 AddFunc (module, "llvm.x86.sse2.psrli.q", ret_type, arg_types, 2);
7535 AddFunc (module, "llvm.x86.sse2.pslli.q", ret_type, arg_types, 2);
7538 ret_type = LLVMInt32Type ();
7539 arg_types [0] = type_to_simd_type (MONO_TYPE_I1);
7540 AddFunc (module, "llvm.x86.sse2.pmovmskb.128", ret_type, arg_types, 1);
7543 AddFunc (module, "llvm.x86.sse2.pause", LLVMVoidType (), NULL, 0);
7546 /* Load/Store intrinsics */
7548 LLVMTypeRef arg_types [5];
7552 for (i = 1; i <= 8; i *= 2) {
7553 arg_types [0] = LLVMPointerType (LLVMIntType (i * 8), 0);
7554 arg_types [1] = LLVMInt32Type ();
7555 arg_types [2] = LLVMInt1Type ();
7556 arg_types [3] = LLVMInt32Type ();
7557 sprintf (name, "llvm.mono.load.i%d.p0i%d", i * 8, i * 8);
7558 AddFunc (module, name, LLVMIntType (i * 8), arg_types, 4);
7560 arg_types [0] = LLVMIntType (i * 8);
7561 arg_types [1] = LLVMPointerType (LLVMIntType (i * 8), 0);
7562 arg_types [2] = LLVMInt32Type ();
7563 arg_types [3] = LLVMInt1Type ();
7564 arg_types [4] = LLVMInt32Type ();
7565 sprintf (name, "llvm.mono.store.i%d.p0i%d", i * 8, i * 8);
7566 AddFunc (module, name, LLVMVoidType (), arg_types, 5);
7572 add_types (MonoLLVMModule *module)
7574 module->ptr_type = LLVMPointerType (sizeof (gpointer) == 8 ? LLVMInt64Type () : LLVMInt32Type (), 0);
7578 mono_llvm_init (void)
7580 mono_native_tls_alloc (¤t_cfg_tls_id, NULL);
7584 init_jit_module (MonoDomain *domain)
7586 MonoJitICallInfo *info;
7587 MonoJitDomainInfo *dinfo;
7588 MonoLLVMModule *module;
7591 dinfo = domain_jit_info (domain);
7592 if (dinfo->llvm_module)
7595 mono_loader_lock ();
7597 if (dinfo->llvm_module) {
7598 mono_loader_unlock ();
7602 module = g_new0 (MonoLLVMModule, 1);
7604 name = g_strdup_printf ("mono-%s", domain->friendly_name);
7605 module->lmodule = LLVMModuleCreateWithName (name);
7606 module->context = LLVMGetGlobalContext ();
7608 module->mono_ee = (MonoEERef*)mono_llvm_create_ee (LLVMCreateModuleProviderForExistingModule (module->lmodule), alloc_cb, emitted_cb, exception_cb, dlsym_cb, &module->ee);
7610 add_intrinsics (module->lmodule);
7613 module->llvm_types = g_hash_table_new (NULL, NULL);
7615 info = mono_find_jit_icall_by_name ("llvm_resume_unwind_trampoline");
7617 LLVMAddGlobalMapping (module->ee, LLVMGetNamedFunction (module->lmodule, "llvm_resume_unwind_trampoline"), (void*)info->func);
7619 mono_memory_barrier ();
7621 dinfo->llvm_module = module;
7623 mono_loader_unlock ();
7627 mono_llvm_cleanup (void)
7629 MonoLLVMModule *module = &aot_module;
7631 if (module->lmodule)
7632 LLVMDisposeModule (module->lmodule);
7634 if (module->context)
7635 LLVMContextDispose (module->context);
7639 mono_llvm_free_domain_info (MonoDomain *domain)
7641 MonoJitDomainInfo *info = domain_jit_info (domain);
7642 MonoLLVMModule *module = (MonoLLVMModule*)info->llvm_module;
7648 if (module->llvm_types)
7649 g_hash_table_destroy (module->llvm_types);
7651 mono_llvm_dispose_ee (module->mono_ee);
7653 if (module->bb_names) {
7654 for (i = 0; i < module->bb_names_len; ++i)
7655 g_free (module->bb_names [i]);
7656 g_free (module->bb_names);
7658 //LLVMDisposeModule (module->module);
7662 info->llvm_module = NULL;
7666 mono_llvm_create_aot_module (MonoAssembly *assembly, const char *global_prefix, gboolean emit_dwarf, gboolean static_link, gboolean llvm_only)
7668 MonoLLVMModule *module = &aot_module;
7670 /* Delete previous module */
7671 if (module->plt_entries)
7672 g_hash_table_destroy (module->plt_entries);
7673 if (module->lmodule)
7674 LLVMDisposeModule (module->lmodule);
7676 memset (module, 0, sizeof (aot_module));
7678 module->lmodule = LLVMModuleCreateWithName ("aot");
7679 module->assembly = assembly;
7680 module->global_prefix = g_strdup (global_prefix);
7681 module->got_symbol = g_strdup_printf ("%s_llvm_got", global_prefix);
7682 module->eh_frame_symbol = g_strdup_printf ("%s_eh_frame", global_prefix);
7683 module->get_method_symbol = g_strdup_printf ("%s_get_method", global_prefix);
7684 module->get_unbox_tramp_symbol = g_strdup_printf ("%s_get_unbox_tramp", global_prefix);
7685 module->external_symbols = TRUE;
7686 module->emit_dwarf = emit_dwarf;
7687 module->static_link = static_link;
7688 module->llvm_only = llvm_only;
7689 /* The first few entries are reserved */
7690 module->max_got_offset = 16;
7691 module->context = LLVMContextCreate ();
7694 /* clang ignores our debug info because it has an invalid version */
7695 module->emit_dwarf = FALSE;
7697 #if LLVM_API_VERSION > 100
7698 module->emit_dwarf = FALSE;
7701 add_intrinsics (module->lmodule);
7704 #if LLVM_API_VERSION > 100
7705 if (module->emit_dwarf) {
7706 char *dir, *build_info, *s, *cu_name;
7708 module->di_builder = mono_llvm_create_di_builder (module->lmodule);
7711 dir = g_strdup (".");
7712 build_info = mono_get_runtime_build_info ();
7713 s = g_strdup_printf ("Mono AOT Compiler %s (LLVM)", build_info);
7714 cu_name = g_path_get_basename (assembly->image->name);
7715 module->cu = mono_llvm_di_create_compile_unit (module->di_builder, cu_name, dir, s);
7717 g_free (build_info);
7724 * We couldn't compute the type of the LLVM global representing the got because
7725 * its size is only known after all the methods have been emitted. So create
7726 * a dummy variable, and replace all uses it with the real got variable when
7727 * its size is known in mono_llvm_emit_aot_module ().
7730 LLVMTypeRef got_type = LLVMArrayType (module->ptr_type, 0);
7732 module->got_var = LLVMAddGlobal (module->lmodule, got_type, "mono_dummy_got");
7733 LLVMSetInitializer (module->got_var, LLVMConstNull (got_type));
7736 /* Add initialization array */
7738 LLVMTypeRef inited_type = LLVMArrayType (LLVMInt8Type (), 0);
7740 module->inited_var = LLVMAddGlobal (aot_module.lmodule, inited_type, "mono_inited_tmp");
7741 LLVMSetInitializer (module->inited_var, LLVMConstNull (inited_type));
7745 emit_init_icall_wrappers (module);
7747 emit_llvm_code_start (module);
7749 /* Add a dummy personality function */
7750 if (!use_debug_personality) {
7751 LLVMValueRef personality = LLVMAddFunction (module->lmodule, default_personality_name, LLVMFunctionType (LLVMInt32Type (), NULL, 0, TRUE));
7752 LLVMSetLinkage (personality, LLVMExternalLinkage);
7753 mark_as_used (module, personality);
7756 /* Add a reference to the c++ exception we throw/catch */
7758 LLVMTypeRef exc = LLVMPointerType (LLVMInt8Type (), 0);
7759 module->sentinel_exception = LLVMAddGlobal (module->lmodule, exc, "_ZTIPi");
7760 LLVMSetLinkage (module->sentinel_exception, LLVMExternalLinkage);
7761 mono_llvm_set_is_constant (module->sentinel_exception);
7764 module->llvm_types = g_hash_table_new (NULL, NULL);
7765 module->plt_entries = g_hash_table_new (g_str_hash, g_str_equal);
7766 module->plt_entries_ji = g_hash_table_new (NULL, NULL);
7767 module->direct_callables = g_hash_table_new (g_str_hash, g_str_equal);
7768 module->method_to_lmethod = g_hash_table_new (NULL, NULL);
7769 module->idx_to_lmethod = g_hash_table_new (NULL, NULL);
7770 module->idx_to_unbox_tramp = g_hash_table_new (NULL, NULL);
7771 module->method_to_callers = g_hash_table_new (NULL, NULL);
7775 llvm_array_from_uints (LLVMTypeRef el_type, guint32 *values, int nvalues)
7778 LLVMValueRef res, *vals;
7780 vals = g_new0 (LLVMValueRef, nvalues);
7781 for (i = 0; i < nvalues; ++i)
7782 vals [i] = LLVMConstInt (LLVMInt32Type (), values [i], FALSE);
7783 res = LLVMConstArray (LLVMInt32Type (), vals, nvalues);
7789 * mono_llvm_emit_aot_file_info:
7791 * Emit the MonoAotFileInfo structure.
7792 * Same as emit_aot_file_info () in aot-compiler.c.
7795 mono_llvm_emit_aot_file_info (MonoAotFileInfo *info, gboolean has_jitted_code)
7797 MonoLLVMModule *module = &aot_module;
7799 /* Save these for later */
7800 memcpy (&module->aot_info, info, sizeof (MonoAotFileInfo));
7801 module->has_jitted_code = has_jitted_code;
7805 * mono_llvm_emit_aot_data:
7807 * Emit the binary data DATA pointed to by symbol SYMBOL.
7810 mono_llvm_emit_aot_data (const char *symbol, guint8 *data, int data_len)
7812 MonoLLVMModule *module = &aot_module;
7816 type = LLVMArrayType (LLVMInt8Type (), data_len);
7817 d = LLVMAddGlobal (module->lmodule, type, symbol);
7818 LLVMSetVisibility (d, LLVMHiddenVisibility);
7819 LLVMSetLinkage (d, LLVMInternalLinkage);
7820 LLVMSetInitializer (d, mono_llvm_create_constant_data_array (data, data_len));
7821 mono_llvm_set_is_constant (d);
7824 /* Add a reference to a global defined in JITted code */
7826 AddJitGlobal (MonoLLVMModule *module, LLVMTypeRef type, const char *name)
7831 s = g_strdup_printf ("%s%s", module->global_prefix, name);
7832 v = LLVMAddGlobal (module->lmodule, LLVMInt8Type (), s);
7838 emit_aot_file_info (MonoLLVMModule *module)
7840 LLVMTypeRef file_info_type;
7841 LLVMTypeRef *eltypes, eltype;
7842 LLVMValueRef info_var;
7843 LLVMValueRef *fields;
7844 int i, nfields, tindex;
7845 MonoAotFileInfo *info;
7846 LLVMModuleRef lmodule = module->lmodule;
7848 info = &module->aot_info;
7850 /* Create an LLVM type to represent MonoAotFileInfo */
7851 nfields = 2 + MONO_AOT_FILE_INFO_NUM_SYMBOLS + 15 + 5;
7852 eltypes = g_new (LLVMTypeRef, nfields);
7854 eltypes [tindex ++] = LLVMInt32Type ();
7855 eltypes [tindex ++] = LLVMInt32Type ();
7857 for (i = 0; i < MONO_AOT_FILE_INFO_NUM_SYMBOLS; ++i)
7858 eltypes [tindex ++] = LLVMPointerType (LLVMInt8Type (), 0);
7860 for (i = 0; i < 15; ++i)
7861 eltypes [tindex ++] = LLVMInt32Type ();
7863 eltypes [tindex ++] = LLVMArrayType (LLVMInt32Type (), MONO_AOT_TABLE_NUM);
7864 for (i = 0; i < 4; ++i)
7865 eltypes [tindex ++] = LLVMArrayType (LLVMInt32Type (), MONO_AOT_TRAMP_NUM);
7866 g_assert (tindex == nfields);
7867 file_info_type = LLVMStructCreateNamed (module->context, "MonoAotFileInfo");
7868 LLVMStructSetBody (file_info_type, eltypes, nfields, FALSE);
7870 info_var = LLVMAddGlobal (lmodule, file_info_type, "mono_aot_file_info");
7871 if (module->static_link) {
7872 LLVMSetVisibility (info_var, LLVMHiddenVisibility);
7873 LLVMSetLinkage (info_var, LLVMInternalLinkage);
7875 fields = g_new (LLVMValueRef, nfields);
7877 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->version, FALSE);
7878 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->dummy, FALSE);
7882 * We use LLVMGetNamedGlobal () for symbol which are defined in LLVM code, and LLVMAddGlobal ()
7883 * for symbols defined in the .s file emitted by the aot compiler.
7885 eltype = eltypes [tindex];
7886 if (module->llvm_only)
7887 fields [tindex ++] = LLVMConstNull (eltype);
7889 fields [tindex ++] = AddJitGlobal (module, eltype, "jit_got");
7890 fields [tindex ++] = module->got_var;
7891 /* llc defines this directly */
7892 if (!module->llvm_only) {
7893 fields [tindex ++] = LLVMAddGlobal (lmodule, eltype, module->eh_frame_symbol);
7894 fields [tindex ++] = LLVMConstNull (eltype);
7895 fields [tindex ++] = LLVMConstNull (eltype);
7897 fields [tindex ++] = LLVMConstNull (eltype);
7898 fields [tindex ++] = module->get_method;
7899 fields [tindex ++] = module->get_unbox_tramp;
7901 if (module->has_jitted_code) {
7902 fields [tindex ++] = AddJitGlobal (module, eltype, "jit_code_start");
7903 fields [tindex ++] = AddJitGlobal (module, eltype, "jit_code_end");
7905 fields [tindex ++] = LLVMConstNull (eltype);
7906 fields [tindex ++] = LLVMConstNull (eltype);
7908 if (!module->llvm_only)
7909 fields [tindex ++] = AddJitGlobal (module, eltype, "method_addresses");
7911 fields [tindex ++] = LLVMConstNull (eltype);
7912 if (info->flags & MONO_AOT_FILE_FLAG_SEPARATE_DATA) {
7913 for (i = 0; i < MONO_AOT_TABLE_NUM; ++i)
7914 fields [tindex ++] = LLVMConstNull (eltype);
7916 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "blob");
7917 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "class_name_table");
7918 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "class_info_offsets");
7919 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "method_info_offsets");
7920 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "ex_info_offsets");
7921 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "extra_method_info_offsets");
7922 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "extra_method_table");
7923 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "got_info_offsets");
7924 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "llvm_got_info_offsets");
7925 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "image_table");
7927 /* Not needed (mem_end) */
7928 fields [tindex ++] = LLVMConstNull (eltype);
7929 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "assembly_guid");
7930 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "runtime_version");
7931 if (info->trampoline_size [0]) {
7932 fields [tindex ++] = AddJitGlobal (module, eltype, "specific_trampolines");
7933 fields [tindex ++] = AddJitGlobal (module, eltype, "static_rgctx_trampolines");
7934 fields [tindex ++] = AddJitGlobal (module, eltype, "imt_thunks");
7935 fields [tindex ++] = AddJitGlobal (module, eltype, "gsharedvt_arg_trampolines");
7937 fields [tindex ++] = LLVMConstNull (eltype);
7938 fields [tindex ++] = LLVMConstNull (eltype);
7939 fields [tindex ++] = LLVMConstNull (eltype);
7940 fields [tindex ++] = LLVMConstNull (eltype);
7942 if (module->static_link && !module->llvm_only)
7943 fields [tindex ++] = AddJitGlobal (module, eltype, "globals");
7945 fields [tindex ++] = LLVMConstNull (eltype);
7946 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "assembly_name");
7947 if (!module->llvm_only) {
7948 fields [tindex ++] = AddJitGlobal (module, eltype, "plt");
7949 fields [tindex ++] = AddJitGlobal (module, eltype, "plt_end");
7950 fields [tindex ++] = AddJitGlobal (module, eltype, "unwind_info");
7951 fields [tindex ++] = AddJitGlobal (module, eltype, "unbox_trampolines");
7952 fields [tindex ++] = AddJitGlobal (module, eltype, "unbox_trampolines_end");
7953 fields [tindex ++] = AddJitGlobal (module, eltype, "unbox_trampoline_addresses");
7955 fields [tindex ++] = LLVMConstNull (eltype);
7956 fields [tindex ++] = LLVMConstNull (eltype);
7957 fields [tindex ++] = LLVMConstNull (eltype);
7958 fields [tindex ++] = LLVMConstNull (eltype);
7959 fields [tindex ++] = LLVMConstNull (eltype);
7960 fields [tindex ++] = LLVMConstNull (eltype);
7963 for (i = 0; i < MONO_AOT_FILE_INFO_NUM_SYMBOLS; ++i)
7964 fields [2 + i] = LLVMConstBitCast (fields [2 + i], eltype);
7967 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->plt_got_offset_base, FALSE);
7968 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->got_size, FALSE);
7969 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->plt_size, FALSE);
7970 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->nmethods, FALSE);
7971 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->flags, FALSE);
7972 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->opts, FALSE);
7973 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->simd_opts, FALSE);
7974 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->gc_name_index, FALSE);
7975 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->num_rgctx_fetch_trampolines, FALSE);
7976 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->double_align, FALSE);
7977 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->long_align, FALSE);
7978 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->generic_tramp_num, FALSE);
7979 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->tramp_page_size, FALSE);
7980 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->nshared_got_entries, FALSE);
7981 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->datafile_size, FALSE);
7983 fields [tindex ++] = llvm_array_from_uints (LLVMInt32Type (), info->table_offsets, MONO_AOT_TABLE_NUM);
7984 fields [tindex ++] = llvm_array_from_uints (LLVMInt32Type (), info->num_trampolines, MONO_AOT_TRAMP_NUM);
7985 fields [tindex ++] = llvm_array_from_uints (LLVMInt32Type (), info->trampoline_got_offset_base, MONO_AOT_TRAMP_NUM);
7986 fields [tindex ++] = llvm_array_from_uints (LLVMInt32Type (), info->trampoline_size, MONO_AOT_TRAMP_NUM);
7987 fields [tindex ++] = llvm_array_from_uints (LLVMInt32Type (), info->tramp_page_code_offsets, MONO_AOT_TRAMP_NUM);
7988 g_assert (tindex == nfields);
7990 LLVMSetInitializer (info_var, LLVMConstNamedStruct (file_info_type, fields, nfields));
7992 if (module->static_link) {
7996 s = g_strdup_printf ("mono_aot_module_%s_info", module->assembly->aname.name);
7997 /* Get rid of characters which cannot occur in symbols */
7999 for (p = s; *p; ++p) {
8000 if (!(isalnum (*p) || *p == '_'))
8003 var = LLVMAddGlobal (module->lmodule, LLVMPointerType (LLVMInt8Type (), 0), s);
8005 LLVMSetInitializer (var, LLVMConstBitCast (LLVMGetNamedGlobal (module->lmodule, "mono_aot_file_info"), LLVMPointerType (LLVMInt8Type (), 0)));
8006 LLVMSetLinkage (var, LLVMExternalLinkage);
8011 * Emit the aot module into the LLVM bitcode file FILENAME.
8014 mono_llvm_emit_aot_module (const char *filename, const char *cu_name)
8016 LLVMTypeRef got_type, inited_type;
8017 LLVMValueRef real_got, real_inited;
8018 MonoLLVMModule *module = &aot_module;
8020 emit_llvm_code_end (module);
8023 * Create the real got variable and replace all uses of the dummy variable with
8026 got_type = LLVMArrayType (module->ptr_type, module->max_got_offset + 1);
8027 real_got = LLVMAddGlobal (module->lmodule, got_type, module->got_symbol);
8028 LLVMSetInitializer (real_got, LLVMConstNull (got_type));
8029 if (module->external_symbols) {
8030 LLVMSetLinkage (real_got, LLVMExternalLinkage);
8031 LLVMSetVisibility (real_got, LLVMHiddenVisibility);
8033 LLVMSetLinkage (real_got, LLVMInternalLinkage);
8035 mono_llvm_replace_uses_of (module->got_var, real_got);
8037 mark_as_used (&aot_module, real_got);
8039 /* Delete the dummy got so it doesn't become a global */
8040 LLVMDeleteGlobal (module->got_var);
8041 module->got_var = real_got;
8044 * Same for the init_var
8046 if (module->llvm_only) {
8047 inited_type = LLVMArrayType (LLVMInt8Type (), module->max_inited_idx + 1);
8048 real_inited = LLVMAddGlobal (module->lmodule, inited_type, "mono_inited");
8049 LLVMSetInitializer (real_inited, LLVMConstNull (inited_type));
8050 LLVMSetLinkage (real_inited, LLVMInternalLinkage);
8051 mono_llvm_replace_uses_of (module->inited_var, real_inited);
8052 LLVMDeleteGlobal (module->inited_var);
8055 if (module->llvm_only) {
8056 emit_get_method (&aot_module);
8057 emit_get_unbox_tramp (&aot_module);
8060 emit_llvm_used (&aot_module);
8061 emit_dbg_info (&aot_module, filename, cu_name);
8062 emit_aot_file_info (&aot_module);
8065 * Replace GOT entries for directly callable methods with the methods themselves.
8066 * It would be easier to implement this by predefining all methods before compiling
8067 * their bodies, but that couldn't handle the case when a method fails to compile
8070 if (module->llvm_only) {
8071 GHashTableIter iter;
8073 GSList *callers, *l;
8075 g_hash_table_iter_init (&iter, module->method_to_callers);
8076 while (g_hash_table_iter_next (&iter, (void**)&method, (void**)&callers)) {
8077 LLVMValueRef lmethod;
8079 lmethod = (LLVMValueRef)g_hash_table_lookup (module->method_to_lmethod, method);
8081 for (l = callers; l; l = l->next) {
8082 LLVMValueRef caller = (LLVMValueRef)l->data;
8084 mono_llvm_replace_uses_of (caller, lmethod);
8090 /* Replace PLT entries for directly callable methods with the methods themselves */
8092 GHashTableIter iter;
8094 LLVMValueRef callee;
8096 g_hash_table_iter_init (&iter, module->plt_entries_ji);
8097 while (g_hash_table_iter_next (&iter, (void**)&ji, (void**)&callee)) {
8098 if (mono_aot_is_direct_callable (ji)) {
8099 LLVMValueRef lmethod;
8101 lmethod = (LLVMValueRef)g_hash_table_lookup (module->method_to_lmethod, ji->data.method);
8102 /* The types might not match because the caller might pass an rgctx */
8103 if (lmethod && LLVMTypeOf (callee) == LLVMTypeOf (lmethod)) {
8104 mono_llvm_replace_uses_of (callee, lmethod);
8105 mono_aot_mark_unused_llvm_plt_entry (ji);
8115 if (LLVMVerifyModule (module->lmodule, LLVMReturnStatusAction, &verifier_err)) {
8116 g_assert_not_reached ();
8121 LLVMWriteBitcodeToFile (module->lmodule, filename);
8126 md_string (const char *s)
8128 return LLVMMDString (s, strlen (s));
8131 /* Debugging support */
8134 emit_dbg_info (MonoLLVMModule *module, const char *filename, const char *cu_name)
8136 LLVMModuleRef lmodule = module->lmodule;
8137 LLVMValueRef args [16], ver;
8140 * This can only be enabled when LLVM code is emitted into a separate object
8141 * file, since the AOT compiler also emits dwarf info,
8142 * and the abbrev indexes will not be correct since llvm has added its own
8145 if (!module->emit_dwarf)
8148 #if LLVM_API_VERSION > 100
8149 mono_llvm_di_builder_finalize (module->di_builder);
8151 LLVMValueRef cu_args [16], cu;
8153 char *build_info, *s, *dir;
8156 * Emit dwarf info in the form of LLVM metadata. There is some
8157 * out-of-date documentation at:
8158 * http://llvm.org/docs/SourceLevelDebugging.html
8159 * but most of this was gathered from the llvm and
8164 cu_args [n_cuargs ++] = LLVMConstInt (LLVMInt32Type (), DW_TAG_compile_unit, FALSE);
8165 /* CU name/compilation dir */
8166 dir = g_path_get_dirname (filename);
8167 args [0] = LLVMMDString (cu_name, strlen (cu_name));
8168 args [1] = LLVMMDString (dir, strlen (dir));
8169 cu_args [n_cuargs ++] = LLVMMDNode (args, 2);
8172 cu_args [n_cuargs ++] = LLVMConstInt (LLVMInt32Type (), DW_LANG_C99, FALSE);
8174 build_info = mono_get_runtime_build_info ();
8175 s = g_strdup_printf ("Mono AOT Compiler %s (LLVM)", build_info);
8176 cu_args [n_cuargs ++] = LLVMMDString (s, strlen (s));
8177 g_free (build_info);
8179 cu_args [n_cuargs ++] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
8181 cu_args [n_cuargs ++] = LLVMMDString ("", strlen (""));
8182 /* Runtime version */
8183 cu_args [n_cuargs ++] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
8185 cu_args [n_cuargs ++] = LLVMMDNode (args, 0);
8186 cu_args [n_cuargs ++] = LLVMMDNode (args, 0);
8188 if (module->subprogram_mds) {
8192 mds = g_new0 (LLVMValueRef, module->subprogram_mds->len);
8193 for (i = 0; i < module->subprogram_mds->len; ++i)
8194 mds [i] = (LLVMValueRef)g_ptr_array_index (module->subprogram_mds, i);
8195 cu_args [n_cuargs ++] = LLVMMDNode (mds, module->subprogram_mds->len);
8197 cu_args [n_cuargs ++] = LLVMMDNode (args, 0);
8200 cu_args [n_cuargs ++] = LLVMMDNode (args, 0);
8201 /* Imported modules */
8202 cu_args [n_cuargs ++] = LLVMMDNode (args, 0);
8204 cu_args [n_cuargs ++] = LLVMMDString ("", strlen (""));
8205 /* DebugEmissionKind = FullDebug */
8206 cu_args [n_cuargs ++] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
8207 cu = LLVMMDNode (cu_args, n_cuargs);
8208 LLVMAddNamedMetadataOperand (lmodule, "llvm.dbg.cu", cu);
8211 #if LLVM_API_VERSION > 100
8212 args [0] = LLVMConstInt (LLVMInt32Type (), 2, FALSE);
8213 args [1] = LLVMMDString ("Dwarf Version", strlen ("Dwarf Version"));
8214 args [2] = LLVMConstInt (LLVMInt32Type (), 2, FALSE);
8215 ver = LLVMMDNode (args, 3);
8216 LLVMAddNamedMetadataOperand (lmodule, "llvm.module.flags", ver);
8218 args [0] = LLVMConstInt (LLVMInt32Type (), 2, FALSE);
8219 args [1] = LLVMMDString ("Debug Info Version", strlen ("Debug Info Version"));
8220 args [2] = LLVMConstInt (LLVMInt64Type (), 3, FALSE);
8221 ver = LLVMMDNode (args, 3);
8222 LLVMAddNamedMetadataOperand (lmodule, "llvm.module.flags", ver);
8224 args [0] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
8225 args [1] = LLVMMDString ("Dwarf Version", strlen ("Dwarf Version"));
8226 args [2] = LLVMConstInt (LLVMInt32Type (), 2, FALSE);
8227 ver = LLVMMDNode (args, 3);
8228 LLVMAddNamedMetadataOperand (lmodule, "llvm.module.flags", ver);
8230 args [0] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
8231 args [1] = LLVMMDString ("Debug Info Version", strlen ("Debug Info Version"));
8232 args [2] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
8233 ver = LLVMMDNode (args, 3);
8234 LLVMAddNamedMetadataOperand (lmodule, "llvm.module.flags", ver);
8239 emit_dbg_subprogram (EmitContext *ctx, MonoCompile *cfg, LLVMValueRef method, const char *name)
8241 MonoLLVMModule *module = ctx->module;
8242 MonoDebugMethodInfo *minfo = ctx->minfo;
8243 char *source_file, *dir, *filename;
8244 LLVMValueRef md, args [16], ctx_args [16], md_args [64], type_args [16], ctx_md, type_md;
8245 MonoSymSeqPoint *sym_seq_points;
8251 mono_debug_symfile_get_seq_points (minfo, &source_file, NULL, NULL, &sym_seq_points, &n_seq_points);
8253 source_file = g_strdup ("<unknown>");
8254 dir = g_path_get_dirname (source_file);
8255 filename = g_path_get_basename (source_file);
8257 #if LLVM_API_VERSION > 100
8258 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);
8261 ctx_args [0] = LLVMConstInt (LLVMInt32Type (), 0x29, FALSE);
8262 args [0] = md_string (filename);
8263 args [1] = md_string (dir);
8264 ctx_args [1] = LLVMMDNode (args, 2);
8265 ctx_md = LLVMMDNode (ctx_args, 2);
8267 type_args [0] = LLVMConstInt (LLVMInt32Type (), DW_TAG_subroutine_type, FALSE);
8268 type_args [1] = NULL;
8269 type_args [2] = NULL;
8270 type_args [3] = LLVMMDString ("", 0);
8271 type_args [4] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
8272 type_args [5] = LLVMConstInt (LLVMInt64Type (), 0, FALSE);
8273 type_args [6] = LLVMConstInt (LLVMInt64Type (), 0, FALSE);
8274 type_args [7] = LLVMConstInt (LLVMInt64Type (), 0, FALSE);
8275 type_args [8] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
8276 type_args [9] = NULL;
8277 type_args [10] = NULL;
8278 type_args [11] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
8279 type_args [12] = NULL;
8280 type_args [13] = NULL;
8281 type_args [14] = NULL;
8282 type_md = LLVMMDNode (type_args, 14);
8284 /* http://llvm.org/docs/SourceLevelDebugging.html#subprogram-descriptors */
8285 md_args [0] = LLVMConstInt (LLVMInt32Type (), DW_TAG_subprogram, FALSE);
8286 /* Source directory + file pair */
8287 args [0] = md_string (filename);
8288 args [1] = md_string (dir);
8289 md_args [1] = LLVMMDNode (args ,2);
8290 md_args [2] = ctx_md;
8291 md_args [3] = md_string (cfg->method->name);
8292 md_args [4] = md_string (name);
8293 md_args [5] = md_string (name);
8296 md_args [6] = LLVMConstInt (LLVMInt32Type (), sym_seq_points [0].line, FALSE);
8298 md_args [6] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
8300 md_args [7] = type_md;
8302 md_args [8] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
8304 md_args [9] = LLVMConstInt (LLVMInt1Type (), 1, FALSE);
8306 md_args [10] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
8307 /* Index into a virtual function */
8308 md_args [11] = NULL;
8309 md_args [12] = NULL;
8311 md_args [13] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
8313 md_args [14] = LLVMConstInt (LLVMInt1Type (), 1, FALSE);
8314 /* Pointer to LLVM function */
8315 md_args [15] = method;
8316 /* Function template parameter */
8317 md_args [16] = NULL;
8318 /* Function declaration descriptor */
8319 md_args [17] = NULL;
8320 /* List of function variables */
8321 md_args [18] = LLVMMDNode (args, 0);
8323 md_args [19] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
8324 md = LLVMMDNode (md_args, 20);
8326 if (!module->subprogram_mds)
8327 module->subprogram_mds = g_ptr_array_new ();
8328 g_ptr_array_add (module->subprogram_mds, md);
8332 g_free (source_file);
8333 g_free (sym_seq_points);
8339 emit_dbg_loc (EmitContext *ctx, LLVMBuilderRef builder, const unsigned char *cil_code)
8341 MonoCompile *cfg = ctx->cfg;
8343 if (ctx->minfo && cil_code && cil_code >= cfg->header->code && cil_code < cfg->header->code + cfg->header->code_size) {
8344 MonoDebugSourceLocation *loc;
8345 LLVMValueRef loc_md;
8347 loc = mono_debug_symfile_lookup_location (ctx->minfo, cil_code - cfg->header->code);
8350 #if LLVM_API_VERSION > 100
8351 loc_md = mono_llvm_di_create_location (ctx->module->di_builder, ctx->dbg_md, loc->row, loc->column);
8352 mono_llvm_di_set_location (builder, loc_md);
8354 LLVMValueRef md_args [16];
8358 md_args [nmd_args ++] = LLVMConstInt (LLVMInt32Type (), loc->row, FALSE);
8359 md_args [nmd_args ++] = LLVMConstInt (LLVMInt32Type (), loc->column, FALSE);
8360 md_args [nmd_args ++] = ctx->dbg_md;
8361 md_args [nmd_args ++] = NULL;
8362 loc_md = LLVMMDNode (md_args, nmd_args);
8363 LLVMSetCurrentDebugLocation (builder, loc_md);
8365 mono_debug_symfile_free_location (loc);
8371 default_mono_llvm_unhandled_exception (void)
8373 MonoJitTlsData *jit_tls = mono_get_jit_tls ();
8374 MonoObject *target = mono_gchandle_get_target (jit_tls->thrown_exc);
8376 mono_unhandled_exception (target);
8377 exit (mono_environment_exitcode_get ());
8382 - Emit LLVM IR from the mono IR using the LLVM C API.
8383 - The original arch specific code remains, so we can fall back to it if we run
8384 into something we can't handle.
8388 A partial list of issues:
8389 - Handling of opcodes which can throw exceptions.
8391 In the mono JIT, these are implemented using code like this:
8398 push throw_pos - method
8399 call <exception trampoline>
8401 The problematic part is push throw_pos - method, which cannot be represented
8402 in the LLVM IR, since it does not support label values.
8403 -> this can be implemented in AOT mode using inline asm + labels, but cannot
8404 be implemented in JIT mode ?
8405 -> a possible but slower implementation would use the normal exception
8406 throwing code but it would need to control the placement of the throw code
8407 (it needs to be exactly after the compare+branch).
8408 -> perhaps add a PC offset intrinsics ?
8410 - efficient implementation of .ovf opcodes.
8412 These are currently implemented as:
8413 <ins which sets the condition codes>
8416 Some overflow opcodes are now supported by LLVM SVN.
8418 - exception handling, unwinding.
8419 - SSA is disabled for methods with exception handlers
8420 - How to obtain unwind info for LLVM compiled methods ?
8421 -> this is now solved by converting the unwind info generated by LLVM
8423 - LLVM uses the c++ exception handling framework, while we use our home grown
8424 code, and couldn't use the c++ one:
8425 - its not supported under VC++, other exotic platforms.
8426 - it might be impossible to support filter clauses with it.
8430 The trampolines need a predictable call sequence, since they need to disasm
8431 the calling code to obtain register numbers / offsets.
8433 LLVM currently generates this code in non-JIT mode:
8434 mov -0x98(%rax),%eax
8436 Here, the vtable pointer is lost.
8437 -> solution: use one vtable trampoline per class.
8439 - passing/receiving the IMT pointer/RGCTX.
8440 -> solution: pass them as normal arguments ?
8444 LLVM does not allow the specification of argument registers etc. This means
8445 that all calls are made according to the platform ABI.
8447 - passing/receiving vtypes.
8449 Vtypes passed/received in registers are handled by the front end by using
8450 a signature with scalar arguments, and loading the parts of the vtype into those
8453 Vtypes passed on the stack are handled using the 'byval' attribute.
8457 Supported though alloca, we need to emit the load/store code.
8461 The mono JIT uses pointer sized iregs/double fregs, while LLVM uses precisely
8462 typed registers, so we have to keep track of the precise LLVM type of each vreg.
8463 This is made easier because the IR is already in SSA form.
8464 An additional problem is that our IR is not consistent with types, i.e. i32/ia64
8465 types are frequently used incorrectly.
8470 Emit LLVM bytecode into a .bc file, compile it using llc into a .s file, then link
8471 it with the file containing the methods emitted by the JIT and the AOT data
8475 /* FIXME: Normalize some aspects of the mono IR to allow easier translation, like:
8476 * - each bblock should end with a branch
8477 * - setting the return value, making cfg->ret non-volatile
8478 * - avoid some transformations in the JIT which make it harder for us to generate
8480 * - use pointer types to help optimizations.