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 LLVMTypeRef method_type;
147 LLVMBasicBlockRef init_bb, inited_bb;
149 gboolean *unreachable;
151 gboolean has_got_access;
152 gboolean is_linkonce;
153 int this_arg_pindex, rgctx_arg_pindex;
154 LLVMValueRef imt_rgctx_loc;
155 GHashTable *llvm_types;
157 MonoDebugMethodInfo *minfo;
159 /* For every clause, the clauses it is nested in */
162 GHashTable *exc_meta;
163 GHashTable *method_to_callers;
164 GPtrArray *phi_values;
165 GPtrArray *bblock_list;
172 MonoBasicBlock *in_bb;
177 * Instruction metadata
178 * This is the same as ins_info, but LREG != IREG.
186 #define MINI_OP(a,b,dest,src1,src2) dest, src1, src2, ' ',
187 #define MINI_OP3(a,b,dest,src1,src2,src3) dest, src1, src2, src3,
194 /* keep in sync with the enum in mini.h */
197 #include "mini-ops.h"
202 #if SIZEOF_VOID_P == 4
203 #define GET_LONG_IMM(ins) (((guint64)(ins)->inst_ms_word << 32) | (guint64)(guint32)(ins)->inst_ls_word)
205 #define GET_LONG_IMM(ins) ((ins)->inst_imm)
208 #define LLVM_INS_INFO(opcode) (&llvm_ins_info [((opcode) - OP_START - 1) * 4])
211 #define TRACE_FAILURE(msg) do { printf ("%s\n", msg); } while (0)
213 #define TRACE_FAILURE(msg)
217 #define IS_TARGET_X86 1
219 #define IS_TARGET_X86 0
223 #define IS_TARGET_AMD64 1
225 #define IS_TARGET_AMD64 0
228 #define ctx_ok(ctx) (!(ctx)->cfg->disable_llvm)
230 static LLVMIntPredicate cond_to_llvm_cond [] = {
243 static LLVMRealPredicate fpcond_to_llvm_cond [] = {
256 static MonoNativeTlsKey current_cfg_tls_id;
258 static MonoLLVMModule aot_module;
259 static int memset_param_count, memcpy_param_count;
260 static const char *memset_func_name;
261 static const char *memcpy_func_name;
263 static void init_jit_module (MonoDomain *domain);
265 static void emit_dbg_loc (EmitContext *ctx, LLVMBuilderRef builder, const unsigned char *cil_code);
266 static LLVMValueRef emit_dbg_subprogram (EmitContext *ctx, MonoCompile *cfg, LLVMValueRef method, const char *name);
267 static void emit_dbg_info (MonoLLVMModule *module, const char *filename, const char *cu_name);
271 set_failure (EmitContext *ctx, const char *message)
273 TRACE_FAILURE (reason);
274 ctx->cfg->exception_message = g_strdup (message);
275 ctx->cfg->disable_llvm = TRUE;
281 * The LLVM type with width == sizeof (gpointer)
286 return sizeof (gpointer) == 8 ? LLVMInt64Type () : LLVMInt32Type ();
292 return sizeof (gpointer) == 8 ? LLVMPointerType (LLVMInt64Type (), 0) : LLVMPointerType (LLVMInt32Type (), 0);
298 return sizeof (gpointer) == 8 ? LLVMPointerType (LLVMInt64Type (), 0) : LLVMPointerType (LLVMInt32Type (), 0);
304 * Return the size of the LLVM representation of the vtype T.
307 get_vtype_size (MonoType *t)
311 size = mono_class_value_size (mono_class_from_mono_type (t), NULL);
313 /* LLVMArgAsIArgs depends on this since it stores whole words */
314 while (size < 2 * sizeof (gpointer) && mono_is_power_of_two (size) == -1)
321 * simd_class_to_llvm_type:
323 * Return the LLVM type corresponding to the Mono.SIMD class KLASS
326 simd_class_to_llvm_type (EmitContext *ctx, MonoClass *klass)
328 if (!strcmp (klass->name, "Vector2d")) {
329 return LLVMVectorType (LLVMDoubleType (), 2);
330 } else if (!strcmp (klass->name, "Vector2l")) {
331 return LLVMVectorType (LLVMInt64Type (), 2);
332 } else if (!strcmp (klass->name, "Vector2ul")) {
333 return LLVMVectorType (LLVMInt64Type (), 2);
334 } else if (!strcmp (klass->name, "Vector4i")) {
335 return LLVMVectorType (LLVMInt32Type (), 4);
336 } else if (!strcmp (klass->name, "Vector4ui")) {
337 return LLVMVectorType (LLVMInt32Type (), 4);
338 } else if (!strcmp (klass->name, "Vector4f")) {
339 return LLVMVectorType (LLVMFloatType (), 4);
340 } else if (!strcmp (klass->name, "Vector8s")) {
341 return LLVMVectorType (LLVMInt16Type (), 8);
342 } else if (!strcmp (klass->name, "Vector8us")) {
343 return LLVMVectorType (LLVMInt16Type (), 8);
344 } else if (!strcmp (klass->name, "Vector16sb")) {
345 return LLVMVectorType (LLVMInt8Type (), 16);
346 } else if (!strcmp (klass->name, "Vector16b")) {
347 return LLVMVectorType (LLVMInt8Type (), 16);
349 printf ("%s\n", klass->name);
355 /* Return the 128 bit SIMD type corresponding to the mono type TYPE */
356 static inline G_GNUC_UNUSED LLVMTypeRef
357 type_to_simd_type (int type)
361 return LLVMVectorType (LLVMInt8Type (), 16);
363 return LLVMVectorType (LLVMInt16Type (), 8);
365 return LLVMVectorType (LLVMInt32Type (), 4);
367 return LLVMVectorType (LLVMInt64Type (), 2);
369 return LLVMVectorType (LLVMDoubleType (), 2);
371 return LLVMVectorType (LLVMFloatType (), 4);
373 g_assert_not_reached ();
379 create_llvm_type_for_type (MonoLLVMModule *module, MonoClass *klass)
381 int i, size, nfields, esize;
382 LLVMTypeRef *eltypes;
387 t = &klass->byval_arg;
389 if (mini_type_is_hfa (t, &nfields, &esize)) {
391 * This is needed on arm64 where HFAs are returned in
395 eltypes = g_new (LLVMTypeRef, size);
396 for (i = 0; i < size; ++i)
397 eltypes [i] = esize == 4 ? LLVMFloatType () : LLVMDoubleType ();
399 size = get_vtype_size (t);
401 eltypes = g_new (LLVMTypeRef, size);
402 for (i = 0; i < size; ++i)
403 eltypes [i] = LLVMInt8Type ();
406 name = mono_type_full_name (&klass->byval_arg);
407 ltype = LLVMStructCreateNamed (module->context, name);
408 LLVMStructSetBody (ltype, eltypes, size, FALSE);
418 * Return the LLVM type corresponding to T.
421 type_to_llvm_type (EmitContext *ctx, MonoType *t)
423 t = mini_get_underlying_type (t);
427 return LLVMVoidType ();
429 return LLVMInt8Type ();
431 return LLVMInt16Type ();
433 return LLVMInt32Type ();
435 return LLVMInt8Type ();
437 return LLVMInt16Type ();
439 return LLVMInt32Type ();
440 case MONO_TYPE_BOOLEAN:
441 return LLVMInt8Type ();
444 return LLVMInt64Type ();
446 return LLVMInt16Type ();
448 return LLVMFloatType ();
450 return LLVMDoubleType ();
453 return IntPtrType ();
454 case MONO_TYPE_OBJECT:
455 case MONO_TYPE_CLASS:
456 case MONO_TYPE_ARRAY:
457 case MONO_TYPE_SZARRAY:
458 case MONO_TYPE_STRING:
460 return ObjRefType ();
463 /* Because of generic sharing */
464 return ObjRefType ();
465 case MONO_TYPE_GENERICINST:
466 if (!mono_type_generic_inst_is_valuetype (t))
467 return ObjRefType ();
469 case MONO_TYPE_VALUETYPE:
470 case MONO_TYPE_TYPEDBYREF: {
474 klass = mono_class_from_mono_type (t);
476 if (MONO_CLASS_IS_SIMD (ctx->cfg, klass))
477 return simd_class_to_llvm_type (ctx, klass);
480 return type_to_llvm_type (ctx, mono_class_enum_basetype (klass));
482 ltype = (LLVMTypeRef)g_hash_table_lookup (ctx->module->llvm_types, klass);
484 ltype = create_llvm_type_for_type (ctx->module, klass);
485 g_hash_table_insert (ctx->module->llvm_types, klass, ltype);
491 printf ("X: %d\n", t->type);
492 ctx->cfg->exception_message = g_strdup_printf ("type %s", mono_type_full_name (t));
493 ctx->cfg->disable_llvm = TRUE;
501 * Return whenever T is an unsigned int type.
504 type_is_unsigned (EmitContext *ctx, MonoType *t)
506 t = mini_get_underlying_type (t);
522 * type_to_llvm_arg_type:
524 * Same as type_to_llvm_type, but treat i8/i16 as i32.
527 type_to_llvm_arg_type (EmitContext *ctx, MonoType *t)
529 LLVMTypeRef ptype = type_to_llvm_type (ctx, t);
531 if (ctx->cfg->llvm_only)
535 * This works on all abis except arm64/ios which passes multiple
536 * arguments in one stack slot.
539 if (ptype == LLVMInt8Type () || ptype == LLVMInt16Type ()) {
541 * LLVM generates code which only sets the lower bits, while JITted
542 * code expects all the bits to be set.
544 ptype = LLVMInt32Type ();
552 * llvm_type_to_stack_type:
554 * Return the LLVM type which needs to be used when a value of type TYPE is pushed
557 static G_GNUC_UNUSED LLVMTypeRef
558 llvm_type_to_stack_type (MonoCompile *cfg, LLVMTypeRef type)
562 if (type == LLVMInt8Type ())
563 return LLVMInt32Type ();
564 else if (type == LLVMInt16Type ())
565 return LLVMInt32Type ();
566 else if (!cfg->r4fp && type == LLVMFloatType ())
567 return LLVMDoubleType ();
573 * regtype_to_llvm_type:
575 * Return the LLVM type corresponding to the regtype C used in instruction
579 regtype_to_llvm_type (char c)
583 return LLVMInt32Type ();
585 return LLVMInt64Type ();
587 return LLVMDoubleType ();
596 * Return the LLVM type corresponding to the unary/binary opcode OPCODE.
599 op_to_llvm_type (int opcode)
604 return LLVMInt8Type ();
607 return LLVMInt8Type ();
610 return LLVMInt16Type ();
613 return LLVMInt16Type ();
616 return LLVMInt32Type ();
619 return LLVMInt32Type ();
621 return LLVMInt64Type ();
623 return LLVMFloatType ();
625 return LLVMDoubleType ();
627 return LLVMInt64Type ();
629 return LLVMInt32Type ();
631 return LLVMInt64Type ();
636 return LLVMInt8Type ();
641 return LLVMInt16Type ();
643 return LLVMInt32Type ();
646 return sizeof (gpointer) == 8 ? LLVMInt64Type () : LLVMInt32Type ();
653 return LLVMInt32Type ();
660 return LLVMInt64Type ();
662 printf ("%s\n", mono_inst_name (opcode));
663 g_assert_not_reached ();
668 #define CLAUSE_START(clause) ((clause)->try_offset)
669 #define CLAUSE_END(clause) (((clause))->try_offset + ((clause))->try_len)
672 * load_store_to_llvm_type:
674 * Return the size/sign/zero extension corresponding to the load/store opcode
678 load_store_to_llvm_type (int opcode, int *size, gboolean *sext, gboolean *zext)
684 case OP_LOADI1_MEMBASE:
685 case OP_STOREI1_MEMBASE_REG:
686 case OP_STOREI1_MEMBASE_IMM:
687 case OP_ATOMIC_LOAD_I1:
688 case OP_ATOMIC_STORE_I1:
691 return LLVMInt8Type ();
692 case OP_LOADU1_MEMBASE:
694 case OP_ATOMIC_LOAD_U1:
695 case OP_ATOMIC_STORE_U1:
698 return LLVMInt8Type ();
699 case OP_LOADI2_MEMBASE:
700 case OP_STOREI2_MEMBASE_REG:
701 case OP_STOREI2_MEMBASE_IMM:
702 case OP_ATOMIC_LOAD_I2:
703 case OP_ATOMIC_STORE_I2:
706 return LLVMInt16Type ();
707 case OP_LOADU2_MEMBASE:
709 case OP_ATOMIC_LOAD_U2:
710 case OP_ATOMIC_STORE_U2:
713 return LLVMInt16Type ();
714 case OP_LOADI4_MEMBASE:
715 case OP_LOADU4_MEMBASE:
718 case OP_STOREI4_MEMBASE_REG:
719 case OP_STOREI4_MEMBASE_IMM:
720 case OP_ATOMIC_LOAD_I4:
721 case OP_ATOMIC_STORE_I4:
722 case OP_ATOMIC_LOAD_U4:
723 case OP_ATOMIC_STORE_U4:
725 return LLVMInt32Type ();
726 case OP_LOADI8_MEMBASE:
728 case OP_STOREI8_MEMBASE_REG:
729 case OP_STOREI8_MEMBASE_IMM:
730 case OP_ATOMIC_LOAD_I8:
731 case OP_ATOMIC_STORE_I8:
732 case OP_ATOMIC_LOAD_U8:
733 case OP_ATOMIC_STORE_U8:
735 return LLVMInt64Type ();
736 case OP_LOADR4_MEMBASE:
737 case OP_STORER4_MEMBASE_REG:
738 case OP_ATOMIC_LOAD_R4:
739 case OP_ATOMIC_STORE_R4:
741 return LLVMFloatType ();
742 case OP_LOADR8_MEMBASE:
743 case OP_STORER8_MEMBASE_REG:
744 case OP_ATOMIC_LOAD_R8:
745 case OP_ATOMIC_STORE_R8:
747 return LLVMDoubleType ();
748 case OP_LOAD_MEMBASE:
750 case OP_STORE_MEMBASE_REG:
751 case OP_STORE_MEMBASE_IMM:
752 *size = sizeof (gpointer);
753 return IntPtrType ();
755 g_assert_not_reached ();
763 * Return the LLVM intrinsics corresponding to the overflow opcode OPCODE.
766 ovf_op_to_intrins (int opcode)
770 return "llvm.sadd.with.overflow.i32";
772 return "llvm.uadd.with.overflow.i32";
774 return "llvm.ssub.with.overflow.i32";
776 return "llvm.usub.with.overflow.i32";
778 return "llvm.smul.with.overflow.i32";
780 return "llvm.umul.with.overflow.i32";
782 return "llvm.sadd.with.overflow.i64";
784 return "llvm.uadd.with.overflow.i64";
786 return "llvm.ssub.with.overflow.i64";
788 return "llvm.usub.with.overflow.i64";
790 return "llvm.smul.with.overflow.i64";
792 return "llvm.umul.with.overflow.i64";
794 g_assert_not_reached ();
800 simd_op_to_intrins (int opcode)
803 #if defined(TARGET_X86) || defined(TARGET_AMD64)
805 return "llvm.x86.sse2.min.pd";
807 return "llvm.x86.sse.min.ps";
809 return "llvm.x86.sse41.pminud";
811 return "llvm.x86.sse41.pminuw";
813 return "llvm.x86.sse2.pminu.b";
815 return "llvm.x86.sse2.pmins.w";
817 return "llvm.x86.sse2.max.pd";
819 return "llvm.x86.sse.max.ps";
821 return "llvm.x86.sse3.hadd.pd";
823 return "llvm.x86.sse3.hadd.ps";
825 return "llvm.x86.sse3.hsub.pd";
827 return "llvm.x86.sse3.hsub.ps";
829 return "llvm.x86.sse41.pmaxud";
831 return "llvm.x86.sse41.pmaxuw";
833 return "llvm.x86.sse2.pmaxu.b";
835 return "llvm.x86.sse3.addsub.ps";
837 return "llvm.x86.sse3.addsub.pd";
838 case OP_EXTRACT_MASK:
839 return "llvm.x86.sse2.pmovmskb.128";
842 return "llvm.x86.sse2.psrli.w";
845 return "llvm.x86.sse2.psrli.d";
848 return "llvm.x86.sse2.psrli.q";
851 return "llvm.x86.sse2.pslli.w";
854 return "llvm.x86.sse2.pslli.d";
857 return "llvm.x86.sse2.pslli.q";
860 return "llvm.x86.sse2.psrai.w";
863 return "llvm.x86.sse2.psrai.d";
865 return "llvm.x86.sse2.padds.b";
867 return "llvm.x86.sse2.padds.w";
869 return "llvm.x86.sse2.psubs.b";
871 return "llvm.x86.sse2.psubs.w";
872 case OP_PADDB_SAT_UN:
873 return "llvm.x86.sse2.paddus.b";
874 case OP_PADDW_SAT_UN:
875 return "llvm.x86.sse2.paddus.w";
876 case OP_PSUBB_SAT_UN:
877 return "llvm.x86.sse2.psubus.b";
878 case OP_PSUBW_SAT_UN:
879 return "llvm.x86.sse2.psubus.w";
881 return "llvm.x86.sse2.pavg.b";
883 return "llvm.x86.sse2.pavg.w";
885 return "llvm.x86.sse.sqrt.ps";
887 return "llvm.x86.sse2.sqrt.pd";
889 return "llvm.x86.sse.rsqrt.ps";
891 return "llvm.x86.sse.rcp.ps";
893 return "llvm.x86.sse2.cvtdq2pd";
895 return "llvm.x86.sse2.cvtdq2ps";
897 return "llvm.x86.sse2.cvtpd2dq";
899 return "llvm.x86.sse2.cvtps2dq";
901 return "llvm.x86.sse2.cvtpd2ps";
903 return "llvm.x86.sse2.cvtps2pd";
905 return "llvm.x86.sse2.cvttpd2dq";
907 return "llvm.x86.sse2.cvttps2dq";
909 return "llvm.x86.sse.cmp.ps";
911 return "llvm.x86.sse2.cmp.pd";
913 return "llvm.x86.sse2.packsswb.128";
915 return "llvm.x86.sse2.packssdw.128";
917 return "llvm.x86.sse2.packuswb.128";
919 return "llvm.x86.sse41.packusdw";
921 return "llvm.x86.sse2.pmulh.w";
922 case OP_PMULW_HIGH_UN:
923 return "llvm.x86.sse2.pmulhu.w";
926 g_assert_not_reached ();
932 simd_op_to_llvm_type (int opcode)
934 #if defined(TARGET_X86) || defined(TARGET_AMD64)
938 return type_to_simd_type (MONO_TYPE_R8);
941 return type_to_simd_type (MONO_TYPE_I8);
944 return type_to_simd_type (MONO_TYPE_I4);
949 return type_to_simd_type (MONO_TYPE_I2);
953 return type_to_simd_type (MONO_TYPE_I1);
955 return type_to_simd_type (MONO_TYPE_R4);
958 return type_to_simd_type (MONO_TYPE_I4);
962 return type_to_simd_type (MONO_TYPE_R8);
966 return type_to_simd_type (MONO_TYPE_R4);
967 case OP_EXTRACT_MASK:
968 return type_to_simd_type (MONO_TYPE_I1);
974 return type_to_simd_type (MONO_TYPE_R4);
977 return type_to_simd_type (MONO_TYPE_R8);
979 g_assert_not_reached ();
990 * Return the LLVM basic block corresponding to BB.
992 static LLVMBasicBlockRef
993 get_bb (EmitContext *ctx, MonoBasicBlock *bb)
995 char bb_name_buf [128];
998 if (ctx->bblocks [bb->block_num].bblock == NULL) {
999 if (bb->flags & BB_EXCEPTION_HANDLER) {
1000 int clause_index = (mono_get_block_region_notry (ctx->cfg, bb->region) >> 8) - 1;
1001 sprintf (bb_name_buf, "EH_CLAUSE%d_BB%d", clause_index, bb->block_num);
1002 bb_name = bb_name_buf;
1003 } else if (bb->block_num < 256) {
1004 if (!ctx->module->bb_names) {
1005 ctx->module->bb_names_len = 256;
1006 ctx->module->bb_names = g_new0 (char*, ctx->module->bb_names_len);
1008 if (!ctx->module->bb_names [bb->block_num]) {
1011 n = g_strdup_printf ("BB%d", bb->block_num);
1012 mono_memory_barrier ();
1013 ctx->module->bb_names [bb->block_num] = n;
1015 bb_name = ctx->module->bb_names [bb->block_num];
1017 sprintf (bb_name_buf, "BB%d", bb->block_num);
1018 bb_name = bb_name_buf;
1021 ctx->bblocks [bb->block_num].bblock = LLVMAppendBasicBlock (ctx->lmethod, bb_name);
1022 ctx->bblocks [bb->block_num].end_bblock = ctx->bblocks [bb->block_num].bblock;
1025 return ctx->bblocks [bb->block_num].bblock;
1031 * Return the last LLVM bblock corresponding to BB.
1032 * This might not be equal to the bb returned by get_bb () since we need to generate
1033 * multiple LLVM bblocks for a mono bblock to handle throwing exceptions.
1035 static LLVMBasicBlockRef
1036 get_end_bb (EmitContext *ctx, MonoBasicBlock *bb)
1039 return ctx->bblocks [bb->block_num].end_bblock;
1042 static LLVMBasicBlockRef
1043 gen_bb (EmitContext *ctx, const char *prefix)
1047 sprintf (bb_name, "%s%d", prefix, ++ ctx->ex_index);
1048 return LLVMAppendBasicBlock (ctx->lmethod, bb_name);
1054 * Return the target of the patch identified by TYPE and TARGET.
1057 resolve_patch (MonoCompile *cfg, MonoJumpInfoType type, gconstpointer target)
1061 memset (&ji, 0, sizeof (ji));
1063 ji.data.target = target;
1065 return mono_resolve_patch_target (cfg->method, cfg->domain, NULL, &ji, FALSE);
1071 * Emit code to convert the LLVM value V to DTYPE.
1074 convert_full (EmitContext *ctx, LLVMValueRef v, LLVMTypeRef dtype, gboolean is_unsigned)
1076 LLVMTypeRef stype = LLVMTypeOf (v);
1078 if (stype != dtype) {
1079 gboolean ext = FALSE;
1082 if (dtype == LLVMInt64Type () && (stype == LLVMInt32Type () || stype == LLVMInt16Type () || stype == LLVMInt8Type ()))
1084 else if (dtype == LLVMInt32Type () && (stype == LLVMInt16Type () || stype == LLVMInt8Type ()))
1086 else if (dtype == LLVMInt16Type () && (stype == LLVMInt8Type ()))
1090 return is_unsigned ? LLVMBuildZExt (ctx->builder, v, dtype, "") : LLVMBuildSExt (ctx->builder, v, dtype, "");
1092 if (dtype == LLVMDoubleType () && stype == LLVMFloatType ())
1093 return LLVMBuildFPExt (ctx->builder, v, dtype, "");
1096 if (stype == LLVMInt64Type () && (dtype == LLVMInt32Type () || dtype == LLVMInt16Type () || dtype == LLVMInt8Type ()))
1097 return LLVMBuildTrunc (ctx->builder, v, dtype, "");
1098 if (stype == LLVMInt32Type () && (dtype == LLVMInt16Type () || dtype == LLVMInt8Type ()))
1099 return LLVMBuildTrunc (ctx->builder, v, dtype, "");
1100 if (stype == LLVMInt16Type () && dtype == LLVMInt8Type ())
1101 return LLVMBuildTrunc (ctx->builder, v, dtype, "");
1102 if (stype == LLVMDoubleType () && dtype == LLVMFloatType ())
1103 return LLVMBuildFPTrunc (ctx->builder, v, dtype, "");
1105 if (LLVMGetTypeKind (stype) == LLVMPointerTypeKind && LLVMGetTypeKind (dtype) == LLVMPointerTypeKind)
1106 return LLVMBuildBitCast (ctx->builder, v, dtype, "");
1107 if (LLVMGetTypeKind (dtype) == LLVMPointerTypeKind)
1108 return LLVMBuildIntToPtr (ctx->builder, v, dtype, "");
1109 if (LLVMGetTypeKind (stype) == LLVMPointerTypeKind)
1110 return LLVMBuildPtrToInt (ctx->builder, v, dtype, "");
1112 if (mono_arch_is_soft_float ()) {
1113 if (stype == LLVMInt32Type () && dtype == LLVMFloatType ())
1114 return LLVMBuildBitCast (ctx->builder, v, dtype, "");
1115 if (stype == LLVMInt32Type () && dtype == LLVMDoubleType ())
1116 return LLVMBuildBitCast (ctx->builder, LLVMBuildZExt (ctx->builder, v, LLVMInt64Type (), ""), dtype, "");
1119 if (LLVMGetTypeKind (stype) == LLVMVectorTypeKind && LLVMGetTypeKind (dtype) == LLVMVectorTypeKind)
1120 return LLVMBuildBitCast (ctx->builder, v, dtype, "");
1123 LLVMDumpValue (LLVMConstNull (dtype));
1124 g_assert_not_reached ();
1132 convert (EmitContext *ctx, LLVMValueRef v, LLVMTypeRef dtype)
1134 return convert_full (ctx, v, dtype, FALSE);
1138 * emit_volatile_load:
1140 * If vreg is volatile, emit a load from its address.
1143 emit_volatile_load (EmitContext *ctx, int vreg)
1147 LLVMValueRef v = LLVMBuildLoad (ctx->builder, ctx->addresses [vreg], "");
1148 t = ctx->vreg_cli_types [vreg];
1149 if (t && !t->byref) {
1151 * Might have to zero extend since llvm doesn't have
1154 if (t->type == MONO_TYPE_U1 || t->type == MONO_TYPE_U2 || t->type == MONO_TYPE_CHAR || t->type == MONO_TYPE_BOOLEAN)
1155 v = LLVMBuildZExt (ctx->builder, v, LLVMInt32Type (), "");
1156 else if (t->type == MONO_TYPE_I1 || t->type == MONO_TYPE_I2)
1157 v = LLVMBuildSExt (ctx->builder, v, LLVMInt32Type (), "");
1158 else if (t->type == MONO_TYPE_U8)
1159 v = LLVMBuildZExt (ctx->builder, v, LLVMInt64Type (), "");
1166 * emit_volatile_store:
1168 * If VREG is volatile, emit a store from its value to its address.
1171 emit_volatile_store (EmitContext *ctx, int vreg)
1173 MonoInst *var = get_vreg_to_inst (ctx->cfg, vreg);
1175 if (var && var->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT)) {
1176 g_assert (ctx->addresses [vreg]);
1177 LLVMBuildStore (ctx->builder, convert (ctx, ctx->values [vreg], type_to_llvm_type (ctx, var->inst_vtype)), ctx->addresses [vreg]);
1182 sig_to_llvm_sig_no_cinfo (EmitContext *ctx, MonoMethodSignature *sig)
1184 LLVMTypeRef ret_type;
1185 LLVMTypeRef *param_types = NULL;
1190 rtype = mini_get_underlying_type (sig->ret);
1191 ret_type = type_to_llvm_type (ctx, rtype);
1195 param_types = g_new0 (LLVMTypeRef, (sig->param_count * 8) + 3);
1199 param_types [pindex ++] = ThisType ();
1200 for (i = 0; i < sig->param_count; ++i)
1201 param_types [pindex ++] = type_to_llvm_arg_type (ctx, sig->params [i]);
1203 if (!ctx_ok (ctx)) {
1204 g_free (param_types);
1208 res = LLVMFunctionType (ret_type, param_types, pindex, FALSE);
1209 g_free (param_types);
1215 * sig_to_llvm_sig_full:
1217 * Return the LLVM signature corresponding to the mono signature SIG using the
1218 * calling convention information in CINFO. Fill out the parameter mapping information in CINFO.
1221 sig_to_llvm_sig_full (EmitContext *ctx, MonoMethodSignature *sig, LLVMCallInfo *cinfo)
1223 LLVMTypeRef ret_type;
1224 LLVMTypeRef *param_types = NULL;
1226 int i, j, pindex, vret_arg_pindex = 0;
1227 gboolean vretaddr = FALSE;
1231 return sig_to_llvm_sig_no_cinfo (ctx, sig);
1233 rtype = mini_get_underlying_type (sig->ret);
1234 ret_type = type_to_llvm_type (ctx, rtype);
1238 switch (cinfo->ret.storage) {
1239 case LLVMArgVtypeInReg:
1240 /* LLVM models this by returning an aggregate value */
1241 if (cinfo->ret.pair_storage [0] == LLVMArgInIReg && cinfo->ret.pair_storage [1] == LLVMArgNone) {
1242 LLVMTypeRef members [2];
1244 members [0] = IntPtrType ();
1245 ret_type = LLVMStructType (members, 1, FALSE);
1246 } else if (cinfo->ret.pair_storage [0] == LLVMArgNone && cinfo->ret.pair_storage [1] == LLVMArgNone) {
1248 ret_type = LLVMVoidType ();
1249 } else if (cinfo->ret.pair_storage [0] == LLVMArgInIReg && cinfo->ret.pair_storage [1] == LLVMArgInIReg) {
1250 LLVMTypeRef members [2];
1252 members [0] = IntPtrType ();
1253 members [1] = IntPtrType ();
1254 ret_type = LLVMStructType (members, 2, FALSE);
1256 g_assert_not_reached ();
1259 case LLVMArgVtypeByVal:
1260 /* Vtype returned normally by val */
1262 case LLVMArgVtypeAsScalar:
1263 /* LLVM models this by returning an int */
1264 g_assert (cinfo->ret.nslots == 1 || cinfo->ret.nslots == 2);
1265 ret_type = LLVMIntType (cinfo->ret.nslots * sizeof (mgreg_t) * 8);
1267 case LLVMArgFpStruct: {
1268 /* Vtype returned as a fp struct */
1269 LLVMTypeRef members [16];
1271 /* Have to create our own structure since we don't map fp structures to LLVM fp structures yet */
1272 for (i = 0; i < cinfo->ret.nslots; ++i)
1273 members [i] = cinfo->ret.esize == 8 ? LLVMDoubleType () : LLVMFloatType ();
1274 ret_type = LLVMStructType (members, cinfo->ret.nslots, FALSE);
1277 case LLVMArgVtypeByRef:
1278 /* Vtype returned using a hidden argument */
1279 ret_type = LLVMVoidType ();
1281 case LLVMArgVtypeRetAddr:
1282 case LLVMArgScalarRetAddr:
1283 case LLVMArgGsharedvtFixed:
1284 case LLVMArgGsharedvtFixedVtype:
1285 case LLVMArgGsharedvtVariable:
1287 ret_type = LLVMVoidType ();
1293 param_types = g_new0 (LLVMTypeRef, (sig->param_count * 8) + 3);
1295 if (cinfo->ret.storage == LLVMArgVtypeByRef) {
1297 * Has to be the first argument because of the sret argument attribute
1298 * FIXME: This might conflict with passing 'this' as the first argument, but
1299 * this is only used on arm64 which has a dedicated struct return register.
1301 cinfo->vret_arg_pindex = pindex;
1302 param_types [pindex] = type_to_llvm_arg_type (ctx, sig->ret);
1303 if (!ctx_ok (ctx)) {
1304 g_free (param_types);
1307 param_types [pindex] = LLVMPointerType (param_types [pindex], 0);
1310 if (!ctx->llvm_only && cinfo->rgctx_arg) {
1311 cinfo->rgctx_arg_pindex = pindex;
1312 param_types [pindex] = ctx->module->ptr_type;
1315 if (cinfo->imt_arg) {
1316 cinfo->imt_arg_pindex = pindex;
1317 param_types [pindex] = ctx->module->ptr_type;
1321 /* Compute the index in the LLVM signature where the vret arg needs to be passed */
1322 vret_arg_pindex = pindex;
1323 if (cinfo->vret_arg_index == 1) {
1324 /* Add the slots consumed by the first argument */
1325 LLVMArgInfo *ainfo = &cinfo->args [0];
1326 switch (ainfo->storage) {
1327 case LLVMArgVtypeInReg:
1328 for (j = 0; j < 2; ++j) {
1329 if (ainfo->pair_storage [j] == LLVMArgInIReg)
1338 cinfo->vret_arg_pindex = vret_arg_pindex;
1341 if (vretaddr && vret_arg_pindex == pindex)
1342 param_types [pindex ++] = IntPtrType ();
1344 cinfo->this_arg_pindex = pindex;
1345 param_types [pindex ++] = ThisType ();
1346 cinfo->args [0].pindex = cinfo->this_arg_pindex;
1348 if (vretaddr && vret_arg_pindex == pindex)
1349 param_types [pindex ++] = IntPtrType ();
1350 for (i = 0; i < sig->param_count; ++i) {
1351 LLVMArgInfo *ainfo = &cinfo->args [i + sig->hasthis];
1353 if (vretaddr && vret_arg_pindex == pindex)
1354 param_types [pindex ++] = IntPtrType ();
1355 ainfo->pindex = pindex;
1357 switch (ainfo->storage) {
1358 case LLVMArgVtypeInReg:
1359 for (j = 0; j < 2; ++j) {
1360 switch (ainfo->pair_storage [j]) {
1362 param_types [pindex ++] = LLVMIntType (sizeof (gpointer) * 8);
1367 g_assert_not_reached ();
1371 case LLVMArgVtypeByVal:
1372 param_types [pindex] = type_to_llvm_arg_type (ctx, ainfo->type);
1375 param_types [pindex] = LLVMPointerType (param_types [pindex], 0);
1378 case LLVMArgAsIArgs:
1379 param_types [pindex] = LLVMArrayType (IntPtrType (), ainfo->nslots);
1382 case LLVMArgVtypeByRef:
1383 case LLVMArgScalarByRef:
1384 param_types [pindex] = type_to_llvm_arg_type (ctx, ainfo->type);
1387 param_types [pindex] = LLVMPointerType (param_types [pindex], 0);
1390 case LLVMArgAsFpArgs: {
1393 /* Emit dummy fp arguments if needed so the rest is passed on the stack */
1394 for (j = 0; j < ainfo->ndummy_fpargs; ++j)
1395 param_types [pindex ++] = LLVMDoubleType ();
1396 for (j = 0; j < ainfo->nslots; ++j)
1397 param_types [pindex ++] = ainfo->esize == 8 ? LLVMDoubleType () : LLVMFloatType ();
1400 case LLVMArgVtypeAsScalar:
1401 g_assert_not_reached ();
1403 case LLVMArgGsharedvtFixed:
1404 case LLVMArgGsharedvtFixedVtype:
1405 param_types [pindex ++] = LLVMPointerType (type_to_llvm_arg_type (ctx, ainfo->type), 0);
1407 case LLVMArgGsharedvtVariable:
1408 param_types [pindex ++] = LLVMPointerType (IntPtrType (), 0);
1411 param_types [pindex ++] = type_to_llvm_arg_type (ctx, ainfo->type);
1415 if (!ctx_ok (ctx)) {
1416 g_free (param_types);
1419 if (vretaddr && vret_arg_pindex == pindex)
1420 param_types [pindex ++] = IntPtrType ();
1421 if (ctx->llvm_only && cinfo->rgctx_arg) {
1422 /* Pass the rgctx as the last argument */
1423 cinfo->rgctx_arg_pindex = pindex;
1424 param_types [pindex] = ctx->module->ptr_type;
1428 res = LLVMFunctionType (ret_type, param_types, pindex, FALSE);
1429 g_free (param_types);
1435 sig_to_llvm_sig (EmitContext *ctx, MonoMethodSignature *sig)
1437 return sig_to_llvm_sig_full (ctx, sig, NULL);
1441 * LLVMFunctionType1:
1443 * Create an LLVM function type from the arguments.
1445 static G_GNUC_UNUSED LLVMTypeRef
1446 LLVMFunctionType0 (LLVMTypeRef ReturnType,
1449 return LLVMFunctionType (ReturnType, NULL, 0, IsVarArg);
1453 * LLVMFunctionType1:
1455 * Create an LLVM function type from the arguments.
1457 static G_GNUC_UNUSED LLVMTypeRef
1458 LLVMFunctionType1 (LLVMTypeRef ReturnType,
1459 LLVMTypeRef ParamType1,
1462 LLVMTypeRef param_types [1];
1464 param_types [0] = ParamType1;
1466 return LLVMFunctionType (ReturnType, param_types, 1, IsVarArg);
1470 * LLVMFunctionType2:
1472 * Create an LLVM function type from the arguments.
1474 static G_GNUC_UNUSED LLVMTypeRef
1475 LLVMFunctionType2 (LLVMTypeRef ReturnType,
1476 LLVMTypeRef ParamType1,
1477 LLVMTypeRef ParamType2,
1480 LLVMTypeRef param_types [2];
1482 param_types [0] = ParamType1;
1483 param_types [1] = ParamType2;
1485 return LLVMFunctionType (ReturnType, param_types, 2, IsVarArg);
1489 * LLVMFunctionType3:
1491 * Create an LLVM function type from the arguments.
1493 static G_GNUC_UNUSED LLVMTypeRef
1494 LLVMFunctionType3 (LLVMTypeRef ReturnType,
1495 LLVMTypeRef ParamType1,
1496 LLVMTypeRef ParamType2,
1497 LLVMTypeRef ParamType3,
1500 LLVMTypeRef param_types [3];
1502 param_types [0] = ParamType1;
1503 param_types [1] = ParamType2;
1504 param_types [2] = ParamType3;
1506 return LLVMFunctionType (ReturnType, param_types, 3, IsVarArg);
1509 static G_GNUC_UNUSED LLVMTypeRef
1510 LLVMFunctionType5 (LLVMTypeRef ReturnType,
1511 LLVMTypeRef ParamType1,
1512 LLVMTypeRef ParamType2,
1513 LLVMTypeRef ParamType3,
1514 LLVMTypeRef ParamType4,
1515 LLVMTypeRef ParamType5,
1518 LLVMTypeRef param_types [5];
1520 param_types [0] = ParamType1;
1521 param_types [1] = ParamType2;
1522 param_types [2] = ParamType3;
1523 param_types [3] = ParamType4;
1524 param_types [4] = ParamType5;
1526 return LLVMFunctionType (ReturnType, param_types, 5, IsVarArg);
1532 * Create an LLVM builder and remember it so it can be freed later.
1534 static LLVMBuilderRef
1535 create_builder (EmitContext *ctx)
1537 LLVMBuilderRef builder = LLVMCreateBuilder ();
1539 ctx->builders = g_slist_prepend_mempool (ctx->cfg->mempool, ctx->builders, builder);
1545 get_aotconst_name (MonoJumpInfoType type, gconstpointer data, int got_offset)
1550 case MONO_PATCH_INFO_INTERNAL_METHOD:
1551 name = g_strdup_printf ("jit_icall_%s", data);
1553 case MONO_PATCH_INFO_RGCTX_SLOT_INDEX: {
1554 MonoJumpInfoRgctxEntry *entry = (MonoJumpInfoRgctxEntry*)data;
1555 name = g_strdup_printf ("RGCTX_SLOT_INDEX_%s", mono_rgctx_info_type_to_str (entry->info_type));
1559 name = g_strdup_printf ("%s_%d", mono_ji_type_to_string (type), got_offset);
1567 get_aotconst_typed (EmitContext *ctx, MonoJumpInfoType type, gconstpointer data, LLVMTypeRef llvm_type)
1571 LLVMValueRef indexes [2];
1573 LLVMValueRef got_entry_addr, load;
1574 LLVMBuilderRef builder = ctx->builder;
1579 ji = g_new0 (MonoJumpInfo, 1);
1581 ji->data.target = data;
1583 ji = mono_aot_patch_info_dup (ji);
1585 ji->next = cfg->patch_info;
1586 cfg->patch_info = ji;
1588 got_offset = mono_aot_get_got_offset (cfg->patch_info);
1589 ctx->module->max_got_offset = MAX (ctx->module->max_got_offset, got_offset);
1591 * If the got slot is shared, it means its initialized when the aot image is loaded, so we don't need to
1592 * explicitly initialize it.
1594 if (!mono_aot_is_shared_got_offset (got_offset)) {
1595 //mono_print_ji (ji);
1597 ctx->has_got_access = TRUE;
1600 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
1601 indexes [1] = LLVMConstInt (LLVMInt32Type (), (gssize)got_offset, FALSE);
1602 got_entry_addr = LLVMBuildGEP (builder, ctx->module->got_var, indexes, 2, "");
1604 name = get_aotconst_name (type, data, got_offset);
1606 load = convert (ctx, LLVMBuildLoad (builder, got_entry_addr, ""), llvm_type);
1607 LLVMSetValueName (load, name ? name : "");
1609 load = LLVMBuildLoad (builder, got_entry_addr, name ? name : "");
1612 //set_invariant_load_flag (load);
1618 get_aotconst (EmitContext *ctx, MonoJumpInfoType type, gconstpointer data)
1620 return get_aotconst_typed (ctx, type, data, NULL);
1624 get_callee (EmitContext *ctx, LLVMTypeRef llvm_sig, MonoJumpInfoType type, gconstpointer data)
1626 LLVMValueRef callee;
1628 if (ctx->llvm_only) {
1629 callee_name = mono_aot_get_direct_call_symbol (type, data);
1631 /* Directly callable */
1633 callee = (LLVMValueRef)g_hash_table_lookup (ctx->module->direct_callables, callee_name);
1635 callee = LLVMAddFunction (ctx->lmodule, callee_name, llvm_sig);
1637 LLVMSetVisibility (callee, LLVMHiddenVisibility);
1639 g_hash_table_insert (ctx->module->direct_callables, (char*)callee_name, callee);
1641 g_free (callee_name);
1647 * Calls are made through the GOT.
1649 return get_aotconst_typed (ctx, type, data, LLVMPointerType (llvm_sig, 0));
1651 MonoJumpInfo *ji = NULL;
1653 callee_name = mono_aot_get_plt_symbol (type, data);
1657 if (ctx->cfg->compile_aot)
1658 /* Add a patch so referenced wrappers can be compiled in full aot mode */
1659 mono_add_patch_info (ctx->cfg, 0, type, data);
1662 callee = (LLVMValueRef)g_hash_table_lookup (ctx->module->plt_entries, callee_name);
1664 callee = LLVMAddFunction (ctx->lmodule, callee_name, llvm_sig);
1666 LLVMSetVisibility (callee, LLVMHiddenVisibility);
1668 g_hash_table_insert (ctx->module->plt_entries, (char*)callee_name, callee);
1671 if (ctx->cfg->compile_aot) {
1672 ji = g_new0 (MonoJumpInfo, 1);
1674 ji->data.target = data;
1676 g_hash_table_insert (ctx->module->plt_entries_ji, ji, callee);
1684 get_handler_clause (MonoCompile *cfg, MonoBasicBlock *bb)
1686 MonoMethodHeader *header = cfg->header;
1687 MonoExceptionClause *clause;
1691 if (bb->region != -1 && MONO_BBLOCK_IS_IN_REGION (bb, MONO_REGION_TRY))
1692 return (bb->region >> 8) - 1;
1695 for (i = 0; i < header->num_clauses; ++i) {
1696 clause = &header->clauses [i];
1698 if (MONO_OFFSET_IN_CLAUSE (clause, bb->real_offset) && clause->flags == MONO_EXCEPTION_CLAUSE_NONE)
1705 static MonoExceptionClause *
1706 get_most_deep_clause (MonoCompile *cfg, EmitContext *ctx, MonoBasicBlock *bb)
1708 // Since they're sorted by nesting we just need
1709 // the first one that the bb is a member of
1710 MonoExceptionClause *last = NULL;
1712 for (int i = 0; i < cfg->header->num_clauses; i++) {
1713 MonoExceptionClause *curr = &cfg->header->clauses [i];
1715 if (MONO_OFFSET_IN_CLAUSE (curr, bb->real_offset))
1718 if (MONO_OFFSET_IN_CLAUSE (curr, bb->real_offset)) {
1719 if (last && CLAUSE_END(last) > CLAUSE_END(curr))
1733 set_metadata_flag (LLVMValueRef v, const char *flag_name)
1735 LLVMValueRef md_arg;
1738 md_kind = LLVMGetMDKindID (flag_name, strlen (flag_name));
1739 md_arg = LLVMMDString ("mono", 4);
1740 LLVMSetMetadata (v, md_kind, LLVMMDNode (&md_arg, 1));
1744 set_invariant_load_flag (LLVMValueRef v)
1746 LLVMValueRef md_arg;
1748 const char *flag_name;
1750 // FIXME: Cache this
1751 flag_name = "invariant.load";
1752 md_kind = LLVMGetMDKindID (flag_name, strlen (flag_name));
1753 md_arg = LLVMMDString ("<index>", strlen ("<index>"));
1754 LLVMSetMetadata (v, md_kind, LLVMMDNode (&md_arg, 1));
1760 * Emit an LLVM call or invoke instruction depending on whenever the call is inside
1764 emit_call (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, LLVMValueRef callee, LLVMValueRef *args, int pindex)
1766 MonoCompile *cfg = ctx->cfg;
1767 LLVMValueRef lcall = NULL;
1768 LLVMBuilderRef builder = *builder_ref;
1769 MonoExceptionClause *clause;
1771 if (ctx->llvm_only) {
1772 clause = get_most_deep_clause (cfg, ctx, bb);
1775 g_assert (clause->flags == MONO_EXCEPTION_CLAUSE_NONE || clause->flags == MONO_EXCEPTION_CLAUSE_FINALLY);
1778 * Have to use an invoke instead of a call, branching to the
1779 * handler bblock of the clause containing this bblock.
1781 intptr_t key = CLAUSE_END(clause);
1783 LLVMBasicBlockRef lpad_bb = (LLVMBasicBlockRef)g_hash_table_lookup (ctx->exc_meta, (gconstpointer)key);
1785 // FIXME: Find the one that has the lowest end bound for the right start address
1786 // FIXME: Finally + nesting
1789 LLVMBasicBlockRef noex_bb = gen_bb (ctx, "CALL_NOEX_BB");
1792 lcall = LLVMBuildInvoke (builder, callee, args, pindex, noex_bb, lpad_bb, "");
1794 builder = ctx->builder = create_builder (ctx);
1795 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
1797 ctx->bblocks [bb->block_num].end_bblock = noex_bb;
1801 int clause_index = get_handler_clause (cfg, bb);
1803 if (clause_index != -1) {
1804 MonoMethodHeader *header = cfg->header;
1805 MonoExceptionClause *ec = &header->clauses [clause_index];
1806 MonoBasicBlock *tblock;
1807 LLVMBasicBlockRef ex_bb, noex_bb;
1810 * Have to use an invoke instead of a call, branching to the
1811 * handler bblock of the clause containing this bblock.
1814 g_assert (ec->flags == MONO_EXCEPTION_CLAUSE_NONE || ec->flags == MONO_EXCEPTION_CLAUSE_FINALLY);
1816 tblock = cfg->cil_offset_to_bb [ec->handler_offset];
1819 ctx->bblocks [tblock->block_num].invoke_target = TRUE;
1821 ex_bb = get_bb (ctx, tblock);
1823 noex_bb = gen_bb (ctx, "NOEX_BB");
1826 lcall = LLVMBuildInvoke (builder, callee, args, pindex, noex_bb, ex_bb, "");
1828 builder = ctx->builder = create_builder (ctx);
1829 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
1831 ctx->bblocks [bb->block_num].end_bblock = noex_bb;
1836 lcall = LLVMBuildCall (builder, callee, args, pindex, "");
1837 ctx->builder = builder;
1841 *builder_ref = ctx->builder;
1847 emit_load_general (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, int size, LLVMValueRef addr, const char *name, gboolean is_faulting, BarrierKind barrier)
1849 const char *intrins_name;
1850 LLVMValueRef args [16], res;
1851 LLVMTypeRef addr_type;
1853 if (is_faulting && bb->region != -1 && !ctx->cfg->llvm_only) {
1854 LLVMAtomicOrdering ordering;
1857 case LLVM_BARRIER_NONE:
1858 ordering = LLVMAtomicOrderingNotAtomic;
1860 case LLVM_BARRIER_ACQ:
1861 ordering = LLVMAtomicOrderingAcquire;
1863 case LLVM_BARRIER_SEQ:
1864 ordering = LLVMAtomicOrderingSequentiallyConsistent;
1867 g_assert_not_reached ();
1872 * We handle loads which can fault by calling a mono specific intrinsic
1873 * using an invoke, so they are handled properly inside try blocks.
1874 * We can't use this outside clauses, since LLVM optimizes intrinsics which
1875 * are marked with IntrReadArgMem.
1879 intrins_name = "llvm.mono.load.i8.p0i8";
1882 intrins_name = "llvm.mono.load.i16.p0i16";
1885 intrins_name = "llvm.mono.load.i32.p0i32";
1888 intrins_name = "llvm.mono.load.i64.p0i64";
1891 g_assert_not_reached ();
1894 addr_type = LLVMTypeOf (addr);
1895 if (addr_type == LLVMPointerType (LLVMDoubleType (), 0) || addr_type == LLVMPointerType (LLVMFloatType (), 0))
1896 addr = LLVMBuildBitCast (*builder_ref, addr, LLVMPointerType (LLVMIntType (size * 8), 0), "");
1899 args [1] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
1900 args [2] = LLVMConstInt (LLVMInt1Type (), TRUE, FALSE);
1901 args [3] = LLVMConstInt (LLVMInt32Type (), ordering, FALSE);
1902 res = emit_call (ctx, bb, builder_ref, LLVMGetNamedFunction (ctx->lmodule, intrins_name), args, 4);
1904 if (addr_type == LLVMPointerType (LLVMDoubleType (), 0))
1905 res = LLVMBuildBitCast (*builder_ref, res, LLVMDoubleType (), "");
1906 else if (addr_type == LLVMPointerType (LLVMFloatType (), 0))
1907 res = LLVMBuildBitCast (*builder_ref, res, LLVMFloatType (), "");
1914 * We emit volatile loads for loads which can fault, because otherwise
1915 * LLVM will generate invalid code when encountering a load from a
1918 res = mono_llvm_build_load (*builder_ref, addr, name, is_faulting, barrier);
1920 /* Mark it with a custom metadata */
1923 set_metadata_flag (res, "mono.faulting.load");
1931 emit_load (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, int size, LLVMValueRef addr, const char *name, gboolean is_faulting)
1933 return emit_load_general (ctx, bb, builder_ref, size, addr, name, is_faulting, LLVM_BARRIER_NONE);
1937 emit_store_general (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, int size, LLVMValueRef value, LLVMValueRef addr, gboolean is_faulting, BarrierKind barrier)
1939 const char *intrins_name;
1940 LLVMValueRef args [16];
1942 if (is_faulting && bb->region != -1 && !ctx->cfg->llvm_only) {
1943 LLVMAtomicOrdering ordering;
1946 case LLVM_BARRIER_NONE:
1947 ordering = LLVMAtomicOrderingNotAtomic;
1949 case LLVM_BARRIER_REL:
1950 ordering = LLVMAtomicOrderingRelease;
1952 case LLVM_BARRIER_SEQ:
1953 ordering = LLVMAtomicOrderingSequentiallyConsistent;
1956 g_assert_not_reached ();
1962 intrins_name = "llvm.mono.store.i8.p0i8";
1965 intrins_name = "llvm.mono.store.i16.p0i16";
1968 intrins_name = "llvm.mono.store.i32.p0i32";
1971 intrins_name = "llvm.mono.store.i64.p0i64";
1974 g_assert_not_reached ();
1977 if (LLVMTypeOf (value) == LLVMDoubleType () || LLVMTypeOf (value) == LLVMFloatType ()) {
1978 value = LLVMBuildBitCast (*builder_ref, value, LLVMIntType (size * 8), "");
1979 addr = LLVMBuildBitCast (*builder_ref, addr, LLVMPointerType (LLVMIntType (size * 8), 0), "");
1984 args [2] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
1985 args [3] = LLVMConstInt (LLVMInt1Type (), TRUE, FALSE);
1986 args [4] = LLVMConstInt (LLVMInt32Type (), ordering, FALSE);
1987 emit_call (ctx, bb, builder_ref, LLVMGetNamedFunction (ctx->lmodule, intrins_name), args, 5);
1989 mono_llvm_build_store (*builder_ref, value, addr, is_faulting, barrier);
1994 emit_store (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, int size, LLVMValueRef value, LLVMValueRef addr, gboolean is_faulting)
1996 emit_store_general (ctx, bb, builder_ref, size, value, addr, is_faulting, LLVM_BARRIER_NONE);
2000 * emit_cond_system_exception:
2002 * Emit code to throw the exception EXC_TYPE if the condition CMP is false.
2003 * Might set the ctx exception.
2006 emit_cond_system_exception (EmitContext *ctx, MonoBasicBlock *bb, const char *exc_type, LLVMValueRef cmp)
2008 LLVMBasicBlockRef ex_bb, ex2_bb = NULL, noex_bb;
2009 LLVMBuilderRef builder;
2010 MonoClass *exc_class;
2011 LLVMValueRef args [2];
2012 LLVMValueRef callee;
2014 ex_bb = gen_bb (ctx, "EX_BB");
2016 ex2_bb = gen_bb (ctx, "EX2_BB");
2017 noex_bb = gen_bb (ctx, "NOEX_BB");
2019 LLVMBuildCondBr (ctx->builder, cmp, ex_bb, noex_bb);
2021 exc_class = mono_class_from_name (mono_get_corlib (), "System", exc_type);
2022 g_assert (exc_class);
2024 /* Emit exception throwing code */
2025 ctx->builder = builder = create_builder (ctx);
2026 LLVMPositionBuilderAtEnd (builder, ex_bb);
2028 if (ctx->cfg->llvm_only) {
2029 static LLVMTypeRef sig;
2032 sig = LLVMFunctionType1 (LLVMVoidType (), LLVMInt32Type (), FALSE);
2033 callee = get_callee (ctx, sig, MONO_PATCH_INFO_INTERNAL_METHOD, "mono_llvm_throw_corlib_exception");
2035 LLVMBuildBr (builder, ex2_bb);
2037 ctx->builder = builder = create_builder (ctx);
2038 LLVMPositionBuilderAtEnd (ctx->builder, ex2_bb);
2040 args [0] = LLVMConstInt (LLVMInt32Type (), exc_class->type_token - MONO_TOKEN_TYPE_DEF, FALSE);
2041 emit_call (ctx, bb, &builder, callee, args, 1);
2042 LLVMBuildUnreachable (builder);
2044 ctx->builder = builder = create_builder (ctx);
2045 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
2047 ctx->bblocks [bb->block_num].end_bblock = noex_bb;
2053 callee = ctx->module->throw_corlib_exception;
2056 const char *icall_name;
2058 sig = LLVMFunctionType2 (LLVMVoidType (), LLVMInt32Type (), LLVMPointerType (LLVMInt8Type (), 0), FALSE);
2059 icall_name = "llvm_throw_corlib_exception_abs_trampoline";
2061 if (ctx->cfg->compile_aot) {
2062 callee = get_callee (ctx, sig, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
2064 callee = LLVMAddFunction (ctx->lmodule, "llvm_throw_corlib_exception_trampoline", sig);
2067 * Differences between the LLVM/non-LLVM throw corlib exception trampoline:
2068 * - On x86, LLVM generated code doesn't push the arguments
2069 * - The trampoline takes the throw address as an arguments, not a pc offset.
2071 LLVMAddGlobalMapping (ctx->module->ee, callee, resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name));
2073 mono_memory_barrier ();
2074 ctx->module->throw_corlib_exception = callee;
2078 if (IS_TARGET_X86 || IS_TARGET_AMD64)
2079 args [0] = LLVMConstInt (LLVMInt32Type (), exc_class->type_token - MONO_TOKEN_TYPE_DEF, FALSE);
2081 args [0] = LLVMConstInt (LLVMInt32Type (), exc_class->type_token, FALSE);
2084 * The LLVM mono branch contains changes so a block address can be passed as an
2085 * argument to a call.
2087 args [1] = LLVMBlockAddress (ctx->lmethod, ex_bb);
2088 emit_call (ctx, bb, &builder, callee, args, 2);
2090 LLVMBuildUnreachable (builder);
2092 ctx->builder = builder = create_builder (ctx);
2093 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
2095 ctx->bblocks [bb->block_num].end_bblock = noex_bb;
2102 * emit_args_to_vtype:
2104 * Emit code to store the vtype in the arguments args to the address ADDRESS.
2107 emit_args_to_vtype (EmitContext *ctx, LLVMBuilderRef builder, MonoType *t, LLVMValueRef address, LLVMArgInfo *ainfo, LLVMValueRef *args)
2109 int j, size, nslots;
2111 size = get_vtype_size (t);
2113 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (t))) {
2114 address = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (LLVMInt8Type (), 0), "");
2117 if (ainfo->storage == LLVMArgAsFpArgs)
2118 nslots = ainfo->nslots;
2122 for (j = 0; j < nslots; ++j) {
2123 LLVMValueRef index [2], addr, daddr;
2124 int part_size = size > sizeof (gpointer) ? sizeof (gpointer) : size;
2125 LLVMTypeRef part_type;
2127 if (ainfo->pair_storage [j] == LLVMArgNone)
2130 switch (ainfo->pair_storage [j]) {
2131 case LLVMArgInIReg: {
2132 part_type = LLVMIntType (part_size * 8);
2133 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (t))) {
2134 index [0] = LLVMConstInt (LLVMInt32Type (), j * sizeof (gpointer), FALSE);
2135 addr = LLVMBuildGEP (builder, address, index, 1, "");
2137 daddr = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (IntPtrType (), 0), "");
2138 index [0] = LLVMConstInt (LLVMInt32Type (), j, FALSE);
2139 addr = LLVMBuildGEP (builder, daddr, index, 1, "");
2141 LLVMBuildStore (builder, convert (ctx, args [j], part_type), LLVMBuildBitCast (ctx->builder, addr, LLVMPointerType (part_type, 0), ""));
2144 case LLVMArgInFPReg: {
2145 LLVMTypeRef arg_type;
2147 if (ainfo->esize == 8)
2148 arg_type = LLVMDoubleType ();
2150 arg_type = LLVMFloatType ();
2152 index [0] = LLVMConstInt (LLVMInt32Type (), j, FALSE);
2153 daddr = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (arg_type, 0), "");
2154 addr = LLVMBuildGEP (builder, daddr, index, 1, "");
2155 LLVMBuildStore (builder, args [j], addr);
2161 g_assert_not_reached ();
2164 size -= sizeof (gpointer);
2169 * emit_vtype_to_args:
2171 * Emit code to load a vtype at address ADDRESS into scalar arguments. Store the arguments
2172 * into ARGS, and the number of arguments into NARGS.
2175 emit_vtype_to_args (EmitContext *ctx, LLVMBuilderRef builder, MonoType *t, LLVMValueRef address, LLVMArgInfo *ainfo, LLVMValueRef *args, guint32 *nargs)
2178 int j, size, nslots;
2179 LLVMTypeRef arg_type;
2181 size = get_vtype_size (t);
2183 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (t)))
2184 address = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (LLVMInt8Type (), 0), "");
2186 if (ainfo->storage == LLVMArgAsFpArgs)
2187 nslots = ainfo->nslots;
2190 for (j = 0; j < nslots; ++j) {
2191 LLVMValueRef index [2], addr, daddr;
2192 int partsize = size > sizeof (gpointer) ? sizeof (gpointer) : size;
2194 if (ainfo->pair_storage [j] == LLVMArgNone)
2197 switch (ainfo->pair_storage [j]) {
2199 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (t))) {
2200 index [0] = LLVMConstInt (LLVMInt32Type (), j * sizeof (gpointer), FALSE);
2201 addr = LLVMBuildGEP (builder, address, index, 1, "");
2203 daddr = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (IntPtrType (), 0), "");
2204 index [0] = LLVMConstInt (LLVMInt32Type (), j, FALSE);
2205 addr = LLVMBuildGEP (builder, daddr, index, 1, "");
2207 args [pindex ++] = convert (ctx, LLVMBuildLoad (builder, LLVMBuildBitCast (ctx->builder, addr, LLVMPointerType (LLVMIntType (partsize * 8), 0), ""), ""), IntPtrType ());
2209 case LLVMArgInFPReg:
2210 if (ainfo->esize == 8)
2211 arg_type = LLVMDoubleType ();
2213 arg_type = LLVMFloatType ();
2214 daddr = LLVMBuildBitCast (ctx->builder, address, LLVMPointerType (arg_type, 0), "");
2215 index [0] = LLVMConstInt (LLVMInt32Type (), j, FALSE);
2216 addr = LLVMBuildGEP (builder, daddr, index, 1, "");
2217 args [pindex ++] = LLVMBuildLoad (builder, addr, "");
2222 g_assert_not_reached ();
2224 size -= sizeof (gpointer);
2231 build_alloca_llvm_type_name (EmitContext *ctx, LLVMTypeRef t, int align, const char *name)
2234 * Have to place all alloca's at the end of the entry bb, since otherwise they would
2235 * get executed every time control reaches them.
2237 LLVMPositionBuilder (ctx->alloca_builder, get_bb (ctx, ctx->cfg->bb_entry), ctx->last_alloca);
2239 ctx->last_alloca = mono_llvm_build_alloca (ctx->alloca_builder, t, NULL, align, name);
2240 return ctx->last_alloca;
2244 build_alloca_llvm_type (EmitContext *ctx, LLVMTypeRef t, int align)
2246 return build_alloca_llvm_type_name (ctx, t, align, "");
2250 build_alloca (EmitContext *ctx, MonoType *t)
2252 MonoClass *k = mono_class_from_mono_type (t);
2255 g_assert (!mini_is_gsharedvt_variable_type (t));
2257 if (MONO_CLASS_IS_SIMD (ctx->cfg, k))
2260 align = mono_class_min_align (k);
2262 /* Sometimes align is not a power of 2 */
2263 while (mono_is_power_of_two (align) == -1)
2266 return build_alloca_llvm_type (ctx, type_to_llvm_type (ctx, t), align);
2270 emit_gsharedvt_ldaddr (EmitContext *ctx, int vreg)
2274 * Compute the address of the local as gsharedvt_locals_var + gsharedvt_info_var->locals_offsets [idx].
2276 MonoCompile *cfg = ctx->cfg;
2277 LLVMBuilderRef builder = ctx->builder;
2278 LLVMValueRef offset, offset_var;
2279 LLVMValueRef info_var = ctx->values [cfg->gsharedvt_info_var->dreg];
2280 LLVMValueRef locals_var = ctx->values [cfg->gsharedvt_locals_var->dreg];
2284 g_assert (info_var);
2285 g_assert (locals_var);
2287 int idx = cfg->gsharedvt_vreg_to_idx [vreg] - 1;
2289 offset = LLVMConstInt (LLVMInt32Type (), MONO_STRUCT_OFFSET (MonoGSharedVtMethodRuntimeInfo, entries) + (idx * sizeof (gpointer)), FALSE);
2290 ptr = LLVMBuildAdd (builder, convert (ctx, info_var, IntPtrType ()), convert (ctx, offset, IntPtrType ()), "");
2292 name = g_strdup_printf ("gsharedvt_local_%d_offset", vreg);
2293 offset_var = LLVMBuildLoad (builder, convert (ctx, ptr, LLVMPointerType (LLVMInt32Type (), 0)), name);
2295 return LLVMBuildAdd (builder, convert (ctx, locals_var, IntPtrType ()), convert (ctx, offset_var, IntPtrType ()), "");
2299 * Put the global into the 'llvm.used' array to prevent it from being optimized away.
2302 mark_as_used (MonoLLVMModule *module, LLVMValueRef global)
2305 module->used = g_ptr_array_sized_new (16);
2306 g_ptr_array_add (module->used, global);
2310 emit_llvm_used (MonoLLVMModule *module)
2312 LLVMModuleRef lmodule = module->lmodule;
2313 LLVMTypeRef used_type;
2314 LLVMValueRef used, *used_elem;
2320 used_type = LLVMArrayType (LLVMPointerType (LLVMInt8Type (), 0), module->used->len);
2321 used = LLVMAddGlobal (lmodule, used_type, "llvm.used");
2322 used_elem = g_new0 (LLVMValueRef, module->used->len);
2323 for (i = 0; i < module->used->len; ++i)
2324 used_elem [i] = LLVMConstBitCast ((LLVMValueRef)g_ptr_array_index (module->used, i), LLVMPointerType (LLVMInt8Type (), 0));
2325 LLVMSetInitializer (used, LLVMConstArray (LLVMPointerType (LLVMInt8Type (), 0), used_elem, module->used->len));
2326 LLVMSetLinkage (used, LLVMAppendingLinkage);
2327 LLVMSetSection (used, "llvm.metadata");
2333 * Emit a function mapping method indexes to their code
2336 emit_get_method (MonoLLVMModule *module)
2338 LLVMModuleRef lmodule = module->lmodule;
2339 LLVMValueRef func, switch_ins, m;
2340 LLVMBasicBlockRef entry_bb, fail_bb, bb, code_start_bb, code_end_bb;
2341 LLVMBasicBlockRef *bbs;
2343 LLVMBuilderRef builder;
2348 * Emit a switch statement. Emitting a table of function addresses is smaller/faster,
2349 * but generating code seems safer.
2351 rtype = LLVMPointerType (LLVMInt8Type (), 0);
2352 func = LLVMAddFunction (lmodule, module->get_method_symbol, LLVMFunctionType1 (rtype, LLVMInt32Type (), FALSE));
2353 LLVMSetLinkage (func, LLVMExternalLinkage);
2354 LLVMSetVisibility (func, LLVMHiddenVisibility);
2355 LLVMAddFunctionAttr (func, LLVMNoUnwindAttribute);
2356 module->get_method = func;
2358 entry_bb = LLVMAppendBasicBlock (func, "ENTRY");
2361 * Return llvm_code_start/llvm_code_end when called with -1/-2.
2362 * Hopefully, the toolchain doesn't reorder these functions. If it does,
2363 * then we will have to find another solution.
2366 name = g_strdup_printf ("BB_CODE_START");
2367 code_start_bb = LLVMAppendBasicBlock (func, name);
2369 builder = LLVMCreateBuilder ();
2370 LLVMPositionBuilderAtEnd (builder, code_start_bb);
2371 LLVMBuildRet (builder, LLVMBuildBitCast (builder, module->code_start, rtype, ""));
2373 name = g_strdup_printf ("BB_CODE_END");
2374 code_end_bb = LLVMAppendBasicBlock (func, name);
2376 builder = LLVMCreateBuilder ();
2377 LLVMPositionBuilderAtEnd (builder, code_end_bb);
2378 LLVMBuildRet (builder, LLVMBuildBitCast (builder, module->code_end, rtype, ""));
2380 bbs = g_new0 (LLVMBasicBlockRef, module->max_method_idx + 1);
2381 for (i = 0; i < module->max_method_idx + 1; ++i) {
2382 name = g_strdup_printf ("BB_%d", i);
2383 bb = LLVMAppendBasicBlock (func, name);
2387 builder = LLVMCreateBuilder ();
2388 LLVMPositionBuilderAtEnd (builder, bb);
2390 m = (LLVMValueRef)g_hash_table_lookup (module->idx_to_lmethod, GINT_TO_POINTER (i));
2392 LLVMBuildRet (builder, LLVMBuildBitCast (builder, m, rtype, ""));
2394 LLVMBuildRet (builder, LLVMConstNull (rtype));
2397 fail_bb = LLVMAppendBasicBlock (func, "FAIL");
2398 builder = LLVMCreateBuilder ();
2399 LLVMPositionBuilderAtEnd (builder, fail_bb);
2400 LLVMBuildRet (builder, LLVMConstNull (rtype));
2402 builder = LLVMCreateBuilder ();
2403 LLVMPositionBuilderAtEnd (builder, entry_bb);
2405 switch_ins = LLVMBuildSwitch (builder, LLVMGetParam (func, 0), fail_bb, 0);
2406 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), -1, FALSE), code_start_bb);
2407 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), -2, FALSE), code_end_bb);
2408 for (i = 0; i < module->max_method_idx + 1; ++i) {
2409 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), i, FALSE), bbs [i]);
2412 mark_as_used (module, func);
2416 * emit_get_unbox_tramp:
2418 * Emit a function mapping method indexes to their unbox trampoline
2421 emit_get_unbox_tramp (MonoLLVMModule *module)
2423 LLVMModuleRef lmodule = module->lmodule;
2424 LLVMValueRef func, switch_ins, m;
2425 LLVMBasicBlockRef entry_bb, fail_bb, bb;
2426 LLVMBasicBlockRef *bbs;
2428 LLVMBuilderRef builder;
2432 /* Similar to emit_get_method () */
2434 rtype = LLVMPointerType (LLVMInt8Type (), 0);
2435 func = LLVMAddFunction (lmodule, module->get_unbox_tramp_symbol, LLVMFunctionType1 (rtype, LLVMInt32Type (), FALSE));
2436 LLVMSetLinkage (func, LLVMExternalLinkage);
2437 LLVMSetVisibility (func, LLVMHiddenVisibility);
2438 LLVMAddFunctionAttr (func, LLVMNoUnwindAttribute);
2439 module->get_unbox_tramp = func;
2441 entry_bb = LLVMAppendBasicBlock (func, "ENTRY");
2443 bbs = g_new0 (LLVMBasicBlockRef, module->max_method_idx + 1);
2444 for (i = 0; i < module->max_method_idx + 1; ++i) {
2445 m = (LLVMValueRef)g_hash_table_lookup (module->idx_to_unbox_tramp, GINT_TO_POINTER (i));
2449 name = g_strdup_printf ("BB_%d", i);
2450 bb = LLVMAppendBasicBlock (func, name);
2454 builder = LLVMCreateBuilder ();
2455 LLVMPositionBuilderAtEnd (builder, bb);
2457 LLVMBuildRet (builder, LLVMBuildBitCast (builder, m, rtype, ""));
2460 fail_bb = LLVMAppendBasicBlock (func, "FAIL");
2461 builder = LLVMCreateBuilder ();
2462 LLVMPositionBuilderAtEnd (builder, fail_bb);
2463 LLVMBuildRet (builder, LLVMConstNull (rtype));
2465 builder = LLVMCreateBuilder ();
2466 LLVMPositionBuilderAtEnd (builder, entry_bb);
2468 switch_ins = LLVMBuildSwitch (builder, LLVMGetParam (func, 0), fail_bb, 0);
2469 for (i = 0; i < module->max_method_idx + 1; ++i) {
2470 m = (LLVMValueRef)g_hash_table_lookup (module->idx_to_unbox_tramp, GINT_TO_POINTER (i));
2474 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), i, FALSE), bbs [i]);
2477 mark_as_used (module, func);
2480 /* Add a function to mark the beginning of LLVM code */
2482 emit_llvm_code_start (MonoLLVMModule *module)
2484 LLVMModuleRef lmodule = module->lmodule;
2486 LLVMBasicBlockRef entry_bb;
2487 LLVMBuilderRef builder;
2489 func = LLVMAddFunction (lmodule, "llvm_code_start", LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE));
2490 LLVMSetLinkage (func, LLVMInternalLinkage);
2491 LLVMAddFunctionAttr (func, LLVMNoUnwindAttribute);
2492 module->code_start = func;
2493 entry_bb = LLVMAppendBasicBlock (func, "ENTRY");
2494 builder = LLVMCreateBuilder ();
2495 LLVMPositionBuilderAtEnd (builder, entry_bb);
2496 LLVMBuildRetVoid (builder);
2500 emit_init_icall_wrapper (MonoLLVMModule *module, const char *name, const char *icall_name, int subtype)
2502 LLVMModuleRef lmodule = module->lmodule;
2503 LLVMValueRef func, indexes [2], got_entry_addr, args [16], callee;
2504 LLVMBasicBlockRef entry_bb;
2505 LLVMBuilderRef builder;
2512 func = LLVMAddFunction (lmodule, name, LLVMFunctionType1 (LLVMVoidType (), LLVMInt32Type (), FALSE));
2513 sig = LLVMFunctionType2 (LLVMVoidType (), IntPtrType (), LLVMInt32Type (), FALSE);
2518 func = LLVMAddFunction (lmodule, name, LLVMFunctionType2 (LLVMVoidType (), LLVMInt32Type (), IntPtrType (), FALSE));
2519 sig = LLVMFunctionType3 (LLVMVoidType (), IntPtrType (), LLVMInt32Type (), IntPtrType (), FALSE);
2522 func = LLVMAddFunction (lmodule, name, LLVMFunctionType2 (LLVMVoidType (), LLVMInt32Type (), ObjRefType (), FALSE));
2523 sig = LLVMFunctionType3 (LLVMVoidType (), IntPtrType (), LLVMInt32Type (), ObjRefType (), FALSE);
2526 g_assert_not_reached ();
2528 LLVMSetLinkage (func, LLVMInternalLinkage);
2529 LLVMAddFunctionAttr (func, LLVMNoInlineAttribute);
2530 mono_llvm_set_preserveall_cc (func);
2531 entry_bb = LLVMAppendBasicBlock (func, "ENTRY");
2532 builder = LLVMCreateBuilder ();
2533 LLVMPositionBuilderAtEnd (builder, entry_bb);
2536 ji = g_new0 (MonoJumpInfo, 1);
2537 ji->type = MONO_PATCH_INFO_AOT_MODULE;
2538 ji = mono_aot_patch_info_dup (ji);
2539 got_offset = mono_aot_get_got_offset (ji);
2540 module->max_got_offset = MAX (module->max_got_offset, got_offset);
2541 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
2542 indexes [1] = LLVMConstInt (LLVMInt32Type (), got_offset, FALSE);
2543 got_entry_addr = LLVMBuildGEP (builder, module->got_var, indexes, 2, "");
2544 args [0] = LLVMBuildPtrToInt (builder, LLVMBuildLoad (builder, got_entry_addr, ""), IntPtrType (), "");
2545 args [1] = LLVMGetParam (func, 0);
2547 args [2] = LLVMGetParam (func, 1);
2549 ji = g_new0 (MonoJumpInfo, 1);
2550 ji->type = MONO_PATCH_INFO_INTERNAL_METHOD;
2551 ji->data.name = icall_name;
2552 ji = mono_aot_patch_info_dup (ji);
2553 got_offset = mono_aot_get_got_offset (ji);
2554 module->max_got_offset = MAX (module->max_got_offset, got_offset);
2555 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
2556 indexes [1] = LLVMConstInt (LLVMInt32Type (), got_offset, FALSE);
2557 got_entry_addr = LLVMBuildGEP (builder, module->got_var, indexes, 2, "");
2558 callee = LLVMBuildLoad (builder, got_entry_addr, "");
2559 callee = LLVMBuildBitCast (builder, callee, LLVMPointerType (sig, 0), "");
2560 LLVMBuildCall (builder, callee, args, LLVMCountParamTypes (sig), "");
2562 // Set the inited flag
2563 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
2564 indexes [1] = LLVMGetParam (func, 0);
2565 LLVMBuildStore (builder, LLVMConstInt (LLVMInt8Type (), 1, FALSE), LLVMBuildGEP (builder, module->inited_var, indexes, 2, ""));
2567 LLVMBuildRetVoid (builder);
2569 LLVMVerifyFunction(func, LLVMAbortProcessAction);
2574 * Emit wrappers around the C icalls used to initialize llvm methods, to
2575 * make the calling code smaller and to enable usage of the llvm
2576 * PreserveAll calling convention.
2579 emit_init_icall_wrappers (MonoLLVMModule *module)
2581 module->init_method = emit_init_icall_wrapper (module, "init_method", "mono_aot_init_llvm_method", 0);
2582 module->init_method_gshared_mrgctx = emit_init_icall_wrapper (module, "init_method_gshared_mrgctx", "mono_aot_init_gshared_method_mrgctx", 1);
2583 module->init_method_gshared_this = emit_init_icall_wrapper (module, "init_method_gshared_this", "mono_aot_init_gshared_method_this", 2);
2584 module->init_method_gshared_vtable = emit_init_icall_wrapper (module, "init_method_gshared_vtable", "mono_aot_init_gshared_method_vtable", 3);
2588 emit_llvm_code_end (MonoLLVMModule *module)
2590 LLVMModuleRef lmodule = module->lmodule;
2592 LLVMBasicBlockRef entry_bb;
2593 LLVMBuilderRef builder;
2595 func = LLVMAddFunction (lmodule, "llvm_code_end", LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE));
2596 LLVMSetLinkage (func, LLVMInternalLinkage);
2597 LLVMAddFunctionAttr (func, LLVMNoUnwindAttribute);
2598 module->code_end = func;
2599 entry_bb = LLVMAppendBasicBlock (func, "ENTRY");
2600 builder = LLVMCreateBuilder ();
2601 LLVMPositionBuilderAtEnd (builder, entry_bb);
2602 LLVMBuildRetVoid (builder);
2606 emit_div_check (EmitContext *ctx, LLVMBuilderRef builder, MonoBasicBlock *bb, MonoInst *ins, LLVMValueRef lhs, LLVMValueRef rhs)
2608 gboolean need_div_check = ctx->cfg->backend->need_div_check;
2611 /* LLVM doesn't know that these can throw an exception since they are not called through an intrinsic */
2612 need_div_check = TRUE;
2614 if (!need_div_check)
2617 switch (ins->opcode) {
2630 case OP_IDIV_UN_IMM:
2631 case OP_LDIV_UN_IMM:
2632 case OP_IREM_UN_IMM:
2633 case OP_LREM_UN_IMM: {
2635 gboolean is_signed = (ins->opcode == OP_IDIV || ins->opcode == OP_LDIV || ins->opcode == OP_IREM || ins->opcode == OP_LREM ||
2636 ins->opcode == OP_IDIV_IMM || ins->opcode == OP_LDIV_IMM || ins->opcode == OP_IREM_IMM || ins->opcode == OP_LREM_IMM);
2638 cmp = LLVMBuildICmp (builder, LLVMIntEQ, rhs, LLVMConstInt (LLVMTypeOf (rhs), 0, FALSE), "");
2639 emit_cond_system_exception (ctx, bb, "DivideByZeroException", cmp);
2642 builder = ctx->builder;
2644 /* b == -1 && a == 0x80000000 */
2646 LLVMValueRef c = (LLVMTypeOf (lhs) == LLVMInt32Type ()) ? LLVMConstInt (LLVMTypeOf (lhs), 0x80000000, FALSE) : LLVMConstInt (LLVMTypeOf (lhs), 0x8000000000000000LL, FALSE);
2647 LLVMValueRef cond1 = LLVMBuildICmp (builder, LLVMIntEQ, rhs, LLVMConstInt (LLVMTypeOf (rhs), -1, FALSE), "");
2648 LLVMValueRef cond2 = LLVMBuildICmp (builder, LLVMIntEQ, lhs, c, "");
2650 cmp = LLVMBuildICmp (builder, LLVMIntEQ, LLVMBuildAnd (builder, cond1, cond2, ""), LLVMConstInt (LLVMInt1Type (), 1, FALSE), "");
2651 emit_cond_system_exception (ctx, bb, "OverflowException", cmp);
2654 builder = ctx->builder;
2666 * Emit code to initialize the GOT slots used by the method.
2669 emit_init_method (EmitContext *ctx)
2671 LLVMValueRef indexes [16], args [16], callee;
2672 LLVMValueRef inited_var, cmp, call;
2673 LLVMBasicBlockRef inited_bb, notinited_bb;
2674 LLVMBuilderRef builder = ctx->builder;
2675 MonoCompile *cfg = ctx->cfg;
2677 ctx->module->max_inited_idx = MAX (ctx->module->max_inited_idx, cfg->method_index);
2679 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
2680 indexes [1] = LLVMConstInt (LLVMInt32Type (), cfg->method_index, FALSE);
2681 inited_var = LLVMBuildLoad (builder, LLVMBuildGEP (builder, ctx->module->inited_var, indexes, 2, ""), "is_inited");
2683 args [0] = inited_var;
2684 args [1] = LLVMConstInt (LLVMInt8Type (), 1, FALSE);
2685 inited_var = LLVMBuildCall (ctx->builder, LLVMGetNamedFunction (ctx->lmodule, "llvm.expect.i8"), args, 2, "");
2687 cmp = LLVMBuildICmp (builder, LLVMIntEQ, inited_var, LLVMConstInt (LLVMTypeOf (inited_var), 0, FALSE), "");
2689 inited_bb = ctx->inited_bb;
2690 notinited_bb = gen_bb (ctx, "NOTINITED_BB");
2692 LLVMBuildCondBr (ctx->builder, cmp, notinited_bb, inited_bb);
2694 builder = ctx->builder = create_builder (ctx);
2695 LLVMPositionBuilderAtEnd (ctx->builder, notinited_bb);
2698 if (ctx->rgctx_arg && cfg->method->is_inflated && mono_method_get_context (cfg->method)->method_inst) {
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_mrgctx;
2702 call = LLVMBuildCall (builder, callee, args, 2, "");
2703 } else if (ctx->rgctx_arg) {
2704 /* A vtable is passed as the rgctx argument */
2705 args [0] = LLVMConstInt (LLVMInt32Type (), cfg->method_index, 0);
2706 args [1] = convert (ctx, ctx->rgctx_arg, IntPtrType ());
2707 callee = ctx->module->init_method_gshared_vtable;
2708 call = LLVMBuildCall (builder, callee, args, 2, "");
2709 } else if (cfg->gshared) {
2710 args [0] = LLVMConstInt (LLVMInt32Type (), cfg->method_index, 0);
2711 args [1] = convert (ctx, ctx->this_arg, ObjRefType ());
2712 callee = ctx->module->init_method_gshared_this;
2713 call = LLVMBuildCall (builder, callee, args, 2, "");
2715 args [0] = LLVMConstInt (LLVMInt32Type (), cfg->method_index, 0);
2716 callee = ctx->module->init_method;
2717 call = LLVMBuildCall (builder, callee, args, 1, "");
2721 * This enables llvm to keep arguments in their original registers/
2722 * scratch registers, since the call will not clobber them.
2724 mono_llvm_set_call_preserveall_cc (call);
2726 LLVMBuildBr (builder, inited_bb);
2727 ctx->bblocks [cfg->bb_entry->block_num].end_bblock = inited_bb;
2729 builder = ctx->builder = create_builder (ctx);
2730 LLVMPositionBuilderAtEnd (ctx->builder, inited_bb);
2734 emit_unbox_tramp (EmitContext *ctx, const char *method_name, LLVMTypeRef method_type, LLVMValueRef method, int method_index)
2737 * Emit unbox trampoline using a tail call
2739 LLVMValueRef tramp, call, *args;
2740 LLVMBuilderRef builder;
2741 LLVMBasicBlockRef lbb;
2742 LLVMCallInfo *linfo;
2746 tramp_name = g_strdup_printf ("ut_%s", method_name);
2747 tramp = LLVMAddFunction (ctx->module->lmodule, tramp_name, method_type);
2748 LLVMSetLinkage (tramp, LLVMInternalLinkage);
2749 LLVMAddFunctionAttr (tramp, LLVMOptimizeForSizeAttribute);
2750 //LLVMAddFunctionAttr (tramp, LLVMNoUnwindAttribute);
2752 // FIXME: Reduce code duplication with mono_llvm_compile_method () etc.
2753 if (!ctx->llvm_only && ctx->rgctx_arg_pindex != -1)
2754 LLVMAddAttribute (LLVMGetParam (tramp, ctx->rgctx_arg_pindex), LLVMInRegAttribute);
2755 if (ctx->cfg->vret_addr) {
2756 LLVMSetValueName (LLVMGetParam (tramp, linfo->vret_arg_pindex), "vret");
2757 if (linfo->ret.storage == LLVMArgVtypeByRef) {
2758 LLVMAddAttribute (LLVMGetParam (tramp, linfo->vret_arg_pindex), LLVMStructRetAttribute);
2759 LLVMAddAttribute (LLVMGetParam (tramp, linfo->vret_arg_pindex), LLVMNoAliasAttribute);
2763 lbb = LLVMAppendBasicBlock (tramp, "");
2764 builder = LLVMCreateBuilder ();
2765 LLVMPositionBuilderAtEnd (builder, lbb);
2767 nargs = LLVMCountParamTypes (method_type);
2768 args = g_new0 (LLVMValueRef, nargs);
2769 for (i = 0; i < nargs; ++i) {
2770 args [i] = LLVMGetParam (tramp, i);
2771 if (i == ctx->this_arg_pindex) {
2772 LLVMTypeRef arg_type = LLVMTypeOf (args [i]);
2774 args [i] = LLVMBuildPtrToInt (builder, args [i], IntPtrType (), "");
2775 args [i] = LLVMBuildAdd (builder, args [i], LLVMConstInt (IntPtrType (), sizeof (MonoObject), FALSE), "");
2776 args [i] = LLVMBuildIntToPtr (builder, args [i], arg_type, "");
2779 call = LLVMBuildCall (builder, method, args, nargs, "");
2780 if (!ctx->llvm_only && ctx->rgctx_arg_pindex != -1)
2781 LLVMAddInstrAttribute (call, 1 + ctx->rgctx_arg_pindex, LLVMInRegAttribute);
2782 if (linfo->ret.storage == LLVMArgVtypeByRef)
2783 LLVMAddInstrAttribute (call, 1 + linfo->vret_arg_pindex, LLVMStructRetAttribute);
2785 // FIXME: This causes assertions in clang
2786 //mono_llvm_set_must_tail (call);
2787 if (LLVMGetReturnType (method_type) == LLVMVoidType ())
2788 LLVMBuildRetVoid (builder);
2790 LLVMBuildRet (builder, call);
2792 g_hash_table_insert (ctx->module->idx_to_unbox_tramp, GINT_TO_POINTER (method_index), tramp);
2798 * Emit code to load/convert arguments.
2801 emit_entry_bb (EmitContext *ctx, LLVMBuilderRef builder)
2804 MonoCompile *cfg = ctx->cfg;
2805 MonoMethodSignature *sig = ctx->sig;
2806 LLVMCallInfo *linfo = ctx->linfo;
2810 LLVMBuilderRef old_builder = ctx->builder;
2811 ctx->builder = builder;
2813 ctx->alloca_builder = create_builder (ctx);
2816 * Handle indirect/volatile variables by allocating memory for them
2817 * using 'alloca', and storing their address in a temporary.
2819 for (i = 0; i < cfg->num_varinfo; ++i) {
2820 MonoInst *var = cfg->varinfo [i];
2823 if (var->opcode == OP_GSHAREDVT_LOCAL || var->opcode == OP_GSHAREDVT_ARG_REGOFFSET) {
2824 } 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))) {
2825 vtype = type_to_llvm_type (ctx, var->inst_vtype);
2828 /* Could be already created by an OP_VPHI */
2829 if (!ctx->addresses [var->dreg]) {
2830 ctx->addresses [var->dreg] = build_alloca (ctx, var->inst_vtype);
2831 //LLVMSetValueName (ctx->addresses [var->dreg], g_strdup_printf ("vreg_loc_%d", var->dreg));
2833 ctx->vreg_cli_types [var->dreg] = var->inst_vtype;
2837 names = g_new (char *, sig->param_count);
2838 mono_method_get_param_names (cfg->method, (const char **) names);
2840 for (i = 0; i < sig->param_count; ++i) {
2841 LLVMArgInfo *ainfo = &linfo->args [i + sig->hasthis];
2842 int reg = cfg->args [i + sig->hasthis]->dreg;
2845 pindex = ainfo->pindex;
2847 switch (ainfo->storage) {
2848 case LLVMArgVtypeInReg:
2849 case LLVMArgAsFpArgs: {
2850 LLVMValueRef args [8];
2853 pindex += ainfo->ndummy_fpargs;
2855 /* The argument is received as a set of int/fp arguments, store them into the real argument */
2856 memset (args, 0, sizeof (args));
2857 if (ainfo->storage == LLVMArgVtypeInReg) {
2858 args [0] = LLVMGetParam (ctx->lmethod, pindex);
2859 if (ainfo->pair_storage [1] != LLVMArgNone)
2860 args [1] = LLVMGetParam (ctx->lmethod, pindex + 1);
2862 g_assert (ainfo->nslots <= 8);
2863 for (j = 0; j < ainfo->nslots; ++j)
2864 args [j] = LLVMGetParam (ctx->lmethod, pindex + j);
2866 ctx->addresses [reg] = build_alloca (ctx, ainfo->type);
2868 emit_args_to_vtype (ctx, builder, ainfo->type, ctx->addresses [reg], ainfo, args);
2870 if (ainfo->storage == LLVMArgVtypeInReg && MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (ainfo->type))) {
2871 /* Treat these as normal values */
2872 ctx->values [reg] = LLVMBuildLoad (builder, ctx->addresses [reg], "");
2876 case LLVMArgVtypeByVal: {
2877 ctx->addresses [reg] = LLVMGetParam (ctx->lmethod, pindex);
2879 if (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (ainfo->type))) {
2880 /* Treat these as normal values */
2881 ctx->values [reg] = LLVMBuildLoad (builder, ctx->addresses [reg], "");
2885 case LLVMArgVtypeByRef: {
2886 /* The argument is passed by ref */
2887 ctx->addresses [reg] = LLVMGetParam (ctx->lmethod, pindex);
2890 case LLVMArgScalarByRef: {
2892 name = g_strdup_printf ("arg_%s", names [i]);
2894 name = g_strdup_printf ("arg_%d", i);
2895 ctx->values [reg] = LLVMBuildLoad (builder, LLVMGetParam (ctx->lmethod, pindex), name);
2899 case LLVMArgAsIArgs: {
2900 LLVMValueRef arg = LLVMGetParam (ctx->lmethod, pindex);
2902 ctx->addresses [reg] = build_alloca (ctx, ainfo->type);
2904 /* The argument is received as an array of ints, store it into the real argument */
2905 LLVMBuildStore (ctx->builder, arg, convert (ctx, ctx->addresses [reg], LLVMPointerType (LLVMTypeOf (arg), 0)));
2908 case LLVMArgVtypeAsScalar:
2909 g_assert_not_reached ();
2911 case LLVMArgGsharedvtFixed: {
2912 /* These are non-gsharedvt arguments passed by ref, the rest of the IR treats them as scalars */
2913 LLVMValueRef arg = LLVMGetParam (ctx->lmethod, pindex);
2916 name = g_strdup_printf ("arg_%s", names [i]);
2918 name = g_strdup_printf ("arg_%d", i);
2920 ctx->values [reg] = LLVMBuildLoad (builder, convert (ctx, arg, LLVMPointerType (type_to_llvm_type (ctx, ainfo->type), 0)), name);
2923 case LLVMArgGsharedvtFixedVtype: {
2924 LLVMValueRef arg = LLVMGetParam (ctx->lmethod, pindex);
2927 name = g_strdup_printf ("vtype_arg_%s", names [i]);
2929 name = g_strdup_printf ("vtype_arg_%d", i);
2931 /* Non-gsharedvt vtype argument passed by ref, the rest of the IR treats it as a vtype */
2932 g_assert (ctx->addresses [reg]);
2933 LLVMSetValueName (ctx->addresses [reg], name);
2934 LLVMBuildStore (builder, LLVMBuildLoad (builder, convert (ctx, arg, LLVMPointerType (type_to_llvm_type (ctx, ainfo->type), 0)), ""), ctx->addresses [reg]);
2937 case LLVMArgGsharedvtVariable:
2938 /* The IR treats these as variables with addresses */
2939 ctx->addresses [reg] = LLVMGetParam (ctx->lmethod, pindex);
2942 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));
2949 emit_volatile_store (ctx, cfg->vret_addr->dreg);
2951 emit_volatile_store (ctx, cfg->args [0]->dreg);
2952 for (i = 0; i < sig->param_count; ++i)
2953 if (!mini_type_is_vtype (sig->params [i]))
2954 emit_volatile_store (ctx, cfg->args [i + sig->hasthis]->dreg);
2956 if (sig->hasthis && !cfg->rgctx_var && cfg->gshared) {
2957 LLVMValueRef this_alloc;
2960 * The exception handling code needs the location where the this argument was
2961 * stored for gshared methods. We create a separate alloca to hold it, and mark it
2962 * with the "mono.this" custom metadata to tell llvm that it needs to save its
2963 * location into the LSDA.
2965 this_alloc = mono_llvm_build_alloca (builder, ThisType (), LLVMConstInt (LLVMInt32Type (), 1, FALSE), 0, "");
2966 /* This volatile store will keep the alloca alive */
2967 mono_llvm_build_store (builder, ctx->values [cfg->args [0]->dreg], this_alloc, TRUE, LLVM_BARRIER_NONE);
2969 set_metadata_flag (this_alloc, "mono.this");
2972 if (cfg->rgctx_var) {
2973 LLVMValueRef rgctx_alloc, store;
2976 * We handle the rgctx arg similarly to the this pointer.
2978 g_assert (ctx->addresses [cfg->rgctx_var->dreg]);
2979 rgctx_alloc = ctx->addresses [cfg->rgctx_var->dreg];
2980 /* This volatile store will keep the alloca alive */
2981 store = mono_llvm_build_store (builder, convert (ctx, ctx->rgctx_arg, IntPtrType ()), rgctx_alloc, TRUE, LLVM_BARRIER_NONE);
2983 set_metadata_flag (rgctx_alloc, "mono.this");
2986 /* Initialize the method if needed */
2987 if (cfg->compile_aot && ctx->llvm_only) {
2988 /* Emit a location for the initialization code */
2989 ctx->init_bb = gen_bb (ctx, "INIT_BB");
2990 ctx->inited_bb = gen_bb (ctx, "INITED_BB");
2992 LLVMBuildBr (ctx->builder, ctx->init_bb);
2993 builder = ctx->builder = create_builder (ctx);
2994 LLVMPositionBuilderAtEnd (ctx->builder, ctx->inited_bb);
2995 ctx->bblocks [cfg->bb_entry->block_num].end_bblock = ctx->inited_bb;
2998 /* Compute nesting between clauses */
2999 ctx->nested_in = (GSList**)mono_mempool_alloc0 (cfg->mempool, sizeof (GSList*) * cfg->header->num_clauses);
3000 for (i = 0; i < cfg->header->num_clauses; ++i) {
3001 for (j = 0; j < cfg->header->num_clauses; ++j) {
3002 MonoExceptionClause *clause1 = &cfg->header->clauses [i];
3003 MonoExceptionClause *clause2 = &cfg->header->clauses [j];
3005 if (i != j && clause1->try_offset >= clause2->try_offset && clause1->handler_offset <= clause2->handler_offset)
3006 ctx->nested_in [i] = g_slist_prepend_mempool (cfg->mempool, ctx->nested_in [i], GINT_TO_POINTER (j));
3011 * For finally clauses, create an indicator variable telling OP_ENDFINALLY whenever
3012 * it needs to continue normally, or return back to the exception handling system.
3014 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
3018 if (!(bb->region != -1 && (bb->flags & BB_EXCEPTION_HANDLER)))
3021 clause_index = MONO_REGION_CLAUSE_INDEX (bb->region);
3022 g_hash_table_insert (ctx->region_to_handler, GUINT_TO_POINTER (mono_get_block_region_notry (cfg, bb->region)), bb);
3023 g_hash_table_insert (ctx->clause_to_handler, GINT_TO_POINTER (clause_index), bb);
3025 if (bb->in_scount == 0) {
3028 sprintf (name, "finally_ind_bb%d", bb->block_num);
3029 val = LLVMBuildAlloca (builder, LLVMInt32Type (), name);
3030 LLVMBuildStore (builder, LLVMConstInt (LLVMInt32Type (), 0, FALSE), val);
3032 ctx->bblocks [bb->block_num].finally_ind = val;
3034 /* Create a variable to hold the exception var */
3036 ctx->ex_var = LLVMBuildAlloca (builder, ObjRefType (), "exvar");
3040 * Create a new bblock which CALL_HANDLER/landing pads can branch to, because branching to the
3041 * LLVM bblock containing a landing pad causes problems for the
3042 * LLVM optimizer passes.
3044 sprintf (name, "BB%d_CALL_HANDLER_TARGET", bb->block_num);
3045 ctx->bblocks [bb->block_num].call_handler_target_bb = LLVMAppendBasicBlock (ctx->lmethod, name);
3047 ctx->builder = old_builder;
3051 process_call (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, MonoInst *ins)
3053 MonoCompile *cfg = ctx->cfg;
3054 LLVMModuleRef lmodule = ctx->lmodule;
3055 LLVMValueRef *values = ctx->values;
3056 LLVMValueRef *addresses = ctx->addresses;
3057 MonoCallInst *call = (MonoCallInst*)ins;
3058 MonoMethodSignature *sig = call->signature;
3059 LLVMValueRef callee = NULL, lcall;
3061 LLVMCallInfo *cinfo;
3065 LLVMTypeRef llvm_sig;
3067 gboolean is_virtual, calli, preserveall;
3068 LLVMBuilderRef builder = *builder_ref;
3070 if (call->signature->call_convention != MONO_CALL_DEFAULT) {
3071 set_failure (ctx, "non-default callconv");
3075 cinfo = call->cinfo;
3077 if (call->rgctx_arg_reg)
3078 cinfo->rgctx_arg = TRUE;
3079 if (call->imt_arg_reg)
3080 cinfo->imt_arg = TRUE;
3082 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);
3084 llvm_sig = sig_to_llvm_sig_full (ctx, sig, cinfo);
3088 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);
3089 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);
3091 preserveall = FALSE;
3093 /* FIXME: Avoid creating duplicate methods */
3095 if (ins->flags & MONO_INST_HAS_METHOD) {
3099 if (cfg->compile_aot) {
3100 callee = get_callee (ctx, llvm_sig, MONO_PATCH_INFO_METHOD, call->method);
3102 set_failure (ctx, "can't encode patch");
3105 if (cfg->llvm_only && call->method->klass->image->assembly == ctx->module->assembly) {
3107 * Collect instructions representing the callee into a hash so they can be replaced
3108 * by the llvm method for the callee if the callee turns out to be direct
3109 * callable. Currently this only requires it to not fail llvm compilation.
3111 GSList *l = (GSList*)g_hash_table_lookup (ctx->method_to_callers, call->method);
3112 l = g_slist_prepend (l, callee);
3113 g_hash_table_insert (ctx->method_to_callers, call->method, l);
3116 callee = LLVMAddFunction (lmodule, "", llvm_sig);
3119 mono_create_jit_trampoline_in_domain (mono_domain_get (),
3121 LLVMAddGlobalMapping (ctx->module->ee, callee, target);
3125 if (!cfg->llvm_only && call->method && strstr (call->method->klass->name, "AsyncVoidMethodBuilder")) {
3126 /* LLVM miscompiles async methods */
3127 set_failure (ctx, "#13734");
3132 MonoJitICallInfo *info = mono_find_jit_icall_by_addr (call->fptr);
3138 memset (&ji, 0, sizeof (ji));
3139 ji.type = MONO_PATCH_INFO_JIT_ICALL_ADDR;
3140 ji.data.target = info->name;
3142 target = mono_resolve_patch_target (cfg->method, cfg->domain, NULL, &ji, FALSE);
3144 if (cfg->compile_aot) {
3145 callee = get_callee (ctx, llvm_sig, MONO_PATCH_INFO_INTERNAL_METHOD, (char*)info->name);
3147 set_failure (ctx, "can't encode patch");
3151 callee = LLVMAddFunction (lmodule, "", llvm_sig);
3152 target = (gpointer)mono_icall_get_wrapper (info);
3153 LLVMAddGlobalMapping (ctx->module->ee, callee, target);
3156 if (cfg->compile_aot) {
3158 if (cfg->abs_patches) {
3159 MonoJumpInfo *abs_ji = (MonoJumpInfo*)g_hash_table_lookup (cfg->abs_patches, call->fptr);
3161 callee = get_callee (ctx, llvm_sig, abs_ji->type, abs_ji->data.target);
3163 set_failure (ctx, "can't encode patch");
3169 set_failure (ctx, "aot");
3173 callee = LLVMAddFunction (lmodule, "", llvm_sig);
3175 if (cfg->abs_patches) {
3176 MonoJumpInfo *abs_ji = (MonoJumpInfo*)g_hash_table_lookup (cfg->abs_patches, call->fptr);
3179 * FIXME: Some trampolines might have
3180 * their own calling convention on some platforms.
3182 target = mono_resolve_patch_target (cfg->method, cfg->domain, NULL, abs_ji, FALSE);
3183 LLVMAddGlobalMapping (ctx->module->ee, callee, target);
3187 LLVMAddGlobalMapping (ctx->module->ee, callee, (gpointer)call->fptr);
3193 int size = sizeof (gpointer);
3196 g_assert (ins->inst_offset % size == 0);
3197 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
3199 callee = convert (ctx, LLVMBuildLoad (builder, LLVMBuildGEP (builder, convert (ctx, values [ins->inst_basereg], LLVMPointerType (LLVMPointerType (IntPtrType (), 0), 0)), &index, 1, ""), ""), LLVMPointerType (llvm_sig, 0));
3201 callee = convert (ctx, values [ins->sreg1], LLVMPointerType (llvm_sig, 0));
3203 if (ins->flags & MONO_INST_HAS_METHOD) {
3208 * Collect and convert arguments
3210 nargs = (sig->param_count * 16) + sig->hasthis + vretaddr + call->rgctx_reg + call->imt_arg_reg;
3211 len = sizeof (LLVMValueRef) * nargs;
3212 args = (LLVMValueRef*)alloca (len);
3213 memset (args, 0, len);
3214 l = call->out_ireg_args;
3216 if (call->rgctx_arg_reg) {
3217 g_assert (values [call->rgctx_arg_reg]);
3218 g_assert (cinfo->rgctx_arg_pindex < nargs);
3220 * On ARM, the imt/rgctx argument is passed in a caller save register, but some of our trampolines etc. clobber it, leading to
3221 * problems is LLVM moves the arg assignment earlier. To work around this, save the argument into a stack slot and load
3222 * it using a volatile load.
3225 if (!ctx->imt_rgctx_loc)
3226 ctx->imt_rgctx_loc = build_alloca_llvm_type (ctx, ctx->module->ptr_type, sizeof (gpointer));
3227 LLVMBuildStore (builder, convert (ctx, ctx->values [call->rgctx_arg_reg], ctx->module->ptr_type), ctx->imt_rgctx_loc);
3228 args [cinfo->rgctx_arg_pindex] = mono_llvm_build_load (builder, ctx->imt_rgctx_loc, "", TRUE, LLVM_BARRIER_NONE);
3230 args [cinfo->rgctx_arg_pindex] = convert (ctx, values [call->rgctx_arg_reg], ctx->module->ptr_type);
3233 if (call->imt_arg_reg) {
3234 g_assert (!ctx->llvm_only);
3235 g_assert (values [call->imt_arg_reg]);
3236 g_assert (cinfo->imt_arg_pindex < nargs);
3238 if (!ctx->imt_rgctx_loc)
3239 ctx->imt_rgctx_loc = build_alloca_llvm_type (ctx, ctx->module->ptr_type, sizeof (gpointer));
3240 LLVMBuildStore (builder, convert (ctx, ctx->values [call->imt_arg_reg], ctx->module->ptr_type), ctx->imt_rgctx_loc);
3241 args [cinfo->imt_arg_pindex] = mono_llvm_build_load (builder, ctx->imt_rgctx_loc, "", TRUE, LLVM_BARRIER_NONE);
3243 args [cinfo->imt_arg_pindex] = convert (ctx, values [call->imt_arg_reg], ctx->module->ptr_type);
3246 switch (cinfo->ret.storage) {
3247 case LLVMArgGsharedvtVariable: {
3248 MonoInst *var = get_vreg_to_inst (cfg, call->inst.dreg);
3250 if (var && var->opcode == OP_GSHAREDVT_LOCAL) {
3251 args [cinfo->vret_arg_pindex] = convert (ctx, emit_gsharedvt_ldaddr (ctx, var->dreg), IntPtrType ());
3253 g_assert (addresses [call->inst.dreg]);
3254 args [cinfo->vret_arg_pindex] = addresses [call->inst.dreg];
3260 if (!addresses [call->inst.dreg])
3261 addresses [call->inst.dreg] = build_alloca (ctx, sig->ret);
3262 g_assert (cinfo->vret_arg_pindex < nargs);
3263 if (cinfo->ret.storage == LLVMArgVtypeByRef)
3264 args [cinfo->vret_arg_pindex] = addresses [call->inst.dreg];
3266 args [cinfo->vret_arg_pindex] = LLVMBuildPtrToInt (builder, addresses [call->inst.dreg], IntPtrType (), "");
3272 * Sometimes the same method is called with two different signatures (i.e. with and without 'this'), so
3273 * use the real callee for argument type conversion.
3275 LLVMTypeRef callee_type = LLVMGetElementType (LLVMTypeOf (callee));
3276 LLVMTypeRef *param_types = (LLVMTypeRef*)g_alloca (sizeof (LLVMTypeRef) * LLVMCountParamTypes (callee_type));
3277 LLVMGetParamTypes (callee_type, param_types);
3279 for (i = 0; i < sig->param_count + sig->hasthis; ++i) {
3282 LLVMArgInfo *ainfo = &call->cinfo->args [i];
3284 pindex = ainfo->pindex;
3286 regpair = (guint32)(gssize)(l->data);
3287 reg = regpair & 0xffffff;
3288 args [pindex] = values [reg];
3289 switch (ainfo->storage) {
3290 case LLVMArgVtypeInReg:
3291 case LLVMArgAsFpArgs: {
3295 for (j = 0; j < ainfo->ndummy_fpargs; ++j)
3296 args [pindex + j] = LLVMConstNull (LLVMDoubleType ());
3297 pindex += ainfo->ndummy_fpargs;
3299 g_assert (addresses [reg]);
3300 emit_vtype_to_args (ctx, builder, ainfo->type, addresses [reg], ainfo, args + pindex, &nargs);
3304 // FIXME: Get rid of the VMOVE
3307 case LLVMArgVtypeByVal:
3308 g_assert (addresses [reg]);
3309 args [pindex] = addresses [reg];
3311 case LLVMArgVtypeByRef:
3312 case LLVMArgScalarByRef: {
3313 g_assert (addresses [reg]);
3314 args [pindex] = convert (ctx, addresses [reg], LLVMPointerType (type_to_llvm_arg_type (ctx, ainfo->type), 0));
3317 case LLVMArgAsIArgs:
3318 g_assert (addresses [reg]);
3319 args [pindex] = LLVMBuildLoad (ctx->builder, convert (ctx, addresses [reg], LLVMPointerType (LLVMArrayType (IntPtrType (), ainfo->nslots), 0)), "");
3321 case LLVMArgVtypeAsScalar:
3322 g_assert_not_reached ();
3324 case LLVMArgGsharedvtFixed:
3325 case LLVMArgGsharedvtFixedVtype:
3326 g_assert (addresses [reg]);
3327 args [pindex] = convert (ctx, addresses [reg], LLVMPointerType (type_to_llvm_arg_type (ctx, ainfo->type), 0));
3329 case LLVMArgGsharedvtVariable:
3330 g_assert (addresses [reg]);
3331 args [pindex] = convert (ctx, addresses [reg], LLVMPointerType (IntPtrType (), 0));
3334 g_assert (args [pindex]);
3335 if (i == 0 && sig->hasthis)
3336 args [pindex] = convert (ctx, args [pindex], param_types [pindex]);
3338 args [pindex] = convert (ctx, args [pindex], type_to_llvm_arg_type (ctx, ainfo->type));
3341 g_assert (pindex <= nargs);
3346 // FIXME: Align call sites
3352 lcall = emit_call (ctx, bb, &builder, callee, args, LLVMCountParamTypes (llvm_sig));
3355 * Modify cconv and parameter attributes to pass rgctx/imt correctly.
3357 #if defined(MONO_ARCH_IMT_REG) && defined(MONO_ARCH_RGCTX_REG)
3358 g_assert (MONO_ARCH_IMT_REG == MONO_ARCH_RGCTX_REG);
3360 /* The two can't be used together, so use only one LLVM calling conv to pass them */
3361 g_assert (!(call->rgctx_arg_reg && call->imt_arg_reg));
3362 if (!sig->pinvoke && !cfg->llvm_only)
3363 LLVMSetInstructionCallConv (lcall, LLVMMono1CallConv);
3365 mono_llvm_set_call_preserveall_cc (lcall);
3367 if (cinfo->ret.storage == LLVMArgVtypeByRef)
3368 LLVMAddInstrAttribute (lcall, 1 + cinfo->vret_arg_pindex, LLVMStructRetAttribute);
3369 if (!ctx->llvm_only && call->rgctx_arg_reg)
3370 LLVMAddInstrAttribute (lcall, 1 + cinfo->rgctx_arg_pindex, LLVMInRegAttribute);
3371 if (call->imt_arg_reg)
3372 LLVMAddInstrAttribute (lcall, 1 + cinfo->imt_arg_pindex, LLVMInRegAttribute);
3374 /* Add byval attributes if needed */
3375 for (i = 0; i < sig->param_count; ++i) {
3376 LLVMArgInfo *ainfo = &call->cinfo->args [i + sig->hasthis];
3378 if (ainfo && ainfo->storage == LLVMArgVtypeByVal)
3379 LLVMAddInstrAttribute (lcall, 1 + ainfo->pindex, LLVMByValAttribute);
3383 * Convert the result
3385 switch (cinfo->ret.storage) {
3386 case LLVMArgVtypeInReg: {
3387 LLVMValueRef regs [2];
3389 if (LLVMTypeOf (lcall) == LLVMVoidType ())
3393 if (!addresses [ins->dreg])
3394 addresses [ins->dreg] = build_alloca (ctx, sig->ret);
3396 regs [0] = LLVMBuildExtractValue (builder, lcall, 0, "");
3397 if (cinfo->ret.pair_storage [1] != LLVMArgNone)
3398 regs [1] = LLVMBuildExtractValue (builder, lcall, 1, "");
3399 emit_args_to_vtype (ctx, builder, sig->ret, addresses [ins->dreg], &cinfo->ret, regs);
3402 case LLVMArgVtypeByVal:
3403 if (!addresses [call->inst.dreg])
3404 addresses [call->inst.dreg] = build_alloca (ctx, sig->ret);
3405 LLVMBuildStore (builder, lcall, addresses [call->inst.dreg]);
3407 case LLVMArgFpStruct:
3408 if (!addresses [call->inst.dreg])
3409 addresses [call->inst.dreg] = build_alloca (ctx, sig->ret);
3410 LLVMBuildStore (builder, lcall, convert_full (ctx, addresses [call->inst.dreg], LLVMPointerType (LLVMTypeOf (lcall), 0), FALSE));
3412 case LLVMArgVtypeAsScalar:
3413 if (!addresses [call->inst.dreg])
3414 addresses [call->inst.dreg] = build_alloca (ctx, sig->ret);
3415 LLVMBuildStore (builder, lcall, convert_full (ctx, addresses [call->inst.dreg], LLVMPointerType (LLVMTypeOf (lcall), 0), FALSE));
3417 case LLVMArgVtypeRetAddr:
3418 case LLVMArgVtypeByRef:
3420 case LLVMArgScalarRetAddr:
3421 /* Normal scalar returned using a vtype return argument */
3422 values [ins->dreg] = LLVMBuildLoad (builder, convert_full (ctx, addresses [call->inst.dreg], LLVMPointerType (type_to_llvm_type (ctx, sig->ret), 0), FALSE), "");
3424 case LLVMArgGsharedvtVariable:
3426 case LLVMArgGsharedvtFixed:
3427 case LLVMArgGsharedvtFixedVtype:
3428 values [ins->dreg] = LLVMBuildLoad (builder, convert_full (ctx, addresses [call->inst.dreg], LLVMPointerType (type_to_llvm_type (ctx, sig->ret), 0), FALSE), "");
3431 if (sig->ret->type != MONO_TYPE_VOID)
3432 /* If the method returns an unsigned value, need to zext it */
3433 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));
3437 *builder_ref = ctx->builder;
3441 emit_llvmonly_throw (EmitContext *ctx, MonoBasicBlock *bb, gboolean rethrow, LLVMValueRef exc)
3443 const char *icall_name = rethrow ? "mono_llvm_rethrow_exception" : "mono_llvm_throw_exception";
3444 LLVMValueRef callee = rethrow ? ctx->module->rethrow : ctx->module->throw_icall;
3446 LLVMTypeRef exc_type = type_to_llvm_type (ctx, &mono_get_exception_class ()->byval_arg);
3449 LLVMTypeRef fun_sig = LLVMFunctionType1 (LLVMVoidType (), exc_type, FALSE);
3451 if (ctx->cfg->compile_aot) {
3452 callee = get_callee (ctx, fun_sig, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
3454 callee = LLVMAddFunction (ctx->lmodule, icall_name, fun_sig);
3455 LLVMAddGlobalMapping (ctx->module->ee, callee, resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name));
3456 mono_memory_barrier ();
3459 ctx->module->rethrow = callee;
3461 ctx->module->throw_icall = callee;
3465 LLVMValueRef args [2];
3467 args [0] = convert (ctx, exc, exc_type);
3468 emit_call (ctx, bb, &ctx->builder, callee, args, 1);
3470 LLVMBuildUnreachable (ctx->builder);
3472 ctx->builder = create_builder (ctx);
3476 emit_throw (EmitContext *ctx, MonoBasicBlock *bb, gboolean rethrow, LLVMValueRef exc)
3478 MonoMethodSignature *throw_sig;
3479 LLVMValueRef callee, arg;
3480 const char *icall_name;
3482 callee = rethrow ? ctx->module->rethrow : ctx->module->throw_icall;
3483 icall_name = rethrow ? "mono_arch_rethrow_exception" : "mono_arch_throw_exception";
3486 throw_sig = mono_metadata_signature_alloc (mono_get_corlib (), 1);
3487 throw_sig->ret = &mono_get_void_class ()->byval_arg;
3488 throw_sig->params [0] = &mono_get_object_class ()->byval_arg;
3489 if (ctx->cfg->compile_aot) {
3490 callee = get_callee (ctx, sig_to_llvm_sig (ctx, throw_sig), MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
3492 callee = LLVMAddFunction (ctx->lmodule, icall_name, sig_to_llvm_sig (ctx, throw_sig));
3496 * LLVM doesn't push the exception argument, so we need a different
3499 LLVMAddGlobalMapping (ctx->module->ee, callee, resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, rethrow ? "llvm_rethrow_exception_trampoline" : "llvm_throw_exception_trampoline"));
3501 LLVMAddGlobalMapping (ctx->module->ee, callee, resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name));
3505 mono_memory_barrier ();
3507 ctx->module->rethrow = callee;
3509 ctx->module->throw_icall = callee;
3511 arg = convert (ctx, exc, type_to_llvm_type (ctx, &mono_get_object_class ()->byval_arg));
3512 emit_call (ctx, bb, &ctx->builder, callee, &arg, 1);
3516 emit_resume_eh (EmitContext *ctx, MonoBasicBlock *bb)
3518 const char *icall_name = "mono_llvm_resume_exception";
3519 LLVMValueRef callee = ctx->module->resume_eh;
3521 LLVMTypeRef fun_sig = LLVMFunctionType0 (LLVMVoidType (), FALSE);
3524 if (ctx->cfg->compile_aot) {
3525 callee = get_callee (ctx, fun_sig, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
3527 callee = LLVMAddFunction (ctx->lmodule, icall_name, fun_sig);
3528 LLVMAddGlobalMapping (ctx->module->ee, callee, resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name));
3529 mono_memory_barrier ();
3531 ctx->module->resume_eh = callee;
3535 emit_call (ctx, bb, &ctx->builder, callee, NULL, 0);
3537 LLVMBuildUnreachable (ctx->builder);
3539 ctx->builder = create_builder (ctx);
3543 mono_llvm_emit_clear_exception_call (EmitContext *ctx, LLVMBuilderRef builder)
3545 const char *icall_name = "mono_llvm_clear_exception";
3547 LLVMTypeRef call_sig = LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE);
3548 LLVMValueRef callee = NULL;
3551 if (ctx->cfg->compile_aot) {
3552 callee = get_callee (ctx, call_sig, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
3554 // FIXME: This is broken.
3555 callee = LLVMAddFunction (ctx->lmodule, icall_name, call_sig);
3559 g_assert (builder && callee);
3561 return LLVMBuildCall (builder, callee, NULL, 0, "");
3565 mono_llvm_emit_load_exception_call (EmitContext *ctx, LLVMBuilderRef builder)
3567 const char *icall_name = "mono_llvm_load_exception";
3569 LLVMTypeRef call_sig = LLVMFunctionType (ObjRefType (), NULL, 0, FALSE);
3570 LLVMValueRef callee = NULL;
3573 if (ctx->cfg->compile_aot) {
3574 callee = get_callee (ctx, call_sig, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
3576 // FIXME: This is broken.
3577 callee = LLVMAddFunction (ctx->lmodule, icall_name, call_sig);
3581 g_assert (builder && callee);
3583 return LLVMBuildCall (builder, callee, NULL, 0, icall_name);
3588 mono_llvm_emit_match_exception_call (EmitContext *ctx, LLVMBuilderRef builder, gint32 region_start, gint32 region_end)
3590 const char *icall_name = "mono_llvm_match_exception";
3592 ctx->builder = builder;
3594 const int num_args = 5;
3595 LLVMValueRef args [num_args];
3596 args [0] = convert (ctx, get_aotconst (ctx, MONO_PATCH_INFO_AOT_JIT_INFO, GINT_TO_POINTER (ctx->cfg->method_index)), IntPtrType ());
3597 args [1] = LLVMConstInt (LLVMInt32Type (), region_start, 0);
3598 args [2] = LLVMConstInt (LLVMInt32Type (), region_end, 0);
3599 if (ctx->cfg->rgctx_var) {
3600 LLVMValueRef rgctx_alloc = ctx->addresses [ctx->cfg->rgctx_var->dreg];
3601 g_assert (rgctx_alloc);
3602 args [3] = LLVMBuildLoad (builder, convert (ctx, rgctx_alloc, LLVMPointerType (IntPtrType (), 0)), "");
3604 args [3] = LLVMConstInt (IntPtrType (), 0, 0);
3607 args [4] = convert (ctx, ctx->this_arg, IntPtrType ());
3609 args [4] = LLVMConstInt (IntPtrType (), 0, 0);
3611 LLVMTypeRef match_sig = LLVMFunctionType5 (LLVMInt32Type (), IntPtrType (), LLVMInt32Type (), LLVMInt32Type (), IntPtrType (), IntPtrType (), FALSE);
3612 LLVMValueRef callee = ctx->module->match_exc;
3615 if (ctx->cfg->compile_aot) {
3616 ctx->builder = builder;
3617 // get_callee expects ctx->builder to be the emitting builder
3618 callee = get_callee (ctx, match_sig, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
3620 callee = ctx->module->match_exc = LLVMAddFunction (ctx->lmodule, icall_name, match_sig);
3621 LLVMAddGlobalMapping (ctx->module->ee, ctx->module->match_exc, resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name));
3622 ctx->module->match_exc = callee;
3623 mono_memory_barrier ();
3627 g_assert (builder && callee);
3629 g_assert (ctx->ex_var);
3631 return LLVMBuildCall (builder, callee, args, num_args, icall_name);
3634 // FIXME: This won't work because the code-finding makes this
3636 /*#define MONO_PERSONALITY_DEBUG*/
3638 #ifdef MONO_PERSONALITY_DEBUG
3639 static const gboolean use_debug_personality = TRUE;
3640 static const char *default_personality_name = "mono_debug_personality";
3642 static const gboolean use_debug_personality = FALSE;
3643 static const char *default_personality_name = "__gxx_personality_v0";
3647 default_cpp_lpad_exc_signature (void)
3649 static gboolean inited = FALSE;
3650 static LLVMTypeRef sig;
3653 LLVMTypeRef signature [2];
3654 signature [0] = LLVMPointerType (LLVMInt8Type (), 0);
3655 signature [1] = LLVMInt32Type ();
3656 sig = LLVMStructType (signature, 2, FALSE);
3664 get_mono_personality (EmitContext *ctx)
3666 LLVMValueRef personality = NULL;
3667 static gint32 mapping_inited = FALSE;
3668 LLVMTypeRef personality_type = LLVMFunctionType (LLVMInt32Type (), NULL, 0, TRUE);
3670 if (!use_debug_personality) {
3671 if (ctx->cfg->compile_aot) {
3672 personality = LLVMGetNamedFunction (ctx->lmodule, default_personality_name);
3673 } else if (InterlockedCompareExchange (&mapping_inited, 1, 0) == 0) {
3674 personality = LLVMAddFunction (ctx->lmodule, default_personality_name, personality_type);
3675 LLVMAddGlobalMapping (ctx->module->ee, personality, personality);
3678 if (ctx->cfg->compile_aot) {
3679 personality = get_callee (ctx, personality_type, MONO_PATCH_INFO_INTERNAL_METHOD, default_personality_name);
3681 personality = LLVMAddFunction (ctx->lmodule, default_personality_name, personality_type);
3682 LLVMAddGlobalMapping (ctx->module->ee, personality, resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, default_personality_name));
3683 mono_memory_barrier ();
3687 g_assert (personality);
3691 static LLVMBasicBlockRef
3692 emit_landing_pad (EmitContext *ctx, int group_index, int group_size)
3694 MonoCompile *cfg = ctx->cfg;
3695 LLVMBuilderRef old_builder = ctx->builder;
3696 MonoExceptionClause *group_start = cfg->header->clauses + group_index;
3698 LLVMBuilderRef lpadBuilder = create_builder (ctx);
3699 ctx->builder = lpadBuilder;
3701 MonoBasicBlock *handler_bb = cfg->cil_offset_to_bb [CLAUSE_START (group_start)];
3702 g_assert (handler_bb);
3704 // <resultval> = landingpad <somety> personality <type> <pers_fn> <clause>+
3705 LLVMValueRef personality = get_mono_personality (ctx);
3706 g_assert (personality);
3708 char *bb_name = g_strdup_printf ("LPAD%d_BB", group_index);
3709 LLVMBasicBlockRef lpad_bb = gen_bb (ctx, bb_name);
3711 LLVMPositionBuilderAtEnd (lpadBuilder, lpad_bb);
3712 LLVMValueRef landing_pad = LLVMBuildLandingPad (lpadBuilder, default_cpp_lpad_exc_signature (), personality, 0, "");
3713 g_assert (landing_pad);
3715 LLVMValueRef cast = LLVMBuildBitCast (lpadBuilder, ctx->module->sentinel_exception, LLVMPointerType (LLVMInt8Type (), 0), "int8TypeInfo");
3716 LLVMAddClause (landing_pad, cast);
3718 LLVMBasicBlockRef resume_bb = gen_bb (ctx, "RESUME_BB");
3719 LLVMBuilderRef resume_builder = create_builder (ctx);
3720 ctx->builder = resume_builder;
3721 LLVMPositionBuilderAtEnd (resume_builder, resume_bb);
3723 emit_resume_eh (ctx, handler_bb);
3726 ctx->builder = lpadBuilder;
3727 LLVMPositionBuilderAtEnd (lpadBuilder, lpad_bb);
3729 gboolean finally_only = TRUE;
3731 MonoExceptionClause *group_cursor = group_start;
3733 for (int i = 0; i < group_size; i ++) {
3734 if (!(group_cursor->flags & MONO_EXCEPTION_CLAUSE_FINALLY))
3735 finally_only = FALSE;
3741 // Handle landing pad inlining
3743 if (!finally_only) {
3744 // So at each level of the exception stack we will match the exception again.
3745 // During that match, we need to compare against the handler types for the current
3746 // protected region. We send the try start and end so that we can only check against
3747 // handlers for this lexical protected region.
3748 LLVMValueRef match = mono_llvm_emit_match_exception_call (ctx, lpadBuilder, group_start->try_offset, group_start->try_offset + group_start->try_len);
3750 // if returns -1, resume
3751 LLVMValueRef switch_ins = LLVMBuildSwitch (lpadBuilder, match, resume_bb, group_size);
3753 // else move to that target bb
3754 for (int i=0; i < group_size; i++) {
3755 MonoExceptionClause *clause = group_start + i;
3756 int clause_index = clause - cfg->header->clauses;
3757 MonoBasicBlock *handler_bb = (MonoBasicBlock*)g_hash_table_lookup (ctx->clause_to_handler, GINT_TO_POINTER (clause_index));
3758 g_assert (handler_bb);
3759 g_assert (ctx->bblocks [handler_bb->block_num].call_handler_target_bb);
3760 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), clause_index, FALSE), ctx->bblocks [handler_bb->block_num].call_handler_target_bb);
3763 int clause_index = group_start - cfg->header->clauses;
3764 MonoBasicBlock *finally_bb = (MonoBasicBlock*)g_hash_table_lookup (ctx->clause_to_handler, GINT_TO_POINTER (clause_index));
3765 g_assert (finally_bb);
3767 LLVMBuildBr (ctx->builder, ctx->bblocks [finally_bb->block_num].call_handler_target_bb);
3770 ctx->builder = old_builder;
3777 emit_llvmonly_handler_start (EmitContext *ctx, MonoBasicBlock *bb, LLVMBasicBlockRef cbb)
3779 int clause_index = MONO_REGION_CLAUSE_INDEX (bb->region);
3780 MonoExceptionClause *clause = &ctx->cfg->header->clauses [clause_index];
3782 // Make exception available to catch blocks
3783 if (!(clause->flags & MONO_EXCEPTION_CLAUSE_FINALLY)) {
3784 LLVMValueRef mono_exc = mono_llvm_emit_load_exception_call (ctx, ctx->builder);
3786 g_assert (ctx->ex_var);
3787 LLVMBuildStore (ctx->builder, LLVMBuildBitCast (ctx->builder, mono_exc, ObjRefType (), ""), ctx->ex_var);
3789 if (bb->in_scount == 1) {
3790 MonoInst *exvar = bb->in_stack [0];
3791 g_assert (!ctx->values [exvar->dreg]);
3792 g_assert (ctx->ex_var);
3793 ctx->values [exvar->dreg] = LLVMBuildLoad (ctx->builder, ctx->ex_var, "save_exception");
3794 emit_volatile_store (ctx, exvar->dreg);
3797 mono_llvm_emit_clear_exception_call (ctx, ctx->builder);
3800 LLVMBuilderRef handler_builder = create_builder (ctx);
3801 LLVMBasicBlockRef target_bb = ctx->bblocks [bb->block_num].call_handler_target_bb;
3802 LLVMPositionBuilderAtEnd (handler_builder, target_bb);
3804 // Make the handler code end with a jump to cbb
3805 LLVMBuildBr (handler_builder, cbb);
3809 emit_handler_start (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef builder)
3811 MonoCompile *cfg = ctx->cfg;
3812 LLVMValueRef *values = ctx->values;
3813 LLVMModuleRef lmodule = ctx->lmodule;
3814 BBInfo *bblocks = ctx->bblocks;
3816 LLVMValueRef personality;
3817 LLVMValueRef landing_pad;
3818 LLVMBasicBlockRef target_bb;
3820 static gint32 mapping_inited;
3821 static int ti_generator;
3824 LLVMValueRef type_info;
3828 // <resultval> = landingpad <somety> personality <type> <pers_fn> <clause>+
3830 if (cfg->compile_aot) {
3831 /* Use a dummy personality function */
3832 personality = LLVMGetNamedFunction (lmodule, "mono_personality");
3833 g_assert (personality);
3835 personality = LLVMGetNamedFunction (lmodule, "mono_personality");
3836 if (InterlockedCompareExchange (&mapping_inited, 1, 0) == 0)
3837 LLVMAddGlobalMapping (ctx->module->ee, personality, (gpointer)mono_personality);
3840 i8ptr = LLVMPointerType (LLVMInt8Type (), 0);
3842 clause_index = (mono_get_block_region_notry (cfg, bb->region) >> 8) - 1;
3845 * Create the type info
3847 sprintf (ti_name, "type_info_%d", ti_generator);
3850 if (cfg->compile_aot) {
3851 /* decode_eh_frame () in aot-runtime.c will decode this */
3852 type_info = LLVMAddGlobal (lmodule, LLVMInt32Type (), ti_name);
3853 LLVMSetInitializer (type_info, LLVMConstInt (LLVMInt32Type (), clause_index, FALSE));
3856 * These symbols are not really used, the clause_index is embedded into the EH tables generated by DwarfMonoException in LLVM.
3858 LLVMSetLinkage (type_info, LLVMInternalLinkage);
3861 * After the cfg mempool is freed, the type info will point to stale memory,
3862 * but this is not a problem, since we decode it once in exception_cb during
3865 ti = (gint32*)mono_mempool_alloc (cfg->mempool, sizeof (gint32));
3866 *(gint32*)ti = clause_index;
3868 type_info = LLVMAddGlobal (lmodule, i8ptr, ti_name);
3870 LLVMAddGlobalMapping (ctx->module->ee, type_info, ti);
3874 LLVMTypeRef members [2], ret_type;
3876 members [0] = i8ptr;
3877 members [1] = LLVMInt32Type ();
3878 ret_type = LLVMStructType (members, 2, FALSE);
3880 landing_pad = LLVMBuildLandingPad (builder, ret_type, personality, 1, "");
3881 LLVMAddClause (landing_pad, type_info);
3883 /* Store the exception into the exvar */
3885 LLVMBuildStore (builder, convert (ctx, LLVMBuildExtractValue (builder, landing_pad, 0, "ex_obj"), ObjRefType ()), ctx->ex_var);
3889 * LLVM throw sites are associated with a one landing pad, and LLVM generated
3890 * code expects control to be transferred to this landing pad even in the
3891 * presence of nested clauses. The landing pad needs to branch to the landing
3892 * pads belonging to nested clauses based on the selector value returned by
3893 * the landing pad instruction, which is passed to the landing pad in a
3894 * register by the EH code.
3896 target_bb = bblocks [bb->block_num].call_handler_target_bb;
3897 g_assert (target_bb);
3900 * Branch to the correct landing pad
3902 LLVMValueRef ex_selector = LLVMBuildExtractValue (builder, landing_pad, 1, "ex_selector");
3903 LLVMValueRef switch_ins = LLVMBuildSwitch (builder, ex_selector, target_bb, 0);
3905 for (l = ctx->nested_in [clause_index]; l; l = l->next) {
3906 int nesting_clause_index = GPOINTER_TO_INT (l->data);
3907 MonoBasicBlock *handler_bb;
3909 handler_bb = (MonoBasicBlock*)g_hash_table_lookup (ctx->clause_to_handler, GINT_TO_POINTER (nesting_clause_index));
3910 g_assert (handler_bb);
3912 g_assert (ctx->bblocks [handler_bb->block_num].call_handler_target_bb);
3913 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), nesting_clause_index, FALSE), ctx->bblocks [handler_bb->block_num].call_handler_target_bb);
3916 /* Start a new bblock which CALL_HANDLER can branch to */
3917 target_bb = bblocks [bb->block_num].call_handler_target_bb;
3919 ctx->builder = builder = create_builder (ctx);
3920 LLVMPositionBuilderAtEnd (ctx->builder, target_bb);
3922 ctx->bblocks [bb->block_num].end_bblock = target_bb;
3924 /* Store the exception into the IL level exvar */
3925 if (bb->in_scount == 1) {
3926 g_assert (bb->in_scount == 1);
3927 exvar = bb->in_stack [0];
3929 // FIXME: This is shared with filter clauses ?
3930 g_assert (!values [exvar->dreg]);
3932 g_assert (ctx->ex_var);
3933 values [exvar->dreg] = LLVMBuildLoad (builder, ctx->ex_var, "");
3934 emit_volatile_store (ctx, exvar->dreg);
3940 process_bb (EmitContext *ctx, MonoBasicBlock *bb)
3942 MonoCompile *cfg = ctx->cfg;
3943 MonoMethodSignature *sig = ctx->sig;
3944 LLVMValueRef method = ctx->lmethod;
3945 LLVMValueRef *values = ctx->values;
3946 LLVMValueRef *addresses = ctx->addresses;
3947 LLVMCallInfo *linfo = ctx->linfo;
3948 LLVMModuleRef lmodule = ctx->lmodule;
3949 BBInfo *bblocks = ctx->bblocks;
3951 LLVMBasicBlockRef cbb;
3952 LLVMBuilderRef builder, starting_builder;
3953 gboolean has_terminator;
3955 LLVMValueRef lhs, rhs;
3958 cbb = get_end_bb (ctx, bb);
3960 builder = create_builder (ctx);
3961 ctx->builder = builder;
3962 LLVMPositionBuilderAtEnd (builder, cbb);
3967 if (bb->flags & BB_EXCEPTION_HANDLER) {
3968 if (!ctx->llvm_only && !bblocks [bb->block_num].invoke_target) {
3969 set_failure (ctx, "handler without invokes");
3974 emit_llvmonly_handler_start (ctx, bb, cbb);
3976 emit_handler_start (ctx, bb, builder);
3979 builder = ctx->builder;
3982 has_terminator = FALSE;
3983 starting_builder = builder;
3984 for (ins = bb->code; ins; ins = ins->next) {
3985 const char *spec = LLVM_INS_INFO (ins->opcode);
3987 char dname_buf [128];
3989 emit_dbg_loc (ctx, builder, ins->cil_code);
3994 * Some steps in llc are non-linear in the size of basic blocks, see #5714.
3995 * Start a new bblock. If the llvm optimization passes merge these, we
3996 * can work around that by doing a volatile load + cond branch from
3997 * localloc-ed memory.
3999 //set_failure (ctx, "basic block too long");
4000 cbb = gen_bb (ctx, "CONT_LONG_BB");
4001 LLVMBuildBr (ctx->builder, cbb);
4002 ctx->builder = builder = create_builder (ctx);
4003 LLVMPositionBuilderAtEnd (builder, cbb);
4004 ctx->bblocks [bb->block_num].end_bblock = cbb;
4009 /* There could be instructions after a terminator, skip them */
4012 if (spec [MONO_INST_DEST] != ' ' && !MONO_IS_STORE_MEMBASE (ins)) {
4013 sprintf (dname_buf, "t%d", ins->dreg);
4017 if (spec [MONO_INST_SRC1] != ' ' && spec [MONO_INST_SRC1] != 'v') {
4018 MonoInst *var = get_vreg_to_inst (cfg, ins->sreg1);
4020 if (var && var->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT) && var->opcode != OP_GSHAREDVT_ARG_REGOFFSET) {
4021 lhs = emit_volatile_load (ctx, ins->sreg1);
4023 /* It is ok for SETRET to have an uninitialized argument */
4024 if (!values [ins->sreg1] && ins->opcode != OP_SETRET) {
4025 set_failure (ctx, "sreg1");
4028 lhs = values [ins->sreg1];
4034 if (spec [MONO_INST_SRC2] != ' ' && spec [MONO_INST_SRC2] != ' ') {
4035 MonoInst *var = get_vreg_to_inst (cfg, ins->sreg2);
4036 if (var && var->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT)) {
4037 rhs = emit_volatile_load (ctx, ins->sreg2);
4039 if (!values [ins->sreg2]) {
4040 set_failure (ctx, "sreg2");
4043 rhs = values [ins->sreg2];
4049 //mono_print_ins (ins);
4050 switch (ins->opcode) {
4053 case OP_LIVERANGE_START:
4054 case OP_LIVERANGE_END:
4057 values [ins->dreg] = LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE);
4060 #if SIZEOF_VOID_P == 4
4061 values [ins->dreg] = LLVMConstInt (LLVMInt64Type (), GET_LONG_IMM (ins), FALSE);
4063 values [ins->dreg] = LLVMConstInt (LLVMInt64Type (), (gint64)ins->inst_c0, FALSE);
4067 values [ins->dreg] = LLVMConstReal (LLVMDoubleType (), *(double*)ins->inst_p0);
4071 values [ins->dreg] = LLVMConstReal (LLVMFloatType (), *(float*)ins->inst_p0);
4073 values [ins->dreg] = LLVMConstFPExt (LLVMConstReal (LLVMFloatType (), *(float*)ins->inst_p0), LLVMDoubleType ());
4075 case OP_DUMMY_ICONST:
4076 values [ins->dreg] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
4078 case OP_DUMMY_I8CONST:
4079 values [ins->dreg] = LLVMConstInt (LLVMInt64Type (), 0, FALSE);
4081 case OP_DUMMY_R8CONST:
4082 values [ins->dreg] = LLVMConstReal (LLVMDoubleType (), 0.0f);
4085 LLVMBasicBlockRef target_bb = get_bb (ctx, ins->inst_target_bb);
4086 LLVMBuildBr (builder, target_bb);
4087 has_terminator = TRUE;
4094 LLVMBasicBlockRef new_bb;
4095 LLVMBuilderRef new_builder;
4097 // The default branch is already handled
4098 // FIXME: Handle it here
4100 /* Start new bblock */
4101 sprintf (bb_name, "SWITCH_DEFAULT_BB%d", ctx->default_index ++);
4102 new_bb = LLVMAppendBasicBlock (ctx->lmethod, bb_name);
4104 lhs = convert (ctx, lhs, LLVMInt32Type ());
4105 v = LLVMBuildSwitch (builder, lhs, new_bb, GPOINTER_TO_UINT (ins->klass));
4106 for (i = 0; i < GPOINTER_TO_UINT (ins->klass); ++i) {
4107 MonoBasicBlock *target_bb = ins->inst_many_bb [i];
4109 LLVMAddCase (v, LLVMConstInt (LLVMInt32Type (), i, FALSE), get_bb (ctx, target_bb));
4112 new_builder = create_builder (ctx);
4113 LLVMPositionBuilderAtEnd (new_builder, new_bb);
4114 LLVMBuildUnreachable (new_builder);
4116 has_terminator = TRUE;
4117 g_assert (!ins->next);
4123 switch (linfo->ret.storage) {
4124 case LLVMArgVtypeInReg: {
4125 LLVMTypeRef ret_type = LLVMGetReturnType (LLVMGetElementType (LLVMTypeOf (method)));
4126 LLVMValueRef val, addr, retval;
4129 retval = LLVMGetUndef (ret_type);
4131 if (!addresses [ins->sreg1]) {
4133 * The return type is an LLVM vector type, have to convert between it and the
4134 * real return type which is a struct type.
4136 g_assert (MONO_CLASS_IS_SIMD (ctx->cfg, mono_class_from_mono_type (sig->ret)));
4137 /* Convert to 2xi64 first */
4138 val = LLVMBuildBitCast (builder, values [ins->sreg1], LLVMVectorType (IntPtrType (), 2), "");
4140 for (i = 0; i < 2; ++i) {
4141 if (linfo->ret.pair_storage [i] == LLVMArgInIReg) {
4142 retval = LLVMBuildInsertValue (builder, retval, LLVMBuildExtractElement (builder, val, LLVMConstInt (LLVMInt32Type (), i, FALSE), ""), i, "");
4144 g_assert (linfo->ret.pair_storage [i] == LLVMArgNone);
4148 addr = LLVMBuildBitCast (builder, addresses [ins->sreg1], LLVMPointerType (ret_type, 0), "");
4149 for (i = 0; i < 2; ++i) {
4150 if (linfo->ret.pair_storage [i] == LLVMArgInIReg) {
4151 LLVMValueRef indexes [2], part_addr;
4153 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
4154 indexes [1] = LLVMConstInt (LLVMInt32Type (), i, FALSE);
4155 part_addr = LLVMBuildGEP (builder, addr, indexes, 2, "");
4157 retval = LLVMBuildInsertValue (builder, retval, LLVMBuildLoad (builder, part_addr, ""), i, "");
4159 g_assert (linfo->ret.pair_storage [i] == LLVMArgNone);
4163 LLVMBuildRet (builder, retval);
4166 case LLVMArgVtypeAsScalar: {
4167 LLVMTypeRef ret_type = LLVMGetReturnType (LLVMGetElementType (LLVMTypeOf (method)));
4168 LLVMValueRef retval;
4171 size = get_vtype_size (sig->ret);
4173 g_assert (addresses [ins->sreg1]);
4175 retval = LLVMBuildLoad (builder, LLVMBuildBitCast (builder, addresses [ins->sreg1], LLVMPointerType (ret_type, 0), ""), "");
4176 LLVMBuildRet (builder, retval);
4179 case LLVMArgVtypeByVal: {
4180 LLVMValueRef retval;
4182 g_assert (addresses [ins->sreg1]);
4183 retval = LLVMBuildLoad (builder, addresses [ins->sreg1], "");
4184 LLVMBuildRet (builder, retval);
4187 case LLVMArgVtypeByRef: {
4188 LLVMBuildRetVoid (builder);
4191 case LLVMArgGsharedvtFixed: {
4192 LLVMTypeRef ret_type = type_to_llvm_type (ctx, sig->ret);
4193 /* The return value is in lhs, need to store to the vret argument */
4194 /* sreg1 might not be set */
4196 g_assert (cfg->vret_addr);
4197 g_assert (values [cfg->vret_addr->dreg]);
4198 LLVMBuildStore (builder, convert (ctx, lhs, ret_type), convert (ctx, values [cfg->vret_addr->dreg], LLVMPointerType (ret_type, 0)));
4200 LLVMBuildRetVoid (builder);
4203 case LLVMArgGsharedvtFixedVtype: {
4205 LLVMBuildRetVoid (builder);
4208 case LLVMArgGsharedvtVariable: {
4210 LLVMBuildRetVoid (builder);
4213 case LLVMArgVtypeRetAddr: {
4214 LLVMBuildRetVoid (builder);
4217 case LLVMArgScalarRetAddr: {
4218 LLVMTypeRef ret_type = type_to_llvm_type (ctx, sig->ret);
4219 LLVMValueRef param = LLVMGetParam (method, linfo->vret_arg_pindex);
4221 /* sreg1 might not be set */
4223 LLVMBuildStore (builder, convert (ctx, lhs, ret_type), convert (ctx, param, LLVMPointerType (ret_type, 0)));
4224 LLVMBuildRetVoid (builder);
4227 case LLVMArgFpStruct: {
4228 LLVMTypeRef ret_type = LLVMGetReturnType (LLVMGetElementType (LLVMTypeOf (method)));
4229 LLVMValueRef retval;
4231 g_assert (addresses [ins->sreg1]);
4232 retval = LLVMBuildLoad (builder, convert (ctx, addresses [ins->sreg1], LLVMPointerType (ret_type, 0)), "");
4233 LLVMBuildRet (builder, retval);
4237 case LLVMArgNormal: {
4238 if (!lhs || ctx->is_dead [ins->sreg1]) {
4240 * The method did not set its return value, probably because it
4241 * ends with a throw.
4244 LLVMBuildRetVoid (builder);
4246 LLVMBuildRet (builder, LLVMConstNull (type_to_llvm_type (ctx, sig->ret)));
4248 LLVMBuildRet (builder, convert (ctx, lhs, type_to_llvm_type (ctx, sig->ret)));
4250 has_terminator = TRUE;
4254 g_assert_not_reached ();
4263 case OP_ICOMPARE_IMM:
4264 case OP_LCOMPARE_IMM:
4265 case OP_COMPARE_IMM: {
4267 LLVMValueRef cmp, args [16];
4268 gboolean likely = (ins->flags & MONO_INST_LIKELY) != 0;
4270 if (ins->next->opcode == OP_NOP)
4273 if (ins->next->opcode == OP_BR)
4274 /* The comparison result is not needed */
4277 rel = mono_opcode_to_cond (ins->next->opcode);
4279 if (ins->opcode == OP_ICOMPARE_IMM) {
4280 lhs = convert (ctx, lhs, LLVMInt32Type ());
4281 rhs = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
4283 if (ins->opcode == OP_LCOMPARE_IMM) {
4284 lhs = convert (ctx, lhs, LLVMInt64Type ());
4285 rhs = LLVMConstInt (LLVMInt64Type (), GET_LONG_IMM (ins), FALSE);
4287 if (ins->opcode == OP_LCOMPARE) {
4288 lhs = convert (ctx, lhs, LLVMInt64Type ());
4289 rhs = convert (ctx, rhs, LLVMInt64Type ());
4291 if (ins->opcode == OP_ICOMPARE) {
4292 lhs = convert (ctx, lhs, LLVMInt32Type ());
4293 rhs = convert (ctx, rhs, LLVMInt32Type ());
4297 if (LLVMGetTypeKind (LLVMTypeOf (lhs)) == LLVMPointerTypeKind)
4298 rhs = convert (ctx, rhs, LLVMTypeOf (lhs));
4299 else if (LLVMGetTypeKind (LLVMTypeOf (rhs)) == LLVMPointerTypeKind)
4300 lhs = convert (ctx, lhs, LLVMTypeOf (rhs));
4303 /* We use COMPARE+SETcc/Bcc, llvm uses SETcc+br cond */
4304 if (ins->opcode == OP_FCOMPARE) {
4305 cmp = LLVMBuildFCmp (builder, fpcond_to_llvm_cond [rel], convert (ctx, lhs, LLVMDoubleType ()), convert (ctx, rhs, LLVMDoubleType ()), "");
4306 } else if (ins->opcode == OP_RCOMPARE) {
4307 cmp = LLVMBuildFCmp (builder, fpcond_to_llvm_cond [rel], convert (ctx, lhs, LLVMFloatType ()), convert (ctx, rhs, LLVMFloatType ()), "");
4308 } else if (ins->opcode == OP_COMPARE_IMM) {
4309 if (LLVMGetTypeKind (LLVMTypeOf (lhs)) == LLVMPointerTypeKind && ins->inst_imm == 0)
4310 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], lhs, LLVMConstNull (LLVMTypeOf (lhs)), "");
4312 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE), "");
4313 } else if (ins->opcode == OP_LCOMPARE_IMM) {
4314 if (SIZEOF_REGISTER == 4 && COMPILE_LLVM (cfg)) {
4315 /* The immediate is encoded in two fields */
4316 guint64 l = ((guint64)(guint32)ins->inst_offset << 32) | ((guint32)ins->inst_imm);
4317 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, LLVMInt64Type ()), LLVMConstInt (LLVMInt64Type (), l, FALSE), "");
4319 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, LLVMInt64Type ()), LLVMConstInt (LLVMInt64Type (), ins->inst_imm, FALSE), "");
4322 else if (ins->opcode == OP_COMPARE) {
4323 if (LLVMGetTypeKind (LLVMTypeOf (lhs)) == LLVMPointerTypeKind && LLVMTypeOf (lhs) == LLVMTypeOf (rhs))
4324 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], lhs, rhs, "");
4326 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, IntPtrType ()), convert (ctx, rhs, IntPtrType ()), "");
4328 cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], lhs, rhs, "");
4332 args [1] = LLVMConstInt (LLVMInt1Type (), 1, FALSE);
4333 cmp = LLVMBuildCall (ctx->builder, LLVMGetNamedFunction (ctx->lmodule, "llvm.expect.i1"), args, 2, "");
4336 if (MONO_IS_COND_BRANCH_OP (ins->next)) {
4337 if (ins->next->inst_true_bb == ins->next->inst_false_bb) {
4339 * If the target bb contains PHI instructions, LLVM requires
4340 * two PHI entries for this bblock, while we only generate one.
4341 * So convert this to an unconditional bblock. (bxc #171).
4343 LLVMBuildBr (builder, get_bb (ctx, ins->next->inst_true_bb));
4345 LLVMBuildCondBr (builder, cmp, get_bb (ctx, ins->next->inst_true_bb), get_bb (ctx, ins->next->inst_false_bb));
4347 has_terminator = TRUE;
4348 } else if (MONO_IS_SETCC (ins->next)) {
4349 sprintf (dname_buf, "t%d", ins->next->dreg);
4351 values [ins->next->dreg] = LLVMBuildZExt (builder, cmp, LLVMInt32Type (), dname);
4353 /* Add stores for volatile variables */
4354 emit_volatile_store (ctx, ins->next->dreg);
4355 } else if (MONO_IS_COND_EXC (ins->next)) {
4356 emit_cond_system_exception (ctx, bb, (const char*)ins->next->inst_p1, cmp);
4359 builder = ctx->builder;
4361 set_failure (ctx, "next");
4379 rel = mono_opcode_to_cond (ins->opcode);
4381 cmp = LLVMBuildFCmp (builder, fpcond_to_llvm_cond [rel], convert (ctx, lhs, LLVMDoubleType ()), convert (ctx, rhs, LLVMDoubleType ()), "");
4382 values [ins->dreg] = LLVMBuildZExt (builder, cmp, LLVMInt32Type (), dname);
4393 rel = mono_opcode_to_cond (ins->opcode);
4395 cmp = LLVMBuildFCmp (builder, fpcond_to_llvm_cond [rel], convert (ctx, lhs, LLVMFloatType ()), convert (ctx, rhs, LLVMFloatType ()), "");
4396 values [ins->dreg] = LLVMBuildZExt (builder, cmp, LLVMInt32Type (), dname);
4404 gboolean empty = TRUE;
4406 /* Check that all input bblocks really branch to us */
4407 for (i = 0; i < bb->in_count; ++i) {
4408 if (bb->in_bb [i]->last_ins && bb->in_bb [i]->last_ins->opcode == OP_NOT_REACHED)
4409 ins->inst_phi_args [i + 1] = -1;
4415 /* LLVM doesn't like phi instructions with zero operands */
4416 ctx->is_dead [ins->dreg] = TRUE;
4420 /* Created earlier, insert it now */
4421 LLVMInsertIntoBuilder (builder, values [ins->dreg]);
4423 for (i = 0; i < ins->inst_phi_args [0]; i++) {
4424 int sreg1 = ins->inst_phi_args [i + 1];
4428 * Count the number of times the incoming bblock branches to us,
4429 * since llvm requires a separate entry for each.
4431 if (bb->in_bb [i]->last_ins && bb->in_bb [i]->last_ins->opcode == OP_SWITCH) {
4432 MonoInst *switch_ins = bb->in_bb [i]->last_ins;
4435 for (j = 0; j < GPOINTER_TO_UINT (switch_ins->klass); ++j) {
4436 if (switch_ins->inst_many_bb [j] == bb)
4443 /* Remember for later */
4444 for (j = 0; j < count; ++j) {
4445 PhiNode *node = (PhiNode*)mono_mempool_alloc0 (ctx->mempool, sizeof (PhiNode));
4448 node->in_bb = bb->in_bb [i];
4450 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);
4460 values [ins->dreg] = lhs;
4464 MonoInst *var = get_vreg_to_inst (cfg, ins->dreg);
4467 values [ins->dreg] = lhs;
4469 if (var && var->klass->byval_arg.type == MONO_TYPE_R4) {
4471 * This is added by the spilling pass in case of the JIT,
4472 * but we have to do it ourselves.
4474 values [ins->dreg] = convert (ctx, values [ins->dreg], LLVMFloatType ());
4478 case OP_MOVE_F_TO_I4: {
4479 values [ins->dreg] = LLVMBuildBitCast (builder, LLVMBuildFPTrunc (builder, lhs, LLVMFloatType (), ""), LLVMInt32Type (), "");
4482 case OP_MOVE_I4_TO_F: {
4483 values [ins->dreg] = LLVMBuildFPExt (builder, LLVMBuildBitCast (builder, lhs, LLVMFloatType (), ""), LLVMDoubleType (), "");
4486 case OP_MOVE_F_TO_I8: {
4487 values [ins->dreg] = LLVMBuildBitCast (builder, lhs, LLVMInt64Type (), "");
4490 case OP_MOVE_I8_TO_F: {
4491 values [ins->dreg] = LLVMBuildBitCast (builder, lhs, LLVMDoubleType (), "");
4524 lhs = convert (ctx, lhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
4525 rhs = convert (ctx, rhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
4527 emit_div_check (ctx, builder, bb, ins, lhs, rhs);
4530 builder = ctx->builder;
4532 switch (ins->opcode) {
4535 values [ins->dreg] = LLVMBuildAdd (builder, lhs, rhs, dname);
4539 values [ins->dreg] = LLVMBuildSub (builder, lhs, rhs, dname);
4543 values [ins->dreg] = LLVMBuildMul (builder, lhs, rhs, dname);
4547 values [ins->dreg] = LLVMBuildSRem (builder, lhs, rhs, dname);
4551 values [ins->dreg] = LLVMBuildURem (builder, lhs, rhs, dname);
4555 values [ins->dreg] = LLVMBuildSDiv (builder, lhs, rhs, dname);
4559 values [ins->dreg] = LLVMBuildUDiv (builder, lhs, rhs, dname);
4563 values [ins->dreg] = LLVMBuildFDiv (builder, lhs, rhs, dname);
4567 values [ins->dreg] = LLVMBuildAnd (builder, lhs, rhs, dname);
4571 values [ins->dreg] = LLVMBuildOr (builder, lhs, rhs, dname);
4575 values [ins->dreg] = LLVMBuildXor (builder, lhs, rhs, dname);
4579 values [ins->dreg] = LLVMBuildShl (builder, lhs, rhs, dname);
4583 values [ins->dreg] = LLVMBuildAShr (builder, lhs, rhs, dname);
4587 values [ins->dreg] = LLVMBuildLShr (builder, lhs, rhs, dname);
4591 values [ins->dreg] = LLVMBuildFAdd (builder, lhs, rhs, dname);
4594 values [ins->dreg] = LLVMBuildFSub (builder, lhs, rhs, dname);
4597 values [ins->dreg] = LLVMBuildFMul (builder, lhs, rhs, dname);
4601 g_assert_not_reached ();
4608 lhs = convert (ctx, lhs, LLVMFloatType ());
4609 rhs = convert (ctx, rhs, LLVMFloatType ());
4610 switch (ins->opcode) {
4612 values [ins->dreg] = LLVMBuildFAdd (builder, lhs, rhs, dname);
4615 values [ins->dreg] = LLVMBuildFSub (builder, lhs, rhs, dname);
4618 values [ins->dreg] = LLVMBuildFMul (builder, lhs, rhs, dname);
4621 values [ins->dreg] = LLVMBuildFDiv (builder, lhs, rhs, dname);
4624 g_assert_not_reached ();
4633 case OP_IREM_UN_IMM:
4635 case OP_IDIV_UN_IMM:
4641 case OP_ISHR_UN_IMM:
4651 case OP_LSHR_UN_IMM:
4657 case OP_SHR_UN_IMM: {
4660 if (spec [MONO_INST_SRC1] == 'l') {
4661 imm = LLVMConstInt (LLVMInt64Type (), GET_LONG_IMM (ins), FALSE);
4663 imm = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
4666 emit_div_check (ctx, builder, bb, ins, lhs, imm);
4669 builder = ctx->builder;
4671 #if SIZEOF_VOID_P == 4
4672 if (ins->opcode == OP_LSHL_IMM || ins->opcode == OP_LSHR_IMM || ins->opcode == OP_LSHR_UN_IMM)
4673 imm = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
4676 if (LLVMGetTypeKind (LLVMTypeOf (lhs)) == LLVMPointerTypeKind)
4677 lhs = convert (ctx, lhs, IntPtrType ());
4678 imm = convert (ctx, imm, LLVMTypeOf (lhs));
4679 switch (ins->opcode) {
4683 values [ins->dreg] = LLVMBuildAdd (builder, lhs, imm, dname);
4687 values [ins->dreg] = LLVMBuildSub (builder, lhs, imm, dname);
4692 values [ins->dreg] = LLVMBuildMul (builder, lhs, imm, dname);
4696 values [ins->dreg] = LLVMBuildSDiv (builder, lhs, imm, dname);
4698 case OP_IDIV_UN_IMM:
4699 case OP_LDIV_UN_IMM:
4700 values [ins->dreg] = LLVMBuildUDiv (builder, lhs, imm, dname);
4704 values [ins->dreg] = LLVMBuildSRem (builder, lhs, imm, dname);
4706 case OP_IREM_UN_IMM:
4707 values [ins->dreg] = LLVMBuildURem (builder, lhs, imm, dname);
4712 values [ins->dreg] = LLVMBuildAnd (builder, lhs, imm, dname);
4716 values [ins->dreg] = LLVMBuildOr (builder, lhs, imm, dname);
4720 values [ins->dreg] = LLVMBuildXor (builder, lhs, imm, dname);
4725 values [ins->dreg] = LLVMBuildShl (builder, lhs, imm, dname);
4730 values [ins->dreg] = LLVMBuildAShr (builder, lhs, imm, dname);
4732 case OP_ISHR_UN_IMM:
4733 /* This is used to implement conv.u4, so the lhs could be an i8 */
4734 lhs = convert (ctx, lhs, LLVMInt32Type ());
4735 imm = convert (ctx, imm, LLVMInt32Type ());
4736 values [ins->dreg] = LLVMBuildLShr (builder, lhs, imm, dname);
4738 case OP_LSHR_UN_IMM:
4740 values [ins->dreg] = LLVMBuildLShr (builder, lhs, imm, dname);
4743 g_assert_not_reached ();
4748 values [ins->dreg] = LLVMBuildSub (builder, LLVMConstInt (LLVMInt32Type (), 0, FALSE), convert (ctx, lhs, LLVMInt32Type ()), dname);
4751 values [ins->dreg] = LLVMBuildSub (builder, LLVMConstInt (LLVMInt64Type (), 0, FALSE), lhs, dname);
4754 lhs = convert (ctx, lhs, LLVMDoubleType ());
4755 values [ins->dreg] = LLVMBuildFSub (builder, LLVMConstReal (LLVMDoubleType (), 0.0), lhs, dname);
4758 lhs = convert (ctx, lhs, LLVMFloatType ());
4759 values [ins->dreg] = LLVMBuildFSub (builder, LLVMConstReal (LLVMFloatType (), 0.0), lhs, dname);
4762 guint32 v = 0xffffffff;
4763 values [ins->dreg] = LLVMBuildXor (builder, LLVMConstInt (LLVMInt32Type (), v, FALSE), convert (ctx, lhs, LLVMInt32Type ()), dname);
4767 guint64 v = 0xffffffffffffffffLL;
4768 values [ins->dreg] = LLVMBuildXor (builder, LLVMConstInt (LLVMInt64Type (), v, FALSE), lhs, dname);
4771 #if defined(TARGET_X86) || defined(TARGET_AMD64)
4773 LLVMValueRef v1, v2;
4775 v1 = LLVMBuildMul (builder, convert (ctx, rhs, IntPtrType ()), LLVMConstInt (IntPtrType (), (1 << ins->backend.shift_amount), FALSE), "");
4776 v2 = LLVMBuildAdd (builder, convert (ctx, lhs, IntPtrType ()), v1, "");
4777 values [ins->dreg] = LLVMBuildAdd (builder, v2, LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE), dname);
4782 case OP_ICONV_TO_I1:
4783 case OP_ICONV_TO_I2:
4784 case OP_ICONV_TO_I4:
4785 case OP_ICONV_TO_U1:
4786 case OP_ICONV_TO_U2:
4787 case OP_ICONV_TO_U4:
4788 case OP_LCONV_TO_I1:
4789 case OP_LCONV_TO_I2:
4790 case OP_LCONV_TO_U1:
4791 case OP_LCONV_TO_U2:
4792 case OP_LCONV_TO_U4: {
4795 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);
4797 /* Have to do two casts since our vregs have type int */
4798 v = LLVMBuildTrunc (builder, lhs, op_to_llvm_type (ins->opcode), "");
4800 values [ins->dreg] = LLVMBuildSExt (builder, v, LLVMInt32Type (), dname);
4802 values [ins->dreg] = LLVMBuildZExt (builder, v, LLVMInt32Type (), dname);
4805 case OP_ICONV_TO_I8:
4806 values [ins->dreg] = LLVMBuildSExt (builder, lhs, LLVMInt64Type (), dname);
4808 case OP_ICONV_TO_U8:
4809 values [ins->dreg] = LLVMBuildZExt (builder, lhs, LLVMInt64Type (), dname);
4811 case OP_FCONV_TO_I4:
4812 case OP_RCONV_TO_I4:
4813 values [ins->dreg] = LLVMBuildFPToSI (builder, lhs, LLVMInt32Type (), dname);
4815 case OP_FCONV_TO_I1:
4816 case OP_RCONV_TO_I1:
4817 values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildFPToSI (builder, lhs, LLVMInt8Type (), dname), LLVMInt32Type (), "");
4819 case OP_FCONV_TO_U1:
4820 case OP_RCONV_TO_U1:
4821 values [ins->dreg] = LLVMBuildZExt (builder, LLVMBuildFPToUI (builder, lhs, LLVMInt8Type (), dname), LLVMInt32Type (), "");
4823 case OP_FCONV_TO_I2:
4824 case OP_RCONV_TO_I2:
4825 values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildFPToSI (builder, lhs, LLVMInt16Type (), dname), LLVMInt32Type (), "");
4827 case OP_FCONV_TO_U2:
4828 case OP_RCONV_TO_U2:
4829 values [ins->dreg] = LLVMBuildZExt (builder, LLVMBuildFPToUI (builder, lhs, LLVMInt16Type (), dname), LLVMInt32Type (), "");
4831 case OP_RCONV_TO_U4:
4832 values [ins->dreg] = LLVMBuildFPToUI (builder, lhs, LLVMInt32Type (), dname);
4834 case OP_FCONV_TO_I8:
4835 case OP_RCONV_TO_I8:
4836 values [ins->dreg] = LLVMBuildFPToSI (builder, lhs, LLVMInt64Type (), dname);
4839 values [ins->dreg] = LLVMBuildFPToSI (builder, lhs, IntPtrType (), dname);
4841 case OP_ICONV_TO_R8:
4842 case OP_LCONV_TO_R8:
4843 values [ins->dreg] = LLVMBuildSIToFP (builder, lhs, LLVMDoubleType (), dname);
4845 case OP_ICONV_TO_R_UN:
4846 case OP_LCONV_TO_R_UN:
4847 values [ins->dreg] = LLVMBuildUIToFP (builder, lhs, LLVMDoubleType (), dname);
4849 #if SIZEOF_VOID_P == 4
4852 case OP_LCONV_TO_I4:
4853 values [ins->dreg] = LLVMBuildTrunc (builder, lhs, LLVMInt32Type (), dname);
4855 case OP_ICONV_TO_R4:
4856 case OP_LCONV_TO_R4:
4857 v = LLVMBuildSIToFP (builder, lhs, LLVMFloatType (), "");
4859 values [ins->dreg] = v;
4861 values [ins->dreg] = LLVMBuildFPExt (builder, v, LLVMDoubleType (), dname);
4863 case OP_FCONV_TO_R4:
4864 v = LLVMBuildFPTrunc (builder, lhs, LLVMFloatType (), "");
4866 values [ins->dreg] = v;
4868 values [ins->dreg] = LLVMBuildFPExt (builder, v, LLVMDoubleType (), dname);
4870 case OP_RCONV_TO_R8:
4871 values [ins->dreg] = LLVMBuildFPExt (builder, lhs, LLVMDoubleType (), dname);
4873 case OP_RCONV_TO_R4:
4874 values [ins->dreg] = lhs;
4877 values [ins->dreg] = LLVMBuildSExt (builder, convert (ctx, lhs, LLVMInt32Type ()), LLVMInt64Type (), dname);
4880 values [ins->dreg] = LLVMBuildZExt (builder, convert (ctx, lhs, LLVMInt32Type ()), LLVMInt64Type (), dname);
4883 values [ins->dreg] = LLVMBuildTrunc (builder, lhs, LLVMInt32Type (), dname);
4885 case OP_LOCALLOC_IMM: {
4888 guint32 size = ins->inst_imm;
4889 size = (size + (MONO_ARCH_FRAME_ALIGNMENT - 1)) & ~ (MONO_ARCH_FRAME_ALIGNMENT - 1);
4891 v = mono_llvm_build_alloca (builder, LLVMInt8Type (), LLVMConstInt (LLVMInt32Type (), size, FALSE), MONO_ARCH_FRAME_ALIGNMENT, "");
4893 if (ins->flags & MONO_INST_INIT) {
4894 LLVMValueRef args [5];
4897 args [1] = LLVMConstInt (LLVMInt8Type (), 0, FALSE);
4898 args [2] = LLVMConstInt (LLVMInt32Type (), size, FALSE);
4899 args [3] = LLVMConstInt (LLVMInt32Type (), MONO_ARCH_FRAME_ALIGNMENT, FALSE);
4900 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
4901 LLVMBuildCall (builder, LLVMGetNamedFunction (lmodule, memset_func_name), args, memset_param_count, "");
4904 values [ins->dreg] = v;
4908 LLVMValueRef v, size;
4910 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), "");
4912 v = mono_llvm_build_alloca (builder, LLVMInt8Type (), size, MONO_ARCH_FRAME_ALIGNMENT, "");
4914 if (ins->flags & MONO_INST_INIT) {
4915 LLVMValueRef args [5];
4918 args [1] = LLVMConstInt (LLVMInt8Type (), 0, FALSE);
4920 args [3] = LLVMConstInt (LLVMInt32Type (), MONO_ARCH_FRAME_ALIGNMENT, FALSE);
4921 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
4922 LLVMBuildCall (builder, LLVMGetNamedFunction (lmodule, memset_func_name), args, memset_param_count, "");
4924 values [ins->dreg] = v;
4928 case OP_LOADI1_MEMBASE:
4929 case OP_LOADU1_MEMBASE:
4930 case OP_LOADI2_MEMBASE:
4931 case OP_LOADU2_MEMBASE:
4932 case OP_LOADI4_MEMBASE:
4933 case OP_LOADU4_MEMBASE:
4934 case OP_LOADI8_MEMBASE:
4935 case OP_LOADR4_MEMBASE:
4936 case OP_LOADR8_MEMBASE:
4937 case OP_LOAD_MEMBASE:
4945 LLVMValueRef base, index, addr;
4947 gboolean sext = FALSE, zext = FALSE;
4948 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
4950 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
4955 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)) {
4956 addr = LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE);
4961 if (ins->inst_offset == 0) {
4963 } else if (ins->inst_offset % size != 0) {
4964 /* Unaligned load */
4965 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset, FALSE);
4966 addr = LLVMBuildGEP (builder, convert (ctx, base, LLVMPointerType (LLVMInt8Type (), 0)), &index, 1, "");
4968 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
4969 addr = LLVMBuildGEP (builder, convert (ctx, base, LLVMPointerType (t, 0)), &index, 1, "");
4973 addr = convert (ctx, addr, LLVMPointerType (t, 0));
4975 values [ins->dreg] = emit_load (ctx, bb, &builder, size, addr, dname, is_volatile);
4977 if (!is_volatile && (ins->flags & MONO_INST_INVARIANT_LOAD)) {
4979 * These will signal LLVM that these loads do not alias any stores, and
4980 * they can't fail, allowing them to be hoisted out of loops.
4982 set_invariant_load_flag (values [ins->dreg]);
4983 set_metadata_flag (values [ins->dreg], "mono.nofail.load");
4987 values [ins->dreg] = LLVMBuildSExt (builder, values [ins->dreg], LLVMInt32Type (), dname);
4989 values [ins->dreg] = LLVMBuildZExt (builder, values [ins->dreg], LLVMInt32Type (), dname);
4990 else if (!cfg->r4fp && ins->opcode == OP_LOADR4_MEMBASE)
4991 values [ins->dreg] = LLVMBuildFPExt (builder, values [ins->dreg], LLVMDoubleType (), dname);
4995 case OP_STOREI1_MEMBASE_REG:
4996 case OP_STOREI2_MEMBASE_REG:
4997 case OP_STOREI4_MEMBASE_REG:
4998 case OP_STOREI8_MEMBASE_REG:
4999 case OP_STORER4_MEMBASE_REG:
5000 case OP_STORER8_MEMBASE_REG:
5001 case OP_STORE_MEMBASE_REG: {
5003 LLVMValueRef index, addr;
5005 gboolean sext = FALSE, zext = FALSE;
5006 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
5008 if (!values [ins->inst_destbasereg]) {
5009 set_failure (ctx, "inst_destbasereg");
5013 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
5015 if (ins->inst_offset % size != 0) {
5016 /* Unaligned store */
5017 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset, FALSE);
5018 addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (LLVMInt8Type (), 0)), &index, 1, "");
5020 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
5021 addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (t, 0)), &index, 1, "");
5023 emit_store (ctx, bb, &builder, size, convert (ctx, values [ins->sreg1], t), convert (ctx, addr, LLVMPointerType (t, 0)), is_volatile);
5027 case OP_STOREI1_MEMBASE_IMM:
5028 case OP_STOREI2_MEMBASE_IMM:
5029 case OP_STOREI4_MEMBASE_IMM:
5030 case OP_STOREI8_MEMBASE_IMM:
5031 case OP_STORE_MEMBASE_IMM: {
5033 LLVMValueRef index, addr;
5035 gboolean sext = FALSE, zext = FALSE;
5036 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
5038 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
5040 if (ins->inst_offset % size != 0) {
5041 /* Unaligned store */
5042 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset, FALSE);
5043 addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (LLVMInt8Type (), 0)), &index, 1, "");
5045 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
5046 addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (t, 0)), &index, 1, "");
5048 emit_store (ctx, bb, &builder, size, convert (ctx, LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE), t), convert (ctx, addr, LLVMPointerType (t, 0)), is_volatile);
5053 emit_load (ctx, bb, &builder, sizeof (gpointer), convert (ctx, lhs, LLVMPointerType (IntPtrType (), 0)), "", TRUE);
5055 case OP_OUTARG_VTRETADDR:
5063 case OP_VOIDCALL_MEMBASE:
5064 case OP_CALL_MEMBASE:
5065 case OP_LCALL_MEMBASE:
5066 case OP_FCALL_MEMBASE:
5067 case OP_RCALL_MEMBASE:
5068 case OP_VCALL_MEMBASE:
5069 case OP_VOIDCALL_REG:
5074 case OP_VCALL_REG: {
5075 process_call (ctx, bb, &builder, ins);
5080 LLVMValueRef indexes [2];
5081 MonoJumpInfo *tmp_ji, *ji;
5082 LLVMValueRef got_entry_addr;
5086 * FIXME: Can't allocate from the cfg mempool since that is freed if
5087 * the LLVM compile fails.
5089 tmp_ji = g_new0 (MonoJumpInfo, 1);
5090 tmp_ji->type = (MonoJumpInfoType)ins->inst_c1;
5091 tmp_ji->data.target = ins->inst_p0;
5093 ji = mono_aot_patch_info_dup (tmp_ji);
5096 ji->next = cfg->patch_info;
5097 cfg->patch_info = ji;
5099 //mono_add_patch_info (cfg, 0, (MonoJumpInfoType)ins->inst_i1, ins->inst_p0);
5100 got_offset = mono_aot_get_got_offset (cfg->patch_info);
5101 ctx->module->max_got_offset = MAX (ctx->module->max_got_offset, got_offset);
5102 if (!mono_aot_is_shared_got_offset (got_offset)) {
5103 //mono_print_ji (ji);
5105 ctx->has_got_access = TRUE;
5108 indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
5109 indexes [1] = LLVMConstInt (LLVMInt32Type (), (gssize)got_offset, FALSE);
5110 got_entry_addr = LLVMBuildGEP (builder, ctx->module->got_var, indexes, 2, "");
5112 name = get_aotconst_name (ji->type, ji->data.target, got_offset);
5113 values [ins->dreg] = LLVMBuildLoad (builder, got_entry_addr, name);
5115 /* Can't use this in llvmonly mode since the got slots are initialized by the methods themselves */
5116 if (!mono_llvm_only)
5117 set_invariant_load_flag (values [ins->dreg]);
5120 case OP_NOT_REACHED:
5121 LLVMBuildUnreachable (builder);
5122 has_terminator = TRUE;
5123 g_assert (bb->block_num < cfg->max_block_num);
5124 ctx->unreachable [bb->block_num] = TRUE;
5125 /* Might have instructions after this */
5127 MonoInst *next = ins->next;
5129 * FIXME: If later code uses the regs defined by these instructions,
5130 * compilation will fail.
5132 MONO_DELETE_INS (bb, next);
5136 MonoInst *var = ins->inst_i0;
5138 if (var->opcode == OP_VTARG_ADDR) {
5139 /* The variable contains the vtype address */
5140 values [ins->dreg] = values [var->dreg];
5141 } else if (var->opcode == OP_GSHAREDVT_LOCAL) {
5142 values [ins->dreg] = emit_gsharedvt_ldaddr (ctx, var->dreg);
5144 values [ins->dreg] = addresses [var->dreg];
5149 LLVMValueRef args [1];
5151 args [0] = convert (ctx, lhs, LLVMDoubleType ());
5152 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (lmodule, "llvm.sin.f64"), args, 1, dname);
5156 LLVMValueRef args [1];
5158 args [0] = convert (ctx, lhs, LLVMDoubleType ());
5159 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (lmodule, "llvm.cos.f64"), args, 1, dname);
5163 LLVMValueRef args [1];
5165 args [0] = convert (ctx, lhs, LLVMDoubleType ());
5166 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (lmodule, "llvm.sqrt.f64"), args, 1, dname);
5170 LLVMValueRef args [1];
5172 args [0] = convert (ctx, lhs, LLVMDoubleType ());
5173 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (lmodule, "fabs"), args, 1, dname);
5187 lhs = convert (ctx, lhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
5188 rhs = convert (ctx, rhs, regtype_to_llvm_type (spec [MONO_INST_DEST]));
5190 switch (ins->opcode) {
5193 v = LLVMBuildICmp (builder, LLVMIntSLE, lhs, rhs, "");
5197 v = LLVMBuildICmp (builder, LLVMIntSGE, lhs, rhs, "");
5201 v = LLVMBuildICmp (builder, LLVMIntULE, lhs, rhs, "");
5205 v = LLVMBuildICmp (builder, LLVMIntUGE, lhs, rhs, "");
5208 g_assert_not_reached ();
5211 values [ins->dreg] = LLVMBuildSelect (builder, v, lhs, rhs, dname);
5214 case OP_ATOMIC_EXCHANGE_I4:
5215 case OP_ATOMIC_EXCHANGE_I8: {
5216 LLVMValueRef args [2];
5219 if (ins->opcode == OP_ATOMIC_EXCHANGE_I4)
5220 t = LLVMInt32Type ();
5222 t = LLVMInt64Type ();
5224 g_assert (ins->inst_offset == 0);
5226 args [0] = convert (ctx, lhs, LLVMPointerType (t, 0));
5227 args [1] = convert (ctx, rhs, t);
5229 values [ins->dreg] = mono_llvm_build_atomic_rmw (builder, LLVM_ATOMICRMW_OP_XCHG, args [0], args [1]);
5232 case OP_ATOMIC_ADD_I4:
5233 case OP_ATOMIC_ADD_I8: {
5234 LLVMValueRef args [2];
5237 if (ins->opcode == OP_ATOMIC_ADD_I4)
5238 t = LLVMInt32Type ();
5240 t = LLVMInt64Type ();
5242 g_assert (ins->inst_offset == 0);
5244 args [0] = convert (ctx, lhs, LLVMPointerType (t, 0));
5245 args [1] = convert (ctx, rhs, t);
5246 values [ins->dreg] = LLVMBuildAdd (builder, mono_llvm_build_atomic_rmw (builder, LLVM_ATOMICRMW_OP_ADD, args [0], args [1]), args [1], dname);
5249 case OP_ATOMIC_CAS_I4:
5250 case OP_ATOMIC_CAS_I8: {
5251 LLVMValueRef args [3], val;
5254 if (ins->opcode == OP_ATOMIC_CAS_I4)
5255 t = LLVMInt32Type ();
5257 t = LLVMInt64Type ();
5259 args [0] = convert (ctx, lhs, LLVMPointerType (t, 0));
5261 args [1] = convert (ctx, values [ins->sreg3], t);
5263 args [2] = convert (ctx, values [ins->sreg2], t);
5264 val = mono_llvm_build_cmpxchg (builder, args [0], args [1], args [2]);
5265 /* cmpxchg returns a pair */
5266 values [ins->dreg] = LLVMBuildExtractValue (builder, val, 0, "");
5269 case OP_MEMORY_BARRIER: {
5270 mono_llvm_build_fence (builder, (BarrierKind) ins->backend.memory_barrier_kind);
5273 case OP_ATOMIC_LOAD_I1:
5274 case OP_ATOMIC_LOAD_I2:
5275 case OP_ATOMIC_LOAD_I4:
5276 case OP_ATOMIC_LOAD_I8:
5277 case OP_ATOMIC_LOAD_U1:
5278 case OP_ATOMIC_LOAD_U2:
5279 case OP_ATOMIC_LOAD_U4:
5280 case OP_ATOMIC_LOAD_U8:
5281 case OP_ATOMIC_LOAD_R4:
5282 case OP_ATOMIC_LOAD_R8: {
5283 set_failure (ctx, "atomic mono.load intrinsic");
5287 gboolean sext, zext;
5289 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
5290 BarrierKind barrier = (BarrierKind) ins->backend.memory_barrier_kind;
5291 LLVMValueRef index, addr;
5293 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
5298 if (ins->inst_offset != 0) {
5299 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
5300 addr = LLVMBuildGEP (builder, convert (ctx, lhs, LLVMPointerType (t, 0)), &index, 1, "");
5305 addr = convert (ctx, addr, LLVMPointerType (t, 0));
5307 values [ins->dreg] = emit_load_general (ctx, bb, &builder, size, addr, dname, is_volatile, barrier);
5310 values [ins->dreg] = LLVMBuildSExt (builder, values [ins->dreg], LLVMInt32Type (), dname);
5312 values [ins->dreg] = LLVMBuildZExt (builder, values [ins->dreg], LLVMInt32Type (), dname);
5316 case OP_ATOMIC_STORE_I1:
5317 case OP_ATOMIC_STORE_I2:
5318 case OP_ATOMIC_STORE_I4:
5319 case OP_ATOMIC_STORE_I8:
5320 case OP_ATOMIC_STORE_U1:
5321 case OP_ATOMIC_STORE_U2:
5322 case OP_ATOMIC_STORE_U4:
5323 case OP_ATOMIC_STORE_U8:
5324 case OP_ATOMIC_STORE_R4:
5325 case OP_ATOMIC_STORE_R8: {
5326 set_failure (ctx, "atomic mono.store intrinsic");
5330 gboolean sext, zext;
5332 gboolean is_volatile = (ins->flags & MONO_INST_FAULT);
5333 BarrierKind barrier = (BarrierKind) ins->backend.memory_barrier_kind;
5334 LLVMValueRef index, addr, value;
5336 if (!values [ins->inst_destbasereg]) {
5337 set_failure (ctx, "inst_destbasereg");
5341 t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
5343 index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
5344 addr = LLVMBuildGEP (builder, convert (ctx, values [ins->inst_destbasereg], LLVMPointerType (t, 0)), &index, 1, "");
5345 value = convert (ctx, values [ins->sreg1], t);
5347 emit_store_general (ctx, bb, &builder, size, value, addr, is_volatile, barrier);
5351 case OP_RELAXED_NOP: {
5352 #if defined(TARGET_AMD64) || defined(TARGET_X86)
5353 emit_call (ctx, bb, &builder, LLVMGetNamedFunction (ctx->lmodule, "llvm.x86.sse2.pause"), NULL, 0);
5360 #if (defined(TARGET_AMD64) || defined(TARGET_X86)) && defined(__linux__)
5362 // 257 == FS segment register
5363 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 257);
5365 // 256 == GS segment register
5366 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 256);
5369 values [ins->dreg] = LLVMBuildLoad (builder, LLVMBuildIntToPtr (builder, LLVMConstInt (IntPtrType (), ins->inst_offset, TRUE), ptrtype, ""), "");
5370 #elif defined(TARGET_AMD64) && defined(TARGET_OSX)
5371 /* See mono_amd64_emit_tls_get () */
5372 int offset = mono_amd64_get_tls_gs_offset () + (ins->inst_offset * 8);
5374 // 256 == GS segment register
5375 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 256);
5376 values [ins->dreg] = LLVMBuildLoad (builder, LLVMBuildIntToPtr (builder, LLVMConstInt (IntPtrType (), offset, TRUE), ptrtype, ""), "");
5378 set_failure (ctx, "opcode tls-get");
5384 case OP_TLS_GET_REG: {
5385 #if defined(TARGET_AMD64) && defined(TARGET_OSX)
5386 /* See emit_tls_get_reg () */
5387 // 256 == GS segment register
5388 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 256);
5389 values [ins->dreg] = LLVMBuildLoad (builder, LLVMBuildIntToPtr (builder, convert (ctx, lhs, LLVMInt32Type ()), ptrtype, ""), "");
5391 set_failure (ctx, "opcode tls-get");
5397 case OP_TLS_SET_REG: {
5398 #if defined(TARGET_AMD64) && defined(TARGET_OSX)
5399 /* See emit_tls_get_reg () */
5400 // 256 == GS segment register
5401 LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 256);
5402 LLVMBuildStore (builder, convert (ctx, lhs, IntPtrType ()), LLVMBuildIntToPtr (builder, convert (ctx, rhs, LLVMInt32Type ()), ptrtype, ""));
5404 set_failure (ctx, "opcode tls-set-reg");
5414 case OP_IADD_OVF_UN:
5416 case OP_ISUB_OVF_UN:
5418 case OP_IMUL_OVF_UN:
5419 #if SIZEOF_VOID_P == 8
5421 case OP_LADD_OVF_UN:
5423 case OP_LSUB_OVF_UN:
5425 case OP_LMUL_OVF_UN:
5428 LLVMValueRef args [2], val, ovf, func;
5430 args [0] = convert (ctx, lhs, op_to_llvm_type (ins->opcode));
5431 args [1] = convert (ctx, rhs, op_to_llvm_type (ins->opcode));
5432 func = LLVMGetNamedFunction (lmodule, ovf_op_to_intrins (ins->opcode));
5434 val = LLVMBuildCall (builder, func, args, 2, "");
5435 values [ins->dreg] = LLVMBuildExtractValue (builder, val, 0, dname);
5436 ovf = LLVMBuildExtractValue (builder, val, 1, "");
5437 emit_cond_system_exception (ctx, bb, "OverflowException", ovf);
5440 builder = ctx->builder;
5446 * We currently model them using arrays. Promotion to local vregs is
5447 * disabled for them in mono_handle_global_vregs () in the LLVM case,
5448 * so we always have an entry in cfg->varinfo for them.
5449 * FIXME: Is this needed ?
5452 MonoClass *klass = ins->klass;
5453 LLVMValueRef args [5];
5457 set_failure (ctx, "!klass");
5461 if (!addresses [ins->dreg])
5462 addresses [ins->dreg] = build_alloca (ctx, &klass->byval_arg);
5463 args [0] = LLVMBuildBitCast (builder, addresses [ins->dreg], LLVMPointerType (LLVMInt8Type (), 0), "");
5464 args [1] = LLVMConstInt (LLVMInt8Type (), 0, FALSE);
5465 args [2] = LLVMConstInt (LLVMInt32Type (), mono_class_value_size (klass, NULL), FALSE);
5467 args [3] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
5468 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
5469 LLVMBuildCall (builder, LLVMGetNamedFunction (lmodule, memset_func_name), args, memset_param_count, "");
5472 case OP_DUMMY_VZERO:
5475 case OP_STOREV_MEMBASE:
5476 case OP_LOADV_MEMBASE:
5478 MonoClass *klass = ins->klass;
5479 LLVMValueRef src = NULL, dst, args [5];
5480 gboolean done = FALSE;
5484 set_failure (ctx, "!klass");
5488 if (mini_is_gsharedvt_klass (klass)) {
5490 set_failure (ctx, "gsharedvt");
5494 switch (ins->opcode) {
5495 case OP_STOREV_MEMBASE:
5496 if (cfg->gen_write_barriers && klass->has_references && ins->inst_destbasereg != cfg->frame_reg &&
5497 LLVMGetInstructionOpcode (values [ins->inst_destbasereg]) != LLVMAlloca) {
5498 /* Decomposed earlier */
5499 g_assert_not_reached ();
5502 if (!addresses [ins->sreg1]) {
5504 g_assert (values [ins->sreg1]);
5505 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));
5506 LLVMBuildStore (builder, values [ins->sreg1], dst);
5509 src = LLVMBuildBitCast (builder, addresses [ins->sreg1], LLVMPointerType (LLVMInt8Type (), 0), "");
5510 dst = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_destbasereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (LLVMInt8Type (), 0));
5513 case OP_LOADV_MEMBASE:
5514 if (!addresses [ins->dreg])
5515 addresses [ins->dreg] = build_alloca (ctx, &klass->byval_arg);
5516 src = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_basereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (LLVMInt8Type (), 0));
5517 dst = LLVMBuildBitCast (builder, addresses [ins->dreg], LLVMPointerType (LLVMInt8Type (), 0), "");
5520 if (!addresses [ins->sreg1])
5521 addresses [ins->sreg1] = build_alloca (ctx, &klass->byval_arg);
5522 if (!addresses [ins->dreg])
5523 addresses [ins->dreg] = build_alloca (ctx, &klass->byval_arg);
5524 src = LLVMBuildBitCast (builder, addresses [ins->sreg1], LLVMPointerType (LLVMInt8Type (), 0), "");
5525 dst = LLVMBuildBitCast (builder, addresses [ins->dreg], LLVMPointerType (LLVMInt8Type (), 0), "");
5528 g_assert_not_reached ();
5538 args [2] = LLVMConstInt (LLVMInt32Type (), mono_class_value_size (klass, NULL), FALSE);
5539 args [3] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
5541 args [3] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
5542 args [4] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
5543 LLVMBuildCall (builder, LLVMGetNamedFunction (lmodule, memcpy_func_name), args, memcpy_param_count, "");
5546 case OP_LLVM_OUTARG_VT: {
5547 LLVMArgInfo *ainfo = (LLVMArgInfo*)ins->inst_p0;
5548 MonoType *t = mini_get_underlying_type (ins->inst_vtype);
5550 if (ainfo->storage == LLVMArgScalarByRef) {
5551 LLVMTypeRef argtype;
5552 LLVMValueRef loc, v;
5554 argtype = type_to_llvm_arg_type (ctx, t);
5555 loc = build_alloca_llvm_type (ctx, argtype, 0);
5556 v = convert (ctx, values [ins->sreg1], argtype);
5557 LLVMBuildStore (ctx->builder, v, loc);
5558 addresses [ins->dreg] = loc;
5559 } else if (ainfo->storage == LLVMArgGsharedvtVariable) {
5560 MonoInst *var = get_vreg_to_inst (cfg, ins->sreg1);
5562 if (var && var->opcode == OP_GSHAREDVT_LOCAL) {
5563 addresses [ins->dreg] = convert (ctx, emit_gsharedvt_ldaddr (ctx, var->dreg), LLVMPointerType (IntPtrType (), 0));
5565 g_assert (addresses [ins->sreg1]);
5566 addresses [ins->dreg] = addresses [ins->sreg1];
5568 } else if (ainfo->storage == LLVMArgGsharedvtFixed) {
5569 if (!addresses [ins->sreg1]) {
5570 addresses [ins->sreg1] = build_alloca (ctx, t);
5571 g_assert (values [ins->sreg1]);
5573 LLVMBuildStore (builder, convert (ctx, values [ins->sreg1], LLVMGetElementType (LLVMTypeOf (addresses [ins->sreg1]))), addresses [ins->sreg1]);
5574 addresses [ins->dreg] = addresses [ins->sreg1];
5576 if (!addresses [ins->sreg1]) {
5577 addresses [ins->sreg1] = build_alloca (ctx, t);
5578 g_assert (values [ins->sreg1]);
5579 LLVMBuildStore (builder, convert (ctx, values [ins->sreg1], type_to_llvm_type (ctx, t)), addresses [ins->sreg1]);
5581 addresses [ins->dreg] = addresses [ins->sreg1];
5589 #if defined(TARGET_X86) || defined(TARGET_AMD64)
5591 values [ins->dreg] = LLVMConstNull (type_to_llvm_type (ctx, &ins->klass->byval_arg));
5594 case OP_LOADX_MEMBASE: {
5595 LLVMTypeRef t = type_to_llvm_type (ctx, &ins->klass->byval_arg);
5598 src = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_basereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (t, 0));
5599 values [ins->dreg] = mono_llvm_build_aligned_load (builder, src, "", FALSE, 1);
5602 case OP_STOREX_MEMBASE: {
5603 LLVMTypeRef t = LLVMTypeOf (values [ins->sreg1]);
5606 dest = convert (ctx, LLVMBuildAdd (builder, convert (ctx, values [ins->inst_destbasereg], IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_offset, FALSE), ""), LLVMPointerType (t, 0));
5607 mono_llvm_build_aligned_store (builder, values [ins->sreg1], dest, FALSE, 1);
5614 values [ins->dreg] = LLVMBuildAdd (builder, lhs, rhs, "");
5618 values [ins->dreg] = LLVMBuildFAdd (builder, lhs, rhs, "");
5624 values [ins->dreg] = LLVMBuildSub (builder, lhs, rhs, "");
5628 values [ins->dreg] = LLVMBuildFSub (builder, lhs, rhs, "");
5632 values [ins->dreg] = LLVMBuildFMul (builder, lhs, rhs, "");
5636 values [ins->dreg] = LLVMBuildFDiv (builder, lhs, rhs, "");
5639 values [ins->dreg] = LLVMBuildAnd (builder, lhs, rhs, "");
5642 values [ins->dreg] = LLVMBuildOr (builder, lhs, rhs, "");
5645 values [ins->dreg] = LLVMBuildXor (builder, lhs, rhs, "");
5649 values [ins->dreg] = LLVMBuildMul (builder, lhs, rhs, "");
5660 LLVMValueRef v = NULL;
5662 switch (ins->opcode) {
5667 t = LLVMVectorType (LLVMInt32Type (), 4);
5668 rt = LLVMVectorType (LLVMFloatType (), 4);
5674 t = LLVMVectorType (LLVMInt64Type (), 2);
5675 rt = LLVMVectorType (LLVMDoubleType (), 2);
5678 t = LLVMInt32Type ();
5679 rt = LLVMInt32Type ();
5680 g_assert_not_reached ();
5683 lhs = LLVMBuildBitCast (builder, lhs, t, "");
5684 rhs = LLVMBuildBitCast (builder, rhs, t, "");
5685 switch (ins->opcode) {
5688 v = LLVMBuildAnd (builder, lhs, rhs, "");
5692 v = LLVMBuildOr (builder, lhs, rhs, "");
5696 v = LLVMBuildXor (builder, lhs, rhs, "");
5700 v = LLVMBuildAnd (builder, rhs, LLVMBuildNot (builder, lhs, ""), "");
5703 values [ins->dreg] = LLVMBuildBitCast (builder, v, rt, "");
5727 case OP_PADDB_SAT_UN:
5728 case OP_PADDW_SAT_UN:
5729 case OP_PSUBB_SAT_UN:
5730 case OP_PSUBW_SAT_UN:
5738 case OP_PMULW_HIGH_UN: {
5739 LLVMValueRef args [2];
5744 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (lmodule, simd_op_to_intrins (ins->opcode)), args, 2, dname);
5751 values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildICmp (builder, LLVMIntEQ, lhs, rhs, ""), LLVMTypeOf (lhs), "");
5755 values [ins->dreg] = LLVMBuildSExt (builder, LLVMBuildICmp (builder, LLVMIntSGT, lhs, rhs, ""), LLVMTypeOf (lhs), "");
5763 case OP_EXTRACTX_U2:
5765 case OP_EXTRACT_U1: {
5767 gboolean zext = FALSE;
5769 t = simd_op_to_llvm_type (ins->opcode);
5771 switch (ins->opcode) {
5779 case OP_EXTRACTX_U2:
5784 t = LLVMInt32Type ();
5785 g_assert_not_reached ();
5788 lhs = LLVMBuildBitCast (builder, lhs, t, "");
5789 values [ins->dreg] = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), "");
5791 values [ins->dreg] = LLVMBuildZExt (builder, values [ins->dreg], LLVMInt32Type (), "");
5800 case OP_EXPAND_R8: {
5801 LLVMTypeRef t = simd_op_to_llvm_type (ins->opcode);
5802 LLVMValueRef mask [16], v;
5805 for (i = 0; i < 16; ++i)
5806 mask [i] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
5808 v = convert (ctx, values [ins->sreg1], LLVMGetElementType (t));
5810 values [ins->dreg] = LLVMBuildInsertElement (builder, LLVMConstNull (t), v, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
5811 values [ins->dreg] = LLVMBuildShuffleVector (builder, values [ins->dreg], LLVMGetUndef (t), LLVMConstVector (mask, LLVMGetVectorSize (t)), "");
5816 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt8Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
5819 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt16Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
5822 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt32Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
5825 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMInt64Type ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
5828 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMFloatType ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
5831 values [ins->dreg] = LLVMBuildInsertElement (builder, values [ins->sreg1], convert (ctx, values [ins->sreg2], LLVMDoubleType ()), LLVMConstInt (LLVMInt32Type (), ins->inst_c0, FALSE), dname);
5842 case OP_EXTRACT_MASK:
5849 v = convert (ctx, values [ins->sreg1], simd_op_to_llvm_type (ins->opcode));
5851 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (lmodule, simd_op_to_intrins (ins->opcode)), &v, 1, dname);
5857 LLVMValueRef args [3];
5861 args [2] = LLVMConstInt (LLVMInt8Type (), ins->inst_c0, FALSE);
5863 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (lmodule, simd_op_to_intrins (ins->opcode)), args, 3, dname);
5868 /* This is only used for implementing shifts by non-immediate */
5869 values [ins->dreg] = lhs;
5880 LLVMValueRef args [3];
5883 args [1] = LLVMConstInt (LLVMInt32Type (), ins->inst_imm, FALSE);
5885 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (lmodule, simd_op_to_intrins (ins->opcode)), args, 2, dname);
5896 case OP_PSHLQ_REG: {
5897 LLVMValueRef args [3];
5900 args [1] = values [ins->sreg2];
5902 values [ins->dreg] = LLVMBuildCall (builder, LLVMGetNamedFunction (lmodule, simd_op_to_intrins (ins->opcode)), args, 2, dname);
5909 case OP_PSHUFLEW_LOW:
5910 case OP_PSHUFLEW_HIGH: {
5912 LLVMValueRef v1 = NULL, v2 = NULL, mask_values [16];
5913 int i, mask_size = 0;
5914 int imask = ins->inst_c0;
5916 /* Convert the x86 shuffle mask to LLVM's */
5917 switch (ins->opcode) {
5920 mask [0] = ((imask >> 0) & 3);
5921 mask [1] = ((imask >> 2) & 3);
5922 mask [2] = ((imask >> 4) & 3) + 4;
5923 mask [3] = ((imask >> 6) & 3) + 4;
5924 v1 = values [ins->sreg1];
5925 v2 = values [ins->sreg2];
5929 mask [0] = ((imask >> 0) & 1);
5930 mask [1] = ((imask >> 1) & 1) + 2;
5931 v1 = values [ins->sreg1];
5932 v2 = values [ins->sreg2];
5934 case OP_PSHUFLEW_LOW:
5936 mask [0] = ((imask >> 0) & 3);
5937 mask [1] = ((imask >> 2) & 3);
5938 mask [2] = ((imask >> 4) & 3);
5939 mask [3] = ((imask >> 6) & 3);
5944 v1 = values [ins->sreg1];
5945 v2 = LLVMGetUndef (LLVMTypeOf (v1));
5947 case OP_PSHUFLEW_HIGH:
5953 mask [4] = 4 + ((imask >> 0) & 3);
5954 mask [5] = 4 + ((imask >> 2) & 3);
5955 mask [6] = 4 + ((imask >> 4) & 3);
5956 mask [7] = 4 + ((imask >> 6) & 3);
5957 v1 = values [ins->sreg1];
5958 v2 = LLVMGetUndef (LLVMTypeOf (v1));
5962 mask [0] = ((imask >> 0) & 3);
5963 mask [1] = ((imask >> 2) & 3);
5964 mask [2] = ((imask >> 4) & 3);
5965 mask [3] = ((imask >> 6) & 3);
5966 v1 = values [ins->sreg1];
5967 v2 = LLVMGetUndef (LLVMTypeOf (v1));
5970 g_assert_not_reached ();
5972 for (i = 0; i < mask_size; ++i)
5973 mask_values [i] = LLVMConstInt (LLVMInt32Type (), mask [i], FALSE);
5975 values [ins->dreg] =
5976 LLVMBuildShuffleVector (builder, v1, v2,
5977 LLVMConstVector (mask_values, mask_size), dname);
5981 case OP_UNPACK_LOWB:
5982 case OP_UNPACK_LOWW:
5983 case OP_UNPACK_LOWD:
5984 case OP_UNPACK_LOWQ:
5985 case OP_UNPACK_LOWPS:
5986 case OP_UNPACK_LOWPD:
5987 case OP_UNPACK_HIGHB:
5988 case OP_UNPACK_HIGHW:
5989 case OP_UNPACK_HIGHD:
5990 case OP_UNPACK_HIGHQ:
5991 case OP_UNPACK_HIGHPS:
5992 case OP_UNPACK_HIGHPD: {
5994 LLVMValueRef mask_values [16];
5995 int i, mask_size = 0;
5996 gboolean low = FALSE;
5998 switch (ins->opcode) {
5999 case OP_UNPACK_LOWB:
6003 case OP_UNPACK_LOWW:
6007 case OP_UNPACK_LOWD:
6008 case OP_UNPACK_LOWPS:
6012 case OP_UNPACK_LOWQ:
6013 case OP_UNPACK_LOWPD:
6017 case OP_UNPACK_HIGHB:
6020 case OP_UNPACK_HIGHW:
6023 case OP_UNPACK_HIGHD:
6024 case OP_UNPACK_HIGHPS:
6027 case OP_UNPACK_HIGHQ:
6028 case OP_UNPACK_HIGHPD:
6032 g_assert_not_reached ();
6036 for (i = 0; i < (mask_size / 2); ++i) {
6038 mask [(i * 2) + 1] = mask_size + i;
6041 for (i = 0; i < (mask_size / 2); ++i) {
6042 mask [(i * 2)] = (mask_size / 2) + i;
6043 mask [(i * 2) + 1] = mask_size + (mask_size / 2) + i;
6047 for (i = 0; i < mask_size; ++i)
6048 mask_values [i] = LLVMConstInt (LLVMInt32Type (), mask [i], FALSE);
6050 values [ins->dreg] =
6051 LLVMBuildShuffleVector (builder, values [ins->sreg1], values [ins->sreg2],
6052 LLVMConstVector (mask_values, mask_size), dname);
6057 LLVMTypeRef t = simd_op_to_llvm_type (ins->opcode);
6058 LLVMValueRef v, val;
6060 v = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
6061 val = LLVMConstNull (t);
6062 val = LLVMBuildInsertElement (builder, val, v, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
6063 val = LLVMBuildInsertElement (builder, val, v, LLVMConstInt (LLVMInt32Type (), 1, FALSE), dname);
6065 values [ins->dreg] = val;
6069 case OP_DUPPS_HIGH: {
6070 LLVMTypeRef t = simd_op_to_llvm_type (ins->opcode);
6071 LLVMValueRef v1, v2, val;
6074 if (ins->opcode == OP_DUPPS_LOW) {
6075 v1 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
6076 v2 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 2, FALSE), "");
6078 v1 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 1, FALSE), "");
6079 v2 = LLVMBuildExtractElement (builder, lhs, LLVMConstInt (LLVMInt32Type (), 3, FALSE), "");
6081 val = LLVMConstNull (t);
6082 val = LLVMBuildInsertElement (builder, val, v1, LLVMConstInt (LLVMInt32Type (), 0, FALSE), "");
6083 val = LLVMBuildInsertElement (builder, val, v1, LLVMConstInt (LLVMInt32Type (), 1, FALSE), "");
6084 val = LLVMBuildInsertElement (builder, val, v2, LLVMConstInt (LLVMInt32Type (), 2, FALSE), "");
6085 val = LLVMBuildInsertElement (builder, val, v2, LLVMConstInt (LLVMInt32Type (), 3, FALSE), "");
6087 values [ins->dreg] = val;
6097 * EXCEPTION HANDLING
6099 case OP_IMPLICIT_EXCEPTION:
6100 /* This marks a place where an implicit exception can happen */
6101 if (bb->region != -1)
6102 set_failure (ctx, "implicit-exception");
6106 gboolean rethrow = (ins->opcode == OP_RETHROW);
6107 if (ctx->llvm_only) {
6108 emit_llvmonly_throw (ctx, bb, rethrow, lhs);
6109 has_terminator = TRUE;
6110 ctx->unreachable [bb->block_num] = TRUE;
6112 emit_throw (ctx, bb, rethrow, lhs);
6113 builder = ctx->builder;
6117 case OP_CALL_HANDLER: {
6119 * We don't 'call' handlers, but instead simply branch to them.
6120 * The code generated by ENDFINALLY will branch back to us.
6122 LLVMBasicBlockRef noex_bb;
6124 BBInfo *info = &bblocks [ins->inst_target_bb->block_num];
6126 bb_list = info->call_handler_return_bbs;
6129 * Set the indicator variable for the finally clause.
6131 lhs = info->finally_ind;
6133 LLVMBuildStore (builder, LLVMConstInt (LLVMInt32Type (), g_slist_length (bb_list) + 1, FALSE), lhs);
6135 /* Branch to the finally clause */
6136 LLVMBuildBr (builder, info->call_handler_target_bb);
6138 noex_bb = gen_bb (ctx, "CALL_HANDLER_CONT_BB");
6139 info->call_handler_return_bbs = g_slist_append_mempool (cfg->mempool, info->call_handler_return_bbs, noex_bb);
6141 builder = ctx->builder = create_builder (ctx);
6142 LLVMPositionBuilderAtEnd (ctx->builder, noex_bb);
6144 bblocks [bb->block_num].end_bblock = noex_bb;
6147 case OP_START_HANDLER: {
6150 case OP_ENDFINALLY: {
6151 LLVMBasicBlockRef resume_bb;
6152 MonoBasicBlock *handler_bb;
6153 LLVMValueRef val, switch_ins, callee;
6157 handler_bb = (MonoBasicBlock*)g_hash_table_lookup (ctx->region_to_handler, GUINT_TO_POINTER (mono_get_block_region_notry (cfg, bb->region)));
6158 g_assert (handler_bb);
6159 info = &bblocks [handler_bb->block_num];
6160 lhs = info->finally_ind;
6163 bb_list = info->call_handler_return_bbs;
6165 resume_bb = gen_bb (ctx, "ENDFINALLY_RESUME_BB");
6167 /* Load the finally variable */
6168 val = LLVMBuildLoad (builder, lhs, "");
6170 /* Reset the variable */
6171 LLVMBuildStore (builder, LLVMConstInt (LLVMInt32Type (), 0, FALSE), lhs);
6173 /* Branch to either resume_bb, or to the bblocks in bb_list */
6174 switch_ins = LLVMBuildSwitch (builder, val, resume_bb, g_slist_length (bb_list));
6176 * The other targets are added at the end to handle OP_CALL_HANDLER
6177 * opcodes processed later.
6179 info->endfinally_switch_ins_list = g_slist_append_mempool (cfg->mempool, info->endfinally_switch_ins_list, switch_ins);
6181 builder = ctx->builder = create_builder (ctx);
6182 LLVMPositionBuilderAtEnd (ctx->builder, resume_bb);
6184 if (ctx->llvm_only) {
6185 emit_resume_eh (ctx, bb);
6187 if (ctx->cfg->compile_aot) {
6188 callee = get_callee (ctx, LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE), MONO_PATCH_INFO_INTERNAL_METHOD, "llvm_resume_unwind_trampoline");
6190 callee = LLVMGetNamedFunction (lmodule, "llvm_resume_unwind_trampoline");
6192 LLVMBuildCall (builder, callee, NULL, 0, "");
6193 LLVMBuildUnreachable (builder);
6196 has_terminator = TRUE;
6199 case OP_IL_SEQ_POINT:
6204 sprintf (reason, "opcode %s", mono_inst_name (ins->opcode));
6205 set_failure (ctx, reason);
6213 /* Convert the value to the type required by phi nodes */
6214 if (spec [MONO_INST_DEST] != ' ' && !MONO_IS_STORE_MEMBASE (ins) && ctx->vreg_types [ins->dreg]) {
6215 if (!values [ins->dreg])
6217 values [ins->dreg] = addresses [ins->dreg];
6219 values [ins->dreg] = convert (ctx, values [ins->dreg], ctx->vreg_types [ins->dreg]);
6222 /* Add stores for volatile variables */
6223 if (spec [MONO_INST_DEST] != ' ' && spec [MONO_INST_DEST] != 'v' && !MONO_IS_STORE_MEMBASE (ins))
6224 emit_volatile_store (ctx, ins->dreg);
6230 if (!has_terminator && bb->next_bb && (bb == cfg->bb_entry || bb->in_count > 0)) {
6231 LLVMBuildBr (builder, get_bb (ctx, bb->next_bb));
6234 if (bb == cfg->bb_exit && sig->ret->type == MONO_TYPE_VOID) {
6235 emit_dbg_loc (ctx, builder, cfg->header->code + cfg->header->code_size - 1);
6236 LLVMBuildRetVoid (builder);
6239 if (bb == cfg->bb_entry)
6240 ctx->last_alloca = LLVMGetLastInstruction (get_bb (ctx, cfg->bb_entry));
6244 * mono_llvm_check_method_supported:
6246 * Do some quick checks to decide whenever cfg->method can be compiled by LLVM, to avoid
6247 * compiling a method twice.
6250 mono_llvm_check_method_supported (MonoCompile *cfg)
6257 if (cfg->method->save_lmf) {
6258 cfg->exception_message = g_strdup ("lmf");
6259 cfg->disable_llvm = TRUE;
6261 if (cfg->disable_llvm)
6265 * Nested clauses where one of the clauses is a finally clause is
6266 * not supported, because LLVM can't figure out the control flow,
6267 * probably because we resume exception handling by calling our
6268 * own function instead of using the 'resume' llvm instruction.
6270 for (i = 0; i < cfg->header->num_clauses; ++i) {
6271 for (j = 0; j < cfg->header->num_clauses; ++j) {
6272 MonoExceptionClause *clause1 = &cfg->header->clauses [i];
6273 MonoExceptionClause *clause2 = &cfg->header->clauses [j];
6275 // FIXME: Nested try clauses fail in some cases too, i.e. #37273
6276 if (i != j && clause1->try_offset >= clause2->try_offset && clause1->handler_offset <= clause2->handler_offset) {
6277 //(clause1->flags == MONO_EXCEPTION_CLAUSE_FINALLY || clause2->flags == MONO_EXCEPTION_CLAUSE_FINALLY)) {
6278 cfg->exception_message = g_strdup ("nested clauses");
6279 cfg->disable_llvm = TRUE;
6284 if (cfg->disable_llvm)
6288 if (cfg->method->dynamic) {
6289 cfg->exception_message = g_strdup ("dynamic.");
6290 cfg->disable_llvm = TRUE;
6292 if (cfg->disable_llvm)
6296 static LLVMCallInfo*
6297 get_llvm_call_info (MonoCompile *cfg, MonoMethodSignature *sig)
6299 LLVMCallInfo *linfo;
6302 if (cfg->gsharedvt && cfg->llvm_only && mini_is_gsharedvt_variable_signature (sig)) {
6306 * Gsharedvt methods have the following calling convention:
6307 * - all arguments are passed by ref, even non generic ones
6308 * - the return value is returned by ref too, using a vret
6309 * argument passed after 'this'.
6311 n = sig->param_count + sig->hasthis;
6312 linfo = (LLVMCallInfo*)mono_mempool_alloc0 (cfg->mempool, sizeof (LLVMCallInfo) + (sizeof (LLVMArgInfo) * n));
6316 linfo->args [pindex ++].storage = LLVMArgNormal;
6318 if (sig->ret->type != MONO_TYPE_VOID) {
6319 if (mini_is_gsharedvt_variable_type (sig->ret))
6320 linfo->ret.storage = LLVMArgGsharedvtVariable;
6321 else if (mini_type_is_vtype (sig->ret))
6322 linfo->ret.storage = LLVMArgGsharedvtFixedVtype;
6324 linfo->ret.storage = LLVMArgGsharedvtFixed;
6325 linfo->vret_arg_index = pindex;
6327 linfo->ret.storage = LLVMArgNone;
6330 for (i = 0; i < sig->param_count; ++i) {
6331 if (sig->params [i]->byref)
6332 linfo->args [pindex].storage = LLVMArgNormal;
6333 else if (mini_is_gsharedvt_variable_type (sig->params [i]))
6334 linfo->args [pindex].storage = LLVMArgGsharedvtVariable;
6335 else if (mini_type_is_vtype (sig->params [i]))
6336 linfo->args [pindex].storage = LLVMArgGsharedvtFixedVtype;
6338 linfo->args [pindex].storage = LLVMArgGsharedvtFixed;
6339 linfo->args [pindex].type = sig->params [i];
6346 linfo = mono_arch_get_llvm_call_info (cfg, sig);
6347 for (i = 0; i < sig->param_count; ++i)
6348 linfo->args [i + sig->hasthis].type = sig->params [i];
6354 emit_method_inner (EmitContext *ctx);
6357 free_ctx (EmitContext *ctx)
6361 g_free (ctx->values);
6362 g_free (ctx->addresses);
6363 g_free (ctx->vreg_types);
6364 g_free (ctx->vreg_cli_types);
6365 g_free (ctx->is_dead);
6366 g_free (ctx->unreachable);
6367 g_ptr_array_free (ctx->phi_values, TRUE);
6368 g_free (ctx->bblocks);
6369 g_hash_table_destroy (ctx->region_to_handler);
6370 g_hash_table_destroy (ctx->clause_to_handler);
6371 g_free (ctx->method_name);
6372 g_ptr_array_free (ctx->bblock_list, TRUE);
6374 for (l = ctx->builders; l; l = l->next) {
6375 LLVMBuilderRef builder = (LLVMBuilderRef)l->data;
6376 LLVMDisposeBuilder (builder);
6383 * mono_llvm_emit_method:
6385 * Emit LLVM IL from the mono IL, and compile it to native code using LLVM.
6388 mono_llvm_emit_method (MonoCompile *cfg)
6392 gboolean is_linkonce = FALSE;
6395 /* The code below might acquire the loader lock, so use it for global locking */
6396 mono_loader_lock ();
6398 /* Used to communicate with the callbacks */
6399 mono_native_tls_set_value (current_cfg_tls_id, cfg);
6401 ctx = g_new0 (EmitContext, 1);
6403 ctx->mempool = cfg->mempool;
6406 * This maps vregs to the LLVM instruction defining them
6408 ctx->values = g_new0 (LLVMValueRef, cfg->next_vreg);
6410 * This maps vregs for volatile variables to the LLVM instruction defining their
6413 ctx->addresses = g_new0 (LLVMValueRef, cfg->next_vreg);
6414 ctx->vreg_types = g_new0 (LLVMTypeRef, cfg->next_vreg);
6415 ctx->vreg_cli_types = g_new0 (MonoType*, cfg->next_vreg);
6416 ctx->phi_values = g_ptr_array_sized_new (256);
6418 * This signals whenever the vreg was defined by a phi node with no input vars
6419 * (i.e. all its input bblocks end with NOT_REACHABLE).
6421 ctx->is_dead = g_new0 (gboolean, cfg->next_vreg);
6422 /* Whenever the bblock is unreachable */
6423 ctx->unreachable = g_new0 (gboolean, cfg->max_block_num);
6424 ctx->bblock_list = g_ptr_array_sized_new (256);
6426 ctx->region_to_handler = g_hash_table_new (NULL, NULL);
6427 ctx->clause_to_handler = g_hash_table_new (NULL, NULL);
6428 ctx->method_to_callers = g_hash_table_new (NULL, NULL);
6429 if (cfg->compile_aot) {
6430 ctx->module = &aot_module;
6434 * Allow the linker to discard duplicate copies of wrappers, generic instances etc. by using the 'linkonce'
6435 * linkage for them. This requires the following:
6436 * - the method needs to have a unique mangled name
6437 * - llvmonly mode, since the code in aot-runtime.c would initialize got slots in the wrong aot image etc.
6439 is_linkonce = ctx->module->llvm_only && ctx->module->static_link && mono_aot_is_linkonce_method (cfg->method);
6441 method_name = mono_aot_get_mangled_method_name (cfg->method);
6443 is_linkonce = FALSE;
6446 printf ("%s %s\n", mono_method_full_name (cfg->method, 1), method_name);
6448 printf ("%s\n", mono_method_full_name (cfg->method, 1));
6452 method_name = mono_aot_get_method_name (cfg);
6453 cfg->llvm_method_name = g_strdup (method_name);
6455 init_jit_module (cfg->domain);
6456 ctx->module = (MonoLLVMModule*)domain_jit_info (cfg->domain)->llvm_module;
6457 method_name = mono_method_full_name (cfg->method, TRUE);
6459 ctx->method_name = method_name;
6460 ctx->is_linkonce = is_linkonce;
6462 ctx->lmodule = ctx->module->lmodule;
6463 ctx->llvm_only = ctx->module->llvm_only;
6465 emit_method_inner (ctx);
6467 if (!ctx_ok (ctx)) {
6469 /* Need to add unused phi nodes as they can be referenced by other values */
6470 LLVMBasicBlockRef phi_bb = LLVMAppendBasicBlock (ctx->lmethod, "PHI_BB");
6471 LLVMBuilderRef builder;
6473 builder = create_builder (ctx);
6474 LLVMPositionBuilderAtEnd (builder, phi_bb);
6476 for (i = 0; i < ctx->phi_values->len; ++i) {
6477 LLVMValueRef v = (LLVMValueRef)g_ptr_array_index (ctx->phi_values, i);
6478 if (LLVMGetInstructionParent (v) == NULL)
6479 LLVMInsertIntoBuilder (builder, v);
6482 LLVMDeleteFunction (ctx->lmethod);
6488 mono_native_tls_set_value (current_cfg_tls_id, NULL);
6490 mono_loader_unlock ();
6494 emit_method_inner (EmitContext *ctx)
6496 MonoCompile *cfg = ctx->cfg;
6497 MonoMethodSignature *sig;
6499 LLVMTypeRef method_type;
6500 LLVMValueRef method = NULL;
6501 LLVMValueRef *values = ctx->values;
6502 int i, max_block_num, bb_index;
6503 gboolean last = FALSE;
6504 LLVMCallInfo *linfo;
6505 LLVMModuleRef lmodule = ctx->lmodule;
6507 GPtrArray *bblock_list = ctx->bblock_list;
6508 MonoMethodHeader *header;
6509 MonoExceptionClause *clause;
6512 if (cfg->gsharedvt && !cfg->llvm_only) {
6513 set_failure (ctx, "gsharedvt");
6519 static int count = 0;
6522 if (g_getenv ("LLVM_COUNT")) {
6523 if (count == atoi (g_getenv ("LLVM_COUNT"))) {
6524 printf ("LAST: %s\n", mono_method_full_name (cfg->method, TRUE));
6528 if (count > atoi (g_getenv ("LLVM_COUNT"))) {
6529 set_failure (ctx, "count");
6536 sig = mono_method_signature (cfg->method);
6539 linfo = get_llvm_call_info (cfg, sig);
6545 linfo->rgctx_arg = TRUE;
6546 ctx->method_type = method_type = sig_to_llvm_sig_full (ctx, sig, linfo);
6550 method = LLVMAddFunction (lmodule, ctx->method_name, method_type);
6551 ctx->lmethod = method;
6553 if (!cfg->llvm_only)
6554 LLVMSetFunctionCallConv (method, LLVMMono1CallConv);
6555 LLVMSetLinkage (method, LLVMPrivateLinkage);
6557 LLVMAddFunctionAttr (method, LLVMUWTable);
6559 if (cfg->compile_aot) {
6560 LLVMSetLinkage (method, LLVMInternalLinkage);
6561 if (ctx->module->external_symbols) {
6562 LLVMSetLinkage (method, LLVMExternalLinkage);
6563 LLVMSetVisibility (method, LLVMHiddenVisibility);
6565 if (ctx->is_linkonce) {
6566 LLVMSetLinkage (method, LLVMLinkOnceAnyLinkage);
6567 LLVMSetVisibility (method, LLVMDefaultVisibility);
6570 LLVMSetLinkage (method, LLVMPrivateLinkage);
6573 if (cfg->method->save_lmf && !cfg->llvm_only) {
6574 set_failure (ctx, "lmf");
6578 if (sig->pinvoke && cfg->method->wrapper_type != MONO_WRAPPER_RUNTIME_INVOKE && !cfg->llvm_only) {
6579 set_failure (ctx, "pinvoke signature");
6583 header = cfg->header;
6584 for (i = 0; i < header->num_clauses; ++i) {
6585 clause = &header->clauses [i];
6586 if (clause->flags != MONO_EXCEPTION_CLAUSE_FINALLY && clause->flags != MONO_EXCEPTION_CLAUSE_NONE) {
6587 set_failure (ctx, "non-finally/catch clause.");
6591 if (header->num_clauses || (cfg->method->iflags & METHOD_IMPL_ATTRIBUTE_NOINLINING) || cfg->no_inline)
6592 /* We can't handle inlined methods with clauses */
6593 LLVMAddFunctionAttr (method, LLVMNoInlineAttribute);
6595 if (linfo->rgctx_arg) {
6596 ctx->rgctx_arg = LLVMGetParam (method, linfo->rgctx_arg_pindex);
6597 ctx->rgctx_arg_pindex = linfo->rgctx_arg_pindex;
6599 * We mark the rgctx parameter with the inreg attribute, which is mapped to
6600 * MONO_ARCH_RGCTX_REG in the Mono calling convention in llvm, i.e.
6601 * CC_X86_64_Mono in X86CallingConv.td.
6603 if (!ctx->llvm_only)
6604 LLVMAddAttribute (ctx->rgctx_arg, LLVMInRegAttribute);
6605 LLVMSetValueName (ctx->rgctx_arg, "rgctx");
6607 ctx->rgctx_arg_pindex = -1;
6609 if (cfg->vret_addr) {
6610 values [cfg->vret_addr->dreg] = LLVMGetParam (method, linfo->vret_arg_pindex);
6611 LLVMSetValueName (values [cfg->vret_addr->dreg], "vret");
6612 if (linfo->ret.storage == LLVMArgVtypeByRef) {
6613 LLVMAddAttribute (LLVMGetParam (method, linfo->vret_arg_pindex), LLVMStructRetAttribute);
6614 LLVMAddAttribute (LLVMGetParam (method, linfo->vret_arg_pindex), LLVMNoAliasAttribute);
6616 } else if (linfo->ret.storage == LLVMArgScalarRetAddr) {
6617 LLVMValueRef param = LLVMGetParam (method, linfo->vret_arg_pindex);
6618 LLVMSetValueName (param, "vret");
6622 ctx->this_arg_pindex = linfo->this_arg_pindex;
6623 ctx->this_arg = LLVMGetParam (method, linfo->this_arg_pindex);
6624 values [cfg->args [0]->dreg] = ctx->this_arg;
6625 LLVMSetValueName (values [cfg->args [0]->dreg], "this");
6628 names = g_new (char *, sig->param_count);
6629 mono_method_get_param_names (cfg->method, (const char **) names);
6631 for (i = 0; i < sig->param_count; ++i) {
6632 LLVMArgInfo *ainfo = &linfo->args [i + sig->hasthis];
6634 int pindex = ainfo->pindex + ainfo->ndummy_fpargs;
6637 for (j = 0; j < ainfo->ndummy_fpargs; ++j) {
6638 name = g_strdup_printf ("dummy_%d_%d", i, j);
6639 LLVMSetValueName (LLVMGetParam (method, ainfo->pindex + j), name);
6643 values [cfg->args [i + sig->hasthis]->dreg] = LLVMGetParam (method, pindex);
6644 if (ainfo->storage == LLVMArgScalarByRef) {
6645 if (names [i] && names [i][0] != '\0')
6646 name = g_strdup_printf ("p_arg_%s", names [i]);
6648 name = g_strdup_printf ("p_arg_%d", i);
6649 } else if (ainfo->storage == LLVMArgGsharedvtFixed || ainfo->storage == LLVMArgGsharedvtFixedVtype) {
6650 if (names [i] && names [i][0] != '\0')
6651 name = g_strdup_printf ("p_arg_%s", names [i]);
6653 name = g_strdup_printf ("p_arg_%d", i);
6655 if (names [i] && names [i][0] != '\0')
6656 name = g_strdup_printf ("arg_%s", names [i]);
6658 name = g_strdup_printf ("arg_%d", i);
6660 LLVMSetValueName (values [cfg->args [i + sig->hasthis]->dreg], name);
6662 if (ainfo->storage == LLVMArgVtypeByVal)
6663 LLVMAddAttribute (LLVMGetParam (method, pindex), LLVMByValAttribute);
6665 if (ainfo->storage == LLVMArgVtypeByRef) {
6667 cfg->args [i + sig->hasthis]->opcode = OP_VTARG_ADDR;
6672 if (ctx->module->emit_dwarf && cfg->compile_aot && mono_debug_enabled ()) {
6673 ctx->minfo = mono_debug_lookup_method (cfg->method);
6674 ctx->dbg_md = emit_dbg_subprogram (ctx, cfg, method, ctx->method_name);
6678 for (bb = cfg->bb_entry; bb; bb = bb->next_bb)
6679 max_block_num = MAX (max_block_num, bb->block_num);
6680 ctx->bblocks = bblocks = g_new0 (BBInfo, max_block_num + 1);
6682 /* Add branches between non-consecutive bblocks */
6683 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
6684 if (bb->last_ins && MONO_IS_COND_BRANCH_OP (bb->last_ins) &&
6685 bb->next_bb != bb->last_ins->inst_false_bb) {
6687 MonoInst *inst = (MonoInst*)mono_mempool_alloc0 (cfg->mempool, sizeof (MonoInst));
6688 inst->opcode = OP_BR;
6689 inst->inst_target_bb = bb->last_ins->inst_false_bb;
6690 mono_bblock_add_inst (bb, inst);
6695 * The INDIRECT flag added by OP_LDADDR inhibits optimizations, even if the LDADDR
6696 * was later optimized away, so clear these flags, and add them back for the still
6697 * present OP_LDADDR instructions.
6699 for (i = 0; i < cfg->next_vreg; ++i) {
6702 ins = get_vreg_to_inst (cfg, i);
6703 if (ins && ins != cfg->rgctx_var)
6704 ins->flags &= ~MONO_INST_INDIRECT;
6708 * Make a first pass over the code to precreate PHI nodes/set INDIRECT flags.
6710 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
6712 LLVMBuilderRef builder;
6714 char dname_buf[128];
6716 builder = create_builder (ctx);
6718 for (ins = bb->code; ins; ins = ins->next) {
6719 switch (ins->opcode) {
6724 LLVMTypeRef phi_type = llvm_type_to_stack_type (cfg, type_to_llvm_type (ctx, &ins->klass->byval_arg));
6729 if (ins->opcode == OP_VPHI) {
6730 /* Treat valuetype PHI nodes as operating on the address itself */
6731 g_assert (ins->klass);
6732 phi_type = LLVMPointerType (type_to_llvm_type (ctx, &ins->klass->byval_arg), 0);
6736 * Have to precreate these, as they can be referenced by
6737 * earlier instructions.
6739 sprintf (dname_buf, "t%d", ins->dreg);
6741 values [ins->dreg] = LLVMBuildPhi (builder, phi_type, dname);
6743 if (ins->opcode == OP_VPHI)
6744 ctx->addresses [ins->dreg] = values [ins->dreg];
6746 g_ptr_array_add (ctx->phi_values, values [ins->dreg]);
6749 * Set the expected type of the incoming arguments since these have
6750 * to have the same type.
6752 for (i = 0; i < ins->inst_phi_args [0]; i++) {
6753 int sreg1 = ins->inst_phi_args [i + 1];
6756 ctx->vreg_types [sreg1] = phi_type;
6761 ((MonoInst*)ins->inst_p0)->flags |= MONO_INST_INDIRECT;
6770 * Create an ordering for bblocks, use the depth first order first, then
6771 * put the exception handling bblocks last.
6773 for (bb_index = 0; bb_index < cfg->num_bblocks; ++bb_index) {
6774 bb = cfg->bblocks [bb_index];
6775 if (!(bb->region != -1 && !MONO_BBLOCK_IS_IN_REGION (bb, MONO_REGION_TRY))) {
6776 g_ptr_array_add (bblock_list, bb);
6777 bblocks [bb->block_num].added = TRUE;
6781 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
6782 if (!bblocks [bb->block_num].added)
6783 g_ptr_array_add (bblock_list, bb);
6787 * Second pass: generate code.
6790 LLVMBuilderRef entry_builder = create_builder (ctx);
6791 LLVMBasicBlockRef entry_bb = get_bb (ctx, cfg->bb_entry);
6792 LLVMPositionBuilderAtEnd (entry_builder, entry_bb);
6793 emit_entry_bb (ctx, entry_builder);
6795 // Make landing pads first
6796 ctx->exc_meta = g_hash_table_new_full (NULL, NULL, NULL, NULL);
6798 if (ctx->llvm_only) {
6799 size_t group_index = 0;
6800 while (group_index < cfg->header->num_clauses) {
6802 size_t cursor = group_index;
6803 while (cursor < cfg->header->num_clauses &&
6804 CLAUSE_START (&cfg->header->clauses [cursor]) == CLAUSE_START (&cfg->header->clauses [group_index]) &&
6805 CLAUSE_END (&cfg->header->clauses [cursor]) == CLAUSE_END (&cfg->header->clauses [group_index])) {
6810 LLVMBasicBlockRef lpad_bb = emit_landing_pad (ctx, group_index, count);
6811 intptr_t key = CLAUSE_END (&cfg->header->clauses [group_index]);
6812 g_hash_table_insert (ctx->exc_meta, (gpointer)key, lpad_bb);
6814 group_index = cursor;
6818 for (bb_index = 0; bb_index < bblock_list->len; ++bb_index) {
6819 bb = (MonoBasicBlock*)g_ptr_array_index (bblock_list, bb_index);
6821 // Prune unreachable mono BBs.
6822 if (!(bb == cfg->bb_entry || bb->in_count > 0))
6825 process_bb (ctx, bb);
6829 g_hash_table_destroy (ctx->exc_meta);
6831 mono_memory_barrier ();
6833 /* Add incoming phi values */
6834 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
6835 GSList *l, *ins_list;
6837 ins_list = bblocks [bb->block_num].phi_nodes;
6839 for (l = ins_list; l; l = l->next) {
6840 PhiNode *node = (PhiNode*)l->data;
6841 MonoInst *phi = node->phi;
6842 int sreg1 = node->sreg;
6843 LLVMBasicBlockRef in_bb;
6848 in_bb = get_end_bb (ctx, node->in_bb);
6850 if (ctx->unreachable [node->in_bb->block_num])
6853 if (!values [sreg1]) {
6854 /* Can happen with values in EH clauses */
6855 set_failure (ctx, "incoming phi sreg1");
6859 if (phi->opcode == OP_VPHI) {
6860 g_assert (LLVMTypeOf (ctx->addresses [sreg1]) == LLVMTypeOf (values [phi->dreg]));
6861 LLVMAddIncoming (values [phi->dreg], &ctx->addresses [sreg1], &in_bb, 1);
6863 if (LLVMTypeOf (values [sreg1]) != LLVMTypeOf (values [phi->dreg])) {
6864 set_failure (ctx, "incoming phi arg type mismatch");
6867 g_assert (LLVMTypeOf (values [sreg1]) == LLVMTypeOf (values [phi->dreg]));
6868 LLVMAddIncoming (values [phi->dreg], &values [sreg1], &in_bb, 1);
6873 /* Nullify empty phi instructions */
6874 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
6875 GSList *l, *ins_list;
6877 ins_list = bblocks [bb->block_num].phi_nodes;
6879 for (l = ins_list; l; l = l->next) {
6880 PhiNode *node = (PhiNode*)l->data;
6881 MonoInst *phi = node->phi;
6882 LLVMValueRef phi_ins = values [phi->dreg];
6885 /* Already removed */
6888 if (LLVMCountIncoming (phi_ins) == 0) {
6889 mono_llvm_replace_uses_of (phi_ins, LLVMConstNull (LLVMTypeOf (phi_ins)));
6890 LLVMInstructionEraseFromParent (phi_ins);
6891 values [phi->dreg] = NULL;
6896 /* Create the SWITCH statements for ENDFINALLY instructions */
6897 for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
6898 BBInfo *info = &bblocks [bb->block_num];
6900 for (l = info->endfinally_switch_ins_list; l; l = l->next) {
6901 LLVMValueRef switch_ins = (LLVMValueRef)l->data;
6902 GSList *bb_list = info->call_handler_return_bbs;
6904 for (i = 0; i < g_slist_length (bb_list); ++i)
6905 LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), i + 1, FALSE), (LLVMBasicBlockRef)(g_slist_nth (bb_list, i)->data));
6909 /* Initialize the method if needed */
6910 if (cfg->compile_aot && ctx->llvm_only) {
6911 // FIXME: Add more shared got entries
6912 ctx->builder = create_builder (ctx);
6913 LLVMPositionBuilderAtEnd (ctx->builder, ctx->init_bb);
6915 ctx->module->max_method_idx = MAX (ctx->module->max_method_idx, cfg->method_index);
6917 // FIXME: beforefieldinit
6918 if (ctx->has_got_access || mono_class_get_cctor (cfg->method->klass)) {
6919 emit_init_method (ctx);
6921 LLVMBuildBr (ctx->builder, ctx->inited_bb);
6925 if (cfg->llvm_only) {
6926 GHashTableIter iter;
6928 GSList *callers, *l, *l2;
6931 * Add the contents of ctx->method_to_callers to module->method_to_callers.
6932 * We can't do this earlier, as it contains llvm instructions which can be
6933 * freed if compilation fails.
6934 * FIXME: Get rid of this when all methods can be llvm compiled.
6936 g_hash_table_iter_init (&iter, ctx->method_to_callers);
6937 while (g_hash_table_iter_next (&iter, (void**)&method, (void**)&callers)) {
6938 for (l = callers; l; l = l->next) {
6939 l2 = (GSList*)g_hash_table_lookup (ctx->module->method_to_callers, method);
6940 l2 = g_slist_prepend (l2, l->data);
6941 g_hash_table_insert (ctx->module->method_to_callers, method, l2);
6946 if (cfg->verbose_level > 1)
6947 mono_llvm_dump_value (method);
6949 if (cfg->compile_aot && !cfg->llvm_only)
6950 mark_as_used (ctx->module, method);
6952 if (cfg->compile_aot && !cfg->llvm_only) {
6953 LLVMValueRef md_args [16];
6954 LLVMValueRef md_node;
6957 method_index = mono_aot_get_method_index (cfg->orig_method);
6958 md_args [0] = LLVMMDString (ctx->method_name, strlen (ctx->method_name));
6959 md_args [1] = LLVMConstInt (LLVMInt32Type (), method_index, FALSE);
6960 md_node = LLVMMDNode (md_args, 2);
6961 LLVMAddNamedMetadataOperand (lmodule, "mono.function_indexes", md_node);
6962 //LLVMSetMetadata (method, md_kind, LLVMMDNode (&md_arg, 1));
6965 if (cfg->compile_aot) {
6966 /* Don't generate native code, keep the LLVM IR */
6967 if (cfg->verbose_level)
6968 printf ("%s emitted as %s\n", mono_method_full_name (cfg->method, TRUE), ctx->method_name);
6970 int err = LLVMVerifyFunction(ctx->lmethod, LLVMPrintMessageAction);
6971 g_assert (err == 0);
6973 //LLVMVerifyFunction(method, 0);
6974 mono_llvm_optimize_method (ctx->module->mono_ee, ctx->lmethod);
6976 if (cfg->verbose_level > 1)
6977 mono_llvm_dump_value (ctx->lmethod);
6979 cfg->native_code = (unsigned char*)LLVMGetPointerToGlobal (ctx->module->ee, ctx->lmethod);
6981 /* Set by emit_cb */
6982 g_assert (cfg->code_len);
6985 if (ctx->module->method_to_lmethod)
6986 g_hash_table_insert (ctx->module->method_to_lmethod, cfg->method, ctx->lmethod);
6987 if (ctx->module->idx_to_lmethod)
6988 g_hash_table_insert (ctx->module->idx_to_lmethod, GINT_TO_POINTER (cfg->method_index), ctx->lmethod);
6990 if (ctx->llvm_only && cfg->orig_method->klass->valuetype && !(cfg->orig_method->flags & METHOD_ATTRIBUTE_STATIC))
6991 emit_unbox_tramp (ctx, ctx->method_name, ctx->method_type, ctx->lmethod, cfg->method_index);
6995 * mono_llvm_create_vars:
6997 * Same as mono_arch_create_vars () for LLVM.
7000 mono_llvm_create_vars (MonoCompile *cfg)
7002 MonoMethodSignature *sig;
7004 sig = mono_method_signature (cfg->method);
7005 if (cfg->gsharedvt && cfg->llvm_only) {
7006 if (mini_is_gsharedvt_variable_signature (sig) && sig->ret->type != MONO_TYPE_VOID) {
7007 cfg->vret_addr = mono_compile_create_var (cfg, &mono_get_intptr_class ()->byval_arg, OP_ARG);
7008 if (G_UNLIKELY (cfg->verbose_level > 1)) {
7009 printf ("vret_addr = ");
7010 mono_print_ins (cfg->vret_addr);
7014 mono_arch_create_vars (cfg);
7019 * mono_llvm_emit_call:
7021 * Same as mono_arch_emit_call () for LLVM.
7024 mono_llvm_emit_call (MonoCompile *cfg, MonoCallInst *call)
7027 MonoMethodSignature *sig;
7028 int i, n, stack_size;
7033 sig = call->signature;
7034 n = sig->param_count + sig->hasthis;
7036 call->cinfo = get_llvm_call_info (cfg, sig);
7038 if (cfg->disable_llvm)
7041 if (sig->call_convention == MONO_CALL_VARARG) {
7042 cfg->exception_message = g_strdup ("varargs");
7043 cfg->disable_llvm = TRUE;
7046 for (i = 0; i < n; ++i) {
7049 ainfo = call->cinfo->args + i;
7051 in = call->args [i];
7053 /* Simply remember the arguments */
7054 switch (ainfo->storage) {
7055 case LLVMArgNormal: {
7056 MonoType *t = (sig->hasthis && i == 0) ? &mono_get_intptr_class ()->byval_arg : ainfo->type;
7059 opcode = mono_type_to_regmove (cfg, t);
7060 if (opcode == OP_FMOVE) {
7061 MONO_INST_NEW (cfg, ins, OP_FMOVE);
7062 ins->dreg = mono_alloc_freg (cfg);
7063 } else if (opcode == OP_LMOVE) {
7064 MONO_INST_NEW (cfg, ins, OP_LMOVE);
7065 ins->dreg = mono_alloc_lreg (cfg);
7066 } else if (opcode == OP_RMOVE) {
7067 MONO_INST_NEW (cfg, ins, OP_RMOVE);
7068 ins->dreg = mono_alloc_freg (cfg);
7070 MONO_INST_NEW (cfg, ins, OP_MOVE);
7071 ins->dreg = mono_alloc_ireg (cfg);
7073 ins->sreg1 = in->dreg;
7076 case LLVMArgVtypeByVal:
7077 case LLVMArgVtypeByRef:
7078 case LLVMArgVtypeInReg:
7079 case LLVMArgVtypeAsScalar:
7080 case LLVMArgScalarByRef:
7081 case LLVMArgAsIArgs:
7082 case LLVMArgAsFpArgs:
7083 case LLVMArgGsharedvtVariable:
7084 case LLVMArgGsharedvtFixed:
7085 case LLVMArgGsharedvtFixedVtype:
7086 MONO_INST_NEW (cfg, ins, OP_LLVM_OUTARG_VT);
7087 ins->dreg = mono_alloc_ireg (cfg);
7088 ins->sreg1 = in->dreg;
7089 ins->inst_p0 = mono_mempool_alloc0 (cfg->mempool, sizeof (LLVMArgInfo));
7090 memcpy (ins->inst_p0, ainfo, sizeof (LLVMArgInfo));
7091 ins->inst_vtype = ainfo->type;
7092 ins->klass = mono_class_from_mono_type (ainfo->type);
7095 cfg->exception_message = g_strdup ("ainfo->storage");
7096 cfg->disable_llvm = TRUE;
7100 if (!cfg->disable_llvm) {
7101 MONO_ADD_INS (cfg->cbb, ins);
7102 mono_call_inst_add_outarg_reg (cfg, call, ins->dreg, 0, FALSE);
7107 static unsigned char*
7108 alloc_cb (LLVMValueRef function, int size)
7112 cfg = (MonoCompile*)mono_native_tls_get_value (current_cfg_tls_id);
7116 return (unsigned char*)mono_domain_code_reserve (cfg->domain, size);
7118 return (unsigned char*)mono_domain_code_reserve (mono_domain_get (), size);
7123 emitted_cb (LLVMValueRef function, void *start, void *end)
7127 cfg = (MonoCompile*)mono_native_tls_get_value (current_cfg_tls_id);
7129 cfg->code_len = (guint8*)end - (guint8*)start;
7133 exception_cb (void *data)
7136 MonoJitExceptionInfo *ei;
7137 guint32 ei_len, i, j, nested_len, nindex;
7138 gpointer *type_info;
7139 int this_reg, this_offset;
7141 cfg = (MonoCompile*)mono_native_tls_get_value (current_cfg_tls_id);
7145 * data points to a DWARF FDE structure, convert it to our unwind format and
7147 * An alternative would be to save it directly, and modify our unwinder to work
7150 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);
7151 if (cfg->verbose_level > 1)
7152 mono_print_unwind_info (cfg->encoded_unwind_ops, cfg->encoded_unwind_ops_len);
7154 /* Count nested clauses */
7156 for (i = 0; i < ei_len; ++i) {
7157 gint32 cindex1 = *(gint32*)type_info [i];
7158 MonoExceptionClause *clause1 = &cfg->header->clauses [cindex1];
7160 for (j = 0; j < cfg->header->num_clauses; ++j) {
7162 MonoExceptionClause *clause2 = &cfg->header->clauses [cindex2];
7164 if (cindex1 != cindex2 && clause1->try_offset >= clause2->try_offset && clause1->handler_offset <= clause2->handler_offset) {
7170 cfg->llvm_ex_info = (MonoJitExceptionInfo*)mono_mempool_alloc0 (cfg->mempool, (ei_len + nested_len) * sizeof (MonoJitExceptionInfo));
7171 cfg->llvm_ex_info_len = ei_len + nested_len;
7172 memcpy (cfg->llvm_ex_info, ei, ei_len * sizeof (MonoJitExceptionInfo));
7173 /* Fill the rest of the information from the type info */
7174 for (i = 0; i < ei_len; ++i) {
7175 gint32 clause_index = *(gint32*)type_info [i];
7176 MonoExceptionClause *clause = &cfg->header->clauses [clause_index];
7178 cfg->llvm_ex_info [i].flags = clause->flags;
7179 cfg->llvm_ex_info [i].data.catch_class = clause->data.catch_class;
7180 cfg->llvm_ex_info [i].clause_index = clause_index;
7184 * For nested clauses, the LLVM produced exception info associates the try interval with
7185 * the innermost handler, while mono expects it to be associated with all nesting clauses.
7186 * So add new clauses which use the IL info (catch class etc.) from the nesting clause,
7187 * and everything else from the nested clause.
7190 for (i = 0; i < ei_len; ++i) {
7191 gint32 cindex1 = *(gint32*)type_info [i];
7192 MonoExceptionClause *clause1 = &cfg->header->clauses [cindex1];
7194 for (j = 0; j < cfg->header->num_clauses; ++j) {
7196 MonoExceptionClause *clause2 = &cfg->header->clauses [cindex2];
7197 MonoJitExceptionInfo *nesting_ei, *nested_ei;
7199 if (cindex1 != cindex2 && clause1->try_offset >= clause2->try_offset && clause1->handler_offset <= clause2->handler_offset) {
7200 /* clause1 is the nested clause */
7201 nested_ei = &cfg->llvm_ex_info [i];
7202 nesting_ei = &cfg->llvm_ex_info [nindex];
7205 memcpy (nesting_ei, nested_ei, sizeof (MonoJitExceptionInfo));
7207 nesting_ei->flags = clause2->flags;
7208 nesting_ei->data.catch_class = clause2->data.catch_class;
7209 nesting_ei->clause_index = cindex2;
7213 g_assert (nindex == ei_len + nested_len);
7214 cfg->llvm_this_reg = this_reg;
7215 cfg->llvm_this_offset = this_offset;
7217 /* type_info [i] is cfg mempool allocated, no need to free it */
7224 dlsym_cb (const char *name, void **symbol)
7230 if (!strcmp (name, "__bzero")) {
7231 *symbol = (void*)bzero;
7233 current = mono_dl_open (NULL, 0, NULL);
7236 err = mono_dl_symbol (current, name, symbol);
7238 mono_dl_close (current);
7240 #ifdef MONO_ARCH_HAVE_CREATE_LLVM_NATIVE_THUNK
7241 *symbol = (char*)mono_arch_create_llvm_native_thunk (mono_domain_get (), (guint8*)(*symbol));
7247 AddFunc (LLVMModuleRef module, const char *name, LLVMTypeRef ret_type, LLVMTypeRef *param_types, int nparams)
7249 LLVMAddFunction (module, name, LLVMFunctionType (ret_type, param_types, nparams, FALSE));
7253 AddFunc2 (LLVMModuleRef module, const char *name, LLVMTypeRef ret_type, LLVMTypeRef param_type1, LLVMTypeRef param_type2)
7255 LLVMTypeRef param_types [4];
7257 param_types [0] = param_type1;
7258 param_types [1] = param_type2;
7260 AddFunc (module, name, ret_type, param_types, 2);
7264 add_intrinsics (LLVMModuleRef module)
7266 /* Emit declarations of instrinsics */
7268 * It would be nicer to emit only the intrinsics actually used, but LLVM's Module
7269 * type doesn't seem to do any locking.
7272 LLVMTypeRef params [] = { LLVMPointerType (LLVMInt8Type (), 0), LLVMInt8Type (), LLVMInt32Type (), LLVMInt32Type (), LLVMInt1Type () };
7274 memset_param_count = 5;
7275 memset_func_name = "llvm.memset.p0i8.i32";
7277 AddFunc (module, memset_func_name, LLVMVoidType (), params, memset_param_count);
7281 LLVMTypeRef params [] = { LLVMPointerType (LLVMInt8Type (), 0), LLVMPointerType (LLVMInt8Type (), 0), LLVMInt32Type (), LLVMInt32Type (), LLVMInt1Type () };
7283 memcpy_param_count = 5;
7284 memcpy_func_name = "llvm.memcpy.p0i8.p0i8.i32";
7286 AddFunc (module, memcpy_func_name, LLVMVoidType (), params, memcpy_param_count);
7290 LLVMTypeRef params [] = { LLVMDoubleType () };
7292 AddFunc (module, "llvm.sin.f64", LLVMDoubleType (), params, 1);
7293 AddFunc (module, "llvm.cos.f64", LLVMDoubleType (), params, 1);
7294 AddFunc (module, "llvm.sqrt.f64", LLVMDoubleType (), params, 1);
7296 /* This isn't an intrinsic, instead llvm seems to special case it by name */
7297 AddFunc (module, "fabs", LLVMDoubleType (), params, 1);
7301 LLVMTypeRef ovf_res_i32 [] = { LLVMInt32Type (), LLVMInt1Type () };
7302 LLVMTypeRef params [] = { LLVMInt32Type (), LLVMInt32Type () };
7303 LLVMTypeRef ret_type = LLVMStructType (ovf_res_i32, 2, FALSE);
7305 AddFunc (module, "llvm.sadd.with.overflow.i32", ret_type, params, 2);
7306 AddFunc (module, "llvm.sadd.with.overflow.i32", ret_type, params, 2);
7307 AddFunc (module, "llvm.uadd.with.overflow.i32", ret_type, params, 2);
7308 AddFunc (module, "llvm.ssub.with.overflow.i32", ret_type, params, 2);
7309 AddFunc (module, "llvm.usub.with.overflow.i32", ret_type, params, 2);
7310 AddFunc (module, "llvm.smul.with.overflow.i32", ret_type, params, 2);
7311 AddFunc (module, "llvm.umul.with.overflow.i32", ret_type, params, 2);
7315 LLVMTypeRef ovf_res_i64 [] = { LLVMInt64Type (), LLVMInt1Type () };
7316 LLVMTypeRef params [] = { LLVMInt64Type (), LLVMInt64Type () };
7317 LLVMTypeRef ret_type = LLVMStructType (ovf_res_i64, 2, FALSE);
7319 AddFunc (module, "llvm.sadd.with.overflow.i64", ret_type, params, 2);
7320 AddFunc (module, "llvm.uadd.with.overflow.i64", ret_type, params, 2);
7321 AddFunc (module, "llvm.ssub.with.overflow.i64", ret_type, params, 2);
7322 AddFunc (module, "llvm.usub.with.overflow.i64", ret_type, params, 2);
7323 AddFunc (module, "llvm.smul.with.overflow.i64", ret_type, params, 2);
7324 AddFunc (module, "llvm.umul.with.overflow.i64", ret_type, params, 2);
7327 AddFunc2 (module, "llvm.expect.i8", LLVMInt8Type (), LLVMInt8Type (), LLVMInt8Type ());
7328 AddFunc2 (module, "llvm.expect.i1", LLVMInt1Type (), LLVMInt1Type (), LLVMInt1Type ());
7332 AddFunc (module, "mono_personality", LLVMVoidType (), NULL, 0);
7334 AddFunc (module, "llvm_resume_unwind_trampoline", LLVMVoidType (), NULL, 0);
7337 /* SSE intrinsics */
7338 #if defined(TARGET_X86) || defined(TARGET_AMD64)
7340 LLVMTypeRef ret_type, arg_types [16];
7343 ret_type = type_to_simd_type (MONO_TYPE_I4);
7344 arg_types [0] = ret_type;
7345 arg_types [1] = ret_type;
7346 AddFunc (module, "llvm.x86.sse41.pminud", ret_type, arg_types, 2);
7347 AddFunc (module, "llvm.x86.sse41.pmaxud", ret_type, arg_types, 2);
7349 ret_type = type_to_simd_type (MONO_TYPE_I2);
7350 arg_types [0] = ret_type;
7351 arg_types [1] = ret_type;
7352 AddFunc (module, "llvm.x86.sse41.pminuw", ret_type, arg_types, 2);
7353 AddFunc (module, "llvm.x86.sse2.pmins.w", ret_type, arg_types, 2);
7354 AddFunc (module, "llvm.x86.sse41.pmaxuw", ret_type, arg_types, 2);
7355 AddFunc (module, "llvm.x86.sse2.padds.w", ret_type, arg_types, 2);
7356 AddFunc (module, "llvm.x86.sse2.psubs.w", ret_type, arg_types, 2);
7357 AddFunc (module, "llvm.x86.sse2.paddus.w", ret_type, arg_types, 2);
7358 AddFunc (module, "llvm.x86.sse2.psubus.w", ret_type, arg_types, 2);
7359 AddFunc (module, "llvm.x86.sse2.pavg.w", ret_type, arg_types, 2);
7360 AddFunc (module, "llvm.x86.sse2.pmulh.w", ret_type, arg_types, 2);
7361 AddFunc (module, "llvm.x86.sse2.pmulhu.w", ret_type, arg_types, 2);
7363 ret_type = type_to_simd_type (MONO_TYPE_I1);
7364 arg_types [0] = ret_type;
7365 arg_types [1] = ret_type;
7366 AddFunc (module, "llvm.x86.sse2.pminu.b", ret_type, arg_types, 2);
7367 AddFunc (module, "llvm.x86.sse2.pmaxu.b", ret_type, arg_types, 2);
7368 AddFunc (module, "llvm.x86.sse2.padds.b", ret_type, arg_types, 2);
7369 AddFunc (module, "llvm.x86.sse2.psubs.b", ret_type, arg_types, 2);
7370 AddFunc (module, "llvm.x86.sse2.paddus.b", ret_type, arg_types, 2);
7371 AddFunc (module, "llvm.x86.sse2.psubus.b", ret_type, arg_types, 2);
7372 AddFunc (module, "llvm.x86.sse2.pavg.b", ret_type, arg_types, 2);
7374 ret_type = type_to_simd_type (MONO_TYPE_R8);
7375 arg_types [0] = ret_type;
7376 arg_types [1] = ret_type;
7377 AddFunc (module, "llvm.x86.sse2.min.pd", ret_type, arg_types, 2);
7378 AddFunc (module, "llvm.x86.sse2.max.pd", ret_type, arg_types, 2);
7379 AddFunc (module, "llvm.x86.sse3.hadd.pd", ret_type, arg_types, 2);
7380 AddFunc (module, "llvm.x86.sse3.hsub.pd", ret_type, arg_types, 2);
7381 AddFunc (module, "llvm.x86.sse3.addsub.pd", ret_type, arg_types, 2);
7383 ret_type = type_to_simd_type (MONO_TYPE_R4);
7384 arg_types [0] = ret_type;
7385 arg_types [1] = ret_type;
7386 AddFunc (module, "llvm.x86.sse.min.ps", ret_type, arg_types, 2);
7387 AddFunc (module, "llvm.x86.sse.max.ps", ret_type, arg_types, 2);
7388 AddFunc (module, "llvm.x86.sse3.hadd.ps", ret_type, arg_types, 2);
7389 AddFunc (module, "llvm.x86.sse3.hsub.ps", ret_type, arg_types, 2);
7390 AddFunc (module, "llvm.x86.sse3.addsub.ps", ret_type, arg_types, 2);
7393 ret_type = type_to_simd_type (MONO_TYPE_I1);
7394 arg_types [0] = type_to_simd_type (MONO_TYPE_I2);
7395 arg_types [1] = type_to_simd_type (MONO_TYPE_I2);
7396 AddFunc (module, "llvm.x86.sse2.packsswb.128", ret_type, arg_types, 2);
7397 AddFunc (module, "llvm.x86.sse2.packuswb.128", ret_type, arg_types, 2);
7398 ret_type = type_to_simd_type (MONO_TYPE_I2);
7399 arg_types [0] = type_to_simd_type (MONO_TYPE_I4);
7400 arg_types [1] = type_to_simd_type (MONO_TYPE_I4);
7401 AddFunc (module, "llvm.x86.sse2.packssdw.128", ret_type, arg_types, 2);
7402 AddFunc (module, "llvm.x86.sse41.packusdw", ret_type, arg_types, 2);
7405 ret_type = type_to_simd_type (MONO_TYPE_R8);
7406 arg_types [0] = ret_type;
7407 arg_types [1] = ret_type;
7408 arg_types [2] = LLVMInt8Type ();
7409 AddFunc (module, "llvm.x86.sse2.cmp.pd", ret_type, arg_types, 3);
7410 ret_type = type_to_simd_type (MONO_TYPE_R4);
7411 arg_types [0] = ret_type;
7412 arg_types [1] = ret_type;
7413 arg_types [2] = LLVMInt8Type ();
7414 AddFunc (module, "llvm.x86.sse.cmp.ps", ret_type, arg_types, 3);
7416 /* Conversion ops */
7417 ret_type = type_to_simd_type (MONO_TYPE_R8);
7418 arg_types [0] = type_to_simd_type (MONO_TYPE_I4);
7419 AddFunc (module, "llvm.x86.sse2.cvtdq2pd", ret_type, arg_types, 1);
7420 ret_type = type_to_simd_type (MONO_TYPE_R4);
7421 arg_types [0] = type_to_simd_type (MONO_TYPE_I4);
7422 AddFunc (module, "llvm.x86.sse2.cvtdq2ps", ret_type, arg_types, 1);
7423 ret_type = type_to_simd_type (MONO_TYPE_I4);
7424 arg_types [0] = type_to_simd_type (MONO_TYPE_R8);
7425 AddFunc (module, "llvm.x86.sse2.cvtpd2dq", ret_type, arg_types, 1);
7426 ret_type = type_to_simd_type (MONO_TYPE_I4);
7427 arg_types [0] = type_to_simd_type (MONO_TYPE_R4);
7428 AddFunc (module, "llvm.x86.sse2.cvtps2dq", ret_type, arg_types, 1);
7429 ret_type = type_to_simd_type (MONO_TYPE_R4);
7430 arg_types [0] = type_to_simd_type (MONO_TYPE_R8);
7431 AddFunc (module, "llvm.x86.sse2.cvtpd2ps", ret_type, arg_types, 1);
7432 ret_type = type_to_simd_type (MONO_TYPE_R8);
7433 arg_types [0] = type_to_simd_type (MONO_TYPE_R4);
7434 AddFunc (module, "llvm.x86.sse2.cvtps2pd", ret_type, arg_types, 1);
7436 ret_type = type_to_simd_type (MONO_TYPE_I4);
7437 arg_types [0] = type_to_simd_type (MONO_TYPE_R8);
7438 AddFunc (module, "llvm.x86.sse2.cvttpd2dq", ret_type, arg_types, 1);
7439 ret_type = type_to_simd_type (MONO_TYPE_I4);
7440 arg_types [0] = type_to_simd_type (MONO_TYPE_R4);
7441 AddFunc (module, "llvm.x86.sse2.cvttps2dq", ret_type, arg_types, 1);
7444 ret_type = type_to_simd_type (MONO_TYPE_R8);
7445 arg_types [0] = ret_type;
7446 AddFunc (module, "llvm.x86.sse2.sqrt.pd", ret_type, arg_types, 1);
7447 ret_type = type_to_simd_type (MONO_TYPE_R4);
7448 arg_types [0] = ret_type;
7449 AddFunc (module, "llvm.x86.sse.sqrt.ps", ret_type, arg_types, 1);
7450 ret_type = type_to_simd_type (MONO_TYPE_R4);
7451 arg_types [0] = ret_type;
7452 AddFunc (module, "llvm.x86.sse.rsqrt.ps", ret_type, arg_types, 1);
7453 ret_type = type_to_simd_type (MONO_TYPE_R4);
7454 arg_types [0] = ret_type;
7455 AddFunc (module, "llvm.x86.sse.rcp.ps", ret_type, arg_types, 1);
7458 ret_type = type_to_simd_type (MONO_TYPE_I2);
7459 arg_types [0] = ret_type;
7460 arg_types [1] = LLVMInt32Type ();
7461 AddFunc (module, "llvm.x86.sse2.psrli.w", ret_type, arg_types, 2);
7462 AddFunc (module, "llvm.x86.sse2.psrai.w", ret_type, arg_types, 2);
7463 AddFunc (module, "llvm.x86.sse2.pslli.w", ret_type, arg_types, 2);
7464 ret_type = type_to_simd_type (MONO_TYPE_I4);
7465 arg_types [0] = ret_type;
7466 arg_types [1] = LLVMInt32Type ();
7467 AddFunc (module, "llvm.x86.sse2.psrli.d", ret_type, arg_types, 2);
7468 AddFunc (module, "llvm.x86.sse2.psrai.d", ret_type, arg_types, 2);
7469 AddFunc (module, "llvm.x86.sse2.pslli.d", ret_type, arg_types, 2);
7470 ret_type = type_to_simd_type (MONO_TYPE_I8);
7471 arg_types [0] = ret_type;
7472 arg_types [1] = LLVMInt32Type ();
7473 AddFunc (module, "llvm.x86.sse2.psrli.q", ret_type, arg_types, 2);
7474 AddFunc (module, "llvm.x86.sse2.pslli.q", ret_type, arg_types, 2);
7477 ret_type = LLVMInt32Type ();
7478 arg_types [0] = type_to_simd_type (MONO_TYPE_I1);
7479 AddFunc (module, "llvm.x86.sse2.pmovmskb.128", ret_type, arg_types, 1);
7482 AddFunc (module, "llvm.x86.sse2.pause", LLVMVoidType (), NULL, 0);
7485 /* Load/Store intrinsics */
7487 LLVMTypeRef arg_types [5];
7491 for (i = 1; i <= 8; i *= 2) {
7492 arg_types [0] = LLVMPointerType (LLVMIntType (i * 8), 0);
7493 arg_types [1] = LLVMInt32Type ();
7494 arg_types [2] = LLVMInt1Type ();
7495 arg_types [3] = LLVMInt32Type ();
7496 sprintf (name, "llvm.mono.load.i%d.p0i%d", i * 8, i * 8);
7497 AddFunc (module, name, LLVMIntType (i * 8), arg_types, 4);
7499 arg_types [0] = LLVMIntType (i * 8);
7500 arg_types [1] = LLVMPointerType (LLVMIntType (i * 8), 0);
7501 arg_types [2] = LLVMInt32Type ();
7502 arg_types [3] = LLVMInt1Type ();
7503 arg_types [4] = LLVMInt32Type ();
7504 sprintf (name, "llvm.mono.store.i%d.p0i%d", i * 8, i * 8);
7505 AddFunc (module, name, LLVMVoidType (), arg_types, 5);
7511 add_types (MonoLLVMModule *module)
7513 module->ptr_type = LLVMPointerType (sizeof (gpointer) == 8 ? LLVMInt64Type () : LLVMInt32Type (), 0);
7517 mono_llvm_init (void)
7519 mono_native_tls_alloc (¤t_cfg_tls_id, NULL);
7523 init_jit_module (MonoDomain *domain)
7525 MonoJitICallInfo *info;
7526 MonoJitDomainInfo *dinfo;
7527 MonoLLVMModule *module;
7530 dinfo = domain_jit_info (domain);
7531 if (dinfo->llvm_module)
7534 mono_loader_lock ();
7536 if (dinfo->llvm_module) {
7537 mono_loader_unlock ();
7541 module = g_new0 (MonoLLVMModule, 1);
7543 name = g_strdup_printf ("mono-%s", domain->friendly_name);
7544 module->lmodule = LLVMModuleCreateWithName (name);
7545 module->context = LLVMGetGlobalContext ();
7547 module->mono_ee = (MonoEERef*)mono_llvm_create_ee (LLVMCreateModuleProviderForExistingModule (module->lmodule), alloc_cb, emitted_cb, exception_cb, dlsym_cb, &module->ee);
7549 add_intrinsics (module->lmodule);
7552 module->llvm_types = g_hash_table_new (NULL, NULL);
7554 info = mono_find_jit_icall_by_name ("llvm_resume_unwind_trampoline");
7556 LLVMAddGlobalMapping (module->ee, LLVMGetNamedFunction (module->lmodule, "llvm_resume_unwind_trampoline"), (void*)info->func);
7558 mono_memory_barrier ();
7560 dinfo->llvm_module = module;
7562 mono_loader_unlock ();
7566 mono_llvm_cleanup (void)
7568 MonoLLVMModule *module = &aot_module;
7570 if (module->lmodule)
7571 LLVMDisposeModule (module->lmodule);
7573 if (module->context)
7574 LLVMContextDispose (module->context);
7578 mono_llvm_free_domain_info (MonoDomain *domain)
7580 MonoJitDomainInfo *info = domain_jit_info (domain);
7581 MonoLLVMModule *module = (MonoLLVMModule*)info->llvm_module;
7587 if (module->llvm_types)
7588 g_hash_table_destroy (module->llvm_types);
7590 mono_llvm_dispose_ee (module->mono_ee);
7592 if (module->bb_names) {
7593 for (i = 0; i < module->bb_names_len; ++i)
7594 g_free (module->bb_names [i]);
7595 g_free (module->bb_names);
7597 //LLVMDisposeModule (module->module);
7601 info->llvm_module = NULL;
7605 mono_llvm_create_aot_module (MonoAssembly *assembly, const char *global_prefix, gboolean emit_dwarf, gboolean static_link, gboolean llvm_only)
7607 MonoLLVMModule *module = &aot_module;
7609 /* Delete previous module */
7610 if (module->plt_entries)
7611 g_hash_table_destroy (module->plt_entries);
7612 if (module->lmodule)
7613 LLVMDisposeModule (module->lmodule);
7615 memset (module, 0, sizeof (aot_module));
7617 module->lmodule = LLVMModuleCreateWithName ("aot");
7618 module->assembly = assembly;
7619 module->global_prefix = g_strdup (global_prefix);
7620 module->got_symbol = g_strdup_printf ("%s_llvm_got", global_prefix);
7621 module->eh_frame_symbol = g_strdup_printf ("%s_eh_frame", global_prefix);
7622 module->get_method_symbol = g_strdup_printf ("%s_get_method", global_prefix);
7623 module->get_unbox_tramp_symbol = g_strdup_printf ("%s_get_unbox_tramp", global_prefix);
7624 module->external_symbols = TRUE;
7625 module->emit_dwarf = emit_dwarf;
7626 module->static_link = static_link;
7627 module->llvm_only = llvm_only;
7628 /* The first few entries are reserved */
7629 module->max_got_offset = 16;
7630 module->context = LLVMContextCreate ();
7633 /* clang ignores our debug info because it has an invalid version */
7634 module->emit_dwarf = FALSE;
7636 add_intrinsics (module->lmodule);
7641 * We couldn't compute the type of the LLVM global representing the got because
7642 * its size is only known after all the methods have been emitted. So create
7643 * a dummy variable, and replace all uses it with the real got variable when
7644 * its size is known in mono_llvm_emit_aot_module ().
7647 LLVMTypeRef got_type = LLVMArrayType (module->ptr_type, 0);
7649 module->got_var = LLVMAddGlobal (module->lmodule, got_type, "mono_dummy_got");
7650 LLVMSetInitializer (module->got_var, LLVMConstNull (got_type));
7653 /* Add initialization array */
7655 LLVMTypeRef inited_type = LLVMArrayType (LLVMInt8Type (), 0);
7657 module->inited_var = LLVMAddGlobal (aot_module.lmodule, inited_type, "mono_inited_tmp");
7658 LLVMSetInitializer (module->inited_var, LLVMConstNull (inited_type));
7662 emit_init_icall_wrappers (module);
7664 emit_llvm_code_start (module);
7666 /* Add a dummy personality function */
7667 if (!use_debug_personality) {
7668 LLVMValueRef personality = LLVMAddFunction (module->lmodule, default_personality_name, LLVMFunctionType (LLVMInt32Type (), NULL, 0, TRUE));
7669 LLVMSetLinkage (personality, LLVMExternalLinkage);
7670 mark_as_used (module, personality);
7673 /* Add a reference to the c++ exception we throw/catch */
7675 LLVMTypeRef exc = LLVMPointerType (LLVMInt8Type (), 0);
7676 module->sentinel_exception = LLVMAddGlobal (module->lmodule, exc, "_ZTIPi");
7677 LLVMSetLinkage (module->sentinel_exception, LLVMExternalLinkage);
7678 mono_llvm_set_is_constant (module->sentinel_exception);
7681 module->llvm_types = g_hash_table_new (NULL, NULL);
7682 module->plt_entries = g_hash_table_new (g_str_hash, g_str_equal);
7683 module->plt_entries_ji = g_hash_table_new (NULL, NULL);
7684 module->direct_callables = g_hash_table_new (g_str_hash, g_str_equal);
7685 module->method_to_lmethod = g_hash_table_new (NULL, NULL);
7686 module->idx_to_lmethod = g_hash_table_new (NULL, NULL);
7687 module->idx_to_unbox_tramp = g_hash_table_new (NULL, NULL);
7688 module->method_to_callers = g_hash_table_new (NULL, NULL);
7692 llvm_array_from_uints (LLVMTypeRef el_type, guint32 *values, int nvalues)
7695 LLVMValueRef res, *vals;
7697 vals = g_new0 (LLVMValueRef, nvalues);
7698 for (i = 0; i < nvalues; ++i)
7699 vals [i] = LLVMConstInt (LLVMInt32Type (), values [i], FALSE);
7700 res = LLVMConstArray (LLVMInt32Type (), vals, nvalues);
7706 * mono_llvm_emit_aot_file_info:
7708 * Emit the MonoAotFileInfo structure.
7709 * Same as emit_aot_file_info () in aot-compiler.c.
7712 mono_llvm_emit_aot_file_info (MonoAotFileInfo *info, gboolean has_jitted_code)
7714 MonoLLVMModule *module = &aot_module;
7716 /* Save these for later */
7717 memcpy (&module->aot_info, info, sizeof (MonoAotFileInfo));
7718 module->has_jitted_code = has_jitted_code;
7722 * mono_llvm_emit_aot_data:
7724 * Emit the binary data DATA pointed to by symbol SYMBOL.
7727 mono_llvm_emit_aot_data (const char *symbol, guint8 *data, int data_len)
7729 MonoLLVMModule *module = &aot_module;
7733 type = LLVMArrayType (LLVMInt8Type (), data_len);
7734 d = LLVMAddGlobal (module->lmodule, type, symbol);
7735 LLVMSetVisibility (d, LLVMHiddenVisibility);
7736 LLVMSetLinkage (d, LLVMInternalLinkage);
7737 LLVMSetInitializer (d, mono_llvm_create_constant_data_array (data, data_len));
7738 mono_llvm_set_is_constant (d);
7741 /* Add a reference to a global defined in JITted code */
7743 AddJitGlobal (MonoLLVMModule *module, LLVMTypeRef type, const char *name)
7748 s = g_strdup_printf ("%s%s", module->global_prefix, name);
7749 v = LLVMAddGlobal (module->lmodule, LLVMInt8Type (), s);
7755 emit_aot_file_info (MonoLLVMModule *module)
7757 LLVMTypeRef file_info_type;
7758 LLVMTypeRef *eltypes, eltype;
7759 LLVMValueRef info_var;
7760 LLVMValueRef *fields;
7761 int i, nfields, tindex;
7762 MonoAotFileInfo *info;
7763 LLVMModuleRef lmodule = module->lmodule;
7765 info = &module->aot_info;
7767 /* Create an LLVM type to represent MonoAotFileInfo */
7768 nfields = 2 + MONO_AOT_FILE_INFO_NUM_SYMBOLS + 15 + 5;
7769 eltypes = g_new (LLVMTypeRef, nfields);
7771 eltypes [tindex ++] = LLVMInt32Type ();
7772 eltypes [tindex ++] = LLVMInt32Type ();
7774 for (i = 0; i < MONO_AOT_FILE_INFO_NUM_SYMBOLS; ++i)
7775 eltypes [tindex ++] = LLVMPointerType (LLVMInt8Type (), 0);
7777 for (i = 0; i < 15; ++i)
7778 eltypes [tindex ++] = LLVMInt32Type ();
7780 eltypes [tindex ++] = LLVMArrayType (LLVMInt32Type (), MONO_AOT_TABLE_NUM);
7781 for (i = 0; i < 4; ++i)
7782 eltypes [tindex ++] = LLVMArrayType (LLVMInt32Type (), MONO_AOT_TRAMP_NUM);
7783 g_assert (tindex == nfields);
7784 file_info_type = LLVMStructCreateNamed (module->context, "MonoAotFileInfo");
7785 LLVMStructSetBody (file_info_type, eltypes, nfields, FALSE);
7787 info_var = LLVMAddGlobal (lmodule, file_info_type, "mono_aot_file_info");
7788 if (module->static_link) {
7789 LLVMSetVisibility (info_var, LLVMHiddenVisibility);
7790 LLVMSetLinkage (info_var, LLVMInternalLinkage);
7792 fields = g_new (LLVMValueRef, nfields);
7794 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->version, FALSE);
7795 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->dummy, FALSE);
7799 * We use LLVMGetNamedGlobal () for symbol which are defined in LLVM code, and LLVMAddGlobal ()
7800 * for symbols defined in the .s file emitted by the aot compiler.
7802 eltype = eltypes [tindex];
7803 if (module->llvm_only)
7804 fields [tindex ++] = LLVMConstNull (eltype);
7806 fields [tindex ++] = AddJitGlobal (module, eltype, "jit_got");
7807 fields [tindex ++] = module->got_var;
7808 /* llc defines this directly */
7809 if (!module->llvm_only) {
7810 fields [tindex ++] = LLVMAddGlobal (lmodule, eltype, module->eh_frame_symbol);
7811 fields [tindex ++] = LLVMConstNull (eltype);
7812 fields [tindex ++] = LLVMConstNull (eltype);
7814 fields [tindex ++] = LLVMConstNull (eltype);
7815 fields [tindex ++] = module->get_method;
7816 fields [tindex ++] = module->get_unbox_tramp;
7818 if (module->has_jitted_code) {
7819 fields [tindex ++] = AddJitGlobal (module, eltype, "jit_code_start");
7820 fields [tindex ++] = AddJitGlobal (module, eltype, "jit_code_end");
7822 fields [tindex ++] = LLVMConstNull (eltype);
7823 fields [tindex ++] = LLVMConstNull (eltype);
7825 if (!module->llvm_only)
7826 fields [tindex ++] = AddJitGlobal (module, eltype, "method_addresses");
7828 fields [tindex ++] = LLVMConstNull (eltype);
7829 if (info->flags & MONO_AOT_FILE_FLAG_SEPARATE_DATA) {
7830 for (i = 0; i < MONO_AOT_TABLE_NUM; ++i)
7831 fields [tindex ++] = LLVMConstNull (eltype);
7833 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "blob");
7834 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "class_name_table");
7835 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "class_info_offsets");
7836 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "method_info_offsets");
7837 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "ex_info_offsets");
7838 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "extra_method_info_offsets");
7839 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "extra_method_table");
7840 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "got_info_offsets");
7841 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "llvm_got_info_offsets");
7842 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "image_table");
7844 /* Not needed (mem_end) */
7845 fields [tindex ++] = LLVMConstNull (eltype);
7846 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "assembly_guid");
7847 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "runtime_version");
7848 if (info->trampoline_size [0]) {
7849 fields [tindex ++] = AddJitGlobal (module, eltype, "specific_trampolines");
7850 fields [tindex ++] = AddJitGlobal (module, eltype, "static_rgctx_trampolines");
7851 fields [tindex ++] = AddJitGlobal (module, eltype, "imt_thunks");
7852 fields [tindex ++] = AddJitGlobal (module, eltype, "gsharedvt_arg_trampolines");
7854 fields [tindex ++] = LLVMConstNull (eltype);
7855 fields [tindex ++] = LLVMConstNull (eltype);
7856 fields [tindex ++] = LLVMConstNull (eltype);
7857 fields [tindex ++] = LLVMConstNull (eltype);
7859 if (module->static_link && !module->llvm_only)
7860 fields [tindex ++] = AddJitGlobal (module, eltype, "globals");
7862 fields [tindex ++] = LLVMConstNull (eltype);
7863 fields [tindex ++] = LLVMGetNamedGlobal (lmodule, "assembly_name");
7864 if (!module->llvm_only) {
7865 fields [tindex ++] = AddJitGlobal (module, eltype, "plt");
7866 fields [tindex ++] = AddJitGlobal (module, eltype, "plt_end");
7867 fields [tindex ++] = AddJitGlobal (module, eltype, "unwind_info");
7868 fields [tindex ++] = AddJitGlobal (module, eltype, "unbox_trampolines");
7869 fields [tindex ++] = AddJitGlobal (module, eltype, "unbox_trampolines_end");
7870 fields [tindex ++] = AddJitGlobal (module, eltype, "unbox_trampoline_addresses");
7872 fields [tindex ++] = LLVMConstNull (eltype);
7873 fields [tindex ++] = LLVMConstNull (eltype);
7874 fields [tindex ++] = LLVMConstNull (eltype);
7875 fields [tindex ++] = LLVMConstNull (eltype);
7876 fields [tindex ++] = LLVMConstNull (eltype);
7877 fields [tindex ++] = LLVMConstNull (eltype);
7880 for (i = 0; i < MONO_AOT_FILE_INFO_NUM_SYMBOLS; ++i)
7881 fields [2 + i] = LLVMConstBitCast (fields [2 + i], eltype);
7884 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->plt_got_offset_base, FALSE);
7885 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->got_size, FALSE);
7886 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->plt_size, FALSE);
7887 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->nmethods, FALSE);
7888 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->flags, FALSE);
7889 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->opts, FALSE);
7890 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->simd_opts, FALSE);
7891 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->gc_name_index, FALSE);
7892 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->num_rgctx_fetch_trampolines, FALSE);
7893 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->double_align, FALSE);
7894 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->long_align, FALSE);
7895 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->generic_tramp_num, FALSE);
7896 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->tramp_page_size, FALSE);
7897 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->nshared_got_entries, FALSE);
7898 fields [tindex ++] = LLVMConstInt (LLVMInt32Type (), info->datafile_size, FALSE);
7900 fields [tindex ++] = llvm_array_from_uints (LLVMInt32Type (), info->table_offsets, MONO_AOT_TABLE_NUM);
7901 fields [tindex ++] = llvm_array_from_uints (LLVMInt32Type (), info->num_trampolines, MONO_AOT_TRAMP_NUM);
7902 fields [tindex ++] = llvm_array_from_uints (LLVMInt32Type (), info->trampoline_got_offset_base, MONO_AOT_TRAMP_NUM);
7903 fields [tindex ++] = llvm_array_from_uints (LLVMInt32Type (), info->trampoline_size, MONO_AOT_TRAMP_NUM);
7904 fields [tindex ++] = llvm_array_from_uints (LLVMInt32Type (), info->tramp_page_code_offsets, MONO_AOT_TRAMP_NUM);
7905 g_assert (tindex == nfields);
7907 LLVMSetInitializer (info_var, LLVMConstNamedStruct (file_info_type, fields, nfields));
7909 if (module->static_link) {
7913 s = g_strdup_printf ("mono_aot_module_%s_info", module->assembly->aname.name);
7914 /* Get rid of characters which cannot occur in symbols */
7916 for (p = s; *p; ++p) {
7917 if (!(isalnum (*p) || *p == '_'))
7920 var = LLVMAddGlobal (module->lmodule, LLVMPointerType (LLVMInt8Type (), 0), s);
7922 LLVMSetInitializer (var, LLVMConstBitCast (LLVMGetNamedGlobal (module->lmodule, "mono_aot_file_info"), LLVMPointerType (LLVMInt8Type (), 0)));
7923 LLVMSetLinkage (var, LLVMExternalLinkage);
7928 * Emit the aot module into the LLVM bitcode file FILENAME.
7931 mono_llvm_emit_aot_module (const char *filename, const char *cu_name)
7933 LLVMTypeRef got_type, inited_type;
7934 LLVMValueRef real_got, real_inited;
7935 MonoLLVMModule *module = &aot_module;
7937 emit_llvm_code_end (module);
7940 * Create the real got variable and replace all uses of the dummy variable with
7943 got_type = LLVMArrayType (module->ptr_type, module->max_got_offset + 1);
7944 real_got = LLVMAddGlobal (module->lmodule, got_type, module->got_symbol);
7945 LLVMSetInitializer (real_got, LLVMConstNull (got_type));
7946 if (module->external_symbols) {
7947 LLVMSetLinkage (real_got, LLVMExternalLinkage);
7948 LLVMSetVisibility (real_got, LLVMHiddenVisibility);
7950 LLVMSetLinkage (real_got, LLVMInternalLinkage);
7952 mono_llvm_replace_uses_of (module->got_var, real_got);
7954 mark_as_used (&aot_module, real_got);
7956 /* Delete the dummy got so it doesn't become a global */
7957 LLVMDeleteGlobal (module->got_var);
7958 module->got_var = real_got;
7961 * Same for the init_var
7963 if (module->llvm_only) {
7964 inited_type = LLVMArrayType (LLVMInt8Type (), module->max_inited_idx + 1);
7965 real_inited = LLVMAddGlobal (module->lmodule, inited_type, "mono_inited");
7966 LLVMSetInitializer (real_inited, LLVMConstNull (inited_type));
7967 LLVMSetLinkage (real_inited, LLVMInternalLinkage);
7968 mono_llvm_replace_uses_of (module->inited_var, real_inited);
7969 LLVMDeleteGlobal (module->inited_var);
7972 if (module->llvm_only) {
7973 emit_get_method (&aot_module);
7974 emit_get_unbox_tramp (&aot_module);
7977 emit_llvm_used (&aot_module);
7978 emit_dbg_info (&aot_module, filename, cu_name);
7979 emit_aot_file_info (&aot_module);
7982 * Replace GOT entries for directly callable methods with the methods themselves.
7983 * It would be easier to implement this by predefining all methods before compiling
7984 * their bodies, but that couldn't handle the case when a method fails to compile
7987 if (module->llvm_only) {
7988 GHashTableIter iter;
7990 GSList *callers, *l;
7992 g_hash_table_iter_init (&iter, module->method_to_callers);
7993 while (g_hash_table_iter_next (&iter, (void**)&method, (void**)&callers)) {
7994 LLVMValueRef lmethod;
7996 lmethod = (LLVMValueRef)g_hash_table_lookup (module->method_to_lmethod, method);
7998 for (l = callers; l; l = l->next) {
7999 LLVMValueRef caller = (LLVMValueRef)l->data;
8001 mono_llvm_replace_uses_of (caller, lmethod);
8007 /* Replace PLT entries for directly callable methods with the methods themselves */
8009 GHashTableIter iter;
8011 LLVMValueRef callee;
8013 g_hash_table_iter_init (&iter, module->plt_entries_ji);
8014 while (g_hash_table_iter_next (&iter, (void**)&ji, (void**)&callee)) {
8015 if (mono_aot_is_direct_callable (ji)) {
8016 LLVMValueRef lmethod;
8018 lmethod = (LLVMValueRef)g_hash_table_lookup (module->method_to_lmethod, ji->data.method);
8019 /* The types might not match because the caller might pass an rgctx */
8020 if (lmethod && LLVMTypeOf (callee) == LLVMTypeOf (lmethod)) {
8021 mono_llvm_replace_uses_of (callee, lmethod);
8022 mono_aot_mark_unused_llvm_plt_entry (ji);
8032 if (LLVMVerifyModule (module->module, LLVMReturnStatusAction, &verifier_err)) {
8033 g_assert_not_reached ();
8038 LLVMWriteBitcodeToFile (module->lmodule, filename);
8043 md_string (const char *s)
8045 return LLVMMDString (s, strlen (s));
8048 /* Debugging support */
8051 emit_dbg_info (MonoLLVMModule *module, const char *filename, const char *cu_name)
8053 LLVMModuleRef lmodule = module->lmodule;
8054 LLVMValueRef args [16], cu_args [16], cu, ver;
8056 char *build_info, *s, *dir;
8059 * This can only be enabled when LLVM code is emitted into a separate object
8060 * file, since the AOT compiler also emits dwarf info,
8061 * and the abbrev indexes will not be correct since llvm has added its own
8064 if (!module->emit_dwarf)
8068 * Emit dwarf info in the form of LLVM metadata. There is some
8069 * out-of-date documentation at:
8070 * http://llvm.org/docs/SourceLevelDebugging.html
8071 * but most of this was gathered from the llvm and
8076 cu_args [n_cuargs ++] = LLVMConstInt (LLVMInt32Type (), DW_TAG_compile_unit, FALSE);
8077 /* CU name/compilation dir */
8078 dir = g_path_get_dirname (filename);
8079 args [0] = LLVMMDString (cu_name, strlen (cu_name));
8080 args [1] = LLVMMDString (dir, strlen (dir));
8081 cu_args [n_cuargs ++] = LLVMMDNode (args, 2);
8084 cu_args [n_cuargs ++] = LLVMConstInt (LLVMInt32Type (), DW_LANG_C99, FALSE);
8086 build_info = mono_get_runtime_build_info ();
8087 s = g_strdup_printf ("Mono AOT Compiler %s (LLVM)", build_info);
8088 cu_args [n_cuargs ++] = LLVMMDString (s, strlen (s));
8089 g_free (build_info);
8091 cu_args [n_cuargs ++] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
8093 cu_args [n_cuargs ++] = LLVMMDString ("", strlen (""));
8094 /* Runtime version */
8095 cu_args [n_cuargs ++] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
8097 cu_args [n_cuargs ++] = LLVMMDNode (args, 0);
8098 cu_args [n_cuargs ++] = LLVMMDNode (args, 0);
8100 if (module->subprogram_mds) {
8104 mds = g_new0 (LLVMValueRef, module->subprogram_mds->len);
8105 for (i = 0; i < module->subprogram_mds->len; ++i)
8106 mds [i] = (LLVMValueRef)g_ptr_array_index (module->subprogram_mds, i);
8107 cu_args [n_cuargs ++] = LLVMMDNode (mds, module->subprogram_mds->len);
8109 cu_args [n_cuargs ++] = LLVMMDNode (args, 0);
8112 cu_args [n_cuargs ++] = LLVMMDNode (args, 0);
8113 /* Imported modules */
8114 cu_args [n_cuargs ++] = LLVMMDNode (args, 0);
8116 cu_args [n_cuargs ++] = LLVMMDString ("", strlen (""));
8117 /* DebugEmissionKind = FullDebug */
8118 cu_args [n_cuargs ++] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
8119 cu = LLVMMDNode (cu_args, n_cuargs);
8120 LLVMAddNamedMetadataOperand (lmodule, "llvm.dbg.cu", cu);
8122 args [0] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
8123 args [1] = LLVMMDString ("Dwarf Version", strlen ("Dwarf Version"));
8124 args [2] = LLVMConstInt (LLVMInt32Type (), 2, FALSE);
8125 ver = LLVMMDNode (args, 3);
8126 LLVMAddNamedMetadataOperand (lmodule, "llvm.module.flags", ver);
8128 args [0] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
8129 args [1] = LLVMMDString ("Debug Info Version", strlen ("Debug Info Version"));
8130 args [2] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
8131 ver = LLVMMDNode (args, 3);
8132 LLVMAddNamedMetadataOperand (lmodule, "llvm.module.flags", ver);
8136 emit_dbg_subprogram (EmitContext *ctx, MonoCompile *cfg, LLVMValueRef method, const char *name)
8138 MonoLLVMModule *module = ctx->module;
8139 MonoDebugMethodInfo *minfo = ctx->minfo;
8140 char *source_file, *dir, *filename;
8141 LLVMValueRef md, args [16], ctx_args [16], md_args [64], type_args [16], ctx_md, type_md;
8142 MonoSymSeqPoint *sym_seq_points;
8148 mono_debug_symfile_get_seq_points (minfo, &source_file, NULL, NULL, &sym_seq_points, &n_seq_points);
8150 source_file = g_strdup ("<unknown>");
8151 dir = g_path_get_dirname (source_file);
8152 filename = g_path_get_basename (source_file);
8154 ctx_args [0] = LLVMConstInt (LLVMInt32Type (), 0x29, FALSE);
8155 args [0] = md_string (filename);
8156 args [1] = md_string (dir);
8157 ctx_args [1] = LLVMMDNode (args, 2);
8158 ctx_md = LLVMMDNode (ctx_args, 2);
8160 type_args [0] = LLVMConstInt (LLVMInt32Type (), DW_TAG_subroutine_type, FALSE);
8161 type_args [1] = NULL;
8162 type_args [2] = NULL;
8163 type_args [3] = LLVMMDString ("", 0);
8164 type_args [4] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
8165 type_args [5] = LLVMConstInt (LLVMInt64Type (), 0, FALSE);
8166 type_args [6] = LLVMConstInt (LLVMInt64Type (), 0, FALSE);
8167 type_args [7] = LLVMConstInt (LLVMInt64Type (), 0, FALSE);
8168 type_args [8] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
8169 type_args [9] = NULL;
8170 type_args [10] = NULL;
8171 type_args [11] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
8172 type_args [12] = NULL;
8173 type_args [13] = NULL;
8174 type_args [14] = NULL;
8175 type_md = LLVMMDNode (type_args, 14);
8177 /* http://llvm.org/docs/SourceLevelDebugging.html#subprogram-descriptors */
8178 md_args [0] = LLVMConstInt (LLVMInt32Type (), DW_TAG_subprogram, FALSE);
8179 /* Source directory + file pair */
8180 args [0] = md_string (filename);
8181 args [1] = md_string (dir);
8182 md_args [1] = LLVMMDNode (args ,2);
8183 md_args [2] = ctx_md;
8184 md_args [3] = md_string (cfg->method->name);
8185 md_args [4] = md_string (name);
8186 md_args [5] = md_string (name);
8189 md_args [6] = LLVMConstInt (LLVMInt32Type (), sym_seq_points [0].line, FALSE);
8191 md_args [6] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
8193 md_args [7] = type_md;
8195 md_args [8] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
8197 md_args [9] = LLVMConstInt (LLVMInt1Type (), 1, FALSE);
8199 md_args [10] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
8200 /* Index into a virtual function */
8201 md_args [11] = NULL;
8202 md_args [12] = NULL;
8204 md_args [13] = LLVMConstInt (LLVMInt1Type (), 0, FALSE);
8206 md_args [14] = LLVMConstInt (LLVMInt1Type (), 1, FALSE);
8207 /* Pointer to LLVM function */
8208 md_args [15] = method;
8209 /* Function template parameter */
8210 md_args [16] = NULL;
8211 /* Function declaration descriptor */
8212 md_args [17] = NULL;
8213 /* List of function variables */
8214 md_args [18] = LLVMMDNode (args, 0);
8216 md_args [19] = LLVMConstInt (LLVMInt32Type (), 1, FALSE);
8217 md = LLVMMDNode (md_args, 20);
8219 if (!module->subprogram_mds)
8220 module->subprogram_mds = g_ptr_array_new ();
8221 g_ptr_array_add (module->subprogram_mds, md);
8225 g_free (source_file);
8226 g_free (sym_seq_points);
8232 emit_dbg_loc (EmitContext *ctx, LLVMBuilderRef builder, const unsigned char *cil_code)
8234 MonoCompile *cfg = ctx->cfg;
8236 if (ctx->minfo && cil_code && cil_code >= cfg->header->code && cil_code < cfg->header->code + cfg->header->code_size) {
8237 MonoDebugSourceLocation *loc;
8238 LLVMValueRef loc_md, md_args [16];
8241 loc = mono_debug_symfile_lookup_location (ctx->minfo, cil_code - cfg->header->code);
8245 md_args [nmd_args ++] = LLVMConstInt (LLVMInt32Type (), loc->row, FALSE);
8246 md_args [nmd_args ++] = LLVMConstInt (LLVMInt32Type (), loc->column, FALSE);
8247 md_args [nmd_args ++] = ctx->dbg_md;
8248 md_args [nmd_args ++] = NULL;
8249 loc_md = LLVMMDNode (md_args, nmd_args);
8250 LLVMSetCurrentDebugLocation (builder, loc_md);
8251 mono_debug_symfile_free_location (loc);
8257 default_mono_llvm_unhandled_exception (void)
8259 MonoJitTlsData *jit_tls = mono_get_jit_tls ();
8260 MonoObject *target = mono_gchandle_get_target (jit_tls->thrown_exc);
8262 mono_unhandled_exception (target);
8263 exit (mono_environment_exitcode_get ());
8268 - Emit LLVM IR from the mono IR using the LLVM C API.
8269 - The original arch specific code remains, so we can fall back to it if we run
8270 into something we can't handle.
8274 A partial list of issues:
8275 - Handling of opcodes which can throw exceptions.
8277 In the mono JIT, these are implemented using code like this:
8284 push throw_pos - method
8285 call <exception trampoline>
8287 The problematic part is push throw_pos - method, which cannot be represented
8288 in the LLVM IR, since it does not support label values.
8289 -> this can be implemented in AOT mode using inline asm + labels, but cannot
8290 be implemented in JIT mode ?
8291 -> a possible but slower implementation would use the normal exception
8292 throwing code but it would need to control the placement of the throw code
8293 (it needs to be exactly after the compare+branch).
8294 -> perhaps add a PC offset intrinsics ?
8296 - efficient implementation of .ovf opcodes.
8298 These are currently implemented as:
8299 <ins which sets the condition codes>
8302 Some overflow opcodes are now supported by LLVM SVN.
8304 - exception handling, unwinding.
8305 - SSA is disabled for methods with exception handlers
8306 - How to obtain unwind info for LLVM compiled methods ?
8307 -> this is now solved by converting the unwind info generated by LLVM
8309 - LLVM uses the c++ exception handling framework, while we use our home grown
8310 code, and couldn't use the c++ one:
8311 - its not supported under VC++, other exotic platforms.
8312 - it might be impossible to support filter clauses with it.
8316 The trampolines need a predictable call sequence, since they need to disasm
8317 the calling code to obtain register numbers / offsets.
8319 LLVM currently generates this code in non-JIT mode:
8320 mov -0x98(%rax),%eax
8322 Here, the vtable pointer is lost.
8323 -> solution: use one vtable trampoline per class.
8325 - passing/receiving the IMT pointer/RGCTX.
8326 -> solution: pass them as normal arguments ?
8330 LLVM does not allow the specification of argument registers etc. This means
8331 that all calls are made according to the platform ABI.
8333 - passing/receiving vtypes.
8335 Vtypes passed/received in registers are handled by the front end by using
8336 a signature with scalar arguments, and loading the parts of the vtype into those
8339 Vtypes passed on the stack are handled using the 'byval' attribute.
8343 Supported though alloca, we need to emit the load/store code.
8347 The mono JIT uses pointer sized iregs/double fregs, while LLVM uses precisely
8348 typed registers, so we have to keep track of the precise LLVM type of each vreg.
8349 This is made easier because the IR is already in SSA form.
8350 An additional problem is that our IR is not consistent with types, i.e. i32/ia64
8351 types are frequently used incorrectly.
8356 Emit LLVM bytecode into a .bc file, compile it using llc into a .s file, then link
8357 it with the file containing the methods emitted by the JIT and the AOT data
8361 /* FIXME: Normalize some aspects of the mono IR to allow easier translation, like:
8362 * - each bblock should end with a branch
8363 * - setting the return value, making cfg->ret non-volatile
8364 * - avoid some transformations in the JIT which make it harder for us to generate
8366 * - use pointer types to help optimizations.