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);
2743 LLVMAddFunctionAttr (tramp, LLVMOptimizeForSizeAttribute);
2744 //LLVMAddFunctionAttr (tramp, LLVMNoUnwindAttribute);
2746 // FIXME: Reduce code duplication with mono_llvm_compile_method () etc.
2747 if (!ctx->llvm_only && ctx->rgctx_arg_pindex != -1)
2748 LLVMAddAttribute (LLVMGetParam (tramp, ctx->rgctx_arg_pindex), LLVMInRegAttribute);
2749 if (ctx->cfg->vret_addr) {
2750 LLVMSetValueName (LLVMGetParam (tramp, linfo->vret_arg_pindex), "vret");
2751 if (linfo->ret.storage == LLVMArgVtypeByRef) {
2752 LLVMAddAttribute (LLVMGetParam (tramp, linfo->vret_arg_pindex), LLVMStructRetAttribute);
2753 LLVMAddAttribute (LLVMGetParam (tramp, linfo->vret_arg_pindex), LLVMNoAliasAttribute);
2757 lbb = LLVMAppendBasicBlock (tramp, "");
2758 builder = LLVMCreateBuilder ();
2759 LLVMPositionBuilderAtEnd (builder, lbb);
2761 nargs = LLVMCountParamTypes (method_type);
2762 args = g_new0 (LLVMValueRef, nargs);
2763 for (i = 0; i < nargs; ++i) {
2764 args [i] = LLVMGetParam (tramp, i);
2765 if (i == ctx->this_arg_pindex) {
2766 LLVMTypeRef arg_type = LLVMTypeOf (args [i]);
2768 args [i] = LLVMBuildPtrToInt (builder, args [i], IntPtrType (), "");
2769 args [i] = LLVMBuildAdd (builder, args [i], LLVMConstInt (IntPtrType (), sizeof (MonoObject), FALSE), "");
2770 args [i] = LLVMBuildIntToPtr (builder, args [i], arg_type, "");
2773 call = LLVMBuildCall (builder, method, args, nargs, "");
2774 if (!ctx->llvm_only && ctx->rgctx_arg_pindex != -1)
2775 LLVMAddInstrAttribute (call, 1 + ctx->rgctx_arg_pindex, LLVMInRegAttribute);
2776 if (linfo->ret.storage == LLVMArgVtypeByRef)
2777 LLVMAddInstrAttribute (call, 1 + linfo->vret_arg_pindex, LLVMStructRetAttribute);
2779 // FIXME: This causes assertions in clang
2780 //mono_llvm_set_must_tail (call);
2781 if (LLVMGetReturnType (method_type) == LLVMVoidType ())
2782 LLVMBuildRetVoid (builder);
2784 LLVMBuildRet (builder, call);
2786 g_hash_table_insert (ctx->module->idx_to_unbox_tramp, GINT_TO_POINTER (method_index), tramp);
2792 * Emit code to load/convert arguments.
2795 emit_entry_bb (EmitContext *ctx, LLVMBuilderRef builder)
2798 MonoCompile *cfg = ctx->cfg;
2799 MonoMethodSignature *sig = ctx->sig;
2800 LLVMCallInfo *linfo = ctx->linfo;
2804 LLVMBuilderRef old_builder = ctx->builder;
2805 ctx->builder = builder;
2807 ctx->alloca_builder = create_builder (ctx);
2810 * Handle indirect/volatile variables by allocating memory for them
2811 * using 'alloca', and storing their address in a temporary.
2813 for (i = 0; i < cfg->num_varinfo; ++i) {
2814 MonoInst *var = cfg->varinfo [i];
2817 if (var->opcode == OP_GSHAREDVT_LOCAL || var->opcode == OP_GSHAREDVT_ARG_REGOFFSET) {
2818 } 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))) {
2819 vtype = type_to_llvm_type (ctx, var->inst_vtype);
2820 CHECK_FAILURE (ctx);
2821 /* Could be already created by an OP_VPHI */
2822 if (!ctx->addresses [var->dreg]) {
2823 ctx->addresses [var->dreg] = build_alloca (ctx, var->inst_vtype);
2824 //LLVMSetValueName (ctx->addresses [var->dreg], g_strdup_printf ("vreg_loc_%d", var->dreg));
2826 ctx->vreg_cli_types [var->dreg] = var->inst_vtype;
2830 names = g_new (char *, sig->param_count);
2831 mono_method_get_param_names (cfg->method, (const char **) names);
2833 for (i = 0; i < sig->param_count; ++i) {
2834 LLVMArgInfo *ainfo = &linfo->args [i + sig->hasthis];
2835 int reg = cfg->args [i + sig->hasthis]->dreg;
2838 pindex = ainfo->pindex;
2840 switch (ainfo->storage) {
2841 case LLVMArgVtypeInReg:
2842 case LLVMArgAsFpArgs: {
2843 LLVMValueRef args [8];
2846 pindex += ainfo->ndummy_fpargs;
2848 /* The argument is received as a set of int/fp arguments, store them into the real argument */
2849 memset (args, 0, sizeof (args));
2850 if (ainfo->storage == LLVMArgVtypeInReg) {
2851 args [0] = LLVMGetParam (ctx->lmethod, pindex);
2852 if (ainfo->pair_storage [1] != LLVMArgNone)
2853 args [1] = LLVMGetParam (ctx->lmethod, pindex + 1);
2855 g_assert (ainfo->nslots <= 8);
2856 for (j = 0; j < ainfo->nslots; ++j)
2857 args [j] = LLVMGetParam (ctx->lmethod, pindex + j);
2859 ctx->addresses [reg] = build_alloca (ctx, ainfo->type);
2861 emit_args_to_vtype (ctx, builder, ainfo->type, ctx->addresses [reg], ainfo, args);
2863 if (ainfo->storage == LLVMArgVtypeInReg && MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (ainfo->type))) {
2864 /* Treat these as normal values */
2865 ctx->values [reg] = LLVMBuildLoad (builder, ctx->addresses [reg], "");
2869 case LLVMArgVtypeByVal: {
2870 ctx->addresses [reg] = LLVMGetParam (ctx->lmethod, pindex);
2872 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (ainfo->type))) {
2873 /* Treat these as normal values */
2874 ctx->values [reg] = LLVMBuildLoad (builder, ctx->addresses [reg], "");
2878 case LLVMArgVtypeByRef: {
2879 /* The argument is passed by ref */
2880 ctx->addresses [reg] = LLVMGetParam (ctx->lmethod, pindex);
2883 case LLVMArgScalarByRef: {
2885 name = g_strdup_printf ("arg_%s", names [i]);
2887 name = g_strdup_printf ("arg_%d", i);
2888 ctx->values [reg] = LLVMBuildLoad (builder, LLVMGetParam (ctx->lmethod, pindex), name);
2892 case LLVMArgAsIArgs: {
2893 LLVMValueRef arg = LLVMGetParam (ctx->lmethod, pindex);
2895 ctx->addresses [reg] = build_alloca (ctx, ainfo->type);
2897 /* The argument is received as an array of ints, store it into the real argument */
2898 LLVMBuildStore (ctx->builder, arg, convert (ctx, ctx->addresses [reg], LLVMPointerType (LLVMTypeOf (arg), 0)));
2901 case LLVMArgVtypeAsScalar:
2902 g_assert_not_reached ();
2904 case LLVMArgGsharedvtFixed: {
2905 /* These are non-gsharedvt arguments passed by ref, the rest of the IR treats them as scalars */
2906 LLVMValueRef arg = LLVMGetParam (ctx->lmethod, pindex);
2909 name = g_strdup_printf ("arg_%s", names [i]);
2911 name = g_strdup_printf ("arg_%d", i);
2913 ctx->values [reg] = LLVMBuildLoad (builder, convert (ctx, arg, LLVMPointerType (type_to_llvm_type (ctx, ainfo->type), 0)), name);
2916 case LLVMArgGsharedvtFixedVtype: {
2917 LLVMValueRef arg = LLVMGetParam (ctx->lmethod, pindex);
2920 name = g_strdup_printf ("vtype_arg_%s", names [i]);
2922 name = g_strdup_printf ("vtype_arg_%d", i);
2924 /* Non-gsharedvt vtype argument passed by ref, the rest of the IR treats it as a vtype */
2925 g_assert (ctx->addresses [reg]);
2926 LLVMSetValueName (ctx->addresses [reg], name);
2927 LLVMBuildStore (builder, LLVMBuildLoad (builder, convert (ctx, arg, LLVMPointerType (type_to_llvm_type (ctx, ainfo->type), 0)), ""), ctx->addresses [reg]);
2930 case LLVMArgGsharedvtVariable:
2931 /* The IR treats these as variables with addresses */
2932 ctx->addresses [reg] = LLVMGetParam (ctx->lmethod, pindex);
2935 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));
2942 emit_volatile_store (ctx, cfg->vret_addr->dreg);
2944 emit_volatile_store (ctx, cfg->args [0]->dreg);
2945 for (i = 0; i < sig->param_count; ++i)
2946 if (!mini_type_is_vtype (sig->params [i]))
2947 emit_volatile_store (ctx, cfg->args [i + sig->hasthis]->dreg);
2949 if (sig->hasthis && !cfg->rgctx_var && cfg->gshared) {
2950 LLVMValueRef this_alloc;
2953 * The exception handling code needs the location where the this argument was
2954 * stored for gshared methods. We create a separate alloca to hold it, and mark it
2955 * with the "mono.this" custom metadata to tell llvm that it needs to save its
2956 * location into the LSDA.
2958 this_alloc = mono_llvm_build_alloca (builder, ThisType (), LLVMConstInt (LLVMInt32Type (), 1, FALSE), 0, "");
2959 /* This volatile store will keep the alloca alive */
2960 mono_llvm_build_store (builder, ctx->values [cfg->args [0]->dreg], this_alloc, TRUE, LLVM_BARRIER_NONE);
2962 set_metadata_flag (this_alloc, "mono.this");
2965 if (cfg->rgctx_var) {
2966 LLVMValueRef rgctx_alloc, store;
2969 * We handle the rgctx arg similarly to the this pointer.
2971 g_assert (ctx->addresses [cfg->rgctx_var->dreg]);
2972 rgctx_alloc = ctx->addresses [cfg->rgctx_var->dreg];
2973 /* This volatile store will keep the alloca alive */
2974 store = mono_llvm_build_store (builder, convert (ctx, ctx->rgctx_arg, IntPtrType ()), rgctx_alloc, TRUE, LLVM_BARRIER_NONE);
2976 set_metadata_flag (rgctx_alloc, "mono.this");
2979 /* Initialize the method if needed */
2980 if (cfg->compile_aot && ctx->llvm_only) {
2981 /* Emit a location for the initialization code */
2982 ctx->init_bb = gen_bb (ctx, "INIT_BB");
2983 ctx->inited_bb = gen_bb (ctx, "INITED_BB");
2985 LLVMBuildBr (ctx->builder, ctx->init_bb);
2986 builder = ctx->builder = create_builder (ctx);
2987 LLVMPositionBuilderAtEnd (ctx->builder, ctx->inited_bb);
2988 ctx->bblocks [cfg->bb_entry->block_num].end_bblock = ctx->inited_bb;
2991 /* Compute nesting between clauses */
2992 ctx->nested_in = (GSList**)mono_mempool_alloc0 (cfg->mempool, sizeof (GSList*) * cfg->header->num_clauses);
2993 for (i = 0; i < cfg->header->num_clauses; ++i) {
2994 for (j = 0; j < cfg->header->num_clauses; ++j) {
2995 MonoExceptionClause *clause1 = &cfg->header->clauses [i];
2996 MonoExceptionClause *clause2 = &cfg->header->clauses [j];
2998 if (i != j && clause1->try_offset >= clause2->try_offset && clause1->handler_offset <= clause2->handler_offset)
2999 ctx->nested_in [i] = g_slist_prepend_mempool (cfg->mempool, ctx->nested_in [i], GINT_TO_POINTER (j));
3004 * For finally clauses, create an indicator variable telling OP_ENDFINALLY whenever
3005 * it needs to continue normally, or return back to the exception handling system.
3007 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
3011 if (!(bb->region != -1 && (bb->flags & BB_EXCEPTION_HANDLER)))
3014 clause_index = MONO_REGION_CLAUSE_INDEX (bb->region);
3015 g_hash_table_insert (ctx->region_to_handler, GUINT_TO_POINTER (mono_get_block_region_notry (cfg, bb->region)), bb);
3016 g_hash_table_insert (ctx->clause_to_handler, GINT_TO_POINTER (clause_index), bb);
3018 if (bb->in_scount == 0) {
3021 sprintf (name, "finally_ind_bb%d", bb->block_num);
3022 val = LLVMBuildAlloca (builder, LLVMInt32Type (), name);
3023 LLVMBuildStore (builder, LLVMConstInt (LLVMInt32Type (), 0, FALSE), val);
3025 ctx->bblocks [bb->block_num].finally_ind = val;
3027 /* Create a variable to hold the exception var */
3029 ctx->ex_var = LLVMBuildAlloca (builder, ObjRefType (), "exvar");
3033 * Create a new bblock which CALL_HANDLER/landing pads can branch to, because branching to the
3034 * LLVM bblock containing a landing pad causes problems for the
3035 * LLVM optimizer passes.
3037 sprintf (name, "BB%d_CALL_HANDLER_TARGET", bb->block_num);
3038 ctx->bblocks [bb->block_num].call_handler_target_bb = LLVMAppendBasicBlock (ctx->lmethod, name);
3045 ctx->builder = old_builder;
3049 process_call (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, MonoInst *ins)
3051 MonoCompile *cfg = ctx->cfg;
3052 LLVMModuleRef lmodule = ctx->lmodule;
3053 LLVMValueRef *values = ctx->values;
3054 LLVMValueRef *addresses = ctx->addresses;
3055 MonoCallInst *call = (MonoCallInst*)ins;
3056 MonoMethodSignature *sig = call->signature;
3057 LLVMValueRef callee = NULL, lcall;
3059 LLVMCallInfo *cinfo;
3063 LLVMTypeRef llvm_sig;
3065 gboolean is_virtual, calli, preserveall;
3066 LLVMBuilderRef builder = *builder_ref;
3068 if (call->signature->call_convention != MONO_CALL_DEFAULT)
3069 LLVM_FAILURE (ctx, "non-default callconv");
3071 cinfo = call->cinfo;
3073 if (call->rgctx_arg_reg)
3074 cinfo->rgctx_arg = TRUE;
3075 if (call->imt_arg_reg)
3076 cinfo->imt_arg = TRUE;
3078 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);
3080 llvm_sig = sig_to_llvm_sig_full (ctx, sig, cinfo);
3081 CHECK_FAILURE (ctx);
3083 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);
3084 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);
3086 preserveall = FALSE;
3088 /* FIXME: Avoid creating duplicate methods */
3090 if (ins->flags & MONO_INST_HAS_METHOD) {
3094 if (cfg->compile_aot) {
3095 callee = get_callee (ctx, llvm_sig, MONO_PATCH_INFO_METHOD, call->method);
3097 LLVM_FAILURE (ctx, "can't encode patch");
3099 if (cfg->llvm_only && call->method->klass->image->assembly == ctx->module->assembly) {
3101 * Collect instructions representing the callee into a hash so they can be replaced
3102 * by the llvm method for the callee if the callee turns out to be direct
3103 * callable. Currently this only requires it to not fail llvm compilation.
3105 GSList *l = (GSList*)g_hash_table_lookup (ctx->method_to_callers, call->method);
3106 l = g_slist_prepend (l, callee);
3107 g_hash_table_insert (ctx->method_to_callers, call->method, l);
3110 callee = LLVMAddFunction (lmodule, "", llvm_sig);
3113 mono_create_jit_trampoline_in_domain (mono_domain_get (),
3115 LLVMAddGlobalMapping (ctx->module->ee, callee, target);
3119 if (!cfg->llvm_only && call->method && strstr (call->method->klass->name, "AsyncVoidMethodBuilder"))
3120 /* LLVM miscompiles async methods */
3121 LLVM_FAILURE (ctx, "#13734");
3124 MonoJitICallInfo *info = mono_find_jit_icall_by_addr (call->fptr);
3130 memset (&ji, 0, sizeof (ji));
3131 ji.type = MONO_PATCH_INFO_JIT_ICALL_ADDR;
3132 ji.data.target = info->name;
3134 target = mono_resolve_patch_target (cfg->method, cfg->domain, NULL, &ji, FALSE);
3136 if (cfg->compile_aot) {
3137 callee = get_callee (ctx, llvm_sig, MONO_PATCH_INFO_INTERNAL_METHOD, (char*)info->name);
3139 LLVM_FAILURE (ctx, "can't encode patch");
3141 callee = LLVMAddFunction (lmodule, "", llvm_sig);
3142 target = (gpointer)mono_icall_get_wrapper (info);
3143 LLVMAddGlobalMapping (ctx->module->ee, callee, target);
3146 if (cfg->compile_aot) {
3148 if (cfg->abs_patches) {
3149 MonoJumpInfo *abs_ji = (MonoJumpInfo*)g_hash_table_lookup (cfg->abs_patches, call->fptr);
3151 callee = get_callee (ctx, llvm_sig, abs_ji->type, abs_ji->data.target);
3153 LLVM_FAILURE (ctx, "can't encode patch");
3157 LLVM_FAILURE (ctx, "aot");
3159 callee = LLVMAddFunction (lmodule, "", llvm_sig);
3161 if (cfg->abs_patches) {
3162 MonoJumpInfo *abs_ji = (MonoJumpInfo*)g_hash_table_lookup (cfg->abs_patches, call->fptr);
3165 * FIXME: Some trampolines might have
3166 * their own calling convention on some platforms.
3168 #ifndef TARGET_AMD64
3169 if (abs_ji->type == MONO_PATCH_INFO_MONITOR_ENTER || abs_ji->type == MONO_PATCH_INFO_MONITOR_ENTER_V4 ||
3170 abs_ji->type == MONO_PATCH_INFO_MONITOR_EXIT)
3171 LLVM_FAILURE (ctx, "trampoline with own cconv");
3173 target = mono_resolve_patch_target (cfg->method, cfg->domain, NULL, abs_ji, FALSE);
3174 LLVMAddGlobalMapping (ctx->module->ee, callee, target);
3178 LLVMAddGlobalMapping (ctx->module->ee, callee, (gpointer)call->fptr);
3184 int size = sizeof (gpointer);
3187 g_assert (ins->inst_offset % size == 0);
3188 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
3190 callee = convert (ctx, LLVMBuildLoad (builder, LLVMBuildGEP (builder, convert (ctx, values [ins->inst_basereg], LLVMPointerType (LLVMPointerType (IntPtrType (), 0), 0)), &index, 1, ""), ""), LLVMPointerType (llvm_sig, 0));
3192 callee = convert (ctx, values [ins->sreg1], LLVMPointerType (llvm_sig, 0));
3194 if (ins->flags & MONO_INST_HAS_METHOD) {
3199 * Collect and convert arguments
3201 nargs = (sig->param_count * 16) + sig->hasthis + vretaddr + call->rgctx_reg + call->imt_arg_reg;
3202 len = sizeof (LLVMValueRef) * nargs;
3203 args = (LLVMValueRef*)alloca (len);
3204 memset (args, 0, len);
3205 l = call->out_ireg_args;
3207 if (call->rgctx_arg_reg) {
3208 g_assert (values [call->rgctx_arg_reg]);
3209 g_assert (cinfo->rgctx_arg_pindex < nargs);
3211 * On ARM, the imt/rgctx argument is passed in a caller save register, but some of our trampolines etc. clobber it, leading to
3212 * problems is LLVM moves the arg assignment earlier. To work around this, save the argument into a stack slot and load
3213 * it using a volatile load.
3216 if (!ctx->imt_rgctx_loc)
3217 ctx->imt_rgctx_loc = build_alloca_llvm_type (ctx, ctx->module->ptr_type, sizeof (gpointer));
3218 LLVMBuildStore (builder, convert (ctx, ctx->values [call->rgctx_arg_reg], ctx->module->ptr_type), ctx->imt_rgctx_loc);
3219 args [cinfo->rgctx_arg_pindex] = mono_llvm_build_load (builder, ctx->imt_rgctx_loc, "", TRUE, LLVM_BARRIER_NONE);
3221 args [cinfo->rgctx_arg_pindex] = convert (ctx, values [call->rgctx_arg_reg], ctx->module->ptr_type);
3224 if (call->imt_arg_reg) {
3225 g_assert (!ctx->llvm_only);
3226 g_assert (values [call->imt_arg_reg]);
3227 g_assert (cinfo->imt_arg_pindex < nargs);
3229 if (!ctx->imt_rgctx_loc)
3230 ctx->imt_rgctx_loc = build_alloca_llvm_type (ctx, ctx->module->ptr_type, sizeof (gpointer));
3231 LLVMBuildStore (builder, convert (ctx, ctx->values [call->imt_arg_reg], ctx->module->ptr_type), ctx->imt_rgctx_loc);
3232 args [cinfo->imt_arg_pindex] = mono_llvm_build_load (builder, ctx->imt_rgctx_loc, "", TRUE, LLVM_BARRIER_NONE);
3234 args [cinfo->imt_arg_pindex] = convert (ctx, values [call->imt_arg_reg], ctx->module->ptr_type);
3237 switch (cinfo->ret.storage) {
3238 case LLVMArgGsharedvtVariable: {
3239 MonoInst *var = get_vreg_to_inst (cfg, call->inst.dreg);
3241 if (var && var->opcode == OP_GSHAREDVT_LOCAL) {
3242 args [cinfo->vret_arg_pindex] = convert (ctx, emit_gsharedvt_ldaddr (ctx, var->dreg), IntPtrType ());
3244 g_assert (addresses [call->inst.dreg]);
3245 args [cinfo->vret_arg_pindex] = addresses [call->inst.dreg];
3251 if (!addresses [call->inst.dreg])
3252 addresses [call->inst.dreg] = build_alloca (ctx, sig->ret);
3253 g_assert (cinfo->vret_arg_pindex < nargs);
3254 if (cinfo->ret.storage == LLVMArgVtypeByRef)
3255 args [cinfo->vret_arg_pindex] = addresses [call->inst.dreg];
3257 args [cinfo->vret_arg_pindex] = LLVMBuildPtrToInt (builder, addresses [call->inst.dreg], IntPtrType (), "");
3263 * Sometimes the same method is called with two different signatures (i.e. with and without 'this'), so
3264 * use the real callee for argument type conversion.
3266 LLVMTypeRef callee_type = LLVMGetElementType (LLVMTypeOf (callee));
3267 LLVMTypeRef *param_types = (LLVMTypeRef*)g_alloca (sizeof (LLVMTypeRef) * LLVMCountParamTypes (callee_type));
3268 LLVMGetParamTypes (callee_type, param_types);
3270 for (i = 0; i < sig->param_count + sig->hasthis; ++i) {
3273 LLVMArgInfo *ainfo = &call->cinfo->args [i];
3275 pindex = ainfo->pindex;
3277 regpair = (guint32)(gssize)(l->data);
3278 reg = regpair & 0xffffff;
3279 args [pindex] = values [reg];
3280 switch (ainfo->storage) {
3281 case LLVMArgVtypeInReg:
3282 case LLVMArgAsFpArgs: {
3286 for (j = 0; j < ainfo->ndummy_fpargs; ++j)
3287 args [pindex + j] = LLVMConstNull (LLVMDoubleType ());
3288 pindex += ainfo->ndummy_fpargs;
3290 g_assert (addresses [reg]);
3291 emit_vtype_to_args (ctx, builder, ainfo->type, addresses [reg], ainfo, args + pindex, &nargs);
3295 // FIXME: Get rid of the VMOVE
3298 case LLVMArgVtypeByVal:
3299 g_assert (addresses [reg]);
3300 args [pindex] = addresses [reg];
3302 case LLVMArgVtypeByRef:
3303 case LLVMArgScalarByRef: {
3304 g_assert (addresses [reg]);
3305 args [pindex] = convert (ctx, addresses [reg], LLVMPointerType (type_to_llvm_arg_type (ctx, ainfo->type), 0));
3308 case LLVMArgAsIArgs:
3309 g_assert (addresses [reg]);
3310 args [pindex] = LLVMBuildLoad (ctx->builder, convert (ctx, addresses [reg], LLVMPointerType (LLVMArrayType (IntPtrType (), ainfo->nslots), 0)), "");
3312 case LLVMArgVtypeAsScalar:
3313 g_assert_not_reached ();
3315 case LLVMArgGsharedvtFixed:
3316 case LLVMArgGsharedvtFixedVtype:
3317 g_assert (addresses [reg]);
3318 args [pindex] = convert (ctx, addresses [reg], LLVMPointerType (type_to_llvm_arg_type (ctx, ainfo->type), 0));
3320 case LLVMArgGsharedvtVariable:
3321 g_assert (addresses [reg]);
3322 args [pindex] = convert (ctx, addresses [reg], LLVMPointerType (IntPtrType (), 0));
3325 g_assert (args [pindex]);
3326 if (i == 0 && sig->hasthis)
3327 args [pindex] = convert (ctx, args [pindex], param_types [pindex]);
3329 args [pindex] = convert (ctx, args [pindex], type_to_llvm_arg_type (ctx, ainfo->type));
3332 g_assert (pindex <= nargs);
3337 // FIXME: Align call sites
3343 lcall = emit_call (ctx, bb, &builder, callee, args, LLVMCountParamTypes (llvm_sig));
3346 * Modify cconv and parameter attributes to pass rgctx/imt correctly.
3348 #if defined(MONO_ARCH_IMT_REG) && defined(MONO_ARCH_RGCTX_REG)
3349 g_assert (MONO_ARCH_IMT_REG == MONO_ARCH_RGCTX_REG);
3351 /* The two can't be used together, so use only one LLVM calling conv to pass them */
3352 g_assert (!(call->rgctx_arg_reg && call->imt_arg_reg));
3353 if (!sig->pinvoke && !cfg->llvm_only)
3354 LLVMSetInstructionCallConv (lcall, LLVMMono1CallConv);
3356 mono_llvm_set_call_preserveall_cc (lcall);
3358 if (cinfo->ret.storage == LLVMArgVtypeByRef)
3359 LLVMAddInstrAttribute (lcall, 1 + cinfo->vret_arg_pindex, LLVMStructRetAttribute);
3360 if (!ctx->llvm_only && call->rgctx_arg_reg)
3361 LLVMAddInstrAttribute (lcall, 1 + cinfo->rgctx_arg_pindex, LLVMInRegAttribute);
3362 if (call->imt_arg_reg)
3363 LLVMAddInstrAttribute (lcall, 1 + cinfo->imt_arg_pindex, LLVMInRegAttribute);
3365 /* Add byval attributes if needed */
3366 for (i = 0; i < sig->param_count; ++i) {
3367 LLVMArgInfo *ainfo = &call->cinfo->args [i + sig->hasthis];
3369 if (ainfo && ainfo->storage == LLVMArgVtypeByVal)
3370 LLVMAddInstrAttribute (lcall, 1 + ainfo->pindex, LLVMByValAttribute);
3374 * Convert the result
3376 switch (cinfo->ret.storage) {
3377 case LLVMArgVtypeInReg: {
3378 LLVMValueRef regs [2];
3380 if (LLVMTypeOf (lcall) == LLVMVoidType ())
3384 if (!addresses [ins->dreg])
3385 addresses [ins->dreg] = build_alloca (ctx, sig->ret);
3387 regs [0] = LLVMBuildExtractValue (builder, lcall, 0, "");
3388 if (cinfo->ret.pair_storage [1] != LLVMArgNone)
3389 regs [1] = LLVMBuildExtractValue (builder, lcall, 1, "");
3390 emit_args_to_vtype (ctx, builder, sig->ret, addresses [ins->dreg], &cinfo->ret, regs);
3393 case LLVMArgVtypeByVal:
3394 if (!addresses [call->inst.dreg])
3395 addresses [call->inst.dreg] = build_alloca (ctx, sig->ret);
3396 LLVMBuildStore (builder, lcall, addresses [call->inst.dreg]);
3398 case LLVMArgFpStruct:
3399 if (!addresses [call->inst.dreg])
3400 addresses [call->inst.dreg] = build_alloca (ctx, sig->ret);
3401 LLVMBuildStore (builder, lcall, convert_full (ctx, addresses [call->inst.dreg], LLVMPointerType (LLVMTypeOf (lcall), 0), FALSE));
3403 case LLVMArgVtypeAsScalar:
3404 if (!addresses [call->inst.dreg])
3405 addresses [call->inst.dreg] = build_alloca (ctx, sig->ret);
3406 LLVMBuildStore (builder, lcall, convert_full (ctx, addresses [call->inst.dreg], LLVMPointerType (LLVMTypeOf (lcall), 0), FALSE));
3408 case LLVMArgVtypeRetAddr:
3409 case LLVMArgVtypeByRef:
3411 case LLVMArgScalarRetAddr:
3412 /* Normal scalar returned using a vtype return argument */
3413 values [ins->dreg] = LLVMBuildLoad (builder, convert_full (ctx, addresses [call->inst.dreg], LLVMPointerType (type_to_llvm_type (ctx, sig->ret), 0), FALSE), "");
3415 case LLVMArgGsharedvtVariable:
3417 case LLVMArgGsharedvtFixed:
3418 case LLVMArgGsharedvtFixedVtype:
3419 values [ins->dreg] = LLVMBuildLoad (builder, convert_full (ctx, addresses [call->inst.dreg], LLVMPointerType (type_to_llvm_type (ctx, sig->ret), 0), FALSE), "");
3422 if (sig->ret->type != MONO_TYPE_VOID)
3423 /* If the method returns an unsigned value, need to zext it */
3424 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));
3428 *builder_ref = ctx->builder;
3436 emit_llvmonly_throw (EmitContext *ctx, MonoBasicBlock *bb, gboolean rethrow, LLVMValueRef exc)
3438 const char *icall_name = rethrow ? "mono_llvm_rethrow_exception" : "mono_llvm_throw_exception";
3439 LLVMValueRef callee = rethrow ? ctx->module->rethrow : ctx->module->throw_icall;
3441 LLVMTypeRef exc_type = type_to_llvm_type (ctx, &mono_get_exception_class ()->byval_arg);
3444 LLVMTypeRef fun_sig = LLVMFunctionType1 (LLVMVoidType (), exc_type, FALSE);
3446 if (ctx->cfg->compile_aot) {
3447 callee = get_callee (ctx, fun_sig, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
3449 callee = LLVMAddFunction (ctx->lmodule, icall_name, fun_sig);
3450 LLVMAddGlobalMapping (ctx->module->ee, callee, resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name));
3451 mono_memory_barrier ();
3454 ctx->module->rethrow = callee;
3456 ctx->module->throw_icall = callee;
3460 LLVMValueRef args [2];
3462 args [0] = convert (ctx, exc, exc_type);
3463 emit_call (ctx, bb, &ctx->builder, callee, args, 1);
3465 LLVMBuildUnreachable (ctx->builder);
3467 ctx->builder = create_builder (ctx);
3471 emit_throw (EmitContext *ctx, MonoBasicBlock *bb, gboolean rethrow, LLVMValueRef exc)
3473 MonoMethodSignature *throw_sig;
3474 LLVMValueRef callee, arg;
3475 const char *icall_name;
3477 callee = rethrow ? ctx->module->rethrow : ctx->module->throw_icall;
3478 icall_name = rethrow ? "mono_arch_rethrow_exception" : "mono_arch_throw_exception";
3481 throw_sig = mono_metadata_signature_alloc (mono_get_corlib (), 1);
3482 throw_sig->ret = &mono_get_void_class ()->byval_arg;
3483 throw_sig->params [0] = &mono_get_object_class ()->byval_arg;
3484 if (ctx->cfg->compile_aot) {
3485 callee = get_callee (ctx, sig_to_llvm_sig (ctx, throw_sig), MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
3487 callee = LLVMAddFunction (ctx->lmodule, icall_name, sig_to_llvm_sig (ctx, throw_sig));
3491 * LLVM doesn't push the exception argument, so we need a different
3494 LLVMAddGlobalMapping (ctx->module->ee, callee, resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, rethrow ? "llvm_rethrow_exception_trampoline" : "llvm_throw_exception_trampoline"));
3496 LLVMAddGlobalMapping (ctx->module->ee, callee, resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name));
3500 mono_memory_barrier ();
3502 ctx->module->rethrow = callee;
3504 ctx->module->throw_icall = callee;
3506 arg = convert (ctx, exc, type_to_llvm_type (ctx, &mono_get_object_class ()->byval_arg));
3507 emit_call (ctx, bb, &ctx->builder, callee, &arg, 1);
3511 emit_resume_eh (EmitContext *ctx, MonoBasicBlock *bb)
3513 const char *icall_name = "mono_llvm_resume_exception";
3514 LLVMValueRef callee = ctx->module->resume_eh;
3516 LLVMTypeRef fun_sig = LLVMFunctionType0 (LLVMVoidType (), FALSE);
3519 if (ctx->cfg->compile_aot) {
3520 callee = get_callee (ctx, fun_sig, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
3522 callee = LLVMAddFunction (ctx->lmodule, icall_name, fun_sig);
3523 LLVMAddGlobalMapping (ctx->module->ee, callee, resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name));
3524 mono_memory_barrier ();
3526 ctx->module->resume_eh = callee;
3530 emit_call (ctx, bb, &ctx->builder, callee, NULL, 0);
3532 LLVMBuildUnreachable (ctx->builder);
3534 ctx->builder = create_builder (ctx);
3538 mono_llvm_emit_clear_exception_call (EmitContext *ctx, LLVMBuilderRef builder)
3540 const char *icall_name = "mono_llvm_clear_exception";
3542 LLVMTypeRef call_sig = LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE);
3543 LLVMValueRef callee = NULL;
3546 if (ctx->cfg->compile_aot) {
3547 callee = get_callee (ctx, call_sig, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
3549 // FIXME: This is broken.
3550 callee = LLVMAddFunction (ctx->lmodule, icall_name, call_sig);
3554 g_assert (builder && callee);
3556 return LLVMBuildCall (builder, callee, NULL, 0, "");
3560 mono_llvm_emit_load_exception_call (EmitContext *ctx, LLVMBuilderRef builder)
3562 const char *icall_name = "mono_llvm_load_exception";
3564 LLVMTypeRef call_sig = LLVMFunctionType (ObjRefType (), NULL, 0, FALSE);
3565 LLVMValueRef callee = NULL;
3568 if (ctx->cfg->compile_aot) {
3569 callee = get_callee (ctx, call_sig, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
3571 // FIXME: This is broken.
3572 callee = LLVMAddFunction (ctx->lmodule, icall_name, call_sig);
3576 g_assert (builder && callee);
3578 return LLVMBuildCall (builder, callee, NULL, 0, icall_name);
3583 mono_llvm_emit_match_exception_call (EmitContext *ctx, LLVMBuilderRef builder, gint32 region_start, gint32 region_end)
3585 const char *icall_name = "mono_llvm_match_exception";
3587 ctx->builder = builder;
3589 const int num_args = 5;
3590 LLVMValueRef args [num_args];
3591 args [0] = convert (ctx, get_aotconst (ctx, MONO_PATCH_INFO_AOT_JIT_INFO, GINT_TO_POINTER (ctx->cfg->method_index)), IntPtrType ());
3592 args [1] = LLVMConstInt (LLVMInt32Type (), region_start, 0);
3593 args [2] = LLVMConstInt (LLVMInt32Type (), region_end, 0);
3594 if (ctx->cfg->rgctx_var) {
3595 LLVMValueRef rgctx_alloc = ctx->addresses [ctx->cfg->rgctx_var->dreg];
3596 g_assert (rgctx_alloc);
3597 args [3] = LLVMBuildLoad (builder, convert (ctx, rgctx_alloc, LLVMPointerType (IntPtrType (), 0)), "");
3599 args [3] = LLVMConstInt (IntPtrType (), 0, 0);
3602 args [4] = convert (ctx, ctx->this_arg, IntPtrType ());
3604 args [4] = LLVMConstInt (IntPtrType (), 0, 0);
3606 LLVMTypeRef match_sig = LLVMFunctionType5 (LLVMInt32Type (), IntPtrType (), LLVMInt32Type (), LLVMInt32Type (), IntPtrType (), IntPtrType (), FALSE);
3607 LLVMValueRef callee = ctx->module->match_exc;
3610 if (ctx->cfg->compile_aot) {
3611 ctx->builder = builder;
3612 // get_callee expects ctx->builder to be the emitting builder
3613 callee = get_callee (ctx, match_sig, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
3615 callee = ctx->module->match_exc = LLVMAddFunction (ctx->lmodule, icall_name, match_sig);
3616 LLVMAddGlobalMapping (ctx->module->ee, ctx->module->match_exc, resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name));
3617 ctx->module->match_exc = callee;
3618 mono_memory_barrier ();
3622 g_assert (builder && callee);
3624 g_assert (ctx->ex_var);
3626 return LLVMBuildCall (builder, callee, args, num_args, icall_name);
3629 // FIXME: This won't work because the code-finding makes this
3631 /*#define MONO_PERSONALITY_DEBUG*/
3633 #ifdef MONO_PERSONALITY_DEBUG
3634 static const gboolean use_debug_personality = TRUE;
3635 static const char *default_personality_name = "mono_debug_personality";
3637 static const gboolean use_debug_personality = FALSE;
3638 static const char *default_personality_name = "__gxx_personality_v0";
3642 default_cpp_lpad_exc_signature (void)
3644 static gboolean inited = FALSE;
3645 static LLVMTypeRef sig;
3648 LLVMTypeRef signature [2];
3649 signature [0] = LLVMPointerType (LLVMInt8Type (), 0);
3650 signature [1] = LLVMInt32Type ();
3651 sig = LLVMStructType (signature, 2, FALSE);
3659 get_mono_personality (EmitContext *ctx)
3661 LLVMValueRef personality = NULL;
3662 static gint32 mapping_inited = FALSE;
3663 LLVMTypeRef personality_type = LLVMFunctionType (LLVMInt32Type (), NULL, 0, TRUE);
3665 if (!use_debug_personality) {
3666 if (ctx->cfg->compile_aot) {
3667 personality = LLVMGetNamedFunction (ctx->lmodule, default_personality_name);
3668 } else if (InterlockedCompareExchange (&mapping_inited, 1, 0) == 0) {
3669 personality = LLVMAddFunction (ctx->lmodule, default_personality_name, personality_type);
3670 LLVMAddGlobalMapping (ctx->module->ee, personality, personality);
3673 if (ctx->cfg->compile_aot) {
3674 personality = get_callee (ctx, personality_type, MONO_PATCH_INFO_INTERNAL_METHOD, default_personality_name);
3676 personality = LLVMAddFunction (ctx->lmodule, default_personality_name, personality_type);
3677 LLVMAddGlobalMapping (ctx->module->ee, personality, resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, default_personality_name));
3678 mono_memory_barrier ();
3682 g_assert (personality);
3686 static LLVMBasicBlockRef
3687 emit_landing_pad (EmitContext *ctx, int group_index, int group_size)
3689 MonoCompile *cfg = ctx->cfg;
3690 LLVMBuilderRef old_builder = ctx->builder;
3691 MonoExceptionClause *group_start = cfg->header->clauses + group_index;
3693 LLVMBuilderRef lpadBuilder = create_builder (ctx);
3694 ctx->builder = lpadBuilder;
3696 MonoBasicBlock *handler_bb = cfg->cil_offset_to_bb [CLAUSE_START (group_start)];
3697 g_assert (handler_bb);
3699 // <resultval> = landingpad <somety> personality <type> <pers_fn> <clause>+
3700 LLVMValueRef personality = get_mono_personality (ctx);
3701 g_assert (personality);
3703 char *bb_name = g_strdup_printf ("LPAD%d_BB", group_index);
3704 LLVMBasicBlockRef lpad_bb = gen_bb (ctx, bb_name);
3706 LLVMPositionBuilderAtEnd (lpadBuilder, lpad_bb);
3707 LLVMValueRef landing_pad = LLVMBuildLandingPad (lpadBuilder, default_cpp_lpad_exc_signature (), personality, 0, "");
3708 g_assert (landing_pad);
3710 LLVMValueRef cast = LLVMBuildBitCast (lpadBuilder, ctx->module->sentinel_exception, LLVMPointerType (LLVMInt8Type (), 0), "int8TypeInfo");
3711 LLVMAddClause (landing_pad, cast);
3713 LLVMBasicBlockRef resume_bb = gen_bb (ctx, "RESUME_BB");
3714 LLVMBuilderRef resume_builder = create_builder (ctx);
3715 ctx->builder = resume_builder;
3716 LLVMPositionBuilderAtEnd (resume_builder, resume_bb);
3718 emit_resume_eh (ctx, handler_bb);
3721 ctx->builder = lpadBuilder;
3722 LLVMPositionBuilderAtEnd (lpadBuilder, lpad_bb);
3724 gboolean finally_only = TRUE;
3726 MonoExceptionClause *group_cursor = group_start;
3728 for (int i = 0; i < group_size; i ++) {
3729 if (!(group_cursor->flags & MONO_EXCEPTION_CLAUSE_FINALLY))
3730 finally_only = FALSE;
3736 // Handle landing pad inlining
3738 if (!finally_only) {
3739 // So at each level of the exception stack we will match the exception again.
3740 // During that match, we need to compare against the handler types for the current
3741 // protected region. We send the try start and end so that we can only check against
3742 // handlers for this lexical protected region.
3743 LLVMValueRef match = mono_llvm_emit_match_exception_call (ctx, lpadBuilder, group_start->try_offset, group_start->try_offset + group_start->try_len);
3745 // if returns -1, resume
3746 LLVMValueRef switch_ins = LLVMBuildSwitch (lpadBuilder, match, resume_bb, group_size);
3748 // else move to that target bb
3749 for (int i=0; i < group_size; i++) {
3750 MonoExceptionClause *clause = group_start + i;
3751 int clause_index = clause - cfg->header->clauses;
3752 MonoBasicBlock *handler_bb = (MonoBasicBlock*)g_hash_table_lookup (ctx->clause_to_handler, GINT_TO_POINTER (clause_index));
3753 g_assert (handler_bb);
3754 g_assert (ctx->bblocks [handler_bb->block_num].call_handler_target_bb);
3755 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), clause_index, FALSE), ctx->bblocks [handler_bb->block_num].call_handler_target_bb);
3758 int clause_index = group_start - cfg->header->clauses;
3759 MonoBasicBlock *finally_bb = (MonoBasicBlock*)g_hash_table_lookup (ctx->clause_to_handler, GINT_TO_POINTER (clause_index));
3760 g_assert (finally_bb);
3762 LLVMBuildBr (ctx->builder, ctx->bblocks [finally_bb->block_num].call_handler_target_bb);
3765 ctx->builder = old_builder;
3772 emit_llvmonly_handler_start (EmitContext *ctx, MonoBasicBlock *bb, LLVMBasicBlockRef cbb)
3774 int clause_index = MONO_REGION_CLAUSE_INDEX (bb->region);
3775 MonoExceptionClause *clause = &ctx->cfg->header->clauses [clause_index];
3777 // Make exception available to catch blocks
3778 if (!(clause->flags & MONO_EXCEPTION_CLAUSE_FINALLY)) {
3779 LLVMValueRef mono_exc = mono_llvm_emit_load_exception_call (ctx, ctx->builder);
3781 g_assert (ctx->ex_var);
3782 LLVMBuildStore (ctx->builder, LLVMBuildBitCast (ctx->builder, mono_exc, ObjRefType (), ""), ctx->ex_var);
3784 if (bb->in_scount == 1) {
3785 MonoInst *exvar = bb->in_stack [0];
3786 g_assert (!ctx->values [exvar->dreg]);
3787 g_assert (ctx->ex_var);
3788 ctx->values [exvar->dreg] = LLVMBuildLoad (ctx->builder, ctx->ex_var, "save_exception");
3789 emit_volatile_store (ctx, exvar->dreg);
3792 mono_llvm_emit_clear_exception_call (ctx, ctx->builder);
3795 LLVMBuilderRef handler_builder = create_builder (ctx);
3796 LLVMBasicBlockRef target_bb = ctx->bblocks [bb->block_num].call_handler_target_bb;
3797 LLVMPositionBuilderAtEnd (handler_builder, target_bb);
3799 // Make the handler code end with a jump to cbb
3800 LLVMBuildBr (handler_builder, cbb);
3804 emit_handler_start (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef builder)
3806 MonoCompile *cfg = ctx->cfg;
3807 LLVMValueRef *values = ctx->values;
3808 LLVMModuleRef lmodule = ctx->lmodule;
3809 BBInfo *bblocks = ctx->bblocks;
3811 LLVMValueRef personality;
3812 LLVMValueRef landing_pad;
3813 LLVMBasicBlockRef target_bb;
3815 static gint32 mapping_inited;
3816 static int ti_generator;
3819 LLVMValueRef type_info;
3823 // <resultval> = landingpad <somety> personality <type> <pers_fn> <clause>+
3825 if (cfg->compile_aot) {
3826 /* Use a dummy personality function */
3827 personality = LLVMGetNamedFunction (lmodule, "mono_personality");
3828 g_assert (personality);
3830 personality = LLVMGetNamedFunction (lmodule, "mono_personality");
3831 if (InterlockedCompareExchange (&mapping_inited, 1, 0) == 0)
3832 LLVMAddGlobalMapping (ctx->module->ee, personality, (gpointer)mono_personality);
3835 i8ptr = LLVMPointerType (LLVMInt8Type (), 0);
3837 clause_index = (mono_get_block_region_notry (cfg, bb->region) >> 8) - 1;
3840 * Create the type info
3842 sprintf (ti_name, "type_info_%d", ti_generator);
3845 if (cfg->compile_aot) {
3846 /* decode_eh_frame () in aot-runtime.c will decode this */
3847 type_info = LLVMAddGlobal (lmodule, LLVMInt32Type (), ti_name);
3848 LLVMSetInitializer (type_info, LLVMConstInt (LLVMInt32Type (), clause_index, FALSE));
3851 * These symbols are not really used, the clause_index is embedded into the EH tables generated by DwarfMonoException in LLVM.
3853 LLVMSetLinkage (type_info, LLVMInternalLinkage);
3856 * After the cfg mempool is freed, the type info will point to stale memory,
3857 * but this is not a problem, since we decode it once in exception_cb during
3860 ti = (gint32*)mono_mempool_alloc (cfg->mempool, sizeof (gint32));
3861 *(gint32*)ti = clause_index;
3863 type_info = LLVMAddGlobal (lmodule, i8ptr, ti_name);
3865 LLVMAddGlobalMapping (ctx->module->ee, type_info, ti);
3869 LLVMTypeRef members [2], ret_type;
3871 members [0] = i8ptr;
3872 members [1] = LLVMInt32Type ();
3873 ret_type = LLVMStructType (members, 2, FALSE);
3875 landing_pad = LLVMBuildLandingPad (builder, ret_type, personality, 1, "");
3876 LLVMAddClause (landing_pad, type_info);
3878 /* Store the exception into the exvar */
3880 LLVMBuildStore (builder, convert (ctx, LLVMBuildExtractValue (builder, landing_pad, 0, "ex_obj"), ObjRefType ()), ctx->ex_var);
3884 * LLVM throw sites are associated with a one landing pad, and LLVM generated
3885 * code expects control to be transferred to this landing pad even in the
3886 * presence of nested clauses. The landing pad needs to branch to the landing
3887 * pads belonging to nested clauses based on the selector value returned by
3888 * the landing pad instruction, which is passed to the landing pad in a
3889 * register by the EH code.
3891 target_bb = bblocks [bb->block_num].call_handler_target_bb;
3892 g_assert (target_bb);
3895 * Branch to the correct landing pad
3897 LLVMValueRef ex_selector = LLVMBuildExtractValue (builder, landing_pad, 1, "ex_selector");
3898 LLVMValueRef switch_ins = LLVMBuildSwitch (builder, ex_selector, target_bb, 0);
3900 for (l = ctx->nested_in [clause_index]; l; l = l->next) {
3901 int nesting_clause_index = GPOINTER_TO_INT (l->data);
3902 MonoBasicBlock *handler_bb;
3904 handler_bb = (MonoBasicBlock*)g_hash_table_lookup (ctx->clause_to_handler, GINT_TO_POINTER (nesting_clause_index));
3905 g_assert (handler_bb);
3907 g_assert (ctx->bblocks [handler_bb->block_num].call_handler_target_bb);
3908 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), nesting_clause_index, FALSE), ctx->bblocks [handler_bb->block_num].call_handler_target_bb);
3911 /* Start a new bblock which CALL_HANDLER can branch to */
3912 target_bb = bblocks [bb->block_num].call_handler_target_bb;
3914 ctx->builder = builder = create_builder (ctx);
3915 LLVMPositionBuilderAtEnd (ctx->builder, target_bb);
3917 ctx->bblocks [bb->block_num].end_bblock = target_bb;
3919 /* Store the exception into the IL level exvar */
3920 if (bb->in_scount == 1) {
3921 g_assert (bb->in_scount == 1);
3922 exvar = bb->in_stack [0];
3924 // FIXME: This is shared with filter clauses ?
3925 g_assert (!values [exvar->dreg]);
3927 g_assert (ctx->ex_var);
3928 values [exvar->dreg] = LLVMBuildLoad (builder, ctx->ex_var, "");
3929 emit_volatile_store (ctx, exvar->dreg);
3935 process_bb (EmitContext *ctx, MonoBasicBlock *bb)
3937 MonoCompile *cfg = ctx->cfg;
3938 MonoMethodSignature *sig = ctx->sig;
3939 LLVMValueRef method = ctx->lmethod;
3940 LLVMValueRef *values = ctx->values;
3941 LLVMValueRef *addresses = ctx->addresses;
3942 LLVMCallInfo *linfo = ctx->linfo;
3943 LLVMModuleRef lmodule = ctx->lmodule;
3944 BBInfo *bblocks = ctx->bblocks;
3946 LLVMBasicBlockRef cbb;
3947 LLVMBuilderRef builder, starting_builder;
3948 gboolean has_terminator;
3950 LLVMValueRef lhs, rhs;
3953 cbb = get_end_bb (ctx, bb);
3955 builder = create_builder (ctx);
3956 ctx->builder = builder;
3957 LLVMPositionBuilderAtEnd (builder, cbb);
3959 CHECK_FAILURE (ctx);
3961 if (bb->flags & BB_EXCEPTION_HANDLER) {
3962 if (!ctx->llvm_only && !bblocks [bb->block_num].invoke_target) {
3963 LLVM_FAILURE (ctx, "handler without invokes");
3967 emit_llvmonly_handler_start (ctx, bb, cbb);
3969 emit_handler_start (ctx, bb, builder);
3970 CHECK_FAILURE (ctx);
3971 builder = ctx->builder;
3974 has_terminator = FALSE;
3975 starting_builder = builder;
3976 for (ins = bb->code; ins; ins = ins->next) {
3977 const char *spec = LLVM_INS_INFO (ins->opcode);
3979 char dname_buf [128];
3981 emit_dbg_loc (ctx, builder, ins->cil_code);
3986 * Some steps in llc are non-linear in the size of basic blocks, see #5714.
3987 * Start a new bblock. If the llvm optimization passes merge these, we
3988 * can work around that by doing a volatile load + cond branch from
3989 * localloc-ed memory.
3991 //LLVM_FAILURE (ctx, "basic block too long");
3992 cbb = gen_bb (ctx, "CONT_LONG_BB");
3993 LLVMBuildBr (ctx->builder, cbb);
3994 ctx->builder = builder = create_builder (ctx);
3995 LLVMPositionBuilderAtEnd (builder, cbb);
3996 ctx->bblocks [bb->block_num].end_bblock = cbb;
4001 /* There could be instructions after a terminator, skip them */
4004 if (spec [MONO_INST_DEST] != ' ' && !MONO_IS_STORE_MEMBASE (ins)) {
4005 sprintf (dname_buf, "t%d", ins->dreg);
4009 if (spec [MONO_INST_SRC1] != ' ' && spec [MONO_INST_SRC1] != 'v') {
4010 MonoInst *var = get_vreg_to_inst (cfg, ins->sreg1);
4012 if (var && var->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT) && var->opcode != OP_GSHAREDVT_ARG_REGOFFSET) {
4013 lhs = emit_volatile_load (ctx, ins->sreg1);
4015 /* It is ok for SETRET to have an uninitialized argument */
4016 if (!values [ins->sreg1] && ins->opcode != OP_SETRET)
4017 LLVM_FAILURE (ctx, "sreg1");
4018 lhs = values [ins->sreg1];
4024 if (spec [MONO_INST_SRC2] != ' ' && spec [MONO_INST_SRC2] != ' ') {
4025 MonoInst *var = get_vreg_to_inst (cfg, ins->sreg2);
4026 if (var && var->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT)) {
4027 rhs = emit_volatile_load (ctx, ins->sreg2);
4029 if (!values [ins->sreg2])
4030 LLVM_FAILURE (ctx, "sreg2");
4031 rhs = values [ins->sreg2];
4037 //mono_print_ins (ins);
4038 switch (ins->opcode) {
4041 case OP_LIVERANGE_START:
4042 case OP_LIVERANGE_END:
4045 values [ins->dreg] = LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE);
4048 #if SIZEOF_VOID_P == 4
4049 values [ins->dreg] = LLVMConstInt (LLVMInt64Type (), GET_LONG_IMM (ins), FALSE);
4051 values [ins->dreg] = LLVMConstInt (LLVMInt64Type (), (gint64)ins->inst_c0, FALSE);
4055 values [ins->dreg] = LLVMConstReal (LLVMDoubleType (), *(double*)ins->inst_p0);
4059 values [ins->dreg] = LLVMConstReal (LLVMFloatType (), *(float*)ins->inst_p0);
4061 values [ins->dreg] = LLVMConstFPExt (LLVMConstReal (LLVMFloatType (), *(float*)ins->inst_p0), LLVMDoubleType ());
4063 case OP_DUMMY_ICONST:
4064 values [ins->dreg] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
4066 case OP_DUMMY_I8CONST:
4067 values [ins->dreg] = LLVMConstInt (LLVMInt64Type (), 0, FALSE);
4069 case OP_DUMMY_R8CONST:
4070 values [ins->dreg] = LLVMConstReal (LLVMDoubleType (), 0.0f);
4073 LLVMBasicBlockRef target_bb = get_bb (ctx, ins->inst_target_bb);
4074 LLVMBuildBr (builder, target_bb);
4075 has_terminator = TRUE;
4082 LLVMBasicBlockRef new_bb;
4083 LLVMBuilderRef new_builder;
4085 // The default branch is already handled
4086 // FIXME: Handle it here
4088 /* Start new bblock */
4089 sprintf (bb_name, "SWITCH_DEFAULT_BB%d", ctx->default_index ++);
4090 new_bb = LLVMAppendBasicBlock (ctx->lmethod, bb_name);
4092 lhs = convert (ctx, lhs, LLVMInt32Type ());
4093 v = LLVMBuildSwitch (builder, lhs, new_bb, GPOINTER_TO_UINT (ins->klass));
4094 for (i = 0; i < GPOINTER_TO_UINT (ins->klass); ++i) {
4095 MonoBasicBlock *target_bb = ins->inst_many_bb [i];
4097 LLVMAddCase (v, LLVMConstInt (LLVMInt32Type (), i, FALSE), get_bb (ctx, target_bb));
4100 new_builder = create_builder (ctx);
4101 LLVMPositionBuilderAtEnd (new_builder, new_bb);
4102 LLVMBuildUnreachable (new_builder);
4104 has_terminator = TRUE;
4105 g_assert (!ins->next);
4111 switch (linfo->ret.storage) {
4112 case LLVMArgVtypeInReg: {
4113 LLVMTypeRef ret_type = LLVMGetReturnType (LLVMGetElementType (LLVMTypeOf (method)));
4114 LLVMValueRef val, addr, retval;
4117 retval = LLVMGetUndef (ret_type);
4119 if (!addresses [ins->sreg1]) {
4121 * The return type is an LLVM vector type, have to convert between it and the
4122 * real return type which is a struct type.
4124 g_assert (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (sig->ret)));
4125 /* Convert to 2xi64 first */
4126 val = LLVMBuildBitCast (builder, values [ins->sreg1], LLVMVectorType (IntPtrType (), 2), "");
4128 for (i = 0; i < 2; ++i) {
4129 if (linfo->ret.pair_storage [i] == LLVMArgInIReg) {
4130 retval = LLVMBuildInsertValue (builder, retval, LLVMBuildExtractElement (builder, val, LLVMConstInt (LLVMInt32Type (), i, FALSE), ""), i, "");
4132 g_assert (linfo->ret.pair_storage [i] == LLVMArgNone);
4136 addr = LLVMBuildBitCast (builder, addresses [ins->sreg1], LLVMPointerType (ret_type, 0), "");
4137 for (i = 0; i < 2; ++i) {
4138 if (linfo->ret.pair_storage [i] == LLVMArgInIReg) {
4139 LLVMValueRef indexes [2], part_addr;
4141 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
4142 indexes [1] = LLVMConstInt (LLVMInt32Type (), i, FALSE);
4143 part_addr = LLVMBuildGEP (builder, addr, indexes, 2, "");
4145 retval = LLVMBuildInsertValue (builder, retval, LLVMBuildLoad (builder, part_addr, ""), i, "");
4147 g_assert (linfo->ret.pair_storage [i] == LLVMArgNone);
4151 LLVMBuildRet (builder, retval);
4154 case LLVMArgVtypeAsScalar: {
4155 LLVMTypeRef ret_type = LLVMGetReturnType (LLVMGetElementType (LLVMTypeOf (method)));
4156 LLVMValueRef retval;
4159 size = get_vtype_size (sig->ret);
4161 g_assert (addresses [ins->sreg1]);
4163 retval = LLVMBuildLoad (builder, LLVMBuildBitCast (builder, addresses [ins->sreg1], LLVMPointerType (ret_type, 0), ""), "");
4164 LLVMBuildRet (builder, retval);
4167 case LLVMArgVtypeByVal: {
4168 LLVMValueRef retval;
4170 g_assert (addresses [ins->sreg1]);
4171 retval = LLVMBuildLoad (builder, addresses [ins->sreg1], "");
4172 LLVMBuildRet (builder, retval);
4175 case LLVMArgVtypeByRef: {
4176 LLVMBuildRetVoid (builder);
4179 case LLVMArgGsharedvtFixed: {
4180 LLVMTypeRef ret_type = type_to_llvm_type (ctx, sig->ret);
4181 /* The return value is in lhs, need to store to the vret argument */
4182 /* sreg1 might not be set */
4184 g_assert (cfg->vret_addr);
4185 g_assert (values [cfg->vret_addr->dreg]);
4186 LLVMBuildStore (builder, convert (ctx, lhs, ret_type), convert (ctx, values [cfg->vret_addr->dreg], LLVMPointerType (ret_type, 0)));
4188 LLVMBuildRetVoid (builder);
4191 case LLVMArgGsharedvtFixedVtype: {
4193 LLVMBuildRetVoid (builder);
4196 case LLVMArgGsharedvtVariable: {
4198 LLVMBuildRetVoid (builder);
4201 case LLVMArgVtypeRetAddr: {
4202 LLVMBuildRetVoid (builder);
4205 case LLVMArgScalarRetAddr: {
4206 LLVMTypeRef ret_type = type_to_llvm_type (ctx, sig->ret);
4207 LLVMValueRef param = LLVMGetParam (method, linfo->vret_arg_pindex);
4209 /* sreg1 might not be set */
4211 LLVMBuildStore (builder, convert (ctx, lhs, ret_type), convert (ctx, param, LLVMPointerType (ret_type, 0)));
4212 LLVMBuildRetVoid (builder);
4215 case LLVMArgFpStruct: {
4216 LLVMTypeRef ret_type = LLVMGetReturnType (LLVMGetElementType (LLVMTypeOf (method)));
4217 LLVMValueRef retval;
4219 g_assert (addresses [ins->sreg1]);
4220 retval = LLVMBuildLoad (builder, convert (ctx, addresses [ins->sreg1], LLVMPointerType (ret_type, 0)), "");
4221 LLVMBuildRet (builder, retval);
4225 case LLVMArgNormal: {
4226 if (!lhs || ctx->is_dead [ins->sreg1]) {
4228 * The method did not set its return value, probably because it
4229 * ends with a throw.
4232 LLVMBuildRetVoid (builder);
4234 LLVMBuildRet (builder, LLVMConstNull (type_to_llvm_type (ctx, sig->ret)));
4236 LLVMBuildRet (builder, convert (ctx, lhs, type_to_llvm_type (ctx, sig->ret)));
4238 has_terminator = TRUE;
4242 g_assert_not_reached ();
4251 case OP_ICOMPARE_IMM:
4252 case OP_LCOMPARE_IMM:
4253 case OP_COMPARE_IMM: {
4255 LLVMValueRef cmp, args [16];
4256 gboolean likely = (ins->flags & MONO_INST_LIKELY) != 0;
4258 if (ins->next->opcode == OP_NOP)
4261 if (ins->next->opcode == OP_BR)
4262 /* The comparison result is not needed */
4265 rel = mono_opcode_to_cond (ins->next->opcode);
4267 if (ins->opcode == OP_ICOMPARE_IMM) {
4268 lhs = convert (ctx, lhs, LLVMInt32Type ());
4269 rhs = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
4271 if (ins->opcode == OP_LCOMPARE_IMM) {
4272 lhs = convert (ctx, lhs, LLVMInt64Type ());
4273 rhs = LLVMConstInt (LLVMInt64Type (), GET_LONG_IMM (ins), FALSE);
4275 if (ins->opcode == OP_LCOMPARE) {
4276 lhs = convert (ctx, lhs, LLVMInt64Type ());
4277 rhs = convert (ctx, rhs, LLVMInt64Type ());
4279 if (ins->opcode == OP_ICOMPARE) {
4280 lhs = convert (ctx, lhs, LLVMInt32Type ());
4281 rhs = convert (ctx, rhs, LLVMInt32Type ());
4285 if (LLVMGetTypeKind (LLVMTypeOf (lhs)) == LLVMPointerTypeKind)
4286 rhs = convert (ctx, rhs, LLVMTypeOf (lhs));
4287 else if (LLVMGetTypeKind (LLVMTypeOf (rhs)) == LLVMPointerTypeKind)
4288 lhs = convert (ctx, lhs, LLVMTypeOf (rhs));
4291 /* We use COMPARE+SETcc/Bcc, llvm uses SETcc+br cond */
4292 if (ins->opcode == OP_FCOMPARE) {
4293 cmp = LLVMBuildFCmp (builder, fpcond_to_llvm_cond [rel], convert (ctx, lhs, LLVMDoubleType ()), convert (ctx, rhs, LLVMDoubleType ()), "");
4294 } else if (ins->opcode == OP_RCOMPARE) {
4295 cmp = LLVMBuildFCmp (builder, fpcond_to_llvm_cond [rel], convert (ctx, lhs, LLVMFloatType ()), convert (ctx, rhs, LLVMFloatType ()), "");
4296 } else if (ins->opcode == OP_COMPARE_IMM) {
4297 if (LLVMGetTypeKind (LLVMTypeOf (lhs)) == LLVMPointerTypeKind && ins->inst_imm == 0)
4298 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], lhs, LLVMConstNull (LLVMTypeOf (lhs)), "");
4300 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE), "");
4301 } else if (ins->opcode == OP_LCOMPARE_IMM) {
4302 if (SIZEOF_REGISTER == 4 && COMPILE_LLVM (cfg)) {
4303 /* The immediate is encoded in two fields */
4304 guint64 l = ((guint64)(guint32)ins->inst_offset << 32) | ((guint32)ins->inst_imm);
4305 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, LLVMInt64Type ()), LLVMConstInt (LLVMInt64Type (), l, FALSE), "");
4307 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, LLVMInt64Type ()), LLVMConstInt (LLVMInt64Type (), ins->inst_imm, FALSE), "");
4310 else if (ins->opcode == OP_COMPARE) {
4311 if (LLVMGetTypeKind (LLVMTypeOf (lhs)) == LLVMPointerTypeKind && LLVMTypeOf (lhs) == LLVMTypeOf (rhs))
4312 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], lhs, rhs, "");
4314 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, IntPtrType ()), convert (ctx, rhs, IntPtrType ()), "");
4316 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], lhs, rhs, "");
4320 args [1] = LLVMConstInt (LLVMInt1Type (), 1, FALSE);
4321 cmp = LLVMBuildCall (ctx->builder, LLVMGetNamedFunction (ctx->lmodule, "llvm.expect.i1"), args, 2, "");
4324 if (MONO_IS_COND_BRANCH_OP (ins->next)) {
4325 if (ins->next->inst_true_bb == ins->next->inst_false_bb) {
4327 * If the target bb contains PHI instructions, LLVM requires
4328 * two PHI entries for this bblock, while we only generate one.
4329 * So convert this to an unconditional bblock. (bxc #171).
4331 LLVMBuildBr (builder, get_bb (ctx, ins->next->inst_true_bb));
4333 LLVMBuildCondBr (builder, cmp, get_bb (ctx, ins->next->inst_true_bb), get_bb (ctx, ins->next->inst_false_bb));
4335 has_terminator = TRUE;
4336 } else if (MONO_IS_SETCC (ins->next)) {
4337 sprintf (dname_buf, "t%d", ins->next->dreg);
4339 values [ins->next->dreg] = LLVMBuildZExt (builder, cmp, LLVMInt32Type (), dname);
4341 /* Add stores for volatile variables */
4342 emit_volatile_store (ctx, ins->next->dreg);
4343 } else if (MONO_IS_COND_EXC (ins->next)) {
4344 emit_cond_system_exception (ctx, bb, (const char*)ins->next->inst_p1, cmp);
4345 CHECK_FAILURE (ctx);
4346 builder = ctx->builder;
4348 LLVM_FAILURE (ctx, "next");
4365 rel = mono_opcode_to_cond (ins->opcode);
4367 cmp = LLVMBuildFCmp (builder, fpcond_to_llvm_cond [rel], convert (ctx, lhs, LLVMDoubleType ()), convert (ctx, rhs, LLVMDoubleType ()), "");
4368 values [ins->dreg] = LLVMBuildZExt (builder, cmp, LLVMInt32Type (), dname);
4379 rel = mono_opcode_to_cond (ins->opcode);
4381 cmp = LLVMBuildFCmp (builder, fpcond_to_llvm_cond [rel], convert (ctx, lhs, LLVMFloatType ()), convert (ctx, rhs, LLVMFloatType ()), "");
4382 values [ins->dreg] = LLVMBuildZExt (builder, cmp, LLVMInt32Type (), dname);
4390 gboolean empty = TRUE;
4392 /* Check that all input bblocks really branch to us */
4393 for (i = 0; i < bb->in_count; ++i) {
4394 if (bb->in_bb [i]->last_ins && bb->in_bb [i]->last_ins->opcode == OP_NOT_REACHED)
4395 ins->inst_phi_args [i + 1] = -1;
4401 /* LLVM doesn't like phi instructions with zero operands */
4402 ctx->is_dead [ins->dreg] = TRUE;
4406 /* Created earlier, insert it now */
4407 LLVMInsertIntoBuilder (builder, values [ins->dreg]);
4409 for (i = 0; i < ins->inst_phi_args [0]; i++) {
4410 int sreg1 = ins->inst_phi_args [i + 1];
4414 * Count the number of times the incoming bblock branches to us,
4415 * since llvm requires a separate entry for each.
4417 if (bb->in_bb [i]->last_ins && bb->in_bb [i]->last_ins->opcode == OP_SWITCH) {
4418 MonoInst *switch_ins = bb->in_bb [i]->last_ins;
4421 for (j = 0; j < GPOINTER_TO_UINT (switch_ins->klass); ++j) {
4422 if (switch_ins->inst_many_bb [j] == bb)
4429 /* Remember for later */
4430 for (j = 0; j < count; ++j) {
4431 PhiNode *node = (PhiNode*)mono_mempool_alloc0 (ctx->mempool, sizeof (PhiNode));
4434 node->in_bb = bb->in_bb [i];
4436 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);
4446 values [ins->dreg] = lhs;
4450 MonoInst *var = get_vreg_to_inst (cfg, ins->dreg);
4453 values [ins->dreg] = lhs;
4455 if (var && var->klass->byval_arg.type == MONO_TYPE_R4) {
4457 * This is added by the spilling pass in case of the JIT,
4458 * but we have to do it ourselves.
4460 values [ins->dreg] = convert (ctx, values [ins->dreg], LLVMFloatType ());
4464 case OP_MOVE_F_TO_I4: {
4465 values [ins->dreg] = LLVMBuildBitCast (builder, LLVMBuildFPTrunc (builder, lhs, LLVMFloatType (), ""), LLVMInt32Type (), "");
4468 case OP_MOVE_I4_TO_F: {
4469 values [ins->dreg] = LLVMBuildFPExt (builder, LLVMBuildBitCast (builder, lhs, LLVMFloatType (), ""), LLVMDoubleType (), "");
4472 case OP_MOVE_F_TO_I8: {
4473 values [ins->dreg] = LLVMBuildBitCast (builder, lhs, LLVMInt64Type (), "");
4476 case OP_MOVE_I8_TO_F: {
4477 values [ins->dreg] = LLVMBuildBitCast (builder, lhs, LLVMDoubleType (), "");
4510 lhs = convert (ctx, lhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
4511 rhs = convert (ctx, rhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
4513 emit_div_check (ctx, builder, bb, ins, lhs, rhs);
4514 CHECK_FAILURE (ctx);
4515 builder = ctx->builder;
4517 switch (ins->opcode) {
4520 values [ins->dreg] = LLVMBuildAdd (builder, lhs, rhs, dname);
4524 values [ins->dreg] = LLVMBuildSub (builder, lhs, rhs, dname);
4528 values [ins->dreg] = LLVMBuildMul (builder, lhs, rhs, dname);
4532 values [ins->dreg] = LLVMBuildSRem (builder, lhs, rhs, dname);
4536 values [ins->dreg] = LLVMBuildURem (builder, lhs, rhs, dname);
4540 values [ins->dreg] = LLVMBuildSDiv (builder, lhs, rhs, dname);
4544 values [ins->dreg] = LLVMBuildUDiv (builder, lhs, rhs, dname);
4548 values [ins->dreg] = LLVMBuildFDiv (builder, lhs, rhs, dname);
4552 values [ins->dreg] = LLVMBuildAnd (builder, lhs, rhs, dname);
4556 values [ins->dreg] = LLVMBuildOr (builder, lhs, rhs, dname);
4560 values [ins->dreg] = LLVMBuildXor (builder, lhs, rhs, dname);
4564 values [ins->dreg] = LLVMBuildShl (builder, lhs, rhs, dname);
4568 values [ins->dreg] = LLVMBuildAShr (builder, lhs, rhs, dname);
4572 values [ins->dreg] = LLVMBuildLShr (builder, lhs, rhs, dname);
4576 values [ins->dreg] = LLVMBuildFAdd (builder, lhs, rhs, dname);
4579 values [ins->dreg] = LLVMBuildFSub (builder, lhs, rhs, dname);
4582 values [ins->dreg] = LLVMBuildFMul (builder, lhs, rhs, dname);
4586 g_assert_not_reached ();
4593 lhs = convert (ctx, lhs, LLVMFloatType ());
4594 rhs = convert (ctx, rhs, LLVMFloatType ());
4595 switch (ins->opcode) {
4597 values [ins->dreg] = LLVMBuildFAdd (builder, lhs, rhs, dname);
4600 values [ins->dreg] = LLVMBuildFSub (builder, lhs, rhs, dname);
4603 values [ins->dreg] = LLVMBuildFMul (builder, lhs, rhs, dname);
4606 values [ins->dreg] = LLVMBuildFDiv (builder, lhs, rhs, dname);
4609 g_assert_not_reached ();
4618 case OP_IREM_UN_IMM:
4620 case OP_IDIV_UN_IMM:
4626 case OP_ISHR_UN_IMM:
4636 case OP_LSHR_UN_IMM:
4642 case OP_SHR_UN_IMM: {
4645 if (spec [MONO_INST_SRC1] == 'l') {
4646 imm = LLVMConstInt (LLVMInt64Type (), GET_LONG_IMM (ins), FALSE);
4648 imm = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
4651 emit_div_check (ctx, builder, bb, ins, lhs, imm);
4652 CHECK_FAILURE (ctx);
4653 builder = ctx->builder;
4655 #if SIZEOF_VOID_P == 4
4656 if (ins->opcode == OP_LSHL_IMM || ins->opcode == OP_LSHR_IMM || ins->opcode == OP_LSHR_UN_IMM)
4657 imm = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
4660 if (LLVMGetTypeKind (LLVMTypeOf (lhs)) == LLVMPointerTypeKind)
4661 lhs = convert (ctx, lhs, IntPtrType ());
4662 imm = convert (ctx, imm, LLVMTypeOf (lhs));
4663 switch (ins->opcode) {
4667 values [ins->dreg] = LLVMBuildAdd (builder, lhs, imm, dname);
4671 values [ins->dreg] = LLVMBuildSub (builder, lhs, imm, dname);
4676 values [ins->dreg] = LLVMBuildMul (builder, lhs, imm, dname);
4680 values [ins->dreg] = LLVMBuildSDiv (builder, lhs, imm, dname);
4682 case OP_IDIV_UN_IMM:
4683 case OP_LDIV_UN_IMM:
4684 values [ins->dreg] = LLVMBuildUDiv (builder, lhs, imm, dname);
4688 values [ins->dreg] = LLVMBuildSRem (builder, lhs, imm, dname);
4690 case OP_IREM_UN_IMM:
4691 values [ins->dreg] = LLVMBuildURem (builder, lhs, imm, dname);
4696 values [ins->dreg] = LLVMBuildAnd (builder, lhs, imm, dname);
4700 values [ins->dreg] = LLVMBuildOr (builder, lhs, imm, dname);
4704 values [ins->dreg] = LLVMBuildXor (builder, lhs, imm, dname);
4709 values [ins->dreg] = LLVMBuildShl (builder, lhs, imm, dname);
4714 values [ins->dreg] = LLVMBuildAShr (builder, lhs, imm, dname);
4716 case OP_ISHR_UN_IMM:
4717 /* This is used to implement conv.u4, so the lhs could be an i8 */
4718 lhs = convert (ctx, lhs, LLVMInt32Type ());
4719 imm = convert (ctx, imm, LLVMInt32Type ());
4720 values [ins->dreg] = LLVMBuildLShr (builder, lhs, imm, dname);
4722 case OP_LSHR_UN_IMM:
4724 values [ins->dreg] = LLVMBuildLShr (builder, lhs, imm, dname);
4727 g_assert_not_reached ();
4732 values [ins->dreg] = LLVMBuildSub (builder, LLVMConstInt (LLVMInt32Type (), 0, FALSE), convert (ctx, lhs, LLVMInt32Type ()), dname);
4735 values [ins->dreg] = LLVMBuildSub (builder, LLVMConstInt (LLVMInt64Type (), 0, FALSE), lhs, dname);
4738 lhs = convert (ctx, lhs, LLVMDoubleType ());
4739 values [ins->dreg] = LLVMBuildFSub (builder, LLVMConstReal (LLVMDoubleType (), 0.0), lhs, dname);
4742 lhs = convert (ctx, lhs, LLVMFloatType ());
4743 values [ins->dreg] = LLVMBuildFSub (builder, LLVMConstReal (LLVMFloatType (), 0.0), lhs, dname);
4746 guint32 v = 0xffffffff;
4747 values [ins->dreg] = LLVMBuildXor (builder, LLVMConstInt (LLVMInt32Type (), v, FALSE), convert (ctx, lhs, LLVMInt32Type ()), dname);
4751 guint64 v = 0xffffffffffffffffLL;
4752 values [ins->dreg] = LLVMBuildXor (builder, LLVMConstInt (LLVMInt64Type (), v, FALSE), lhs, dname);
4755 #if defined(TARGET_X86) || defined(TARGET_AMD64)
4757 LLVMValueRef v1, v2;
4759 v1 = LLVMBuildMul (builder, convert (ctx, rhs, IntPtrType ()), LLVMConstInt (IntPtrType (), (1 << ins->backend.shift_amount), FALSE), "");
4760 v2 = LLVMBuildAdd (builder, convert (ctx, lhs, IntPtrType ()), v1, "");
4761 values [ins->dreg] = LLVMBuildAdd (builder, v2, LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE), dname);
4766 case OP_ICONV_TO_I1:
4767 case OP_ICONV_TO_I2:
4768 case OP_ICONV_TO_I4:
4769 case OP_ICONV_TO_U1:
4770 case OP_ICONV_TO_U2:
4771 case OP_ICONV_TO_U4:
4772 case OP_LCONV_TO_I1:
4773 case OP_LCONV_TO_I2:
4774 case OP_LCONV_TO_U1:
4775 case OP_LCONV_TO_U2:
4776 case OP_LCONV_TO_U4: {
4779 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);
4781 /* Have to do two casts since our vregs have type int */
4782 v = LLVMBuildTrunc (builder, lhs, op_to_llvm_type (ins->opcode), "");
4784 values [ins->dreg] = LLVMBuildSExt (builder, v, LLVMInt32Type (), dname);
4786 values [ins->dreg] = LLVMBuildZExt (builder, v, LLVMInt32Type (), dname);
4789 case OP_ICONV_TO_I8:
4790 values [ins->dreg] = LLVMBuildSExt (builder, lhs, LLVMInt64Type (), dname);
4792 case OP_ICONV_TO_U8:
4793 values [ins->dreg] = LLVMBuildZExt (builder, lhs, LLVMInt64Type (), dname);
4795 case OP_FCONV_TO_I4:
4796 case OP_RCONV_TO_I4:
4797 values [ins->dreg] = LLVMBuildFPToSI (builder, lhs, LLVMInt32Type (), dname);
4799 case OP_FCONV_TO_I1:
4800 case OP_RCONV_TO_I1:
4801 values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildFPToSI (builder, lhs, LLVMInt8Type (), dname), LLVMInt32Type (), "");
4803 case OP_FCONV_TO_U1:
4804 case OP_RCONV_TO_U1:
4805 values [ins->dreg] = LLVMBuildZExt (builder, LLVMBuildFPToUI (builder, lhs, LLVMInt8Type (), dname), LLVMInt32Type (), "");
4807 case OP_FCONV_TO_I2:
4808 case OP_RCONV_TO_I2:
4809 values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildFPToSI (builder, lhs, LLVMInt16Type (), dname), LLVMInt32Type (), "");
4811 case OP_FCONV_TO_U2:
4812 case OP_RCONV_TO_U2:
4813 values [ins->dreg] = LLVMBuildZExt (builder, LLVMBuildFPToUI (builder, lhs, LLVMInt16Type (), dname), LLVMInt32Type (), "");
4815 case OP_RCONV_TO_U4:
4816 values [ins->dreg] = LLVMBuildFPToUI (builder, lhs, LLVMInt32Type (), dname);
4818 case OP_FCONV_TO_I8:
4819 case OP_RCONV_TO_I8:
4820 values [ins->dreg] = LLVMBuildFPToSI (builder, lhs, LLVMInt64Type (), dname);
4823 values [ins->dreg] = LLVMBuildFPToSI (builder, lhs, IntPtrType (), dname);
4825 case OP_ICONV_TO_R8:
4826 case OP_LCONV_TO_R8:
4827 values [ins->dreg] = LLVMBuildSIToFP (builder, lhs, LLVMDoubleType (), dname);
4829 case OP_ICONV_TO_R_UN:
4830 case OP_LCONV_TO_R_UN:
4831 values [ins->dreg] = LLVMBuildUIToFP (builder, lhs, LLVMDoubleType (), dname);
4833 #if SIZEOF_VOID_P == 4
4836 case OP_LCONV_TO_I4:
4837 values [ins->dreg] = LLVMBuildTrunc (builder, lhs, LLVMInt32Type (), dname);
4839 case OP_ICONV_TO_R4:
4840 case OP_LCONV_TO_R4:
4841 v = LLVMBuildSIToFP (builder, lhs, LLVMFloatType (), "");
4843 values [ins->dreg] = v;
4845 values [ins->dreg] = LLVMBuildFPExt (builder, v, LLVMDoubleType (), dname);
4847 case OP_FCONV_TO_R4:
4848 v = LLVMBuildFPTrunc (builder, lhs, LLVMFloatType (), "");
4850 values [ins->dreg] = v;
4852 values [ins->dreg] = LLVMBuildFPExt (builder, v, LLVMDoubleType (), dname);
4854 case OP_RCONV_TO_R8:
4855 values [ins->dreg] = LLVMBuildFPExt (builder, lhs, LLVMDoubleType (), dname);
4857 case OP_RCONV_TO_R4:
4858 values [ins->dreg] = lhs;
4861 values [ins->dreg] = LLVMBuildSExt (builder, convert (ctx, lhs, LLVMInt32Type ()), LLVMInt64Type (), dname);
4864 values [ins->dreg] = LLVMBuildZExt (builder, convert (ctx, lhs, LLVMInt32Type ()), LLVMInt64Type (), dname);
4867 values [ins->dreg] = LLVMBuildTrunc (builder, lhs, LLVMInt32Type (), dname);
4869 case OP_LOCALLOC_IMM: {
4872 guint32 size = ins->inst_imm;
4873 size = (size + (MONO_ARCH_FRAME_ALIGNMENT - 1)) & ~ (MONO_ARCH_FRAME_ALIGNMENT - 1);
4875 v = mono_llvm_build_alloca (builder, LLVMInt8Type (), LLVMConstInt (LLVMInt32Type (), size, FALSE), MONO_ARCH_FRAME_ALIGNMENT, "");
4877 if (ins->flags & MONO_INST_INIT) {
4878 LLVMValueRef args [5];
4881 args [1] = LLVMConstInt (LLVMInt8Type (), 0, FALSE);
4882 args [2] = LLVMConstInt (LLVMInt32Type (), size, FALSE);
4883 args [3] = LLVMConstInt (LLVMInt32Type (), MONO_ARCH_FRAME_ALIGNMENT, FALSE);
4884 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
4885 LLVMBuildCall (builder, LLVMGetNamedFunction (lmodule, memset_func_name), args, memset_param_count, "");
4888 values [ins->dreg] = v;
4892 LLVMValueRef v, size;
4894 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), "");
4896 v = mono_llvm_build_alloca (builder, LLVMInt8Type (), size, MONO_ARCH_FRAME_ALIGNMENT, "");
4898 if (ins->flags & MONO_INST_INIT) {
4899 LLVMValueRef args [5];
4902 args [1] = LLVMConstInt (LLVMInt8Type (), 0, FALSE);
4904 args [3] = LLVMConstInt (LLVMInt32Type (), MONO_ARCH_FRAME_ALIGNMENT, FALSE);
4905 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
4906 LLVMBuildCall (builder, LLVMGetNamedFunction (lmodule, memset_func_name), args, memset_param_count, "");
4908 values [ins->dreg] = v;
4912 case OP_LOADI1_MEMBASE:
4913 case OP_LOADU1_MEMBASE:
4914 case OP_LOADI2_MEMBASE:
4915 case OP_LOADU2_MEMBASE:
4916 case OP_LOADI4_MEMBASE:
4917 case OP_LOADU4_MEMBASE:
4918 case OP_LOADI8_MEMBASE:
4919 case OP_LOADR4_MEMBASE:
4920 case OP_LOADR8_MEMBASE:
4921 case OP_LOAD_MEMBASE:
4929 LLVMValueRef base, index, addr;
4931 gboolean sext = FALSE, zext = FALSE;
4932 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
4934 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
4939 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)) {
4940 addr = LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE);
4945 if (ins->inst_offset == 0) {
4947 } else if (ins->inst_offset % size != 0) {
4948 /* Unaligned load */
4949 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset, FALSE);
4950 addr = LLVMBuildGEP (builder, convert (ctx, base, LLVMPointerType (LLVMInt8Type (), 0)), &index, 1, "");
4952 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
4953 addr = LLVMBuildGEP (builder, convert (ctx, base, LLVMPointerType (t, 0)), &index, 1, "");
4957 addr = convert (ctx, addr, LLVMPointerType (t, 0));
4959 values [ins->dreg] = emit_load (ctx, bb, &builder, size, addr, dname, is_volatile);
4961 if (!is_volatile && (ins->flags & MONO_INST_INVARIANT_LOAD)) {
4963 * These will signal LLVM that these loads do not alias any stores, and
4964 * they can't fail, allowing them to be hoisted out of loops.
4966 set_invariant_load_flag (values [ins->dreg]);
4967 set_metadata_flag (values [ins->dreg], "mono.nofail.load");
4971 values [ins->dreg] = LLVMBuildSExt (builder, values [ins->dreg], LLVMInt32Type (), dname);
4973 values [ins->dreg] = LLVMBuildZExt (builder, values [ins->dreg], LLVMInt32Type (), dname);
4974 else if (!cfg->r4fp && ins->opcode == OP_LOADR4_MEMBASE)
4975 values [ins->dreg] = LLVMBuildFPExt (builder, values [ins->dreg], LLVMDoubleType (), dname);
4979 case OP_STOREI1_MEMBASE_REG:
4980 case OP_STOREI2_MEMBASE_REG:
4981 case OP_STOREI4_MEMBASE_REG:
4982 case OP_STOREI8_MEMBASE_REG:
4983 case OP_STORER4_MEMBASE_REG:
4984 case OP_STORER8_MEMBASE_REG:
4985 case OP_STORE_MEMBASE_REG: {
4987 LLVMValueRef index, addr;
4989 gboolean sext = FALSE, zext = FALSE;
4990 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
4992 if (!values [ins->inst_destbasereg])
4993 LLVM_FAILURE (ctx, "inst_destbasereg");
4995 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
4997 if (ins->inst_offset % size != 0) {
4998 /* Unaligned store */
4999 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset, FALSE);
5000 addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (LLVMInt8Type (), 0)), &index, 1, "");
5002 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
5003 addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (t, 0)), &index, 1, "");
5005 emit_store (ctx, bb, &builder, size, convert (ctx, values [ins->sreg1], t), convert (ctx, addr, LLVMPointerType (t, 0)), is_volatile);
5009 case OP_STOREI1_MEMBASE_IMM:
5010 case OP_STOREI2_MEMBASE_IMM:
5011 case OP_STOREI4_MEMBASE_IMM:
5012 case OP_STOREI8_MEMBASE_IMM:
5013 case OP_STORE_MEMBASE_IMM: {
5015 LLVMValueRef index, addr;
5017 gboolean sext = FALSE, zext = FALSE;
5018 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
5020 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
5022 if (ins->inst_offset % size != 0) {
5023 /* Unaligned store */
5024 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset, FALSE);
5025 addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (LLVMInt8Type (), 0)), &index, 1, "");
5027 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
5028 addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (t, 0)), &index, 1, "");
5030 emit_store (ctx, bb, &builder, size, convert (ctx, LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE), t), convert (ctx, addr, LLVMPointerType (t, 0)), is_volatile);
5035 emit_load (ctx, bb, &builder, sizeof (gpointer), convert (ctx, lhs, LLVMPointerType (IntPtrType (), 0)), "", TRUE);
5037 case OP_OUTARG_VTRETADDR:
5045 case OP_VOIDCALL_MEMBASE:
5046 case OP_CALL_MEMBASE:
5047 case OP_LCALL_MEMBASE:
5048 case OP_FCALL_MEMBASE:
5049 case OP_RCALL_MEMBASE:
5050 case OP_VCALL_MEMBASE:
5051 case OP_VOIDCALL_REG:
5056 case OP_VCALL_REG: {
5057 process_call (ctx, bb, &builder, ins);
5058 CHECK_FAILURE (ctx);
5063 LLVMValueRef indexes [2];
5064 MonoJumpInfo *tmp_ji, *ji;
5065 LLVMValueRef got_entry_addr;
5069 * FIXME: Can't allocate from the cfg mempool since that is freed if
5070 * the LLVM compile fails.
5072 tmp_ji = g_new0 (MonoJumpInfo, 1);
5073 tmp_ji->type = (MonoJumpInfoType)ins->inst_c1;
5074 tmp_ji->data.target = ins->inst_p0;
5076 ji = mono_aot_patch_info_dup (tmp_ji);
5079 ji->next = cfg->patch_info;
5080 cfg->patch_info = ji;
5082 //mono_add_patch_info (cfg, 0, (MonoJumpInfoType)ins->inst_i1, ins->inst_p0);
5083 got_offset = mono_aot_get_got_offset (cfg->patch_info);
5084 ctx->module->max_got_offset = MAX (ctx->module->max_got_offset, got_offset);
5085 if (!mono_aot_is_shared_got_offset (got_offset)) {
5086 //mono_print_ji (ji);
5088 ctx->has_got_access = TRUE;
5091 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
5092 indexes [1] = LLVMConstInt (LLVMInt32Type (), (gssize)got_offset, FALSE);
5093 got_entry_addr = LLVMBuildGEP (builder, ctx->module->got_var, indexes, 2, "");
5095 name = get_aotconst_name (ji->type, ji->data.target, got_offset);
5096 values [ins->dreg] = LLVMBuildLoad (builder, got_entry_addr, name);
5098 set_invariant_load_flag (values [ins->dreg]);
5101 case OP_NOT_REACHED:
5102 LLVMBuildUnreachable (builder);
5103 has_terminator = TRUE;
5104 g_assert (bb->block_num < cfg->max_block_num);
5105 ctx->unreachable [bb->block_num] = TRUE;
5106 /* Might have instructions after this */
5108 MonoInst *next = ins->next;
5110 * FIXME: If later code uses the regs defined by these instructions,
5111 * compilation will fail.
5113 MONO_DELETE_INS (bb, next);
5117 MonoInst *var = ins->inst_i0;
5119 if (var->opcode == OP_VTARG_ADDR) {
5120 /* The variable contains the vtype address */
5121 values [ins->dreg] = values [var->dreg];
5122 } else if (var->opcode == OP_GSHAREDVT_LOCAL) {
5123 values [ins->dreg] = emit_gsharedvt_ldaddr (ctx, var->dreg);
5125 values [ins->dreg] = addresses [var->dreg];
5130 LLVMValueRef args [1];
5132 args [0] = convert (ctx, lhs, LLVMDoubleType ());
5133 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (lmodule, "llvm.sin.f64"), args, 1, dname);
5137 LLVMValueRef args [1];
5139 args [0] = convert (ctx, lhs, LLVMDoubleType ());
5140 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (lmodule, "llvm.cos.f64"), args, 1, dname);
5144 LLVMValueRef args [1];
5147 /* This no longer seems to happen */
5149 * LLVM optimizes sqrt(nan) into undefined in
5150 * lib/Analysis/ConstantFolding.cpp
5151 * Also, sqrt(NegativeInfinity) is optimized into 0.
5153 LLVM_FAILURE (ctx, "sqrt");
5155 args [0] = convert (ctx, lhs, LLVMDoubleType ());
5156 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (lmodule, "llvm.sqrt.f64"), args, 1, dname);
5160 LLVMValueRef args [1];
5162 args [0] = convert (ctx, lhs, LLVMDoubleType ());
5163 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (lmodule, "fabs"), args, 1, dname);
5177 lhs = convert (ctx, lhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
5178 rhs = convert (ctx, rhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
5180 switch (ins->opcode) {
5183 v = LLVMBuildICmp (builder, LLVMIntSLE, lhs, rhs, "");
5187 v = LLVMBuildICmp (builder, LLVMIntSGE, lhs, rhs, "");
5191 v = LLVMBuildICmp (builder, LLVMIntULE, lhs, rhs, "");
5195 v = LLVMBuildICmp (builder, LLVMIntUGE, lhs, rhs, "");
5198 g_assert_not_reached ();
5201 values [ins->dreg] = LLVMBuildSelect (builder, v, lhs, rhs, dname);
5204 case OP_ATOMIC_EXCHANGE_I4:
5205 case OP_ATOMIC_EXCHANGE_I8: {
5206 LLVMValueRef args [2];
5209 if (ins->opcode == OP_ATOMIC_EXCHANGE_I4)
5210 t = LLVMInt32Type ();
5212 t = LLVMInt64Type ();
5214 g_assert (ins->inst_offset == 0);
5216 args [0] = convert (ctx, lhs, LLVMPointerType (t, 0));
5217 args [1] = convert (ctx, rhs, t);
5219 values [ins->dreg] = mono_llvm_build_atomic_rmw (builder, LLVM_ATOMICRMW_OP_XCHG, args [0], args [1]);
5222 case OP_ATOMIC_ADD_I4:
5223 case OP_ATOMIC_ADD_I8: {
5224 LLVMValueRef args [2];
5227 if (ins->opcode == OP_ATOMIC_ADD_I4)
5228 t = LLVMInt32Type ();
5230 t = LLVMInt64Type ();
5232 g_assert (ins->inst_offset == 0);
5234 args [0] = convert (ctx, lhs, LLVMPointerType (t, 0));
5235 args [1] = convert (ctx, rhs, t);
5236 values [ins->dreg] = LLVMBuildAdd (builder, mono_llvm_build_atomic_rmw (builder, LLVM_ATOMICRMW_OP_ADD, args [0], args [1]), args [1], dname);
5239 case OP_ATOMIC_CAS_I4:
5240 case OP_ATOMIC_CAS_I8: {
5241 LLVMValueRef args [3], val;
5244 if (ins->opcode == OP_ATOMIC_CAS_I4)
5245 t = LLVMInt32Type ();
5247 t = LLVMInt64Type ();
5249 args [0] = convert (ctx, lhs, LLVMPointerType (t, 0));
5251 args [1] = convert (ctx, values [ins->sreg3], t);
5253 args [2] = convert (ctx, values [ins->sreg2], t);
5254 val = mono_llvm_build_cmpxchg (builder, args [0], args [1], args [2]);
5255 /* cmpxchg returns a pair */
5256 values [ins->dreg] = LLVMBuildExtractValue (builder, val, 0, "");
5259 case OP_MEMORY_BARRIER: {
5260 mono_llvm_build_fence (builder, (BarrierKind) ins->backend.memory_barrier_kind);
5263 case OP_ATOMIC_LOAD_I1:
5264 case OP_ATOMIC_LOAD_I2:
5265 case OP_ATOMIC_LOAD_I4:
5266 case OP_ATOMIC_LOAD_I8:
5267 case OP_ATOMIC_LOAD_U1:
5268 case OP_ATOMIC_LOAD_U2:
5269 case OP_ATOMIC_LOAD_U4:
5270 case OP_ATOMIC_LOAD_U8:
5271 case OP_ATOMIC_LOAD_R4:
5272 case OP_ATOMIC_LOAD_R8: {
5273 LLVM_FAILURE (ctx, "atomic mono.load intrinsic");
5276 gboolean sext, zext;
5278 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
5279 BarrierKind barrier = (BarrierKind) ins->backend.memory_barrier_kind;
5280 LLVMValueRef index, addr;
5282 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
5287 if (ins->inst_offset != 0) {
5288 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
5289 addr = LLVMBuildGEP (builder, convert (ctx, lhs, LLVMPointerType (t, 0)), &index, 1, "");
5294 addr = convert (ctx, addr, LLVMPointerType (t, 0));
5296 values [ins->dreg] = emit_load_general (ctx, bb, &builder, size, addr, dname, is_volatile, barrier);
5299 values [ins->dreg] = LLVMBuildSExt (builder, values [ins->dreg], LLVMInt32Type (), dname);
5301 values [ins->dreg] = LLVMBuildZExt (builder, values [ins->dreg], LLVMInt32Type (), dname);
5304 case OP_ATOMIC_STORE_I1:
5305 case OP_ATOMIC_STORE_I2:
5306 case OP_ATOMIC_STORE_I4:
5307 case OP_ATOMIC_STORE_I8:
5308 case OP_ATOMIC_STORE_U1:
5309 case OP_ATOMIC_STORE_U2:
5310 case OP_ATOMIC_STORE_U4:
5311 case OP_ATOMIC_STORE_U8:
5312 case OP_ATOMIC_STORE_R4:
5313 case OP_ATOMIC_STORE_R8: {
5314 LLVM_FAILURE (ctx, "atomic mono.store intrinsic");
5317 gboolean sext, zext;
5319 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
5320 BarrierKind barrier = (BarrierKind) ins->backend.memory_barrier_kind;
5321 LLVMValueRef index, addr, value;
5323 if (!values [ins->inst_destbasereg])
5324 LLVM_FAILURE (ctx, "inst_destbasereg");
5326 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
5328 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
5329 addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (t, 0)), &index, 1, "");
5330 value = convert (ctx, values [ins->sreg1], t);
5332 emit_store_general (ctx, bb, &builder, size, value, addr, is_volatile, barrier);
5335 case OP_RELAXED_NOP: {
5336 #if defined(TARGET_AMD64) || defined(TARGET_X86)
5337 emit_call (ctx, bb, &builder, LLVMGetNamedFunction (ctx->lmodule, "llvm.x86.sse2.pause"), NULL, 0);
5344 #if (defined(TARGET_AMD64) || defined(TARGET_X86)) && defined(__linux__)
5346 // 257 == FS segment register
5347 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 257);
5349 // 256 == GS segment register
5350 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 256);
5353 values [ins->dreg] = LLVMBuildLoad (builder, LLVMBuildIntToPtr (builder, LLVMConstInt (IntPtrType (), ins->inst_offset, TRUE), ptrtype, ""), "");
5354 #elif defined(TARGET_AMD64) && defined(TARGET_OSX)
5355 /* See mono_amd64_emit_tls_get () */
5356 int offset = mono_amd64_get_tls_gs_offset () + (ins->inst_offset * 8);
5358 // 256 == GS segment register
5359 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 256);
5360 values [ins->dreg] = LLVMBuildLoad (builder, LLVMBuildIntToPtr (builder, LLVMConstInt (IntPtrType (), offset, TRUE), ptrtype, ""), "");
5362 LLVM_FAILURE (ctx, "opcode tls-get");
5367 case OP_TLS_GET_REG: {
5368 #if defined(TARGET_AMD64) && defined(TARGET_OSX)
5369 /* See emit_tls_get_reg () */
5370 // 256 == GS segment register
5371 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 256);
5372 values [ins->dreg] = LLVMBuildLoad (builder, LLVMBuildIntToPtr (builder, convert (ctx, lhs, LLVMInt32Type ()), ptrtype, ""), "");
5374 LLVM_FAILURE (ctx, "opcode tls-get");
5379 case OP_TLS_SET_REG: {
5380 #if defined(TARGET_AMD64) && defined(TARGET_OSX)
5381 /* See emit_tls_get_reg () */
5382 // 256 == GS segment register
5383 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 256);
5384 LLVMBuildStore (builder, convert (ctx, lhs, IntPtrType ()), LLVMBuildIntToPtr (builder, convert (ctx, rhs, LLVMInt32Type ()), ptrtype, ""));
5386 LLVM_FAILURE (ctx, "opcode tls-set-reg");
5395 case OP_IADD_OVF_UN:
5397 case OP_ISUB_OVF_UN:
5399 case OP_IMUL_OVF_UN:
5400 #if SIZEOF_VOID_P == 8
5402 case OP_LADD_OVF_UN:
5404 case OP_LSUB_OVF_UN:
5406 case OP_LMUL_OVF_UN:
5409 LLVMValueRef args [2], val, ovf, func;
5411 args [0] = convert (ctx, lhs, op_to_llvm_type (ins->opcode));
5412 args [1] = convert (ctx, rhs, op_to_llvm_type (ins->opcode));
5413 func = LLVMGetNamedFunction (lmodule, ovf_op_to_intrins (ins->opcode));
5415 val = LLVMBuildCall (builder, func, args, 2, "");
5416 values [ins->dreg] = LLVMBuildExtractValue (builder, val, 0, dname);
5417 ovf = LLVMBuildExtractValue (builder, val, 1, "");
5418 emit_cond_system_exception (ctx, bb, "OverflowException", ovf);
5419 CHECK_FAILURE (ctx);
5420 builder = ctx->builder;
5426 * We currently model them using arrays. Promotion to local vregs is
5427 * disabled for them in mono_handle_global_vregs () in the LLVM case,
5428 * so we always have an entry in cfg->varinfo for them.
5429 * FIXME: Is this needed ?
5432 MonoClass *klass = ins->klass;
5433 LLVMValueRef args [5];
5437 LLVM_FAILURE (ctx, "!klass");
5441 if (!addresses [ins->dreg])
5442 addresses [ins->dreg] = build_alloca (ctx, &klass->byval_arg);
5443 args [0] = LLVMBuildBitCast (builder, addresses [ins->dreg], LLVMPointerType (LLVMInt8Type (), 0), "");
5444 args [1] = LLVMConstInt (LLVMInt8Type (), 0, FALSE);
5445 args [2] = LLVMConstInt (LLVMInt32Type (), mono_class_value_size (klass, NULL), FALSE);
5447 args [3] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
5448 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
5449 LLVMBuildCall (builder, LLVMGetNamedFunction (lmodule, memset_func_name), args, memset_param_count, "");
5452 case OP_DUMMY_VZERO:
5455 case OP_STOREV_MEMBASE:
5456 case OP_LOADV_MEMBASE:
5458 MonoClass *klass = ins->klass;
5459 LLVMValueRef src = NULL, dst, args [5];
5460 gboolean done = FALSE;
5464 LLVM_FAILURE (ctx, "!klass");
5468 if (mini_is_gsharedvt_klass (klass)) {
5470 LLVM_FAILURE (ctx, "gsharedvt");
5474 switch (ins->opcode) {
5475 case OP_STOREV_MEMBASE:
5476 if (cfg->gen_write_barriers && klass->has_references && ins->inst_destbasereg != cfg->frame_reg &&
5477 LLVMGetInstructionOpcode (values [ins->inst_destbasereg]) != LLVMAlloca) {
5478 /* Decomposed earlier */
5479 g_assert_not_reached ();
5482 if (!addresses [ins->sreg1]) {
5484 g_assert (values [ins->sreg1]);
5485 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));
5486 LLVMBuildStore (builder, values [ins->sreg1], dst);
5489 src = LLVMBuildBitCast (builder, addresses [ins->sreg1], LLVMPointerType (LLVMInt8Type (), 0), "");
5490 dst = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_destbasereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (LLVMInt8Type (), 0));
5493 case OP_LOADV_MEMBASE:
5494 if (!addresses [ins->dreg])
5495 addresses [ins->dreg] = build_alloca (ctx, &klass->byval_arg);
5496 src = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_basereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (LLVMInt8Type (), 0));
5497 dst = LLVMBuildBitCast (builder, addresses [ins->dreg], LLVMPointerType (LLVMInt8Type (), 0), "");
5500 if (!addresses [ins->sreg1])
5501 addresses [ins->sreg1] = build_alloca (ctx, &klass->byval_arg);
5502 if (!addresses [ins->dreg])
5503 addresses [ins->dreg] = build_alloca (ctx, &klass->byval_arg);
5504 src = LLVMBuildBitCast (builder, addresses [ins->sreg1], LLVMPointerType (LLVMInt8Type (), 0), "");
5505 dst = LLVMBuildBitCast (builder, addresses [ins->dreg], LLVMPointerType (LLVMInt8Type (), 0), "");
5508 g_assert_not_reached ();
5510 CHECK_FAILURE (ctx);
5517 args [2] = LLVMConstInt (LLVMInt32Type (), mono_class_value_size (klass, NULL), FALSE);
5518 args [3] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
5520 args [3] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
5521 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
5522 LLVMBuildCall (builder, LLVMGetNamedFunction (lmodule, memcpy_func_name), args, memcpy_param_count, "");
5525 case OP_LLVM_OUTARG_VT: {
5526 LLVMArgInfo *ainfo = (LLVMArgInfo*)ins->inst_p0;
5527 MonoType *t = mini_get_underlying_type (ins->inst_vtype);
5529 if (ainfo->storage == LLVMArgScalarByRef) {
5530 LLVMTypeRef argtype;
5531 LLVMValueRef loc, v;
5533 argtype = type_to_llvm_arg_type (ctx, t);
5534 loc = build_alloca_llvm_type (ctx, argtype, 0);
5535 v = convert (ctx, values [ins->sreg1], argtype);
5536 LLVMBuildStore (ctx->builder, v, loc);
5537 addresses [ins->dreg] = loc;
5538 } else if (ainfo->storage == LLVMArgGsharedvtVariable) {
5539 MonoInst *var = get_vreg_to_inst (cfg, ins->sreg1);
5541 if (var && var->opcode == OP_GSHAREDVT_LOCAL) {
5542 addresses [ins->dreg] = convert (ctx, emit_gsharedvt_ldaddr (ctx, var->dreg), LLVMPointerType (IntPtrType (), 0));
5544 g_assert (addresses [ins->sreg1]);
5545 addresses [ins->dreg] = addresses [ins->sreg1];
5547 } else if (ainfo->storage == LLVMArgGsharedvtFixed) {
5548 if (!addresses [ins->sreg1]) {
5549 addresses [ins->sreg1] = build_alloca (ctx, t);
5550 g_assert (values [ins->sreg1]);
5552 LLVMBuildStore (builder, convert (ctx, values [ins->sreg1], LLVMGetElementType (LLVMTypeOf (addresses [ins->sreg1]))), addresses [ins->sreg1]);
5553 addresses [ins->dreg] = addresses [ins->sreg1];
5555 if (!addresses [ins->sreg1]) {
5556 addresses [ins->sreg1] = build_alloca (ctx, t);
5557 g_assert (values [ins->sreg1]);
5558 LLVMBuildStore (builder, convert (ctx, values [ins->sreg1], type_to_llvm_type (ctx, t)), addresses [ins->sreg1]);
5560 addresses [ins->dreg] = addresses [ins->sreg1];
5568 #if defined(TARGET_X86) || defined(TARGET_AMD64)
5570 values [ins->dreg] = LLVMConstNull (type_to_llvm_type (ctx, &ins->klass->byval_arg));
5573 case OP_LOADX_MEMBASE: {
5574 LLVMTypeRef t = type_to_llvm_type (ctx, &ins->klass->byval_arg);
5577 src = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_basereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (t, 0));
5578 values [ins->dreg] = mono_llvm_build_aligned_load (builder, src, "", FALSE, 1);
5581 case OP_STOREX_MEMBASE: {
5582 LLVMTypeRef t = LLVMTypeOf (values [ins->sreg1]);
5585 dest = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_destbasereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (t, 0));
5586 mono_llvm_build_aligned_store (builder, values [ins->sreg1], dest, FALSE, 1);
5593 values [ins->dreg] = LLVMBuildAdd (builder, lhs, rhs, "");
5597 values [ins->dreg] = LLVMBuildFAdd (builder, lhs, rhs, "");
5603 values [ins->dreg] = LLVMBuildSub (builder, lhs, rhs, "");
5607 values [ins->dreg] = LLVMBuildFSub (builder, lhs, rhs, "");
5611 values [ins->dreg] = LLVMBuildFMul (builder, lhs, rhs, "");
5615 values [ins->dreg] = LLVMBuildFDiv (builder, lhs, rhs, "");
5618 values [ins->dreg] = LLVMBuildAnd (builder, lhs, rhs, "");
5621 values [ins->dreg] = LLVMBuildOr (builder, lhs, rhs, "");
5624 values [ins->dreg] = LLVMBuildXor (builder, lhs, rhs, "");
5628 values [ins->dreg] = LLVMBuildMul (builder, lhs, rhs, "");
5639 LLVMValueRef v = NULL;
5641 switch (ins->opcode) {
5646 t = LLVMVectorType (LLVMInt32Type (), 4);
5647 rt = LLVMVectorType (LLVMFloatType (), 4);
5653 t = LLVMVectorType (LLVMInt64Type (), 2);
5654 rt = LLVMVectorType (LLVMDoubleType (), 2);
5657 t = LLVMInt32Type ();
5658 rt = LLVMInt32Type ();
5659 g_assert_not_reached ();
5662 lhs = LLVMBuildBitCast (builder, lhs, t, "");
5663 rhs = LLVMBuildBitCast (builder, rhs, t, "");
5664 switch (ins->opcode) {
5667 v = LLVMBuildAnd (builder, lhs, rhs, "");
5671 v = LLVMBuildOr (builder, lhs, rhs, "");
5675 v = LLVMBuildXor (builder, lhs, rhs, "");
5679 v = LLVMBuildAnd (builder, rhs, LLVMBuildNot (builder, lhs, ""), "");
5682 values [ins->dreg] = LLVMBuildBitCast (builder, v, rt, "");
5706 case OP_PADDB_SAT_UN:
5707 case OP_PADDW_SAT_UN:
5708 case OP_PSUBB_SAT_UN:
5709 case OP_PSUBW_SAT_UN:
5717 case OP_PMULW_HIGH_UN: {
5718 LLVMValueRef args [2];
5723 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (lmodule, simd_op_to_intrins (ins->opcode)), args, 2, dname);
5730 values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildICmp (builder, LLVMIntEQ, lhs, rhs, ""), LLVMTypeOf (lhs), "");
5734 values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildICmp (builder, LLVMIntSGT, lhs, rhs, ""), LLVMTypeOf (lhs), "");
5742 case OP_EXTRACTX_U2:
5744 case OP_EXTRACT_U1: {
5746 gboolean zext = FALSE;
5748 t = simd_op_to_llvm_type (ins->opcode);
5750 switch (ins->opcode) {
5758 case OP_EXTRACTX_U2:
5763 t = LLVMInt32Type ();
5764 g_assert_not_reached ();
5767 lhs = LLVMBuildBitCast (builder, lhs, t, "");
5768 values [ins->dreg] = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), "");
5770 values [ins->dreg] = LLVMBuildZExt (builder, values [ins->dreg], LLVMInt32Type (), "");
5779 case OP_EXPAND_R8: {
5780 LLVMTypeRef t = simd_op_to_llvm_type (ins->opcode);
5781 LLVMValueRef mask [16], v;
5784 for (i = 0; i < 16; ++i)
5785 mask [i] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
5787 v = convert (ctx, values [ins->sreg1], LLVMGetElementType (t));
5789 values [ins->dreg] = LLVMBuildInsertElement (builder, LLVMConstNull (t), v, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
5790 values [ins->dreg] = LLVMBuildShuffleVector (builder, values [ins->dreg], LLVMGetUndef (t), LLVMConstVector (mask, LLVMGetVectorSize (t)), "");
5795 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt8Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
5798 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt16Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
5801 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt32Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
5804 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt64Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
5807 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMFloatType ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
5810 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMDoubleType ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
5821 case OP_EXTRACT_MASK:
5828 v = convert (ctx, values [ins->sreg1], simd_op_to_llvm_type (ins->opcode));
5830 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (lmodule, simd_op_to_intrins (ins->opcode)), &v, 1, dname);
5836 LLVMValueRef args [3];
5840 args [2] = LLVMConstInt (LLVMInt8Type (), ins->inst_c0, FALSE);
5842 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (lmodule, simd_op_to_intrins (ins->opcode)), args, 3, dname);
5847 /* This is only used for implementing shifts by non-immediate */
5848 values [ins->dreg] = lhs;
5859 LLVMValueRef args [3];
5862 args [1] = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
5864 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (lmodule, simd_op_to_intrins (ins->opcode)), args, 2, dname);
5875 case OP_PSHLQ_REG: {
5876 LLVMValueRef args [3];
5879 args [1] = values [ins->sreg2];
5881 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (lmodule, simd_op_to_intrins (ins->opcode)), args, 2, dname);
5888 case OP_PSHUFLEW_LOW:
5889 case OP_PSHUFLEW_HIGH: {
5891 LLVMValueRef v1 = NULL, v2 = NULL, mask_values [16];
5892 int i, mask_size = 0;
5893 int imask = ins->inst_c0;
5895 /* Convert the x86 shuffle mask to LLVM's */
5896 switch (ins->opcode) {
5899 mask [0] = ((imask >> 0) & 3);
5900 mask [1] = ((imask >> 2) & 3);
5901 mask [2] = ((imask >> 4) & 3) + 4;
5902 mask [3] = ((imask >> 6) & 3) + 4;
5903 v1 = values [ins->sreg1];
5904 v2 = values [ins->sreg2];
5908 mask [0] = ((imask >> 0) & 1);
5909 mask [1] = ((imask >> 1) & 1) + 2;
5910 v1 = values [ins->sreg1];
5911 v2 = values [ins->sreg2];
5913 case OP_PSHUFLEW_LOW:
5915 mask [0] = ((imask >> 0) & 3);
5916 mask [1] = ((imask >> 2) & 3);
5917 mask [2] = ((imask >> 4) & 3);
5918 mask [3] = ((imask >> 6) & 3);
5923 v1 = values [ins->sreg1];
5924 v2 = LLVMGetUndef (LLVMTypeOf (v1));
5926 case OP_PSHUFLEW_HIGH:
5932 mask [4] = 4 + ((imask >> 0) & 3);
5933 mask [5] = 4 + ((imask >> 2) & 3);
5934 mask [6] = 4 + ((imask >> 4) & 3);
5935 mask [7] = 4 + ((imask >> 6) & 3);
5936 v1 = values [ins->sreg1];
5937 v2 = LLVMGetUndef (LLVMTypeOf (v1));
5941 mask [0] = ((imask >> 0) & 3);
5942 mask [1] = ((imask >> 2) & 3);
5943 mask [2] = ((imask >> 4) & 3);
5944 mask [3] = ((imask >> 6) & 3);
5945 v1 = values [ins->sreg1];
5946 v2 = LLVMGetUndef (LLVMTypeOf (v1));
5949 g_assert_not_reached ();
5951 for (i = 0; i < mask_size; ++i)
5952 mask_values [i] = LLVMConstInt (LLVMInt32Type (), mask [i], FALSE);
5954 values [ins->dreg] =
5955 LLVMBuildShuffleVector (builder, v1, v2,
5956 LLVMConstVector (mask_values, mask_size), dname);
5960 case OP_UNPACK_LOWB:
5961 case OP_UNPACK_LOWW:
5962 case OP_UNPACK_LOWD:
5963 case OP_UNPACK_LOWQ:
5964 case OP_UNPACK_LOWPS:
5965 case OP_UNPACK_LOWPD:
5966 case OP_UNPACK_HIGHB:
5967 case OP_UNPACK_HIGHW:
5968 case OP_UNPACK_HIGHD:
5969 case OP_UNPACK_HIGHQ:
5970 case OP_UNPACK_HIGHPS:
5971 case OP_UNPACK_HIGHPD: {
5973 LLVMValueRef mask_values [16];
5974 int i, mask_size = 0;
5975 gboolean low = FALSE;
5977 switch (ins->opcode) {
5978 case OP_UNPACK_LOWB:
5982 case OP_UNPACK_LOWW:
5986 case OP_UNPACK_LOWD:
5987 case OP_UNPACK_LOWPS:
5991 case OP_UNPACK_LOWQ:
5992 case OP_UNPACK_LOWPD:
5996 case OP_UNPACK_HIGHB:
5999 case OP_UNPACK_HIGHW:
6002 case OP_UNPACK_HIGHD:
6003 case OP_UNPACK_HIGHPS:
6006 case OP_UNPACK_HIGHQ:
6007 case OP_UNPACK_HIGHPD:
6011 g_assert_not_reached ();
6015 for (i = 0; i < (mask_size / 2); ++i) {
6017 mask [(i * 2) + 1] = mask_size + i;
6020 for (i = 0; i < (mask_size / 2); ++i) {
6021 mask [(i * 2)] = (mask_size / 2) + i;
6022 mask [(i * 2) + 1] = mask_size + (mask_size / 2) + i;
6026 for (i = 0; i < mask_size; ++i)
6027 mask_values [i] = LLVMConstInt (LLVMInt32Type (), mask [i], FALSE);
6029 values [ins->dreg] =
6030 LLVMBuildShuffleVector (builder, values [ins->sreg1], values [ins->sreg2],
6031 LLVMConstVector (mask_values, mask_size), dname);
6036 LLVMTypeRef t = simd_op_to_llvm_type (ins->opcode);
6037 LLVMValueRef v, val;
6039 v = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
6040 val = LLVMConstNull (t);
6041 val = LLVMBuildInsertElement (builder, val, v, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
6042 val = LLVMBuildInsertElement (builder, val, v, LLVMConstInt (LLVMInt32Type (), 1, FALSE), dname);
6044 values [ins->dreg] = val;
6048 case OP_DUPPS_HIGH: {
6049 LLVMTypeRef t = simd_op_to_llvm_type (ins->opcode);
6050 LLVMValueRef v1, v2, val;
6053 if (ins->opcode == OP_DUPPS_LOW) {
6054 v1 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
6055 v2 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 2, FALSE), "");
6057 v1 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 1, FALSE), "");
6058 v2 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 3, FALSE), "");
6060 val = LLVMConstNull (t);
6061 val = LLVMBuildInsertElement (builder, val, v1, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
6062 val = LLVMBuildInsertElement (builder, val, v1, LLVMConstInt (LLVMInt32Type (), 1, FALSE), "");
6063 val = LLVMBuildInsertElement (builder, val, v2, LLVMConstInt (LLVMInt32Type (), 2, FALSE), "");
6064 val = LLVMBuildInsertElement (builder, val, v2, LLVMConstInt (LLVMInt32Type (), 3, FALSE), "");
6066 values [ins->dreg] = val;
6076 * EXCEPTION HANDLING
6078 case OP_IMPLICIT_EXCEPTION:
6079 /* This marks a place where an implicit exception can happen */
6080 if (bb->region != -1)
6081 LLVM_FAILURE (ctx, "implicit-exception");
6085 gboolean rethrow = (ins->opcode == OP_RETHROW);
6086 if (ctx->llvm_only) {
6087 emit_llvmonly_throw (ctx, bb, rethrow, lhs);
6088 has_terminator = TRUE;
6089 ctx->unreachable [bb->block_num] = TRUE;
6091 emit_throw (ctx, bb, rethrow, lhs);
6092 builder = ctx->builder;
6096 case OP_CALL_HANDLER: {
6098 * We don't 'call' handlers, but instead simply branch to them.
6099 * The code generated by ENDFINALLY will branch back to us.
6101 LLVMBasicBlockRef noex_bb;
6103 BBInfo *info = &bblocks [ins->inst_target_bb->block_num];
6105 bb_list = info->call_handler_return_bbs;
6108 * Set the indicator variable for the finally clause.
6110 lhs = info->finally_ind;
6112 LLVMBuildStore (builder, LLVMConstInt (LLVMInt32Type (), g_slist_length (bb_list) + 1, FALSE), lhs);
6114 /* Branch to the finally clause */
6115 LLVMBuildBr (builder, info->call_handler_target_bb);
6117 noex_bb = gen_bb (ctx, "CALL_HANDLER_CONT_BB");
6118 info->call_handler_return_bbs = g_slist_append_mempool (cfg->mempool, info->call_handler_return_bbs, noex_bb);
6120 builder = ctx->builder = create_builder (ctx);
6121 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
6123 bblocks [bb->block_num].end_bblock = noex_bb;
6126 case OP_START_HANDLER: {
6129 case OP_ENDFINALLY: {
6130 LLVMBasicBlockRef resume_bb;
6131 MonoBasicBlock *handler_bb;
6132 LLVMValueRef val, switch_ins, callee;
6136 handler_bb = (MonoBasicBlock*)g_hash_table_lookup (ctx->region_to_handler, GUINT_TO_POINTER (mono_get_block_region_notry (cfg, bb->region)));
6137 g_assert (handler_bb);
6138 info = &bblocks [handler_bb->block_num];
6139 lhs = info->finally_ind;
6142 bb_list = info->call_handler_return_bbs;
6144 resume_bb = gen_bb (ctx, "ENDFINALLY_RESUME_BB");
6146 /* Load the finally variable */
6147 val = LLVMBuildLoad (builder, lhs, "");
6149 /* Reset the variable */
6150 LLVMBuildStore (builder, LLVMConstInt (LLVMInt32Type (), 0, FALSE), lhs);
6152 /* Branch to either resume_bb, or to the bblocks in bb_list */
6153 switch_ins = LLVMBuildSwitch (builder, val, resume_bb, g_slist_length (bb_list));
6155 * The other targets are added at the end to handle OP_CALL_HANDLER
6156 * opcodes processed later.
6158 info->endfinally_switch_ins_list = g_slist_append_mempool (cfg->mempool, info->endfinally_switch_ins_list, switch_ins);
6160 builder = ctx->builder = create_builder (ctx);
6161 LLVMPositionBuilderAtEnd (ctx->builder, resume_bb);
6163 if (ctx->llvm_only) {
6164 emit_resume_eh (ctx, bb);
6166 if (ctx->cfg->compile_aot) {
6167 callee = get_callee (ctx, LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE), MONO_PATCH_INFO_INTERNAL_METHOD, "llvm_resume_unwind_trampoline");
6169 callee = LLVMGetNamedFunction (lmodule, "llvm_resume_unwind_trampoline");
6171 LLVMBuildCall (builder, callee, NULL, 0, "");
6172 LLVMBuildUnreachable (builder);
6175 has_terminator = TRUE;
6178 case OP_IL_SEQ_POINT:
6183 sprintf (reason, "opcode %s", mono_inst_name (ins->opcode));
6184 LLVM_FAILURE (ctx, reason);
6189 /* Convert the value to the type required by phi nodes */
6190 if (spec [MONO_INST_DEST] != ' ' && !MONO_IS_STORE_MEMBASE (ins) && ctx->vreg_types [ins->dreg]) {
6191 if (!values [ins->dreg])
6193 values [ins->dreg] = addresses [ins->dreg];
6195 values [ins->dreg] = convert (ctx, values [ins->dreg], ctx->vreg_types [ins->dreg]);
6198 /* Add stores for volatile variables */
6199 if (spec [MONO_INST_DEST] != ' ' && spec [MONO_INST_DEST] != 'v' && !MONO_IS_STORE_MEMBASE (ins))
6200 emit_volatile_store (ctx, ins->dreg);
6203 if (!has_terminator && bb->next_bb && (bb == cfg->bb_entry || bb->in_count > 0)) {
6204 LLVMBuildBr (builder, get_bb (ctx, bb->next_bb));
6207 if (bb == cfg->bb_exit && sig->ret->type == MONO_TYPE_VOID) {
6208 emit_dbg_loc (ctx, builder, cfg->header->code + cfg->header->code_size - 1);
6209 LLVMBuildRetVoid (builder);
6212 if (bb == cfg->bb_entry)
6213 ctx->last_alloca = LLVMGetLastInstruction (get_bb (ctx, cfg->bb_entry));
6222 * mono_llvm_check_method_supported:
6224 * Do some quick checks to decide whenever cfg->method can be compiled by LLVM, to avoid
6225 * compiling a method twice.
6228 mono_llvm_check_method_supported (MonoCompile *cfg)
6235 if (cfg->method->save_lmf) {
6236 cfg->exception_message = g_strdup ("lmf");
6237 cfg->disable_llvm = TRUE;
6239 if (cfg->disable_llvm)
6243 * Nested clauses where one of the clauses is a finally clause is
6244 * not supported, because LLVM can't figure out the control flow,
6245 * probably because we resume exception handling by calling our
6246 * own function instead of using the 'resume' llvm instruction.
6248 for (i = 0; i < cfg->header->num_clauses; ++i) {
6249 for (j = 0; j < cfg->header->num_clauses; ++j) {
6250 MonoExceptionClause *clause1 = &cfg->header->clauses [i];
6251 MonoExceptionClause *clause2 = &cfg->header->clauses [j];
6253 // FIXME: Nested try clauses fail in some cases too, i.e. #37273
6254 if (i != j && clause1->try_offset >= clause2->try_offset && clause1->handler_offset <= clause2->handler_offset) {
6255 //(clause1->flags == MONO_EXCEPTION_CLAUSE_FINALLY || clause2->flags == MONO_EXCEPTION_CLAUSE_FINALLY)) {
6256 cfg->exception_message = g_strdup ("nested clauses");
6257 cfg->disable_llvm = TRUE;
6262 if (cfg->disable_llvm)
6266 if (cfg->method->dynamic) {
6267 cfg->exception_message = g_strdup ("dynamic.");
6268 cfg->disable_llvm = TRUE;
6270 if (cfg->disable_llvm)
6274 static LLVMCallInfo*
6275 get_llvm_call_info (MonoCompile *cfg, MonoMethodSignature *sig)
6277 LLVMCallInfo *linfo;
6280 if (cfg->gsharedvt && cfg->llvm_only && mini_is_gsharedvt_variable_signature (sig)) {
6284 * Gsharedvt methods have the following calling convention:
6285 * - all arguments are passed by ref, even non generic ones
6286 * - the return value is returned by ref too, using a vret
6287 * argument passed after 'this'.
6289 n = sig->param_count + sig->hasthis;
6290 linfo = (LLVMCallInfo*)mono_mempool_alloc0 (cfg->mempool, sizeof (LLVMCallInfo) + (sizeof (LLVMArgInfo) * n));
6294 linfo->args [pindex ++].storage = LLVMArgNormal;
6296 if (sig->ret->type != MONO_TYPE_VOID) {
6297 if (mini_is_gsharedvt_variable_type (sig->ret))
6298 linfo->ret.storage = LLVMArgGsharedvtVariable;
6299 else if (mini_type_is_vtype (sig->ret))
6300 linfo->ret.storage = LLVMArgGsharedvtFixedVtype;
6302 linfo->ret.storage = LLVMArgGsharedvtFixed;
6303 linfo->vret_arg_index = pindex;
6305 linfo->ret.storage = LLVMArgNone;
6308 for (i = 0; i < sig->param_count; ++i) {
6309 if (sig->params [i]->byref)
6310 linfo->args [pindex].storage = LLVMArgNormal;
6311 else if (mini_is_gsharedvt_variable_type (sig->params [i]))
6312 linfo->args [pindex].storage = LLVMArgGsharedvtVariable;
6313 else if (mini_type_is_vtype (sig->params [i]))
6314 linfo->args [pindex].storage = LLVMArgGsharedvtFixedVtype;
6316 linfo->args [pindex].storage = LLVMArgGsharedvtFixed;
6317 linfo->args [pindex].type = sig->params [i];
6324 linfo = mono_arch_get_llvm_call_info (cfg, sig);
6325 for (i = 0; i < sig->param_count; ++i)
6326 linfo->args [i + sig->hasthis].type = sig->params [i];
6332 * mono_llvm_emit_method:
6334 * Emit LLVM IL from the mono IL, and compile it to native code using LLVM.
6337 mono_llvm_emit_method (MonoCompile *cfg)
6340 MonoMethodSignature *sig;
6342 LLVMTypeRef method_type;
6343 LLVMValueRef method = NULL;
6345 LLVMValueRef *values;
6346 int i, max_block_num, bb_index;
6347 gboolean last = FALSE, is_linkonce = FALSE;
6348 GPtrArray *phi_values;
6349 LLVMCallInfo *linfo;
6351 LLVMModuleRef lmodule;
6353 GPtrArray *bblock_list;
6354 MonoMethodHeader *header;
6355 MonoExceptionClause *clause;
6358 /* The code below might acquire the loader lock, so use it for global locking */
6359 mono_loader_lock ();
6361 /* Used to communicate with the callbacks */
6362 mono_native_tls_set_value (current_cfg_tls_id, cfg);
6364 ctx = g_new0 (EmitContext, 1);
6366 ctx->mempool = cfg->mempool;
6369 * This maps vregs to the LLVM instruction defining them
6371 values = g_new0 (LLVMValueRef, cfg->next_vreg);
6373 * This maps vregs for volatile variables to the LLVM instruction defining their
6376 ctx->addresses = g_new0 (LLVMValueRef, cfg->next_vreg);
6377 ctx->vreg_types = g_new0 (LLVMTypeRef, cfg->next_vreg);
6378 ctx->vreg_cli_types = g_new0 (MonoType*, cfg->next_vreg);
6379 phi_values = g_ptr_array_sized_new (256);
6381 * This signals whenever the vreg was defined by a phi node with no input vars
6382 * (i.e. all its input bblocks end with NOT_REACHABLE).
6384 ctx->is_dead = g_new0 (gboolean, cfg->next_vreg);
6385 /* Whenever the bblock is unreachable */
6386 ctx->unreachable = g_new0 (gboolean, cfg->max_block_num);
6387 bblock_list = g_ptr_array_sized_new (256);
6389 ctx->values = values;
6390 ctx->region_to_handler = g_hash_table_new (NULL, NULL);
6391 ctx->clause_to_handler = g_hash_table_new (NULL, NULL);
6392 ctx->method_to_callers = g_hash_table_new (NULL, NULL);
6394 if (cfg->compile_aot) {
6395 ctx->module = &aot_module;
6399 * Allow the linker to discard duplicate copies of wrappers, generic instances etc. by using the 'linkonce'
6400 * linkage for them. This requires the following:
6401 * - the method needs to have a unique mangled name
6402 * - llvmonly mode, since the code in aot-runtime.c would initialize got slots in the wrong aot image etc.
6404 is_linkonce = ctx->module->llvm_only && ctx->module->static_link && mono_aot_is_linkonce_method (cfg->method);
6406 method_name = mono_aot_get_mangled_method_name (cfg->method);
6408 is_linkonce = FALSE;
6411 printf ("%s %s\n", mono_method_full_name (cfg->method, 1), method_name);
6413 printf ("%s\n", mono_method_full_name (cfg->method, 1));
6417 method_name = mono_aot_get_method_name (cfg);
6418 cfg->llvm_method_name = g_strdup (method_name);
6420 init_jit_module (cfg->domain);
6421 ctx->module = (MonoLLVMModule*)domain_jit_info (cfg->domain)->llvm_module;
6422 method_name = mono_method_full_name (cfg->method, TRUE);
6425 lmodule = ctx->lmodule = ctx->module->lmodule;
6426 ctx->llvm_only = ctx->module->llvm_only;
6428 if (cfg->gsharedvt && !cfg->llvm_only)
6429 LLVM_FAILURE (ctx, "gsharedvt");
6433 static int count = 0;
6436 if (g_getenv ("LLVM_COUNT")) {
6437 if (count == atoi (g_getenv ("LLVM_COUNT"))) {
6438 printf ("LAST: %s\n", mono_method_full_name (cfg->method, TRUE));
6442 if (count > atoi (g_getenv ("LLVM_COUNT")))
6443 LLVM_FAILURE (ctx, "");
6448 sig = mono_method_signature (cfg->method);
6451 linfo = get_llvm_call_info (cfg, sig);
6453 CHECK_FAILURE (ctx);
6456 linfo->rgctx_arg = TRUE;
6457 method_type = sig_to_llvm_sig_full (ctx, sig, linfo);
6458 CHECK_FAILURE (ctx);
6460 method = LLVMAddFunction (lmodule, method_name, method_type);
6461 ctx->lmethod = method;
6463 if (!cfg->llvm_only)
6464 LLVMSetFunctionCallConv (method, LLVMMono1CallConv);
6465 LLVMSetLinkage (method, LLVMPrivateLinkage);
6467 LLVMAddFunctionAttr (method, LLVMUWTable);
6469 if (cfg->compile_aot) {
6470 LLVMSetLinkage (method, LLVMInternalLinkage);
6471 if (ctx->module->external_symbols) {
6472 LLVMSetLinkage (method, LLVMExternalLinkage);
6473 LLVMSetVisibility (method, LLVMHiddenVisibility);
6476 LLVMSetLinkage (method, LLVMLinkOnceAnyLinkage);
6477 LLVMSetVisibility (method, LLVMDefaultVisibility);
6480 LLVMSetLinkage (method, LLVMPrivateLinkage);
6483 if (cfg->method->save_lmf && !cfg->llvm_only)
6484 LLVM_FAILURE (ctx, "lmf");
6486 if (sig->pinvoke && cfg->method->wrapper_type != MONO_WRAPPER_RUNTIME_INVOKE && !cfg->llvm_only)
6487 LLVM_FAILURE (ctx, "pinvoke signature");
6489 header = cfg->header;
6490 for (i = 0; i < header->num_clauses; ++i) {
6491 clause = &header->clauses [i];
6492 if (clause->flags != MONO_EXCEPTION_CLAUSE_FINALLY && clause->flags != MONO_EXCEPTION_CLAUSE_NONE)
6493 LLVM_FAILURE (ctx, "non-finally/catch clause.");
6495 if (header->num_clauses || (cfg->method->iflags & METHOD_IMPL_ATTRIBUTE_NOINLINING) || cfg->no_inline)
6496 /* We can't handle inlined methods with clauses */
6497 LLVMAddFunctionAttr (method, LLVMNoInlineAttribute);
6499 if (linfo->rgctx_arg) {
6500 ctx->rgctx_arg = LLVMGetParam (method, linfo->rgctx_arg_pindex);
6501 ctx->rgctx_arg_pindex = linfo->rgctx_arg_pindex;
6503 * We mark the rgctx parameter with the inreg attribute, which is mapped to
6504 * MONO_ARCH_RGCTX_REG in the Mono calling convention in llvm, i.e.
6505 * CC_X86_64_Mono in X86CallingConv.td.
6507 if (!ctx->llvm_only)
6508 LLVMAddAttribute (ctx->rgctx_arg, LLVMInRegAttribute);
6509 LLVMSetValueName (ctx->rgctx_arg, "rgctx");
6511 ctx->rgctx_arg_pindex = -1;
6513 if (cfg->vret_addr) {
6514 values [cfg->vret_addr->dreg] = LLVMGetParam (method, linfo->vret_arg_pindex);
6515 LLVMSetValueName (values [cfg->vret_addr->dreg], "vret");
6516 if (linfo->ret.storage == LLVMArgVtypeByRef) {
6517 LLVMAddAttribute (LLVMGetParam (method, linfo->vret_arg_pindex), LLVMStructRetAttribute);
6518 LLVMAddAttribute (LLVMGetParam (method, linfo->vret_arg_pindex), LLVMNoAliasAttribute);
6520 } else if (linfo->ret.storage == LLVMArgScalarRetAddr) {
6521 LLVMValueRef param = LLVMGetParam (method, linfo->vret_arg_pindex);
6522 LLVMSetValueName (param, "vret");
6526 ctx->this_arg_pindex = linfo->this_arg_pindex;
6527 ctx->this_arg = LLVMGetParam (method, linfo->this_arg_pindex);
6528 values [cfg->args [0]->dreg] = ctx->this_arg;
6529 LLVMSetValueName (values [cfg->args [0]->dreg], "this");
6532 names = g_new (char *, sig->param_count);
6533 mono_method_get_param_names (cfg->method, (const char **) names);
6535 for (i = 0; i < sig->param_count; ++i) {
6536 LLVMArgInfo *ainfo = &linfo->args [i + sig->hasthis];
6538 int pindex = ainfo->pindex + ainfo->ndummy_fpargs;
6541 for (j = 0; j < ainfo->ndummy_fpargs; ++j) {
6542 name = g_strdup_printf ("dummy_%d_%d", i, j);
6543 LLVMSetValueName (LLVMGetParam (method, ainfo->pindex + j), name);
6547 values [cfg->args [i + sig->hasthis]->dreg] = LLVMGetParam (method, pindex);
6548 if (ainfo->storage == LLVMArgScalarByRef) {
6549 if (names [i] && names [i][0] != '\0')
6550 name = g_strdup_printf ("p_arg_%s", names [i]);
6552 name = g_strdup_printf ("p_arg_%d", i);
6553 } else if (ainfo->storage == LLVMArgGsharedvtFixed || ainfo->storage == LLVMArgGsharedvtFixedVtype) {
6554 if (names [i] && names [i][0] != '\0')
6555 name = g_strdup_printf ("p_arg_%s", names [i]);
6557 name = g_strdup_printf ("p_arg_%d", i);
6559 if (names [i] && names [i][0] != '\0')
6560 name = g_strdup_printf ("arg_%s", names [i]);
6562 name = g_strdup_printf ("arg_%d", i);
6564 LLVMSetValueName (values [cfg->args [i + sig->hasthis]->dreg], name);
6566 if (ainfo->storage == LLVMArgVtypeByVal)
6567 LLVMAddAttribute (LLVMGetParam (method, pindex), LLVMByValAttribute);
6569 if (ainfo->storage == LLVMArgVtypeByRef) {
6571 cfg->args [i + sig->hasthis]->opcode = OP_VTARG_ADDR;
6576 if (ctx->module->emit_dwarf && cfg->compile_aot && mono_debug_enabled ()) {
6577 ctx->minfo = mono_debug_lookup_method (cfg->method);
6578 ctx->dbg_md = emit_dbg_subprogram (ctx, cfg, method, method_name);
6582 for (bb = cfg->bb_entry; bb; bb = bb->next_bb)
6583 max_block_num = MAX (max_block_num, bb->block_num);
6584 ctx->bblocks = bblocks = g_new0 (BBInfo, max_block_num + 1);
6586 /* Add branches between non-consecutive bblocks */
6587 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
6588 if (bb->last_ins && MONO_IS_COND_BRANCH_OP (bb->last_ins) &&
6589 bb->next_bb != bb->last_ins->inst_false_bb) {
6591 MonoInst *inst = (MonoInst*)mono_mempool_alloc0 (cfg->mempool, sizeof (MonoInst));
6592 inst->opcode = OP_BR;
6593 inst->inst_target_bb = bb->last_ins->inst_false_bb;
6594 mono_bblock_add_inst (bb, inst);
6599 * The INDIRECT flag added by OP_LDADDR inhibits optimizations, even if the LDADDR
6600 * was later optimized away, so clear these flags, and add them back for the still
6601 * present OP_LDADDR instructions.
6603 for (i = 0; i < cfg->next_vreg; ++i) {
6606 ins = get_vreg_to_inst (cfg, i);
6607 if (ins && ins != cfg->rgctx_var)
6608 ins->flags &= ~MONO_INST_INDIRECT;
6612 * Make a first pass over the code to precreate PHI nodes/set INDIRECT flags.
6614 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
6616 LLVMBuilderRef builder;
6618 char dname_buf[128];
6620 builder = create_builder (ctx);
6622 for (ins = bb->code; ins; ins = ins->next) {
6623 switch (ins->opcode) {
6628 LLVMTypeRef phi_type = llvm_type_to_stack_type (cfg, type_to_llvm_type (ctx, &ins->klass->byval_arg));
6630 CHECK_FAILURE (ctx);
6632 if (ins->opcode == OP_VPHI) {
6633 /* Treat valuetype PHI nodes as operating on the address itself */
6634 g_assert (ins->klass);
6635 phi_type = LLVMPointerType (type_to_llvm_type (ctx, &ins->klass->byval_arg), 0);
6639 * Have to precreate these, as they can be referenced by
6640 * earlier instructions.
6642 sprintf (dname_buf, "t%d", ins->dreg);
6644 values [ins->dreg] = LLVMBuildPhi (builder, phi_type, dname);
6646 if (ins->opcode == OP_VPHI)
6647 ctx->addresses [ins->dreg] = values [ins->dreg];
6649 g_ptr_array_add (phi_values, values [ins->dreg]);
6652 * Set the expected type of the incoming arguments since these have
6653 * to have the same type.
6655 for (i = 0; i < ins->inst_phi_args [0]; i++) {
6656 int sreg1 = ins->inst_phi_args [i + 1];
6659 ctx->vreg_types [sreg1] = phi_type;
6664 ((MonoInst*)ins->inst_p0)->flags |= MONO_INST_INDIRECT;
6673 * Create an ordering for bblocks, use the depth first order first, then
6674 * put the exception handling bblocks last.
6676 for (bb_index = 0; bb_index < cfg->num_bblocks; ++bb_index) {
6677 bb = cfg->bblocks [bb_index];
6678 if (!(bb->region != -1 && !MONO_BBLOCK_IS_IN_REGION (bb, MONO_REGION_TRY))) {
6679 g_ptr_array_add (bblock_list, bb);
6680 bblocks [bb->block_num].added = TRUE;
6684 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
6685 if (!bblocks [bb->block_num].added)
6686 g_ptr_array_add (bblock_list, bb);
6690 * Second pass: generate code.
6693 LLVMBuilderRef entry_builder = create_builder (ctx);
6694 LLVMBasicBlockRef entry_bb = get_bb (ctx, cfg->bb_entry);
6695 LLVMPositionBuilderAtEnd (entry_builder, entry_bb);
6696 emit_entry_bb (ctx, entry_builder);
6698 // Make landing pads first
6699 ctx->exc_meta = g_hash_table_new_full (NULL, NULL, NULL, NULL);
6701 if (ctx->llvm_only) {
6702 size_t group_index = 0;
6703 while (group_index < cfg->header->num_clauses) {
6705 size_t cursor = group_index;
6706 while (cursor < cfg->header->num_clauses &&
6707 CLAUSE_START (&cfg->header->clauses [cursor]) == CLAUSE_START (&cfg->header->clauses [group_index]) &&
6708 CLAUSE_END (&cfg->header->clauses [cursor]) == CLAUSE_END (&cfg->header->clauses [group_index])) {
6713 LLVMBasicBlockRef lpad_bb = emit_landing_pad (ctx, group_index, count);
6714 intptr_t key = CLAUSE_END (&cfg->header->clauses [group_index]);
6715 g_hash_table_insert (ctx->exc_meta, (gpointer)key, lpad_bb);
6717 group_index = cursor;
6721 for (bb_index = 0; bb_index < bblock_list->len; ++bb_index) {
6722 bb = (MonoBasicBlock*)g_ptr_array_index (bblock_list, bb_index);
6724 // Prune unreachable mono BBs.
6725 if (!(bb == cfg->bb_entry || bb->in_count > 0))
6728 process_bb (ctx, bb);
6729 CHECK_FAILURE (ctx);
6731 g_hash_table_destroy (ctx->exc_meta);
6733 mono_memory_barrier ();
6735 /* Add incoming phi values */
6736 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
6737 GSList *l, *ins_list;
6739 ins_list = bblocks [bb->block_num].phi_nodes;
6741 for (l = ins_list; l; l = l->next) {
6742 PhiNode *node = (PhiNode*)l->data;
6743 MonoInst *phi = node->phi;
6744 int sreg1 = node->sreg;
6745 LLVMBasicBlockRef in_bb;
6750 in_bb = get_end_bb (ctx, node->in_bb);
6752 if (ctx->unreachable [node->in_bb->block_num])
6755 if (!values [sreg1])
6756 /* Can happen with values in EH clauses */
6757 LLVM_FAILURE (ctx, "incoming phi sreg1");
6759 if (phi->opcode == OP_VPHI) {
6760 g_assert (LLVMTypeOf (ctx->addresses [sreg1]) == LLVMTypeOf (values [phi->dreg]));
6761 LLVMAddIncoming (values [phi->dreg], &ctx->addresses [sreg1], &in_bb, 1);
6763 if (LLVMTypeOf (values [sreg1]) != LLVMTypeOf (values [phi->dreg]))
6765 LLVM_FAILURE (ctx, "incoming phi arg type mismatch");
6766 g_assert (LLVMTypeOf (values [sreg1]) == LLVMTypeOf (values [phi->dreg]));
6767 LLVMAddIncoming (values [phi->dreg], &values [sreg1], &in_bb, 1);
6772 /* Nullify empty phi instructions */
6773 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
6774 GSList *l, *ins_list;
6776 ins_list = bblocks [bb->block_num].phi_nodes;
6778 for (l = ins_list; l; l = l->next) {
6779 PhiNode *node = (PhiNode*)l->data;
6780 MonoInst *phi = node->phi;
6781 LLVMValueRef phi_ins = values [phi->dreg];
6784 /* Already removed */
6787 if (LLVMCountIncoming (phi_ins) == 0) {
6788 mono_llvm_replace_uses_of (phi_ins, LLVMConstNull (LLVMTypeOf (phi_ins)));
6789 LLVMInstructionEraseFromParent (phi_ins);
6790 values [phi->dreg] = NULL;
6795 /* Create the SWITCH statements for ENDFINALLY instructions */
6796 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
6797 BBInfo *info = &bblocks [bb->block_num];
6799 for (l = info->endfinally_switch_ins_list; l; l = l->next) {
6800 LLVMValueRef switch_ins = (LLVMValueRef)l->data;
6801 GSList *bb_list = info->call_handler_return_bbs;
6803 for (i = 0; i < g_slist_length (bb_list); ++i)
6804 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), i + 1, FALSE), (LLVMBasicBlockRef)(g_slist_nth (bb_list, i)->data));
6808 /* Initialize the method if needed */
6809 if (cfg->compile_aot && ctx->llvm_only) {
6810 // FIXME: Add more shared got entries
6811 ctx->builder = create_builder (ctx);
6812 LLVMPositionBuilderAtEnd (ctx->builder, ctx->init_bb);
6814 ctx->module->max_method_idx = MAX (ctx->module->max_method_idx, cfg->method_index);
6816 // FIXME: beforefieldinit
6817 if (ctx->has_got_access || mono_class_get_cctor (cfg->method->klass)) {
6818 emit_init_method (ctx);
6820 LLVMBuildBr (ctx->builder, ctx->inited_bb);
6824 if (cfg->llvm_only) {
6825 GHashTableIter iter;
6827 GSList *callers, *l, *l2;
6830 * Add the contents of ctx->method_to_callers to module->method_to_callers.
6831 * We can't do this earlier, as it contains llvm instructions which can be
6832 * freed if compilation fails.
6833 * FIXME: Get rid of this when all methods can be llvm compiled.
6835 g_hash_table_iter_init (&iter, ctx->method_to_callers);
6836 while (g_hash_table_iter_next (&iter, (void**)&method, (void**)&callers)) {
6837 for (l = callers; l; l = l->next) {
6838 l2 = (GSList*)g_hash_table_lookup (ctx->module->method_to_callers, method);
6839 l2 = g_slist_prepend (l2, l->data);
6840 g_hash_table_insert (ctx->module->method_to_callers, method, l2);
6845 if (cfg->verbose_level > 1)
6846 mono_llvm_dump_value (method);
6848 if (cfg->compile_aot && !cfg->llvm_only)
6849 mark_as_used (ctx->module, method);
6851 if (cfg->compile_aot) {
6852 LLVMValueRef md_args [16];
6853 LLVMValueRef md_node;
6856 method_index = mono_aot_get_method_index (cfg->orig_method);
6857 md_args [0] = LLVMMDString (method_name, strlen (method_name));
6858 md_args [1] = LLVMConstInt (LLVMInt32Type (), method_index, FALSE);
6859 md_node = LLVMMDNode (md_args, 2);
6860 LLVMAddNamedMetadataOperand (lmodule, "mono.function_indexes", md_node);
6861 //LLVMSetMetadata (method, md_kind, LLVMMDNode (&md_arg, 1));
6864 if (cfg->compile_aot) {
6865 /* Don't generate native code, keep the LLVM IR */
6866 if (cfg->verbose_level)
6867 printf ("%s emitted as %s\n", mono_method_full_name (cfg->method, TRUE), method_name);
6869 int err = LLVMVerifyFunction(method, LLVMPrintMessageAction);
6870 g_assert (err == 0);
6872 //LLVMVerifyFunction(method, 0);
6873 mono_llvm_optimize_method (ctx->module->mono_ee, method);
6875 if (cfg->verbose_level > 1)
6876 mono_llvm_dump_value (method);
6878 cfg->native_code = (unsigned char*)LLVMGetPointerToGlobal (ctx->module->ee, method);
6880 /* Set by emit_cb */
6881 g_assert (cfg->code_len);
6883 /* FIXME: Free the LLVM IL for the function */
6886 if (ctx->module->method_to_lmethod)
6887 g_hash_table_insert (ctx->module->method_to_lmethod, cfg->method, method);
6888 if (ctx->module->idx_to_lmethod)
6889 g_hash_table_insert (ctx->module->idx_to_lmethod, GINT_TO_POINTER (cfg->method_index), method);
6891 if (ctx->llvm_only && cfg->orig_method->klass->valuetype && !(cfg->orig_method->flags & METHOD_ATTRIBUTE_STATIC))
6892 emit_unbox_tramp (ctx, method_name, method_type, method, cfg->method_index);
6899 /* Need to add unused phi nodes as they can be referenced by other values */
6900 LLVMBasicBlockRef phi_bb = LLVMAppendBasicBlock (method, "PHI_BB");
6901 LLVMBuilderRef builder;
6903 builder = create_builder (ctx);
6904 LLVMPositionBuilderAtEnd (builder, phi_bb);
6906 for (i = 0; i < phi_values->len; ++i) {
6907 LLVMValueRef v = (LLVMValueRef)g_ptr_array_index (phi_values, i);
6908 if (LLVMGetInstructionParent (v) == NULL)
6909 LLVMInsertIntoBuilder (builder, v);
6912 LLVMDeleteFunction (method);
6917 g_free (ctx->addresses);
6918 g_free (ctx->vreg_types);
6919 g_free (ctx->vreg_cli_types);
6920 g_free (ctx->is_dead);
6921 g_free (ctx->unreachable);
6922 g_ptr_array_free (phi_values, TRUE);
6923 g_free (ctx->bblocks);
6924 g_hash_table_destroy (ctx->region_to_handler);
6925 g_hash_table_destroy (ctx->clause_to_handler);
6926 g_free (method_name);
6927 g_ptr_array_free (bblock_list, TRUE);
6929 for (l = ctx->builders; l; l = l->next) {
6930 LLVMBuilderRef builder = (LLVMBuilderRef)l->data;
6931 LLVMDisposeBuilder (builder);
6936 mono_native_tls_set_value (current_cfg_tls_id, NULL);
6938 mono_loader_unlock ();
6942 * mono_llvm_create_vars:
6944 * Same as mono_arch_create_vars () for LLVM.
6947 mono_llvm_create_vars (MonoCompile *cfg)
6949 MonoMethodSignature *sig;
6951 sig = mono_method_signature (cfg->method);
6952 if (cfg->gsharedvt && cfg->llvm_only) {
6953 if (mini_is_gsharedvt_variable_signature (sig) && sig->ret->type != MONO_TYPE_VOID) {
6954 cfg->vret_addr = mono_compile_create_var (cfg, &mono_get_intptr_class ()->byval_arg, OP_ARG);
6955 if (G_UNLIKELY (cfg->verbose_level > 1)) {
6956 printf ("vret_addr = ");
6957 mono_print_ins (cfg->vret_addr);
6961 mono_arch_create_vars (cfg);
6966 * mono_llvm_emit_call:
6968 * Same as mono_arch_emit_call () for LLVM.
6971 mono_llvm_emit_call (MonoCompile *cfg, MonoCallInst *call)
6974 MonoMethodSignature *sig;
6975 int i, n, stack_size;
6980 sig = call->signature;
6981 n = sig->param_count + sig->hasthis;
6983 call->cinfo = get_llvm_call_info (cfg, sig);
6985 if (cfg->disable_llvm)
6988 if (sig->call_convention == MONO_CALL_VARARG) {
6989 cfg->exception_message = g_strdup ("varargs");
6990 cfg->disable_llvm = TRUE;
6993 for (i = 0; i < n; ++i) {
6996 ainfo = call->cinfo->args + i;
6998 in = call->args [i];
7000 /* Simply remember the arguments */
7001 switch (ainfo->storage) {
7002 case LLVMArgNormal: {
7003 MonoType *t = (sig->hasthis && i == 0) ? &mono_get_intptr_class ()->byval_arg : ainfo->type;
7006 opcode = mono_type_to_regmove (cfg, t);
7007 if (opcode == OP_FMOVE) {
7008 MONO_INST_NEW (cfg, ins, OP_FMOVE);
7009 ins->dreg = mono_alloc_freg (cfg);
7010 } else if (opcode == OP_LMOVE) {
7011 MONO_INST_NEW (cfg, ins, OP_LMOVE);
7012 ins->dreg = mono_alloc_lreg (cfg);
7013 } else if (opcode == OP_RMOVE) {
7014 MONO_INST_NEW (cfg, ins, OP_RMOVE);
7015 ins->dreg = mono_alloc_freg (cfg);
7017 MONO_INST_NEW (cfg, ins, OP_MOVE);
7018 ins->dreg = mono_alloc_ireg (cfg);
7020 ins->sreg1 = in->dreg;
7023 case LLVMArgVtypeByVal:
7024 case LLVMArgVtypeByRef:
7025 case LLVMArgVtypeInReg:
7026 case LLVMArgVtypeAsScalar:
7027 case LLVMArgScalarByRef:
7028 case LLVMArgAsIArgs:
7029 case LLVMArgAsFpArgs:
7030 case LLVMArgGsharedvtVariable:
7031 case LLVMArgGsharedvtFixed:
7032 case LLVMArgGsharedvtFixedVtype:
7033 MONO_INST_NEW (cfg, ins, OP_LLVM_OUTARG_VT);
7034 ins->dreg = mono_alloc_ireg (cfg);
7035 ins->sreg1 = in->dreg;
7036 ins->inst_p0 = mono_mempool_alloc0 (cfg->mempool, sizeof (LLVMArgInfo));
7037 memcpy (ins->inst_p0, ainfo, sizeof (LLVMArgInfo));
7038 ins->inst_vtype = ainfo->type;
7039 ins->klass = mono_class_from_mono_type (ainfo->type);
7042 cfg->exception_message = g_strdup ("ainfo->storage");
7043 cfg->disable_llvm = TRUE;
7047 if (!cfg->disable_llvm) {
7048 MONO_ADD_INS (cfg->cbb, ins);
7049 mono_call_inst_add_outarg_reg (cfg, call, ins->dreg, 0, FALSE);
7054 static unsigned char*
7055 alloc_cb (LLVMValueRef function, int size)
7059 cfg = (MonoCompile*)mono_native_tls_get_value (current_cfg_tls_id);
7063 return (unsigned char*)mono_domain_code_reserve (cfg->domain, size);
7065 return (unsigned char*)mono_domain_code_reserve (mono_domain_get (), size);
7070 emitted_cb (LLVMValueRef function, void *start, void *end)
7074 cfg = (MonoCompile*)mono_native_tls_get_value (current_cfg_tls_id);
7076 cfg->code_len = (guint8*)end - (guint8*)start;
7080 exception_cb (void *data)
7083 MonoJitExceptionInfo *ei;
7084 guint32 ei_len, i, j, nested_len, nindex;
7085 gpointer *type_info;
7086 int this_reg, this_offset;
7088 cfg = (MonoCompile*)mono_native_tls_get_value (current_cfg_tls_id);
7092 * data points to a DWARF FDE structure, convert it to our unwind format and
7094 * An alternative would be to save it directly, and modify our unwinder to work
7097 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);
7098 if (cfg->verbose_level > 1)
7099 mono_print_unwind_info (cfg->encoded_unwind_ops, cfg->encoded_unwind_ops_len);
7101 /* Count nested clauses */
7103 for (i = 0; i < ei_len; ++i) {
7104 gint32 cindex1 = *(gint32*)type_info [i];
7105 MonoExceptionClause *clause1 = &cfg->header->clauses [cindex1];
7107 for (j = 0; j < cfg->header->num_clauses; ++j) {
7109 MonoExceptionClause *clause2 = &cfg->header->clauses [cindex2];
7111 if (cindex1 != cindex2 && clause1->try_offset >= clause2->try_offset && clause1->handler_offset <= clause2->handler_offset) {
7117 cfg->llvm_ex_info = (MonoJitExceptionInfo*)mono_mempool_alloc0 (cfg->mempool, (ei_len + nested_len) * sizeof (MonoJitExceptionInfo));
7118 cfg->llvm_ex_info_len = ei_len + nested_len;
7119 memcpy (cfg->llvm_ex_info, ei, ei_len * sizeof (MonoJitExceptionInfo));
7120 /* Fill the rest of the information from the type info */
7121 for (i = 0; i < ei_len; ++i) {
7122 gint32 clause_index = *(gint32*)type_info [i];
7123 MonoExceptionClause *clause = &cfg->header->clauses [clause_index];
7125 cfg->llvm_ex_info [i].flags = clause->flags;
7126 cfg->llvm_ex_info [i].data.catch_class = clause->data.catch_class;
7127 cfg->llvm_ex_info [i].clause_index = clause_index;
7131 * For nested clauses, the LLVM produced exception info associates the try interval with
7132 * the innermost handler, while mono expects it to be associated with all nesting clauses.
7133 * So add new clauses which use the IL info (catch class etc.) from the nesting clause,
7134 * and everything else from the nested clause.
7137 for (i = 0; i < ei_len; ++i) {
7138 gint32 cindex1 = *(gint32*)type_info [i];
7139 MonoExceptionClause *clause1 = &cfg->header->clauses [cindex1];
7141 for (j = 0; j < cfg->header->num_clauses; ++j) {
7143 MonoExceptionClause *clause2 = &cfg->header->clauses [cindex2];
7144 MonoJitExceptionInfo *nesting_ei, *nested_ei;
7146 if (cindex1 != cindex2 && clause1->try_offset >= clause2->try_offset && clause1->handler_offset <= clause2->handler_offset) {
7147 /* clause1 is the nested clause */
7148 nested_ei = &cfg->llvm_ex_info [i];
7149 nesting_ei = &cfg->llvm_ex_info [nindex];
7152 memcpy (nesting_ei, nested_ei, sizeof (MonoJitExceptionInfo));
7154 nesting_ei->flags = clause2->flags;
7155 nesting_ei->data.catch_class = clause2->data.catch_class;
7156 nesting_ei->clause_index = cindex2;
7160 g_assert (nindex == ei_len + nested_len);
7161 cfg->llvm_this_reg = this_reg;
7162 cfg->llvm_this_offset = this_offset;
7164 /* type_info [i] is cfg mempool allocated, no need to free it */
7171 dlsym_cb (const char *name, void **symbol)
7177 if (!strcmp (name, "__bzero")) {
7178 *symbol = (void*)bzero;
7180 current = mono_dl_open (NULL, 0, NULL);
7183 err = mono_dl_symbol (current, name, symbol);
7185 mono_dl_close (current);
7187 #ifdef MONO_ARCH_HAVE_CREATE_LLVM_NATIVE_THUNK
7188 *symbol = (char*)mono_arch_create_llvm_native_thunk (mono_domain_get (), (guint8*)(*symbol));
7194 AddFunc (LLVMModuleRef module, const char *name, LLVMTypeRef ret_type, LLVMTypeRef *param_types, int nparams)
7196 LLVMAddFunction (module, name, LLVMFunctionType (ret_type, param_types, nparams, FALSE));
7200 AddFunc2 (LLVMModuleRef module, const char *name, LLVMTypeRef ret_type, LLVMTypeRef param_type1, LLVMTypeRef param_type2)
7202 LLVMTypeRef param_types [4];
7204 param_types [0] = param_type1;
7205 param_types [1] = param_type2;
7207 AddFunc (module, name, ret_type, param_types, 2);
7211 add_intrinsics (LLVMModuleRef module)
7213 /* Emit declarations of instrinsics */
7215 * It would be nicer to emit only the intrinsics actually used, but LLVM's Module
7216 * type doesn't seem to do any locking.
7219 LLVMTypeRef params [] = { LLVMPointerType (LLVMInt8Type (), 0), LLVMInt8Type (), LLVMInt32Type (), LLVMInt32Type (), LLVMInt1Type () };
7221 memset_param_count = 5;
7222 memset_func_name = "llvm.memset.p0i8.i32";
7224 AddFunc (module, memset_func_name, LLVMVoidType (), params, memset_param_count);
7228 LLVMTypeRef params [] = { LLVMPointerType (LLVMInt8Type (), 0), LLVMPointerType (LLVMInt8Type (), 0), LLVMInt32Type (), LLVMInt32Type (), LLVMInt1Type () };
7230 memcpy_param_count = 5;
7231 memcpy_func_name = "llvm.memcpy.p0i8.p0i8.i32";
7233 AddFunc (module, memcpy_func_name, LLVMVoidType (), params, memcpy_param_count);
7237 LLVMTypeRef params [] = { LLVMDoubleType () };
7239 AddFunc (module, "llvm.sin.f64", LLVMDoubleType (), params, 1);
7240 AddFunc (module, "llvm.cos.f64", LLVMDoubleType (), params, 1);
7241 AddFunc (module, "llvm.sqrt.f64", LLVMDoubleType (), params, 1);
7243 /* This isn't an intrinsic, instead llvm seems to special case it by name */
7244 AddFunc (module, "fabs", LLVMDoubleType (), params, 1);
7248 LLVMTypeRef ovf_res_i32 [] = { LLVMInt32Type (), LLVMInt1Type () };
7249 LLVMTypeRef params [] = { LLVMInt32Type (), LLVMInt32Type () };
7250 LLVMTypeRef ret_type = LLVMStructType (ovf_res_i32, 2, FALSE);
7252 AddFunc (module, "llvm.sadd.with.overflow.i32", ret_type, params, 2);
7253 AddFunc (module, "llvm.sadd.with.overflow.i32", ret_type, params, 2);
7254 AddFunc (module, "llvm.uadd.with.overflow.i32", ret_type, params, 2);
7255 AddFunc (module, "llvm.ssub.with.overflow.i32", ret_type, params, 2);
7256 AddFunc (module, "llvm.usub.with.overflow.i32", ret_type, params, 2);
7257 AddFunc (module, "llvm.smul.with.overflow.i32", ret_type, params, 2);
7258 AddFunc (module, "llvm.umul.with.overflow.i32", ret_type, params, 2);
7262 LLVMTypeRef ovf_res_i64 [] = { LLVMInt64Type (), LLVMInt1Type () };
7263 LLVMTypeRef params [] = { LLVMInt64Type (), LLVMInt64Type () };
7264 LLVMTypeRef ret_type = LLVMStructType (ovf_res_i64, 2, FALSE);
7266 AddFunc (module, "llvm.sadd.with.overflow.i64", ret_type, params, 2);
7267 AddFunc (module, "llvm.uadd.with.overflow.i64", ret_type, params, 2);
7268 AddFunc (module, "llvm.ssub.with.overflow.i64", ret_type, params, 2);
7269 AddFunc (module, "llvm.usub.with.overflow.i64", ret_type, params, 2);
7270 AddFunc (module, "llvm.smul.with.overflow.i64", ret_type, params, 2);
7271 AddFunc (module, "llvm.umul.with.overflow.i64", ret_type, params, 2);
7274 AddFunc2 (module, "llvm.expect.i8", LLVMInt8Type (), LLVMInt8Type (), LLVMInt8Type ());
7275 AddFunc2 (module, "llvm.expect.i1", LLVMInt1Type (), LLVMInt1Type (), LLVMInt1Type ());
7279 AddFunc (module, "mono_personality", LLVMVoidType (), NULL, 0);
7281 AddFunc (module, "llvm_resume_unwind_trampoline", LLVMVoidType (), NULL, 0);
7284 /* SSE intrinsics */
7285 #if defined(TARGET_X86) || defined(TARGET_AMD64)
7287 LLVMTypeRef ret_type, arg_types [16];
7290 ret_type = type_to_simd_type (MONO_TYPE_I4);
7291 arg_types [0] = ret_type;
7292 arg_types [1] = ret_type;
7293 AddFunc (module, "llvm.x86.sse41.pminud", ret_type, arg_types, 2);
7294 AddFunc (module, "llvm.x86.sse41.pmaxud", ret_type, arg_types, 2);
7296 ret_type = type_to_simd_type (MONO_TYPE_I2);
7297 arg_types [0] = ret_type;
7298 arg_types [1] = ret_type;
7299 AddFunc (module, "llvm.x86.sse41.pminuw", ret_type, arg_types, 2);
7300 AddFunc (module, "llvm.x86.sse2.pmins.w", ret_type, arg_types, 2);
7301 AddFunc (module, "llvm.x86.sse41.pmaxuw", ret_type, arg_types, 2);
7302 AddFunc (module, "llvm.x86.sse2.padds.w", ret_type, arg_types, 2);
7303 AddFunc (module, "llvm.x86.sse2.psubs.w", ret_type, arg_types, 2);
7304 AddFunc (module, "llvm.x86.sse2.paddus.w", ret_type, arg_types, 2);
7305 AddFunc (module, "llvm.x86.sse2.psubus.w", ret_type, arg_types, 2);
7306 AddFunc (module, "llvm.x86.sse2.pavg.w", ret_type, arg_types, 2);
7307 AddFunc (module, "llvm.x86.sse2.pmulh.w", ret_type, arg_types, 2);
7308 AddFunc (module, "llvm.x86.sse2.pmulhu.w", ret_type, arg_types, 2);
7310 ret_type = type_to_simd_type (MONO_TYPE_I1);
7311 arg_types [0] = ret_type;
7312 arg_types [1] = ret_type;
7313 AddFunc (module, "llvm.x86.sse2.pminu.b", ret_type, arg_types, 2);
7314 AddFunc (module, "llvm.x86.sse2.pmaxu.b", ret_type, arg_types, 2);
7315 AddFunc (module, "llvm.x86.sse2.padds.b", ret_type, arg_types, 2);
7316 AddFunc (module, "llvm.x86.sse2.psubs.b", ret_type, arg_types, 2);
7317 AddFunc (module, "llvm.x86.sse2.paddus.b", ret_type, arg_types, 2);
7318 AddFunc (module, "llvm.x86.sse2.psubus.b", ret_type, arg_types, 2);
7319 AddFunc (module, "llvm.x86.sse2.pavg.b", ret_type, arg_types, 2);
7321 ret_type = type_to_simd_type (MONO_TYPE_R8);
7322 arg_types [0] = ret_type;
7323 arg_types [1] = ret_type;
7324 AddFunc (module, "llvm.x86.sse2.min.pd", ret_type, arg_types, 2);
7325 AddFunc (module, "llvm.x86.sse2.max.pd", ret_type, arg_types, 2);
7326 AddFunc (module, "llvm.x86.sse3.hadd.pd", ret_type, arg_types, 2);
7327 AddFunc (module, "llvm.x86.sse3.hsub.pd", ret_type, arg_types, 2);
7328 AddFunc (module, "llvm.x86.sse3.addsub.pd", ret_type, arg_types, 2);
7330 ret_type = type_to_simd_type (MONO_TYPE_R4);
7331 arg_types [0] = ret_type;
7332 arg_types [1] = ret_type;
7333 AddFunc (module, "llvm.x86.sse.min.ps", ret_type, arg_types, 2);
7334 AddFunc (module, "llvm.x86.sse.max.ps", ret_type, arg_types, 2);
7335 AddFunc (module, "llvm.x86.sse3.hadd.ps", ret_type, arg_types, 2);
7336 AddFunc (module, "llvm.x86.sse3.hsub.ps", ret_type, arg_types, 2);
7337 AddFunc (module, "llvm.x86.sse3.addsub.ps", ret_type, arg_types, 2);
7340 ret_type = type_to_simd_type (MONO_TYPE_I1);
7341 arg_types [0] = type_to_simd_type (MONO_TYPE_I2);
7342 arg_types [1] = type_to_simd_type (MONO_TYPE_I2);
7343 AddFunc (module, "llvm.x86.sse2.packsswb.128", ret_type, arg_types, 2);
7344 AddFunc (module, "llvm.x86.sse2.packuswb.128", ret_type, arg_types, 2);
7345 ret_type = type_to_simd_type (MONO_TYPE_I2);
7346 arg_types [0] = type_to_simd_type (MONO_TYPE_I4);
7347 arg_types [1] = type_to_simd_type (MONO_TYPE_I4);
7348 AddFunc (module, "llvm.x86.sse2.packssdw.128", ret_type, arg_types, 2);
7349 AddFunc (module, "llvm.x86.sse41.packusdw", ret_type, arg_types, 2);
7352 ret_type = type_to_simd_type (MONO_TYPE_R8);
7353 arg_types [0] = ret_type;
7354 arg_types [1] = ret_type;
7355 arg_types [2] = LLVMInt8Type ();
7356 AddFunc (module, "llvm.x86.sse2.cmp.pd", ret_type, arg_types, 3);
7357 ret_type = type_to_simd_type (MONO_TYPE_R4);
7358 arg_types [0] = ret_type;
7359 arg_types [1] = ret_type;
7360 arg_types [2] = LLVMInt8Type ();
7361 AddFunc (module, "llvm.x86.sse.cmp.ps", ret_type, arg_types, 3);
7363 /* Conversion ops */
7364 ret_type = type_to_simd_type (MONO_TYPE_R8);
7365 arg_types [0] = type_to_simd_type (MONO_TYPE_I4);
7366 AddFunc (module, "llvm.x86.sse2.cvtdq2pd", ret_type, arg_types, 1);
7367 ret_type = type_to_simd_type (MONO_TYPE_R4);
7368 arg_types [0] = type_to_simd_type (MONO_TYPE_I4);
7369 AddFunc (module, "llvm.x86.sse2.cvtdq2ps", ret_type, arg_types, 1);
7370 ret_type = type_to_simd_type (MONO_TYPE_I4);
7371 arg_types [0] = type_to_simd_type (MONO_TYPE_R8);
7372 AddFunc (module, "llvm.x86.sse2.cvtpd2dq", ret_type, arg_types, 1);
7373 ret_type = type_to_simd_type (MONO_TYPE_I4);
7374 arg_types [0] = type_to_simd_type (MONO_TYPE_R4);
7375 AddFunc (module, "llvm.x86.sse2.cvtps2dq", ret_type, arg_types, 1);
7376 ret_type = type_to_simd_type (MONO_TYPE_R4);
7377 arg_types [0] = type_to_simd_type (MONO_TYPE_R8);
7378 AddFunc (module, "llvm.x86.sse2.cvtpd2ps", ret_type, arg_types, 1);
7379 ret_type = type_to_simd_type (MONO_TYPE_R8);
7380 arg_types [0] = type_to_simd_type (MONO_TYPE_R4);
7381 AddFunc (module, "llvm.x86.sse2.cvtps2pd", ret_type, arg_types, 1);
7383 ret_type = type_to_simd_type (MONO_TYPE_I4);
7384 arg_types [0] = type_to_simd_type (MONO_TYPE_R8);
7385 AddFunc (module, "llvm.x86.sse2.cvttpd2dq", ret_type, arg_types, 1);
7386 ret_type = type_to_simd_type (MONO_TYPE_I4);
7387 arg_types [0] = type_to_simd_type (MONO_TYPE_R4);
7388 AddFunc (module, "llvm.x86.sse2.cvttps2dq", ret_type, arg_types, 1);
7391 ret_type = type_to_simd_type (MONO_TYPE_R8);
7392 arg_types [0] = ret_type;
7393 AddFunc (module, "llvm.x86.sse2.sqrt.pd", ret_type, arg_types, 1);
7394 ret_type = type_to_simd_type (MONO_TYPE_R4);
7395 arg_types [0] = ret_type;
7396 AddFunc (module, "llvm.x86.sse.sqrt.ps", ret_type, arg_types, 1);
7397 ret_type = type_to_simd_type (MONO_TYPE_R4);
7398 arg_types [0] = ret_type;
7399 AddFunc (module, "llvm.x86.sse.rsqrt.ps", ret_type, arg_types, 1);
7400 ret_type = type_to_simd_type (MONO_TYPE_R4);
7401 arg_types [0] = ret_type;
7402 AddFunc (module, "llvm.x86.sse.rcp.ps", ret_type, arg_types, 1);
7405 ret_type = type_to_simd_type (MONO_TYPE_I2);
7406 arg_types [0] = ret_type;
7407 arg_types [1] = LLVMInt32Type ();
7408 AddFunc (module, "llvm.x86.sse2.psrli.w", ret_type, arg_types, 2);
7409 AddFunc (module, "llvm.x86.sse2.psrai.w", ret_type, arg_types, 2);
7410 AddFunc (module, "llvm.x86.sse2.pslli.w", ret_type, arg_types, 2);
7411 ret_type = type_to_simd_type (MONO_TYPE_I4);
7412 arg_types [0] = ret_type;
7413 arg_types [1] = LLVMInt32Type ();
7414 AddFunc (module, "llvm.x86.sse2.psrli.d", ret_type, arg_types, 2);
7415 AddFunc (module, "llvm.x86.sse2.psrai.d", ret_type, arg_types, 2);
7416 AddFunc (module, "llvm.x86.sse2.pslli.d", ret_type, arg_types, 2);
7417 ret_type = type_to_simd_type (MONO_TYPE_I8);
7418 arg_types [0] = ret_type;
7419 arg_types [1] = LLVMInt32Type ();
7420 AddFunc (module, "llvm.x86.sse2.psrli.q", ret_type, arg_types, 2);
7421 AddFunc (module, "llvm.x86.sse2.pslli.q", ret_type, arg_types, 2);
7424 ret_type = LLVMInt32Type ();
7425 arg_types [0] = type_to_simd_type (MONO_TYPE_I1);
7426 AddFunc (module, "llvm.x86.sse2.pmovmskb.128", ret_type, arg_types, 1);
7429 AddFunc (module, "llvm.x86.sse2.pause", LLVMVoidType (), NULL, 0);
7432 /* Load/Store intrinsics */
7434 LLVMTypeRef arg_types [5];
7438 for (i = 1; i <= 8; i *= 2) {
7439 arg_types [0] = LLVMPointerType (LLVMIntType (i * 8), 0);
7440 arg_types [1] = LLVMInt32Type ();
7441 arg_types [2] = LLVMInt1Type ();
7442 arg_types [3] = LLVMInt32Type ();
7443 sprintf (name, "llvm.mono.load.i%d.p0i%d", i * 8, i * 8);
7444 AddFunc (module, name, LLVMIntType (i * 8), arg_types, 4);
7446 arg_types [0] = LLVMIntType (i * 8);
7447 arg_types [1] = LLVMPointerType (LLVMIntType (i * 8), 0);
7448 arg_types [2] = LLVMInt32Type ();
7449 arg_types [3] = LLVMInt1Type ();
7450 arg_types [4] = LLVMInt32Type ();
7451 sprintf (name, "llvm.mono.store.i%d.p0i%d", i * 8, i * 8);
7452 AddFunc (module, name, LLVMVoidType (), arg_types, 5);
7458 add_types (MonoLLVMModule *module)
7460 module->ptr_type = LLVMPointerType (sizeof (gpointer) == 8 ? LLVMInt64Type () : LLVMInt32Type (), 0);
7464 mono_llvm_init (void)
7466 mono_native_tls_alloc (¤t_cfg_tls_id, NULL);
7470 init_jit_module (MonoDomain *domain)
7472 MonoJitICallInfo *info;
7473 MonoJitDomainInfo *dinfo;
7474 MonoLLVMModule *module;
7477 dinfo = domain_jit_info (domain);
7478 if (dinfo->llvm_module)
7481 mono_loader_lock ();
7483 if (dinfo->llvm_module) {
7484 mono_loader_unlock ();
7488 module = g_new0 (MonoLLVMModule, 1);
7490 name = g_strdup_printf ("mono-%s", domain->friendly_name);
7491 module->lmodule = LLVMModuleCreateWithName (name);
7492 module->context = LLVMGetGlobalContext ();
7494 module->mono_ee = (MonoEERef*)mono_llvm_create_ee (LLVMCreateModuleProviderForExistingModule (module->lmodule), alloc_cb, emitted_cb, exception_cb, dlsym_cb, &module->ee);
7496 add_intrinsics (module->lmodule);
7499 module->llvm_types = g_hash_table_new (NULL, NULL);
7501 info = mono_find_jit_icall_by_name ("llvm_resume_unwind_trampoline");
7503 LLVMAddGlobalMapping (module->ee, LLVMGetNamedFunction (module->lmodule, "llvm_resume_unwind_trampoline"), (void*)info->func);
7505 mono_memory_barrier ();
7507 dinfo->llvm_module = module;
7509 mono_loader_unlock ();
7513 mono_llvm_cleanup (void)
7515 MonoLLVMModule *module = &aot_module;
7517 if (module->lmodule)
7518 LLVMDisposeModule (module->lmodule);
7520 if (module->context)
7521 LLVMContextDispose (module->context);
7525 mono_llvm_free_domain_info (MonoDomain *domain)
7527 MonoJitDomainInfo *info = domain_jit_info (domain);
7528 MonoLLVMModule *module = (MonoLLVMModule*)info->llvm_module;
7534 if (module->llvm_types)
7535 g_hash_table_destroy (module->llvm_types);
7537 mono_llvm_dispose_ee (module->mono_ee);
7539 if (module->bb_names) {
7540 for (i = 0; i < module->bb_names_len; ++i)
7541 g_free (module->bb_names [i]);
7542 g_free (module->bb_names);
7544 //LLVMDisposeModule (module->module);
7548 info->llvm_module = NULL;
7552 mono_llvm_create_aot_module (MonoAssembly *assembly, const char *global_prefix, gboolean emit_dwarf, gboolean static_link, gboolean llvm_only)
7554 MonoLLVMModule *module = &aot_module;
7556 /* Delete previous module */
7557 if (module->plt_entries)
7558 g_hash_table_destroy (module->plt_entries);
7559 if (module->lmodule)
7560 LLVMDisposeModule (module->lmodule);
7562 memset (module, 0, sizeof (aot_module));
7564 module->lmodule = LLVMModuleCreateWithName ("aot");
7565 module->assembly = assembly;
7566 module->global_prefix = g_strdup (global_prefix);
7567 module->got_symbol = g_strdup_printf ("%s_llvm_got", global_prefix);
7568 module->eh_frame_symbol = g_strdup_printf ("%s_eh_frame", global_prefix);
7569 module->get_method_symbol = g_strdup_printf ("%s_get_method", global_prefix);
7570 module->get_unbox_tramp_symbol = g_strdup_printf ("%s_get_unbox_tramp", global_prefix);
7571 module->external_symbols = TRUE;
7572 module->emit_dwarf = emit_dwarf;
7573 module->static_link = static_link;
7574 module->llvm_only = llvm_only;
7575 /* The first few entries are reserved */
7576 module->max_got_offset = 16;
7577 module->context = LLVMContextCreate ();
7580 /* clang ignores our debug info because it has an invalid version */
7581 module->emit_dwarf = FALSE;
7583 add_intrinsics (module->lmodule);
7588 * We couldn't compute the type of the LLVM global representing the got because
7589 * its size is only known after all the methods have been emitted. So create
7590 * a dummy variable, and replace all uses it with the real got variable when
7591 * its size is known in mono_llvm_emit_aot_module ().
7594 LLVMTypeRef got_type = LLVMArrayType (module->ptr_type, 0);
7596 module->got_var = LLVMAddGlobal (module->lmodule, got_type, "mono_dummy_got");
7597 LLVMSetInitializer (module->got_var, LLVMConstNull (got_type));
7600 /* Add initialization array */
7602 LLVMTypeRef inited_type = LLVMArrayType (LLVMInt8Type (), 0);
7604 module->inited_var = LLVMAddGlobal (aot_module.lmodule, inited_type, "mono_inited_tmp");
7605 LLVMSetInitializer (module->inited_var, LLVMConstNull (inited_type));
7609 emit_init_icall_wrappers (module);
7611 emit_llvm_code_start (module);
7613 /* Add a dummy personality function */
7614 if (!use_debug_personality) {
7615 LLVMValueRef personality = LLVMAddFunction (module->lmodule, default_personality_name, LLVMFunctionType (LLVMInt32Type (), NULL, 0, TRUE));
7616 LLVMSetLinkage (personality, LLVMExternalLinkage);
7617 mark_as_used (module, personality);
7620 /* Add a reference to the c++ exception we throw/catch */
7622 LLVMTypeRef exc = LLVMPointerType (LLVMInt8Type (), 0);
7623 module->sentinel_exception = LLVMAddGlobal (module->lmodule, exc, "_ZTIPi");
7624 LLVMSetLinkage (module->sentinel_exception, LLVMExternalLinkage);
7625 mono_llvm_set_is_constant (module->sentinel_exception);
7628 module->llvm_types = g_hash_table_new (NULL, NULL);
7629 module->plt_entries = g_hash_table_new (g_str_hash, g_str_equal);
7630 module->plt_entries_ji = g_hash_table_new (NULL, NULL);
7631 module->direct_callables = g_hash_table_new (g_str_hash, g_str_equal);
7632 module->method_to_lmethod = g_hash_table_new (NULL, NULL);
7633 module->idx_to_lmethod = g_hash_table_new (NULL, NULL);
7634 module->idx_to_unbox_tramp = g_hash_table_new (NULL, NULL);
7635 module->method_to_callers = g_hash_table_new (NULL, NULL);
7639 llvm_array_from_uints (LLVMTypeRef el_type, guint32 *values, int nvalues)
7642 LLVMValueRef res, *vals;
7644 vals = g_new0 (LLVMValueRef, nvalues);
7645 for (i = 0; i < nvalues; ++i)
7646 vals [i] = LLVMConstInt (LLVMInt32Type (), values [i], FALSE);
7647 res = LLVMConstArray (LLVMInt32Type (), vals, nvalues);
7653 * mono_llvm_emit_aot_file_info:
7655 * Emit the MonoAotFileInfo structure.
7656 * Same as emit_aot_file_info () in aot-compiler.c.
7659 mono_llvm_emit_aot_file_info (MonoAotFileInfo *info, gboolean has_jitted_code)
7661 MonoLLVMModule *module = &aot_module;
7663 /* Save these for later */
7664 memcpy (&module->aot_info, info, sizeof (MonoAotFileInfo));
7665 module->has_jitted_code = has_jitted_code;
7669 * mono_llvm_emit_aot_data:
7671 * Emit the binary data DATA pointed to by symbol SYMBOL.
7674 mono_llvm_emit_aot_data (const char *symbol, guint8 *data, int data_len)
7676 MonoLLVMModule *module = &aot_module;
7680 type = LLVMArrayType (LLVMInt8Type (), data_len);
7681 d = LLVMAddGlobal (module->lmodule, type, symbol);
7682 LLVMSetVisibility (d, LLVMHiddenVisibility);
7683 LLVMSetLinkage (d, LLVMInternalLinkage);
7684 LLVMSetInitializer (d, mono_llvm_create_constant_data_array (data, data_len));
7685 mono_llvm_set_is_constant (d);
7688 /* Add a reference to a global defined in JITted code */
7690 AddJitGlobal (MonoLLVMModule *module, LLVMTypeRef type, const char *name)
7695 s = g_strdup_printf ("%s%s", module->global_prefix, name);
7696 v = LLVMAddGlobal (module->lmodule, LLVMInt8Type (), s);
7702 emit_aot_file_info (MonoLLVMModule *module)
7704 LLVMTypeRef file_info_type;
7705 LLVMTypeRef *eltypes, eltype;
7706 LLVMValueRef info_var;
7707 LLVMValueRef *fields;
7708 int i, nfields, tindex;
7709 MonoAotFileInfo *info;
7710 LLVMModuleRef lmodule = module->lmodule;
7712 info = &module->aot_info;
7714 /* Create an LLVM type to represent MonoAotFileInfo */
7715 nfields = 2 + MONO_AOT_FILE_INFO_NUM_SYMBOLS + 15 + 5;
7716 eltypes = g_new (LLVMTypeRef, nfields);
7718 eltypes [tindex ++] = LLVMInt32Type ();
7719 eltypes [tindex ++] = LLVMInt32Type ();
7721 for (i = 0; i < MONO_AOT_FILE_INFO_NUM_SYMBOLS; ++i)
7722 eltypes [tindex ++] = LLVMPointerType (LLVMInt8Type (), 0);
7724 for (i = 0; i < 15; ++i)
7725 eltypes [tindex ++] = LLVMInt32Type ();
7727 eltypes [tindex ++] = LLVMArrayType (LLVMInt32Type (), MONO_AOT_TABLE_NUM);
7728 for (i = 0; i < 4; ++i)
7729 eltypes [tindex ++] = LLVMArrayType (LLVMInt32Type (), MONO_AOT_TRAMP_NUM);
7730 g_assert (tindex == nfields);
7731 file_info_type = LLVMStructCreateNamed (module->context, "MonoAotFileInfo");
7732 LLVMStructSetBody (file_info_type, eltypes, nfields, FALSE);
7734 info_var = LLVMAddGlobal (lmodule, file_info_type, "mono_aot_file_info");
7735 if (module->static_link) {
7736 LLVMSetVisibility (info_var, LLVMHiddenVisibility);
7737 LLVMSetLinkage (info_var, LLVMInternalLinkage);
7739 fields = g_new (LLVMValueRef, nfields);
7741 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->version, FALSE);
7742 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->dummy, FALSE);
7746 * We use LLVMGetNamedGlobal () for symbol which are defined in LLVM code, and LLVMAddGlobal ()
7747 * for symbols defined in the .s file emitted by the aot compiler.
7749 eltype = eltypes [tindex];
7750 if (module->llvm_only)
7751 fields [tindex ++] = LLVMConstNull (eltype);
7753 fields [tindex ++] = AddJitGlobal (module, eltype, "jit_got");
7754 fields [tindex ++] = module->got_var;
7755 /* llc defines this directly */
7756 if (!module->llvm_only) {
7757 fields [tindex ++] = LLVMAddGlobal (lmodule, eltype, module->eh_frame_symbol);
7758 fields [tindex ++] = LLVMConstNull (eltype);
7759 fields [tindex ++] = LLVMConstNull (eltype);
7761 fields [tindex ++] = LLVMConstNull (eltype);
7762 fields [tindex ++] = module->get_method;
7763 fields [tindex ++] = module->get_unbox_tramp;
7765 if (module->has_jitted_code) {
7766 fields [tindex ++] = AddJitGlobal (module, eltype, "jit_code_start");
7767 fields [tindex ++] = AddJitGlobal (module, eltype, "jit_code_end");
7769 fields [tindex ++] = LLVMConstNull (eltype);
7770 fields [tindex ++] = LLVMConstNull (eltype);
7772 if (!module->llvm_only)
7773 fields [tindex ++] = AddJitGlobal (module, eltype, "method_addresses");
7775 fields [tindex ++] = LLVMConstNull (eltype);
7776 if (info->flags & MONO_AOT_FILE_FLAG_SEPARATE_DATA) {
7777 for (i = 0; i < MONO_AOT_TABLE_NUM; ++i)
7778 fields [tindex ++] = LLVMConstNull (eltype);
7780 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "blob");
7781 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "class_name_table");
7782 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "class_info_offsets");
7783 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "method_info_offsets");
7784 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "ex_info_offsets");
7785 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "extra_method_info_offsets");
7786 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "extra_method_table");
7787 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "got_info_offsets");
7788 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "llvm_got_info_offsets");
7789 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "image_table");
7791 /* Not needed (mem_end) */
7792 fields [tindex ++] = LLVMConstNull (eltype);
7793 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "assembly_guid");
7794 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "runtime_version");
7795 if (info->trampoline_size [0]) {
7796 fields [tindex ++] = AddJitGlobal (module, eltype, "specific_trampolines");
7797 fields [tindex ++] = AddJitGlobal (module, eltype, "static_rgctx_trampolines");
7798 fields [tindex ++] = AddJitGlobal (module, eltype, "imt_thunks");
7799 fields [tindex ++] = AddJitGlobal (module, eltype, "gsharedvt_arg_trampolines");
7801 fields [tindex ++] = LLVMConstNull (eltype);
7802 fields [tindex ++] = LLVMConstNull (eltype);
7803 fields [tindex ++] = LLVMConstNull (eltype);
7804 fields [tindex ++] = LLVMConstNull (eltype);
7806 if (module->static_link && !module->llvm_only)
7807 fields [tindex ++] = AddJitGlobal (module, eltype, "globals");
7809 fields [tindex ++] = LLVMConstNull (eltype);
7810 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "assembly_name");
7811 if (!module->llvm_only) {
7812 fields [tindex ++] = AddJitGlobal (module, eltype, "plt");
7813 fields [tindex ++] = AddJitGlobal (module, eltype, "plt_end");
7814 fields [tindex ++] = AddJitGlobal (module, eltype, "unwind_info");
7815 fields [tindex ++] = AddJitGlobal (module, eltype, "unbox_trampolines");
7816 fields [tindex ++] = AddJitGlobal (module, eltype, "unbox_trampolines_end");
7817 fields [tindex ++] = AddJitGlobal (module, eltype, "unbox_trampoline_addresses");
7819 fields [tindex ++] = LLVMConstNull (eltype);
7820 fields [tindex ++] = LLVMConstNull (eltype);
7821 fields [tindex ++] = LLVMConstNull (eltype);
7822 fields [tindex ++] = LLVMConstNull (eltype);
7823 fields [tindex ++] = LLVMConstNull (eltype);
7824 fields [tindex ++] = LLVMConstNull (eltype);
7827 for (i = 0; i < MONO_AOT_FILE_INFO_NUM_SYMBOLS; ++i)
7828 fields [2 + i] = LLVMConstBitCast (fields [2 + i], eltype);
7831 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->plt_got_offset_base, FALSE);
7832 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->got_size, FALSE);
7833 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->plt_size, FALSE);
7834 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->nmethods, FALSE);
7835 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->flags, FALSE);
7836 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->opts, FALSE);
7837 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->simd_opts, FALSE);
7838 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->gc_name_index, FALSE);
7839 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->num_rgctx_fetch_trampolines, FALSE);
7840 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->double_align, FALSE);
7841 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->long_align, FALSE);
7842 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->generic_tramp_num, FALSE);
7843 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->tramp_page_size, FALSE);
7844 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->nshared_got_entries, FALSE);
7845 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->datafile_size, FALSE);
7847 fields [tindex ++] = llvm_array_from_uints (LLVMInt32Type (), info->table_offsets, MONO_AOT_TABLE_NUM);
7848 fields [tindex ++] = llvm_array_from_uints (LLVMInt32Type (), info->num_trampolines, MONO_AOT_TRAMP_NUM);
7849 fields [tindex ++] = llvm_array_from_uints (LLVMInt32Type (), info->trampoline_got_offset_base, MONO_AOT_TRAMP_NUM);
7850 fields [tindex ++] = llvm_array_from_uints (LLVMInt32Type (), info->trampoline_size, MONO_AOT_TRAMP_NUM);
7851 fields [tindex ++] = llvm_array_from_uints (LLVMInt32Type (), info->tramp_page_code_offsets, MONO_AOT_TRAMP_NUM);
7852 g_assert (tindex == nfields);
7854 LLVMSetInitializer (info_var, LLVMConstNamedStruct (file_info_type, fields, nfields));
7856 if (module->static_link) {
7860 s = g_strdup_printf ("mono_aot_module_%s_info", module->assembly->aname.name);
7861 /* Get rid of characters which cannot occur in symbols */
7863 for (p = s; *p; ++p) {
7864 if (!(isalnum (*p) || *p == '_'))
7867 var = LLVMAddGlobal (module->lmodule, LLVMPointerType (LLVMInt8Type (), 0), s);
7869 LLVMSetInitializer (var, LLVMConstBitCast (LLVMGetNamedGlobal (module->lmodule, "mono_aot_file_info"), LLVMPointerType (LLVMInt8Type (), 0)));
7870 LLVMSetLinkage (var, LLVMExternalLinkage);
7875 * Emit the aot module into the LLVM bitcode file FILENAME.
7878 mono_llvm_emit_aot_module (const char *filename, const char *cu_name)
7880 LLVMTypeRef got_type, inited_type;
7881 LLVMValueRef real_got, real_inited;
7882 MonoLLVMModule *module = &aot_module;
7884 emit_llvm_code_end (module);
7887 * Create the real got variable and replace all uses of the dummy variable with
7890 got_type = LLVMArrayType (module->ptr_type, module->max_got_offset + 1);
7891 real_got = LLVMAddGlobal (module->lmodule, got_type, module->got_symbol);
7892 LLVMSetInitializer (real_got, LLVMConstNull (got_type));
7893 if (module->external_symbols) {
7894 LLVMSetLinkage (real_got, LLVMExternalLinkage);
7895 LLVMSetVisibility (real_got, LLVMHiddenVisibility);
7897 LLVMSetLinkage (real_got, LLVMInternalLinkage);
7899 mono_llvm_replace_uses_of (module->got_var, real_got);
7901 mark_as_used (&aot_module, real_got);
7903 /* Delete the dummy got so it doesn't become a global */
7904 LLVMDeleteGlobal (module->got_var);
7905 module->got_var = real_got;
7908 * Same for the init_var
7910 if (module->llvm_only) {
7911 inited_type = LLVMArrayType (LLVMInt8Type (), module->max_inited_idx + 1);
7912 real_inited = LLVMAddGlobal (module->lmodule, inited_type, "mono_inited");
7913 LLVMSetInitializer (real_inited, LLVMConstNull (inited_type));
7914 LLVMSetLinkage (real_inited, LLVMInternalLinkage);
7915 mono_llvm_replace_uses_of (module->inited_var, real_inited);
7916 LLVMDeleteGlobal (module->inited_var);
7919 if (module->llvm_only) {
7920 emit_get_method (&aot_module);
7921 emit_get_unbox_tramp (&aot_module);
7924 emit_llvm_used (&aot_module);
7925 emit_dbg_info (&aot_module, filename, cu_name);
7926 emit_aot_file_info (&aot_module);
7929 * Replace GOT entries for directly callable methods with the methods themselves.
7930 * It would be easier to implement this by predefining all methods before compiling
7931 * their bodies, but that couldn't handle the case when a method fails to compile
7934 if (module->llvm_only) {
7935 GHashTableIter iter;
7937 GSList *callers, *l;
7939 g_hash_table_iter_init (&iter, module->method_to_callers);
7940 while (g_hash_table_iter_next (&iter, (void**)&method, (void**)&callers)) {
7941 LLVMValueRef lmethod;
7943 lmethod = (LLVMValueRef)g_hash_table_lookup (module->method_to_lmethod, method);
7945 for (l = callers; l; l = l->next) {
7946 LLVMValueRef caller = (LLVMValueRef)l->data;
7948 mono_llvm_replace_uses_of (caller, lmethod);
7954 /* Replace PLT entries for directly callable methods with the methods themselves */
7956 GHashTableIter iter;
7958 LLVMValueRef callee;
7960 g_hash_table_iter_init (&iter, module->plt_entries_ji);
7961 while (g_hash_table_iter_next (&iter, (void**)&ji, (void**)&callee)) {
7962 if (mono_aot_is_direct_callable (ji)) {
7963 LLVMValueRef lmethod;
7965 lmethod = (LLVMValueRef)g_hash_table_lookup (module->method_to_lmethod, ji->data.method);
7966 /* The types might not match because the caller might pass an rgctx */
7967 if (lmethod && LLVMTypeOf (callee) == LLVMTypeOf (lmethod)) {
7968 mono_llvm_replace_uses_of (callee, lmethod);
7969 mono_aot_mark_unused_llvm_plt_entry (ji);
7979 if (LLVMVerifyModule (module->module, LLVMReturnStatusAction, &verifier_err)) {
7980 g_assert_not_reached ();
7985 LLVMWriteBitcodeToFile (module->lmodule, filename);
7990 md_string (const char *s)
7992 return LLVMMDString (s, strlen (s));
7995 /* Debugging support */
7998 emit_dbg_info (MonoLLVMModule *module, const char *filename, const char *cu_name)
8000 LLVMModuleRef lmodule = module->lmodule;
8001 LLVMValueRef args [16], cu_args [16], cu, ver;
8003 char *build_info, *s, *dir;
8006 * This can only be enabled when LLVM code is emitted into a separate object
8007 * file, since the AOT compiler also emits dwarf info,
8008 * and the abbrev indexes will not be correct since llvm has added its own
8011 if (!module->emit_dwarf)
8015 * Emit dwarf info in the form of LLVM metadata. There is some
8016 * out-of-date documentation at:
8017 * http://llvm.org/docs/SourceLevelDebugging.html
8018 * but most of this was gathered from the llvm and
8023 cu_args [n_cuargs ++] = LLVMConstInt (LLVMInt32Type (), DW_TAG_compile_unit, FALSE);
8024 /* CU name/compilation dir */
8025 dir = g_path_get_dirname (filename);
8026 args [0] = LLVMMDString (cu_name, strlen (cu_name));
8027 args [1] = LLVMMDString (dir, strlen (dir));
8028 cu_args [n_cuargs ++] = LLVMMDNode (args, 2);
8031 cu_args [n_cuargs ++] = LLVMConstInt (LLVMInt32Type (), DW_LANG_C99, FALSE);
8033 build_info = mono_get_runtime_build_info ();
8034 s = g_strdup_printf ("Mono AOT Compiler %s (LLVM)", build_info);
8035 cu_args [n_cuargs ++] = LLVMMDString (s, strlen (s));
8036 g_free (build_info);
8038 cu_args [n_cuargs ++] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
8040 cu_args [n_cuargs ++] = LLVMMDString ("", strlen (""));
8041 /* Runtime version */
8042 cu_args [n_cuargs ++] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
8044 cu_args [n_cuargs ++] = LLVMMDNode (args, 0);
8045 cu_args [n_cuargs ++] = LLVMMDNode (args, 0);
8047 if (module->subprogram_mds) {
8051 mds = g_new0 (LLVMValueRef, module->subprogram_mds->len);
8052 for (i = 0; i < module->subprogram_mds->len; ++i)
8053 mds [i] = (LLVMValueRef)g_ptr_array_index (module->subprogram_mds, i);
8054 cu_args [n_cuargs ++] = LLVMMDNode (mds, module->subprogram_mds->len);
8056 cu_args [n_cuargs ++] = LLVMMDNode (args, 0);
8059 cu_args [n_cuargs ++] = LLVMMDNode (args, 0);
8060 /* Imported modules */
8061 cu_args [n_cuargs ++] = LLVMMDNode (args, 0);
8063 cu_args [n_cuargs ++] = LLVMMDString ("", strlen (""));
8064 /* DebugEmissionKind = FullDebug */
8065 cu_args [n_cuargs ++] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
8066 cu = LLVMMDNode (cu_args, n_cuargs);
8067 LLVMAddNamedMetadataOperand (lmodule, "llvm.dbg.cu", cu);
8069 args [0] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
8070 args [1] = LLVMMDString ("Dwarf Version", strlen ("Dwarf Version"));
8071 args [2] = LLVMConstInt (LLVMInt32Type (), 2, FALSE);
8072 ver = LLVMMDNode (args, 3);
8073 LLVMAddNamedMetadataOperand (lmodule, "llvm.module.flags", ver);
8075 args [0] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
8076 args [1] = LLVMMDString ("Debug Info Version", strlen ("Debug Info Version"));
8077 args [2] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
8078 ver = LLVMMDNode (args, 3);
8079 LLVMAddNamedMetadataOperand (lmodule, "llvm.module.flags", ver);
8083 emit_dbg_subprogram (EmitContext *ctx, MonoCompile *cfg, LLVMValueRef method, const char *name)
8085 MonoLLVMModule *module = ctx->module;
8086 MonoDebugMethodInfo *minfo = ctx->minfo;
8087 char *source_file, *dir, *filename;
8088 LLVMValueRef md, args [16], ctx_args [16], md_args [64], type_args [16], ctx_md, type_md;
8089 MonoSymSeqPoint *sym_seq_points;
8095 mono_debug_symfile_get_seq_points (minfo, &source_file, NULL, NULL, &sym_seq_points, &n_seq_points);
8097 source_file = g_strdup ("<unknown>");
8098 dir = g_path_get_dirname (source_file);
8099 filename = g_path_get_basename (source_file);
8101 ctx_args [0] = LLVMConstInt (LLVMInt32Type (), 0x29, FALSE);
8102 args [0] = md_string (filename);
8103 args [1] = md_string (dir);
8104 ctx_args [1] = LLVMMDNode (args, 2);
8105 ctx_md = LLVMMDNode (ctx_args, 2);
8107 type_args [0] = LLVMConstInt (LLVMInt32Type (), DW_TAG_subroutine_type, FALSE);
8108 type_args [1] = NULL;
8109 type_args [2] = NULL;
8110 type_args [3] = LLVMMDString ("", 0);
8111 type_args [4] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
8112 type_args [5] = LLVMConstInt (LLVMInt64Type (), 0, FALSE);
8113 type_args [6] = LLVMConstInt (LLVMInt64Type (), 0, FALSE);
8114 type_args [7] = LLVMConstInt (LLVMInt64Type (), 0, FALSE);
8115 type_args [8] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
8116 type_args [9] = NULL;
8117 type_args [10] = NULL;
8118 type_args [11] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
8119 type_args [12] = NULL;
8120 type_args [13] = NULL;
8121 type_args [14] = NULL;
8122 type_md = LLVMMDNode (type_args, 14);
8124 /* http://llvm.org/docs/SourceLevelDebugging.html#subprogram-descriptors */
8125 md_args [0] = LLVMConstInt (LLVMInt32Type (), DW_TAG_subprogram, FALSE);
8126 /* Source directory + file pair */
8127 args [0] = md_string (filename);
8128 args [1] = md_string (dir);
8129 md_args [1] = LLVMMDNode (args ,2);
8130 md_args [2] = ctx_md;
8131 md_args [3] = md_string (cfg->method->name);
8132 md_args [4] = md_string (name);
8133 md_args [5] = md_string (name);
8136 md_args [6] = LLVMConstInt (LLVMInt32Type (), sym_seq_points [0].line, FALSE);
8138 md_args [6] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
8140 md_args [7] = type_md;
8142 md_args [8] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
8144 md_args [9] = LLVMConstInt (LLVMInt1Type (), 1, FALSE);
8146 md_args [10] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
8147 /* Index into a virtual function */
8148 md_args [11] = NULL;
8149 md_args [12] = NULL;
8151 md_args [13] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
8153 md_args [14] = LLVMConstInt (LLVMInt1Type (), 1, FALSE);
8154 /* Pointer to LLVM function */
8155 md_args [15] = method;
8156 /* Function template parameter */
8157 md_args [16] = NULL;
8158 /* Function declaration descriptor */
8159 md_args [17] = NULL;
8160 /* List of function variables */
8161 md_args [18] = LLVMMDNode (args, 0);
8163 md_args [19] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
8164 md = LLVMMDNode (md_args, 20);
8166 if (!module->subprogram_mds)
8167 module->subprogram_mds = g_ptr_array_new ();
8168 g_ptr_array_add (module->subprogram_mds, md);
8172 g_free (source_file);
8173 g_free (sym_seq_points);
8179 emit_dbg_loc (EmitContext *ctx, LLVMBuilderRef builder, const unsigned char *cil_code)
8181 MonoCompile *cfg = ctx->cfg;
8183 if (ctx->minfo && cil_code && cil_code >= cfg->header->code && cil_code < cfg->header->code + cfg->header->code_size) {
8184 MonoDebugSourceLocation *loc;
8185 LLVMValueRef loc_md, md_args [16];
8188 loc = mono_debug_symfile_lookup_location (ctx->minfo, cil_code - cfg->header->code);
8192 md_args [nmd_args ++] = LLVMConstInt (LLVMInt32Type (), loc->row, FALSE);
8193 md_args [nmd_args ++] = LLVMConstInt (LLVMInt32Type (), loc->column, FALSE);
8194 md_args [nmd_args ++] = ctx->dbg_md;
8195 md_args [nmd_args ++] = NULL;
8196 loc_md = LLVMMDNode (md_args, nmd_args);
8197 LLVMSetCurrentDebugLocation (builder, loc_md);
8198 mono_debug_symfile_free_location (loc);
8204 default_mono_llvm_unhandled_exception (void)
8206 MonoJitTlsData *jit_tls = mono_get_jit_tls ();
8207 MonoObject *target = mono_gchandle_get_target (jit_tls->thrown_exc);
8209 mono_unhandled_exception (target);
8210 exit (mono_environment_exitcode_get ());
8215 - Emit LLVM IR from the mono IR using the LLVM C API.
8216 - The original arch specific code remains, so we can fall back to it if we run
8217 into something we can't handle.
8221 A partial list of issues:
8222 - Handling of opcodes which can throw exceptions.
8224 In the mono JIT, these are implemented using code like this:
8231 push throw_pos - method
8232 call <exception trampoline>
8234 The problematic part is push throw_pos - method, which cannot be represented
8235 in the LLVM IR, since it does not support label values.
8236 -> this can be implemented in AOT mode using inline asm + labels, but cannot
8237 be implemented in JIT mode ?
8238 -> a possible but slower implementation would use the normal exception
8239 throwing code but it would need to control the placement of the throw code
8240 (it needs to be exactly after the compare+branch).
8241 -> perhaps add a PC offset intrinsics ?
8243 - efficient implementation of .ovf opcodes.
8245 These are currently implemented as:
8246 <ins which sets the condition codes>
8249 Some overflow opcodes are now supported by LLVM SVN.
8251 - exception handling, unwinding.
8252 - SSA is disabled for methods with exception handlers
8253 - How to obtain unwind info for LLVM compiled methods ?
8254 -> this is now solved by converting the unwind info generated by LLVM
8256 - LLVM uses the c++ exception handling framework, while we use our home grown
8257 code, and couldn't use the c++ one:
8258 - its not supported under VC++, other exotic platforms.
8259 - it might be impossible to support filter clauses with it.
8263 The trampolines need a predictable call sequence, since they need to disasm
8264 the calling code to obtain register numbers / offsets.
8266 LLVM currently generates this code in non-JIT mode:
8267 mov -0x98(%rax),%eax
8269 Here, the vtable pointer is lost.
8270 -> solution: use one vtable trampoline per class.
8272 - passing/receiving the IMT pointer/RGCTX.
8273 -> solution: pass them as normal arguments ?
8277 LLVM does not allow the specification of argument registers etc. This means
8278 that all calls are made according to the platform ABI.
8280 - passing/receiving vtypes.
8282 Vtypes passed/received in registers are handled by the front end by using
8283 a signature with scalar arguments, and loading the parts of the vtype into those
8286 Vtypes passed on the stack are handled using the 'byval' attribute.
8290 Supported though alloca, we need to emit the load/store code.
8294 The mono JIT uses pointer sized iregs/double fregs, while LLVM uses precisely
8295 typed registers, so we have to keep track of the precise LLVM type of each vreg.
8296 This is made easier because the IR is already in SSA form.
8297 An additional problem is that our IR is not consistent with types, i.e. i32/ia64
8298 types are frequently used incorrectly.
8303 Emit LLVM bytecode into a .bc file, compile it using llc into a .s file, then link
8304 it with the file containing the methods emitted by the JIT and the AOT data
8308 /* FIXME: Normalize some aspects of the mono IR to allow easier translation, like:
8309 * - each bblock should end with a branch
8310 * - setting the return value, making cfg->ret non-volatile
8311 * - avoid some transformations in the JIT which make it harder for us to generate
8313 * - use pointer types to help optimizations.