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;
97 * Information associated by the backend with mono basic blocks.
100 LLVMBasicBlockRef bblock, end_bblock;
101 LLVMValueRef finally_ind;
102 gboolean added, invoke_target;
104 * If this bblock is the start of a finally clause, this is a list of bblocks it
105 * needs to branch to in ENDFINALLY.
107 GSList *call_handler_return_bbs;
109 * If this bblock is the start of a finally clause, this is the bblock that
110 * CALL_HANDLER needs to branch to.
112 LLVMBasicBlockRef call_handler_target_bb;
113 /* The list of switch statements generated by ENDFINALLY instructions */
114 GSList *endfinally_switch_ins_list;
119 * Structure containing emit state
122 MonoMemPool *mempool;
124 /* Maps method names to the corresponding LLVMValueRef */
125 GHashTable *emitted_method_decls;
128 LLVMValueRef lmethod;
129 MonoLLVMModule *module;
130 LLVMModuleRef lmodule;
132 int sindex, default_index, ex_index;
133 LLVMBuilderRef builder;
134 LLVMValueRef *values, *addresses;
135 MonoType **vreg_cli_types;
137 MonoMethodSignature *sig;
139 GHashTable *region_to_handler;
140 GHashTable *clause_to_handler;
141 LLVMBuilderRef alloca_builder;
142 LLVMValueRef last_alloca;
143 LLVMValueRef rgctx_arg;
144 LLVMValueRef this_arg;
145 LLVMTypeRef *vreg_types;
146 LLVMBasicBlockRef init_bb, inited_bb;
148 gboolean *unreachable;
150 gboolean has_got_access;
151 int this_arg_pindex, rgctx_arg_pindex;
152 LLVMValueRef imt_rgctx_loc;
153 GHashTable *llvm_types;
155 MonoDebugMethodInfo *minfo;
157 /* For every clause, the clauses it is nested in */
160 GHashTable *exc_meta;
161 GHashTable *method_to_callers;
167 MonoBasicBlock *in_bb;
172 * Instruction metadata
173 * This is the same as ins_info, but LREG != IREG.
181 #define MINI_OP(a,b,dest,src1,src2) dest, src1, src2, ' ',
182 #define MINI_OP3(a,b,dest,src1,src2,src3) dest, src1, src2, src3,
189 /* keep in sync with the enum in mini.h */
192 #include "mini-ops.h"
197 #if SIZEOF_VOID_P == 4
198 #define GET_LONG_IMM(ins) (((guint64)(ins)->inst_ms_word << 32) | (guint64)(guint32)(ins)->inst_ls_word)
200 #define GET_LONG_IMM(ins) ((ins)->inst_imm)
203 #define LLVM_INS_INFO(opcode) (&llvm_ins_info [((opcode) - OP_START - 1) * 4])
206 #define TRACE_FAILURE(msg) do { printf ("%s\n", msg); } while (0)
208 #define TRACE_FAILURE(msg)
212 #define IS_TARGET_X86 1
214 #define IS_TARGET_X86 0
218 #define IS_TARGET_AMD64 1
220 #define IS_TARGET_AMD64 0
223 #define LLVM_FAILURE(ctx, reason) do { \
224 TRACE_FAILURE (reason); \
225 (ctx)->cfg->exception_message = g_strdup (reason); \
226 (ctx)->cfg->disable_llvm = TRUE; \
230 #define CHECK_FAILURE(ctx) do { \
231 if ((ctx)->cfg->disable_llvm) \
235 static LLVMIntPredicate cond_to_llvm_cond [] = {
248 static LLVMRealPredicate fpcond_to_llvm_cond [] = {
261 static MonoNativeTlsKey current_cfg_tls_id;
263 static MonoLLVMModule aot_module;
264 static int memset_param_count, memcpy_param_count;
265 static const char *memset_func_name;
266 static const char *memcpy_func_name;
268 static void init_jit_module (MonoDomain *domain);
270 static void emit_dbg_loc (EmitContext *ctx, LLVMBuilderRef builder, const unsigned char *cil_code);
271 static LLVMValueRef emit_dbg_subprogram (EmitContext *ctx, MonoCompile *cfg, LLVMValueRef method, const char *name);
272 static void emit_dbg_info (MonoLLVMModule *module, const char *filename, const char *cu_name);
277 * The LLVM type with width == sizeof (gpointer)
282 return sizeof (gpointer) == 8 ? LLVMInt64Type () : LLVMInt32Type ();
288 return sizeof (gpointer) == 8 ? LLVMPointerType (LLVMInt64Type (), 0) : LLVMPointerType (LLVMInt32Type (), 0);
294 return sizeof (gpointer) == 8 ? LLVMPointerType (LLVMInt64Type (), 0) : LLVMPointerType (LLVMInt32Type (), 0);
300 * Return the size of the LLVM representation of the vtype T.
303 get_vtype_size (MonoType *t)
307 size = mono_class_value_size (mono_class_from_mono_type (t), NULL);
309 /* LLVMArgAsIArgs depends on this since it stores whole words */
310 while (size < 2 * sizeof (gpointer) && mono_is_power_of_two (size) == -1)
317 * simd_class_to_llvm_type:
319 * Return the LLVM type corresponding to the Mono.SIMD class KLASS
322 simd_class_to_llvm_type (EmitContext *ctx, MonoClass *klass)
324 if (!strcmp (klass->name, "Vector2d")) {
325 return LLVMVectorType (LLVMDoubleType (), 2);
326 } else if (!strcmp (klass->name, "Vector2l")) {
327 return LLVMVectorType (LLVMInt64Type (), 2);
328 } else if (!strcmp (klass->name, "Vector2ul")) {
329 return LLVMVectorType (LLVMInt64Type (), 2);
330 } else if (!strcmp (klass->name, "Vector4i")) {
331 return LLVMVectorType (LLVMInt32Type (), 4);
332 } else if (!strcmp (klass->name, "Vector4ui")) {
333 return LLVMVectorType (LLVMInt32Type (), 4);
334 } else if (!strcmp (klass->name, "Vector4f")) {
335 return LLVMVectorType (LLVMFloatType (), 4);
336 } else if (!strcmp (klass->name, "Vector8s")) {
337 return LLVMVectorType (LLVMInt16Type (), 8);
338 } else if (!strcmp (klass->name, "Vector8us")) {
339 return LLVMVectorType (LLVMInt16Type (), 8);
340 } else if (!strcmp (klass->name, "Vector16sb")) {
341 return LLVMVectorType (LLVMInt8Type (), 16);
342 } else if (!strcmp (klass->name, "Vector16b")) {
343 return LLVMVectorType (LLVMInt8Type (), 16);
345 printf ("%s\n", klass->name);
351 /* Return the 128 bit SIMD type corresponding to the mono type TYPE */
352 static inline G_GNUC_UNUSED LLVMTypeRef
353 type_to_simd_type (int type)
357 return LLVMVectorType (LLVMInt8Type (), 16);
359 return LLVMVectorType (LLVMInt16Type (), 8);
361 return LLVMVectorType (LLVMInt32Type (), 4);
363 return LLVMVectorType (LLVMInt64Type (), 2);
365 return LLVMVectorType (LLVMDoubleType (), 2);
367 return LLVMVectorType (LLVMFloatType (), 4);
369 g_assert_not_reached ();
375 create_llvm_type_for_type (MonoLLVMModule *module, MonoClass *klass)
377 int i, size, nfields, esize;
378 LLVMTypeRef *eltypes;
383 t = &klass->byval_arg;
385 if (mini_type_is_hfa (t, &nfields, &esize)) {
387 * This is needed on arm64 where HFAs are returned in
391 eltypes = g_new (LLVMTypeRef, size);
392 for (i = 0; i < size; ++i)
393 eltypes [i] = esize == 4 ? LLVMFloatType () : LLVMDoubleType ();
395 size = get_vtype_size (t);
397 eltypes = g_new (LLVMTypeRef, size);
398 for (i = 0; i < size; ++i)
399 eltypes [i] = LLVMInt8Type ();
402 name = mono_type_full_name (&klass->byval_arg);
403 ltype = LLVMStructCreateNamed (module->context, name);
404 LLVMStructSetBody (ltype, eltypes, size, FALSE);
414 * Return the LLVM type corresponding to T.
417 type_to_llvm_type (EmitContext *ctx, MonoType *t)
419 t = mini_get_underlying_type (t);
423 return LLVMVoidType ();
425 return LLVMInt8Type ();
427 return LLVMInt16Type ();
429 return LLVMInt32Type ();
431 return LLVMInt8Type ();
433 return LLVMInt16Type ();
435 return LLVMInt32Type ();
436 case MONO_TYPE_BOOLEAN:
437 return LLVMInt8Type ();
440 return LLVMInt64Type ();
442 return LLVMInt16Type ();
444 return LLVMFloatType ();
446 return LLVMDoubleType ();
449 return IntPtrType ();
450 case MONO_TYPE_OBJECT:
451 case MONO_TYPE_CLASS:
452 case MONO_TYPE_ARRAY:
453 case MONO_TYPE_SZARRAY:
454 case MONO_TYPE_STRING:
456 return ObjRefType ();
459 /* Because of generic sharing */
460 return ObjRefType ();
461 case MONO_TYPE_GENERICINST:
462 if (!mono_type_generic_inst_is_valuetype (t))
463 return ObjRefType ();
465 case MONO_TYPE_VALUETYPE:
466 case MONO_TYPE_TYPEDBYREF: {
470 klass = mono_class_from_mono_type (t);
472 if (MONO_CLASS_IS_SIMD (ctx->cfg, klass))
473 return simd_class_to_llvm_type (ctx, klass);
476 return type_to_llvm_type (ctx, mono_class_enum_basetype (klass));
478 ltype = (LLVMTypeRef)g_hash_table_lookup (ctx->module->llvm_types, klass);
480 ltype = create_llvm_type_for_type (ctx->module, klass);
481 g_hash_table_insert (ctx->module->llvm_types, klass, ltype);
487 printf ("X: %d\n", t->type);
488 ctx->cfg->exception_message = g_strdup_printf ("type %s", mono_type_full_name (t));
489 ctx->cfg->disable_llvm = TRUE;
497 * Return whenever T is an unsigned int type.
500 type_is_unsigned (EmitContext *ctx, MonoType *t)
517 * type_to_llvm_arg_type:
519 * Same as type_to_llvm_type, but treat i8/i16 as i32.
522 type_to_llvm_arg_type (EmitContext *ctx, MonoType *t)
524 LLVMTypeRef ptype = type_to_llvm_type (ctx, t);
526 if (ctx->cfg->llvm_only)
530 * This works on all abis except arm64/ios which passes multiple
531 * arguments in one stack slot.
534 if (ptype == LLVMInt8Type () || ptype == LLVMInt16Type ()) {
536 * LLVM generates code which only sets the lower bits, while JITted
537 * code expects all the bits to be set.
539 ptype = LLVMInt32Type ();
547 * llvm_type_to_stack_type:
549 * Return the LLVM type which needs to be used when a value of type TYPE is pushed
552 static G_GNUC_UNUSED LLVMTypeRef
553 llvm_type_to_stack_type (MonoCompile *cfg, LLVMTypeRef type)
557 if (type == LLVMInt8Type ())
558 return LLVMInt32Type ();
559 else if (type == LLVMInt16Type ())
560 return LLVMInt32Type ();
561 else if (!cfg->r4fp && type == LLVMFloatType ())
562 return LLVMDoubleType ();
568 * regtype_to_llvm_type:
570 * Return the LLVM type corresponding to the regtype C used in instruction
574 regtype_to_llvm_type (char c)
578 return LLVMInt32Type ();
580 return LLVMInt64Type ();
582 return LLVMDoubleType ();
591 * Return the LLVM type corresponding to the unary/binary opcode OPCODE.
594 op_to_llvm_type (int opcode)
599 return LLVMInt8Type ();
602 return LLVMInt8Type ();
605 return LLVMInt16Type ();
608 return LLVMInt16Type ();
611 return LLVMInt32Type ();
614 return LLVMInt32Type ();
616 return LLVMInt64Type ();
618 return LLVMFloatType ();
620 return LLVMDoubleType ();
622 return LLVMInt64Type ();
624 return LLVMInt32Type ();
626 return LLVMInt64Type ();
631 return LLVMInt8Type ();
636 return LLVMInt16Type ();
638 return LLVMInt32Type ();
641 return sizeof (gpointer) == 8 ? LLVMInt64Type () : LLVMInt32Type ();
648 return LLVMInt32Type ();
655 return LLVMInt64Type ();
657 printf ("%s\n", mono_inst_name (opcode));
658 g_assert_not_reached ();
663 #define CLAUSE_START(clause) ((clause)->try_offset)
664 #define CLAUSE_END(clause) (((clause))->try_offset + ((clause))->try_len)
667 * load_store_to_llvm_type:
669 * Return the size/sign/zero extension corresponding to the load/store opcode
673 load_store_to_llvm_type (int opcode, int *size, gboolean *sext, gboolean *zext)
679 case OP_LOADI1_MEMBASE:
680 case OP_STOREI1_MEMBASE_REG:
681 case OP_STOREI1_MEMBASE_IMM:
682 case OP_ATOMIC_LOAD_I1:
683 case OP_ATOMIC_STORE_I1:
686 return LLVMInt8Type ();
687 case OP_LOADU1_MEMBASE:
689 case OP_ATOMIC_LOAD_U1:
690 case OP_ATOMIC_STORE_U1:
693 return LLVMInt8Type ();
694 case OP_LOADI2_MEMBASE:
695 case OP_STOREI2_MEMBASE_REG:
696 case OP_STOREI2_MEMBASE_IMM:
697 case OP_ATOMIC_LOAD_I2:
698 case OP_ATOMIC_STORE_I2:
701 return LLVMInt16Type ();
702 case OP_LOADU2_MEMBASE:
704 case OP_ATOMIC_LOAD_U2:
705 case OP_ATOMIC_STORE_U2:
708 return LLVMInt16Type ();
709 case OP_LOADI4_MEMBASE:
710 case OP_LOADU4_MEMBASE:
713 case OP_STOREI4_MEMBASE_REG:
714 case OP_STOREI4_MEMBASE_IMM:
715 case OP_ATOMIC_LOAD_I4:
716 case OP_ATOMIC_STORE_I4:
717 case OP_ATOMIC_LOAD_U4:
718 case OP_ATOMIC_STORE_U4:
720 return LLVMInt32Type ();
721 case OP_LOADI8_MEMBASE:
723 case OP_STOREI8_MEMBASE_REG:
724 case OP_STOREI8_MEMBASE_IMM:
725 case OP_ATOMIC_LOAD_I8:
726 case OP_ATOMIC_STORE_I8:
727 case OP_ATOMIC_LOAD_U8:
728 case OP_ATOMIC_STORE_U8:
730 return LLVMInt64Type ();
731 case OP_LOADR4_MEMBASE:
732 case OP_STORER4_MEMBASE_REG:
733 case OP_ATOMIC_LOAD_R4:
734 case OP_ATOMIC_STORE_R4:
736 return LLVMFloatType ();
737 case OP_LOADR8_MEMBASE:
738 case OP_STORER8_MEMBASE_REG:
739 case OP_ATOMIC_LOAD_R8:
740 case OP_ATOMIC_STORE_R8:
742 return LLVMDoubleType ();
743 case OP_LOAD_MEMBASE:
745 case OP_STORE_MEMBASE_REG:
746 case OP_STORE_MEMBASE_IMM:
747 *size = sizeof (gpointer);
748 return IntPtrType ();
750 g_assert_not_reached ();
758 * Return the LLVM intrinsics corresponding to the overflow opcode OPCODE.
761 ovf_op_to_intrins (int opcode)
765 return "llvm.sadd.with.overflow.i32";
767 return "llvm.uadd.with.overflow.i32";
769 return "llvm.ssub.with.overflow.i32";
771 return "llvm.usub.with.overflow.i32";
773 return "llvm.smul.with.overflow.i32";
775 return "llvm.umul.with.overflow.i32";
777 return "llvm.sadd.with.overflow.i64";
779 return "llvm.uadd.with.overflow.i64";
781 return "llvm.ssub.with.overflow.i64";
783 return "llvm.usub.with.overflow.i64";
785 return "llvm.smul.with.overflow.i64";
787 return "llvm.umul.with.overflow.i64";
789 g_assert_not_reached ();
795 simd_op_to_intrins (int opcode)
798 #if defined(TARGET_X86) || defined(TARGET_AMD64)
800 return "llvm.x86.sse2.min.pd";
802 return "llvm.x86.sse.min.ps";
804 return "llvm.x86.sse41.pminud";
806 return "llvm.x86.sse41.pminuw";
808 return "llvm.x86.sse2.pminu.b";
810 return "llvm.x86.sse2.pmins.w";
812 return "llvm.x86.sse2.max.pd";
814 return "llvm.x86.sse.max.ps";
816 return "llvm.x86.sse3.hadd.pd";
818 return "llvm.x86.sse3.hadd.ps";
820 return "llvm.x86.sse3.hsub.pd";
822 return "llvm.x86.sse3.hsub.ps";
824 return "llvm.x86.sse41.pmaxud";
826 return "llvm.x86.sse41.pmaxuw";
828 return "llvm.x86.sse2.pmaxu.b";
830 return "llvm.x86.sse3.addsub.ps";
832 return "llvm.x86.sse3.addsub.pd";
833 case OP_EXTRACT_MASK:
834 return "llvm.x86.sse2.pmovmskb.128";
837 return "llvm.x86.sse2.psrli.w";
840 return "llvm.x86.sse2.psrli.d";
843 return "llvm.x86.sse2.psrli.q";
846 return "llvm.x86.sse2.pslli.w";
849 return "llvm.x86.sse2.pslli.d";
852 return "llvm.x86.sse2.pslli.q";
855 return "llvm.x86.sse2.psrai.w";
858 return "llvm.x86.sse2.psrai.d";
860 return "llvm.x86.sse2.padds.b";
862 return "llvm.x86.sse2.padds.w";
864 return "llvm.x86.sse2.psubs.b";
866 return "llvm.x86.sse2.psubs.w";
867 case OP_PADDB_SAT_UN:
868 return "llvm.x86.sse2.paddus.b";
869 case OP_PADDW_SAT_UN:
870 return "llvm.x86.sse2.paddus.w";
871 case OP_PSUBB_SAT_UN:
872 return "llvm.x86.sse2.psubus.b";
873 case OP_PSUBW_SAT_UN:
874 return "llvm.x86.sse2.psubus.w";
876 return "llvm.x86.sse2.pavg.b";
878 return "llvm.x86.sse2.pavg.w";
880 return "llvm.x86.sse.sqrt.ps";
882 return "llvm.x86.sse2.sqrt.pd";
884 return "llvm.x86.sse.rsqrt.ps";
886 return "llvm.x86.sse.rcp.ps";
888 return "llvm.x86.sse2.cvtdq2pd";
890 return "llvm.x86.sse2.cvtdq2ps";
892 return "llvm.x86.sse2.cvtpd2dq";
894 return "llvm.x86.sse2.cvtps2dq";
896 return "llvm.x86.sse2.cvtpd2ps";
898 return "llvm.x86.sse2.cvtps2pd";
900 return "llvm.x86.sse2.cvttpd2dq";
902 return "llvm.x86.sse2.cvttps2dq";
904 return "llvm.x86.sse.cmp.ps";
906 return "llvm.x86.sse2.cmp.pd";
908 return "llvm.x86.sse2.packsswb.128";
910 return "llvm.x86.sse2.packssdw.128";
912 return "llvm.x86.sse2.packuswb.128";
914 return "llvm.x86.sse41.packusdw";
916 return "llvm.x86.sse2.pmulh.w";
917 case OP_PMULW_HIGH_UN:
918 return "llvm.x86.sse2.pmulhu.w";
921 g_assert_not_reached ();
927 simd_op_to_llvm_type (int opcode)
929 #if defined(TARGET_X86) || defined(TARGET_AMD64)
933 return type_to_simd_type (MONO_TYPE_R8);
936 return type_to_simd_type (MONO_TYPE_I8);
939 return type_to_simd_type (MONO_TYPE_I4);
944 return type_to_simd_type (MONO_TYPE_I2);
948 return type_to_simd_type (MONO_TYPE_I1);
950 return type_to_simd_type (MONO_TYPE_R4);
953 return type_to_simd_type (MONO_TYPE_I4);
957 return type_to_simd_type (MONO_TYPE_R8);
961 return type_to_simd_type (MONO_TYPE_R4);
962 case OP_EXTRACT_MASK:
963 return type_to_simd_type (MONO_TYPE_I1);
969 return type_to_simd_type (MONO_TYPE_R4);
972 return type_to_simd_type (MONO_TYPE_R8);
974 g_assert_not_reached ();
985 * Return the LLVM basic block corresponding to BB.
987 static LLVMBasicBlockRef
988 get_bb (EmitContext *ctx, MonoBasicBlock *bb)
990 char bb_name_buf [128];
993 if (ctx->bblocks [bb->block_num].bblock == NULL) {
994 if (bb->flags & BB_EXCEPTION_HANDLER) {
995 int clause_index = (mono_get_block_region_notry (ctx->cfg, bb->region) >> 8) - 1;
996 sprintf (bb_name_buf, "EH_CLAUSE%d_BB%d", clause_index, bb->block_num);
997 bb_name = bb_name_buf;
998 } else if (bb->block_num < 256) {
999 if (!ctx->module->bb_names) {
1000 ctx->module->bb_names_len = 256;
1001 ctx->module->bb_names = g_new0 (char*, ctx->module->bb_names_len);
1003 if (!ctx->module->bb_names [bb->block_num]) {
1006 n = g_strdup_printf ("BB%d", bb->block_num);
1007 mono_memory_barrier ();
1008 ctx->module->bb_names [bb->block_num] = n;
1010 bb_name = ctx->module->bb_names [bb->block_num];
1012 sprintf (bb_name_buf, "BB%d", bb->block_num);
1013 bb_name = bb_name_buf;
1016 ctx->bblocks [bb->block_num].bblock = LLVMAppendBasicBlock (ctx->lmethod, bb_name);
1017 ctx->bblocks [bb->block_num].end_bblock = ctx->bblocks [bb->block_num].bblock;
1020 return ctx->bblocks [bb->block_num].bblock;
1026 * Return the last LLVM bblock corresponding to BB.
1027 * This might not be equal to the bb returned by get_bb () since we need to generate
1028 * multiple LLVM bblocks for a mono bblock to handle throwing exceptions.
1030 static LLVMBasicBlockRef
1031 get_end_bb (EmitContext *ctx, MonoBasicBlock *bb)
1034 return ctx->bblocks [bb->block_num].end_bblock;
1037 static LLVMBasicBlockRef
1038 gen_bb (EmitContext *ctx, const char *prefix)
1042 sprintf (bb_name, "%s%d", prefix, ++ ctx->ex_index);
1043 return LLVMAppendBasicBlock (ctx->lmethod, bb_name);
1049 * Return the target of the patch identified by TYPE and TARGET.
1052 resolve_patch (MonoCompile *cfg, MonoJumpInfoType type, gconstpointer target)
1056 memset (&ji, 0, sizeof (ji));
1058 ji.data.target = target;
1060 return mono_resolve_patch_target (cfg->method, cfg->domain, NULL, &ji, FALSE);
1066 * Emit code to convert the LLVM value V to DTYPE.
1069 convert_full (EmitContext *ctx, LLVMValueRef v, LLVMTypeRef dtype, gboolean is_unsigned)
1071 LLVMTypeRef stype = LLVMTypeOf (v);
1073 if (stype != dtype) {
1074 gboolean ext = FALSE;
1077 if (dtype == LLVMInt64Type () && (stype == LLVMInt32Type () || stype == LLVMInt16Type () || stype == LLVMInt8Type ()))
1079 else if (dtype == LLVMInt32Type () && (stype == LLVMInt16Type () || stype == LLVMInt8Type ()))
1081 else if (dtype == LLVMInt16Type () && (stype == LLVMInt8Type ()))
1085 return is_unsigned ? LLVMBuildZExt (ctx->builder, v, dtype, "") : LLVMBuildSExt (ctx->builder, v, dtype, "");
1087 if (dtype == LLVMDoubleType () && stype == LLVMFloatType ())
1088 return LLVMBuildFPExt (ctx->builder, v, dtype, "");
1091 if (stype == LLVMInt64Type () && (dtype == LLVMInt32Type () || dtype == LLVMInt16Type () || dtype == LLVMInt8Type ()))
1092 return LLVMBuildTrunc (ctx->builder, v, dtype, "");
1093 if (stype == LLVMInt32Type () && (dtype == LLVMInt16Type () || dtype == LLVMInt8Type ()))
1094 return LLVMBuildTrunc (ctx->builder, v, dtype, "");
1095 if (stype == LLVMInt16Type () && dtype == LLVMInt8Type ())
1096 return LLVMBuildTrunc (ctx->builder, v, dtype, "");
1097 if (stype == LLVMDoubleType () && dtype == LLVMFloatType ())
1098 return LLVMBuildFPTrunc (ctx->builder, v, dtype, "");
1100 if (LLVMGetTypeKind (stype) == LLVMPointerTypeKind && LLVMGetTypeKind (dtype) == LLVMPointerTypeKind)
1101 return LLVMBuildBitCast (ctx->builder, v, dtype, "");
1102 if (LLVMGetTypeKind (dtype) == LLVMPointerTypeKind)
1103 return LLVMBuildIntToPtr (ctx->builder, v, dtype, "");
1104 if (LLVMGetTypeKind (stype) == LLVMPointerTypeKind)
1105 return LLVMBuildPtrToInt (ctx->builder, v, dtype, "");
1107 if (mono_arch_is_soft_float ()) {
1108 if (stype == LLVMInt32Type () && dtype == LLVMFloatType ())
1109 return LLVMBuildBitCast (ctx->builder, v, dtype, "");
1110 if (stype == LLVMInt32Type () && dtype == LLVMDoubleType ())
1111 return LLVMBuildBitCast (ctx->builder, LLVMBuildZExt (ctx->builder, v, LLVMInt64Type (), ""), dtype, "");
1114 if (LLVMGetTypeKind (stype) == LLVMVectorTypeKind && LLVMGetTypeKind (dtype) == LLVMVectorTypeKind)
1115 return LLVMBuildBitCast (ctx->builder, v, dtype, "");
1118 LLVMDumpValue (LLVMConstNull (dtype));
1119 g_assert_not_reached ();
1127 convert (EmitContext *ctx, LLVMValueRef v, LLVMTypeRef dtype)
1129 return convert_full (ctx, v, dtype, FALSE);
1133 * emit_volatile_load:
1135 * If vreg is volatile, emit a load from its address.
1138 emit_volatile_load (EmitContext *ctx, int vreg)
1142 LLVMValueRef v = LLVMBuildLoad (ctx->builder, ctx->addresses [vreg], "");
1143 t = ctx->vreg_cli_types [vreg];
1144 if (t && !t->byref) {
1146 * Might have to zero extend since llvm doesn't have
1149 if (t->type == MONO_TYPE_U1 || t->type == MONO_TYPE_U2 || t->type == MONO_TYPE_CHAR || t->type == MONO_TYPE_BOOLEAN)
1150 v = LLVMBuildZExt (ctx->builder, v, LLVMInt32Type (), "");
1151 else if (t->type == MONO_TYPE_I1 || t->type == MONO_TYPE_I2)
1152 v = LLVMBuildSExt (ctx->builder, v, LLVMInt32Type (), "");
1153 else if (t->type == MONO_TYPE_U8)
1154 v = LLVMBuildZExt (ctx->builder, v, LLVMInt64Type (), "");
1161 * emit_volatile_store:
1163 * If VREG is volatile, emit a store from its value to its address.
1166 emit_volatile_store (EmitContext *ctx, int vreg)
1168 MonoInst *var = get_vreg_to_inst (ctx->cfg, vreg);
1170 if (var && var->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT)) {
1171 g_assert (ctx->addresses [vreg]);
1172 LLVMBuildStore (ctx->builder, convert (ctx, ctx->values [vreg], type_to_llvm_type (ctx, var->inst_vtype)), ctx->addresses [vreg]);
1177 sig_to_llvm_sig_no_cinfo (EmitContext *ctx, MonoMethodSignature *sig)
1179 LLVMTypeRef ret_type;
1180 LLVMTypeRef *param_types = NULL;
1185 rtype = mini_get_underlying_type (sig->ret);
1186 ret_type = type_to_llvm_type (ctx, rtype);
1187 CHECK_FAILURE (ctx);
1189 param_types = g_new0 (LLVMTypeRef, (sig->param_count * 8) + 3);
1193 param_types [pindex ++] = ThisType ();
1194 for (i = 0; i < sig->param_count; ++i)
1195 param_types [pindex ++] = type_to_llvm_arg_type (ctx, sig->params [i]);
1197 CHECK_FAILURE (ctx);
1199 res = LLVMFunctionType (ret_type, param_types, pindex, FALSE);
1200 g_free (param_types);
1205 g_free (param_types);
1211 * sig_to_llvm_sig_full:
1213 * Return the LLVM signature corresponding to the mono signature SIG using the
1214 * calling convention information in CINFO. Fill out the parameter mapping information in CINFO.
1217 sig_to_llvm_sig_full (EmitContext *ctx, MonoMethodSignature *sig, LLVMCallInfo *cinfo)
1219 LLVMTypeRef ret_type;
1220 LLVMTypeRef *param_types = NULL;
1222 int i, j, pindex, vret_arg_pindex = 0;
1223 gboolean vretaddr = FALSE;
1227 return sig_to_llvm_sig_no_cinfo (ctx, sig);
1229 rtype = mini_get_underlying_type (sig->ret);
1230 ret_type = type_to_llvm_type (ctx, rtype);
1231 CHECK_FAILURE (ctx);
1233 switch (cinfo->ret.storage) {
1234 case LLVMArgVtypeInReg:
1235 /* LLVM models this by returning an aggregate value */
1236 if (cinfo->ret.pair_storage [0] == LLVMArgInIReg && cinfo->ret.pair_storage [1] == LLVMArgNone) {
1237 LLVMTypeRef members [2];
1239 members [0] = IntPtrType ();
1240 ret_type = LLVMStructType (members, 1, FALSE);
1241 } else if (cinfo->ret.pair_storage [0] == LLVMArgNone && cinfo->ret.pair_storage [1] == LLVMArgNone) {
1243 ret_type = LLVMVoidType ();
1244 } else if (cinfo->ret.pair_storage [0] == LLVMArgInIReg && cinfo->ret.pair_storage [1] == LLVMArgInIReg) {
1245 LLVMTypeRef members [2];
1247 members [0] = IntPtrType ();
1248 members [1] = IntPtrType ();
1249 ret_type = LLVMStructType (members, 2, FALSE);
1251 g_assert_not_reached ();
1254 case LLVMArgVtypeByVal:
1255 /* Vtype returned normally by val */
1257 case LLVMArgVtypeAsScalar:
1258 /* LLVM models this by returning an int */
1259 g_assert (cinfo->ret.nslots == 1 || cinfo->ret.nslots == 2);
1260 ret_type = LLVMIntType (cinfo->ret.nslots * sizeof (mgreg_t) * 8);
1262 case LLVMArgFpStruct: {
1263 /* Vtype returned as a fp struct */
1264 LLVMTypeRef members [16];
1266 /* Have to create our own structure since we don't map fp structures to LLVM fp structures yet */
1267 for (i = 0; i < cinfo->ret.nslots; ++i)
1268 members [i] = cinfo->ret.esize == 8 ? LLVMDoubleType () : LLVMFloatType ();
1269 ret_type = LLVMStructType (members, cinfo->ret.nslots, FALSE);
1272 case LLVMArgVtypeByRef:
1273 /* Vtype returned using a hidden argument */
1274 ret_type = LLVMVoidType ();
1276 case LLVMArgVtypeRetAddr:
1277 case LLVMArgScalarRetAddr:
1278 case LLVMArgGsharedvtFixed:
1279 case LLVMArgGsharedvtFixedVtype:
1280 case LLVMArgGsharedvtVariable:
1282 ret_type = LLVMVoidType ();
1288 param_types = g_new0 (LLVMTypeRef, (sig->param_count * 8) + 3);
1290 if (cinfo->ret.storage == LLVMArgVtypeByRef) {
1292 * Has to be the first argument because of the sret argument attribute
1293 * FIXME: This might conflict with passing 'this' as the first argument, but
1294 * this is only used on arm64 which has a dedicated struct return register.
1296 cinfo->vret_arg_pindex = pindex;
1297 param_types [pindex] = type_to_llvm_arg_type (ctx, sig->ret);
1298 CHECK_FAILURE (ctx);
1299 param_types [pindex] = LLVMPointerType (param_types [pindex], 0);
1302 if (!ctx->llvm_only && cinfo->rgctx_arg) {
1303 cinfo->rgctx_arg_pindex = pindex;
1304 param_types [pindex] = ctx->module->ptr_type;
1307 if (cinfo->imt_arg) {
1308 cinfo->imt_arg_pindex = pindex;
1309 param_types [pindex] = ctx->module->ptr_type;
1313 /* Compute the index in the LLVM signature where the vret arg needs to be passed */
1314 vret_arg_pindex = pindex;
1315 if (cinfo->vret_arg_index == 1) {
1316 /* Add the slots consumed by the first argument */
1317 LLVMArgInfo *ainfo = &cinfo->args [0];
1318 switch (ainfo->storage) {
1319 case LLVMArgVtypeInReg:
1320 for (j = 0; j < 2; ++j) {
1321 if (ainfo->pair_storage [j] == LLVMArgInIReg)
1330 cinfo->vret_arg_pindex = vret_arg_pindex;
1333 if (vretaddr && vret_arg_pindex == pindex)
1334 param_types [pindex ++] = IntPtrType ();
1336 cinfo->this_arg_pindex = pindex;
1337 param_types [pindex ++] = ThisType ();
1338 cinfo->args [0].pindex = cinfo->this_arg_pindex;
1340 if (vretaddr && vret_arg_pindex == pindex)
1341 param_types [pindex ++] = IntPtrType ();
1342 for (i = 0; i < sig->param_count; ++i) {
1343 LLVMArgInfo *ainfo = &cinfo->args [i + sig->hasthis];
1345 if (vretaddr && vret_arg_pindex == pindex)
1346 param_types [pindex ++] = IntPtrType ();
1347 ainfo->pindex = pindex;
1349 switch (ainfo->storage) {
1350 case LLVMArgVtypeInReg:
1351 for (j = 0; j < 2; ++j) {
1352 switch (ainfo->pair_storage [j]) {
1354 param_types [pindex ++] = LLVMIntType (sizeof (gpointer) * 8);
1359 g_assert_not_reached ();
1363 case LLVMArgVtypeByVal:
1364 param_types [pindex] = type_to_llvm_arg_type (ctx, ainfo->type);
1365 CHECK_FAILURE (ctx);
1366 param_types [pindex] = LLVMPointerType (param_types [pindex], 0);
1369 case LLVMArgAsIArgs:
1370 param_types [pindex] = LLVMArrayType (IntPtrType (), ainfo->nslots);
1373 case LLVMArgVtypeByRef:
1374 case LLVMArgScalarByRef:
1375 param_types [pindex] = type_to_llvm_arg_type (ctx, ainfo->type);
1376 CHECK_FAILURE (ctx);
1377 param_types [pindex] = LLVMPointerType (param_types [pindex], 0);
1380 case LLVMArgAsFpArgs: {
1383 /* Emit dummy fp arguments if needed so the rest is passed on the stack */
1384 for (j = 0; j < ainfo->ndummy_fpargs; ++j)
1385 param_types [pindex ++] = LLVMDoubleType ();
1386 for (j = 0; j < ainfo->nslots; ++j)
1387 param_types [pindex ++] = ainfo->esize == 8 ? LLVMDoubleType () : LLVMFloatType ();
1390 case LLVMArgVtypeAsScalar:
1391 g_assert_not_reached ();
1393 case LLVMArgGsharedvtFixed:
1394 case LLVMArgGsharedvtFixedVtype:
1395 param_types [pindex ++] = LLVMPointerType (type_to_llvm_arg_type (ctx, ainfo->type), 0);
1397 case LLVMArgGsharedvtVariable:
1398 param_types [pindex ++] = LLVMPointerType (IntPtrType (), 0);
1401 param_types [pindex ++] = type_to_llvm_arg_type (ctx, ainfo->type);
1405 if (vretaddr && vret_arg_pindex == pindex)
1406 param_types [pindex ++] = IntPtrType ();
1407 if (ctx->llvm_only && cinfo->rgctx_arg) {
1408 /* Pass the rgctx as the last argument */
1409 cinfo->rgctx_arg_pindex = pindex;
1410 param_types [pindex] = ctx->module->ptr_type;
1414 CHECK_FAILURE (ctx);
1416 res = LLVMFunctionType (ret_type, param_types, pindex, FALSE);
1417 g_free (param_types);
1422 g_free (param_types);
1428 sig_to_llvm_sig (EmitContext *ctx, MonoMethodSignature *sig)
1430 return sig_to_llvm_sig_full (ctx, sig, NULL);
1434 * LLVMFunctionType1:
1436 * Create an LLVM function type from the arguments.
1438 static G_GNUC_UNUSED LLVMTypeRef
1439 LLVMFunctionType0 (LLVMTypeRef ReturnType,
1442 return LLVMFunctionType (ReturnType, NULL, 0, IsVarArg);
1446 * LLVMFunctionType1:
1448 * Create an LLVM function type from the arguments.
1450 static G_GNUC_UNUSED LLVMTypeRef
1451 LLVMFunctionType1 (LLVMTypeRef ReturnType,
1452 LLVMTypeRef ParamType1,
1455 LLVMTypeRef param_types [1];
1457 param_types [0] = ParamType1;
1459 return LLVMFunctionType (ReturnType, param_types, 1, IsVarArg);
1463 * LLVMFunctionType2:
1465 * Create an LLVM function type from the arguments.
1467 static G_GNUC_UNUSED LLVMTypeRef
1468 LLVMFunctionType2 (LLVMTypeRef ReturnType,
1469 LLVMTypeRef ParamType1,
1470 LLVMTypeRef ParamType2,
1473 LLVMTypeRef param_types [2];
1475 param_types [0] = ParamType1;
1476 param_types [1] = ParamType2;
1478 return LLVMFunctionType (ReturnType, param_types, 2, IsVarArg);
1482 * LLVMFunctionType3:
1484 * Create an LLVM function type from the arguments.
1486 static G_GNUC_UNUSED LLVMTypeRef
1487 LLVMFunctionType3 (LLVMTypeRef ReturnType,
1488 LLVMTypeRef ParamType1,
1489 LLVMTypeRef ParamType2,
1490 LLVMTypeRef ParamType3,
1493 LLVMTypeRef param_types [3];
1495 param_types [0] = ParamType1;
1496 param_types [1] = ParamType2;
1497 param_types [2] = ParamType3;
1499 return LLVMFunctionType (ReturnType, param_types, 3, IsVarArg);
1502 static G_GNUC_UNUSED LLVMTypeRef
1503 LLVMFunctionType5 (LLVMTypeRef ReturnType,
1504 LLVMTypeRef ParamType1,
1505 LLVMTypeRef ParamType2,
1506 LLVMTypeRef ParamType3,
1507 LLVMTypeRef ParamType4,
1508 LLVMTypeRef ParamType5,
1511 LLVMTypeRef param_types [5];
1513 param_types [0] = ParamType1;
1514 param_types [1] = ParamType2;
1515 param_types [2] = ParamType3;
1516 param_types [3] = ParamType4;
1517 param_types [4] = ParamType5;
1519 return LLVMFunctionType (ReturnType, param_types, 5, IsVarArg);
1525 * Create an LLVM builder and remember it so it can be freed later.
1527 static LLVMBuilderRef
1528 create_builder (EmitContext *ctx)
1530 LLVMBuilderRef builder = LLVMCreateBuilder ();
1532 ctx->builders = g_slist_prepend_mempool (ctx->cfg->mempool, ctx->builders, builder);
1538 get_aotconst_name (MonoJumpInfoType type, gconstpointer data, int got_offset)
1543 case MONO_PATCH_INFO_INTERNAL_METHOD:
1544 name = g_strdup_printf ("jit_icall_%s", data);
1546 case MONO_PATCH_INFO_RGCTX_SLOT_INDEX: {
1547 MonoJumpInfoRgctxEntry *entry = (MonoJumpInfoRgctxEntry*)data;
1548 name = g_strdup_printf ("RGCTX_SLOT_INDEX_%s", mono_rgctx_info_type_to_str (entry->info_type));
1552 name = g_strdup_printf ("%s_%d", mono_ji_type_to_string (type), got_offset);
1560 get_aotconst_typed (EmitContext *ctx, MonoJumpInfoType type, gconstpointer data, LLVMTypeRef llvm_type)
1564 LLVMValueRef indexes [2];
1566 LLVMValueRef got_entry_addr, load;
1567 LLVMBuilderRef builder = ctx->builder;
1572 ji = g_new0 (MonoJumpInfo, 1);
1574 ji->data.target = data;
1576 ji = mono_aot_patch_info_dup (ji);
1578 ji->next = cfg->patch_info;
1579 cfg->patch_info = ji;
1581 got_offset = mono_aot_get_got_offset (cfg->patch_info);
1582 ctx->module->max_got_offset = MAX (ctx->module->max_got_offset, got_offset);
1584 * If the got slot is shared, it means its initialized when the aot image is loaded, so we don't need to
1585 * explicitly initialize it.
1587 if (!mono_aot_is_shared_got_offset (got_offset)) {
1588 //mono_print_ji (ji);
1590 ctx->has_got_access = TRUE;
1593 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
1594 indexes [1] = LLVMConstInt (LLVMInt32Type (), (gssize)got_offset, FALSE);
1595 got_entry_addr = LLVMBuildGEP (builder, ctx->module->got_var, indexes, 2, "");
1597 name = get_aotconst_name (type, data, got_offset);
1599 load = convert (ctx, LLVMBuildLoad (builder, got_entry_addr, ""), llvm_type);
1600 LLVMSetValueName (load, name ? name : "");
1602 load = LLVMBuildLoad (builder, got_entry_addr, name ? name : "");
1605 //set_invariant_load_flag (load);
1611 get_aotconst (EmitContext *ctx, MonoJumpInfoType type, gconstpointer data)
1613 return get_aotconst_typed (ctx, type, data, NULL);
1617 get_callee (EmitContext *ctx, LLVMTypeRef llvm_sig, MonoJumpInfoType type, gconstpointer data)
1619 LLVMValueRef callee;
1621 if (ctx->llvm_only) {
1622 callee_name = mono_aot_get_direct_call_symbol (type, data);
1624 /* Directly callable */
1626 callee = (LLVMValueRef)g_hash_table_lookup (ctx->module->direct_callables, callee_name);
1628 callee = LLVMAddFunction (ctx->lmodule, callee_name, llvm_sig);
1630 LLVMSetVisibility (callee, LLVMHiddenVisibility);
1632 g_hash_table_insert (ctx->module->direct_callables, (char*)callee_name, callee);
1634 g_free (callee_name);
1640 * Calls are made through the GOT.
1642 return get_aotconst_typed (ctx, type, data, LLVMPointerType (llvm_sig, 0));
1644 MonoJumpInfo *ji = NULL;
1646 callee_name = mono_aot_get_plt_symbol (type, data);
1650 if (ctx->cfg->compile_aot)
1651 /* Add a patch so referenced wrappers can be compiled in full aot mode */
1652 mono_add_patch_info (ctx->cfg, 0, type, data);
1655 callee = (LLVMValueRef)g_hash_table_lookup (ctx->module->plt_entries, callee_name);
1657 callee = LLVMAddFunction (ctx->lmodule, callee_name, llvm_sig);
1659 LLVMSetVisibility (callee, LLVMHiddenVisibility);
1661 g_hash_table_insert (ctx->module->plt_entries, (char*)callee_name, callee);
1664 if (ctx->cfg->compile_aot) {
1665 ji = g_new0 (MonoJumpInfo, 1);
1667 ji->data.target = data;
1669 g_hash_table_insert (ctx->module->plt_entries_ji, ji, callee);
1677 get_handler_clause (MonoCompile *cfg, MonoBasicBlock *bb)
1679 MonoMethodHeader *header = cfg->header;
1680 MonoExceptionClause *clause;
1684 if (bb->region != -1 && MONO_BBLOCK_IS_IN_REGION (bb, MONO_REGION_TRY))
1685 return (bb->region >> 8) - 1;
1688 for (i = 0; i < header->num_clauses; ++i) {
1689 clause = &header->clauses [i];
1691 if (MONO_OFFSET_IN_CLAUSE (clause, bb->real_offset) && clause->flags == MONO_EXCEPTION_CLAUSE_NONE)
1698 static MonoExceptionClause *
1699 get_most_deep_clause (MonoCompile *cfg, EmitContext *ctx, MonoBasicBlock *bb)
1701 // Since they're sorted by nesting we just need
1702 // the first one that the bb is a member of
1703 MonoExceptionClause *last = NULL;
1705 for (int i = 0; i < cfg->header->num_clauses; i++) {
1706 MonoExceptionClause *curr = &cfg->header->clauses [i];
1708 if (MONO_OFFSET_IN_CLAUSE (curr, bb->real_offset))
1711 if (MONO_OFFSET_IN_CLAUSE (curr, bb->real_offset)) {
1712 if (last && CLAUSE_END(last) > CLAUSE_END(curr))
1726 set_metadata_flag (LLVMValueRef v, const char *flag_name)
1728 LLVMValueRef md_arg;
1731 md_kind = LLVMGetMDKindID (flag_name, strlen (flag_name));
1732 md_arg = LLVMMDString ("mono", 4);
1733 LLVMSetMetadata (v, md_kind, LLVMMDNode (&md_arg, 1));
1737 set_invariant_load_flag (LLVMValueRef v)
1739 LLVMValueRef md_arg;
1741 const char *flag_name;
1743 // FIXME: Cache this
1744 flag_name = "invariant.load";
1745 md_kind = LLVMGetMDKindID (flag_name, strlen (flag_name));
1746 md_arg = LLVMMDString ("<index>", strlen ("<index>"));
1747 LLVMSetMetadata (v, md_kind, LLVMMDNode (&md_arg, 1));
1753 * Emit an LLVM call or invoke instruction depending on whenever the call is inside
1757 emit_call (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, LLVMValueRef callee, LLVMValueRef *args, int pindex)
1759 MonoCompile *cfg = ctx->cfg;
1760 LLVMValueRef lcall = NULL;
1761 LLVMBuilderRef builder = *builder_ref;
1762 MonoExceptionClause *clause;
1764 if (ctx->llvm_only) {
1765 clause = get_most_deep_clause (cfg, ctx, bb);
1768 g_assert (clause->flags == MONO_EXCEPTION_CLAUSE_NONE || clause->flags == MONO_EXCEPTION_CLAUSE_FINALLY);
1771 * Have to use an invoke instead of a call, branching to the
1772 * handler bblock of the clause containing this bblock.
1774 intptr_t key = CLAUSE_END(clause);
1776 LLVMBasicBlockRef lpad_bb = (LLVMBasicBlockRef)g_hash_table_lookup (ctx->exc_meta, (gconstpointer)key);
1778 // FIXME: Find the one that has the lowest end bound for the right start address
1779 // FIXME: Finally + nesting
1782 LLVMBasicBlockRef noex_bb = gen_bb (ctx, "CALL_NOEX_BB");
1785 lcall = LLVMBuildInvoke (builder, callee, args, pindex, noex_bb, lpad_bb, "");
1787 builder = ctx->builder = create_builder (ctx);
1788 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
1790 ctx->bblocks [bb->block_num].end_bblock = noex_bb;
1794 int clause_index = get_handler_clause (cfg, bb);
1796 if (clause_index != -1) {
1797 MonoMethodHeader *header = cfg->header;
1798 MonoExceptionClause *ec = &header->clauses [clause_index];
1799 MonoBasicBlock *tblock;
1800 LLVMBasicBlockRef ex_bb, noex_bb;
1803 * Have to use an invoke instead of a call, branching to the
1804 * handler bblock of the clause containing this bblock.
1807 g_assert (ec->flags == MONO_EXCEPTION_CLAUSE_NONE || ec->flags == MONO_EXCEPTION_CLAUSE_FINALLY);
1809 tblock = cfg->cil_offset_to_bb [ec->handler_offset];
1812 ctx->bblocks [tblock->block_num].invoke_target = TRUE;
1814 ex_bb = get_bb (ctx, tblock);
1816 noex_bb = gen_bb (ctx, "NOEX_BB");
1819 lcall = LLVMBuildInvoke (builder, callee, args, pindex, noex_bb, ex_bb, "");
1821 builder = ctx->builder = create_builder (ctx);
1822 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
1824 ctx->bblocks [bb->block_num].end_bblock = noex_bb;
1829 lcall = LLVMBuildCall (builder, callee, args, pindex, "");
1830 ctx->builder = builder;
1834 *builder_ref = ctx->builder;
1840 emit_load_general (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, int size, LLVMValueRef addr, const char *name, gboolean is_faulting, BarrierKind barrier)
1842 const char *intrins_name;
1843 LLVMValueRef args [16], res;
1844 LLVMTypeRef addr_type;
1846 if (is_faulting && bb->region != -1 && !ctx->cfg->llvm_only) {
1847 LLVMAtomicOrdering ordering;
1850 case LLVM_BARRIER_NONE:
1851 ordering = LLVMAtomicOrderingNotAtomic;
1853 case LLVM_BARRIER_ACQ:
1854 ordering = LLVMAtomicOrderingAcquire;
1856 case LLVM_BARRIER_SEQ:
1857 ordering = LLVMAtomicOrderingSequentiallyConsistent;
1860 g_assert_not_reached ();
1865 * We handle loads which can fault by calling a mono specific intrinsic
1866 * using an invoke, so they are handled properly inside try blocks.
1867 * We can't use this outside clauses, since LLVM optimizes intrinsics which
1868 * are marked with IntrReadArgMem.
1872 intrins_name = "llvm.mono.load.i8.p0i8";
1875 intrins_name = "llvm.mono.load.i16.p0i16";
1878 intrins_name = "llvm.mono.load.i32.p0i32";
1881 intrins_name = "llvm.mono.load.i64.p0i64";
1884 g_assert_not_reached ();
1887 addr_type = LLVMTypeOf (addr);
1888 if (addr_type == LLVMPointerType (LLVMDoubleType (), 0) || addr_type == LLVMPointerType (LLVMFloatType (), 0))
1889 addr = LLVMBuildBitCast (*builder_ref, addr, LLVMPointerType (LLVMIntType (size * 8), 0), "");
1892 args [1] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
1893 args [2] = LLVMConstInt (LLVMInt1Type (), TRUE, FALSE);
1894 args [3] = LLVMConstInt (LLVMInt32Type (), ordering, FALSE);
1895 res = emit_call (ctx, bb, builder_ref, LLVMGetNamedFunction (ctx->lmodule, intrins_name), args, 4);
1897 if (addr_type == LLVMPointerType (LLVMDoubleType (), 0))
1898 res = LLVMBuildBitCast (*builder_ref, res, LLVMDoubleType (), "");
1899 else if (addr_type == LLVMPointerType (LLVMFloatType (), 0))
1900 res = LLVMBuildBitCast (*builder_ref, res, LLVMFloatType (), "");
1907 * We emit volatile loads for loads which can fault, because otherwise
1908 * LLVM will generate invalid code when encountering a load from a
1911 res = mono_llvm_build_load (*builder_ref, addr, name, is_faulting, barrier);
1913 /* Mark it with a custom metadata */
1916 set_metadata_flag (res, "mono.faulting.load");
1924 emit_load (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, int size, LLVMValueRef addr, const char *name, gboolean is_faulting)
1926 return emit_load_general (ctx, bb, builder_ref, size, addr, name, is_faulting, LLVM_BARRIER_NONE);
1930 emit_store_general (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, int size, LLVMValueRef value, LLVMValueRef addr, gboolean is_faulting, BarrierKind barrier)
1932 const char *intrins_name;
1933 LLVMValueRef args [16];
1935 if (is_faulting && bb->region != -1 && !ctx->cfg->llvm_only) {
1936 LLVMAtomicOrdering ordering;
1939 case LLVM_BARRIER_NONE:
1940 ordering = LLVMAtomicOrderingNotAtomic;
1942 case LLVM_BARRIER_REL:
1943 ordering = LLVMAtomicOrderingRelease;
1945 case LLVM_BARRIER_SEQ:
1946 ordering = LLVMAtomicOrderingSequentiallyConsistent;
1949 g_assert_not_reached ();
1955 intrins_name = "llvm.mono.store.i8.p0i8";
1958 intrins_name = "llvm.mono.store.i16.p0i16";
1961 intrins_name = "llvm.mono.store.i32.p0i32";
1964 intrins_name = "llvm.mono.store.i64.p0i64";
1967 g_assert_not_reached ();
1970 if (LLVMTypeOf (value) == LLVMDoubleType () || LLVMTypeOf (value) == LLVMFloatType ()) {
1971 value = LLVMBuildBitCast (*builder_ref, value, LLVMIntType (size * 8), "");
1972 addr = LLVMBuildBitCast (*builder_ref, addr, LLVMPointerType (LLVMIntType (size * 8), 0), "");
1977 args [2] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
1978 args [3] = LLVMConstInt (LLVMInt1Type (), TRUE, FALSE);
1979 args [4] = LLVMConstInt (LLVMInt32Type (), ordering, FALSE);
1980 emit_call (ctx, bb, builder_ref, LLVMGetNamedFunction (ctx->lmodule, intrins_name), args, 5);
1982 mono_llvm_build_store (*builder_ref, value, addr, is_faulting, barrier);
1987 emit_store (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, int size, LLVMValueRef value, LLVMValueRef addr, gboolean is_faulting)
1989 emit_store_general (ctx, bb, builder_ref, size, value, addr, is_faulting, LLVM_BARRIER_NONE);
1993 * emit_cond_system_exception:
1995 * Emit code to throw the exception EXC_TYPE if the condition CMP is false.
1996 * Might set the ctx exception.
1999 emit_cond_system_exception (EmitContext *ctx, MonoBasicBlock *bb, const char *exc_type, LLVMValueRef cmp)
2001 LLVMBasicBlockRef ex_bb, ex2_bb = NULL, noex_bb;
2002 LLVMBuilderRef builder;
2003 MonoClass *exc_class;
2004 LLVMValueRef args [2];
2005 LLVMValueRef callee;
2007 ex_bb = gen_bb (ctx, "EX_BB");
2009 ex2_bb = gen_bb (ctx, "EX2_BB");
2010 noex_bb = gen_bb (ctx, "NOEX_BB");
2012 LLVMBuildCondBr (ctx->builder, cmp, ex_bb, noex_bb);
2014 exc_class = mono_class_from_name (mono_get_corlib (), "System", exc_type);
2015 g_assert (exc_class);
2017 /* Emit exception throwing code */
2018 ctx->builder = builder = create_builder (ctx);
2019 LLVMPositionBuilderAtEnd (builder, ex_bb);
2021 if (ctx->cfg->llvm_only) {
2022 static LLVMTypeRef sig;
2025 sig = LLVMFunctionType1 (LLVMVoidType (), LLVMInt32Type (), FALSE);
2026 callee = get_callee (ctx, sig, MONO_PATCH_INFO_INTERNAL_METHOD, "mono_llvm_throw_corlib_exception");
2028 LLVMBuildBr (builder, ex2_bb);
2030 ctx->builder = builder = create_builder (ctx);
2031 LLVMPositionBuilderAtEnd (ctx->builder, ex2_bb);
2033 args [0] = LLVMConstInt (LLVMInt32Type (), exc_class->type_token - MONO_TOKEN_TYPE_DEF, FALSE);
2034 emit_call (ctx, bb, &builder, callee, args, 1);
2035 LLVMBuildUnreachable (builder);
2037 ctx->builder = builder = create_builder (ctx);
2038 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
2040 ctx->bblocks [bb->block_num].end_bblock = noex_bb;
2046 callee = ctx->module->throw_corlib_exception;
2049 const char *icall_name;
2051 sig = LLVMFunctionType2 (LLVMVoidType (), LLVMInt32Type (), LLVMPointerType (LLVMInt8Type (), 0), FALSE);
2052 icall_name = "llvm_throw_corlib_exception_abs_trampoline";
2054 if (ctx->cfg->compile_aot) {
2055 callee = get_callee (ctx, sig, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
2057 callee = LLVMAddFunction (ctx->lmodule, "llvm_throw_corlib_exception_trampoline", sig);
2060 * Differences between the LLVM/non-LLVM throw corlib exception trampoline:
2061 * - On x86, LLVM generated code doesn't push the arguments
2062 * - The trampoline takes the throw address as an arguments, not a pc offset.
2064 LLVMAddGlobalMapping (ctx->module->ee, callee, resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name));
2066 mono_memory_barrier ();
2067 ctx->module->throw_corlib_exception = callee;
2071 if (IS_TARGET_X86 || IS_TARGET_AMD64)
2072 args [0] = LLVMConstInt (LLVMInt32Type (), exc_class->type_token - MONO_TOKEN_TYPE_DEF, FALSE);
2074 args [0] = LLVMConstInt (LLVMInt32Type (), exc_class->type_token, FALSE);
2077 * The LLVM mono branch contains changes so a block address can be passed as an
2078 * argument to a call.
2080 args [1] = LLVMBlockAddress (ctx->lmethod, ex_bb);
2081 emit_call (ctx, bb, &builder, callee, args, 2);
2083 LLVMBuildUnreachable (builder);
2085 ctx->builder = builder = create_builder (ctx);
2086 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
2088 ctx->bblocks [bb->block_num].end_bblock = noex_bb;
2095 * emit_args_to_vtype:
2097 * Emit code to store the vtype in the arguments args to the address ADDRESS.
2100 emit_args_to_vtype (EmitContext *ctx, LLVMBuilderRef builder, MonoType *t, LLVMValueRef address, LLVMArgInfo *ainfo, LLVMValueRef *args)
2102 int j, size, nslots;
2104 size = get_vtype_size (t);
2106 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (t))) {
2107 address = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (LLVMInt8Type (), 0), "");
2110 if (ainfo->storage == LLVMArgAsFpArgs)
2111 nslots = ainfo->nslots;
2115 for (j = 0; j < nslots; ++j) {
2116 LLVMValueRef index [2], addr, daddr;
2117 int part_size = size > sizeof (gpointer) ? sizeof (gpointer) : size;
2118 LLVMTypeRef part_type;
2120 if (ainfo->pair_storage [j] == LLVMArgNone)
2123 switch (ainfo->pair_storage [j]) {
2124 case LLVMArgInIReg: {
2125 part_type = LLVMIntType (part_size * 8);
2126 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (t))) {
2127 index [0] = LLVMConstInt (LLVMInt32Type (), j * sizeof (gpointer), FALSE);
2128 addr = LLVMBuildGEP (builder, address, index, 1, "");
2130 daddr = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (IntPtrType (), 0), "");
2131 index [0] = LLVMConstInt (LLVMInt32Type (), j, FALSE);
2132 addr = LLVMBuildGEP (builder, daddr, index, 1, "");
2134 LLVMBuildStore (builder, convert (ctx, args [j], part_type), LLVMBuildBitCast (ctx->builder, addr, LLVMPointerType (part_type, 0), ""));
2137 case LLVMArgInFPReg: {
2138 LLVMTypeRef arg_type;
2140 if (ainfo->esize == 8)
2141 arg_type = LLVMDoubleType ();
2143 arg_type = LLVMFloatType ();
2145 index [0] = LLVMConstInt (LLVMInt32Type (), j, FALSE);
2146 daddr = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (arg_type, 0), "");
2147 addr = LLVMBuildGEP (builder, daddr, index, 1, "");
2148 LLVMBuildStore (builder, args [j], addr);
2154 g_assert_not_reached ();
2157 size -= sizeof (gpointer);
2162 * emit_vtype_to_args:
2164 * Emit code to load a vtype at address ADDRESS into scalar arguments. Store the arguments
2165 * into ARGS, and the number of arguments into NARGS.
2168 emit_vtype_to_args (EmitContext *ctx, LLVMBuilderRef builder, MonoType *t, LLVMValueRef address, LLVMArgInfo *ainfo, LLVMValueRef *args, guint32 *nargs)
2171 int j, size, nslots;
2172 LLVMTypeRef arg_type;
2174 size = get_vtype_size (t);
2176 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (t)))
2177 address = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (LLVMInt8Type (), 0), "");
2179 if (ainfo->storage == LLVMArgAsFpArgs)
2180 nslots = ainfo->nslots;
2183 for (j = 0; j < nslots; ++j) {
2184 LLVMValueRef index [2], addr, daddr;
2185 int partsize = size > sizeof (gpointer) ? sizeof (gpointer) : size;
2187 if (ainfo->pair_storage [j] == LLVMArgNone)
2190 switch (ainfo->pair_storage [j]) {
2192 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (t))) {
2193 index [0] = LLVMConstInt (LLVMInt32Type (), j * sizeof (gpointer), FALSE);
2194 addr = LLVMBuildGEP (builder, address, index, 1, "");
2196 daddr = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (IntPtrType (), 0), "");
2197 index [0] = LLVMConstInt (LLVMInt32Type (), j, FALSE);
2198 addr = LLVMBuildGEP (builder, daddr, index, 1, "");
2200 args [pindex ++] = convert (ctx, LLVMBuildLoad (builder, LLVMBuildBitCast (ctx->builder, addr, LLVMPointerType (LLVMIntType (partsize * 8), 0), ""), ""), IntPtrType ());
2202 case LLVMArgInFPReg:
2203 if (ainfo->esize == 8)
2204 arg_type = LLVMDoubleType ();
2206 arg_type = LLVMFloatType ();
2207 daddr = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (arg_type, 0), "");
2208 index [0] = LLVMConstInt (LLVMInt32Type (), j, FALSE);
2209 addr = LLVMBuildGEP (builder, daddr, index, 1, "");
2210 args [pindex ++] = LLVMBuildLoad (builder, addr, "");
2215 g_assert_not_reached ();
2217 size -= sizeof (gpointer);
2224 build_alloca_llvm_type_name (EmitContext *ctx, LLVMTypeRef t, int align, const char *name)
2227 * Have to place all alloca's at the end of the entry bb, since otherwise they would
2228 * get executed every time control reaches them.
2230 LLVMPositionBuilder (ctx->alloca_builder, get_bb (ctx, ctx->cfg->bb_entry), ctx->last_alloca);
2232 ctx->last_alloca = mono_llvm_build_alloca (ctx->alloca_builder, t, NULL, align, name);
2233 return ctx->last_alloca;
2237 build_alloca_llvm_type (EmitContext *ctx, LLVMTypeRef t, int align)
2239 return build_alloca_llvm_type_name (ctx, t, align, "");
2243 build_alloca (EmitContext *ctx, MonoType *t)
2245 MonoClass *k = mono_class_from_mono_type (t);
2248 g_assert (!mini_is_gsharedvt_variable_type (t));
2250 if (MONO_CLASS_IS_SIMD (ctx->cfg, k))
2253 align = mono_class_min_align (k);
2255 /* Sometimes align is not a power of 2 */
2256 while (mono_is_power_of_two (align) == -1)
2259 return build_alloca_llvm_type (ctx, type_to_llvm_type (ctx, t), align);
2263 emit_gsharedvt_ldaddr (EmitContext *ctx, int vreg)
2267 * Compute the address of the local as gsharedvt_locals_var + gsharedvt_info_var->locals_offsets [idx].
2269 MonoCompile *cfg = ctx->cfg;
2270 LLVMBuilderRef builder = ctx->builder;
2271 LLVMValueRef offset, offset_var;
2272 LLVMValueRef info_var = ctx->values [cfg->gsharedvt_info_var->dreg];
2273 LLVMValueRef locals_var = ctx->values [cfg->gsharedvt_locals_var->dreg];
2277 g_assert (info_var);
2278 g_assert (locals_var);
2280 int idx = cfg->gsharedvt_vreg_to_idx [vreg] - 1;
2282 offset = LLVMConstInt (LLVMInt32Type (), MONO_STRUCT_OFFSET (MonoGSharedVtMethodRuntimeInfo, entries) + (idx * sizeof (gpointer)), FALSE);
2283 ptr = LLVMBuildAdd (builder, convert (ctx, info_var, IntPtrType ()), convert (ctx, offset, IntPtrType ()), "");
2285 name = g_strdup_printf ("gsharedvt_local_%d_offset", vreg);
2286 offset_var = LLVMBuildLoad (builder, convert (ctx, ptr, LLVMPointerType (LLVMInt32Type (), 0)), name);
2288 return LLVMBuildAdd (builder, convert (ctx, locals_var, IntPtrType ()), convert (ctx, offset_var, IntPtrType ()), "");
2292 * Put the global into the 'llvm.used' array to prevent it from being optimized away.
2295 mark_as_used (MonoLLVMModule *module, LLVMValueRef global)
2298 module->used = g_ptr_array_sized_new (16);
2299 g_ptr_array_add (module->used, global);
2303 emit_llvm_used (MonoLLVMModule *module)
2305 LLVMModuleRef lmodule = module->lmodule;
2306 LLVMTypeRef used_type;
2307 LLVMValueRef used, *used_elem;
2313 used_type = LLVMArrayType (LLVMPointerType (LLVMInt8Type (), 0), module->used->len);
2314 used = LLVMAddGlobal (lmodule, used_type, "llvm.used");
2315 used_elem = g_new0 (LLVMValueRef, module->used->len);
2316 for (i = 0; i < module->used->len; ++i)
2317 used_elem [i] = LLVMConstBitCast ((LLVMValueRef)g_ptr_array_index (module->used, i), LLVMPointerType (LLVMInt8Type (), 0));
2318 LLVMSetInitializer (used, LLVMConstArray (LLVMPointerType (LLVMInt8Type (), 0), used_elem, module->used->len));
2319 LLVMSetLinkage (used, LLVMAppendingLinkage);
2320 LLVMSetSection (used, "llvm.metadata");
2326 * Emit a function mapping method indexes to their code
2329 emit_get_method (MonoLLVMModule *module)
2331 LLVMModuleRef lmodule = module->lmodule;
2332 LLVMValueRef func, switch_ins, m;
2333 LLVMBasicBlockRef entry_bb, fail_bb, bb, code_start_bb, code_end_bb;
2334 LLVMBasicBlockRef *bbs;
2336 LLVMBuilderRef builder;
2341 * Emit a switch statement. Emitting a table of function addresses is smaller/faster,
2342 * but generating code seems safer.
2344 rtype = LLVMPointerType (LLVMInt8Type (), 0);
2345 func = LLVMAddFunction (lmodule, module->get_method_symbol, LLVMFunctionType1 (rtype, LLVMInt32Type (), FALSE));
2346 LLVMSetLinkage (func, LLVMExternalLinkage);
2347 LLVMSetVisibility (func, LLVMHiddenVisibility);
2348 LLVMAddFunctionAttr (func, LLVMNoUnwindAttribute);
2349 module->get_method = func;
2351 entry_bb = LLVMAppendBasicBlock (func, "ENTRY");
2354 * Return llvm_code_start/llvm_code_end when called with -1/-2.
2355 * Hopefully, the toolchain doesn't reorder these functions. If it does,
2356 * then we will have to find another solution.
2359 name = g_strdup_printf ("BB_CODE_START");
2360 code_start_bb = LLVMAppendBasicBlock (func, name);
2362 builder = LLVMCreateBuilder ();
2363 LLVMPositionBuilderAtEnd (builder, code_start_bb);
2364 LLVMBuildRet (builder, LLVMBuildBitCast (builder, module->code_start, rtype, ""));
2366 name = g_strdup_printf ("BB_CODE_END");
2367 code_end_bb = LLVMAppendBasicBlock (func, name);
2369 builder = LLVMCreateBuilder ();
2370 LLVMPositionBuilderAtEnd (builder, code_end_bb);
2371 LLVMBuildRet (builder, LLVMBuildBitCast (builder, module->code_end, rtype, ""));
2373 bbs = g_new0 (LLVMBasicBlockRef, module->max_method_idx + 1);
2374 for (i = 0; i < module->max_method_idx + 1; ++i) {
2375 name = g_strdup_printf ("BB_%d", i);
2376 bb = LLVMAppendBasicBlock (func, name);
2380 builder = LLVMCreateBuilder ();
2381 LLVMPositionBuilderAtEnd (builder, bb);
2383 m = (LLVMValueRef)g_hash_table_lookup (module->idx_to_lmethod, GINT_TO_POINTER (i));
2385 LLVMBuildRet (builder, LLVMBuildBitCast (builder, m, rtype, ""));
2387 LLVMBuildRet (builder, LLVMConstNull (rtype));
2390 fail_bb = LLVMAppendBasicBlock (func, "FAIL");
2391 builder = LLVMCreateBuilder ();
2392 LLVMPositionBuilderAtEnd (builder, fail_bb);
2393 LLVMBuildRet (builder, LLVMConstNull (rtype));
2395 builder = LLVMCreateBuilder ();
2396 LLVMPositionBuilderAtEnd (builder, entry_bb);
2398 switch_ins = LLVMBuildSwitch (builder, LLVMGetParam (func, 0), fail_bb, 0);
2399 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), -1, FALSE), code_start_bb);
2400 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), -2, FALSE), code_end_bb);
2401 for (i = 0; i < module->max_method_idx + 1; ++i) {
2402 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), i, FALSE), bbs [i]);
2405 mark_as_used (module, func);
2409 * emit_get_unbox_tramp:
2411 * Emit a function mapping method indexes to their unbox trampoline
2414 emit_get_unbox_tramp (MonoLLVMModule *module)
2416 LLVMModuleRef lmodule = module->lmodule;
2417 LLVMValueRef func, switch_ins, m;
2418 LLVMBasicBlockRef entry_bb, fail_bb, bb;
2419 LLVMBasicBlockRef *bbs;
2421 LLVMBuilderRef builder;
2425 /* Similar to emit_get_method () */
2427 rtype = LLVMPointerType (LLVMInt8Type (), 0);
2428 func = LLVMAddFunction (lmodule, module->get_unbox_tramp_symbol, LLVMFunctionType1 (rtype, LLVMInt32Type (), FALSE));
2429 LLVMSetLinkage (func, LLVMExternalLinkage);
2430 LLVMSetVisibility (func, LLVMHiddenVisibility);
2431 LLVMAddFunctionAttr (func, LLVMNoUnwindAttribute);
2432 module->get_unbox_tramp = func;
2434 entry_bb = LLVMAppendBasicBlock (func, "ENTRY");
2436 bbs = g_new0 (LLVMBasicBlockRef, module->max_method_idx + 1);
2437 for (i = 0; i < module->max_method_idx + 1; ++i) {
2438 m = (LLVMValueRef)g_hash_table_lookup (module->idx_to_unbox_tramp, GINT_TO_POINTER (i));
2442 name = g_strdup_printf ("BB_%d", i);
2443 bb = LLVMAppendBasicBlock (func, name);
2447 builder = LLVMCreateBuilder ();
2448 LLVMPositionBuilderAtEnd (builder, bb);
2450 LLVMBuildRet (builder, LLVMBuildBitCast (builder, m, rtype, ""));
2453 fail_bb = LLVMAppendBasicBlock (func, "FAIL");
2454 builder = LLVMCreateBuilder ();
2455 LLVMPositionBuilderAtEnd (builder, fail_bb);
2456 LLVMBuildRet (builder, LLVMConstNull (rtype));
2458 builder = LLVMCreateBuilder ();
2459 LLVMPositionBuilderAtEnd (builder, entry_bb);
2461 switch_ins = LLVMBuildSwitch (builder, LLVMGetParam (func, 0), fail_bb, 0);
2462 for (i = 0; i < module->max_method_idx + 1; ++i) {
2463 m = (LLVMValueRef)g_hash_table_lookup (module->idx_to_unbox_tramp, GINT_TO_POINTER (i));
2467 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), i, FALSE), bbs [i]);
2470 mark_as_used (module, func);
2473 /* Add a function to mark the beginning of LLVM code */
2475 emit_llvm_code_start (MonoLLVMModule *module)
2477 LLVMModuleRef lmodule = module->lmodule;
2479 LLVMBasicBlockRef entry_bb;
2480 LLVMBuilderRef builder;
2482 func = LLVMAddFunction (lmodule, "llvm_code_start", LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE));
2483 LLVMSetLinkage (func, LLVMInternalLinkage);
2484 LLVMAddFunctionAttr (func, LLVMNoUnwindAttribute);
2485 module->code_start = func;
2486 entry_bb = LLVMAppendBasicBlock (func, "ENTRY");
2487 builder = LLVMCreateBuilder ();
2488 LLVMPositionBuilderAtEnd (builder, entry_bb);
2489 LLVMBuildRetVoid (builder);
2493 emit_init_icall_wrapper (MonoLLVMModule *module, const char *name, const char *icall_name, int subtype)
2495 LLVMModuleRef lmodule = module->lmodule;
2496 LLVMValueRef func, indexes [2], got_entry_addr, args [16], callee;
2497 LLVMBasicBlockRef entry_bb;
2498 LLVMBuilderRef builder;
2505 func = LLVMAddFunction (lmodule, name, LLVMFunctionType1 (LLVMVoidType (), LLVMInt32Type (), FALSE));
2506 sig = LLVMFunctionType2 (LLVMVoidType (), IntPtrType (), LLVMInt32Type (), FALSE);
2511 func = LLVMAddFunction (lmodule, name, LLVMFunctionType2 (LLVMVoidType (), LLVMInt32Type (), IntPtrType (), FALSE));
2512 sig = LLVMFunctionType3 (LLVMVoidType (), IntPtrType (), LLVMInt32Type (), IntPtrType (), FALSE);
2515 func = LLVMAddFunction (lmodule, name, LLVMFunctionType2 (LLVMVoidType (), LLVMInt32Type (), ObjRefType (), FALSE));
2516 sig = LLVMFunctionType3 (LLVMVoidType (), IntPtrType (), LLVMInt32Type (), ObjRefType (), FALSE);
2519 g_assert_not_reached ();
2521 LLVMSetLinkage (func, LLVMInternalLinkage);
2522 LLVMAddFunctionAttr (func, LLVMNoInlineAttribute);
2523 mono_llvm_set_preserveall_cc (func);
2524 entry_bb = LLVMAppendBasicBlock (func, "ENTRY");
2525 builder = LLVMCreateBuilder ();
2526 LLVMPositionBuilderAtEnd (builder, entry_bb);
2529 ji = g_new0 (MonoJumpInfo, 1);
2530 ji->type = MONO_PATCH_INFO_AOT_MODULE;
2531 ji = mono_aot_patch_info_dup (ji);
2532 got_offset = mono_aot_get_got_offset (ji);
2533 module->max_got_offset = MAX (module->max_got_offset, got_offset);
2534 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
2535 indexes [1] = LLVMConstInt (LLVMInt32Type (), got_offset, FALSE);
2536 got_entry_addr = LLVMBuildGEP (builder, module->got_var, indexes, 2, "");
2537 args [0] = LLVMBuildPtrToInt (builder, LLVMBuildLoad (builder, got_entry_addr, ""), IntPtrType (), "");
2538 args [1] = LLVMGetParam (func, 0);
2540 args [2] = LLVMGetParam (func, 1);
2542 ji = g_new0 (MonoJumpInfo, 1);
2543 ji->type = MONO_PATCH_INFO_INTERNAL_METHOD;
2544 ji->data.name = icall_name;
2545 ji = mono_aot_patch_info_dup (ji);
2546 got_offset = mono_aot_get_got_offset (ji);
2547 module->max_got_offset = MAX (module->max_got_offset, got_offset);
2548 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
2549 indexes [1] = LLVMConstInt (LLVMInt32Type (), got_offset, FALSE);
2550 got_entry_addr = LLVMBuildGEP (builder, module->got_var, indexes, 2, "");
2551 callee = LLVMBuildLoad (builder, got_entry_addr, "");
2552 callee = LLVMBuildBitCast (builder, callee, LLVMPointerType (sig, 0), "");
2553 LLVMBuildCall (builder, callee, args, LLVMCountParamTypes (sig), "");
2555 // Set the inited flag
2556 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
2557 indexes [1] = LLVMGetParam (func, 0);
2558 LLVMBuildStore (builder, LLVMConstInt (LLVMInt8Type (), 1, FALSE), LLVMBuildGEP (builder, module->inited_var, indexes, 2, ""));
2560 LLVMBuildRetVoid (builder);
2562 LLVMVerifyFunction(func, LLVMAbortProcessAction);
2567 * Emit wrappers around the C icalls used to initialize llvm methods, to
2568 * make the calling code smaller and to enable usage of the llvm
2569 * PreserveAll calling convention.
2572 emit_init_icall_wrappers (MonoLLVMModule *module)
2574 module->init_method = emit_init_icall_wrapper (module, "init_method", "mono_aot_init_llvm_method", 0);
2575 module->init_method_gshared_mrgctx = emit_init_icall_wrapper (module, "init_method_gshared_mrgctx", "mono_aot_init_gshared_method_mrgctx", 1);
2576 module->init_method_gshared_this = emit_init_icall_wrapper (module, "init_method_gshared_this", "mono_aot_init_gshared_method_this", 2);
2577 module->init_method_gshared_vtable = emit_init_icall_wrapper (module, "init_method_gshared_vtable", "mono_aot_init_gshared_method_vtable", 3);
2581 emit_llvm_code_end (MonoLLVMModule *module)
2583 LLVMModuleRef lmodule = module->lmodule;
2585 LLVMBasicBlockRef entry_bb;
2586 LLVMBuilderRef builder;
2588 func = LLVMAddFunction (lmodule, "llvm_code_end", LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE));
2589 LLVMSetLinkage (func, LLVMInternalLinkage);
2590 LLVMAddFunctionAttr (func, LLVMNoUnwindAttribute);
2591 module->code_end = func;
2592 entry_bb = LLVMAppendBasicBlock (func, "ENTRY");
2593 builder = LLVMCreateBuilder ();
2594 LLVMPositionBuilderAtEnd (builder, entry_bb);
2595 LLVMBuildRetVoid (builder);
2599 emit_div_check (EmitContext *ctx, LLVMBuilderRef builder, MonoBasicBlock *bb, MonoInst *ins, LLVMValueRef lhs, LLVMValueRef rhs)
2601 gboolean need_div_check = ctx->cfg->backend->need_div_check;
2604 /* LLVM doesn't know that these can throw an exception since they are not called through an intrinsic */
2605 need_div_check = TRUE;
2607 if (!need_div_check)
2610 switch (ins->opcode) {
2623 case OP_IDIV_UN_IMM:
2624 case OP_LDIV_UN_IMM:
2625 case OP_IREM_UN_IMM:
2626 case OP_LREM_UN_IMM: {
2628 gboolean is_signed = (ins->opcode == OP_IDIV || ins->opcode == OP_LDIV || ins->opcode == OP_IREM || ins->opcode == OP_LREM ||
2629 ins->opcode == OP_IDIV_IMM || ins->opcode == OP_LDIV_IMM || ins->opcode == OP_IREM_IMM || ins->opcode == OP_LREM_IMM);
2631 cmp = LLVMBuildICmp (builder, LLVMIntEQ, rhs, LLVMConstInt (LLVMTypeOf (rhs), 0, FALSE), "");
2632 emit_cond_system_exception (ctx, bb, "DivideByZeroException", cmp);
2633 CHECK_FAILURE (ctx);
2634 builder = ctx->builder;
2636 /* b == -1 && a == 0x80000000 */
2638 LLVMValueRef c = (LLVMTypeOf (lhs) == LLVMInt32Type ()) ? LLVMConstInt (LLVMTypeOf (lhs), 0x80000000, FALSE) : LLVMConstInt (LLVMTypeOf (lhs), 0x8000000000000000LL, FALSE);
2639 LLVMValueRef cond1 = LLVMBuildICmp (builder, LLVMIntEQ, rhs, LLVMConstInt (LLVMTypeOf (rhs), -1, FALSE), "");
2640 LLVMValueRef cond2 = LLVMBuildICmp (builder, LLVMIntEQ, lhs, c, "");
2642 cmp = LLVMBuildICmp (builder, LLVMIntEQ, LLVMBuildAnd (builder, cond1, cond2, ""), LLVMConstInt (LLVMInt1Type (), 1, FALSE), "");
2643 emit_cond_system_exception (ctx, bb, "OverflowException", cmp);
2644 CHECK_FAILURE (ctx);
2645 builder = ctx->builder;
2660 * Emit code to initialize the GOT slots used by the method.
2663 emit_init_method (EmitContext *ctx)
2665 LLVMValueRef indexes [16], args [16], callee;
2666 LLVMValueRef inited_var, cmp, call;
2667 LLVMBasicBlockRef inited_bb, notinited_bb;
2668 LLVMBuilderRef builder = ctx->builder;
2669 MonoCompile *cfg = ctx->cfg;
2671 ctx->module->max_inited_idx = MAX (ctx->module->max_inited_idx, cfg->method_index);
2673 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
2674 indexes [1] = LLVMConstInt (LLVMInt32Type (), cfg->method_index, FALSE);
2675 inited_var = LLVMBuildLoad (builder, LLVMBuildGEP (builder, ctx->module->inited_var, indexes, 2, ""), "is_inited");
2677 args [0] = inited_var;
2678 args [1] = LLVMConstInt (LLVMInt8Type (), 1, FALSE);
2679 inited_var = LLVMBuildCall (ctx->builder, LLVMGetNamedFunction (ctx->lmodule, "llvm.expect.i8"), args, 2, "");
2681 cmp = LLVMBuildICmp (builder, LLVMIntEQ, inited_var, LLVMConstInt (LLVMTypeOf (inited_var), 0, FALSE), "");
2683 inited_bb = ctx->inited_bb;
2684 notinited_bb = gen_bb (ctx, "NOTINITED_BB");
2686 LLVMBuildCondBr (ctx->builder, cmp, notinited_bb, inited_bb);
2688 builder = ctx->builder = create_builder (ctx);
2689 LLVMPositionBuilderAtEnd (ctx->builder, notinited_bb);
2692 if (ctx->rgctx_arg && cfg->method->is_inflated && mono_method_get_context (cfg->method)->method_inst) {
2693 args [0] = LLVMConstInt (LLVMInt32Type (), cfg->method_index, 0);
2694 args [1] = convert (ctx, ctx->rgctx_arg, IntPtrType ());
2695 callee = ctx->module->init_method_gshared_mrgctx;
2696 call = LLVMBuildCall (builder, callee, args, 2, "");
2697 } else if (ctx->rgctx_arg) {
2698 /* A vtable is passed as the rgctx argument */
2699 args [0] = LLVMConstInt (LLVMInt32Type (), cfg->method_index, 0);
2700 args [1] = convert (ctx, ctx->rgctx_arg, IntPtrType ());
2701 callee = ctx->module->init_method_gshared_vtable;
2702 call = LLVMBuildCall (builder, callee, args, 2, "");
2703 } else if (cfg->gshared) {
2704 args [0] = LLVMConstInt (LLVMInt32Type (), cfg->method_index, 0);
2705 args [1] = convert (ctx, ctx->this_arg, ObjRefType ());
2706 callee = ctx->module->init_method_gshared_this;
2707 call = LLVMBuildCall (builder, callee, args, 2, "");
2709 args [0] = LLVMConstInt (LLVMInt32Type (), cfg->method_index, 0);
2710 callee = ctx->module->init_method;
2711 call = LLVMBuildCall (builder, callee, args, 1, "");
2715 * This enables llvm to keep arguments in their original registers/
2716 * scratch registers, since the call will not clobber them.
2718 mono_llvm_set_call_preserveall_cc (call);
2720 LLVMBuildBr (builder, inited_bb);
2721 ctx->bblocks [cfg->bb_entry->block_num].end_bblock = inited_bb;
2723 builder = ctx->builder = create_builder (ctx);
2724 LLVMPositionBuilderAtEnd (ctx->builder, inited_bb);
2728 emit_unbox_tramp (EmitContext *ctx, const char *method_name, LLVMTypeRef method_type, LLVMValueRef method, int method_index)
2731 * Emit unbox trampoline using a tail call
2733 LLVMValueRef tramp, call, *args;
2734 LLVMBuilderRef builder;
2735 LLVMBasicBlockRef lbb;
2736 LLVMCallInfo *linfo;
2740 tramp_name = g_strdup_printf ("ut_%s", method_name);
2741 tramp = LLVMAddFunction (ctx->module->lmodule, tramp_name, method_type);
2742 LLVMSetLinkage (tramp, LLVMInternalLinkage);
2744 // FIXME: Reduce code duplication with mono_llvm_compile_method () etc.
2745 if (!ctx->llvm_only && ctx->rgctx_arg_pindex != -1)
2746 LLVMAddAttribute (LLVMGetParam (tramp, ctx->rgctx_arg_pindex), LLVMInRegAttribute);
2747 if (ctx->cfg->vret_addr) {
2748 LLVMSetValueName (LLVMGetParam (tramp, linfo->vret_arg_pindex), "vret");
2749 if (linfo->ret.storage == LLVMArgVtypeByRef) {
2750 LLVMAddAttribute (LLVMGetParam (tramp, linfo->vret_arg_pindex), LLVMStructRetAttribute);
2751 LLVMAddAttribute (LLVMGetParam (tramp, linfo->vret_arg_pindex), LLVMNoAliasAttribute);
2755 lbb = LLVMAppendBasicBlock (tramp, "");
2756 builder = LLVMCreateBuilder ();
2757 LLVMPositionBuilderAtEnd (builder, lbb);
2759 nargs = LLVMCountParamTypes (method_type);
2760 args = g_new0 (LLVMValueRef, nargs);
2761 for (i = 0; i < nargs; ++i) {
2762 args [i] = LLVMGetParam (tramp, i);
2763 if (i == ctx->this_arg_pindex) {
2764 LLVMTypeRef arg_type = LLVMTypeOf (args [i]);
2766 args [i] = LLVMBuildPtrToInt (builder, args [i], IntPtrType (), "");
2767 args [i] = LLVMBuildAdd (builder, args [i], LLVMConstInt (IntPtrType (), sizeof (MonoObject), FALSE), "");
2768 args [i] = LLVMBuildIntToPtr (builder, args [i], arg_type, "");
2771 call = LLVMBuildCall (builder, method, args, nargs, "");
2772 if (!ctx->llvm_only && ctx->rgctx_arg_pindex != -1)
2773 LLVMAddInstrAttribute (call, 1 + ctx->rgctx_arg_pindex, LLVMInRegAttribute);
2774 if (linfo->ret.storage == LLVMArgVtypeByRef)
2775 LLVMAddInstrAttribute (call, 1 + linfo->vret_arg_pindex, LLVMStructRetAttribute);
2777 //mono_llvm_set_must_tail (call);
2778 if (LLVMGetReturnType (method_type) == LLVMVoidType ())
2779 LLVMBuildRetVoid (builder);
2781 LLVMBuildRet (builder, call);
2783 g_hash_table_insert (ctx->module->idx_to_unbox_tramp, GINT_TO_POINTER (method_index), tramp);
2789 * Emit code to load/convert arguments.
2792 emit_entry_bb (EmitContext *ctx, LLVMBuilderRef builder)
2795 MonoCompile *cfg = ctx->cfg;
2796 MonoMethodSignature *sig = ctx->sig;
2797 LLVMCallInfo *linfo = ctx->linfo;
2801 LLVMBuilderRef old_builder = ctx->builder;
2802 ctx->builder = builder;
2804 ctx->alloca_builder = create_builder (ctx);
2807 * Handle indirect/volatile variables by allocating memory for them
2808 * using 'alloca', and storing their address in a temporary.
2810 for (i = 0; i < cfg->num_varinfo; ++i) {
2811 MonoInst *var = cfg->varinfo [i];
2814 if (var->opcode == OP_GSHAREDVT_LOCAL || var->opcode == OP_GSHAREDVT_ARG_REGOFFSET) {
2815 } 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))) {
2816 vtype = type_to_llvm_type (ctx, var->inst_vtype);
2817 CHECK_FAILURE (ctx);
2818 /* Could be already created by an OP_VPHI */
2819 if (!ctx->addresses [var->dreg]) {
2820 ctx->addresses [var->dreg] = build_alloca (ctx, var->inst_vtype);
2821 //LLVMSetValueName (ctx->addresses [var->dreg], g_strdup_printf ("vreg_loc_%d", var->dreg));
2823 ctx->vreg_cli_types [var->dreg] = var->inst_vtype;
2827 names = g_new (char *, sig->param_count);
2828 mono_method_get_param_names (cfg->method, (const char **) names);
2830 for (i = 0; i < sig->param_count; ++i) {
2831 LLVMArgInfo *ainfo = &linfo->args [i + sig->hasthis];
2832 int reg = cfg->args [i + sig->hasthis]->dreg;
2835 pindex = ainfo->pindex;
2837 switch (ainfo->storage) {
2838 case LLVMArgVtypeInReg:
2839 case LLVMArgAsFpArgs: {
2840 LLVMValueRef args [8];
2843 pindex += ainfo->ndummy_fpargs;
2845 /* The argument is received as a set of int/fp arguments, store them into the real argument */
2846 memset (args, 0, sizeof (args));
2847 if (ainfo->storage == LLVMArgVtypeInReg) {
2848 args [0] = LLVMGetParam (ctx->lmethod, pindex);
2849 if (ainfo->pair_storage [1] != LLVMArgNone)
2850 args [1] = LLVMGetParam (ctx->lmethod, pindex + 1);
2852 g_assert (ainfo->nslots <= 8);
2853 for (j = 0; j < ainfo->nslots; ++j)
2854 args [j] = LLVMGetParam (ctx->lmethod, pindex + j);
2856 ctx->addresses [reg] = build_alloca (ctx, ainfo->type);
2858 emit_args_to_vtype (ctx, builder, ainfo->type, ctx->addresses [reg], ainfo, args);
2860 if (ainfo->storage == LLVMArgVtypeInReg && MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (ainfo->type))) {
2861 /* Treat these as normal values */
2862 ctx->values [reg] = LLVMBuildLoad (builder, ctx->addresses [reg], "");
2866 case LLVMArgVtypeByVal: {
2867 ctx->addresses [reg] = LLVMGetParam (ctx->lmethod, pindex);
2869 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (ainfo->type))) {
2870 /* Treat these as normal values */
2871 ctx->values [reg] = LLVMBuildLoad (builder, ctx->addresses [reg], "");
2875 case LLVMArgVtypeByRef: {
2876 /* The argument is passed by ref */
2877 ctx->addresses [reg] = LLVMGetParam (ctx->lmethod, pindex);
2880 case LLVMArgScalarByRef: {
2882 name = g_strdup_printf ("arg_%s", names [i]);
2884 name = g_strdup_printf ("arg_%d", i);
2885 ctx->values [reg] = LLVMBuildLoad (builder, LLVMGetParam (ctx->lmethod, pindex), name);
2889 case LLVMArgAsIArgs: {
2890 LLVMValueRef arg = LLVMGetParam (ctx->lmethod, pindex);
2892 ctx->addresses [reg] = build_alloca (ctx, ainfo->type);
2894 /* The argument is received as an array of ints, store it into the real argument */
2895 LLVMBuildStore (ctx->builder, arg, convert (ctx, ctx->addresses [reg], LLVMPointerType (LLVMTypeOf (arg), 0)));
2898 case LLVMArgVtypeAsScalar:
2899 g_assert_not_reached ();
2901 case LLVMArgGsharedvtFixed: {
2902 /* These are non-gsharedvt arguments passed by ref, the rest of the IR treats them as scalars */
2903 LLVMValueRef arg = LLVMGetParam (ctx->lmethod, pindex);
2906 name = g_strdup_printf ("arg_%s", names [i]);
2908 name = g_strdup_printf ("arg_%d", i);
2910 ctx->values [reg] = LLVMBuildLoad (builder, convert (ctx, arg, LLVMPointerType (type_to_llvm_type (ctx, ainfo->type), 0)), name);
2913 case LLVMArgGsharedvtFixedVtype: {
2914 LLVMValueRef arg = LLVMGetParam (ctx->lmethod, pindex);
2917 name = g_strdup_printf ("vtype_arg_%s", names [i]);
2919 name = g_strdup_printf ("vtype_arg_%d", i);
2921 /* Non-gsharedvt vtype argument passed by ref, the rest of the IR treats it as a vtype */
2922 g_assert (ctx->addresses [reg]);
2923 LLVMSetValueName (ctx->addresses [reg], name);
2924 LLVMBuildStore (builder, LLVMBuildLoad (builder, convert (ctx, arg, LLVMPointerType (type_to_llvm_type (ctx, ainfo->type), 0)), ""), ctx->addresses [reg]);
2927 case LLVMArgGsharedvtVariable:
2928 /* The IR treats these as variables with addresses */
2929 ctx->addresses [reg] = LLVMGetParam (ctx->lmethod, pindex);
2932 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));
2939 emit_volatile_store (ctx, cfg->vret_addr->dreg);
2941 emit_volatile_store (ctx, cfg->args [0]->dreg);
2942 for (i = 0; i < sig->param_count; ++i)
2943 if (!mini_type_is_vtype (sig->params [i]))
2944 emit_volatile_store (ctx, cfg->args [i + sig->hasthis]->dreg);
2946 if (sig->hasthis && !cfg->rgctx_var && cfg->gshared) {
2947 LLVMValueRef this_alloc;
2950 * The exception handling code needs the location where the this argument was
2951 * stored for gshared methods. We create a separate alloca to hold it, and mark it
2952 * with the "mono.this" custom metadata to tell llvm that it needs to save its
2953 * location into the LSDA.
2955 this_alloc = mono_llvm_build_alloca (builder, ThisType (), LLVMConstInt (LLVMInt32Type (), 1, FALSE), 0, "");
2956 /* This volatile store will keep the alloca alive */
2957 mono_llvm_build_store (builder, ctx->values [cfg->args [0]->dreg], this_alloc, TRUE, LLVM_BARRIER_NONE);
2959 set_metadata_flag (this_alloc, "mono.this");
2962 if (cfg->rgctx_var) {
2963 LLVMValueRef rgctx_alloc, store;
2966 * We handle the rgctx arg similarly to the this pointer.
2968 g_assert (ctx->addresses [cfg->rgctx_var->dreg]);
2969 rgctx_alloc = ctx->addresses [cfg->rgctx_var->dreg];
2970 /* This volatile store will keep the alloca alive */
2971 store = mono_llvm_build_store (builder, convert (ctx, ctx->rgctx_arg, IntPtrType ()), rgctx_alloc, TRUE, LLVM_BARRIER_NONE);
2973 set_metadata_flag (rgctx_alloc, "mono.this");
2976 /* Initialize the method if needed */
2977 if (cfg->compile_aot && ctx->llvm_only) {
2978 /* Emit a location for the initialization code */
2979 ctx->init_bb = gen_bb (ctx, "INIT_BB");
2980 ctx->inited_bb = gen_bb (ctx, "INITED_BB");
2982 LLVMBuildBr (ctx->builder, ctx->init_bb);
2983 builder = ctx->builder = create_builder (ctx);
2984 LLVMPositionBuilderAtEnd (ctx->builder, ctx->inited_bb);
2985 ctx->bblocks [cfg->bb_entry->block_num].end_bblock = ctx->inited_bb;
2988 /* Compute nesting between clauses */
2989 ctx->nested_in = (GSList**)mono_mempool_alloc0 (cfg->mempool, sizeof (GSList*) * cfg->header->num_clauses);
2990 for (i = 0; i < cfg->header->num_clauses; ++i) {
2991 for (j = 0; j < cfg->header->num_clauses; ++j) {
2992 MonoExceptionClause *clause1 = &cfg->header->clauses [i];
2993 MonoExceptionClause *clause2 = &cfg->header->clauses [j];
2995 if (i != j && clause1->try_offset >= clause2->try_offset && clause1->handler_offset <= clause2->handler_offset)
2996 ctx->nested_in [i] = g_slist_prepend_mempool (cfg->mempool, ctx->nested_in [i], GINT_TO_POINTER (j));
3001 * For finally clauses, create an indicator variable telling OP_ENDFINALLY whenever
3002 * it needs to continue normally, or return back to the exception handling system.
3004 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
3008 if (!(bb->region != -1 && (bb->flags & BB_EXCEPTION_HANDLER)))
3011 clause_index = MONO_REGION_CLAUSE_INDEX (bb->region);
3012 g_hash_table_insert (ctx->region_to_handler, GUINT_TO_POINTER (mono_get_block_region_notry (cfg, bb->region)), bb);
3013 g_hash_table_insert (ctx->clause_to_handler, GINT_TO_POINTER (clause_index), bb);
3015 if (bb->in_scount == 0) {
3018 sprintf (name, "finally_ind_bb%d", bb->block_num);
3019 val = LLVMBuildAlloca (builder, LLVMInt32Type (), name);
3020 LLVMBuildStore (builder, LLVMConstInt (LLVMInt32Type (), 0, FALSE), val);
3022 ctx->bblocks [bb->block_num].finally_ind = val;
3024 /* Create a variable to hold the exception var */
3026 ctx->ex_var = LLVMBuildAlloca (builder, ObjRefType (), "exvar");
3030 * Create a new bblock which CALL_HANDLER/landing pads can branch to, because branching to the
3031 * LLVM bblock containing a landing pad causes problems for the
3032 * LLVM optimizer passes.
3034 sprintf (name, "BB%d_CALL_HANDLER_TARGET", bb->block_num);
3035 ctx->bblocks [bb->block_num].call_handler_target_bb = LLVMAppendBasicBlock (ctx->lmethod, name);
3042 ctx->builder = old_builder;
3046 process_call (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, MonoInst *ins)
3048 MonoCompile *cfg = ctx->cfg;
3049 LLVMModuleRef lmodule = ctx->lmodule;
3050 LLVMValueRef *values = ctx->values;
3051 LLVMValueRef *addresses = ctx->addresses;
3052 MonoCallInst *call = (MonoCallInst*)ins;
3053 MonoMethodSignature *sig = call->signature;
3054 LLVMValueRef callee = NULL, lcall;
3056 LLVMCallInfo *cinfo;
3060 LLVMTypeRef llvm_sig;
3062 gboolean is_virtual, calli, preserveall;
3063 LLVMBuilderRef builder = *builder_ref;
3065 if (call->signature->call_convention != MONO_CALL_DEFAULT)
3066 LLVM_FAILURE (ctx, "non-default callconv");
3068 cinfo = call->cinfo;
3070 if (call->rgctx_arg_reg)
3071 cinfo->rgctx_arg = TRUE;
3072 if (call->imt_arg_reg)
3073 cinfo->imt_arg = TRUE;
3075 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);
3077 llvm_sig = sig_to_llvm_sig_full (ctx, sig, cinfo);
3078 CHECK_FAILURE (ctx);
3080 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);
3081 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);
3083 preserveall = FALSE;
3085 /* FIXME: Avoid creating duplicate methods */
3087 if (ins->flags & MONO_INST_HAS_METHOD) {
3091 if (cfg->compile_aot) {
3092 callee = get_callee (ctx, llvm_sig, MONO_PATCH_INFO_METHOD, call->method);
3094 LLVM_FAILURE (ctx, "can't encode patch");
3096 if (cfg->llvm_only && call->method->klass->image->assembly == ctx->module->assembly) {
3098 * Collect instructions representing the callee into a hash so they can be replaced
3099 * by the llvm method for the callee if the callee turns out to be direct
3100 * callable. Currently this only requires it to not fail llvm compilation.
3102 GSList *l = (GSList*)g_hash_table_lookup (ctx->method_to_callers, call->method);
3103 l = g_slist_prepend (l, callee);
3104 g_hash_table_insert (ctx->method_to_callers, call->method, l);
3107 callee = LLVMAddFunction (lmodule, "", llvm_sig);
3110 mono_create_jit_trampoline_in_domain (mono_domain_get (),
3112 LLVMAddGlobalMapping (ctx->module->ee, callee, target);
3116 if (!cfg->llvm_only && call->method && strstr (call->method->klass->name, "AsyncVoidMethodBuilder"))
3117 /* LLVM miscompiles async methods */
3118 LLVM_FAILURE (ctx, "#13734");
3121 MonoJitICallInfo *info = mono_find_jit_icall_by_addr (call->fptr);
3127 memset (&ji, 0, sizeof (ji));
3128 ji.type = MONO_PATCH_INFO_JIT_ICALL_ADDR;
3129 ji.data.target = info->name;
3131 target = mono_resolve_patch_target (cfg->method, cfg->domain, NULL, &ji, FALSE);
3133 if (cfg->compile_aot) {
3134 callee = get_callee (ctx, llvm_sig, MONO_PATCH_INFO_INTERNAL_METHOD, (char*)info->name);
3136 LLVM_FAILURE (ctx, "can't encode patch");
3138 callee = LLVMAddFunction (lmodule, "", llvm_sig);
3139 target = (gpointer)mono_icall_get_wrapper (info);
3140 LLVMAddGlobalMapping (ctx->module->ee, callee, target);
3143 if (cfg->compile_aot) {
3145 if (cfg->abs_patches) {
3146 MonoJumpInfo *abs_ji = (MonoJumpInfo*)g_hash_table_lookup (cfg->abs_patches, call->fptr);
3148 callee = get_callee (ctx, llvm_sig, abs_ji->type, abs_ji->data.target);
3150 LLVM_FAILURE (ctx, "can't encode patch");
3154 LLVM_FAILURE (ctx, "aot");
3156 callee = LLVMAddFunction (lmodule, "", llvm_sig);
3158 if (cfg->abs_patches) {
3159 MonoJumpInfo *abs_ji = (MonoJumpInfo*)g_hash_table_lookup (cfg->abs_patches, call->fptr);
3162 * FIXME: Some trampolines might have
3163 * their own calling convention on some platforms.
3165 #ifndef TARGET_AMD64
3166 if (abs_ji->type == MONO_PATCH_INFO_MONITOR_ENTER || abs_ji->type == MONO_PATCH_INFO_MONITOR_ENTER_V4 ||
3167 abs_ji->type == MONO_PATCH_INFO_MONITOR_EXIT)
3168 LLVM_FAILURE (ctx, "trampoline with own cconv");
3170 target = mono_resolve_patch_target (cfg->method, cfg->domain, NULL, abs_ji, FALSE);
3171 LLVMAddGlobalMapping (ctx->module->ee, callee, target);
3175 LLVMAddGlobalMapping (ctx->module->ee, callee, (gpointer)call->fptr);
3181 int size = sizeof (gpointer);
3184 g_assert (ins->inst_offset % size == 0);
3185 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
3187 callee = convert (ctx, LLVMBuildLoad (builder, LLVMBuildGEP (builder, convert (ctx, values [ins->inst_basereg], LLVMPointerType (LLVMPointerType (IntPtrType (), 0), 0)), &index, 1, ""), ""), LLVMPointerType (llvm_sig, 0));
3189 callee = convert (ctx, values [ins->sreg1], LLVMPointerType (llvm_sig, 0));
3191 if (ins->flags & MONO_INST_HAS_METHOD) {
3196 * Collect and convert arguments
3198 nargs = (sig->param_count * 16) + sig->hasthis + vretaddr + call->rgctx_reg + call->imt_arg_reg;
3199 len = sizeof (LLVMValueRef) * nargs;
3200 args = (LLVMValueRef*)alloca (len);
3201 memset (args, 0, len);
3202 l = call->out_ireg_args;
3204 if (call->rgctx_arg_reg) {
3205 g_assert (values [call->rgctx_arg_reg]);
3206 g_assert (cinfo->rgctx_arg_pindex < nargs);
3208 * On ARM, the imt/rgctx argument is passed in a caller save register, but some of our trampolines etc. clobber it, leading to
3209 * problems is LLVM moves the arg assignment earlier. To work around this, save the argument into a stack slot and load
3210 * it using a volatile load.
3213 if (!ctx->imt_rgctx_loc)
3214 ctx->imt_rgctx_loc = build_alloca_llvm_type (ctx, ctx->module->ptr_type, sizeof (gpointer));
3215 LLVMBuildStore (builder, convert (ctx, ctx->values [call->rgctx_arg_reg], ctx->module->ptr_type), ctx->imt_rgctx_loc);
3216 args [cinfo->rgctx_arg_pindex] = mono_llvm_build_load (builder, ctx->imt_rgctx_loc, "", TRUE, LLVM_BARRIER_NONE);
3218 args [cinfo->rgctx_arg_pindex] = convert (ctx, values [call->rgctx_arg_reg], ctx->module->ptr_type);
3221 if (call->imt_arg_reg) {
3222 g_assert (!ctx->llvm_only);
3223 g_assert (values [call->imt_arg_reg]);
3224 g_assert (cinfo->imt_arg_pindex < nargs);
3226 if (!ctx->imt_rgctx_loc)
3227 ctx->imt_rgctx_loc = build_alloca_llvm_type (ctx, ctx->module->ptr_type, sizeof (gpointer));
3228 LLVMBuildStore (builder, convert (ctx, ctx->values [call->imt_arg_reg], ctx->module->ptr_type), ctx->imt_rgctx_loc);
3229 args [cinfo->imt_arg_pindex] = mono_llvm_build_load (builder, ctx->imt_rgctx_loc, "", TRUE, LLVM_BARRIER_NONE);
3231 args [cinfo->imt_arg_pindex] = convert (ctx, values [call->imt_arg_reg], ctx->module->ptr_type);
3234 switch (cinfo->ret.storage) {
3235 case LLVMArgGsharedvtVariable: {
3236 MonoInst *var = get_vreg_to_inst (cfg, call->inst.dreg);
3238 if (var && var->opcode == OP_GSHAREDVT_LOCAL) {
3239 args [cinfo->vret_arg_pindex] = convert (ctx, emit_gsharedvt_ldaddr (ctx, var->dreg), IntPtrType ());
3241 g_assert (addresses [call->inst.dreg]);
3242 args [cinfo->vret_arg_pindex] = addresses [call->inst.dreg];
3248 if (!addresses [call->inst.dreg])
3249 addresses [call->inst.dreg] = build_alloca (ctx, sig->ret);
3250 g_assert (cinfo->vret_arg_pindex < nargs);
3251 if (cinfo->ret.storage == LLVMArgVtypeByRef)
3252 args [cinfo->vret_arg_pindex] = addresses [call->inst.dreg];
3254 args [cinfo->vret_arg_pindex] = LLVMBuildPtrToInt (builder, addresses [call->inst.dreg], IntPtrType (), "");
3260 * Sometimes the same method is called with two different signatures (i.e. with and without 'this'), so
3261 * use the real callee for argument type conversion.
3263 LLVMTypeRef callee_type = LLVMGetElementType (LLVMTypeOf (callee));
3264 LLVMTypeRef *param_types = (LLVMTypeRef*)g_alloca (sizeof (LLVMTypeRef) * LLVMCountParamTypes (callee_type));
3265 LLVMGetParamTypes (callee_type, param_types);
3267 for (i = 0; i < sig->param_count + sig->hasthis; ++i) {
3270 LLVMArgInfo *ainfo = &call->cinfo->args [i];
3272 pindex = ainfo->pindex;
3274 regpair = (guint32)(gssize)(l->data);
3275 reg = regpair & 0xffffff;
3276 args [pindex] = values [reg];
3277 switch (ainfo->storage) {
3278 case LLVMArgVtypeInReg:
3279 case LLVMArgAsFpArgs: {
3283 for (j = 0; j < ainfo->ndummy_fpargs; ++j)
3284 args [pindex + j] = LLVMConstNull (LLVMDoubleType ());
3285 pindex += ainfo->ndummy_fpargs;
3287 g_assert (addresses [reg]);
3288 emit_vtype_to_args (ctx, builder, ainfo->type, addresses [reg], ainfo, args + pindex, &nargs);
3292 // FIXME: Get rid of the VMOVE
3295 case LLVMArgVtypeByVal:
3296 g_assert (addresses [reg]);
3297 args [pindex] = addresses [reg];
3299 case LLVMArgVtypeByRef:
3300 case LLVMArgScalarByRef: {
3301 g_assert (addresses [reg]);
3302 args [pindex] = convert (ctx, addresses [reg], LLVMPointerType (type_to_llvm_arg_type (ctx, ainfo->type), 0));
3305 case LLVMArgAsIArgs:
3306 g_assert (addresses [reg]);
3307 args [pindex] = LLVMBuildLoad (ctx->builder, convert (ctx, addresses [reg], LLVMPointerType (LLVMArrayType (IntPtrType (), ainfo->nslots), 0)), "");
3309 case LLVMArgVtypeAsScalar:
3310 g_assert_not_reached ();
3312 case LLVMArgGsharedvtFixed:
3313 case LLVMArgGsharedvtFixedVtype:
3314 g_assert (addresses [reg]);
3315 args [pindex] = convert (ctx, addresses [reg], LLVMPointerType (type_to_llvm_arg_type (ctx, ainfo->type), 0));
3317 case LLVMArgGsharedvtVariable:
3318 g_assert (addresses [reg]);
3319 args [pindex] = convert (ctx, addresses [reg], LLVMPointerType (IntPtrType (), 0));
3322 g_assert (args [pindex]);
3323 if (i == 0 && sig->hasthis)
3324 args [pindex] = convert (ctx, args [pindex], param_types [pindex]);
3326 args [pindex] = convert (ctx, args [pindex], type_to_llvm_arg_type (ctx, ainfo->type));
3329 g_assert (pindex <= nargs);
3334 // FIXME: Align call sites
3340 lcall = emit_call (ctx, bb, &builder, callee, args, LLVMCountParamTypes (llvm_sig));
3343 * Modify cconv and parameter attributes to pass rgctx/imt correctly.
3345 #if defined(MONO_ARCH_IMT_REG) && defined(MONO_ARCH_RGCTX_REG)
3346 g_assert (MONO_ARCH_IMT_REG == MONO_ARCH_RGCTX_REG);
3348 /* The two can't be used together, so use only one LLVM calling conv to pass them */
3349 g_assert (!(call->rgctx_arg_reg && call->imt_arg_reg));
3350 if (!sig->pinvoke && !cfg->llvm_only)
3351 LLVMSetInstructionCallConv (lcall, LLVMMono1CallConv);
3353 mono_llvm_set_call_preserveall_cc (lcall);
3355 if (cinfo->ret.storage == LLVMArgVtypeByRef)
3356 LLVMAddInstrAttribute (lcall, 1 + cinfo->vret_arg_pindex, LLVMStructRetAttribute);
3357 if (!ctx->llvm_only && call->rgctx_arg_reg)
3358 LLVMAddInstrAttribute (lcall, 1 + cinfo->rgctx_arg_pindex, LLVMInRegAttribute);
3359 if (call->imt_arg_reg)
3360 LLVMAddInstrAttribute (lcall, 1 + cinfo->imt_arg_pindex, LLVMInRegAttribute);
3362 /* Add byval attributes if needed */
3363 for (i = 0; i < sig->param_count; ++i) {
3364 LLVMArgInfo *ainfo = &call->cinfo->args [i + sig->hasthis];
3366 if (ainfo && ainfo->storage == LLVMArgVtypeByVal)
3367 LLVMAddInstrAttribute (lcall, 1 + ainfo->pindex, LLVMByValAttribute);
3371 * Convert the result
3373 switch (cinfo->ret.storage) {
3374 case LLVMArgVtypeInReg: {
3375 LLVMValueRef regs [2];
3377 if (LLVMTypeOf (lcall) == LLVMVoidType ())
3381 if (!addresses [ins->dreg])
3382 addresses [ins->dreg] = build_alloca (ctx, sig->ret);
3384 regs [0] = LLVMBuildExtractValue (builder, lcall, 0, "");
3385 if (cinfo->ret.pair_storage [1] != LLVMArgNone)
3386 regs [1] = LLVMBuildExtractValue (builder, lcall, 1, "");
3387 emit_args_to_vtype (ctx, builder, sig->ret, addresses [ins->dreg], &cinfo->ret, regs);
3390 case LLVMArgVtypeByVal:
3391 if (!addresses [call->inst.dreg])
3392 addresses [call->inst.dreg] = build_alloca (ctx, sig->ret);
3393 LLVMBuildStore (builder, lcall, addresses [call->inst.dreg]);
3395 case LLVMArgFpStruct:
3396 if (!addresses [call->inst.dreg])
3397 addresses [call->inst.dreg] = build_alloca (ctx, sig->ret);
3398 LLVMBuildStore (builder, lcall, convert_full (ctx, addresses [call->inst.dreg], LLVMPointerType (LLVMTypeOf (lcall), 0), FALSE));
3400 case LLVMArgVtypeAsScalar:
3401 if (!addresses [call->inst.dreg])
3402 addresses [call->inst.dreg] = build_alloca (ctx, sig->ret);
3403 LLVMBuildStore (builder, lcall, convert_full (ctx, addresses [call->inst.dreg], LLVMPointerType (LLVMTypeOf (lcall), 0), FALSE));
3405 case LLVMArgVtypeRetAddr:
3406 case LLVMArgVtypeByRef:
3408 case LLVMArgScalarRetAddr:
3409 /* Normal scalar returned using a vtype return argument */
3410 values [ins->dreg] = LLVMBuildLoad (builder, convert_full (ctx, addresses [call->inst.dreg], LLVMPointerType (type_to_llvm_type (ctx, sig->ret), 0), FALSE), "");
3412 case LLVMArgGsharedvtVariable:
3414 case LLVMArgGsharedvtFixed:
3415 case LLVMArgGsharedvtFixedVtype:
3416 values [ins->dreg] = LLVMBuildLoad (builder, convert_full (ctx, addresses [call->inst.dreg], LLVMPointerType (type_to_llvm_type (ctx, sig->ret), 0), FALSE), "");
3419 if (sig->ret->type != MONO_TYPE_VOID)
3420 /* If the method returns an unsigned value, need to zext it */
3421 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));
3425 *builder_ref = ctx->builder;
3433 emit_llvmonly_throw (EmitContext *ctx, MonoBasicBlock *bb, gboolean rethrow, LLVMValueRef exc)
3435 const char *icall_name = rethrow ? "mono_llvm_rethrow_exception" : "mono_llvm_throw_exception";
3436 LLVMValueRef callee = rethrow ? ctx->module->rethrow : ctx->module->throw_icall;
3438 LLVMTypeRef exc_type = type_to_llvm_type (ctx, &mono_get_exception_class ()->byval_arg);
3441 LLVMTypeRef fun_sig = LLVMFunctionType1 (LLVMVoidType (), exc_type, FALSE);
3443 if (ctx->cfg->compile_aot) {
3444 callee = get_callee (ctx, fun_sig, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
3446 callee = LLVMAddFunction (ctx->lmodule, icall_name, fun_sig);
3447 LLVMAddGlobalMapping (ctx->module->ee, callee, resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name));
3448 mono_memory_barrier ();
3451 ctx->module->rethrow = callee;
3453 ctx->module->throw_icall = callee;
3457 LLVMValueRef args [2];
3459 args [0] = convert (ctx, exc, exc_type);
3460 emit_call (ctx, bb, &ctx->builder, callee, args, 1);
3462 LLVMBuildUnreachable (ctx->builder);
3464 ctx->builder = create_builder (ctx);
3468 emit_throw (EmitContext *ctx, MonoBasicBlock *bb, gboolean rethrow, LLVMValueRef exc)
3470 MonoMethodSignature *throw_sig;
3471 LLVMValueRef callee, arg;
3472 const char *icall_name;
3474 callee = rethrow ? ctx->module->rethrow : ctx->module->throw_icall;
3475 icall_name = rethrow ? "mono_arch_rethrow_exception" : "mono_arch_throw_exception";
3478 throw_sig = mono_metadata_signature_alloc (mono_get_corlib (), 1);
3479 throw_sig->ret = &mono_get_void_class ()->byval_arg;
3480 throw_sig->params [0] = &mono_get_object_class ()->byval_arg;
3481 if (ctx->cfg->compile_aot) {
3482 callee = get_callee (ctx, sig_to_llvm_sig (ctx, throw_sig), MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
3484 callee = LLVMAddFunction (ctx->lmodule, icall_name, sig_to_llvm_sig (ctx, throw_sig));
3488 * LLVM doesn't push the exception argument, so we need a different
3491 LLVMAddGlobalMapping (ctx->module->ee, callee, resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, rethrow ? "llvm_rethrow_exception_trampoline" : "llvm_throw_exception_trampoline"));
3493 LLVMAddGlobalMapping (ctx->module->ee, callee, resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name));
3497 mono_memory_barrier ();
3499 ctx->module->rethrow = callee;
3501 ctx->module->throw_icall = callee;
3503 arg = convert (ctx, exc, type_to_llvm_type (ctx, &mono_get_object_class ()->byval_arg));
3504 emit_call (ctx, bb, &ctx->builder, callee, &arg, 1);
3508 emit_resume_eh (EmitContext *ctx, MonoBasicBlock *bb)
3510 const char *icall_name = "mono_llvm_resume_exception";
3511 LLVMValueRef callee = ctx->module->resume_eh;
3513 LLVMTypeRef fun_sig = LLVMFunctionType0 (LLVMVoidType (), FALSE);
3516 if (ctx->cfg->compile_aot) {
3517 callee = get_callee (ctx, fun_sig, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
3519 callee = LLVMAddFunction (ctx->lmodule, icall_name, fun_sig);
3520 LLVMAddGlobalMapping (ctx->module->ee, callee, resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name));
3521 mono_memory_barrier ();
3523 ctx->module->resume_eh = callee;
3527 emit_call (ctx, bb, &ctx->builder, callee, NULL, 0);
3529 LLVMBuildUnreachable (ctx->builder);
3531 ctx->builder = create_builder (ctx);
3535 mono_llvm_emit_clear_exception_call (EmitContext *ctx, LLVMBuilderRef builder)
3537 const char *icall_name = "mono_llvm_clear_exception";
3539 LLVMTypeRef call_sig = LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE);
3540 LLVMValueRef callee = NULL;
3543 if (ctx->cfg->compile_aot) {
3544 callee = get_callee (ctx, call_sig, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
3546 // FIXME: This is broken.
3547 callee = LLVMAddFunction (ctx->lmodule, icall_name, call_sig);
3551 g_assert (builder && callee);
3553 return LLVMBuildCall (builder, callee, NULL, 0, "");
3557 mono_llvm_emit_load_exception_call (EmitContext *ctx, LLVMBuilderRef builder)
3559 const char *icall_name = "mono_llvm_load_exception";
3561 LLVMTypeRef call_sig = LLVMFunctionType (ObjRefType (), NULL, 0, FALSE);
3562 LLVMValueRef callee = NULL;
3565 if (ctx->cfg->compile_aot) {
3566 callee = get_callee (ctx, call_sig, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
3568 // FIXME: This is broken.
3569 callee = LLVMAddFunction (ctx->lmodule, icall_name, call_sig);
3573 g_assert (builder && callee);
3575 return LLVMBuildCall (builder, callee, NULL, 0, icall_name);
3580 mono_llvm_emit_match_exception_call (EmitContext *ctx, LLVMBuilderRef builder, gint32 region_start, gint32 region_end)
3582 const char *icall_name = "mono_llvm_match_exception";
3584 ctx->builder = builder;
3586 const int num_args = 5;
3587 LLVMValueRef args [num_args];
3588 args [0] = convert (ctx, get_aotconst (ctx, MONO_PATCH_INFO_AOT_JIT_INFO, GINT_TO_POINTER (ctx->cfg->method_index)), IntPtrType ());
3589 args [1] = LLVMConstInt (LLVMInt32Type (), region_start, 0);
3590 args [2] = LLVMConstInt (LLVMInt32Type (), region_end, 0);
3591 if (ctx->cfg->rgctx_var) {
3592 LLVMValueRef rgctx_alloc = ctx->addresses [ctx->cfg->rgctx_var->dreg];
3593 g_assert (rgctx_alloc);
3594 args [3] = LLVMBuildLoad (builder, convert (ctx, rgctx_alloc, LLVMPointerType (IntPtrType (), 0)), "");
3596 args [3] = LLVMConstInt (IntPtrType (), 0, 0);
3599 args [4] = convert (ctx, ctx->this_arg, IntPtrType ());
3601 args [4] = LLVMConstInt (IntPtrType (), 0, 0);
3603 LLVMTypeRef match_sig = LLVMFunctionType5 (LLVMInt32Type (), IntPtrType (), LLVMInt32Type (), LLVMInt32Type (), IntPtrType (), IntPtrType (), FALSE);
3604 LLVMValueRef callee = ctx->module->match_exc;
3607 if (ctx->cfg->compile_aot) {
3608 ctx->builder = builder;
3609 // get_callee expects ctx->builder to be the emitting builder
3610 callee = get_callee (ctx, match_sig, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
3612 callee = ctx->module->match_exc = LLVMAddFunction (ctx->lmodule, icall_name, match_sig);
3613 LLVMAddGlobalMapping (ctx->module->ee, ctx->module->match_exc, resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name));
3614 ctx->module->match_exc = callee;
3615 mono_memory_barrier ();
3619 g_assert (builder && callee);
3621 g_assert (ctx->ex_var);
3623 return LLVMBuildCall (builder, callee, args, num_args, icall_name);
3626 // FIXME: This won't work because the code-finding makes this
3628 /*#define MONO_PERSONALITY_DEBUG*/
3630 #ifdef MONO_PERSONALITY_DEBUG
3631 static const gboolean use_debug_personality = TRUE;
3632 static const char *default_personality_name = "mono_debug_personality";
3634 static const gboolean use_debug_personality = FALSE;
3635 static const char *default_personality_name = "__gxx_personality_v0";
3639 default_cpp_lpad_exc_signature (void)
3641 static gboolean inited = FALSE;
3642 static LLVMTypeRef sig;
3645 LLVMTypeRef signature [2];
3646 signature [0] = LLVMPointerType (LLVMInt8Type (), 0);
3647 signature [1] = LLVMInt32Type ();
3648 sig = LLVMStructType (signature, 2, FALSE);
3656 get_mono_personality (EmitContext *ctx)
3658 LLVMValueRef personality = NULL;
3659 static gint32 mapping_inited = FALSE;
3660 LLVMTypeRef personality_type = LLVMFunctionType (LLVMInt32Type (), NULL, 0, TRUE);
3662 if (!use_debug_personality) {
3663 if (ctx->cfg->compile_aot) {
3664 personality = LLVMGetNamedFunction (ctx->lmodule, default_personality_name);
3665 } else if (InterlockedCompareExchange (&mapping_inited, 1, 0) == 0) {
3666 personality = LLVMAddFunction (ctx->lmodule, default_personality_name, personality_type);
3667 LLVMAddGlobalMapping (ctx->module->ee, personality, personality);
3670 if (ctx->cfg->compile_aot) {
3671 personality = get_callee (ctx, personality_type, MONO_PATCH_INFO_INTERNAL_METHOD, default_personality_name);
3673 personality = LLVMAddFunction (ctx->lmodule, default_personality_name, personality_type);
3674 LLVMAddGlobalMapping (ctx->module->ee, personality, resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, default_personality_name));
3675 mono_memory_barrier ();
3679 g_assert (personality);
3683 static LLVMBasicBlockRef
3684 emit_landing_pad (EmitContext *ctx, int group_index, int group_size)
3686 MonoCompile *cfg = ctx->cfg;
3687 LLVMBuilderRef old_builder = ctx->builder;
3688 MonoExceptionClause *group_start = cfg->header->clauses + group_index;
3690 LLVMBuilderRef lpadBuilder = create_builder (ctx);
3691 ctx->builder = lpadBuilder;
3693 MonoBasicBlock *handler_bb = cfg->cil_offset_to_bb [CLAUSE_START (group_start)];
3694 g_assert (handler_bb);
3696 // <resultval> = landingpad <somety> personality <type> <pers_fn> <clause>+
3697 LLVMValueRef personality = get_mono_personality (ctx);
3698 g_assert (personality);
3700 char *bb_name = g_strdup_printf ("LPAD%d_BB", group_index);
3701 LLVMBasicBlockRef lpad_bb = gen_bb (ctx, bb_name);
3703 LLVMPositionBuilderAtEnd (lpadBuilder, lpad_bb);
3704 LLVMValueRef landing_pad = LLVMBuildLandingPad (lpadBuilder, default_cpp_lpad_exc_signature (), personality, 0, "");
3705 g_assert (landing_pad);
3707 LLVMValueRef cast = LLVMBuildBitCast (lpadBuilder, ctx->module->sentinel_exception, LLVMPointerType (LLVMInt8Type (), 0), "int8TypeInfo");
3708 LLVMAddClause (landing_pad, cast);
3710 LLVMBasicBlockRef resume_bb = gen_bb (ctx, "RESUME_BB");
3711 LLVMBuilderRef resume_builder = create_builder (ctx);
3712 ctx->builder = resume_builder;
3713 LLVMPositionBuilderAtEnd (resume_builder, resume_bb);
3715 emit_resume_eh (ctx, handler_bb);
3718 ctx->builder = lpadBuilder;
3719 LLVMPositionBuilderAtEnd (lpadBuilder, lpad_bb);
3721 gboolean finally_only = TRUE;
3723 MonoExceptionClause *group_cursor = group_start;
3725 for (int i = 0; i < group_size; i ++) {
3726 if (!(group_cursor->flags & MONO_EXCEPTION_CLAUSE_FINALLY))
3727 finally_only = FALSE;
3733 // Handle landing pad inlining
3735 if (!finally_only) {
3736 // So at each level of the exception stack we will match the exception again.
3737 // During that match, we need to compare against the handler types for the current
3738 // protected region. We send the try start and end so that we can only check against
3739 // handlers for this lexical protected region.
3740 LLVMValueRef match = mono_llvm_emit_match_exception_call (ctx, lpadBuilder, group_start->try_offset, group_start->try_offset + group_start->try_len);
3742 // if returns -1, resume
3743 LLVMValueRef switch_ins = LLVMBuildSwitch (lpadBuilder, match, resume_bb, group_size);
3745 // else move to that target bb
3746 for (int i=0; i < group_size; i++) {
3747 MonoExceptionClause *clause = group_start + i;
3748 int clause_index = clause - cfg->header->clauses;
3749 MonoBasicBlock *handler_bb = (MonoBasicBlock*)g_hash_table_lookup (ctx->clause_to_handler, GINT_TO_POINTER (clause_index));
3750 g_assert (handler_bb);
3751 g_assert (ctx->bblocks [handler_bb->block_num].call_handler_target_bb);
3752 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), clause_index, FALSE), ctx->bblocks [handler_bb->block_num].call_handler_target_bb);
3755 int clause_index = group_start - cfg->header->clauses;
3756 MonoBasicBlock *finally_bb = (MonoBasicBlock*)g_hash_table_lookup (ctx->clause_to_handler, GINT_TO_POINTER (clause_index));
3757 g_assert (finally_bb);
3759 LLVMBuildBr (ctx->builder, ctx->bblocks [finally_bb->block_num].call_handler_target_bb);
3762 ctx->builder = old_builder;
3769 emit_llvmonly_handler_start (EmitContext *ctx, MonoBasicBlock *bb, LLVMBasicBlockRef cbb)
3771 int clause_index = MONO_REGION_CLAUSE_INDEX (bb->region);
3772 MonoExceptionClause *clause = &ctx->cfg->header->clauses [clause_index];
3774 // Make exception available to catch blocks
3775 if (!(clause->flags & MONO_EXCEPTION_CLAUSE_FINALLY)) {
3776 LLVMValueRef mono_exc = mono_llvm_emit_load_exception_call (ctx, ctx->builder);
3778 g_assert (ctx->ex_var);
3779 LLVMBuildStore (ctx->builder, LLVMBuildBitCast (ctx->builder, mono_exc, ObjRefType (), ""), ctx->ex_var);
3781 if (bb->in_scount == 1) {
3782 MonoInst *exvar = bb->in_stack [0];
3783 g_assert (!ctx->values [exvar->dreg]);
3784 g_assert (ctx->ex_var);
3785 ctx->values [exvar->dreg] = LLVMBuildLoad (ctx->builder, ctx->ex_var, "save_exception");
3786 emit_volatile_store (ctx, exvar->dreg);
3789 mono_llvm_emit_clear_exception_call (ctx, ctx->builder);
3792 LLVMBuilderRef handler_builder = create_builder (ctx);
3793 LLVMBasicBlockRef target_bb = ctx->bblocks [bb->block_num].call_handler_target_bb;
3794 LLVMPositionBuilderAtEnd (handler_builder, target_bb);
3796 // Make the handler code end with a jump to cbb
3797 LLVMBuildBr (handler_builder, cbb);
3801 emit_handler_start (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef builder)
3803 MonoCompile *cfg = ctx->cfg;
3804 LLVMValueRef *values = ctx->values;
3805 LLVMModuleRef lmodule = ctx->lmodule;
3806 BBInfo *bblocks = ctx->bblocks;
3808 LLVMValueRef personality;
3809 LLVMValueRef landing_pad;
3810 LLVMBasicBlockRef target_bb;
3812 static gint32 mapping_inited;
3813 static int ti_generator;
3816 LLVMValueRef type_info;
3820 // <resultval> = landingpad <somety> personality <type> <pers_fn> <clause>+
3822 if (cfg->compile_aot) {
3823 /* Use a dummy personality function */
3824 personality = LLVMGetNamedFunction (lmodule, "mono_personality");
3825 g_assert (personality);
3827 personality = LLVMGetNamedFunction (lmodule, "mono_personality");
3828 if (InterlockedCompareExchange (&mapping_inited, 1, 0) == 0)
3829 LLVMAddGlobalMapping (ctx->module->ee, personality, (gpointer)mono_personality);
3832 i8ptr = LLVMPointerType (LLVMInt8Type (), 0);
3834 clause_index = (mono_get_block_region_notry (cfg, bb->region) >> 8) - 1;
3837 * Create the type info
3839 sprintf (ti_name, "type_info_%d", ti_generator);
3842 if (cfg->compile_aot) {
3843 /* decode_eh_frame () in aot-runtime.c will decode this */
3844 type_info = LLVMAddGlobal (lmodule, LLVMInt32Type (), ti_name);
3845 LLVMSetInitializer (type_info, LLVMConstInt (LLVMInt32Type (), clause_index, FALSE));
3848 * These symbols are not really used, the clause_index is embedded into the EH tables generated by DwarfMonoException in LLVM.
3850 LLVMSetLinkage (type_info, LLVMInternalLinkage);
3853 * After the cfg mempool is freed, the type info will point to stale memory,
3854 * but this is not a problem, since we decode it once in exception_cb during
3857 ti = (gint32*)mono_mempool_alloc (cfg->mempool, sizeof (gint32));
3858 *(gint32*)ti = clause_index;
3860 type_info = LLVMAddGlobal (lmodule, i8ptr, ti_name);
3862 LLVMAddGlobalMapping (ctx->module->ee, type_info, ti);
3866 LLVMTypeRef members [2], ret_type;
3868 members [0] = i8ptr;
3869 members [1] = LLVMInt32Type ();
3870 ret_type = LLVMStructType (members, 2, FALSE);
3872 landing_pad = LLVMBuildLandingPad (builder, ret_type, personality, 1, "");
3873 LLVMAddClause (landing_pad, type_info);
3875 /* Store the exception into the exvar */
3877 LLVMBuildStore (builder, convert (ctx, LLVMBuildExtractValue (builder, landing_pad, 0, "ex_obj"), ObjRefType ()), ctx->ex_var);
3881 * LLVM throw sites are associated with a one landing pad, and LLVM generated
3882 * code expects control to be transferred to this landing pad even in the
3883 * presence of nested clauses. The landing pad needs to branch to the landing
3884 * pads belonging to nested clauses based on the selector value returned by
3885 * the landing pad instruction, which is passed to the landing pad in a
3886 * register by the EH code.
3888 target_bb = bblocks [bb->block_num].call_handler_target_bb;
3889 g_assert (target_bb);
3892 * Branch to the correct landing pad
3894 LLVMValueRef ex_selector = LLVMBuildExtractValue (builder, landing_pad, 1, "ex_selector");
3895 LLVMValueRef switch_ins = LLVMBuildSwitch (builder, ex_selector, target_bb, 0);
3897 for (l = ctx->nested_in [clause_index]; l; l = l->next) {
3898 int nesting_clause_index = GPOINTER_TO_INT (l->data);
3899 MonoBasicBlock *handler_bb;
3901 handler_bb = (MonoBasicBlock*)g_hash_table_lookup (ctx->clause_to_handler, GINT_TO_POINTER (nesting_clause_index));
3902 g_assert (handler_bb);
3904 g_assert (ctx->bblocks [handler_bb->block_num].call_handler_target_bb);
3905 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), nesting_clause_index, FALSE), ctx->bblocks [handler_bb->block_num].call_handler_target_bb);
3908 /* Start a new bblock which CALL_HANDLER can branch to */
3909 target_bb = bblocks [bb->block_num].call_handler_target_bb;
3911 ctx->builder = builder = create_builder (ctx);
3912 LLVMPositionBuilderAtEnd (ctx->builder, target_bb);
3914 ctx->bblocks [bb->block_num].end_bblock = target_bb;
3916 /* Store the exception into the IL level exvar */
3917 if (bb->in_scount == 1) {
3918 g_assert (bb->in_scount == 1);
3919 exvar = bb->in_stack [0];
3921 // FIXME: This is shared with filter clauses ?
3922 g_assert (!values [exvar->dreg]);
3924 g_assert (ctx->ex_var);
3925 values [exvar->dreg] = LLVMBuildLoad (builder, ctx->ex_var, "");
3926 emit_volatile_store (ctx, exvar->dreg);
3932 process_bb (EmitContext *ctx, MonoBasicBlock *bb)
3934 MonoCompile *cfg = ctx->cfg;
3935 MonoMethodSignature *sig = ctx->sig;
3936 LLVMValueRef method = ctx->lmethod;
3937 LLVMValueRef *values = ctx->values;
3938 LLVMValueRef *addresses = ctx->addresses;
3939 LLVMCallInfo *linfo = ctx->linfo;
3940 LLVMModuleRef lmodule = ctx->lmodule;
3941 BBInfo *bblocks = ctx->bblocks;
3943 LLVMBasicBlockRef cbb;
3944 LLVMBuilderRef builder, starting_builder;
3945 gboolean has_terminator;
3947 LLVMValueRef lhs, rhs;
3950 cbb = get_end_bb (ctx, bb);
3952 builder = create_builder (ctx);
3953 ctx->builder = builder;
3954 LLVMPositionBuilderAtEnd (builder, cbb);
3956 CHECK_FAILURE (ctx);
3958 if (bb->flags & BB_EXCEPTION_HANDLER) {
3959 if (!ctx->llvm_only && !bblocks [bb->block_num].invoke_target) {
3960 LLVM_FAILURE (ctx, "handler without invokes");
3964 emit_llvmonly_handler_start (ctx, bb, cbb);
3966 emit_handler_start (ctx, bb, builder);
3967 CHECK_FAILURE (ctx);
3968 builder = ctx->builder;
3971 has_terminator = FALSE;
3972 starting_builder = builder;
3973 for (ins = bb->code; ins; ins = ins->next) {
3974 const char *spec = LLVM_INS_INFO (ins->opcode);
3976 char dname_buf [128];
3978 emit_dbg_loc (ctx, builder, ins->cil_code);
3983 * Some steps in llc are non-linear in the size of basic blocks, see #5714.
3984 * Start a new bblock. If the llvm optimization passes merge these, we
3985 * can work around that by doing a volatile load + cond branch from
3986 * localloc-ed memory.
3988 //LLVM_FAILURE (ctx, "basic block too long");
3989 cbb = gen_bb (ctx, "CONT_LONG_BB");
3990 LLVMBuildBr (ctx->builder, cbb);
3991 ctx->builder = builder = create_builder (ctx);
3992 LLVMPositionBuilderAtEnd (builder, cbb);
3993 ctx->bblocks [bb->block_num].end_bblock = cbb;
3998 /* There could be instructions after a terminator, skip them */
4001 if (spec [MONO_INST_DEST] != ' ' && !MONO_IS_STORE_MEMBASE (ins)) {
4002 sprintf (dname_buf, "t%d", ins->dreg);
4006 if (spec [MONO_INST_SRC1] != ' ' && spec [MONO_INST_SRC1] != 'v') {
4007 MonoInst *var = get_vreg_to_inst (cfg, ins->sreg1);
4009 if (var && var->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT) && var->opcode != OP_GSHAREDVT_ARG_REGOFFSET) {
4010 lhs = emit_volatile_load (ctx, ins->sreg1);
4012 /* It is ok for SETRET to have an uninitialized argument */
4013 if (!values [ins->sreg1] && ins->opcode != OP_SETRET)
4014 LLVM_FAILURE (ctx, "sreg1");
4015 lhs = values [ins->sreg1];
4021 if (spec [MONO_INST_SRC2] != ' ' && spec [MONO_INST_SRC2] != ' ') {
4022 MonoInst *var = get_vreg_to_inst (cfg, ins->sreg2);
4023 if (var && var->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT)) {
4024 rhs = emit_volatile_load (ctx, ins->sreg2);
4026 if (!values [ins->sreg2])
4027 LLVM_FAILURE (ctx, "sreg2");
4028 rhs = values [ins->sreg2];
4034 //mono_print_ins (ins);
4035 switch (ins->opcode) {
4038 case OP_LIVERANGE_START:
4039 case OP_LIVERANGE_END:
4042 values [ins->dreg] = LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE);
4045 #if SIZEOF_VOID_P == 4
4046 values [ins->dreg] = LLVMConstInt (LLVMInt64Type (), GET_LONG_IMM (ins), FALSE);
4048 values [ins->dreg] = LLVMConstInt (LLVMInt64Type (), (gint64)ins->inst_c0, FALSE);
4052 values [ins->dreg] = LLVMConstReal (LLVMDoubleType (), *(double*)ins->inst_p0);
4056 values [ins->dreg] = LLVMConstReal (LLVMFloatType (), *(float*)ins->inst_p0);
4058 values [ins->dreg] = LLVMConstFPExt (LLVMConstReal (LLVMFloatType (), *(float*)ins->inst_p0), LLVMDoubleType ());
4060 case OP_DUMMY_ICONST:
4061 values [ins->dreg] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
4063 case OP_DUMMY_I8CONST:
4064 values [ins->dreg] = LLVMConstInt (LLVMInt64Type (), 0, FALSE);
4066 case OP_DUMMY_R8CONST:
4067 values [ins->dreg] = LLVMConstReal (LLVMDoubleType (), 0.0f);
4070 LLVMBasicBlockRef target_bb = get_bb (ctx, ins->inst_target_bb);
4071 LLVMBuildBr (builder, target_bb);
4072 has_terminator = TRUE;
4079 LLVMBasicBlockRef new_bb;
4080 LLVMBuilderRef new_builder;
4082 // The default branch is already handled
4083 // FIXME: Handle it here
4085 /* Start new bblock */
4086 sprintf (bb_name, "SWITCH_DEFAULT_BB%d", ctx->default_index ++);
4087 new_bb = LLVMAppendBasicBlock (ctx->lmethod, bb_name);
4089 lhs = convert (ctx, lhs, LLVMInt32Type ());
4090 v = LLVMBuildSwitch (builder, lhs, new_bb, GPOINTER_TO_UINT (ins->klass));
4091 for (i = 0; i < GPOINTER_TO_UINT (ins->klass); ++i) {
4092 MonoBasicBlock *target_bb = ins->inst_many_bb [i];
4094 LLVMAddCase (v, LLVMConstInt (LLVMInt32Type (), i, FALSE), get_bb (ctx, target_bb));
4097 new_builder = create_builder (ctx);
4098 LLVMPositionBuilderAtEnd (new_builder, new_bb);
4099 LLVMBuildUnreachable (new_builder);
4101 has_terminator = TRUE;
4102 g_assert (!ins->next);
4108 switch (linfo->ret.storage) {
4109 case LLVMArgVtypeInReg: {
4110 LLVMTypeRef ret_type = LLVMGetReturnType (LLVMGetElementType (LLVMTypeOf (method)));
4111 LLVMValueRef val, addr, retval;
4114 retval = LLVMGetUndef (ret_type);
4116 if (!addresses [ins->sreg1]) {
4118 * The return type is an LLVM vector type, have to convert between it and the
4119 * real return type which is a struct type.
4121 g_assert (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (sig->ret)));
4122 /* Convert to 2xi64 first */
4123 val = LLVMBuildBitCast (builder, values [ins->sreg1], LLVMVectorType (IntPtrType (), 2), "");
4125 for (i = 0; i < 2; ++i) {
4126 if (linfo->ret.pair_storage [i] == LLVMArgInIReg) {
4127 retval = LLVMBuildInsertValue (builder, retval, LLVMBuildExtractElement (builder, val, LLVMConstInt (LLVMInt32Type (), i, FALSE), ""), i, "");
4129 g_assert (linfo->ret.pair_storage [i] == LLVMArgNone);
4133 addr = LLVMBuildBitCast (builder, addresses [ins->sreg1], LLVMPointerType (ret_type, 0), "");
4134 for (i = 0; i < 2; ++i) {
4135 if (linfo->ret.pair_storage [i] == LLVMArgInIReg) {
4136 LLVMValueRef indexes [2], part_addr;
4138 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
4139 indexes [1] = LLVMConstInt (LLVMInt32Type (), i, FALSE);
4140 part_addr = LLVMBuildGEP (builder, addr, indexes, 2, "");
4142 retval = LLVMBuildInsertValue (builder, retval, LLVMBuildLoad (builder, part_addr, ""), i, "");
4144 g_assert (linfo->ret.pair_storage [i] == LLVMArgNone);
4148 LLVMBuildRet (builder, retval);
4151 case LLVMArgVtypeAsScalar: {
4152 LLVMTypeRef ret_type = LLVMGetReturnType (LLVMGetElementType (LLVMTypeOf (method)));
4153 LLVMValueRef retval;
4156 size = get_vtype_size (sig->ret);
4158 g_assert (addresses [ins->sreg1]);
4160 retval = LLVMBuildLoad (builder, LLVMBuildBitCast (builder, addresses [ins->sreg1], LLVMPointerType (ret_type, 0), ""), "");
4161 LLVMBuildRet (builder, retval);
4164 case LLVMArgVtypeByVal: {
4165 LLVMValueRef retval;
4167 g_assert (addresses [ins->sreg1]);
4168 retval = LLVMBuildLoad (builder, addresses [ins->sreg1], "");
4169 LLVMBuildRet (builder, retval);
4172 case LLVMArgVtypeByRef: {
4173 LLVMBuildRetVoid (builder);
4176 case LLVMArgGsharedvtFixed: {
4177 LLVMTypeRef ret_type = type_to_llvm_type (ctx, sig->ret);
4178 /* The return value is in lhs, need to store to the vret argument */
4179 /* sreg1 might not be set */
4181 g_assert (cfg->vret_addr);
4182 g_assert (values [cfg->vret_addr->dreg]);
4183 LLVMBuildStore (builder, convert (ctx, lhs, ret_type), convert (ctx, values [cfg->vret_addr->dreg], LLVMPointerType (ret_type, 0)));
4185 LLVMBuildRetVoid (builder);
4188 case LLVMArgGsharedvtFixedVtype: {
4190 LLVMBuildRetVoid (builder);
4193 case LLVMArgGsharedvtVariable: {
4195 LLVMBuildRetVoid (builder);
4198 case LLVMArgVtypeRetAddr: {
4199 LLVMBuildRetVoid (builder);
4202 case LLVMArgScalarRetAddr: {
4203 LLVMTypeRef ret_type = type_to_llvm_type (ctx, sig->ret);
4204 LLVMValueRef param = LLVMGetParam (method, linfo->vret_arg_pindex);
4206 /* sreg1 might not be set */
4208 LLVMBuildStore (builder, convert (ctx, lhs, ret_type), convert (ctx, param, LLVMPointerType (ret_type, 0)));
4209 LLVMBuildRetVoid (builder);
4212 case LLVMArgFpStruct: {
4213 LLVMTypeRef ret_type = LLVMGetReturnType (LLVMGetElementType (LLVMTypeOf (method)));
4214 LLVMValueRef retval;
4216 g_assert (addresses [ins->sreg1]);
4217 retval = LLVMBuildLoad (builder, convert (ctx, addresses [ins->sreg1], LLVMPointerType (ret_type, 0)), "");
4218 LLVMBuildRet (builder, retval);
4222 case LLVMArgNormal: {
4223 if (!lhs || ctx->is_dead [ins->sreg1]) {
4225 * The method did not set its return value, probably because it
4226 * ends with a throw.
4229 LLVMBuildRetVoid (builder);
4231 LLVMBuildRet (builder, LLVMConstNull (type_to_llvm_type (ctx, sig->ret)));
4233 LLVMBuildRet (builder, convert (ctx, lhs, type_to_llvm_type (ctx, sig->ret)));
4235 has_terminator = TRUE;
4239 g_assert_not_reached ();
4248 case OP_ICOMPARE_IMM:
4249 case OP_LCOMPARE_IMM:
4250 case OP_COMPARE_IMM: {
4252 LLVMValueRef cmp, args [16];
4253 gboolean likely = (ins->flags & MONO_INST_LIKELY) != 0;
4255 if (ins->next->opcode == OP_NOP)
4258 if (ins->next->opcode == OP_BR)
4259 /* The comparison result is not needed */
4262 rel = mono_opcode_to_cond (ins->next->opcode);
4264 if (ins->opcode == OP_ICOMPARE_IMM) {
4265 lhs = convert (ctx, lhs, LLVMInt32Type ());
4266 rhs = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
4268 if (ins->opcode == OP_LCOMPARE_IMM) {
4269 lhs = convert (ctx, lhs, LLVMInt64Type ());
4270 rhs = LLVMConstInt (LLVMInt64Type (), GET_LONG_IMM (ins), FALSE);
4272 if (ins->opcode == OP_LCOMPARE) {
4273 lhs = convert (ctx, lhs, LLVMInt64Type ());
4274 rhs = convert (ctx, rhs, LLVMInt64Type ());
4276 if (ins->opcode == OP_ICOMPARE) {
4277 lhs = convert (ctx, lhs, LLVMInt32Type ());
4278 rhs = convert (ctx, rhs, LLVMInt32Type ());
4282 if (LLVMGetTypeKind (LLVMTypeOf (lhs)) == LLVMPointerTypeKind)
4283 rhs = convert (ctx, rhs, LLVMTypeOf (lhs));
4284 else if (LLVMGetTypeKind (LLVMTypeOf (rhs)) == LLVMPointerTypeKind)
4285 lhs = convert (ctx, lhs, LLVMTypeOf (rhs));
4288 /* We use COMPARE+SETcc/Bcc, llvm uses SETcc+br cond */
4289 if (ins->opcode == OP_FCOMPARE) {
4290 cmp = LLVMBuildFCmp (builder, fpcond_to_llvm_cond [rel], convert (ctx, lhs, LLVMDoubleType ()), convert (ctx, rhs, LLVMDoubleType ()), "");
4291 } else if (ins->opcode == OP_RCOMPARE) {
4292 cmp = LLVMBuildFCmp (builder, fpcond_to_llvm_cond [rel], convert (ctx, lhs, LLVMFloatType ()), convert (ctx, rhs, LLVMFloatType ()), "");
4293 } else if (ins->opcode == OP_COMPARE_IMM) {
4294 if (LLVMGetTypeKind (LLVMTypeOf (lhs)) == LLVMPointerTypeKind && ins->inst_imm == 0)
4295 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], lhs, LLVMConstNull (LLVMTypeOf (lhs)), "");
4297 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE), "");
4298 } else if (ins->opcode == OP_LCOMPARE_IMM) {
4299 if (SIZEOF_REGISTER == 4 && COMPILE_LLVM (cfg)) {
4300 /* The immediate is encoded in two fields */
4301 guint64 l = ((guint64)(guint32)ins->inst_offset << 32) | ((guint32)ins->inst_imm);
4302 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, LLVMInt64Type ()), LLVMConstInt (LLVMInt64Type (), l, FALSE), "");
4304 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, LLVMInt64Type ()), LLVMConstInt (LLVMInt64Type (), ins->inst_imm, FALSE), "");
4307 else if (ins->opcode == OP_COMPARE) {
4308 if (LLVMGetTypeKind (LLVMTypeOf (lhs)) == LLVMPointerTypeKind && LLVMTypeOf (lhs) == LLVMTypeOf (rhs))
4309 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], lhs, rhs, "");
4311 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, IntPtrType ()), convert (ctx, rhs, IntPtrType ()), "");
4313 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], lhs, rhs, "");
4317 args [1] = LLVMConstInt (LLVMInt1Type (), 1, FALSE);
4318 cmp = LLVMBuildCall (ctx->builder, LLVMGetNamedFunction (ctx->lmodule, "llvm.expect.i1"), args, 2, "");
4321 if (MONO_IS_COND_BRANCH_OP (ins->next)) {
4322 if (ins->next->inst_true_bb == ins->next->inst_false_bb) {
4324 * If the target bb contains PHI instructions, LLVM requires
4325 * two PHI entries for this bblock, while we only generate one.
4326 * So convert this to an unconditional bblock. (bxc #171).
4328 LLVMBuildBr (builder, get_bb (ctx, ins->next->inst_true_bb));
4330 LLVMBuildCondBr (builder, cmp, get_bb (ctx, ins->next->inst_true_bb), get_bb (ctx, ins->next->inst_false_bb));
4332 has_terminator = TRUE;
4333 } else if (MONO_IS_SETCC (ins->next)) {
4334 sprintf (dname_buf, "t%d", ins->next->dreg);
4336 values [ins->next->dreg] = LLVMBuildZExt (builder, cmp, LLVMInt32Type (), dname);
4338 /* Add stores for volatile variables */
4339 emit_volatile_store (ctx, ins->next->dreg);
4340 } else if (MONO_IS_COND_EXC (ins->next)) {
4341 emit_cond_system_exception (ctx, bb, (const char*)ins->next->inst_p1, cmp);
4342 CHECK_FAILURE (ctx);
4343 builder = ctx->builder;
4345 LLVM_FAILURE (ctx, "next");
4361 rel = mono_opcode_to_cond (ins->opcode);
4363 cmp = LLVMBuildFCmp (builder, fpcond_to_llvm_cond [rel], convert (ctx, lhs, LLVMDoubleType ()), convert (ctx, rhs, LLVMDoubleType ()), "");
4364 values [ins->dreg] = LLVMBuildZExt (builder, cmp, LLVMInt32Type (), dname);
4375 rel = mono_opcode_to_cond (ins->opcode);
4377 cmp = LLVMBuildFCmp (builder, fpcond_to_llvm_cond [rel], convert (ctx, lhs, LLVMFloatType ()), convert (ctx, rhs, LLVMFloatType ()), "");
4378 values [ins->dreg] = LLVMBuildZExt (builder, cmp, LLVMInt32Type (), dname);
4386 gboolean empty = TRUE;
4388 /* Check that all input bblocks really branch to us */
4389 for (i = 0; i < bb->in_count; ++i) {
4390 if (bb->in_bb [i]->last_ins && bb->in_bb [i]->last_ins->opcode == OP_NOT_REACHED)
4391 ins->inst_phi_args [i + 1] = -1;
4397 /* LLVM doesn't like phi instructions with zero operands */
4398 ctx->is_dead [ins->dreg] = TRUE;
4402 /* Created earlier, insert it now */
4403 LLVMInsertIntoBuilder (builder, values [ins->dreg]);
4405 for (i = 0; i < ins->inst_phi_args [0]; i++) {
4406 int sreg1 = ins->inst_phi_args [i + 1];
4410 * Count the number of times the incoming bblock branches to us,
4411 * since llvm requires a separate entry for each.
4413 if (bb->in_bb [i]->last_ins && bb->in_bb [i]->last_ins->opcode == OP_SWITCH) {
4414 MonoInst *switch_ins = bb->in_bb [i]->last_ins;
4417 for (j = 0; j < GPOINTER_TO_UINT (switch_ins->klass); ++j) {
4418 if (switch_ins->inst_many_bb [j] == bb)
4425 /* Remember for later */
4426 for (j = 0; j < count; ++j) {
4427 PhiNode *node = (PhiNode*)mono_mempool_alloc0 (ctx->mempool, sizeof (PhiNode));
4430 node->in_bb = bb->in_bb [i];
4432 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);
4442 values [ins->dreg] = lhs;
4446 MonoInst *var = get_vreg_to_inst (cfg, ins->dreg);
4449 values [ins->dreg] = lhs;
4451 if (var && var->klass->byval_arg.type == MONO_TYPE_R4) {
4453 * This is added by the spilling pass in case of the JIT,
4454 * but we have to do it ourselves.
4456 values [ins->dreg] = convert (ctx, values [ins->dreg], LLVMFloatType ());
4460 case OP_MOVE_F_TO_I4: {
4461 values [ins->dreg] = LLVMBuildBitCast (builder, LLVMBuildFPTrunc (builder, lhs, LLVMFloatType (), ""), LLVMInt32Type (), "");
4464 case OP_MOVE_I4_TO_F: {
4465 values [ins->dreg] = LLVMBuildFPExt (builder, LLVMBuildBitCast (builder, lhs, LLVMFloatType (), ""), LLVMDoubleType (), "");
4468 case OP_MOVE_F_TO_I8: {
4469 values [ins->dreg] = LLVMBuildBitCast (builder, lhs, LLVMInt64Type (), "");
4472 case OP_MOVE_I8_TO_F: {
4473 values [ins->dreg] = LLVMBuildBitCast (builder, lhs, LLVMDoubleType (), "");
4506 lhs = convert (ctx, lhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
4507 rhs = convert (ctx, rhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
4509 emit_div_check (ctx, builder, bb, ins, lhs, rhs);
4510 CHECK_FAILURE (ctx);
4511 builder = ctx->builder;
4513 switch (ins->opcode) {
4516 values [ins->dreg] = LLVMBuildAdd (builder, lhs, rhs, dname);
4520 values [ins->dreg] = LLVMBuildSub (builder, lhs, rhs, dname);
4524 values [ins->dreg] = LLVMBuildMul (builder, lhs, rhs, dname);
4528 values [ins->dreg] = LLVMBuildSRem (builder, lhs, rhs, dname);
4532 values [ins->dreg] = LLVMBuildURem (builder, lhs, rhs, dname);
4536 values [ins->dreg] = LLVMBuildSDiv (builder, lhs, rhs, dname);
4540 values [ins->dreg] = LLVMBuildUDiv (builder, lhs, rhs, dname);
4544 values [ins->dreg] = LLVMBuildFDiv (builder, lhs, rhs, dname);
4548 values [ins->dreg] = LLVMBuildAnd (builder, lhs, rhs, dname);
4552 values [ins->dreg] = LLVMBuildOr (builder, lhs, rhs, dname);
4556 values [ins->dreg] = LLVMBuildXor (builder, lhs, rhs, dname);
4560 values [ins->dreg] = LLVMBuildShl (builder, lhs, rhs, dname);
4564 values [ins->dreg] = LLVMBuildAShr (builder, lhs, rhs, dname);
4568 values [ins->dreg] = LLVMBuildLShr (builder, lhs, rhs, dname);
4572 values [ins->dreg] = LLVMBuildFAdd (builder, lhs, rhs, dname);
4575 values [ins->dreg] = LLVMBuildFSub (builder, lhs, rhs, dname);
4578 values [ins->dreg] = LLVMBuildFMul (builder, lhs, rhs, dname);
4582 g_assert_not_reached ();
4589 lhs = convert (ctx, lhs, LLVMFloatType ());
4590 rhs = convert (ctx, rhs, LLVMFloatType ());
4591 switch (ins->opcode) {
4593 values [ins->dreg] = LLVMBuildFAdd (builder, lhs, rhs, dname);
4596 values [ins->dreg] = LLVMBuildFSub (builder, lhs, rhs, dname);
4599 values [ins->dreg] = LLVMBuildFMul (builder, lhs, rhs, dname);
4602 values [ins->dreg] = LLVMBuildFDiv (builder, lhs, rhs, dname);
4605 g_assert_not_reached ();
4614 case OP_IREM_UN_IMM:
4616 case OP_IDIV_UN_IMM:
4622 case OP_ISHR_UN_IMM:
4632 case OP_LSHR_UN_IMM:
4638 case OP_SHR_UN_IMM: {
4641 if (spec [MONO_INST_SRC1] == 'l') {
4642 imm = LLVMConstInt (LLVMInt64Type (), GET_LONG_IMM (ins), FALSE);
4644 imm = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
4647 emit_div_check (ctx, builder, bb, ins, lhs, imm);
4648 CHECK_FAILURE (ctx);
4649 builder = ctx->builder;
4651 #if SIZEOF_VOID_P == 4
4652 if (ins->opcode == OP_LSHL_IMM || ins->opcode == OP_LSHR_IMM || ins->opcode == OP_LSHR_UN_IMM)
4653 imm = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
4656 if (LLVMGetTypeKind (LLVMTypeOf (lhs)) == LLVMPointerTypeKind)
4657 lhs = convert (ctx, lhs, IntPtrType ());
4658 imm = convert (ctx, imm, LLVMTypeOf (lhs));
4659 switch (ins->opcode) {
4663 values [ins->dreg] = LLVMBuildAdd (builder, lhs, imm, dname);
4667 values [ins->dreg] = LLVMBuildSub (builder, lhs, imm, dname);
4672 values [ins->dreg] = LLVMBuildMul (builder, lhs, imm, dname);
4676 values [ins->dreg] = LLVMBuildSDiv (builder, lhs, imm, dname);
4678 case OP_IDIV_UN_IMM:
4679 case OP_LDIV_UN_IMM:
4680 values [ins->dreg] = LLVMBuildUDiv (builder, lhs, imm, dname);
4684 values [ins->dreg] = LLVMBuildSRem (builder, lhs, imm, dname);
4686 case OP_IREM_UN_IMM:
4687 values [ins->dreg] = LLVMBuildURem (builder, lhs, imm, dname);
4692 values [ins->dreg] = LLVMBuildAnd (builder, lhs, imm, dname);
4696 values [ins->dreg] = LLVMBuildOr (builder, lhs, imm, dname);
4700 values [ins->dreg] = LLVMBuildXor (builder, lhs, imm, dname);
4705 values [ins->dreg] = LLVMBuildShl (builder, lhs, imm, dname);
4710 values [ins->dreg] = LLVMBuildAShr (builder, lhs, imm, dname);
4712 case OP_ISHR_UN_IMM:
4713 /* This is used to implement conv.u4, so the lhs could be an i8 */
4714 lhs = convert (ctx, lhs, LLVMInt32Type ());
4715 imm = convert (ctx, imm, LLVMInt32Type ());
4716 values [ins->dreg] = LLVMBuildLShr (builder, lhs, imm, dname);
4718 case OP_LSHR_UN_IMM:
4720 values [ins->dreg] = LLVMBuildLShr (builder, lhs, imm, dname);
4723 g_assert_not_reached ();
4728 values [ins->dreg] = LLVMBuildSub (builder, LLVMConstInt (LLVMInt32Type (), 0, FALSE), convert (ctx, lhs, LLVMInt32Type ()), dname);
4731 values [ins->dreg] = LLVMBuildSub (builder, LLVMConstInt (LLVMInt64Type (), 0, FALSE), lhs, dname);
4734 lhs = convert (ctx, lhs, LLVMDoubleType ());
4735 values [ins->dreg] = LLVMBuildFSub (builder, LLVMConstReal (LLVMDoubleType (), 0.0), lhs, dname);
4738 lhs = convert (ctx, lhs, LLVMFloatType ());
4739 values [ins->dreg] = LLVMBuildFSub (builder, LLVMConstReal (LLVMFloatType (), 0.0), lhs, dname);
4742 guint32 v = 0xffffffff;
4743 values [ins->dreg] = LLVMBuildXor (builder, LLVMConstInt (LLVMInt32Type (), v, FALSE), convert (ctx, lhs, LLVMInt32Type ()), dname);
4747 guint64 v = 0xffffffffffffffffLL;
4748 values [ins->dreg] = LLVMBuildXor (builder, LLVMConstInt (LLVMInt64Type (), v, FALSE), lhs, dname);
4751 #if defined(TARGET_X86) || defined(TARGET_AMD64)
4753 LLVMValueRef v1, v2;
4755 v1 = LLVMBuildMul (builder, convert (ctx, rhs, IntPtrType ()), LLVMConstInt (IntPtrType (), (1 << ins->backend.shift_amount), FALSE), "");
4756 v2 = LLVMBuildAdd (builder, convert (ctx, lhs, IntPtrType ()), v1, "");
4757 values [ins->dreg] = LLVMBuildAdd (builder, v2, LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE), dname);
4762 case OP_ICONV_TO_I1:
4763 case OP_ICONV_TO_I2:
4764 case OP_ICONV_TO_I4:
4765 case OP_ICONV_TO_U1:
4766 case OP_ICONV_TO_U2:
4767 case OP_ICONV_TO_U4:
4768 case OP_LCONV_TO_I1:
4769 case OP_LCONV_TO_I2:
4770 case OP_LCONV_TO_U1:
4771 case OP_LCONV_TO_U2:
4772 case OP_LCONV_TO_U4: {
4775 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);
4777 /* Have to do two casts since our vregs have type int */
4778 v = LLVMBuildTrunc (builder, lhs, op_to_llvm_type (ins->opcode), "");
4780 values [ins->dreg] = LLVMBuildSExt (builder, v, LLVMInt32Type (), dname);
4782 values [ins->dreg] = LLVMBuildZExt (builder, v, LLVMInt32Type (), dname);
4785 case OP_ICONV_TO_I8:
4786 values [ins->dreg] = LLVMBuildSExt (builder, lhs, LLVMInt64Type (), dname);
4788 case OP_ICONV_TO_U8:
4789 values [ins->dreg] = LLVMBuildZExt (builder, lhs, LLVMInt64Type (), dname);
4791 case OP_FCONV_TO_I4:
4792 case OP_RCONV_TO_I4:
4793 values [ins->dreg] = LLVMBuildFPToSI (builder, lhs, LLVMInt32Type (), dname);
4795 case OP_FCONV_TO_I1:
4796 case OP_RCONV_TO_I1:
4797 values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildFPToSI (builder, lhs, LLVMInt8Type (), dname), LLVMInt32Type (), "");
4799 case OP_FCONV_TO_U1:
4800 case OP_RCONV_TO_U1:
4801 values [ins->dreg] = LLVMBuildZExt (builder, LLVMBuildFPToUI (builder, lhs, LLVMInt8Type (), dname), LLVMInt32Type (), "");
4803 case OP_FCONV_TO_I2:
4804 case OP_RCONV_TO_I2:
4805 values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildFPToSI (builder, lhs, LLVMInt16Type (), dname), LLVMInt32Type (), "");
4807 case OP_FCONV_TO_U2:
4808 case OP_RCONV_TO_U2:
4809 values [ins->dreg] = LLVMBuildZExt (builder, LLVMBuildFPToUI (builder, lhs, LLVMInt16Type (), dname), LLVMInt32Type (), "");
4811 case OP_RCONV_TO_U4:
4812 values [ins->dreg] = LLVMBuildFPToUI (builder, lhs, LLVMInt32Type (), dname);
4814 case OP_FCONV_TO_I8:
4815 case OP_RCONV_TO_I8:
4816 values [ins->dreg] = LLVMBuildFPToSI (builder, lhs, LLVMInt64Type (), dname);
4819 values [ins->dreg] = LLVMBuildFPToSI (builder, lhs, IntPtrType (), dname);
4821 case OP_ICONV_TO_R8:
4822 case OP_LCONV_TO_R8:
4823 values [ins->dreg] = LLVMBuildSIToFP (builder, lhs, LLVMDoubleType (), dname);
4825 case OP_ICONV_TO_R_UN:
4826 case OP_LCONV_TO_R_UN:
4827 values [ins->dreg] = LLVMBuildUIToFP (builder, lhs, LLVMDoubleType (), dname);
4829 #if SIZEOF_VOID_P == 4
4832 case OP_LCONV_TO_I4:
4833 values [ins->dreg] = LLVMBuildTrunc (builder, lhs, LLVMInt32Type (), dname);
4835 case OP_ICONV_TO_R4:
4836 case OP_LCONV_TO_R4:
4837 v = LLVMBuildSIToFP (builder, lhs, LLVMFloatType (), "");
4839 values [ins->dreg] = v;
4841 values [ins->dreg] = LLVMBuildFPExt (builder, v, LLVMDoubleType (), dname);
4843 case OP_FCONV_TO_R4:
4844 v = LLVMBuildFPTrunc (builder, lhs, LLVMFloatType (), "");
4846 values [ins->dreg] = v;
4848 values [ins->dreg] = LLVMBuildFPExt (builder, v, LLVMDoubleType (), dname);
4850 case OP_RCONV_TO_R8:
4851 values [ins->dreg] = LLVMBuildFPExt (builder, lhs, LLVMDoubleType (), dname);
4853 case OP_RCONV_TO_R4:
4854 values [ins->dreg] = lhs;
4857 values [ins->dreg] = LLVMBuildSExt (builder, convert (ctx, lhs, LLVMInt32Type ()), LLVMInt64Type (), dname);
4860 values [ins->dreg] = LLVMBuildZExt (builder, convert (ctx, lhs, LLVMInt32Type ()), LLVMInt64Type (), dname);
4863 values [ins->dreg] = LLVMBuildTrunc (builder, lhs, LLVMInt32Type (), dname);
4865 case OP_LOCALLOC_IMM: {
4868 guint32 size = ins->inst_imm;
4869 size = (size + (MONO_ARCH_FRAME_ALIGNMENT - 1)) & ~ (MONO_ARCH_FRAME_ALIGNMENT - 1);
4871 v = mono_llvm_build_alloca (builder, LLVMInt8Type (), LLVMConstInt (LLVMInt32Type (), size, FALSE), MONO_ARCH_FRAME_ALIGNMENT, "");
4873 if (ins->flags & MONO_INST_INIT) {
4874 LLVMValueRef args [5];
4877 args [1] = LLVMConstInt (LLVMInt8Type (), 0, FALSE);
4878 args [2] = LLVMConstInt (LLVMInt32Type (), size, FALSE);
4879 args [3] = LLVMConstInt (LLVMInt32Type (), MONO_ARCH_FRAME_ALIGNMENT, FALSE);
4880 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
4881 LLVMBuildCall (builder, LLVMGetNamedFunction (lmodule, memset_func_name), args, memset_param_count, "");
4884 values [ins->dreg] = v;
4888 LLVMValueRef v, size;
4890 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), "");
4892 v = mono_llvm_build_alloca (builder, LLVMInt8Type (), size, MONO_ARCH_FRAME_ALIGNMENT, "");
4894 if (ins->flags & MONO_INST_INIT) {
4895 LLVMValueRef args [5];
4898 args [1] = LLVMConstInt (LLVMInt8Type (), 0, FALSE);
4900 args [3] = LLVMConstInt (LLVMInt32Type (), MONO_ARCH_FRAME_ALIGNMENT, FALSE);
4901 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
4902 LLVMBuildCall (builder, LLVMGetNamedFunction (lmodule, memset_func_name), args, memset_param_count, "");
4904 values [ins->dreg] = v;
4908 case OP_LOADI1_MEMBASE:
4909 case OP_LOADU1_MEMBASE:
4910 case OP_LOADI2_MEMBASE:
4911 case OP_LOADU2_MEMBASE:
4912 case OP_LOADI4_MEMBASE:
4913 case OP_LOADU4_MEMBASE:
4914 case OP_LOADI8_MEMBASE:
4915 case OP_LOADR4_MEMBASE:
4916 case OP_LOADR8_MEMBASE:
4917 case OP_LOAD_MEMBASE:
4925 LLVMValueRef base, index, addr;
4927 gboolean sext = FALSE, zext = FALSE;
4928 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
4930 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
4935 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)) {
4936 addr = LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE);
4941 if (ins->inst_offset == 0) {
4943 } else if (ins->inst_offset % size != 0) {
4944 /* Unaligned load */
4945 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset, FALSE);
4946 addr = LLVMBuildGEP (builder, convert (ctx, base, LLVMPointerType (LLVMInt8Type (), 0)), &index, 1, "");
4948 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
4949 addr = LLVMBuildGEP (builder, convert (ctx, base, LLVMPointerType (t, 0)), &index, 1, "");
4953 addr = convert (ctx, addr, LLVMPointerType (t, 0));
4955 values [ins->dreg] = emit_load (ctx, bb, &builder, size, addr, dname, is_volatile);
4957 if (!is_volatile && (ins->flags & MONO_INST_INVARIANT_LOAD)) {
4959 * These will signal LLVM that these loads do not alias any stores, and
4960 * they can't fail, allowing them to be hoisted out of loops.
4962 set_invariant_load_flag (values [ins->dreg]);
4963 set_metadata_flag (values [ins->dreg], "mono.nofail.load");
4967 values [ins->dreg] = LLVMBuildSExt (builder, values [ins->dreg], LLVMInt32Type (), dname);
4969 values [ins->dreg] = LLVMBuildZExt (builder, values [ins->dreg], LLVMInt32Type (), dname);
4970 else if (!cfg->r4fp && ins->opcode == OP_LOADR4_MEMBASE)
4971 values [ins->dreg] = LLVMBuildFPExt (builder, values [ins->dreg], LLVMDoubleType (), dname);
4975 case OP_STOREI1_MEMBASE_REG:
4976 case OP_STOREI2_MEMBASE_REG:
4977 case OP_STOREI4_MEMBASE_REG:
4978 case OP_STOREI8_MEMBASE_REG:
4979 case OP_STORER4_MEMBASE_REG:
4980 case OP_STORER8_MEMBASE_REG:
4981 case OP_STORE_MEMBASE_REG: {
4983 LLVMValueRef index, addr;
4985 gboolean sext = FALSE, zext = FALSE;
4986 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
4988 if (!values [ins->inst_destbasereg])
4989 LLVM_FAILURE (ctx, "inst_destbasereg");
4991 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
4993 if (ins->inst_offset % size != 0) {
4994 /* Unaligned store */
4995 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset, FALSE);
4996 addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (LLVMInt8Type (), 0)), &index, 1, "");
4998 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
4999 addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (t, 0)), &index, 1, "");
5001 emit_store (ctx, bb, &builder, size, convert (ctx, values [ins->sreg1], t), convert (ctx, addr, LLVMPointerType (t, 0)), is_volatile);
5005 case OP_STOREI1_MEMBASE_IMM:
5006 case OP_STOREI2_MEMBASE_IMM:
5007 case OP_STOREI4_MEMBASE_IMM:
5008 case OP_STOREI8_MEMBASE_IMM:
5009 case OP_STORE_MEMBASE_IMM: {
5011 LLVMValueRef index, addr;
5013 gboolean sext = FALSE, zext = FALSE;
5014 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
5016 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
5018 if (ins->inst_offset % size != 0) {
5019 /* Unaligned store */
5020 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset, FALSE);
5021 addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (LLVMInt8Type (), 0)), &index, 1, "");
5023 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
5024 addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (t, 0)), &index, 1, "");
5026 emit_store (ctx, bb, &builder, size, convert (ctx, LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE), t), convert (ctx, addr, LLVMPointerType (t, 0)), is_volatile);
5031 emit_load (ctx, bb, &builder, sizeof (gpointer), convert (ctx, lhs, LLVMPointerType (IntPtrType (), 0)), "", TRUE);
5033 case OP_OUTARG_VTRETADDR:
5041 case OP_VOIDCALL_MEMBASE:
5042 case OP_CALL_MEMBASE:
5043 case OP_LCALL_MEMBASE:
5044 case OP_FCALL_MEMBASE:
5045 case OP_RCALL_MEMBASE:
5046 case OP_VCALL_MEMBASE:
5047 case OP_VOIDCALL_REG:
5052 case OP_VCALL_REG: {
5053 process_call (ctx, bb, &builder, ins);
5054 CHECK_FAILURE (ctx);
5059 LLVMValueRef indexes [2];
5060 MonoJumpInfo *tmp_ji, *ji;
5061 LLVMValueRef got_entry_addr;
5065 * FIXME: Can't allocate from the cfg mempool since that is freed if
5066 * the LLVM compile fails.
5068 tmp_ji = g_new0 (MonoJumpInfo, 1);
5069 tmp_ji->type = (MonoJumpInfoType)ins->inst_c1;
5070 tmp_ji->data.target = ins->inst_p0;
5072 ji = mono_aot_patch_info_dup (tmp_ji);
5075 ji->next = cfg->patch_info;
5076 cfg->patch_info = ji;
5078 //mono_add_patch_info (cfg, 0, (MonoJumpInfoType)ins->inst_i1, ins->inst_p0);
5079 got_offset = mono_aot_get_got_offset (cfg->patch_info);
5080 ctx->module->max_got_offset = MAX (ctx->module->max_got_offset, got_offset);
5081 if (!mono_aot_is_shared_got_offset (got_offset)) {
5082 //mono_print_ji (ji);
5084 ctx->has_got_access = TRUE;
5087 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
5088 indexes [1] = LLVMConstInt (LLVMInt32Type (), (gssize)got_offset, FALSE);
5089 got_entry_addr = LLVMBuildGEP (builder, ctx->module->got_var, indexes, 2, "");
5091 name = get_aotconst_name (ji->type, ji->data.target, got_offset);
5092 values [ins->dreg] = LLVMBuildLoad (builder, got_entry_addr, name);
5094 set_invariant_load_flag (values [ins->dreg]);
5097 case OP_NOT_REACHED:
5098 LLVMBuildUnreachable (builder);
5099 has_terminator = TRUE;
5100 g_assert (bb->block_num < cfg->max_block_num);
5101 ctx->unreachable [bb->block_num] = TRUE;
5102 /* Might have instructions after this */
5104 MonoInst *next = ins->next;
5106 * FIXME: If later code uses the regs defined by these instructions,
5107 * compilation will fail.
5109 MONO_DELETE_INS (bb, next);
5113 MonoInst *var = ins->inst_i0;
5115 if (var->opcode == OP_VTARG_ADDR) {
5116 /* The variable contains the vtype address */
5117 values [ins->dreg] = values [var->dreg];
5118 } else if (var->opcode == OP_GSHAREDVT_LOCAL) {
5119 values [ins->dreg] = emit_gsharedvt_ldaddr (ctx, var->dreg);
5121 values [ins->dreg] = addresses [var->dreg];
5126 LLVMValueRef args [1];
5128 args [0] = convert (ctx, lhs, LLVMDoubleType ());
5129 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (lmodule, "llvm.sin.f64"), args, 1, dname);
5133 LLVMValueRef args [1];
5135 args [0] = convert (ctx, lhs, LLVMDoubleType ());
5136 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (lmodule, "llvm.cos.f64"), args, 1, dname);
5140 LLVMValueRef args [1];
5143 /* This no longer seems to happen */
5145 * LLVM optimizes sqrt(nan) into undefined in
5146 * lib/Analysis/ConstantFolding.cpp
5147 * Also, sqrt(NegativeInfinity) is optimized into 0.
5149 LLVM_FAILURE (ctx, "sqrt");
5151 args [0] = convert (ctx, lhs, LLVMDoubleType ());
5152 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (lmodule, "llvm.sqrt.f64"), args, 1, dname);
5156 LLVMValueRef args [1];
5158 args [0] = convert (ctx, lhs, LLVMDoubleType ());
5159 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (lmodule, "fabs"), args, 1, dname);
5173 lhs = convert (ctx, lhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
5174 rhs = convert (ctx, rhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
5176 switch (ins->opcode) {
5179 v = LLVMBuildICmp (builder, LLVMIntSLE, lhs, rhs, "");
5183 v = LLVMBuildICmp (builder, LLVMIntSGE, lhs, rhs, "");
5187 v = LLVMBuildICmp (builder, LLVMIntULE, lhs, rhs, "");
5191 v = LLVMBuildICmp (builder, LLVMIntUGE, lhs, rhs, "");
5194 g_assert_not_reached ();
5197 values [ins->dreg] = LLVMBuildSelect (builder, v, lhs, rhs, dname);
5200 case OP_ATOMIC_EXCHANGE_I4:
5201 case OP_ATOMIC_EXCHANGE_I8: {
5202 LLVMValueRef args [2];
5205 if (ins->opcode == OP_ATOMIC_EXCHANGE_I4)
5206 t = LLVMInt32Type ();
5208 t = LLVMInt64Type ();
5210 g_assert (ins->inst_offset == 0);
5212 args [0] = convert (ctx, lhs, LLVMPointerType (t, 0));
5213 args [1] = convert (ctx, rhs, t);
5215 values [ins->dreg] = mono_llvm_build_atomic_rmw (builder, LLVM_ATOMICRMW_OP_XCHG, args [0], args [1]);
5218 case OP_ATOMIC_ADD_I4:
5219 case OP_ATOMIC_ADD_I8: {
5220 LLVMValueRef args [2];
5223 if (ins->opcode == OP_ATOMIC_ADD_I4)
5224 t = LLVMInt32Type ();
5226 t = LLVMInt64Type ();
5228 g_assert (ins->inst_offset == 0);
5230 args [0] = convert (ctx, lhs, LLVMPointerType (t, 0));
5231 args [1] = convert (ctx, rhs, t);
5232 values [ins->dreg] = LLVMBuildAdd (builder, mono_llvm_build_atomic_rmw (builder, LLVM_ATOMICRMW_OP_ADD, args [0], args [1]), args [1], dname);
5235 case OP_ATOMIC_CAS_I4:
5236 case OP_ATOMIC_CAS_I8: {
5237 LLVMValueRef args [3], val;
5240 if (ins->opcode == OP_ATOMIC_CAS_I4)
5241 t = LLVMInt32Type ();
5243 t = LLVMInt64Type ();
5245 args [0] = convert (ctx, lhs, LLVMPointerType (t, 0));
5247 args [1] = convert (ctx, values [ins->sreg3], t);
5249 args [2] = convert (ctx, values [ins->sreg2], t);
5250 val = mono_llvm_build_cmpxchg (builder, args [0], args [1], args [2]);
5251 /* cmpxchg returns a pair */
5252 values [ins->dreg] = LLVMBuildExtractValue (builder, val, 0, "");
5255 case OP_MEMORY_BARRIER: {
5256 mono_llvm_build_fence (builder, (BarrierKind) ins->backend.memory_barrier_kind);
5259 case OP_ATOMIC_LOAD_I1:
5260 case OP_ATOMIC_LOAD_I2:
5261 case OP_ATOMIC_LOAD_I4:
5262 case OP_ATOMIC_LOAD_I8:
5263 case OP_ATOMIC_LOAD_U1:
5264 case OP_ATOMIC_LOAD_U2:
5265 case OP_ATOMIC_LOAD_U4:
5266 case OP_ATOMIC_LOAD_U8:
5267 case OP_ATOMIC_LOAD_R4:
5268 case OP_ATOMIC_LOAD_R8: {
5269 LLVM_FAILURE (ctx, "atomic mono.load intrinsic");
5272 gboolean sext, zext;
5274 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
5275 BarrierKind barrier = (BarrierKind) ins->backend.memory_barrier_kind;
5276 LLVMValueRef index, addr;
5278 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
5283 if (ins->inst_offset != 0) {
5284 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
5285 addr = LLVMBuildGEP (builder, convert (ctx, lhs, LLVMPointerType (t, 0)), &index, 1, "");
5290 addr = convert (ctx, addr, LLVMPointerType (t, 0));
5292 values [ins->dreg] = emit_load_general (ctx, bb, &builder, size, addr, dname, is_volatile, barrier);
5295 values [ins->dreg] = LLVMBuildSExt (builder, values [ins->dreg], LLVMInt32Type (), dname);
5297 values [ins->dreg] = LLVMBuildZExt (builder, values [ins->dreg], LLVMInt32Type (), dname);
5300 case OP_ATOMIC_STORE_I1:
5301 case OP_ATOMIC_STORE_I2:
5302 case OP_ATOMIC_STORE_I4:
5303 case OP_ATOMIC_STORE_I8:
5304 case OP_ATOMIC_STORE_U1:
5305 case OP_ATOMIC_STORE_U2:
5306 case OP_ATOMIC_STORE_U4:
5307 case OP_ATOMIC_STORE_U8:
5308 case OP_ATOMIC_STORE_R4:
5309 case OP_ATOMIC_STORE_R8: {
5310 LLVM_FAILURE (ctx, "atomic mono.store intrinsic");
5313 gboolean sext, zext;
5315 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
5316 BarrierKind barrier = (BarrierKind) ins->backend.memory_barrier_kind;
5317 LLVMValueRef index, addr, value;
5319 if (!values [ins->inst_destbasereg])
5320 LLVM_FAILURE (ctx, "inst_destbasereg");
5322 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
5324 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
5325 addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (t, 0)), &index, 1, "");
5326 value = convert (ctx, values [ins->sreg1], t);
5328 emit_store_general (ctx, bb, &builder, size, value, addr, is_volatile, barrier);
5331 case OP_RELAXED_NOP: {
5332 #if defined(TARGET_AMD64) || defined(TARGET_X86)
5333 emit_call (ctx, bb, &builder, LLVMGetNamedFunction (ctx->lmodule, "llvm.x86.sse2.pause"), NULL, 0);
5340 #if (defined(TARGET_AMD64) || defined(TARGET_X86)) && defined(__linux__)
5342 // 257 == FS segment register
5343 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 257);
5345 // 256 == GS segment register
5346 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 256);
5349 values [ins->dreg] = LLVMBuildLoad (builder, LLVMBuildIntToPtr (builder, LLVMConstInt (IntPtrType (), ins->inst_offset, TRUE), ptrtype, ""), "");
5350 #elif defined(TARGET_AMD64) && defined(TARGET_OSX)
5351 /* See mono_amd64_emit_tls_get () */
5352 int offset = mono_amd64_get_tls_gs_offset () + (ins->inst_offset * 8);
5354 // 256 == GS segment register
5355 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 256);
5356 values [ins->dreg] = LLVMBuildLoad (builder, LLVMBuildIntToPtr (builder, LLVMConstInt (IntPtrType (), offset, TRUE), ptrtype, ""), "");
5358 LLVM_FAILURE (ctx, "opcode tls-get");
5363 case OP_TLS_GET_REG: {
5364 #if defined(TARGET_AMD64) && defined(TARGET_OSX)
5365 /* See emit_tls_get_reg () */
5366 // 256 == GS segment register
5367 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 256);
5368 values [ins->dreg] = LLVMBuildLoad (builder, LLVMBuildIntToPtr (builder, convert (ctx, lhs, LLVMInt32Type ()), ptrtype, ""), "");
5370 LLVM_FAILURE (ctx, "opcode tls-get");
5375 case OP_TLS_SET_REG: {
5376 #if defined(TARGET_AMD64) && defined(TARGET_OSX)
5377 /* See emit_tls_get_reg () */
5378 // 256 == GS segment register
5379 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 256);
5380 LLVMBuildStore (builder, convert (ctx, lhs, IntPtrType ()), LLVMBuildIntToPtr (builder, convert (ctx, rhs, LLVMInt32Type ()), ptrtype, ""));
5382 LLVM_FAILURE (ctx, "opcode tls-set-reg");
5391 case OP_IADD_OVF_UN:
5393 case OP_ISUB_OVF_UN:
5395 case OP_IMUL_OVF_UN:
5396 #if SIZEOF_VOID_P == 8
5398 case OP_LADD_OVF_UN:
5400 case OP_LSUB_OVF_UN:
5402 case OP_LMUL_OVF_UN:
5405 LLVMValueRef args [2], val, ovf, func;
5407 args [0] = convert (ctx, lhs, op_to_llvm_type (ins->opcode));
5408 args [1] = convert (ctx, rhs, op_to_llvm_type (ins->opcode));
5409 func = LLVMGetNamedFunction (lmodule, ovf_op_to_intrins (ins->opcode));
5411 val = LLVMBuildCall (builder, func, args, 2, "");
5412 values [ins->dreg] = LLVMBuildExtractValue (builder, val, 0, dname);
5413 ovf = LLVMBuildExtractValue (builder, val, 1, "");
5414 emit_cond_system_exception (ctx, bb, "OverflowException", ovf);
5415 CHECK_FAILURE (ctx);
5416 builder = ctx->builder;
5422 * We currently model them using arrays. Promotion to local vregs is
5423 * disabled for them in mono_handle_global_vregs () in the LLVM case,
5424 * so we always have an entry in cfg->varinfo for them.
5425 * FIXME: Is this needed ?
5428 MonoClass *klass = ins->klass;
5429 LLVMValueRef args [5];
5433 LLVM_FAILURE (ctx, "!klass");
5437 if (!addresses [ins->dreg])
5438 addresses [ins->dreg] = build_alloca (ctx, &klass->byval_arg);
5439 args [0] = LLVMBuildBitCast (builder, addresses [ins->dreg], LLVMPointerType (LLVMInt8Type (), 0), "");
5440 args [1] = LLVMConstInt (LLVMInt8Type (), 0, FALSE);
5441 args [2] = LLVMConstInt (LLVMInt32Type (), mono_class_value_size (klass, NULL), FALSE);
5443 args [3] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
5444 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
5445 LLVMBuildCall (builder, LLVMGetNamedFunction (lmodule, memset_func_name), args, memset_param_count, "");
5448 case OP_DUMMY_VZERO:
5451 case OP_STOREV_MEMBASE:
5452 case OP_LOADV_MEMBASE:
5454 MonoClass *klass = ins->klass;
5455 LLVMValueRef src = NULL, dst, args [5];
5456 gboolean done = FALSE;
5460 LLVM_FAILURE (ctx, "!klass");
5464 if (mini_is_gsharedvt_klass (klass)) {
5466 LLVM_FAILURE (ctx, "gsharedvt");
5470 switch (ins->opcode) {
5471 case OP_STOREV_MEMBASE:
5472 if (cfg->gen_write_barriers && klass->has_references && ins->inst_destbasereg != cfg->frame_reg &&
5473 LLVMGetInstructionOpcode (values [ins->inst_destbasereg]) != LLVMAlloca) {
5474 /* Decomposed earlier */
5475 g_assert_not_reached ();
5478 if (!addresses [ins->sreg1]) {
5480 g_assert (values [ins->sreg1]);
5481 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));
5482 LLVMBuildStore (builder, values [ins->sreg1], dst);
5485 src = LLVMBuildBitCast (builder, addresses [ins->sreg1], LLVMPointerType (LLVMInt8Type (), 0), "");
5486 dst = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_destbasereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (LLVMInt8Type (), 0));
5489 case OP_LOADV_MEMBASE:
5490 if (!addresses [ins->dreg])
5491 addresses [ins->dreg] = build_alloca (ctx, &klass->byval_arg);
5492 src = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_basereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (LLVMInt8Type (), 0));
5493 dst = LLVMBuildBitCast (builder, addresses [ins->dreg], LLVMPointerType (LLVMInt8Type (), 0), "");
5496 if (!addresses [ins->sreg1])
5497 addresses [ins->sreg1] = build_alloca (ctx, &klass->byval_arg);
5498 if (!addresses [ins->dreg])
5499 addresses [ins->dreg] = build_alloca (ctx, &klass->byval_arg);
5500 src = LLVMBuildBitCast (builder, addresses [ins->sreg1], LLVMPointerType (LLVMInt8Type (), 0), "");
5501 dst = LLVMBuildBitCast (builder, addresses [ins->dreg], LLVMPointerType (LLVMInt8Type (), 0), "");
5504 g_assert_not_reached ();
5506 CHECK_FAILURE (ctx);
5513 args [2] = LLVMConstInt (LLVMInt32Type (), mono_class_value_size (klass, NULL), FALSE);
5514 args [3] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
5516 args [3] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
5517 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
5518 LLVMBuildCall (builder, LLVMGetNamedFunction (lmodule, memcpy_func_name), args, memcpy_param_count, "");
5521 case OP_LLVM_OUTARG_VT: {
5522 LLVMArgInfo *ainfo = (LLVMArgInfo*)ins->inst_p0;
5523 MonoType *t = mini_get_underlying_type (ins->inst_vtype);
5525 if (ainfo->storage == LLVMArgScalarByRef) {
5526 LLVMTypeRef argtype;
5527 LLVMValueRef loc, v;
5529 argtype = type_to_llvm_arg_type (ctx, t);
5530 loc = build_alloca_llvm_type (ctx, argtype, 0);
5531 v = convert (ctx, values [ins->sreg1], argtype);
5532 LLVMBuildStore (ctx->builder, v, loc);
5533 addresses [ins->dreg] = loc;
5534 } else if (ainfo->storage == LLVMArgGsharedvtVariable) {
5535 MonoInst *var = get_vreg_to_inst (cfg, ins->sreg1);
5537 if (var && var->opcode == OP_GSHAREDVT_LOCAL) {
5538 addresses [ins->dreg] = convert (ctx, emit_gsharedvt_ldaddr (ctx, var->dreg), LLVMPointerType (IntPtrType (), 0));
5540 g_assert (addresses [ins->sreg1]);
5541 addresses [ins->dreg] = addresses [ins->sreg1];
5543 } else if (ainfo->storage == LLVMArgGsharedvtFixed) {
5544 if (!addresses [ins->sreg1]) {
5545 addresses [ins->sreg1] = build_alloca (ctx, t);
5546 g_assert (values [ins->sreg1]);
5548 LLVMBuildStore (builder, convert (ctx, values [ins->sreg1], LLVMGetElementType (LLVMTypeOf (addresses [ins->sreg1]))), addresses [ins->sreg1]);
5549 addresses [ins->dreg] = addresses [ins->sreg1];
5551 if (!addresses [ins->sreg1]) {
5552 addresses [ins->sreg1] = build_alloca (ctx, t);
5553 g_assert (values [ins->sreg1]);
5554 LLVMBuildStore (builder, convert (ctx, values [ins->sreg1], type_to_llvm_type (ctx, t)), addresses [ins->sreg1]);
5556 addresses [ins->dreg] = addresses [ins->sreg1];
5564 #if defined(TARGET_X86) || defined(TARGET_AMD64)
5566 values [ins->dreg] = LLVMConstNull (type_to_llvm_type (ctx, &ins->klass->byval_arg));
5569 case OP_LOADX_MEMBASE: {
5570 LLVMTypeRef t = type_to_llvm_type (ctx, &ins->klass->byval_arg);
5573 src = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_basereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (t, 0));
5574 values [ins->dreg] = mono_llvm_build_aligned_load (builder, src, "", FALSE, 1);
5577 case OP_STOREX_MEMBASE: {
5578 LLVMTypeRef t = LLVMTypeOf (values [ins->sreg1]);
5581 dest = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_destbasereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (t, 0));
5582 mono_llvm_build_aligned_store (builder, values [ins->sreg1], dest, FALSE, 1);
5589 values [ins->dreg] = LLVMBuildAdd (builder, lhs, rhs, "");
5593 values [ins->dreg] = LLVMBuildFAdd (builder, lhs, rhs, "");
5599 values [ins->dreg] = LLVMBuildSub (builder, lhs, rhs, "");
5603 values [ins->dreg] = LLVMBuildFSub (builder, lhs, rhs, "");
5607 values [ins->dreg] = LLVMBuildFMul (builder, lhs, rhs, "");
5611 values [ins->dreg] = LLVMBuildFDiv (builder, lhs, rhs, "");
5614 values [ins->dreg] = LLVMBuildAnd (builder, lhs, rhs, "");
5617 values [ins->dreg] = LLVMBuildOr (builder, lhs, rhs, "");
5620 values [ins->dreg] = LLVMBuildXor (builder, lhs, rhs, "");
5624 values [ins->dreg] = LLVMBuildMul (builder, lhs, rhs, "");
5635 LLVMValueRef v = NULL;
5637 switch (ins->opcode) {
5642 t = LLVMVectorType (LLVMInt32Type (), 4);
5643 rt = LLVMVectorType (LLVMFloatType (), 4);
5649 t = LLVMVectorType (LLVMInt64Type (), 2);
5650 rt = LLVMVectorType (LLVMDoubleType (), 2);
5653 t = LLVMInt32Type ();
5654 rt = LLVMInt32Type ();
5655 g_assert_not_reached ();
5658 lhs = LLVMBuildBitCast (builder, lhs, t, "");
5659 rhs = LLVMBuildBitCast (builder, rhs, t, "");
5660 switch (ins->opcode) {
5663 v = LLVMBuildAnd (builder, lhs, rhs, "");
5667 v = LLVMBuildOr (builder, lhs, rhs, "");
5671 v = LLVMBuildXor (builder, lhs, rhs, "");
5675 v = LLVMBuildAnd (builder, rhs, LLVMBuildNot (builder, lhs, ""), "");
5678 values [ins->dreg] = LLVMBuildBitCast (builder, v, rt, "");
5702 case OP_PADDB_SAT_UN:
5703 case OP_PADDW_SAT_UN:
5704 case OP_PSUBB_SAT_UN:
5705 case OP_PSUBW_SAT_UN:
5713 case OP_PMULW_HIGH_UN: {
5714 LLVMValueRef args [2];
5719 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (lmodule, simd_op_to_intrins (ins->opcode)), args, 2, dname);
5726 values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildICmp (builder, LLVMIntEQ, lhs, rhs, ""), LLVMTypeOf (lhs), "");
5730 values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildICmp (builder, LLVMIntSGT, lhs, rhs, ""), LLVMTypeOf (lhs), "");
5738 case OP_EXTRACTX_U2:
5740 case OP_EXTRACT_U1: {
5742 gboolean zext = FALSE;
5744 t = simd_op_to_llvm_type (ins->opcode);
5746 switch (ins->opcode) {
5754 case OP_EXTRACTX_U2:
5759 t = LLVMInt32Type ();
5760 g_assert_not_reached ();
5763 lhs = LLVMBuildBitCast (builder, lhs, t, "");
5764 values [ins->dreg] = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), "");
5766 values [ins->dreg] = LLVMBuildZExt (builder, values [ins->dreg], LLVMInt32Type (), "");
5775 case OP_EXPAND_R8: {
5776 LLVMTypeRef t = simd_op_to_llvm_type (ins->opcode);
5777 LLVMValueRef mask [16], v;
5780 for (i = 0; i < 16; ++i)
5781 mask [i] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
5783 v = convert (ctx, values [ins->sreg1], LLVMGetElementType (t));
5785 values [ins->dreg] = LLVMBuildInsertElement (builder, LLVMConstNull (t), v, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
5786 values [ins->dreg] = LLVMBuildShuffleVector (builder, values [ins->dreg], LLVMGetUndef (t), LLVMConstVector (mask, LLVMGetVectorSize (t)), "");
5791 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt8Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
5794 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt16Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
5797 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt32Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
5800 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt64Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
5803 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMFloatType ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
5806 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMDoubleType ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
5817 case OP_EXTRACT_MASK:
5824 v = convert (ctx, values [ins->sreg1], simd_op_to_llvm_type (ins->opcode));
5826 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (lmodule, simd_op_to_intrins (ins->opcode)), &v, 1, dname);
5832 LLVMValueRef args [3];
5836 args [2] = LLVMConstInt (LLVMInt8Type (), ins->inst_c0, FALSE);
5838 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (lmodule, simd_op_to_intrins (ins->opcode)), args, 3, dname);
5843 /* This is only used for implementing shifts by non-immediate */
5844 values [ins->dreg] = lhs;
5855 LLVMValueRef args [3];
5858 args [1] = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
5860 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (lmodule, simd_op_to_intrins (ins->opcode)), args, 2, dname);
5871 case OP_PSHLQ_REG: {
5872 LLVMValueRef args [3];
5875 args [1] = values [ins->sreg2];
5877 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (lmodule, simd_op_to_intrins (ins->opcode)), args, 2, dname);
5884 case OP_PSHUFLEW_LOW:
5885 case OP_PSHUFLEW_HIGH: {
5887 LLVMValueRef v1 = NULL, v2 = NULL, mask_values [16];
5888 int i, mask_size = 0;
5889 int imask = ins->inst_c0;
5891 /* Convert the x86 shuffle mask to LLVM's */
5892 switch (ins->opcode) {
5895 mask [0] = ((imask >> 0) & 3);
5896 mask [1] = ((imask >> 2) & 3);
5897 mask [2] = ((imask >> 4) & 3) + 4;
5898 mask [3] = ((imask >> 6) & 3) + 4;
5899 v1 = values [ins->sreg1];
5900 v2 = values [ins->sreg2];
5904 mask [0] = ((imask >> 0) & 1);
5905 mask [1] = ((imask >> 1) & 1) + 2;
5906 v1 = values [ins->sreg1];
5907 v2 = values [ins->sreg2];
5909 case OP_PSHUFLEW_LOW:
5911 mask [0] = ((imask >> 0) & 3);
5912 mask [1] = ((imask >> 2) & 3);
5913 mask [2] = ((imask >> 4) & 3);
5914 mask [3] = ((imask >> 6) & 3);
5919 v1 = values [ins->sreg1];
5920 v2 = LLVMGetUndef (LLVMTypeOf (v1));
5922 case OP_PSHUFLEW_HIGH:
5928 mask [4] = 4 + ((imask >> 0) & 3);
5929 mask [5] = 4 + ((imask >> 2) & 3);
5930 mask [6] = 4 + ((imask >> 4) & 3);
5931 mask [7] = 4 + ((imask >> 6) & 3);
5932 v1 = values [ins->sreg1];
5933 v2 = LLVMGetUndef (LLVMTypeOf (v1));
5937 mask [0] = ((imask >> 0) & 3);
5938 mask [1] = ((imask >> 2) & 3);
5939 mask [2] = ((imask >> 4) & 3);
5940 mask [3] = ((imask >> 6) & 3);
5941 v1 = values [ins->sreg1];
5942 v2 = LLVMGetUndef (LLVMTypeOf (v1));
5945 g_assert_not_reached ();
5947 for (i = 0; i < mask_size; ++i)
5948 mask_values [i] = LLVMConstInt (LLVMInt32Type (), mask [i], FALSE);
5950 values [ins->dreg] =
5951 LLVMBuildShuffleVector (builder, v1, v2,
5952 LLVMConstVector (mask_values, mask_size), dname);
5956 case OP_UNPACK_LOWB:
5957 case OP_UNPACK_LOWW:
5958 case OP_UNPACK_LOWD:
5959 case OP_UNPACK_LOWQ:
5960 case OP_UNPACK_LOWPS:
5961 case OP_UNPACK_LOWPD:
5962 case OP_UNPACK_HIGHB:
5963 case OP_UNPACK_HIGHW:
5964 case OP_UNPACK_HIGHD:
5965 case OP_UNPACK_HIGHQ:
5966 case OP_UNPACK_HIGHPS:
5967 case OP_UNPACK_HIGHPD: {
5969 LLVMValueRef mask_values [16];
5970 int i, mask_size = 0;
5971 gboolean low = FALSE;
5973 switch (ins->opcode) {
5974 case OP_UNPACK_LOWB:
5978 case OP_UNPACK_LOWW:
5982 case OP_UNPACK_LOWD:
5983 case OP_UNPACK_LOWPS:
5987 case OP_UNPACK_LOWQ:
5988 case OP_UNPACK_LOWPD:
5992 case OP_UNPACK_HIGHB:
5995 case OP_UNPACK_HIGHW:
5998 case OP_UNPACK_HIGHD:
5999 case OP_UNPACK_HIGHPS:
6002 case OP_UNPACK_HIGHQ:
6003 case OP_UNPACK_HIGHPD:
6007 g_assert_not_reached ();
6011 for (i = 0; i < (mask_size / 2); ++i) {
6013 mask [(i * 2) + 1] = mask_size + i;
6016 for (i = 0; i < (mask_size / 2); ++i) {
6017 mask [(i * 2)] = (mask_size / 2) + i;
6018 mask [(i * 2) + 1] = mask_size + (mask_size / 2) + i;
6022 for (i = 0; i < mask_size; ++i)
6023 mask_values [i] = LLVMConstInt (LLVMInt32Type (), mask [i], FALSE);
6025 values [ins->dreg] =
6026 LLVMBuildShuffleVector (builder, values [ins->sreg1], values [ins->sreg2],
6027 LLVMConstVector (mask_values, mask_size), dname);
6032 LLVMTypeRef t = simd_op_to_llvm_type (ins->opcode);
6033 LLVMValueRef v, val;
6035 v = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
6036 val = LLVMConstNull (t);
6037 val = LLVMBuildInsertElement (builder, val, v, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
6038 val = LLVMBuildInsertElement (builder, val, v, LLVMConstInt (LLVMInt32Type (), 1, FALSE), dname);
6040 values [ins->dreg] = val;
6044 case OP_DUPPS_HIGH: {
6045 LLVMTypeRef t = simd_op_to_llvm_type (ins->opcode);
6046 LLVMValueRef v1, v2, val;
6049 if (ins->opcode == OP_DUPPS_LOW) {
6050 v1 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
6051 v2 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 2, FALSE), "");
6053 v1 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 1, FALSE), "");
6054 v2 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 3, FALSE), "");
6056 val = LLVMConstNull (t);
6057 val = LLVMBuildInsertElement (builder, val, v1, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
6058 val = LLVMBuildInsertElement (builder, val, v1, LLVMConstInt (LLVMInt32Type (), 1, FALSE), "");
6059 val = LLVMBuildInsertElement (builder, val, v2, LLVMConstInt (LLVMInt32Type (), 2, FALSE), "");
6060 val = LLVMBuildInsertElement (builder, val, v2, LLVMConstInt (LLVMInt32Type (), 3, FALSE), "");
6062 values [ins->dreg] = val;
6072 * EXCEPTION HANDLING
6074 case OP_IMPLICIT_EXCEPTION:
6075 /* This marks a place where an implicit exception can happen */
6076 if (bb->region != -1)
6077 LLVM_FAILURE (ctx, "implicit-exception");
6081 gboolean rethrow = (ins->opcode == OP_RETHROW);
6082 if (ctx->llvm_only) {
6083 emit_llvmonly_throw (ctx, bb, rethrow, lhs);
6084 has_terminator = TRUE;
6085 ctx->unreachable [bb->block_num] = TRUE;
6087 emit_throw (ctx, bb, rethrow, lhs);
6088 builder = ctx->builder;
6092 case OP_CALL_HANDLER: {
6094 * We don't 'call' handlers, but instead simply branch to them.
6095 * The code generated by ENDFINALLY will branch back to us.
6097 LLVMBasicBlockRef noex_bb;
6099 BBInfo *info = &bblocks [ins->inst_target_bb->block_num];
6101 bb_list = info->call_handler_return_bbs;
6104 * Set the indicator variable for the finally clause.
6106 lhs = info->finally_ind;
6108 LLVMBuildStore (builder, LLVMConstInt (LLVMInt32Type (), g_slist_length (bb_list) + 1, FALSE), lhs);
6110 /* Branch to the finally clause */
6111 LLVMBuildBr (builder, info->call_handler_target_bb);
6113 noex_bb = gen_bb (ctx, "CALL_HANDLER_CONT_BB");
6114 info->call_handler_return_bbs = g_slist_append_mempool (cfg->mempool, info->call_handler_return_bbs, noex_bb);
6116 builder = ctx->builder = create_builder (ctx);
6117 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
6119 bblocks [bb->block_num].end_bblock = noex_bb;
6122 case OP_START_HANDLER: {
6125 case OP_ENDFINALLY: {
6126 LLVMBasicBlockRef resume_bb;
6127 MonoBasicBlock *handler_bb;
6128 LLVMValueRef val, switch_ins, callee;
6132 handler_bb = (MonoBasicBlock*)g_hash_table_lookup (ctx->region_to_handler, GUINT_TO_POINTER (mono_get_block_region_notry (cfg, bb->region)));
6133 g_assert (handler_bb);
6134 info = &bblocks [handler_bb->block_num];
6135 lhs = info->finally_ind;
6138 bb_list = info->call_handler_return_bbs;
6140 resume_bb = gen_bb (ctx, "ENDFINALLY_RESUME_BB");
6142 /* Load the finally variable */
6143 val = LLVMBuildLoad (builder, lhs, "");
6145 /* Reset the variable */
6146 LLVMBuildStore (builder, LLVMConstInt (LLVMInt32Type (), 0, FALSE), lhs);
6148 /* Branch to either resume_bb, or to the bblocks in bb_list */
6149 switch_ins = LLVMBuildSwitch (builder, val, resume_bb, g_slist_length (bb_list));
6151 * The other targets are added at the end to handle OP_CALL_HANDLER
6152 * opcodes processed later.
6154 info->endfinally_switch_ins_list = g_slist_append_mempool (cfg->mempool, info->endfinally_switch_ins_list, switch_ins);
6156 builder = ctx->builder = create_builder (ctx);
6157 LLVMPositionBuilderAtEnd (ctx->builder, resume_bb);
6159 if (ctx->llvm_only) {
6160 emit_resume_eh (ctx, bb);
6162 if (ctx->cfg->compile_aot) {
6163 callee = get_callee (ctx, LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE), MONO_PATCH_INFO_INTERNAL_METHOD, "llvm_resume_unwind_trampoline");
6165 callee = LLVMGetNamedFunction (lmodule, "llvm_resume_unwind_trampoline");
6167 LLVMBuildCall (builder, callee, NULL, 0, "");
6168 LLVMBuildUnreachable (builder);
6171 has_terminator = TRUE;
6174 case OP_IL_SEQ_POINT:
6179 sprintf (reason, "opcode %s", mono_inst_name (ins->opcode));
6180 LLVM_FAILURE (ctx, reason);
6185 /* Convert the value to the type required by phi nodes */
6186 if (spec [MONO_INST_DEST] != ' ' && !MONO_IS_STORE_MEMBASE (ins) && ctx->vreg_types [ins->dreg]) {
6187 if (!values [ins->dreg])
6189 values [ins->dreg] = addresses [ins->dreg];
6191 values [ins->dreg] = convert (ctx, values [ins->dreg], ctx->vreg_types [ins->dreg]);
6194 /* Add stores for volatile variables */
6195 if (spec [MONO_INST_DEST] != ' ' && spec [MONO_INST_DEST] != 'v' && !MONO_IS_STORE_MEMBASE (ins))
6196 emit_volatile_store (ctx, ins->dreg);
6199 if (!has_terminator && bb->next_bb && (bb == cfg->bb_entry || bb->in_count > 0)) {
6200 LLVMBuildBr (builder, get_bb (ctx, bb->next_bb));
6203 if (bb == cfg->bb_exit && sig->ret->type == MONO_TYPE_VOID) {
6204 emit_dbg_loc (ctx, builder, cfg->header->code + cfg->header->code_size - 1);
6205 LLVMBuildRetVoid (builder);
6208 if (bb == cfg->bb_entry)
6209 ctx->last_alloca = LLVMGetLastInstruction (get_bb (ctx, cfg->bb_entry));
6218 * mono_llvm_check_method_supported:
6220 * Do some quick checks to decide whenever cfg->method can be compiled by LLVM, to avoid
6221 * compiling a method twice.
6224 mono_llvm_check_method_supported (MonoCompile *cfg)
6231 if (cfg->method->save_lmf) {
6232 cfg->exception_message = g_strdup ("lmf");
6233 cfg->disable_llvm = TRUE;
6235 if (cfg->disable_llvm)
6239 * Nested clauses where one of the clauses is a finally clause is
6240 * not supported, because LLVM can't figure out the control flow,
6241 * probably because we resume exception handling by calling our
6242 * own function instead of using the 'resume' llvm instruction.
6244 for (i = 0; i < cfg->header->num_clauses; ++i) {
6245 for (j = 0; j < cfg->header->num_clauses; ++j) {
6246 MonoExceptionClause *clause1 = &cfg->header->clauses [i];
6247 MonoExceptionClause *clause2 = &cfg->header->clauses [j];
6249 // FIXME: Nested try clauses fail in some cases too, i.e. #37273
6250 if (i != j && clause1->try_offset >= clause2->try_offset && clause1->handler_offset <= clause2->handler_offset) {
6251 //(clause1->flags == MONO_EXCEPTION_CLAUSE_FINALLY || clause2->flags == MONO_EXCEPTION_CLAUSE_FINALLY)) {
6252 cfg->exception_message = g_strdup ("nested clauses");
6253 cfg->disable_llvm = TRUE;
6258 if (cfg->disable_llvm)
6262 if (cfg->method->dynamic) {
6263 cfg->exception_message = g_strdup ("dynamic.");
6264 cfg->disable_llvm = TRUE;
6266 if (cfg->disable_llvm)
6270 static LLVMCallInfo*
6271 get_llvm_call_info (MonoCompile *cfg, MonoMethodSignature *sig)
6273 LLVMCallInfo *linfo;
6276 if (cfg->gsharedvt && cfg->llvm_only && mini_is_gsharedvt_variable_signature (sig)) {
6280 * Gsharedvt methods have the following calling convention:
6281 * - all arguments are passed by ref, even non generic ones
6282 * - the return value is returned by ref too, using a vret
6283 * argument passed after 'this'.
6285 n = sig->param_count + sig->hasthis;
6286 linfo = (LLVMCallInfo*)mono_mempool_alloc0 (cfg->mempool, sizeof (LLVMCallInfo) + (sizeof (LLVMArgInfo) * n));
6290 linfo->args [pindex ++].storage = LLVMArgNormal;
6292 if (sig->ret->type != MONO_TYPE_VOID) {
6293 if (mini_is_gsharedvt_variable_type (sig->ret))
6294 linfo->ret.storage = LLVMArgGsharedvtVariable;
6295 else if (mini_type_is_vtype (sig->ret))
6296 linfo->ret.storage = LLVMArgGsharedvtFixedVtype;
6298 linfo->ret.storage = LLVMArgGsharedvtFixed;
6299 linfo->vret_arg_index = pindex;
6301 linfo->ret.storage = LLVMArgNone;
6304 for (i = 0; i < sig->param_count; ++i) {
6305 if (sig->params [i]->byref)
6306 linfo->args [pindex].storage = LLVMArgNormal;
6307 else if (mini_is_gsharedvt_variable_type (sig->params [i]))
6308 linfo->args [pindex].storage = LLVMArgGsharedvtVariable;
6309 else if (mini_type_is_vtype (sig->params [i]))
6310 linfo->args [pindex].storage = LLVMArgGsharedvtFixedVtype;
6312 linfo->args [pindex].storage = LLVMArgGsharedvtFixed;
6313 linfo->args [pindex].type = sig->params [i];
6320 linfo = mono_arch_get_llvm_call_info (cfg, sig);
6321 for (i = 0; i < sig->param_count; ++i)
6322 linfo->args [i + sig->hasthis].type = sig->params [i];
6328 * mono_llvm_emit_method:
6330 * Emit LLVM IL from the mono IL, and compile it to native code using LLVM.
6333 mono_llvm_emit_method (MonoCompile *cfg)
6336 MonoMethodSignature *sig;
6338 LLVMTypeRef method_type;
6339 LLVMValueRef method = NULL;
6341 LLVMValueRef *values;
6342 int i, max_block_num, bb_index;
6343 gboolean last = FALSE, is_linkonce = FALSE;
6344 GPtrArray *phi_values;
6345 LLVMCallInfo *linfo;
6347 LLVMModuleRef lmodule;
6349 GPtrArray *bblock_list;
6350 MonoMethodHeader *header;
6351 MonoExceptionClause *clause;
6354 /* The code below might acquire the loader lock, so use it for global locking */
6355 mono_loader_lock ();
6357 /* Used to communicate with the callbacks */
6358 mono_native_tls_set_value (current_cfg_tls_id, cfg);
6360 ctx = g_new0 (EmitContext, 1);
6362 ctx->mempool = cfg->mempool;
6365 * This maps vregs to the LLVM instruction defining them
6367 values = g_new0 (LLVMValueRef, cfg->next_vreg);
6369 * This maps vregs for volatile variables to the LLVM instruction defining their
6372 ctx->addresses = g_new0 (LLVMValueRef, cfg->next_vreg);
6373 ctx->vreg_types = g_new0 (LLVMTypeRef, cfg->next_vreg);
6374 ctx->vreg_cli_types = g_new0 (MonoType*, cfg->next_vreg);
6375 phi_values = g_ptr_array_sized_new (256);
6377 * This signals whenever the vreg was defined by a phi node with no input vars
6378 * (i.e. all its input bblocks end with NOT_REACHABLE).
6380 ctx->is_dead = g_new0 (gboolean, cfg->next_vreg);
6381 /* Whenever the bblock is unreachable */
6382 ctx->unreachable = g_new0 (gboolean, cfg->max_block_num);
6383 bblock_list = g_ptr_array_sized_new (256);
6385 ctx->values = values;
6386 ctx->region_to_handler = g_hash_table_new (NULL, NULL);
6387 ctx->clause_to_handler = g_hash_table_new (NULL, NULL);
6388 ctx->method_to_callers = g_hash_table_new (NULL, NULL);
6390 if (cfg->compile_aot) {
6391 ctx->module = &aot_module;
6395 * Allow the linker to discard duplicate copies of wrappers, generic instances etc. by using the 'linkonce'
6396 * linkage for them. This requires the following:
6397 * - the method needs to have a unique mangled name
6398 * - llvmonly mode, since the code in aot-runtime.c would initialize got slots in the wrong aot image etc.
6400 is_linkonce = ctx->module->llvm_only && ctx->module->static_link && mono_aot_is_linkonce_method (cfg->method);
6402 method_name = mono_aot_get_mangled_method_name (cfg->method);
6404 is_linkonce = FALSE;
6407 printf ("%s %s\n", mono_method_full_name (cfg->method, 1), method_name);
6409 printf ("%s\n", mono_method_full_name (cfg->method, 1));
6413 method_name = mono_aot_get_method_name (cfg);
6414 cfg->llvm_method_name = g_strdup (method_name);
6416 init_jit_module (cfg->domain);
6417 ctx->module = (MonoLLVMModule*)domain_jit_info (cfg->domain)->llvm_module;
6418 method_name = mono_method_full_name (cfg->method, TRUE);
6421 lmodule = ctx->lmodule = ctx->module->lmodule;
6422 ctx->llvm_only = ctx->module->llvm_only;
6424 if (cfg->gsharedvt && !cfg->llvm_only)
6425 LLVM_FAILURE (ctx, "gsharedvt");
6429 static int count = 0;
6432 if (g_getenv ("LLVM_COUNT")) {
6433 if (count == atoi (g_getenv ("LLVM_COUNT"))) {
6434 printf ("LAST: %s\n", mono_method_full_name (cfg->method, TRUE));
6438 if (count > atoi (g_getenv ("LLVM_COUNT")))
6439 LLVM_FAILURE (ctx, "");
6444 sig = mono_method_signature (cfg->method);
6447 linfo = get_llvm_call_info (cfg, sig);
6449 CHECK_FAILURE (ctx);
6452 linfo->rgctx_arg = TRUE;
6453 method_type = sig_to_llvm_sig_full (ctx, sig, linfo);
6454 CHECK_FAILURE (ctx);
6456 method = LLVMAddFunction (lmodule, method_name, method_type);
6457 ctx->lmethod = method;
6459 if (!cfg->llvm_only)
6460 LLVMSetFunctionCallConv (method, LLVMMono1CallConv);
6461 LLVMSetLinkage (method, LLVMPrivateLinkage);
6463 LLVMAddFunctionAttr (method, LLVMUWTable);
6465 if (cfg->compile_aot) {
6466 LLVMSetLinkage (method, LLVMInternalLinkage);
6467 if (ctx->module->external_symbols) {
6468 LLVMSetLinkage (method, LLVMExternalLinkage);
6469 LLVMSetVisibility (method, LLVMHiddenVisibility);
6472 LLVMSetLinkage (method, LLVMLinkOnceAnyLinkage);
6473 LLVMSetVisibility (method, LLVMDefaultVisibility);
6476 LLVMSetLinkage (method, LLVMPrivateLinkage);
6479 if (cfg->method->save_lmf && !cfg->llvm_only)
6480 LLVM_FAILURE (ctx, "lmf");
6482 if (sig->pinvoke && cfg->method->wrapper_type != MONO_WRAPPER_RUNTIME_INVOKE && !cfg->llvm_only)
6483 LLVM_FAILURE (ctx, "pinvoke signature");
6485 header = cfg->header;
6486 for (i = 0; i < header->num_clauses; ++i) {
6487 clause = &header->clauses [i];
6488 if (clause->flags != MONO_EXCEPTION_CLAUSE_FINALLY && clause->flags != MONO_EXCEPTION_CLAUSE_NONE)
6489 LLVM_FAILURE (ctx, "non-finally/catch clause.");
6491 if (header->num_clauses || (cfg->method->iflags & METHOD_IMPL_ATTRIBUTE_NOINLINING) || cfg->no_inline)
6492 /* We can't handle inlined methods with clauses */
6493 LLVMAddFunctionAttr (method, LLVMNoInlineAttribute);
6495 if (linfo->rgctx_arg) {
6496 ctx->rgctx_arg = LLVMGetParam (method, linfo->rgctx_arg_pindex);
6497 ctx->rgctx_arg_pindex = linfo->rgctx_arg_pindex;
6499 * We mark the rgctx parameter with the inreg attribute, which is mapped to
6500 * MONO_ARCH_RGCTX_REG in the Mono calling convention in llvm, i.e.
6501 * CC_X86_64_Mono in X86CallingConv.td.
6503 if (!ctx->llvm_only)
6504 LLVMAddAttribute (ctx->rgctx_arg, LLVMInRegAttribute);
6505 LLVMSetValueName (ctx->rgctx_arg, "rgctx");
6507 ctx->rgctx_arg_pindex = -1;
6509 if (cfg->vret_addr) {
6510 values [cfg->vret_addr->dreg] = LLVMGetParam (method, linfo->vret_arg_pindex);
6511 LLVMSetValueName (values [cfg->vret_addr->dreg], "vret");
6512 if (linfo->ret.storage == LLVMArgVtypeByRef) {
6513 LLVMAddAttribute (LLVMGetParam (method, linfo->vret_arg_pindex), LLVMStructRetAttribute);
6514 LLVMAddAttribute (LLVMGetParam (method, linfo->vret_arg_pindex), LLVMNoAliasAttribute);
6516 } else if (linfo->ret.storage == LLVMArgScalarRetAddr) {
6517 LLVMValueRef param = LLVMGetParam (method, linfo->vret_arg_pindex);
6518 LLVMSetValueName (param, "vret");
6522 ctx->this_arg_pindex = linfo->this_arg_pindex;
6523 ctx->this_arg = LLVMGetParam (method, linfo->this_arg_pindex);
6524 values [cfg->args [0]->dreg] = ctx->this_arg;
6525 LLVMSetValueName (values [cfg->args [0]->dreg], "this");
6528 names = g_new (char *, sig->param_count);
6529 mono_method_get_param_names (cfg->method, (const char **) names);
6531 for (i = 0; i < sig->param_count; ++i) {
6532 LLVMArgInfo *ainfo = &linfo->args [i + sig->hasthis];
6534 int pindex = ainfo->pindex + ainfo->ndummy_fpargs;
6537 for (j = 0; j < ainfo->ndummy_fpargs; ++j) {
6538 name = g_strdup_printf ("dummy_%d_%d", i, j);
6539 LLVMSetValueName (LLVMGetParam (method, ainfo->pindex + j), name);
6543 values [cfg->args [i + sig->hasthis]->dreg] = LLVMGetParam (method, pindex);
6544 if (ainfo->storage == LLVMArgScalarByRef) {
6545 if (names [i] && names [i][0] != '\0')
6546 name = g_strdup_printf ("p_arg_%s", names [i]);
6548 name = g_strdup_printf ("p_arg_%d", i);
6549 } else if (ainfo->storage == LLVMArgGsharedvtFixed || ainfo->storage == LLVMArgGsharedvtFixedVtype) {
6550 if (names [i] && names [i][0] != '\0')
6551 name = g_strdup_printf ("p_arg_%s", names [i]);
6553 name = g_strdup_printf ("p_arg_%d", i);
6555 if (names [i] && names [i][0] != '\0')
6556 name = g_strdup_printf ("arg_%s", names [i]);
6558 name = g_strdup_printf ("arg_%d", i);
6560 LLVMSetValueName (values [cfg->args [i + sig->hasthis]->dreg], name);
6562 if (ainfo->storage == LLVMArgVtypeByVal)
6563 LLVMAddAttribute (LLVMGetParam (method, pindex), LLVMByValAttribute);
6565 if (ainfo->storage == LLVMArgVtypeByRef) {
6567 cfg->args [i + sig->hasthis]->opcode = OP_VTARG_ADDR;
6572 if (ctx->module->emit_dwarf && cfg->compile_aot && mono_debug_enabled ()) {
6573 ctx->minfo = mono_debug_lookup_method (cfg->method);
6574 ctx->dbg_md = emit_dbg_subprogram (ctx, cfg, method, method_name);
6578 for (bb = cfg->bb_entry; bb; bb = bb->next_bb)
6579 max_block_num = MAX (max_block_num, bb->block_num);
6580 ctx->bblocks = bblocks = g_new0 (BBInfo, max_block_num + 1);
6582 /* Add branches between non-consecutive bblocks */
6583 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
6584 if (bb->last_ins && MONO_IS_COND_BRANCH_OP (bb->last_ins) &&
6585 bb->next_bb != bb->last_ins->inst_false_bb) {
6587 MonoInst *inst = (MonoInst*)mono_mempool_alloc0 (cfg->mempool, sizeof (MonoInst));
6588 inst->opcode = OP_BR;
6589 inst->inst_target_bb = bb->last_ins->inst_false_bb;
6590 mono_bblock_add_inst (bb, inst);
6595 * The INDIRECT flag added by OP_LDADDR inhibits optimizations, even if the LDADDR
6596 * was later optimized away, so clear these flags, and add them back for the still
6597 * present OP_LDADDR instructions.
6599 for (i = 0; i < cfg->next_vreg; ++i) {
6602 ins = get_vreg_to_inst (cfg, i);
6603 if (ins && ins != cfg->rgctx_var)
6604 ins->flags &= ~MONO_INST_INDIRECT;
6608 * Make a first pass over the code to precreate PHI nodes/set INDIRECT flags.
6610 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
6612 LLVMBuilderRef builder;
6614 char dname_buf[128];
6616 builder = create_builder (ctx);
6618 for (ins = bb->code; ins; ins = ins->next) {
6619 switch (ins->opcode) {
6624 LLVMTypeRef phi_type = llvm_type_to_stack_type (cfg, type_to_llvm_type (ctx, &ins->klass->byval_arg));
6626 CHECK_FAILURE (ctx);
6628 if (ins->opcode == OP_VPHI) {
6629 /* Treat valuetype PHI nodes as operating on the address itself */
6630 g_assert (ins->klass);
6631 phi_type = LLVMPointerType (type_to_llvm_type (ctx, &ins->klass->byval_arg), 0);
6635 * Have to precreate these, as they can be referenced by
6636 * earlier instructions.
6638 sprintf (dname_buf, "t%d", ins->dreg);
6640 values [ins->dreg] = LLVMBuildPhi (builder, phi_type, dname);
6642 if (ins->opcode == OP_VPHI)
6643 ctx->addresses [ins->dreg] = values [ins->dreg];
6645 g_ptr_array_add (phi_values, values [ins->dreg]);
6648 * Set the expected type of the incoming arguments since these have
6649 * to have the same type.
6651 for (i = 0; i < ins->inst_phi_args [0]; i++) {
6652 int sreg1 = ins->inst_phi_args [i + 1];
6655 ctx->vreg_types [sreg1] = phi_type;
6660 ((MonoInst*)ins->inst_p0)->flags |= MONO_INST_INDIRECT;
6669 * Create an ordering for bblocks, use the depth first order first, then
6670 * put the exception handling bblocks last.
6672 for (bb_index = 0; bb_index < cfg->num_bblocks; ++bb_index) {
6673 bb = cfg->bblocks [bb_index];
6674 if (!(bb->region != -1 && !MONO_BBLOCK_IS_IN_REGION (bb, MONO_REGION_TRY))) {
6675 g_ptr_array_add (bblock_list, bb);
6676 bblocks [bb->block_num].added = TRUE;
6680 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
6681 if (!bblocks [bb->block_num].added)
6682 g_ptr_array_add (bblock_list, bb);
6686 * Second pass: generate code.
6689 LLVMBuilderRef entry_builder = create_builder (ctx);
6690 LLVMBasicBlockRef entry_bb = get_bb (ctx, cfg->bb_entry);
6691 LLVMPositionBuilderAtEnd (entry_builder, entry_bb);
6692 emit_entry_bb (ctx, entry_builder);
6694 // Make landing pads first
6695 ctx->exc_meta = g_hash_table_new_full (NULL, NULL, NULL, NULL);
6697 if (ctx->llvm_only) {
6698 size_t group_index = 0;
6699 while (group_index < cfg->header->num_clauses) {
6701 size_t cursor = group_index;
6702 while (cursor < cfg->header->num_clauses &&
6703 CLAUSE_START (&cfg->header->clauses [cursor]) == CLAUSE_START (&cfg->header->clauses [group_index]) &&
6704 CLAUSE_END (&cfg->header->clauses [cursor]) == CLAUSE_END (&cfg->header->clauses [group_index])) {
6709 LLVMBasicBlockRef lpad_bb = emit_landing_pad (ctx, group_index, count);
6710 intptr_t key = CLAUSE_END (&cfg->header->clauses [group_index]);
6711 g_hash_table_insert (ctx->exc_meta, (gpointer)key, lpad_bb);
6713 group_index = cursor;
6717 for (bb_index = 0; bb_index < bblock_list->len; ++bb_index) {
6718 bb = (MonoBasicBlock*)g_ptr_array_index (bblock_list, bb_index);
6720 // Prune unreachable mono BBs.
6721 if (!(bb == cfg->bb_entry || bb->in_count > 0))
6724 process_bb (ctx, bb);
6725 CHECK_FAILURE (ctx);
6727 g_hash_table_destroy (ctx->exc_meta);
6729 mono_memory_barrier ();
6731 /* Add incoming phi values */
6732 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
6733 GSList *l, *ins_list;
6735 ins_list = bblocks [bb->block_num].phi_nodes;
6737 for (l = ins_list; l; l = l->next) {
6738 PhiNode *node = (PhiNode*)l->data;
6739 MonoInst *phi = node->phi;
6740 int sreg1 = node->sreg;
6741 LLVMBasicBlockRef in_bb;
6746 in_bb = get_end_bb (ctx, node->in_bb);
6748 if (ctx->unreachable [node->in_bb->block_num])
6751 if (!values [sreg1])
6752 /* Can happen with values in EH clauses */
6753 LLVM_FAILURE (ctx, "incoming phi sreg1");
6755 if (phi->opcode == OP_VPHI) {
6756 g_assert (LLVMTypeOf (ctx->addresses [sreg1]) == LLVMTypeOf (values [phi->dreg]));
6757 LLVMAddIncoming (values [phi->dreg], &ctx->addresses [sreg1], &in_bb, 1);
6759 if (LLVMTypeOf (values [sreg1]) != LLVMTypeOf (values [phi->dreg]))
6761 LLVM_FAILURE (ctx, "incoming phi arg type mismatch");
6762 g_assert (LLVMTypeOf (values [sreg1]) == LLVMTypeOf (values [phi->dreg]));
6763 LLVMAddIncoming (values [phi->dreg], &values [sreg1], &in_bb, 1);
6768 /* Nullify empty phi instructions */
6769 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
6770 GSList *l, *ins_list;
6772 ins_list = bblocks [bb->block_num].phi_nodes;
6774 for (l = ins_list; l; l = l->next) {
6775 PhiNode *node = (PhiNode*)l->data;
6776 MonoInst *phi = node->phi;
6777 LLVMValueRef phi_ins = values [phi->dreg];
6780 /* Already removed */
6783 if (LLVMCountIncoming (phi_ins) == 0) {
6784 mono_llvm_replace_uses_of (phi_ins, LLVMConstNull (LLVMTypeOf (phi_ins)));
6785 LLVMInstructionEraseFromParent (phi_ins);
6786 values [phi->dreg] = NULL;
6791 /* Create the SWITCH statements for ENDFINALLY instructions */
6792 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
6793 BBInfo *info = &bblocks [bb->block_num];
6795 for (l = info->endfinally_switch_ins_list; l; l = l->next) {
6796 LLVMValueRef switch_ins = (LLVMValueRef)l->data;
6797 GSList *bb_list = info->call_handler_return_bbs;
6799 for (i = 0; i < g_slist_length (bb_list); ++i)
6800 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), i + 1, FALSE), (LLVMBasicBlockRef)(g_slist_nth (bb_list, i)->data));
6804 /* Initialize the method if needed */
6805 if (cfg->compile_aot && ctx->llvm_only) {
6806 // FIXME: Add more shared got entries
6807 ctx->builder = create_builder (ctx);
6808 LLVMPositionBuilderAtEnd (ctx->builder, ctx->init_bb);
6810 ctx->module->max_method_idx = MAX (ctx->module->max_method_idx, cfg->method_index);
6812 // FIXME: beforefieldinit
6813 if (ctx->has_got_access || mono_class_get_cctor (cfg->method->klass)) {
6814 emit_init_method (ctx);
6816 LLVMBuildBr (ctx->builder, ctx->inited_bb);
6820 if (cfg->llvm_only) {
6821 GHashTableIter iter;
6823 GSList *callers, *l, *l2;
6826 * Add the contents of ctx->method_to_callers to module->method_to_callers.
6827 * We can't do this earlier, as it contains llvm instructions which can be
6828 * freed if compilation fails.
6829 * FIXME: Get rid of this when all methods can be llvm compiled.
6831 g_hash_table_iter_init (&iter, ctx->method_to_callers);
6832 while (g_hash_table_iter_next (&iter, (void**)&method, (void**)&callers)) {
6833 for (l = callers; l; l = l->next) {
6834 l2 = (GSList*)g_hash_table_lookup (ctx->module->method_to_callers, method);
6835 l2 = g_slist_prepend (l2, l->data);
6836 g_hash_table_insert (ctx->module->method_to_callers, method, l2);
6841 if (cfg->verbose_level > 1)
6842 mono_llvm_dump_value (method);
6844 if (cfg->compile_aot && !cfg->llvm_only)
6845 mark_as_used (ctx->module, method);
6847 if (cfg->compile_aot) {
6848 LLVMValueRef md_args [16];
6849 LLVMValueRef md_node;
6852 method_index = mono_aot_get_method_index (cfg->orig_method);
6853 md_args [0] = LLVMMDString (method_name, strlen (method_name));
6854 md_args [1] = LLVMConstInt (LLVMInt32Type (), method_index, FALSE);
6855 md_node = LLVMMDNode (md_args, 2);
6856 LLVMAddNamedMetadataOperand (lmodule, "mono.function_indexes", md_node);
6857 //LLVMSetMetadata (method, md_kind, LLVMMDNode (&md_arg, 1));
6860 if (cfg->compile_aot) {
6861 /* Don't generate native code, keep the LLVM IR */
6862 if (cfg->verbose_level)
6863 printf ("%s emitted as %s\n", mono_method_full_name (cfg->method, TRUE), method_name);
6865 int err = LLVMVerifyFunction(method, LLVMPrintMessageAction);
6866 g_assert (err == 0);
6868 //LLVMVerifyFunction(method, 0);
6869 mono_llvm_optimize_method (ctx->module->mono_ee, method);
6871 if (cfg->verbose_level > 1)
6872 mono_llvm_dump_value (method);
6874 cfg->native_code = (unsigned char*)LLVMGetPointerToGlobal (ctx->module->ee, method);
6876 /* Set by emit_cb */
6877 g_assert (cfg->code_len);
6879 /* FIXME: Free the LLVM IL for the function */
6882 if (ctx->module->method_to_lmethod)
6883 g_hash_table_insert (ctx->module->method_to_lmethod, cfg->method, method);
6884 if (ctx->module->idx_to_lmethod)
6885 g_hash_table_insert (ctx->module->idx_to_lmethod, GINT_TO_POINTER (cfg->method_index), method);
6887 if (ctx->llvm_only && cfg->orig_method->klass->valuetype && !(cfg->orig_method->flags & METHOD_ATTRIBUTE_STATIC))
6888 emit_unbox_tramp (ctx, method_name, method_type, method, cfg->method_index);
6895 /* Need to add unused phi nodes as they can be referenced by other values */
6896 LLVMBasicBlockRef phi_bb = LLVMAppendBasicBlock (method, "PHI_BB");
6897 LLVMBuilderRef builder;
6899 builder = create_builder (ctx);
6900 LLVMPositionBuilderAtEnd (builder, phi_bb);
6902 for (i = 0; i < phi_values->len; ++i) {
6903 LLVMValueRef v = (LLVMValueRef)g_ptr_array_index (phi_values, i);
6904 if (LLVMGetInstructionParent (v) == NULL)
6905 LLVMInsertIntoBuilder (builder, v);
6908 LLVMDeleteFunction (method);
6913 g_free (ctx->addresses);
6914 g_free (ctx->vreg_types);
6915 g_free (ctx->vreg_cli_types);
6916 g_free (ctx->is_dead);
6917 g_free (ctx->unreachable);
6918 g_ptr_array_free (phi_values, TRUE);
6919 g_free (ctx->bblocks);
6920 g_hash_table_destroy (ctx->region_to_handler);
6921 g_hash_table_destroy (ctx->clause_to_handler);
6922 g_free (method_name);
6923 g_ptr_array_free (bblock_list, TRUE);
6925 for (l = ctx->builders; l; l = l->next) {
6926 LLVMBuilderRef builder = (LLVMBuilderRef)l->data;
6927 LLVMDisposeBuilder (builder);
6932 mono_native_tls_set_value (current_cfg_tls_id, NULL);
6934 mono_loader_unlock ();
6938 * mono_llvm_create_vars:
6940 * Same as mono_arch_create_vars () for LLVM.
6943 mono_llvm_create_vars (MonoCompile *cfg)
6945 MonoMethodSignature *sig;
6947 sig = mono_method_signature (cfg->method);
6948 if (cfg->gsharedvt && cfg->llvm_only) {
6949 if (mini_is_gsharedvt_variable_signature (sig) && sig->ret->type != MONO_TYPE_VOID) {
6950 cfg->vret_addr = mono_compile_create_var (cfg, &mono_get_intptr_class ()->byval_arg, OP_ARG);
6951 if (G_UNLIKELY (cfg->verbose_level > 1)) {
6952 printf ("vret_addr = ");
6953 mono_print_ins (cfg->vret_addr);
6957 mono_arch_create_vars (cfg);
6962 * mono_llvm_emit_call:
6964 * Same as mono_arch_emit_call () for LLVM.
6967 mono_llvm_emit_call (MonoCompile *cfg, MonoCallInst *call)
6970 MonoMethodSignature *sig;
6971 int i, n, stack_size;
6976 sig = call->signature;
6977 n = sig->param_count + sig->hasthis;
6979 call->cinfo = get_llvm_call_info (cfg, sig);
6981 if (cfg->disable_llvm)
6984 if (sig->call_convention == MONO_CALL_VARARG) {
6985 cfg->exception_message = g_strdup ("varargs");
6986 cfg->disable_llvm = TRUE;
6989 for (i = 0; i < n; ++i) {
6992 ainfo = call->cinfo->args + i;
6994 in = call->args [i];
6996 /* Simply remember the arguments */
6997 switch (ainfo->storage) {
6998 case LLVMArgNormal: {
6999 MonoType *t = (sig->hasthis && i == 0) ? &mono_get_intptr_class ()->byval_arg : ainfo->type;
7002 opcode = mono_type_to_regmove (cfg, t);
7003 if (opcode == OP_FMOVE) {
7004 MONO_INST_NEW (cfg, ins, OP_FMOVE);
7005 ins->dreg = mono_alloc_freg (cfg);
7006 } else if (opcode == OP_LMOVE) {
7007 MONO_INST_NEW (cfg, ins, OP_LMOVE);
7008 ins->dreg = mono_alloc_lreg (cfg);
7009 } else if (opcode == OP_RMOVE) {
7010 MONO_INST_NEW (cfg, ins, OP_RMOVE);
7011 ins->dreg = mono_alloc_freg (cfg);
7013 MONO_INST_NEW (cfg, ins, OP_MOVE);
7014 ins->dreg = mono_alloc_ireg (cfg);
7016 ins->sreg1 = in->dreg;
7019 case LLVMArgVtypeByVal:
7020 case LLVMArgVtypeByRef:
7021 case LLVMArgVtypeInReg:
7022 case LLVMArgVtypeAsScalar:
7023 case LLVMArgScalarByRef:
7024 case LLVMArgAsIArgs:
7025 case LLVMArgAsFpArgs:
7026 case LLVMArgGsharedvtVariable:
7027 case LLVMArgGsharedvtFixed:
7028 case LLVMArgGsharedvtFixedVtype:
7029 MONO_INST_NEW (cfg, ins, OP_LLVM_OUTARG_VT);
7030 ins->dreg = mono_alloc_ireg (cfg);
7031 ins->sreg1 = in->dreg;
7032 ins->inst_p0 = mono_mempool_alloc0 (cfg->mempool, sizeof (LLVMArgInfo));
7033 memcpy (ins->inst_p0, ainfo, sizeof (LLVMArgInfo));
7034 ins->inst_vtype = ainfo->type;
7035 ins->klass = mono_class_from_mono_type (ainfo->type);
7038 cfg->exception_message = g_strdup ("ainfo->storage");
7039 cfg->disable_llvm = TRUE;
7043 if (!cfg->disable_llvm) {
7044 MONO_ADD_INS (cfg->cbb, ins);
7045 mono_call_inst_add_outarg_reg (cfg, call, ins->dreg, 0, FALSE);
7050 static unsigned char*
7051 alloc_cb (LLVMValueRef function, int size)
7055 cfg = (MonoCompile*)mono_native_tls_get_value (current_cfg_tls_id);
7059 return (unsigned char*)mono_domain_code_reserve (cfg->domain, size);
7061 return (unsigned char*)mono_domain_code_reserve (mono_domain_get (), size);
7066 emitted_cb (LLVMValueRef function, void *start, void *end)
7070 cfg = (MonoCompile*)mono_native_tls_get_value (current_cfg_tls_id);
7072 cfg->code_len = (guint8*)end - (guint8*)start;
7076 exception_cb (void *data)
7079 MonoJitExceptionInfo *ei;
7080 guint32 ei_len, i, j, nested_len, nindex;
7081 gpointer *type_info;
7082 int this_reg, this_offset;
7084 cfg = (MonoCompile*)mono_native_tls_get_value (current_cfg_tls_id);
7088 * data points to a DWARF FDE structure, convert it to our unwind format and
7090 * An alternative would be to save it directly, and modify our unwinder to work
7093 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);
7094 if (cfg->verbose_level > 1)
7095 mono_print_unwind_info (cfg->encoded_unwind_ops, cfg->encoded_unwind_ops_len);
7097 /* Count nested clauses */
7099 for (i = 0; i < ei_len; ++i) {
7100 gint32 cindex1 = *(gint32*)type_info [i];
7101 MonoExceptionClause *clause1 = &cfg->header->clauses [cindex1];
7103 for (j = 0; j < cfg->header->num_clauses; ++j) {
7105 MonoExceptionClause *clause2 = &cfg->header->clauses [cindex2];
7107 if (cindex1 != cindex2 && clause1->try_offset >= clause2->try_offset && clause1->handler_offset <= clause2->handler_offset) {
7113 cfg->llvm_ex_info = (MonoJitExceptionInfo*)mono_mempool_alloc0 (cfg->mempool, (ei_len + nested_len) * sizeof (MonoJitExceptionInfo));
7114 cfg->llvm_ex_info_len = ei_len + nested_len;
7115 memcpy (cfg->llvm_ex_info, ei, ei_len * sizeof (MonoJitExceptionInfo));
7116 /* Fill the rest of the information from the type info */
7117 for (i = 0; i < ei_len; ++i) {
7118 gint32 clause_index = *(gint32*)type_info [i];
7119 MonoExceptionClause *clause = &cfg->header->clauses [clause_index];
7121 cfg->llvm_ex_info [i].flags = clause->flags;
7122 cfg->llvm_ex_info [i].data.catch_class = clause->data.catch_class;
7123 cfg->llvm_ex_info [i].clause_index = clause_index;
7127 * For nested clauses, the LLVM produced exception info associates the try interval with
7128 * the innermost handler, while mono expects it to be associated with all nesting clauses.
7129 * So add new clauses which use the IL info (catch class etc.) from the nesting clause,
7130 * and everything else from the nested clause.
7133 for (i = 0; i < ei_len; ++i) {
7134 gint32 cindex1 = *(gint32*)type_info [i];
7135 MonoExceptionClause *clause1 = &cfg->header->clauses [cindex1];
7137 for (j = 0; j < cfg->header->num_clauses; ++j) {
7139 MonoExceptionClause *clause2 = &cfg->header->clauses [cindex2];
7140 MonoJitExceptionInfo *nesting_ei, *nested_ei;
7142 if (cindex1 != cindex2 && clause1->try_offset >= clause2->try_offset && clause1->handler_offset <= clause2->handler_offset) {
7143 /* clause1 is the nested clause */
7144 nested_ei = &cfg->llvm_ex_info [i];
7145 nesting_ei = &cfg->llvm_ex_info [nindex];
7148 memcpy (nesting_ei, nested_ei, sizeof (MonoJitExceptionInfo));
7150 nesting_ei->flags = clause2->flags;
7151 nesting_ei->data.catch_class = clause2->data.catch_class;
7152 nesting_ei->clause_index = cindex2;
7156 g_assert (nindex == ei_len + nested_len);
7157 cfg->llvm_this_reg = this_reg;
7158 cfg->llvm_this_offset = this_offset;
7160 /* type_info [i] is cfg mempool allocated, no need to free it */
7167 dlsym_cb (const char *name, void **symbol)
7173 if (!strcmp (name, "__bzero")) {
7174 *symbol = (void*)bzero;
7176 current = mono_dl_open (NULL, 0, NULL);
7179 err = mono_dl_symbol (current, name, symbol);
7181 mono_dl_close (current);
7183 #ifdef MONO_ARCH_HAVE_CREATE_LLVM_NATIVE_THUNK
7184 *symbol = (char*)mono_arch_create_llvm_native_thunk (mono_domain_get (), (guint8*)(*symbol));
7190 AddFunc (LLVMModuleRef module, const char *name, LLVMTypeRef ret_type, LLVMTypeRef *param_types, int nparams)
7192 LLVMAddFunction (module, name, LLVMFunctionType (ret_type, param_types, nparams, FALSE));
7196 AddFunc2 (LLVMModuleRef module, const char *name, LLVMTypeRef ret_type, LLVMTypeRef param_type1, LLVMTypeRef param_type2)
7198 LLVMTypeRef param_types [4];
7200 param_types [0] = param_type1;
7201 param_types [1] = param_type2;
7203 AddFunc (module, name, ret_type, param_types, 2);
7207 add_intrinsics (LLVMModuleRef module)
7209 /* Emit declarations of instrinsics */
7211 * It would be nicer to emit only the intrinsics actually used, but LLVM's Module
7212 * type doesn't seem to do any locking.
7215 LLVMTypeRef params [] = { LLVMPointerType (LLVMInt8Type (), 0), LLVMInt8Type (), LLVMInt32Type (), LLVMInt32Type (), LLVMInt1Type () };
7217 memset_param_count = 5;
7218 memset_func_name = "llvm.memset.p0i8.i32";
7220 AddFunc (module, memset_func_name, LLVMVoidType (), params, memset_param_count);
7224 LLVMTypeRef params [] = { LLVMPointerType (LLVMInt8Type (), 0), LLVMPointerType (LLVMInt8Type (), 0), LLVMInt32Type (), LLVMInt32Type (), LLVMInt1Type () };
7226 memcpy_param_count = 5;
7227 memcpy_func_name = "llvm.memcpy.p0i8.p0i8.i32";
7229 AddFunc (module, memcpy_func_name, LLVMVoidType (), params, memcpy_param_count);
7233 LLVMTypeRef params [] = { LLVMDoubleType () };
7235 AddFunc (module, "llvm.sin.f64", LLVMDoubleType (), params, 1);
7236 AddFunc (module, "llvm.cos.f64", LLVMDoubleType (), params, 1);
7237 AddFunc (module, "llvm.sqrt.f64", LLVMDoubleType (), params, 1);
7239 /* This isn't an intrinsic, instead llvm seems to special case it by name */
7240 AddFunc (module, "fabs", LLVMDoubleType (), params, 1);
7244 LLVMTypeRef ovf_res_i32 [] = { LLVMInt32Type (), LLVMInt1Type () };
7245 LLVMTypeRef params [] = { LLVMInt32Type (), LLVMInt32Type () };
7246 LLVMTypeRef ret_type = LLVMStructType (ovf_res_i32, 2, FALSE);
7248 AddFunc (module, "llvm.sadd.with.overflow.i32", ret_type, params, 2);
7249 AddFunc (module, "llvm.sadd.with.overflow.i32", ret_type, params, 2);
7250 AddFunc (module, "llvm.uadd.with.overflow.i32", ret_type, params, 2);
7251 AddFunc (module, "llvm.ssub.with.overflow.i32", ret_type, params, 2);
7252 AddFunc (module, "llvm.usub.with.overflow.i32", ret_type, params, 2);
7253 AddFunc (module, "llvm.smul.with.overflow.i32", ret_type, params, 2);
7254 AddFunc (module, "llvm.umul.with.overflow.i32", ret_type, params, 2);
7258 LLVMTypeRef ovf_res_i64 [] = { LLVMInt64Type (), LLVMInt1Type () };
7259 LLVMTypeRef params [] = { LLVMInt64Type (), LLVMInt64Type () };
7260 LLVMTypeRef ret_type = LLVMStructType (ovf_res_i64, 2, FALSE);
7262 AddFunc (module, "llvm.sadd.with.overflow.i64", ret_type, params, 2);
7263 AddFunc (module, "llvm.uadd.with.overflow.i64", ret_type, params, 2);
7264 AddFunc (module, "llvm.ssub.with.overflow.i64", ret_type, params, 2);
7265 AddFunc (module, "llvm.usub.with.overflow.i64", ret_type, params, 2);
7266 AddFunc (module, "llvm.smul.with.overflow.i64", ret_type, params, 2);
7267 AddFunc (module, "llvm.umul.with.overflow.i64", ret_type, params, 2);
7270 AddFunc2 (module, "llvm.expect.i8", LLVMInt8Type (), LLVMInt8Type (), LLVMInt8Type ());
7271 AddFunc2 (module, "llvm.expect.i1", LLVMInt1Type (), LLVMInt1Type (), LLVMInt1Type ());
7275 AddFunc (module, "mono_personality", LLVMVoidType (), NULL, 0);
7277 AddFunc (module, "llvm_resume_unwind_trampoline", LLVMVoidType (), NULL, 0);
7280 /* SSE intrinsics */
7281 #if defined(TARGET_X86) || defined(TARGET_AMD64)
7283 LLVMTypeRef ret_type, arg_types [16];
7286 ret_type = type_to_simd_type (MONO_TYPE_I4);
7287 arg_types [0] = ret_type;
7288 arg_types [1] = ret_type;
7289 AddFunc (module, "llvm.x86.sse41.pminud", ret_type, arg_types, 2);
7290 AddFunc (module, "llvm.x86.sse41.pmaxud", ret_type, arg_types, 2);
7292 ret_type = type_to_simd_type (MONO_TYPE_I2);
7293 arg_types [0] = ret_type;
7294 arg_types [1] = ret_type;
7295 AddFunc (module, "llvm.x86.sse41.pminuw", ret_type, arg_types, 2);
7296 AddFunc (module, "llvm.x86.sse2.pmins.w", ret_type, arg_types, 2);
7297 AddFunc (module, "llvm.x86.sse41.pmaxuw", ret_type, arg_types, 2);
7298 AddFunc (module, "llvm.x86.sse2.padds.w", ret_type, arg_types, 2);
7299 AddFunc (module, "llvm.x86.sse2.psubs.w", ret_type, arg_types, 2);
7300 AddFunc (module, "llvm.x86.sse2.paddus.w", ret_type, arg_types, 2);
7301 AddFunc (module, "llvm.x86.sse2.psubus.w", ret_type, arg_types, 2);
7302 AddFunc (module, "llvm.x86.sse2.pavg.w", ret_type, arg_types, 2);
7303 AddFunc (module, "llvm.x86.sse2.pmulh.w", ret_type, arg_types, 2);
7304 AddFunc (module, "llvm.x86.sse2.pmulhu.w", ret_type, arg_types, 2);
7306 ret_type = type_to_simd_type (MONO_TYPE_I1);
7307 arg_types [0] = ret_type;
7308 arg_types [1] = ret_type;
7309 AddFunc (module, "llvm.x86.sse2.pminu.b", ret_type, arg_types, 2);
7310 AddFunc (module, "llvm.x86.sse2.pmaxu.b", ret_type, arg_types, 2);
7311 AddFunc (module, "llvm.x86.sse2.padds.b", ret_type, arg_types, 2);
7312 AddFunc (module, "llvm.x86.sse2.psubs.b", ret_type, arg_types, 2);
7313 AddFunc (module, "llvm.x86.sse2.paddus.b", ret_type, arg_types, 2);
7314 AddFunc (module, "llvm.x86.sse2.psubus.b", ret_type, arg_types, 2);
7315 AddFunc (module, "llvm.x86.sse2.pavg.b", ret_type, arg_types, 2);
7317 ret_type = type_to_simd_type (MONO_TYPE_R8);
7318 arg_types [0] = ret_type;
7319 arg_types [1] = ret_type;
7320 AddFunc (module, "llvm.x86.sse2.min.pd", ret_type, arg_types, 2);
7321 AddFunc (module, "llvm.x86.sse2.max.pd", ret_type, arg_types, 2);
7322 AddFunc (module, "llvm.x86.sse3.hadd.pd", ret_type, arg_types, 2);
7323 AddFunc (module, "llvm.x86.sse3.hsub.pd", ret_type, arg_types, 2);
7324 AddFunc (module, "llvm.x86.sse3.addsub.pd", ret_type, arg_types, 2);
7326 ret_type = type_to_simd_type (MONO_TYPE_R4);
7327 arg_types [0] = ret_type;
7328 arg_types [1] = ret_type;
7329 AddFunc (module, "llvm.x86.sse.min.ps", ret_type, arg_types, 2);
7330 AddFunc (module, "llvm.x86.sse.max.ps", ret_type, arg_types, 2);
7331 AddFunc (module, "llvm.x86.sse3.hadd.ps", ret_type, arg_types, 2);
7332 AddFunc (module, "llvm.x86.sse3.hsub.ps", ret_type, arg_types, 2);
7333 AddFunc (module, "llvm.x86.sse3.addsub.ps", ret_type, arg_types, 2);
7336 ret_type = type_to_simd_type (MONO_TYPE_I1);
7337 arg_types [0] = type_to_simd_type (MONO_TYPE_I2);
7338 arg_types [1] = type_to_simd_type (MONO_TYPE_I2);
7339 AddFunc (module, "llvm.x86.sse2.packsswb.128", ret_type, arg_types, 2);
7340 AddFunc (module, "llvm.x86.sse2.packuswb.128", ret_type, arg_types, 2);
7341 ret_type = type_to_simd_type (MONO_TYPE_I2);
7342 arg_types [0] = type_to_simd_type (MONO_TYPE_I4);
7343 arg_types [1] = type_to_simd_type (MONO_TYPE_I4);
7344 AddFunc (module, "llvm.x86.sse2.packssdw.128", ret_type, arg_types, 2);
7345 AddFunc (module, "llvm.x86.sse41.packusdw", ret_type, arg_types, 2);
7348 ret_type = type_to_simd_type (MONO_TYPE_R8);
7349 arg_types [0] = ret_type;
7350 arg_types [1] = ret_type;
7351 arg_types [2] = LLVMInt8Type ();
7352 AddFunc (module, "llvm.x86.sse2.cmp.pd", ret_type, arg_types, 3);
7353 ret_type = type_to_simd_type (MONO_TYPE_R4);
7354 arg_types [0] = ret_type;
7355 arg_types [1] = ret_type;
7356 arg_types [2] = LLVMInt8Type ();
7357 AddFunc (module, "llvm.x86.sse.cmp.ps", ret_type, arg_types, 3);
7359 /* Conversion ops */
7360 ret_type = type_to_simd_type (MONO_TYPE_R8);
7361 arg_types [0] = type_to_simd_type (MONO_TYPE_I4);
7362 AddFunc (module, "llvm.x86.sse2.cvtdq2pd", ret_type, arg_types, 1);
7363 ret_type = type_to_simd_type (MONO_TYPE_R4);
7364 arg_types [0] = type_to_simd_type (MONO_TYPE_I4);
7365 AddFunc (module, "llvm.x86.sse2.cvtdq2ps", ret_type, arg_types, 1);
7366 ret_type = type_to_simd_type (MONO_TYPE_I4);
7367 arg_types [0] = type_to_simd_type (MONO_TYPE_R8);
7368 AddFunc (module, "llvm.x86.sse2.cvtpd2dq", ret_type, arg_types, 1);
7369 ret_type = type_to_simd_type (MONO_TYPE_I4);
7370 arg_types [0] = type_to_simd_type (MONO_TYPE_R4);
7371 AddFunc (module, "llvm.x86.sse2.cvtps2dq", ret_type, arg_types, 1);
7372 ret_type = type_to_simd_type (MONO_TYPE_R4);
7373 arg_types [0] = type_to_simd_type (MONO_TYPE_R8);
7374 AddFunc (module, "llvm.x86.sse2.cvtpd2ps", ret_type, arg_types, 1);
7375 ret_type = type_to_simd_type (MONO_TYPE_R8);
7376 arg_types [0] = type_to_simd_type (MONO_TYPE_R4);
7377 AddFunc (module, "llvm.x86.sse2.cvtps2pd", ret_type, arg_types, 1);
7379 ret_type = type_to_simd_type (MONO_TYPE_I4);
7380 arg_types [0] = type_to_simd_type (MONO_TYPE_R8);
7381 AddFunc (module, "llvm.x86.sse2.cvttpd2dq", ret_type, arg_types, 1);
7382 ret_type = type_to_simd_type (MONO_TYPE_I4);
7383 arg_types [0] = type_to_simd_type (MONO_TYPE_R4);
7384 AddFunc (module, "llvm.x86.sse2.cvttps2dq", ret_type, arg_types, 1);
7387 ret_type = type_to_simd_type (MONO_TYPE_R8);
7388 arg_types [0] = ret_type;
7389 AddFunc (module, "llvm.x86.sse2.sqrt.pd", ret_type, arg_types, 1);
7390 ret_type = type_to_simd_type (MONO_TYPE_R4);
7391 arg_types [0] = ret_type;
7392 AddFunc (module, "llvm.x86.sse.sqrt.ps", ret_type, arg_types, 1);
7393 ret_type = type_to_simd_type (MONO_TYPE_R4);
7394 arg_types [0] = ret_type;
7395 AddFunc (module, "llvm.x86.sse.rsqrt.ps", ret_type, arg_types, 1);
7396 ret_type = type_to_simd_type (MONO_TYPE_R4);
7397 arg_types [0] = ret_type;
7398 AddFunc (module, "llvm.x86.sse.rcp.ps", ret_type, arg_types, 1);
7401 ret_type = type_to_simd_type (MONO_TYPE_I2);
7402 arg_types [0] = ret_type;
7403 arg_types [1] = LLVMInt32Type ();
7404 AddFunc (module, "llvm.x86.sse2.psrli.w", ret_type, arg_types, 2);
7405 AddFunc (module, "llvm.x86.sse2.psrai.w", ret_type, arg_types, 2);
7406 AddFunc (module, "llvm.x86.sse2.pslli.w", ret_type, arg_types, 2);
7407 ret_type = type_to_simd_type (MONO_TYPE_I4);
7408 arg_types [0] = ret_type;
7409 arg_types [1] = LLVMInt32Type ();
7410 AddFunc (module, "llvm.x86.sse2.psrli.d", ret_type, arg_types, 2);
7411 AddFunc (module, "llvm.x86.sse2.psrai.d", ret_type, arg_types, 2);
7412 AddFunc (module, "llvm.x86.sse2.pslli.d", ret_type, arg_types, 2);
7413 ret_type = type_to_simd_type (MONO_TYPE_I8);
7414 arg_types [0] = ret_type;
7415 arg_types [1] = LLVMInt32Type ();
7416 AddFunc (module, "llvm.x86.sse2.psrli.q", ret_type, arg_types, 2);
7417 AddFunc (module, "llvm.x86.sse2.pslli.q", ret_type, arg_types, 2);
7420 ret_type = LLVMInt32Type ();
7421 arg_types [0] = type_to_simd_type (MONO_TYPE_I1);
7422 AddFunc (module, "llvm.x86.sse2.pmovmskb.128", ret_type, arg_types, 1);
7425 AddFunc (module, "llvm.x86.sse2.pause", LLVMVoidType (), NULL, 0);
7428 /* Load/Store intrinsics */
7430 LLVMTypeRef arg_types [5];
7434 for (i = 1; i <= 8; i *= 2) {
7435 arg_types [0] = LLVMPointerType (LLVMIntType (i * 8), 0);
7436 arg_types [1] = LLVMInt32Type ();
7437 arg_types [2] = LLVMInt1Type ();
7438 arg_types [3] = LLVMInt32Type ();
7439 sprintf (name, "llvm.mono.load.i%d.p0i%d", i * 8, i * 8);
7440 AddFunc (module, name, LLVMIntType (i * 8), arg_types, 4);
7442 arg_types [0] = LLVMIntType (i * 8);
7443 arg_types [1] = LLVMPointerType (LLVMIntType (i * 8), 0);
7444 arg_types [2] = LLVMInt32Type ();
7445 arg_types [3] = LLVMInt1Type ();
7446 arg_types [4] = LLVMInt32Type ();
7447 sprintf (name, "llvm.mono.store.i%d.p0i%d", i * 8, i * 8);
7448 AddFunc (module, name, LLVMVoidType (), arg_types, 5);
7454 add_types (MonoLLVMModule *module)
7456 module->ptr_type = LLVMPointerType (sizeof (gpointer) == 8 ? LLVMInt64Type () : LLVMInt32Type (), 0);
7460 mono_llvm_init (void)
7462 mono_native_tls_alloc (¤t_cfg_tls_id, NULL);
7466 init_jit_module (MonoDomain *domain)
7468 MonoJitICallInfo *info;
7469 MonoJitDomainInfo *dinfo;
7470 MonoLLVMModule *module;
7473 dinfo = domain_jit_info (domain);
7474 if (dinfo->llvm_module)
7477 mono_loader_lock ();
7479 if (dinfo->llvm_module) {
7480 mono_loader_unlock ();
7484 module = g_new0 (MonoLLVMModule, 1);
7486 name = g_strdup_printf ("mono-%s", domain->friendly_name);
7487 module->lmodule = LLVMModuleCreateWithName (name);
7488 module->context = LLVMGetGlobalContext ();
7490 module->mono_ee = (MonoEERef*)mono_llvm_create_ee (LLVMCreateModuleProviderForExistingModule (module->lmodule), alloc_cb, emitted_cb, exception_cb, dlsym_cb, &module->ee);
7492 add_intrinsics (module->lmodule);
7495 module->llvm_types = g_hash_table_new (NULL, NULL);
7497 info = mono_find_jit_icall_by_name ("llvm_resume_unwind_trampoline");
7499 LLVMAddGlobalMapping (module->ee, LLVMGetNamedFunction (module->lmodule, "llvm_resume_unwind_trampoline"), (void*)info->func);
7501 mono_memory_barrier ();
7503 dinfo->llvm_module = module;
7505 mono_loader_unlock ();
7509 mono_llvm_cleanup (void)
7511 MonoLLVMModule *module = &aot_module;
7513 if (module->lmodule)
7514 LLVMDisposeModule (module->lmodule);
7516 if (module->context)
7517 LLVMContextDispose (module->context);
7521 mono_llvm_free_domain_info (MonoDomain *domain)
7523 MonoJitDomainInfo *info = domain_jit_info (domain);
7524 MonoLLVMModule *module = (MonoLLVMModule*)info->llvm_module;
7530 if (module->llvm_types)
7531 g_hash_table_destroy (module->llvm_types);
7533 mono_llvm_dispose_ee (module->mono_ee);
7535 if (module->bb_names) {
7536 for (i = 0; i < module->bb_names_len; ++i)
7537 g_free (module->bb_names [i]);
7538 g_free (module->bb_names);
7540 //LLVMDisposeModule (module->module);
7544 info->llvm_module = NULL;
7548 mono_llvm_create_aot_module (MonoAssembly *assembly, const char *global_prefix, gboolean emit_dwarf, gboolean static_link, gboolean llvm_only)
7550 MonoLLVMModule *module = &aot_module;
7552 /* Delete previous module */
7553 if (module->plt_entries)
7554 g_hash_table_destroy (module->plt_entries);
7555 if (module->lmodule)
7556 LLVMDisposeModule (module->lmodule);
7558 memset (module, 0, sizeof (aot_module));
7560 module->lmodule = LLVMModuleCreateWithName ("aot");
7561 module->assembly = assembly;
7562 module->global_prefix = g_strdup (global_prefix);
7563 module->got_symbol = g_strdup_printf ("%s_llvm_got", global_prefix);
7564 module->eh_frame_symbol = g_strdup_printf ("%s_eh_frame", global_prefix);
7565 module->get_method_symbol = g_strdup_printf ("%s_get_method", global_prefix);
7566 module->get_unbox_tramp_symbol = g_strdup_printf ("%s_get_unbox_tramp", global_prefix);
7567 module->external_symbols = TRUE;
7568 module->emit_dwarf = emit_dwarf;
7569 module->static_link = static_link;
7570 module->llvm_only = llvm_only;
7571 /* The first few entries are reserved */
7572 module->max_got_offset = 16;
7573 module->context = LLVMContextCreate ();
7576 /* clang ignores our debug info because it has an invalid version */
7577 module->emit_dwarf = FALSE;
7579 add_intrinsics (module->lmodule);
7584 * We couldn't compute the type of the LLVM global representing the got because
7585 * its size is only known after all the methods have been emitted. So create
7586 * a dummy variable, and replace all uses it with the real got variable when
7587 * its size is known in mono_llvm_emit_aot_module ().
7590 LLVMTypeRef got_type = LLVMArrayType (module->ptr_type, 0);
7592 module->got_var = LLVMAddGlobal (module->lmodule, got_type, "mono_dummy_got");
7593 LLVMSetInitializer (module->got_var, LLVMConstNull (got_type));
7596 /* Add initialization array */
7598 LLVMTypeRef inited_type = LLVMArrayType (LLVMInt8Type (), 0);
7600 module->inited_var = LLVMAddGlobal (aot_module.lmodule, inited_type, "mono_inited_tmp");
7601 LLVMSetInitializer (module->inited_var, LLVMConstNull (inited_type));
7605 emit_init_icall_wrappers (module);
7607 emit_llvm_code_start (module);
7609 /* Add a dummy personality function */
7610 if (!use_debug_personality) {
7611 LLVMValueRef personality = LLVMAddFunction (module->lmodule, default_personality_name, LLVMFunctionType (LLVMInt32Type (), NULL, 0, TRUE));
7612 LLVMSetLinkage (personality, LLVMExternalLinkage);
7613 mark_as_used (module, personality);
7616 /* Add a reference to the c++ exception we throw/catch */
7618 LLVMTypeRef exc = LLVMPointerType (LLVMInt8Type (), 0);
7619 module->sentinel_exception = LLVMAddGlobal (module->lmodule, exc, "_ZTIPi");
7620 LLVMSetLinkage (module->sentinel_exception, LLVMExternalLinkage);
7621 mono_llvm_set_is_constant (module->sentinel_exception);
7624 module->llvm_types = g_hash_table_new (NULL, NULL);
7625 module->plt_entries = g_hash_table_new (g_str_hash, g_str_equal);
7626 module->plt_entries_ji = g_hash_table_new (NULL, NULL);
7627 module->direct_callables = g_hash_table_new (g_str_hash, g_str_equal);
7628 module->method_to_lmethod = g_hash_table_new (NULL, NULL);
7629 module->idx_to_lmethod = g_hash_table_new (NULL, NULL);
7630 module->idx_to_unbox_tramp = g_hash_table_new (NULL, NULL);
7631 module->method_to_callers = g_hash_table_new (NULL, NULL);
7635 llvm_array_from_uints (LLVMTypeRef el_type, guint32 *values, int nvalues)
7638 LLVMValueRef res, *vals;
7640 vals = g_new0 (LLVMValueRef, nvalues);
7641 for (i = 0; i < nvalues; ++i)
7642 vals [i] = LLVMConstInt (LLVMInt32Type (), values [i], FALSE);
7643 res = LLVMConstArray (LLVMInt32Type (), vals, nvalues);
7649 * mono_llvm_emit_aot_file_info:
7651 * Emit the MonoAotFileInfo structure.
7652 * Same as emit_aot_file_info () in aot-compiler.c.
7655 mono_llvm_emit_aot_file_info (MonoAotFileInfo *info, gboolean has_jitted_code)
7657 MonoLLVMModule *module = &aot_module;
7659 /* Save these for later */
7660 memcpy (&module->aot_info, info, sizeof (MonoAotFileInfo));
7661 module->has_jitted_code = has_jitted_code;
7665 * mono_llvm_emit_aot_data:
7667 * Emit the binary data DATA pointed to by symbol SYMBOL.
7670 mono_llvm_emit_aot_data (const char *symbol, guint8 *data, int data_len)
7672 MonoLLVMModule *module = &aot_module;
7676 type = LLVMArrayType (LLVMInt8Type (), data_len);
7677 d = LLVMAddGlobal (module->lmodule, type, symbol);
7678 LLVMSetVisibility (d, LLVMHiddenVisibility);
7679 LLVMSetLinkage (d, LLVMInternalLinkage);
7680 LLVMSetInitializer (d, mono_llvm_create_constant_data_array (data, data_len));
7681 mono_llvm_set_is_constant (d);
7684 /* Add a reference to a global defined in JITted code */
7686 AddJitGlobal (MonoLLVMModule *module, LLVMTypeRef type, const char *name)
7691 s = g_strdup_printf ("%s%s", module->global_prefix, name);
7692 v = LLVMAddGlobal (module->lmodule, LLVMInt8Type (), s);
7698 emit_aot_file_info (MonoLLVMModule *module)
7700 LLVMTypeRef file_info_type;
7701 LLVMTypeRef *eltypes, eltype;
7702 LLVMValueRef info_var;
7703 LLVMValueRef *fields;
7704 int i, nfields, tindex;
7705 MonoAotFileInfo *info;
7706 LLVMModuleRef lmodule = module->lmodule;
7708 info = &module->aot_info;
7710 /* Create an LLVM type to represent MonoAotFileInfo */
7711 nfields = 2 + MONO_AOT_FILE_INFO_NUM_SYMBOLS + 15 + 5;
7712 eltypes = g_new (LLVMTypeRef, nfields);
7714 eltypes [tindex ++] = LLVMInt32Type ();
7715 eltypes [tindex ++] = LLVMInt32Type ();
7717 for (i = 0; i < MONO_AOT_FILE_INFO_NUM_SYMBOLS; ++i)
7718 eltypes [tindex ++] = LLVMPointerType (LLVMInt8Type (), 0);
7720 for (i = 0; i < 15; ++i)
7721 eltypes [tindex ++] = LLVMInt32Type ();
7723 eltypes [tindex ++] = LLVMArrayType (LLVMInt32Type (), MONO_AOT_TABLE_NUM);
7724 for (i = 0; i < 4; ++i)
7725 eltypes [tindex ++] = LLVMArrayType (LLVMInt32Type (), MONO_AOT_TRAMP_NUM);
7726 g_assert (tindex == nfields);
7727 file_info_type = LLVMStructCreateNamed (module->context, "MonoAotFileInfo");
7728 LLVMStructSetBody (file_info_type, eltypes, nfields, FALSE);
7730 info_var = LLVMAddGlobal (lmodule, file_info_type, "mono_aot_file_info");
7731 if (module->static_link) {
7732 LLVMSetVisibility (info_var, LLVMHiddenVisibility);
7733 LLVMSetLinkage (info_var, LLVMInternalLinkage);
7735 fields = g_new (LLVMValueRef, nfields);
7737 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->version, FALSE);
7738 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->dummy, FALSE);
7742 * We use LLVMGetNamedGlobal () for symbol which are defined in LLVM code, and LLVMAddGlobal ()
7743 * for symbols defined in the .s file emitted by the aot compiler.
7745 eltype = eltypes [tindex];
7746 if (module->llvm_only)
7747 fields [tindex ++] = LLVMConstNull (eltype);
7749 fields [tindex ++] = AddJitGlobal (module, eltype, "jit_got");
7750 fields [tindex ++] = module->got_var;
7751 /* llc defines this directly */
7752 if (!module->llvm_only) {
7753 fields [tindex ++] = LLVMAddGlobal (lmodule, eltype, module->eh_frame_symbol);
7754 fields [tindex ++] = LLVMConstNull (eltype);
7755 fields [tindex ++] = LLVMConstNull (eltype);
7757 fields [tindex ++] = LLVMConstNull (eltype);
7758 fields [tindex ++] = module->get_method;
7759 fields [tindex ++] = module->get_unbox_tramp;
7761 if (module->has_jitted_code) {
7762 fields [tindex ++] = AddJitGlobal (module, eltype, "jit_code_start");
7763 fields [tindex ++] = AddJitGlobal (module, eltype, "jit_code_end");
7765 fields [tindex ++] = LLVMConstNull (eltype);
7766 fields [tindex ++] = LLVMConstNull (eltype);
7768 if (!module->llvm_only)
7769 fields [tindex ++] = AddJitGlobal (module, eltype, "method_addresses");
7771 fields [tindex ++] = LLVMConstNull (eltype);
7772 if (info->flags & MONO_AOT_FILE_FLAG_SEPARATE_DATA) {
7773 for (i = 0; i < MONO_AOT_TABLE_NUM; ++i)
7774 fields [tindex ++] = LLVMConstNull (eltype);
7776 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "blob");
7777 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "class_name_table");
7778 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "class_info_offsets");
7779 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "method_info_offsets");
7780 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "ex_info_offsets");
7781 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "extra_method_info_offsets");
7782 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "extra_method_table");
7783 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "got_info_offsets");
7784 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "llvm_got_info_offsets");
7785 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "image_table");
7787 /* Not needed (mem_end) */
7788 fields [tindex ++] = LLVMConstNull (eltype);
7789 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "assembly_guid");
7790 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "runtime_version");
7791 if (info->trampoline_size [0]) {
7792 fields [tindex ++] = AddJitGlobal (module, eltype, "specific_trampolines");
7793 fields [tindex ++] = AddJitGlobal (module, eltype, "static_rgctx_trampolines");
7794 fields [tindex ++] = AddJitGlobal (module, eltype, "imt_thunks");
7795 fields [tindex ++] = AddJitGlobal (module, eltype, "gsharedvt_arg_trampolines");
7797 fields [tindex ++] = LLVMConstNull (eltype);
7798 fields [tindex ++] = LLVMConstNull (eltype);
7799 fields [tindex ++] = LLVMConstNull (eltype);
7800 fields [tindex ++] = LLVMConstNull (eltype);
7802 if (module->static_link && !module->llvm_only)
7803 fields [tindex ++] = AddJitGlobal (module, eltype, "globals");
7805 fields [tindex ++] = LLVMConstNull (eltype);
7806 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "assembly_name");
7807 if (!module->llvm_only) {
7808 fields [tindex ++] = AddJitGlobal (module, eltype, "plt");
7809 fields [tindex ++] = AddJitGlobal (module, eltype, "plt_end");
7810 fields [tindex ++] = AddJitGlobal (module, eltype, "unwind_info");
7811 fields [tindex ++] = AddJitGlobal (module, eltype, "unbox_trampolines");
7812 fields [tindex ++] = AddJitGlobal (module, eltype, "unbox_trampolines_end");
7813 fields [tindex ++] = AddJitGlobal (module, eltype, "unbox_trampoline_addresses");
7815 fields [tindex ++] = LLVMConstNull (eltype);
7816 fields [tindex ++] = LLVMConstNull (eltype);
7817 fields [tindex ++] = LLVMConstNull (eltype);
7818 fields [tindex ++] = LLVMConstNull (eltype);
7819 fields [tindex ++] = LLVMConstNull (eltype);
7820 fields [tindex ++] = LLVMConstNull (eltype);
7823 for (i = 0; i < MONO_AOT_FILE_INFO_NUM_SYMBOLS; ++i)
7824 fields [2 + i] = LLVMConstBitCast (fields [2 + i], eltype);
7827 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->plt_got_offset_base, FALSE);
7828 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->got_size, FALSE);
7829 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->plt_size, FALSE);
7830 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->nmethods, FALSE);
7831 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->flags, FALSE);
7832 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->opts, FALSE);
7833 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->simd_opts, FALSE);
7834 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->gc_name_index, FALSE);
7835 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->num_rgctx_fetch_trampolines, FALSE);
7836 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->double_align, FALSE);
7837 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->long_align, FALSE);
7838 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->generic_tramp_num, FALSE);
7839 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->tramp_page_size, FALSE);
7840 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->nshared_got_entries, FALSE);
7841 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->datafile_size, FALSE);
7843 fields [tindex ++] = llvm_array_from_uints (LLVMInt32Type (), info->table_offsets, MONO_AOT_TABLE_NUM);
7844 fields [tindex ++] = llvm_array_from_uints (LLVMInt32Type (), info->num_trampolines, MONO_AOT_TRAMP_NUM);
7845 fields [tindex ++] = llvm_array_from_uints (LLVMInt32Type (), info->trampoline_got_offset_base, MONO_AOT_TRAMP_NUM);
7846 fields [tindex ++] = llvm_array_from_uints (LLVMInt32Type (), info->trampoline_size, MONO_AOT_TRAMP_NUM);
7847 fields [tindex ++] = llvm_array_from_uints (LLVMInt32Type (), info->tramp_page_code_offsets, MONO_AOT_TRAMP_NUM);
7848 g_assert (tindex == nfields);
7850 LLVMSetInitializer (info_var, LLVMConstNamedStruct (file_info_type, fields, nfields));
7852 if (module->static_link) {
7856 s = g_strdup_printf ("mono_aot_module_%s_info", module->assembly->aname.name);
7857 /* Get rid of characters which cannot occur in symbols */
7859 for (p = s; *p; ++p) {
7860 if (!(isalnum (*p) || *p == '_'))
7863 var = LLVMAddGlobal (module->lmodule, LLVMPointerType (LLVMInt8Type (), 0), s);
7865 LLVMSetInitializer (var, LLVMConstBitCast (LLVMGetNamedGlobal (module->lmodule, "mono_aot_file_info"), LLVMPointerType (LLVMInt8Type (), 0)));
7866 LLVMSetLinkage (var, LLVMExternalLinkage);
7871 * Emit the aot module into the LLVM bitcode file FILENAME.
7874 mono_llvm_emit_aot_module (const char *filename, const char *cu_name)
7876 LLVMTypeRef got_type, inited_type;
7877 LLVMValueRef real_got, real_inited;
7878 MonoLLVMModule *module = &aot_module;
7880 emit_llvm_code_end (module);
7883 * Create the real got variable and replace all uses of the dummy variable with
7886 got_type = LLVMArrayType (module->ptr_type, module->max_got_offset + 1);
7887 real_got = LLVMAddGlobal (module->lmodule, got_type, module->got_symbol);
7888 LLVMSetInitializer (real_got, LLVMConstNull (got_type));
7889 if (module->external_symbols) {
7890 LLVMSetLinkage (real_got, LLVMExternalLinkage);
7891 LLVMSetVisibility (real_got, LLVMHiddenVisibility);
7893 LLVMSetLinkage (real_got, LLVMInternalLinkage);
7895 mono_llvm_replace_uses_of (module->got_var, real_got);
7897 mark_as_used (&aot_module, real_got);
7899 /* Delete the dummy got so it doesn't become a global */
7900 LLVMDeleteGlobal (module->got_var);
7901 module->got_var = real_got;
7904 * Same for the init_var
7906 if (module->llvm_only) {
7907 inited_type = LLVMArrayType (LLVMInt8Type (), module->max_inited_idx + 1);
7908 real_inited = LLVMAddGlobal (module->lmodule, inited_type, "mono_inited");
7909 LLVMSetInitializer (real_inited, LLVMConstNull (inited_type));
7910 LLVMSetLinkage (real_inited, LLVMInternalLinkage);
7911 mono_llvm_replace_uses_of (module->inited_var, real_inited);
7912 LLVMDeleteGlobal (module->inited_var);
7915 if (module->llvm_only) {
7916 emit_get_method (&aot_module);
7917 emit_get_unbox_tramp (&aot_module);
7920 emit_llvm_used (&aot_module);
7921 emit_dbg_info (&aot_module, filename, cu_name);
7922 emit_aot_file_info (&aot_module);
7925 * Replace GOT entries for directly callable methods with the methods themselves.
7926 * It would be easier to implement this by predefining all methods before compiling
7927 * their bodies, but that couldn't handle the case when a method fails to compile
7930 if (module->llvm_only) {
7931 GHashTableIter iter;
7933 GSList *callers, *l;
7935 g_hash_table_iter_init (&iter, module->method_to_callers);
7936 while (g_hash_table_iter_next (&iter, (void**)&method, (void**)&callers)) {
7937 LLVMValueRef lmethod;
7939 lmethod = (LLVMValueRef)g_hash_table_lookup (module->method_to_lmethod, method);
7941 for (l = callers; l; l = l->next) {
7942 LLVMValueRef caller = (LLVMValueRef)l->data;
7944 mono_llvm_replace_uses_of (caller, lmethod);
7950 /* Replace PLT entries for directly callable methods with the methods themselves */
7952 GHashTableIter iter;
7954 LLVMValueRef callee;
7956 g_hash_table_iter_init (&iter, module->plt_entries_ji);
7957 while (g_hash_table_iter_next (&iter, (void**)&ji, (void**)&callee)) {
7958 if (mono_aot_is_direct_callable (ji)) {
7959 LLVMValueRef lmethod;
7961 lmethod = (LLVMValueRef)g_hash_table_lookup (module->method_to_lmethod, ji->data.method);
7962 /* The types might not match because the caller might pass an rgctx */
7963 if (lmethod && LLVMTypeOf (callee) == LLVMTypeOf (lmethod)) {
7964 mono_llvm_replace_uses_of (callee, lmethod);
7965 mono_aot_mark_unused_llvm_plt_entry (ji);
7975 if (LLVMVerifyModule (module->module, LLVMReturnStatusAction, &verifier_err)) {
7976 g_assert_not_reached ();
7981 LLVMWriteBitcodeToFile (module->lmodule, filename);
7986 md_string (const char *s)
7988 return LLVMMDString (s, strlen (s));
7991 /* Debugging support */
7994 emit_dbg_info (MonoLLVMModule *module, const char *filename, const char *cu_name)
7996 LLVMModuleRef lmodule = module->lmodule;
7997 LLVMValueRef args [16], cu_args [16], cu, ver;
7999 char *build_info, *s, *dir;
8002 * This can only be enabled when LLVM code is emitted into a separate object
8003 * file, since the AOT compiler also emits dwarf info,
8004 * and the abbrev indexes will not be correct since llvm has added its own
8007 if (!module->emit_dwarf)
8011 * Emit dwarf info in the form of LLVM metadata. There is some
8012 * out-of-date documentation at:
8013 * http://llvm.org/docs/SourceLevelDebugging.html
8014 * but most of this was gathered from the llvm and
8019 cu_args [n_cuargs ++] = LLVMConstInt (LLVMInt32Type (), DW_TAG_compile_unit, FALSE);
8020 /* CU name/compilation dir */
8021 dir = g_path_get_dirname (filename);
8022 args [0] = LLVMMDString (cu_name, strlen (cu_name));
8023 args [1] = LLVMMDString (dir, strlen (dir));
8024 cu_args [n_cuargs ++] = LLVMMDNode (args, 2);
8027 cu_args [n_cuargs ++] = LLVMConstInt (LLVMInt32Type (), DW_LANG_C99, FALSE);
8029 build_info = mono_get_runtime_build_info ();
8030 s = g_strdup_printf ("Mono AOT Compiler %s (LLVM)", build_info);
8031 cu_args [n_cuargs ++] = LLVMMDString (s, strlen (s));
8032 g_free (build_info);
8034 cu_args [n_cuargs ++] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
8036 cu_args [n_cuargs ++] = LLVMMDString ("", strlen (""));
8037 /* Runtime version */
8038 cu_args [n_cuargs ++] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
8040 cu_args [n_cuargs ++] = LLVMMDNode (args, 0);
8041 cu_args [n_cuargs ++] = LLVMMDNode (args, 0);
8043 if (module->subprogram_mds) {
8047 mds = g_new0 (LLVMValueRef, module->subprogram_mds->len);
8048 for (i = 0; i < module->subprogram_mds->len; ++i)
8049 mds [i] = (LLVMValueRef)g_ptr_array_index (module->subprogram_mds, i);
8050 cu_args [n_cuargs ++] = LLVMMDNode (mds, module->subprogram_mds->len);
8052 cu_args [n_cuargs ++] = LLVMMDNode (args, 0);
8055 cu_args [n_cuargs ++] = LLVMMDNode (args, 0);
8056 /* Imported modules */
8057 cu_args [n_cuargs ++] = LLVMMDNode (args, 0);
8059 cu_args [n_cuargs ++] = LLVMMDString ("", strlen (""));
8060 /* DebugEmissionKind = FullDebug */
8061 cu_args [n_cuargs ++] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
8062 cu = LLVMMDNode (cu_args, n_cuargs);
8063 LLVMAddNamedMetadataOperand (lmodule, "llvm.dbg.cu", cu);
8065 args [0] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
8066 args [1] = LLVMMDString ("Dwarf Version", strlen ("Dwarf Version"));
8067 args [2] = LLVMConstInt (LLVMInt32Type (), 2, FALSE);
8068 ver = LLVMMDNode (args, 3);
8069 LLVMAddNamedMetadataOperand (lmodule, "llvm.module.flags", ver);
8071 args [0] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
8072 args [1] = LLVMMDString ("Debug Info Version", strlen ("Debug Info Version"));
8073 args [2] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
8074 ver = LLVMMDNode (args, 3);
8075 LLVMAddNamedMetadataOperand (lmodule, "llvm.module.flags", ver);
8079 emit_dbg_subprogram (EmitContext *ctx, MonoCompile *cfg, LLVMValueRef method, const char *name)
8081 MonoLLVMModule *module = ctx->module;
8082 MonoDebugMethodInfo *minfo = ctx->minfo;
8083 char *source_file, *dir, *filename;
8084 LLVMValueRef md, args [16], ctx_args [16], md_args [64], type_args [16], ctx_md, type_md;
8085 MonoSymSeqPoint *sym_seq_points;
8091 mono_debug_symfile_get_seq_points (minfo, &source_file, NULL, NULL, &sym_seq_points, &n_seq_points);
8093 source_file = g_strdup ("<unknown>");
8094 dir = g_path_get_dirname (source_file);
8095 filename = g_path_get_basename (source_file);
8097 ctx_args [0] = LLVMConstInt (LLVMInt32Type (), 0x29, FALSE);
8098 args [0] = md_string (filename);
8099 args [1] = md_string (dir);
8100 ctx_args [1] = LLVMMDNode (args, 2);
8101 ctx_md = LLVMMDNode (ctx_args, 2);
8103 type_args [0] = LLVMConstInt (LLVMInt32Type (), DW_TAG_subroutine_type, FALSE);
8104 type_args [1] = NULL;
8105 type_args [2] = NULL;
8106 type_args [3] = LLVMMDString ("", 0);
8107 type_args [4] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
8108 type_args [5] = LLVMConstInt (LLVMInt64Type (), 0, FALSE);
8109 type_args [6] = LLVMConstInt (LLVMInt64Type (), 0, FALSE);
8110 type_args [7] = LLVMConstInt (LLVMInt64Type (), 0, FALSE);
8111 type_args [8] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
8112 type_args [9] = NULL;
8113 type_args [10] = NULL;
8114 type_args [11] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
8115 type_args [12] = NULL;
8116 type_args [13] = NULL;
8117 type_args [14] = NULL;
8118 type_md = LLVMMDNode (type_args, 14);
8120 /* http://llvm.org/docs/SourceLevelDebugging.html#subprogram-descriptors */
8121 md_args [0] = LLVMConstInt (LLVMInt32Type (), DW_TAG_subprogram, FALSE);
8122 /* Source directory + file pair */
8123 args [0] = md_string (filename);
8124 args [1] = md_string (dir);
8125 md_args [1] = LLVMMDNode (args ,2);
8126 md_args [2] = ctx_md;
8127 md_args [3] = md_string (cfg->method->name);
8128 md_args [4] = md_string (name);
8129 md_args [5] = md_string (name);
8132 md_args [6] = LLVMConstInt (LLVMInt32Type (), sym_seq_points [0].line, FALSE);
8134 md_args [6] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
8136 md_args [7] = type_md;
8138 md_args [8] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
8140 md_args [9] = LLVMConstInt (LLVMInt1Type (), 1, FALSE);
8142 md_args [10] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
8143 /* Index into a virtual function */
8144 md_args [11] = NULL;
8145 md_args [12] = NULL;
8147 md_args [13] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
8149 md_args [14] = LLVMConstInt (LLVMInt1Type (), 1, FALSE);
8150 /* Pointer to LLVM function */
8151 md_args [15] = method;
8152 /* Function template parameter */
8153 md_args [16] = NULL;
8154 /* Function declaration descriptor */
8155 md_args [17] = NULL;
8156 /* List of function variables */
8157 md_args [18] = LLVMMDNode (args, 0);
8159 md_args [19] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
8160 md = LLVMMDNode (md_args, 20);
8162 if (!module->subprogram_mds)
8163 module->subprogram_mds = g_ptr_array_new ();
8164 g_ptr_array_add (module->subprogram_mds, md);
8168 g_free (source_file);
8169 g_free (sym_seq_points);
8175 emit_dbg_loc (EmitContext *ctx, LLVMBuilderRef builder, const unsigned char *cil_code)
8177 MonoCompile *cfg = ctx->cfg;
8179 if (ctx->minfo && cil_code && cil_code >= cfg->header->code && cil_code < cfg->header->code + cfg->header->code_size) {
8180 MonoDebugSourceLocation *loc;
8181 LLVMValueRef loc_md, md_args [16];
8184 loc = mono_debug_symfile_lookup_location (ctx->minfo, cil_code - cfg->header->code);
8188 md_args [nmd_args ++] = LLVMConstInt (LLVMInt32Type (), loc->row, FALSE);
8189 md_args [nmd_args ++] = LLVMConstInt (LLVMInt32Type (), loc->column, FALSE);
8190 md_args [nmd_args ++] = ctx->dbg_md;
8191 md_args [nmd_args ++] = NULL;
8192 loc_md = LLVMMDNode (md_args, nmd_args);
8193 LLVMSetCurrentDebugLocation (builder, loc_md);
8194 mono_debug_symfile_free_location (loc);
8200 default_mono_llvm_unhandled_exception (void)
8202 MonoJitTlsData *jit_tls = mono_get_jit_tls ();
8203 MonoObject *target = mono_gchandle_get_target (jit_tls->thrown_exc);
8205 mono_unhandled_exception (target);
8206 exit (mono_environment_exitcode_get ());
8211 - Emit LLVM IR from the mono IR using the LLVM C API.
8212 - The original arch specific code remains, so we can fall back to it if we run
8213 into something we can't handle.
8217 A partial list of issues:
8218 - Handling of opcodes which can throw exceptions.
8220 In the mono JIT, these are implemented using code like this:
8227 push throw_pos - method
8228 call <exception trampoline>
8230 The problematic part is push throw_pos - method, which cannot be represented
8231 in the LLVM IR, since it does not support label values.
8232 -> this can be implemented in AOT mode using inline asm + labels, but cannot
8233 be implemented in JIT mode ?
8234 -> a possible but slower implementation would use the normal exception
8235 throwing code but it would need to control the placement of the throw code
8236 (it needs to be exactly after the compare+branch).
8237 -> perhaps add a PC offset intrinsics ?
8239 - efficient implementation of .ovf opcodes.
8241 These are currently implemented as:
8242 <ins which sets the condition codes>
8245 Some overflow opcodes are now supported by LLVM SVN.
8247 - exception handling, unwinding.
8248 - SSA is disabled for methods with exception handlers
8249 - How to obtain unwind info for LLVM compiled methods ?
8250 -> this is now solved by converting the unwind info generated by LLVM
8252 - LLVM uses the c++ exception handling framework, while we use our home grown
8253 code, and couldn't use the c++ one:
8254 - its not supported under VC++, other exotic platforms.
8255 - it might be impossible to support filter clauses with it.
8259 The trampolines need a predictable call sequence, since they need to disasm
8260 the calling code to obtain register numbers / offsets.
8262 LLVM currently generates this code in non-JIT mode:
8263 mov -0x98(%rax),%eax
8265 Here, the vtable pointer is lost.
8266 -> solution: use one vtable trampoline per class.
8268 - passing/receiving the IMT pointer/RGCTX.
8269 -> solution: pass them as normal arguments ?
8273 LLVM does not allow the specification of argument registers etc. This means
8274 that all calls are made according to the platform ABI.
8276 - passing/receiving vtypes.
8278 Vtypes passed/received in registers are handled by the front end by using
8279 a signature with scalar arguments, and loading the parts of the vtype into those
8282 Vtypes passed on the stack are handled using the 'byval' attribute.
8286 Supported though alloca, we need to emit the load/store code.
8290 The mono JIT uses pointer sized iregs/double fregs, while LLVM uses precisely
8291 typed registers, so we have to keep track of the precise LLVM type of each vreg.
8292 This is made easier because the IR is already in SSA form.
8293 An additional problem is that our IR is not consistent with types, i.e. i32/ia64
8294 types are frequently used incorrectly.
8299 Emit LLVM bytecode into a .bc file, compile it using llc into a .s file, then link
8300 it with the file containing the methods emitted by the JIT and the AOT data
8304 /* FIXME: Normalize some aspects of the mono IR to allow easier translation, like:
8305 * - each bblock should end with a branch
8306 * - setting the return value, making cfg->ret non-volatile
8307 * - avoid some transformations in the JIT which make it harder for us to generate
8309 * - use pointer types to help optimizations.